具有Azure功能的无服务器API
在這篇文章中,我將研究一個非常簡單的用例。 在執行部署管道時, FlexDeploy可能會產生一些應被批準或拒絕的人工任務。 例如,某人必須批準對生產環境的部署。 可以在FlexDeploy UI中或通過某些外部通信渠道來完成。 今天,我將重點介紹通過Slack批準/拒絕FlexDeploy人工任務的場景:
我想考慮一些要求和注意事項:
- 我不想教FlexDeploy與Slack通信
- 我不想向Slack提供FlexDeploy API的詳細信息
- 我不想向公眾公開FlexDeploy API
- 我確實希望能夠輕松地將Slack更改為其他內容或添加其他通信工具,而無需接觸FlexDeploy
基本上,我想使FlexDeploy與外部通信機制的細節脫鉤。 因此,我將引入一個額外的層,即FlexDeploy和Slack之間的API 。 看起來無服務器范例是實現此API的一種非常有吸引力的方法。 今天,我將使用Azure Functions構建它,因為……為什么不呢?
因此,從技術上講,該解決方案的Poc版本如下所示:
一旦出現新的人工任務,FlexDeploy會通知無服務器API有關提供內部任務ID和任務描述的API。 有一個SaveTask函數,將提供的任務詳細信息以及生成的令牌(只是一些uid)保存到Azure Table存儲中 。 該令牌具有到期時間,這意味著應該在該時間之前使用它來批準/拒絕任務。
const azure = require( 'azure-storage' ); const uuidv1 = require( 'uuid/v1' ); module.exports = async function (context, taskid) { var tableSvc = azure.createTableService( 'my_account' , 'my_key' ); var entGen = azure.TableUtilities.entityGenerator; var token = uuidv1(); var tokenEntity = { PartitionKey: entGen.String( 'tokens' ), RowKey: entGen.String(token), TaskId: entGen.String(taskid), dueDate: entGen.DateTime( new Date(Date.now() + 24 * 60 * 60 * 1000 )) }; ??? ?tableSvc.insertEntity( 'tokens' ,tokenEntity, function (error, result, response) { }); return token; };保存令牌后,將調用PostToSlack函數,將消息發布到Slack通道。 SaveTask和PostTo Slack函數被編排到一個持久函數 NotifyOnTask中 ,該函數實際上是由FlexDeploy調用的:
const df = require( "durable-functions" ); module.exports = df.orchestrator(function*(context){ var task = context.df.getInput() var token = yield context.df.callActivity( "SaveTask" , task.taskid) return yield context.df.callActivity( "PostToSlack" , { "token" : token, "description" : task.description}) });Slack中的消息包含兩個按鈕來批準和拒絕任務。
這些按鈕指向指向ActionOnToken持久功能的webhooks :
const df = require( "durable-functions" ); module.exports = df.orchestrator(function*(context){ var input = context.df.getInput() var taskId = yield context.df.callActivity( "GetTaskId" , input.token) if (input.action == 'approve' ) { yield context.df.callActivity( "ApproveTask" , taskId) } else if (input.action == 'reject' ) { yield context.df.callActivity( "RejectTask" , taskId) } });ActionOnToken調用GetTaskId函數,通過給定令牌從存儲中檢索任務ID:
const azure = require( 'azure-storage' ); module.exports = async function (context, token) { var tableSvc = azure.createTableService( 'my_account' , 'my_key' ); function queryTaskID(token) { return new Promise(function (resolve, reject) { tableSvc.retrieveEntity( 'tokens' , 'tokens' , token, function (error, result, response) { if (error) { reject(error) } else { resolve(result) } }); }); } var tokenEntity = await queryTaskID(token); if (tokenEntity) { var dueDate = tokenEntity.dueDate._ if (dueDate > Date.now()) { return tokenEntity.TaskId._ } } }; 完成此操作后,它要么通過調用要么批準或拒絕任務
ApproveTask或RejectTask函數。 這些功能依次調用FlexDeploy REST API。
我可以開始直接在云中開發無服務器應用程序
Azure Portal ,但是我決定實現所有功能并在本地使用它,然后再移至云中。 我可以做到這一點,在本地開發和測試功能的事實實際上非常酷,并不是每個無服務器平臺都為您提供該功能。 我在云中配置的唯一內容是
帶有表的Azure Table存儲帳戶,用于存儲我的令牌和任務詳細信息。
在本地開始使用Azure Functions的便捷方法是使用
Visual Studio Code作為開發工具。 我在Mac上工作,因此我下載并安裝了Mac OS X版本。VS Code就是關于擴展的,對于與您一起使用的每種技術,您都將安裝一個或幾個擴展。 關于Azure函數也是如此。 有一個擴展:
完成此操作后,您將獲得一個新選項卡,您可以在其中創建新的功能應用程序并開始實現您的功能:
在配置新項目時,向導會要求您選擇一種語言,您希望該語言用于實現以下功能:
盡管我喜歡Java,但仍選擇JavaScript是因為我想在常規函數之上實現持久性函數,并且它們支持C# ,
僅F#和JavaScript 。 在撰寫本文時, JavaScript最接近我。
休息照常。 您可以創建函數,編寫代碼,調試,測試,修復,然后重新進行所有操作。 您只需單擊F5,VS Code就可以在調試模式下啟動整個應用程序:
首次啟動該應用程序時,VS Code會建議您在計算機上安裝函數運行時(如果該應用程序不存在)。 因此,基本上,假設您在筆記本電腦運行時上有了首選語言(Node.js),則只需要具有VS Code及其功能擴展即可開始使用Azure Functions 。 它將為您完成其余的安裝。
因此,一旦應用程序啟動,我就可以通過調用NotifyOnTask函數來對其進行測試,該函數將啟動整個周期:
curl -X POST --data '{"taskid":"8900","description":"DiPocket v.1.0.0.1 is about to be deployed to PROD"}' -H "Content-type: application/json" http: //localhost:7071/api/orchestrators/NotifyOnTask該應用程序的源代碼可在GitHub上找到 。
好的,到目前為止, Azure Functions的總體觀點是……這很好。 它只是工作。 到目前為止,在實施該解決方案時,我沒有遇到任何煩人的問題(除了一些愚蠢的錯誤,因為我沒有認真閱讀本手冊)。 我一定會繼續在Azure Functions上進行發布和發布,以豐富該解決方案并將其遷移到云中,并可能實現一些不同的東西。
而已!
翻譯自: https://www.javacodegeeks.com/2019/03/serverless-api-azure-functions.html
總結
以上是生活随笔為你收集整理的具有Azure功能的无服务器API的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mac下使用Automator实现截屏编
- 下一篇: 【IT之家开箱】荣耀 V Purse 钱