Key Functions

Here are some very common scenarios and the way to achieve them with codes.

Limit Service Running On Specific Node Type

According to MSDN, we can create more than 1 node types (virtual machine scale set) in one Azure Service Fabric. Usually it means front end and back end, because we can use smaller size and less VMs for front end, use bigger and more VMs for backend. In this example, I create 2 node types: nodetype1 and nodetype2. Please notice they have different domain names. You can get them from Azure Portal Public IP list.

In our solution, we need to configure WebApi1 service is running in front node type and other services running in backend node type.

In WebApi1/PackageRoot/ServiceManifest.xml, we use below configuration to limit this service only can run in "nodetype2". Please notice you need to add this configuration for not upgrade mode if you service fabric is ready running.

<PlacementConstraints>(NodeType==nodetype2)</PlacementConstraints>

Also the other services have been set to run in "nodetype1".

Add Startup Task

Please check WebApi1 project to find the solution source code.

Sometimes we need to install some dependency exe or run some bat file to preset VM environment before Service Fabric starts to run. Just as the cloud service startup task. You can use following steps to achieve this target.

1. Prepare a .pfx file. You can use makecert.exe to generate a test certificate. In this project, it names as vantest.pfx .

2. Prepare installcert.cmd and installcert.ps1 file. You will use these files to install van.pfx certificate into VM localMachine\MY store.

3. RDP to every VM, copy above 3 files to VM. Run installcert.cmd in command window. If you want to install certificate automatically when VMSS scale up or down, you need to use Azure Key-Vault and set certificate in deployment template.

6. Open WebApi1/OwinCommunicationListener.cs and modify it to listen https protocol. By default it only listens http.

7. Open WebApi1/WebApi1.cs and modify it to listen all endpoints in configuration. By default it only listen endpoint "ServiceEndpoint".

8.\ Open Azure Service Fabric Portal, add 8973 port load balancer.

9.\ Publish Service Fabric, and test by https://[service fabric domain]:8973/api/values/getfromstatelessservice/1

Communication between Web API service and Stateless Service

Web API service is the public entry service which needs to invoke other backend services to finish business requests. We have 2 choices to achieve this target: creating backend service public endpoint or using Service Fabric internal communication technology.

1. Open Stateful1/Stateful1.cs. There are interface ITestService, method public async Task<string> GetCount() and public async Task SetCount(long count). They defined Stateful1 service open API.

Please notice that Stateful1 service uses ReliableDictionary to store value. This dictionary data will be synced among all the Stateful1 services in the same partition.

2. Open WebApi1/Controllers/ValuesController.cs. The following codes indicate how to build communication with Stateful1 service.

// GET api/values/getfromstatefulservice/[0-5]
public async Task<string> GetFromStatefulService(int id)
{
var helloWorldClient = ServiceProxy.Create<ITestService>(new Uri("fabric:/Application1/Stateful1"), new Microsoft.ServiceFabric.Services.Client.ServicePartitionKey(id));
var message = await helloWorldClient.GetCount();
return message;
}
// GET api/values/settostatefulservice/[0-5]?value=123
[HttpGet]
public async Task<string> SetToStatefulService(int id, long value)
{
/* Explnation of partition key
* if there are 2 partitions with key from 0-5.
* 0-2 partition key will map to partition #1
* 3-5 partition key will map to partition #2.
* different partitions have different state.
* which means if you set value 10 to any one of partition key 0-2,
* then partition #1 will have value 10 but partition #2 still have value 0
*/
var helloWorldClient = ServiceProxy.Create<ITestService>(new Uri("fabric:/Application1/Stateful1"), new Microsoft.ServiceFabric.Services.Client.ServicePartitionKey(id));
await helloWorldClient.SetCount(value);
return String.Format("id: {0} has been set to {1}", id, value);
}

Please notice that these API have a parameter called "partition id" and it only accepts 0-5.

This is because in Application1/ApplicationPackageRoot/ApplicationManifest.xml, there is XML configuration which limited Stateful1 partition key from 0-5. You can also use this configuration item to control Stateful Service partition key range.