Dynamically create Functions Apps

Jona 660 Reputation points
2023-12-09T04:27:40.7733333+00:00

Hi every one

I have a requirement to create several Event hubs (inside the same namespace). Each Event Hubs will be fed by a Function App. So the sequence is as follows:

  1. A Blob is uploaded to a container
  2. A Blob-triggered Function is executed (evety Function will be listening a specific path)
  3. The output of the Functions is one or more message to a Event Hub

Most of the Function Apps will perform the same code execution to send the messages to the corresponding Event Hub. So, I've created the following Function App:

const { app, output } = require('@azure/functions');
const csv = require('csvtojson');
const { v4: uuidv4 } = require('uuid');

const eventHubOutput = output.eventHub({
    eventHubName: 'mut-admin-detalle-tabla-dividendo',
    connection: 'EventHubConnection',
});

app.storageBlob('mut-admin-detalle-tabla-dividendo', {
    path: 'landing/mut-admin-detalle-tabla-dividendo/{name}',
    connection: 'StorageConnection',
    return : eventHubOutput,
    handler: async (blob, context) => {
        context.log(`Storage blob function processed blob "${context.triggerMetadata.name}" with size ${blob.length} bytes`);
        const stringBlob = blob.toString("utf8");
        const batchId = uuidv4().toString();
        const landedTimestamp = new Date();
        const blobUri = context.triggerMetadata.uri;
        const jsonBlob = await csv({'delimiter': '|'})
                                .fromString(stringBlob)
                                .subscribe((json => {
                                    return new Promise((resolve, reject) => {
                                        try {
                                            json['batch_id'] = batchId;
                                            json['message_id'] = uuidv4().toString();
                                            json['landed_out_dateTime'] = landedTimestamp;
                                            json['blob_uri'] = blobUri
                                            resolve();
                                        } catch(e) {
                                            reject(e);
                                        }
                                    })
                                }));

        context.log(`Sending ${jsonBlob.length} messages to Event Hubs`)
        return jsonBlob;
    }
});

So, in order to create these several Function Apps, I was wondering if I could write the following code, instead of creating differents files per Function (even though I encapsulated the shared logic and called after):

const { app, output } = require('@azure/functions');
const csv = require('csvtojson');
const { v4: uuidv4 } = require('uuid');

// An example of config. This should be specified in local.settings.json
const configs = [ {}, {}. ... ]

for (const config in configs) {
    const eventHubOutput = output.eventHub({
        eventHubName: config['eventHubName'], // 1
        connection: config['EventHubConnection'], // 2
    });

    app.storageBlob(config['functionName'], { // 3
        path: config['path'], // 4
        connection: config['StorageConnection'], // 4
        return : eventHubOutput,
        handler: async (blob, context) => {
            context.log(`Storage blob function processed blob "${context.triggerMetadata.name}" with size ${blob.length} bytes`);
            const stringBlob = blob.toString("utf8");
            const batchId = uuidv4().toString();
            const landedTimestamp = new Date();
            const blobUri = context.triggerMetadata.uri;
            const jsonBlob = await csv({'delimiter': '|'})
                                    .fromString(stringBlob)
                                    .subscribe((json => {
                                        return new Promise((resolve, reject) => {
                                            try {
                                                json['batch_id'] = batchId;
                                                json['message_id'] = uuidv4().toString();
                                                json['landed_out_dateTime'] = landedTimestamp;
                                                json['blob_uri'] = blobUri
                                                resolve();
                                            } catch(e) {
                                                reject(e);
                                            }
                                        })
                                    }));

            context.log(`Sending ${jsonBlob.length} messages to Event Hubs`)
            return jsonBlob;
        }
    });
}

  • Is this a valid approach??
  • The name of the Function is not tied to the name of file inside de src/ folder, but the parameter, right?
app.storageBlob()

Regards

Jonathan

Azure Functions
Azure Functions
An Azure service that provides an event-driven serverless compute platform.
5,916 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Jona 660 Reputation points
    2023-12-18T15:13:27.1733333+00:00

    Actually, your answer did not help quite much. I could success finally, with the following code, and it works like a charm.

    const { app, output } = require('@azure/functions');
    const { functionHandler } = require('./includes')
    
    const availableTables = [
        "direccion",
        "detalle-tabla-dividendo",
        "estado",
        "mutuo-cia",
        "tabla-dividendo"
    ];
    
    for (const table of availableTables) {
    
        // Output to Event Hubs
        const eventHubOutput = output.eventHub({
            eventHubName: table,
            connection: `EventHubConnection.${table}`,
        });
    
        // Listening to Blob Storage
        app.storageBlob(table, {
            path: process.env[`StoragePath.${table}`],
            connection: `StorageConnection.${table}`,
            return : eventHubOutput,
            source: 'EventGrid',
            handler: functionHandler
        });
    }
    

    I hope this can help others. And, as MSFT recommends I decided to use EventGrid as source/engine of event detection to fire Functions.

    regards

    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.