今天要搞點事情,這篇文章我真的寫了一段時間了,應該是說這範例花了我很多時間測試,因為跨越到很多東西,這次我們加玩了 Condition , Inline Code ( javascript) ,所以花了一段時間測試,今天就分享一下測試心得吧..
前置作業,在開始之前,因為撰寫 Inline Code 必須要開啟整合帳號 詳細請參考
https://docs.microsoft.com/zh-tw/azure/logic-apps/logic-apps-enterprise-integration-partners
之後在 Logic App 設定中在 Workflow 有一個地方必須要指定你開啟的 Integration accounts 這樣 Inline code 才能用

現在解釋案例,我寫程式 POST 到 Azure Logic App 的一個 work flow ,我會去 Azure Storage Table 查詢 Partition Key and RowKey 一致的資料,然後我會寫邏輯,如果失敗 或是 成功回應不同訊息
1. 建立第一個 trigger , When A HTTP Request is Received ,因為要制定傳入的資料,所以 JSON Schema ,相關的觀念可以參考
[C#] 使用 NJsonSchema.CodeGeneration.CSharp 製作 JSON Schema + 驗證 JSON
{
"$id": "http://example.com/example.json",
"$schema": "http://json-schema.org/draft-07/schema",
"additionalProperties": true,
"default": {},
"description": "The root schema comprises the entire JSON document.",
"examples": [
{
"PK": "dsadsa",
"RK": "test"
}
],
"properties": {
"PK": {
"$id": "#/properties/PK",
"default": "",
"description": "An explanation about the purpose of this instance.",
"examples": [
"dsadsa"
],
"title": "The PK schema",
"type": "string"
},
"RK": {
"$id": "#/properties/RK",
"default": "",
"description": "An explanation about the purpose of this instance.",
"examples": [
"test"
],
"title": "The RK schema",
"type": "string"
}
},
"required": [
"PK",
"RK"
],
"title": "The root schema",
"type": "object"
}
2. 加入一個 Action 去撈資料,並且設定為 Step1 的傳入的 PK , RK 進行查詢。
3. Step2 有兩種狀況 一個是錯誤 (因為沒拉到資料) ,另一種狀況是成功的 然後我們分別在下面,所以我們加入一個 Condition 去判斷 Partition Key + RowKey 查詢查回來 Partition Key 不等於 null 加入
兩種 inline code 進行判斷並且 輸出.
True Condition Inline Code ( 也就是成功,不等於null) :
var text = "success";
var body=workflowContext.actions.QUERYUSERDATA.outputs.body;
var res={
Status : 'success',
PK:body.PartitionKey,
RK:body.RowKey,
Meta:body.Meta
};
return JSON.stringify(res);
False Condition Inline Code (失敗,等於 null ):
var text = "error";
var obj = {
Status : 'error',
Message : 'Data is not Existed.'
};
return JSON.stringify(obj);
這樣透過 C# 程式端這邊 post 到步驟1 的網址就可以拿到各自的 json 答案。
var url = "https://prod-28.southeastasia.logic.azure.com:443/workflows/ed700fc0f27b48cc9f5abaee54c00fea/triggers/manual/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=6u9Y6ZjyNqhWHGcIDJIblT6OZkIX7-xzmHVNc4qrMcQ";
var client = new RestClient();
var request = new RestRequest(url, Method.POST);
string jsonToSend = "{\"PK\":\"CLASSA\" , \"RK\":\"LOGICAPPKEY1\"}";
//string jsonToSend = "{\"PK\":\"CLASSA\" , \"RK\":\"ERROR\"}";
request.AddParameter("application/json; charset=utf-8", jsonToSend, ParameterType.RequestBody);
request.RequestFormat = DataFormat.Json;
try
{
var c = client.ExecuteAsPost(request, "POST");
Response.Write(c.Content);
}
catch (Exception error)
{
// Log
}
附上完整的 Azure Logic App Code :
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Condition": {
"actions": {
"RES_SUCCESS": {
"inputs": {
"body": "@outputs('SUCCESS_RESPONSE_JS')?['body']",
"statusCode": 200
},
"kind": "Http",
"runAfter": {
"SUCCESS_RESPONSE_JS": [
"Succeeded"
]
},
"type": "Response"
},
"SUCCESS_RESPONSE_JS": {
"inputs": {
"code": "var text = \"success\";\r\n\r\nvar body=workflowContext.actions.QUERYUSERDATA.outputs.body;\r\n\r\nvar res={\r\nStatus : 'success',\r\nPK:body.PartitionKey,\r\nRK:body.RowKey,\r\nMeta:body.Meta\r\n};\r\n\r\nreturn JSON.stringify(res);\r\n"
},
"runAfter": {},
"type": "JavaScriptCode"
}
},
"else": {
"actions": {
"ERROR_RESPONSE_JS": {
"inputs": {
"code": "var text = \"error\";\r\n\r\nvar obj = {\r\n Status : 'error',\r\n Message : 'Data is not Existed.'\r\n};\r\n\r\nreturn JSON.stringify(obj);\r\n"
},
"runAfter": {},
"type": "JavaScriptCode"
},
"RES_FAIL": {
"inputs": {
"body": "@string(outputs('ERROR_RESPONSE_JS')['body'])",
"statusCode": 200
},
"kind": "Http",
"runAfter": {
"ERROR_RESPONSE_JS": [
"Succeeded"
]
},
"type": "Response"
}
}
},
"expression": {
"and": [
{
"not": {
"equals": [
"@body('QUERYUSERDATA')?['PartitionKey']",
"@null"
]
}
}
]
},
"runAfter": {
"QUERYUSERDATA": [
"Succeeded"
]
},
"type": "If"
},
"QUERYUSERDATA": {
"inputs": {
"host": {
"connection": {
"name": "@parameters('$connections')['azuretables']['connectionId']"
}
},
"method": "get",
"path": "/Tables/@{encodeURIComponent('table1')}/entities(PartitionKey='@{encodeURIComponent(triggerBody()['PK'])}',RowKey='@{encodeURIComponent(triggerBody()['RK'])}')",
"queries": {
"$select": "Meta,PartitionKey,RowKey"
}
},
"runAfter": {},
"type": "ApiConnection"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"manual": {
"inputs": {
"schema": {
"$id": "http://example.com/example.json",
"$schema": "http://json-schema.org/draft-07/schema",
"additionalProperties": true,
"default": {},
"description": "The root schema comprises the entire JSON document.",
"examples": [
{
"PK": "dsadsa",
"RK": "test"
}
],
"properties": {
"PK": {
"$id": "#/properties/PK",
"default": "",
"description": "An explanation about the purpose of this instance.",
"examples": [
"dsadsa"
],
"title": "The PK schema",
"type": "string"
},
"RK": {
"$id": "#/properties/RK",
"default": "",
"description": "An explanation about the purpose of this instance.",
"examples": [
"test"
],
"title": "The RK schema",
"type": "string"
}
},
"required": [
"PK",
"RK"
],
"title": "The root schema",
"type": "object"
}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {
"$connections": {
"value": {
"azuretables": {
"connectionId": "/subscriptions/11111111-2222-3333-4444-66666666666/resourceGroups/SPINUS/providers/Microsoft.Web/connections/azuretables",
"connectionName": "azuretables",
"id": "/subscriptions/11111111-2222-3333-4444-66666666666/providers/Microsoft.Web/locations/southeastasia/managedApis/azuretables"
}
}
}
}
}
這花了一點時間盡量紀錄完整希望幫助到有碰到的人,看起來很複雜,其實自己做完之後是到還好,只是有些地方沒這麼熟悉,不過為了達到無 server 化的目標跟成本考量,這點研究我覺得蠻值得的..
reference:
https://docs.microsoft.com/zh-tw/azure/logic-apps/logic-apps-add-run-inline-code