I am connecting a web api service to a backend-stateless service.
The Backservice is called MyProject.Management.Company and its code is:
internal sealed class Company: StatelessService,ICompanyManagement
{
private readonly CompanyManagementImpl _impl;
public Tenents(StatelessServiceContext context, CompanyManagementImpl impl)
: base(context)
{
this._impl = impl;
}
/// <summary>
/// Optional override to create listeners (e.g., TCP, HTTP) for this service replica to handle client or user requests.
/// </summary>
/// <returns>A collection of listeners.</returns>
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new[]
{
new ServiceInstanceListener(serviceContext => new FabricTransportServiceRemotingListener(serviceContext, this), "ServiceEndpoint")
};
}
/// <summary>
/// This is the main entry point for your service instance.
/// </summary>
/// <param name="cancellationToken">Canceled when Service Fabric needs to shut down this service instance.</param>
protected override async Task RunAsync(CancellationToken cancellationToken)
{
// TODO: Replace the following sample code with your own logic
// or remove this RunAsync override if it's not needed in your service.
long iterations = 0;
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
ServiceEventSource.Current.ServiceMessage(this.Context, "Working-{0}", ++iterations);
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
}
}
public Task CreateCompany(Company company)
{
return _impl.CreateCompany(company);
}
public Task<List<Company>> GetAllCompanies()
{
return _impl.GetAllCompanies();
}
public Task<Company> GetCompanyById(string companyId)
{
return _impl.GetCompanyById(companyId);
}
}
The code is Listener code is adopted from This Blog Post and even the documentation code doesn't compile documentation the CreateServiceRemotingListenervextension method doesn't exist.
The ICompanyManagement is an interface inherting from IService interface and the implementation is realized via the CompanyManagament that in this phase just returns static objects.
The API is called MyProject.Portal and the controller code is:
public class CompanyController : Controller
{
ICompanyManagement _proxy;
public CompanyController(StatelessServiceContext context)
{
string serviceUri = $"{context.CodePackageActivationContext.ApplicationName}" + "/MyProject.Management.Company";
_proxy = ServiceProxy.Create<ICompanyManagement>(new Uri(serviceUri));
}
// GET: api/Company
[HttpGet]
public async Task<JsonResult> Get()
{
try
{
var result = await _proxy.GetAllCompanies();
return this.Json(result);
}
catch (Exception ex)
{
throw ex;
}
}
}
When the code run it returns the following error.
NamedEndpoint 'V2Listener' not found in the address '{"Endpoints":{"ServiceEndpoint":"localhost:59286+12a705ed-11a5-4bf5-bafd-84179c966257-131719261525940414-9e876439-9294-4ec9-8b33-05f17515aaf4"}}' for partition '12a705ed-11a5-4bf5-bafd-84179c966257'
Finally: I am using .netcore v2, service fabric v6.2.274.
Right after usings in your ICompanyManagement
file add following line:
[assembly: FabricTransportServiceRemotingProvider(RemotingListener = RemotingListener.V2Listener, RemotingClient = RemotingClient.V2Client)]
In your service (CompanyManagement
) manifest (ServiceManifest.xml
file) make sure that endpoint is set to version 2:
<Resources>
<Endpoints>
<Endpoint Name="ServiceEndpointV2" />
</Endpoints>
</Resources>
Change your CreateServiceInstanceListeners method to:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return this.CreateServiceRemotingInstanceListeners();
}
Finally in your web api controller register your service proxy like this:
ICompanyManagement companyManagementClient = ServiceProxy.Create<ICompanyManagement>(new Uri($"fabric:/{applicationName}/{serviceName}"));
If you follow these steps it will work.