Intermittent Trigger Issues with Event Grid for Blob Upload and Deletion in Azure Function

  Kiến thức lập trình

I am using an Event Grid subscription to trigger an Azure Function for handling blob uploads and deletions in Azure Blob Storage. However, I’m encountering intermittent issues with the triggers not firing consistently.

Setup:

Storage Account (Event Grid)

Event Grid Subscription subscribed to Microsoft.Storage.BlobCreated and Microsoft.Storage.BlobDeleted events.

Azure Function Event Grid Trigger

Issue: The problem is that the Event Grid trigger is not firing every time a blob is uploaded or deleted. When the trigger does fire, both the upload and delete actions work correctly. However, the trigger itself is inconsistent.

Steps Taken:

Subscribed to both Microsoft.Storage.BlobCreated and Microsoft.Storage.BlobDeleted events.

Implemented function code to handle different event types and execute the necessary business logic.

Despite this setup, the triggers do not consistently fire for every blob upload or deletion event.

Request for Help: Could someone help me troubleshoot and resolve these intermittent issues with the Event Grid triggers for blob uploads and deletions? Any insights or guidance would be greatly appreciated.

Thank you!
enter image description here
enter image description here

const { app } = require('@azure/functions');

const { BlobServiceClient, StorageSharedKeyCredential } = require('@azure/storage-blob');

const { SearchClient, AzureKeyCredential } = require('@azure/search-documents');

const pdf = require('pdf-parse');

const path = require('path');

// Azure Blob Storage configuration

const accountName = "";

const accountKey = "";

const containerName = 'content';

// Azure Cognitive Search configuration

const searchServiceName = "";

const indexName = "demoindex2";

const apiKey = "";

const blobServiceClient = new BlobServiceClient(

    `https://${accountName}.blob.core.windows.net`,

    new StorageSharedKeyCredential(accountName, accountKey)

);

const containerClient = blobServiceClient.getContainerClient(containerName);

const searchClient = new SearchClient(

    `https://${searchServiceName}.search.windows.net/`,

    indexName,

    new AzureKeyCredential(apiKey)

);

async function indexBlob(blobName) {

    try {

        const blobClient = containerClient.getBlobClient(blobName);

        const downloadResponse = await blobClient.download();

        const encodedName = Buffer.from(blobName).toString('base64');

        const properties = await blobClient.getProperties();

        const pdfBuffer = await streamToBuffer(downloadResponse.readableStreamBody);

        const pdfText = await pdf(pdfBuffer);

        const blobContent = pdfText.text;

        const document = {

            id: encodedName,

            content: blobContent,

            metadata_storage_content_type: properties.contentType || null,

            metadata_storage_size: properties.contentLength || null,

            metadata_storage_last_modified: properties.lastModified ? new Date(properties.lastModified).toISOString() : null,

            metadata_storage_content_md5: properties.contentMD5 ? Buffer.from(properties.contentMD5).toString('base64') : null,

            metadata_storage_name: blobName,

            metadata_storage_path: blobClient.url,

            metadata_storage_file_extension: path.extname(blobName),

            metadata_content_type: properties.contentType || null,

            metadata_language: null,

            metadata_author: null,

            metadata_creation_date: properties.creationTime ? new Date(properties.creationTime).toISOString() : null,

        };

        await searchClient.uploadDocuments([document]);

        console.log(`Document "${document.id}" has been indexed`);

    } catch (error) {

        console.error(`Error indexing document: ${error}`);

    }

}

async function deleteDocument(blobName) {

    try {

        const encodedName = Buffer.from(blobName).toString('base64');

        await searchClient.deleteDocuments([{ id: encodedName }]);

        console.log(`Document "${encodedName}" has been deleted from the index`);

    } catch (error) {

        console.error(`Error deleting document from the index: ${error}`);

    }

}

app.eventGrid('process-event-grid', {

    handler: async (context, eventGridEvent) => {

        try {

            const event = eventGridEvent.eventType;

            const blobUrl = eventGridEvent.data?.url;

            

            if (!blobUrl) {

                console.error("Event data does not contain 'url':", eventGridEvent);

                return;

            }

            

            const blobName = blobUrl.substring(blobUrl.lastIndexOf('/') + 1);

            if (event === 'Microsoft.Storage.BlobCreated') {

                console.log(`Blob created: ${blobName}`);

                await indexBlob(blobName);

            } else if (event === 'Microsoft.Storage.BlobDeleted') {

                console.log(`Blob deleted: ${blobName}`);

                await deleteDocument(blobName);

            } else {

                console.log(`Unhandled event type: ${event}`);

            }

        } catch (error) {

            console.error(`Error processing event: ${error}`, eventGridEvent);

        }

    }

});

async function streamToBuffer(readableStream) {

    return new Promise((resolve, reject) => {

        const chunks = [];

        readableStream.on("data", (data) => {

            chunks.push(data instanceof Buffer ? data : Buffer.from(data));

        });

        readableStream.on("end", () => {

            resolve(Buffer.concat(chunks));

        });

        readableStream.on("error", reject);

    });

}

New contributor

Su Myat is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

LEAVE A COMMENT