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

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.

Related

Get Azure Configuration value for Blazor

I am trying to pull appsetting.json settings (In Blazor Server app) when I run my code locally and have the settings be pulled from Azure's Configuration when it is running on Azure. But, my code will pull from appsettings.json even if it is live. I pull these values for my Startup.cs file, like this:
options.Authority = Configuration.GetValue<string>("AuthenticationServer:IDAuthority");
options.ClientId = Configuration.GetValue<string>("AuthenticationServer:IDClientID");
options.CallbackPath = Configuration.GetValue<string>("AuthenticationServer:IDRedirectURI");
In my appsetting.json file, I have the settings stored like this:
{
"AuthenticationServer": {
"IDAuthority": "Some Value",
"IDClientID": "Another Value",
"IDRedirectURI": "/Index/"
},
}
And in Azure App Service, under Settings->Configuration, in the Application Settings Tab, I have three key/value pairs:
"IDAuthority" - "New Value"
"IDClientID" - "Another New Value"
"IDRedirectURI" - "/Index/"
But when I do this, the values still get pulled from appsettings.json and not Azure. I've also tried:
"AuthenticationServer_IDAuthority" - "New Value"
"AuthenticationServer_IDClientID" - "Another New Value"
"AuthenticationServer_IDRedirectURI" - "/Index/"
And get the same results. So, how should I pull these values from Azure?
As an aside, getting the Azure db connection string like this, works fine:
services.AddDbContext<DBContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("ConnString")));
I think you can only change the code before publish it to AZURE.
Firstly we need to know when we want to read the value stored in azure app configuration, we need to make your application connect to Azure app configuration and then we can get what we set, and we can get value with the key name. And the opreation should be the same as getting value from appsettings.json, here's my code:
var builder = WebApplication.CreateBuilder(args);
ConfigurationManager configuration = builder.Configuration;
var connectionString = "connection_string_of_app_configuration";
builder.Host.ConfigureAppConfiguration(builder =>
{
//Connect to your App Config Store using the connection string
builder.AddAzureAppConfiguration(connectionString);
});
var a = configuration["Logging:LogLevel:Default"];//get log setting in appsetting.json
var c = configuration["Logging:LogLevel:Default"];//also set the same key in azure
var b = configuration["TestApp:Settings:Message"];//get from app configuration
So I think you may comment the code connect to Azure app configuration when you want to read configuration in appsettings.json, and un-comment the code before you want to publish to azure.
Seems to be a naming convention issue. Because my values were nested in my appsettings.json file, I had to make sure the depth of the parameter was included in the Azure setting.
To get the value:
options.Authority = Configuration["AuthenticationServer:IDAuthority"];
and I then had to make sure the configuration setting, in Azure, was titled: "AuthenticationServer:IDAuthority"

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 create azure batch pool based on custom VM image using java sdk

I want to use custom ubuntu VM image that I had created for by batch job. I can create a new pool by selecting the custom image from the azure portal itself but I wanted to write build script to do the same using the azure batch java sdk. This is what I was able to come up with:
List<NodeAgentSku> skus = client.accountOperations().listNodeAgentSkus().findAll({ it.osType() == OSType.LINUX })
String skuId = null
ImageReference imageRef = new ImageReference().withVirtualMachineImageId('/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.Compute/images/$CUSTOM_VM_IMAGE_NAME')
for (NodeAgentSku sku : skus) {
for (ImageReference imgRef : sku.verifiedImageReferences()) {
if (imgRef.publisher().equalsIgnoreCase(osPublisher) && imgRef.offer().equalsIgnoreCase(osOffer) && imgRef.sku() == '18.04-LTS') {
skuId = sku.id()
break
}
}
}
VirtualMachineConfiguration configuration = new VirtualMachineConfiguration()
configuration.withNodeAgentSKUId(skuId).withImageReference(imageRef)
client.poolOperations().createPool(poolId, poolVMSize, configuration, poolVMCount)
But I am getting exception:
Caused by: com.microsoft.azure.batch.protocol.models.BatchErrorException: Status code 403, {
"odata.metadata":"https://analyticsbatch.eastus.batch.azure.com/$metadata#Microsoft.Azure.Batch.Protocol.Entities.Container.errors/#Element","code":"AuthenticationFailed","message":{
"lang":"en-US","value":"Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.\nRequestId:bf9bf7fd-2ef5-497b-867c-858d081137e6\nTime:2019-04-17T23:08:17.7144177Z"
},"values":[
{
"key":"AuthenticationErrorDetail","value":"The specified type of authentication SharedKey is not allowed when external resources of type Compute are linked."
}
]
}
I definitely think the way I am getting the skuId is wrong. Since client.accountOperations().listNodeAgentSkus() does not list the custom image, I just thought of giving skuId based of the ubuntu version that I had used to create the custom image.
So what is the correct way to create pool using custom VM image for azure batch account using java sdk?
You must use Azure Active Directory credentials in order to create a pool with a custom image. It is in the prerequisites section of the Batch Custom Image doc.
This is a frequently asked question:
Custom Image under AzureBatch ImageReference class not working
Azure Batch Pool: How do I use a custom VM Image via Python?
Just shows as the error, you need to authenticate to Azure first and then you could create the pool with a custom image as you want.
First, you need an Azure Batch Account, you can create it in the Azure portal or using Azure CLI. Or you also can create the batch account through Java. See Manage the Azure Batch Account through Java.
Then I think you also need to authenticate to your batch account. There are two ways below:
Use the account name, key, and URL to create a BatchSharedKeyCredentials instance for authentication with the Azure Batch service. The BatchClient class is the simplest entry point for creating and interacting with Azure Batch objects.
BatchSharedKeyCredentials cred = new BatchSharedKeyCredentials(batchUri, batchAccount, batchKey);
BatchClient client = BatchClient.open(cred);
The other way is using AAD (Azure Active Directory) authentication to create the client. See this document for detail.
BatchApplicationTokenCredentials cred = new BatchApplicationTokenCredentials(batchEndpoint, clientId, applicationSecret, applicationDomain, null, null);
BatchClient client = BatchClient.open(cred);
Then you can create the pool with the custom as you want. Just like this:
System.out.println("Created a pool using an Azure Marketplace image.");
VirtualMachineConfiguration configuration = new VirtualMachineConfiguration();
configuration.withNodeAgentSKUId(skuId).withImageReference(imageRef);
client.poolOperations().createPool(poolId, poolVMSize, configuration, poolVMCount);
System.out.println("Created a Pool: " + poolId);
For more details, see Azure Batch Libraries for Java.

Single Azure Function to Trigger when upload a file in blob then insert the blob name in Azure SQL

I'm just new to Azure Function ,I just gone through the TimerTrigger for Sql Connection and BlobTrigger for Azure Blob.I tired with the demo works fine for me.
Next i tried to do with combination of both this.
When a file uploaded/Added in the Specific Blob Container.I should write the blob name in my Azure SQL Database table.
How could i achieve this in a Single Azure function ?
Also i'm having a doubt that if we create a azure function for a blob trigger,then this function will always be running in the background ? I mean it will consume the Background running cost ?
I'm thinking that azure function for a blob trigger will consume the cost only
during it's run. Isn't it ?
Could somebody help me with this
How could i achieve this in a Single Azure function ?
You could achieve it using blob trigger. You will get blob name from the function parameter [name]. Then you could save this value to your Azure SQL database. Sample code below is for your reference.
public static void Run(Stream myBlob, string name, TraceWriter log)
{
var str = "connection string of your sql server";
using (SqlConnection conn = new SqlConnection(str))
{
conn.Open();
var text = "insert into mytable(id, blobname) values(#id, #blobname)";
using (SqlCommand cmd = new SqlCommand(text, conn))
{
cmd.Parameters.AddWithValue("id", 1);
cmd.Parameters.AddWithValue("blobname", name);
// Execute the command and log the # rows affected.
var rows = cmd.ExecuteNonQuery();
log.Info($"{rows} rows were updated");
}
}
}
I'm thinking that azure function for a blob trigger will consume the cost only during it's run. Isn't it?
You will need to choose hosting plan when creating an Azure function.
If you choose App Service Plan, you will need to pay for the App Service Plan which is depends on the tier you chosen. If you choose Consumption plan, your function is billed based on two things. Resource consumption and executions.
Resource consumption is calculated by multiplying average memory size in Gigabytes by the time in seconds it takes to execute the function. You need to pay for the CPU and Memory consumed by your function. Executions means the requests count which are handled by your function. Please note that Consumption plan pricing also includes a monthly free grant of 1 million requests and 400,000 GB-s of resource consumption per month.
We can also call the Sp (like Exec spname) in the place of Insert Command?Right ?
Yes, we could call the sp by setting CommandType to StoredProcedure. Code below is for your reference.
using (SqlCommand cmd = new SqlCommand("StoredProcedure Name", conn))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
}
Sure, you should use Blob Trigger for your scenario.
If you use Consumption Plan, you will only be changed per event execution. No background cost will apply.

run a WebJob from Asp.Net MVC azure website

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();

Resources