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!
![User's image](https://learn-attachment.microsoft.com/api/attachments/34d887db-4d21-4f00-8588-c287c15ee464?platform=QnA)
![User's image](https://learn-attachment.microsoft.com/api/attachments/5a6e88c3-d416-4dca-ac0e-802f0ef2211c?platform=QnA)
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);
});
}