0

I used the following example to configure a communication listener for my Stateful Service:

https://github.com/Microsoft/azure-docs/blob/master/articles/service-fabric/service-fabric-reliable-services-communication-webapi.md

Relevant snippet:

public Task<string> OpenAsync(CancellationToken cancellationToken)
{
    var serviceEndpoint = this.serviceContext.CodePackageActivationContext.GetEndpoint(this.endpointName);
    var protocol = serviceEndpoint.Protocol;
    int port = serviceEndpoint.Port;

    if (this.serviceContext is StatefulServiceContext)
    {
        StatefulServiceContext statefulServiceContext = this.serviceContext as StatefulServiceContext;

        this.listeningAddress = string.Format(
            CultureInfo.InvariantCulture,
            "{0}://+:{1}/{2}{3}/{4}/{5}",
            protocol,
            port,
            string.IsNullOrWhiteSpace(this.appRoot)
                ? string.Empty
                : this.appRoot.TrimEnd('/') + '/',
            statefulServiceContext.PartitionId,
            statefulServiceContext.ReplicaId,
            Guid.NewGuid());
    }
...

Service manifest snippet:

<Endpoints>
  <Endpoint Protocol="http" Name="ServiceEndpoint" Type="Input" Port="8090" />
  <Endpoint Name="ReplicatorEndpoint" />
</Endpoints>

Now when deploy my application, I get my service on URL with all kind of guids:

http://localhost:8090/ba794109-bba3-4cdf-8434-d718be264087/131407811483781446/614de30b-14a7-4172-a03d-4e28d23cf28d

If I try to access http://localhost:8090/ on itself, I'm getting error 503

Any way to map the general URL to the Primary partition and replica? Or is it impossible in Stateful Services? In Stateless you will get this out of the box.

Mugen
  • 8,301
  • 10
  • 62
  • 140

1 Answers1

2

The "out of the box" solution you are referring to is dependent on the partitioning type. A singleton partition can be accessed by its service URL:

http://localhost:8090/ApplicationName/ServiceName

This doesn't work for a service with Named or Int64Range partitioning because the URL doesn't refer to a specific partition of the service. That's why you have to call the service URL that contains the GUIDs. The GUIDs refer to the partition.

In order to solve this problem you could use a reverse proxy. A reverse proxy allows you to provide the partition information through the URL. You can call your partitioned service through the URL:

http(s)://<Cluster FQDN | internal IP>:Port/<ServiceInstanceName>/<Suffix path>?PartitionKey=<key>&PartitionKind=<partitionkind>&ListenerName=<listenerName>&TargetReplicaSelector=<targetReplicaSelector>&Timeout=<timeout_in_seconds>

In your cluster it would probably look like:

http://clusterIP:19081/ApplicationName/ServiceName/PartitionKey=1&PartitionKind=Int64Range

Note that the reverse proxy (currently) is not available on the local development cluster. For development purposes I would recommend to either use the URL with GUIDs or temporarely change your partitioning to a singleton scheme.

Wouter B
  • 731
  • 5
  • 16
  • if I use a singleton partition, how would I go handling the ReplicaId GUID? – Mugen Jun 01 '17 at 10:27
  • 1
    Whenever you'd call the service, your call will be forwarded to the primary replica. So unless you want to use secondary replicas (they only have read rights) you don't have to supply the replicaId. In the case that you do want to access a secondary replica, you will have to use a reverse proxy or the replicaId in the URL. – Wouter B Jun 01 '17 at 12:12