Skip to content

Commit 36d722e

Browse files
hello-service-fabric (#68)
* Adding hello-service-fabric sample * Updating .gitIgnore for Service Fabric demo. * Fixed http file and readme * Polished the readme * Made changes from code review. Co-authored-by: Donovan Brown <dlbm3@hotmail.com>
1 parent 569f810 commit 36d722e

File tree

10 files changed

+652
-1
lines changed

10 files changed

+652
-1
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@ package-lock.json
44
vendor/**
55
twitter-sentiment-processor/demos/demo2/viewer/handler
66
twitter-sentiment-processor/demos/demo3/demochart/templates/twitter.yaml
7-
.venv/
7+
hello-service-fabric/daprsfpkg/MyService/CodeDapr/daprd.exe
8+
hello-service-fabric/daprsfpkg/MyService/CodeDapr/components/pubsub.yaml
9+
hello-service-fabric/daprsfpkg/MyService/CodeDapr/components/statestore.yaml
10+
.venv/

hello-service-fabric/README.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# Dapr on Service Fabric Sample
2+
3+
## Sample info
4+
5+
| Attribute | Details |
6+
|--------|--------|
7+
| Dapr runtime version | v1.4.0 |
8+
| Language | Javascript |
9+
| Environment | Service Fabric |
10+
11+
## Overview
12+
13+
The following is a sample of how to host a Dapr app on a Service Fabric cluster. We'll be deploying a Node.js app that subscribes to order messages and persists them. The following architecture diagram illustrates the components that make up this sample:
14+
15+
![Architecture Diagram](./img/Architecture_Diagram.png)
16+
17+
Some Dapr functionality, including Pub/Sub, Secrets and Bindings work without any integration with SF. However, service invocation, will not work without additional changes and is out of scope for this post.
18+
19+
## Prerequisites
20+
21+
Clone this repo using `git clone https://github.com/dapr/samples.git` and go to the directory named *\hello-service-fabric*. All commands should be executed from a PowerShell terminal.
22+
23+
- [Docker](https://docs.docker.com/)
24+
- [PowerShell](https://github.com/powershell/powershell)
25+
- [REST Client extension](https://marketplace.visualstudio.com/items?itemName=humao.rest-client)
26+
- [Node.js version 8 or greater](https://nodejs.org/en/)
27+
- [Microsoft Azure Service Fabric SDK](https://www.microsoft.com/web/handlers/webpi.ashx?command=getinstallerredirect&appid=MicrosoftAzure-ServiceFabric-CoreSDK)
28+
29+
## Step 1 - Setup Dapr
30+
31+
Follow these [instructions](https://docs.dapr.io/getting-started/install-dapr/#install-dapr-in-self-hosted-mode) to download and install the Dapr CLI and initialize Dapr with `dapr init`.
32+
33+
```PowerShell
34+
dapr init
35+
```
36+
37+
## Step 2 - Setup Service Fabric
38+
39+
1. Create a basic Service Fabric cluster through the SDK as described [here](https://docs.microsoft.com/azure/service-fabric/service-fabric-get-started).
40+
41+
1. Right click "Service Fabric Local Cluster Manager" in the taskbar and select "Start Local Cluster".
42+
43+
## Step 3 - Create the Service Fabric Application Package
44+
45+
This section will create an application package where daprd.exe and the user node.js app will be run as guest executables in two separate code packages under the same Service Fabric service. They'll always be co-located.
46+
47+
1. Copy daprd.exe from your local Dapr installation, `c:\Users\[user]\.dapr\bin`, into `\daprsfpkg\MyService\CodeDapr\`.
48+
49+
```PowerShell
50+
copy c:\Users\$env:username\.dapr\bin\daprd.exe .\daprsfpkg\MyService\CodeDapr\
51+
```
52+
53+
1. Copy the components from your local Dapr installation, `c:\Users\[user]\.dapr\components`, into `\daprsfpkg\MyService\CodeDapr\components`.
54+
55+
```PowerShell
56+
copy c:\Users\$env:username\.dapr\components\*.* .\daprsfpkg\MyService\CodeDapr\components\
57+
```
58+
59+
1. From `\daprsfpkg\MyService\CodeUserApp\`, run `npm install` to install the node.js app's dependencies and return to `\hello-service-fabric`.
60+
61+
```PowerShell
62+
cd .\daprsfpkg\MyService\CodeUserApp\
63+
npm install
64+
cd ..\..\..
65+
```
66+
67+
1. From `\hello-service-fabric`, confirm the application package is well-formed:
68+
69+
```PowerShell
70+
Test-ServiceFabricApplicationPackage .\daprsfpkg\
71+
```
72+
73+
Notes:
74+
75+
- the application package includes the Dapr `components` folder, which stores Dapr component configurations, in the Dapr code package. In Dapr standalone (local) mode, this is generated by the Dapr CLI. It is included so daprd.exe can read it when running on a Service Fabric cluster.
76+
77+
- the service manifest contains a command to invoke daprd.exe with the same args that the Dapr CLI does in the sample.
78+
79+
## Step 4 - Create the Service Fabric Application
80+
81+
Copy the application package to the cluster, register it, then create the application.
82+
83+
Connect to the cluster:
84+
85+
```PowerShell
86+
Connect-ServiceFabricCluster
87+
```
88+
89+
Copy the application package to the cluster:
90+
91+
```PowerShell
92+
Copy-ServiceFabricApplicationPackage daprsfpkg
93+
```
94+
95+
Register it:
96+
97+
```PowerShell
98+
Register-ServiceFabricApplicationType daprsfpkg
99+
```
100+
101+
Create the application instance:
102+
103+
```PowerShell
104+
New-ServiceFabricApplication -ApplicationName fabric:/dapr1 -ApplicationTypeName daprsf -ApplicationTypeVersion 1.0
105+
```
106+
107+
daprd.exe and the node.js app will run on the same node.
108+
109+
## Part 5 - Post Messages to the Service
110+
111+
Now that Dapr and the Node.js app are running, you can POST messages against it, using the Visual Studio Code [REST Client extension](https://marketplace.visualstudio.com/items?itemName=humao.rest-client).
112+
113+
Open the `requests.http` file in the root folder to execute the following requests.
114+
115+
```text
116+
POST http://localhost:3500/v1.0/invoke/mynode/method/neworder
117+
Content-Type: application/json
118+
119+
{"data":{"orderId":"42"}}
120+
121+
###
122+
123+
GET http://localhost:3500/v1.0/invoke/mynode/method/order
124+
```
125+
126+
## Part 6 - Cleanup
127+
128+
1. Delete the Service Fabric application instance:
129+
130+
```PowerShell
131+
Remove-ServiceFabricApplication -ApplicationName fabric:/dapr1 -Force
132+
```
133+
134+
1. Unregister the Service Fabric application type
135+
136+
```PowerShell
137+
Unregister-ServiceFabricApplicationType -ApplicationTypeName daprsf -ApplicationTypeVersion 1.0 -Force
138+
```
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<ApplicationManifest xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="daprsf" ApplicationTypeVersion="1.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
3+
<ServiceManifestImport>
4+
<ServiceManifestRef ServiceManifestName="MyService" ServiceManifestVersion="1.0.0.0" />
5+
</ServiceManifestImport>
6+
<DefaultServices>
7+
<Service Name="MyServiceName">
8+
<StatelessService ServiceTypeName="MyServiceType">
9+
<SingletonPartition />
10+
</StatelessService>
11+
</Service>
12+
</DefaultServices>
13+
</ApplicationManifest>

hello-service-fabric/daprsfpkg/MyService/CodeDapr/components/.gitkeep

Whitespace-only changes.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// ------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation.
3+
// Licensed under the MIT License.
4+
// ------------------------------------------------------------
5+
6+
const express = require('express');
7+
require('isomorphic-fetch');
8+
9+
const app = express();
10+
app.use(express.json());
11+
12+
const port = process.env.APP_HTTP_PORT || 3000;
13+
const daprPort = process.env.DAPR_HTTP_PORT || 3500;
14+
const stateUrl = `http://localhost:${daprPort}/v1.0/state/statestore/`;
15+
16+
app.get('/order', (_req, res) => {
17+
fetch(`${stateUrl}/order`)
18+
.then((response) => {
19+
return response.json();
20+
}).then((orders) => {
21+
res.send(orders);
22+
});
23+
});
24+
25+
app.post('/neworder', (req, res) => {
26+
const data = req.body.data;
27+
const orderId = data.orderId;
28+
console.log("Got a new order! Order ID: " + orderId);
29+
30+
const state = [{
31+
key: "order",
32+
value: data
33+
}];
34+
35+
fetch(stateUrl, {
36+
method: "POST",
37+
body: JSON.stringify(state),
38+
headers: {
39+
"Content-Type": "application/json"
40+
}
41+
}).then((response) => {
42+
console.log((response.ok) ? "Successfully persisted state" : "Failed to persist state" + response);
43+
});
44+
45+
res.status(200).send();
46+
});
47+
48+
app.listen(port, () => console.log(`Node App listening on port ${port}!`));

0 commit comments

Comments
 (0)