Generic Azure Functions - Dynamic Connections - azure

I want to create and host a azure function that would take as input "azure-storage-account-name" and "path" and run some common logic and then return a list of processed blobs in that storage account at that path. I have 20 storage accounts and I was thinking to write single azure function in same subscription to have listing capability across all of them
I went through Azure function documentation couldn't figure out if this is even possible in current offering. Any pointers would be helpful

You can use Imperative Bindings feature of Azure Functions. This is a sample code:
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, Binder binder, TraceWriter log)
{
var attributes = new Attribute[]
{
new StorageAccountAttribute("your account"),
new BlobAttribute("your folder name")
};
var directory = await binder.BindAsync<CloudBlobDirectory>(attributes);
log.Info(directory.ListBlobs().Count().ToString());
return new HttpResponseMessage(HttpStatusCode.OK);
}

If you have the correct credentials, you can use the Azure Storage REST API to get a list of containers

Related

Azure blob triggered function only triggering on some blobs

I have two blob triggers which I want to trigger on. One works and one does not!
I use Azure Storage Explorer to make sure blobs are uploaded to each blob, scanFiles will never trigger, and scanExports seem to always trigger.
Question: What can cause some blobs to not trigger an Azure function?
[FunctionName("scanFiles")]
public static async Task FilesScan([BlobTrigger("files/{newBlobName}", Connection = "BlobConnectionstring")]CloudBlockBlob newBlob, string newBlobName, ILogger log, ExecutionContext context)
{
await VirusScan(newBlob, newBlobName, log, context);
}
[FunctionName("scanExports")]
public static async Task ExportsScan([BlobTrigger("exports/{newBlobName}", Connection = "BlobConnectionstring")]CloudBlockBlob newBlob, string newBlobName, ILogger log, ExecutionContext context)
{
await VirusScan(newBlob, newBlobName, log, context);
}
I found that the issue was because one of the blobs were considered High scale, which triggers this bug and also makes the host process kill itself when run locally (see this issue)

Reference file from Azure function 2.0 with .net core

I am trying to create an Azure function that reads from a .mmdb file GeoLite2 Country DB
I have added the geolite2 file next to my function. But I cannot find a way programmatically to reference the file path such that it remains the same on my local machine as well as deployed/published.
string GeoLocationDbPath = "D:<path_to_project>\Functions\GeoLocation-Country.mmdb"
var reader = new DatabaseReader($"{GeoLocationDbPath}");
I came across this article How to add assembly references to an Azure Function App
I was hoping there was a better way to reference a file both locally and deployed.
Any ideas?
Other links I've looked at:
How to add and reference a external file in Azure Function
How to add a reference to an Azure Function C# project?
Retrieving information about the currently running function
Azure functions – Read file and use SendGrid to send an email
You can get the path to folder by injecting ExecutionContext to your function:
public static HttpResponseMessage Run(HttpRequestMessage req, ExecutionContext context)
{
var funcPath = context.FunctionDirectory; // e.g. d:\home\site\wwwroot\HttpTrigger1
var appPath = context.FunctionAppDirectory; // e.g. d:\home\site\wwwroot
// ...
}
I've come to the conclusion that referencing files local to the Azure function was not a good approach. I read the Azure functions best practices and Azure functions are meant to be stateless. Also, folder structure changes when you deploy.
If I were to continue I would upload the .mmdb file to a Azure blob container and use the CloudStorageAccount to access the file.

Azure Blob Storage - Send List of image names and get List of images

I am facing a problem. I have to implement a solution to load multiple images from Azure Blob Storage in Xamarin.Forms app.
I would like to know how to send List of image names and get List of images back from Azure Blob Storage Account.
Thank you !
Azure Blob doesn't have a strong query\search story. If you know the container you could always iterate through the blobs in that container but this is going to be very inefficient and less then ideal. You can also use Azure Search to index blob storage (and it's contents) but I find that overkill for your use case.
My suggestion is to store a reference to the blob in a searchable data source. If you already have a data source in place for your app (such as SQL) I would use that.
One inexpensive way to get this into your data source to query later is to use an Azure Function or Logic App to trigger when a new blob is created and store the data you need to later find it (e.g. the filename) along with the blob reference. Table storage is a very inexpensive method or you can use any data store you like. You can then host an API endpoint in Azure Functions (or your host of choice) where your Xamarin app can pass in the filenames and get the results back.
With Azure Functions the code for a a blob trigger that writes to table storage is pretty minimal and would follow something like the pattern below:
public static void Run(
[BlobTrigger("mycollection/{name}")] BlobProperties blobProperties,
[Table("blobdata")]IAsyncCollector<MyBlobDataPoco> tableData,
string name, TraceWriter log)
{
var myData = new MyBlobDataPoco() { Filename = name, Container= "mycollection" };
tableData.AddAsync(myData);
}

Is there a way to change the Azure function trigger type programmatically.

Looks like function.json in your Azure function's zip file defines Az func's trigger. Is it possible to change the trigger from Timer based to Event based programatically? Meaning, can I have a python application running perhaps in my local computer which calls Azure python sdk and says hey, change the Azure Function x's trigger from timer based to event hub based trigger and here is the additional event hub namespace name and connection string information that you need.
This is not possible.
However, I can think of the following workaround, which should accomplish the goal.
First, you can define multiple function triggers within one function project (one function app service). They could be bound to different targets. Something like this:
public static class Functions
{
[FunctionName("FunctionTimer")]
public static async Task RunAsync([TimerTrigger("%Schedule%")]TimerInfo myTimer, ILogger log)
{
if (!AppSettings.IsTimerTriggerActive)
return;
...
}
[FunctionName("FunctionEventHub")]
public static async Task RunAsync([EventHubTrigger("", Connection = "eventHubConnectionString")] EventData[] eventDataBatch, ILogger log)
{
if (!AppSettings.IsEventHubTriggerActive)
return;
...
}
}
You cannot enable/disable a function programmatically, but you can control which one of these is active via the App Service Application Settings. The latter could be managed through the Web App API: https://learn.microsoft.com/en-us/rest/api/appservice/webapps/updateapplicationsettings
Thus you can activate either trigger. One can even skip the (de)activation if that's compatible with the logic.

Azure Blob Storage - Set an alert when a new file is uploaded to a specific folder in a blob container

In Azure, I have a Storage Account that I use to upload files from an IoT device. The files are sent when the IoT device detects certain conditions. All the files are uploaded to the same Blob Container and in the same folder (inside the Blob container).
What I would like to do is to send an email automatically (as an alert) when a new file is uploaded to the Blob Container. I have checked the different options that are provided by Azure to set alerts in Storage accounts (in Azure Portal) but I have not found anything useful.
How could I create this kind of alert?
As far as I know, the azure provides the azure function or webjobs which could be triggered when the new files uploaded to the special container.
I suggest you could use azure function blob trigger to achieve your requirement.
More details, you could refer to this article.
In the azure function blob trigger fired method you could also bind sendgrid to send the email.
More details, you could refer to below steps:
Notice: I used C# azure function as example, you could also use another language.
1.Create a blob trigger azure function.
2.Create a sendgrid(Link) account and create API key.
3.Create set the created azure function sendgrid outbind.
4.Add below codes to azure function run.csx.
#r "SendGrid"
using System;
using SendGrid;
using SendGrid.Helpers.Mail;
public static Mail Run(Stream myBlob, string name, TraceWriter log)
{
var message = new Mail
{
Subject = "Azure news"
};
var personalization = new Personalization();
personalization.AddTo(new Email("sendto email address"));
Content content = new Content
{
Type = "text/plain",
Value = name
};
message.AddContent(content);
message.AddPersonalization(personalization);
return message;
}

Resources