Dziś trochę inny temat. Czy zastanawialiście się kiedyś jak można wbudować w system możliwość wyłączania Azure Functions? Tak, aby nasza aplikacja była w stanie włączyć jakąś funkcję w miarę potrzeb i potem ją wyłączyć. Powodów takich wymagań może być wiele. Możemy przykładowo chcieć odroczyć przetwarzanie jakiś wiadomości do godzin nocnych, tak aby w trakcie dnia nasza funkcja nie obciążała elementu naszej infrastruktury. Innym dość często spotykanym pytaniem w trakcie różnego rodzaju meetupów lub hackatonów jest to czy jesteśmy w stanie w jakiś sposób wyłączyć funkcję automatycznie jeśli wykorzystamy darmową ilość wykonań funkcji.
Nie jest to takie trudne jak nam się wydaje. Generalnie cały problem sprowadza się do zmiany jednego wpisu w pliku functions.json – disabled:
I w sumie jest to nawet całkiem proste. W moim rozwiązaniu stworzyłem oddzielną funkcję, która będzie mogła wyłączać dowolną funkcję na podstawie przesłanych parametrów. Do tego celu wykorzystałem kudu REST API. Funkcja to robiąca jest dość prosta. Powinna ona pobrać plik function.json funkcji, której stan chcemy zmienić. Następnie go zdeserializować i ustawić odpowiednią wartość parametru disabled. I finalnie wgrać jego nową wartość:
#r "Newtonsoft.Json" using System.Net; using Newtonsoft.Json; public static async Task<HttpResponseMessage> Run(HttpRequestMessage req) { dynamic data = await req.Content.ReadAsAsync<object>(); string username = data?.username; string password = data?.password; string functionSiteRoot = data?.functionSiteRoot; string functionName = data?.functionName; bool isDisabled = data?.isDisabled; WebClient webClient = new WebClient { Headers = { ["ContentType"] = "application/json" }, Credentials = new NetworkCredential(username, password), BaseAddress = functionSiteRoot }; var functionJson = JsonConvert.DeserializeObject<FunctionSettings>(webClient.DownloadString($"{functionName}/function.json")); functionJson.disabled = isDisabled; webClient.Headers["If-Match"] = "*"; webClient.UploadString($"{functionName}/function.json", "PUT", JsonConvert.SerializeObject(functionJson)); return req.CreateResponse(HttpStatusCode.OK); } internal class FunctionSettings { public bool disabled { get; set; } public List<Binding> bindings { get; set; } } internal class Binding { public string name { get; set; } public string type { get; set; } public string direction { get; set; } public string queueName { get; set; } public string connection { get; set; } public string accessRights { get; set; } public string schedule { get; set; } }
Tak stworzoną funkcję możemy uruchomić poprzez wysłanie requestu Postman-em:
Mam nadzieję, że parametry są dość czytelne. Większość z nich pobierzemy z PublishSettings aplikacji funkcyjnej w której znajduje się funkcja, którą chcemy wyłączyć:
I na koniec drobna podpowiedź, kopiując kod nie zapomnijcie dodać pliku project.json z następującą zawartością:
{ "frameworks": { "net46":{ "dependencies": { "Newtonsoft.Json": "9.0.1" } } } }
W naszej funkcji korzystamy z dodatkowej biblioteki zewnętrznej.
My function.json file of that specific function is updated but it does not enable/disable my functions. Kindly help.
This way was working for all version of functions.
Interesting, I managed to download the function.json, but when I upload it again, I get a HTTP Conflict error.
Are you using functions in version 1?
Interesting idea, I was able to login but unable to find the json file.
Which version of function are you using? Are you adding function as code (csx), compiled (dll) or compressed (to zip archive)?
Please provide the Azure Function v2 supported article.
I will try to do it in the future.
Here is our case we are trying to disable Programmatically but we are using above code with PUT method to disable this function instead of disabling function is getting deleted from Azure Portal .
Please help on the ASAP.
Above function app not working properly. PUT method action delete the function in Azure portal. cant able to see function.json file also. PUT method behavior like DELETE.
Can you please provide more details about your case? This article has been prepared for Azure Functions v1.
This would probably not work when your function app is pre-compiled and deployed. Reference: https://www.obungi.com/2018/05/23/azure-function-still-running-after-being-disabled/
I tried this myself and disabling the function seemed to have no effect.
You are right.
Also in Functions v2 it works in a different way.