run a WebJob from Asp.Net MVC azure website - azure

What I want to do is run WebJob from my Asp.Net MVC azure website periodically without having to go through https://portal.azure.com/
Can I get the rest calls using Azure Resource Explorer for Azure Webjobs so that I can run it? I looked but I don't see the one I created

Resource Explorer doesn't currently show this, but I can give you the API here. To invoke a triggered WebJob, do a POST like this (with empty request body):
POST /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/sites/{site}/triggeredwebjobs/{jobname}/run?api-version=2015-08-01
There is also a way to do it via the Kudu API instead of going through ARM, and is documented here.
The difference between the two is how you authenticate, in the first case using ARM token, and in the second case using basic auth publishing credentials. But they both do the same in the end.

If it periodically, you can schedule your webjob in the azure portal or using setting deployment (Deploy WebJobs using Visual Studio):
When you configure a Console Application for WebJobs deployment, Visual Studio installs the Microsoft.Web.WebJobs.Publish NuGet package and stores scheduling information in a webjob-publish-settings.json file in the project Properties folder of the WebJobs project. Here is an example of that file:
{
"$schema": "http://schemastore.org/schemas/json/webjob-publish-settings.json",
"webJobName": "WebJob1",
"startTime": "2014-06-23T00:00:00-08:00",
"endTime": "2014-06-27T00:00:00-08:00",
"jobRecurrenceFrequency": "Minute",
"interval": 5,
"runMode": "Scheduled"
}
Another option TimerTriggerAttribute : using the latest WebJobs SDK, which supports triggering job functions on schedule, based on the same CRON expression format. You can use it to schedule your job :
public static void TimerJob([TimerTrigger("00:01:00")] TimerInfo timerInfo, TextWriter log)
{
log.WriteLine("Scheduled job fired!");
}
Other option : use the Webjob API:
Invoke a triggered job**
POST /api/triggeredwebjobs/{job name}/run
Last option: use the Azure Management Libraries from Azure Web Jobs.

Use the Kudu Api... Here is a rough example...
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] data = encoder.GetBytes(serializedObjHere);
var url = "https://{site}.scm.azurewebsites.net/api/triggeredwebjobs/{jobname}/run";
var request = (HttpWebRequest)WebRequest.Create(url);
request.Credentials = new System.Net.NetworkCredential("{username}", "{password}"); //you can get these in yoru publish profile
request.AllowWriteStreamBuffering = true;
request.Method = "POST";
request.Timeout = 60000; //60 seconds
request.KeepAlive = false;
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
var response = (HttpWebResponse)request.GetResponse();
response.Close();
response.Dispose();

Related

Triggered Azure Function to Invoke a Webjob

My Requirement:
As soon as a file being uploaded to a Blob Container, the Azure Function is being alerted and withing that Azure Function I want to call a Webjob who uses the uploaded file and does any task.
What I learnt:
I learnt that Azure Function can be triggered when a file being uploaded to a blob container. I tried the tutorials and was able to configure an Azure function and it acts for any change in blob container. I did this via Azure Portal and not used Visual Studio.
Now I want to call a WebJob within the Azure Function. Please help me on this.
Assuming that you have written your function in C#, below is the code that might help you. Essentially the idea is to send a POST request to trigger your job:
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(“https://your_web_site.azurewebsites.net/api/”);
var byteArray = Encoding.ASCII.GetBytes(“your_username:your_password”);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(“Basic”, Convert.ToBase64String(byteArray));
var response = await client.PostAsync(“triggeredwebjobs/your_web_job_name/run”, null);
Username and password you find in Azure portal, in the properties of your job.

How to update Azure AppSettings from Azure Webjob by C#?

I have hosted Azure Web Job inside Azure Web Apps which runs every hour and I need to write the Web Job Run time as key value pair. Next time when Webjob run then it will pick the last run time and do its operations. I was thinking of adding Key Value pair in Azure AppSettings of Azure App Service but I am not able to fine any code to update the value in Azure AppSettings.
Can anyone please let me know the code? Please let me know if it is good approach or should I go for Azure Storage Container to store Last Batch Run Time value.
but I am not able to fine any code to update the value in Azure AppSettings.
You could use Microsoft.WindowsAzure.Management.WebSites to achieve it.
var credentials = GetCredentials(/*using certificate*/);
using (var client = new WebSiteManagementClient(credentials))
{
var currentConfig = await client.WebSites.GetConfigurationAsync(webSpaceName,
webSiteName);
var newConfig = new WebSiteUpdateConfigurationParameters
{
ConnectionStrings = null,
DefaultDocuments = null,
HandlerMappings = null,
Metadata = null,
AppSettings = currentConfig.AppSettings
};
newConfig.AppSettings[mySetting] = newValue;
await client.WebSites.UpdateConfigurationAsync(webSpaceName, webSiteName,
newConfig);
}
Or using Azure Fluent Api, refer to this SO thread.

How do I write an azure function to trigger a azure devops pipeline? Is this even possible?

I'm trying to set up an Azure function that can trigger a Azure devops build pipeline. But I'm not sure on how to proceed with this and if it's even possible to do so.
I already have a build pipeline ready to be used but the conventional triggers that are already provided by Azure devops cannot be used. I can't disclose the reason but I need to trigger it using an Azure function. Any help regarding this would be really helpful.
Thanks.
You can simply use the REST APIs of Azure DevOps and call those from your function. See here: API for automating Azure DevOps Pipelines?
How to proceed with this and if it's even possible to do so.
Of course, it can do to trigger a Azure Devops pipeline by Azure function.
To achieve this, you will use Visual Studio also, better with the version 2017 or higher , and also installed .Net Core SDK and Develop Azure Functions using Visual Studio.
In the Azure Function App you created, open HttpTrigger1, and
click Get Function Url. This is a key point, so better save
it in the txt. Because as this execution, Azure Function just act as
a switching proxy or mechanism.
Create a Azure Function project in Visual studio. In template,
choose HttpTrigger template, Azure Functions v1 (.NET
Framework) from the framework dropdown.
Open .cs file and input the below script in it:
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
namespace PartsUnlimited.AzureFunction
{
public static class Function1
{
[FunctionName("HttpTriggerCSharp1")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route =
null)]HttpRequestMessage req, TraceWriter log)
{
var userIdKey = req.GetQueryNameValuePairs().FirstOrDefault(q =>
string.Equals(q.Key, "UserId", StringComparison.OrdinalIgnoreCase));
var userId = string.IsNullOrEmpty(userIdKey.Value) ? int.MaxValue : Convert.ToInt64(userIdKey.Value);
var url = $"https://<<APIAppServiceUrl>>/api/{(userId > 10 ? "v1" : "v2")}/specials/GetSpecialsByUserId?id={userId}";
using (HttpClient httpClient = new HttpClient())
{
return await httpClient.GetAsync(url);
}
}
}
}
Replace <<APIAppServiceUrl>> with your AzureWebsite.net URL.
Go xxxxWebsite->Controllers->StoreController.cs, replace the url
variable in line 46 with your Function url which copied in Step 1.
Click Commit and Push All to push the changes to the Azure
Devops repository.
Create a build pipeline, and enable CI. And also, create release pipeline, add deloy Azure App task and enable CD.
That's all the steps you need to create. There has been a blog which written by our Azure DevOps Labs and it has the detailed steps, you can refer to it.
REST API can be easily invoked from an azure function.
You can pretty much deploy a whole infrastructure as well as deploy the code just based on a function call using azure DevOps.
Refer this for more information: https://learn.microsoft.com/en-us/rest/api/azure/devops/

HTTP Request/Response on Azure WebJob

I'm looking to create a WebJob that takes in a request and sends a response, much like an Azure Function with an HTTP trigger. I want to use a WebJob instead because I need to use wkhtmltopdf, which cannot run on a Consumption plan, and we are already paying for an App Service that it can run on.
I know how to run the WebJob using an HTTP POST from this link: https://stackoverflow.com/a/42824776/443044.
What I cannot figure out is how to create the WebJob itself.
Here is my Program class:
public class Program
{
[NoAutomaticTrigger]
public static void TestMethod(TextWriter logger)
{
logger.WriteLine("TEST: " + req.Content.ToString());
}
// Please set the following connection strings in app.config for this WebJob to run:
// AzureWebJobsDashboard and AzureWebJobsStorage
static void Main()
{
var config = new JobHostConfiguration();
...
var host = new JobHost(config);
host.Call(typeof(Program).GetMethod("TestMethod"), null);
}
}
The program throws an exception if I try to give TestMethod the return type of HttpResponseMessage or a parameter of type HttpRequestMessage.
How can I achieve the request/response functionality like with an Azure Function?
we are already paying for an App Service -> You do realize you can host your azure function on an existing app plan as well? learn.microsoft.com/en-us/azure/azure-functions/….
But AFAIK webjobs do not have capabilities to respond to requests.

Does the Azure WebJobs SDK support pushing TextWriter logs into App Insights?

With the Azure WebJobs SDK, the process of adding logging to your functions is relatively straightforward: Add a TextWriter param to your triggered function, and write to it. That's it.
The SDK will will then associate and display these logs with their execution instances in the WebJobs Dashboard, which provides a relatively data-rich, yet frictionless view into the operationalization of your webjobs.
While this data is replicated into a user-accessible Azure Storage Blob Container, more custom code would be required to periodically push these logs to App Insights, which is undesirable.
Looking for ideas or solutions for how to push all logs pushed via the injected TextWriter to be pushed to AppInsights (or OMS, for that matter), complete with the webjobs execution/trigger instance metadata, thereby allowing a unified consumption experience for various log analytics.
Based on this Feature being tracked in the WebJobs SDK, I'm assuming that for now this is not possible? A long while back I looked into trying to inject my own TextWriter instance, but I would've had to fork the WebJobs SDK and use my customized assembly that changed a lot of architecture.
You can write a custom TraceWriter that sends log to AppInsights:
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.ApplicationInsights;
using Microsoft.Azure.WebJobs.Host;
public class AppInsightsTraceWriter : TraceWriter
{
private readonly TelemetryClient _telemetryClient;
public AppInsightsTraceWriter(TraceLevel level, TelemetryClient telemetryClient)
: base(level)
{
_telemetryClient = telemetryClient;
}
public override void Trace(TraceEvent traceEvent)
{
var eventTelemetry = new EventTelemetry() {Name = "WebjobTraceEvent"};
eventTelemetry.Properties.Add(traceEvent.Level.ToString(), traceEvent.ToString());
_telemetryClient.TrackEvent(eventTelemetry);
}
}
In this example, I inject the TelemetryClient class because you should only have one instance of the TelemetryClient class in your application.
So now you just need to configure the Jobhost to use your custom writer :
// Initialize the webjob configuration.
var config = new JobHostConfiguration();
// Only one instance of the telemetry client is needed
var telemetryClient = new TelemetryClient() {InstrumentationKey = "MyInstrumentationKey"};
// Add the app insights tracer for webjob logs/traces.
config.Tracing.Tracers.Add(new AppInsightsTraceWriter(TraceLevel.Info, telemetryClient));
// Detect when the webjob shut down
var cancellationToken = new WebJobsShutdownWatcher().Token;
cancellationToken.Register(() =>
{
// Before shut down, flush the app insights client.
telemetryClient.Flush();
});
new JobHost(config).RunAndBlock();
So if you have a function like that:
public static void ProcessQueueMessage([QueueTrigger("myqueue")] string logMessage, TextWriter log)
{
log.WriteLine(logMessage);
}
Every time you use log.WriteLine, an event will be sent to App Insights.
Note: if this sample also logs from the JobHost are sent to AppInsights.
This is super old (not sure why SO decided to put it in the sidebar for me after this long) but for anyone else that stumbles upon this, app insights is now the recommended way to monitor webjob executions.
Check out the documentation here which steps through the process of connecting app insights to webjobs.
This link walks you through configuring the logging portion of a new webjobs project. Check through the earlier sections to make sure that you've got all the prerequisites.
https://learn.microsoft.com/en-us/azure/app-service/webjobs-sdk-get-started#add-application-insights-logging
static async Task Main()
{
var builder = new HostBuilder();
builder.UseEnvironment(EnvironmentName.Development);
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
b.AddAzureStorage();
});
builder.ConfigureLogging((context, b) =>
{
b.AddConsole();
// If the key exists in settings, use it to enable Application Insights.
string instrumentationKey = context.Configuration["APPINSIGHTS_INSTRUMENTATIONKEY"];
if (!string.IsNullOrEmpty(instrumentationKey))
{
b.AddApplicationInsightsWebJobs(o => o.InstrumentationKey = instrumentationKey);
}
});
var host = builder.Build();
using (host)
{
await host.RunAsync();
}
}
I will share the detailed steps to use Application Insights in Azure Web Job, please refer to it.
Create an new Azure Application Insights in Azure portal
Create Azure Web Job project in Visual Studio and install
Microsoft.ApplicationInsights
Set the instrumentation key and send
telemetry
public static void ProcessQueueMessage([QueueTrigger("queuename")] string message, TextWriter log)
{
TelemetryClient tc = new TelemetryClient();
tc.InstrumentationKey = "key copied from Azure portal";
tc.TrackTrace(message);
tc.Flush();
//log.WriteLine(message);
}
This documentation explained how to monitor usage and performance in Windows Desktop apps, you could refer to it to know how to use Azure Application Insights in non-web application. Besides, ApplicationInsights.Helpers.WebJobs could be also helpful.

Resources