Azure Event Grid events for channel deliveries
Many pipelines react to files arriving in Azure Storage by subscribing to
the Microsoft.Storage.BlobCreated event - directly through an Event Grid
subscription, or indirectly through Azure Data Factory storage event
triggers, Databricks Auto Loader in file notification mode, or Snowflake
Snowpipe auto-ingest. Which events your account emits, and when, depends on
whether the storage account has hierarchical namespace (Data Lake
Storage Gen2) enabled.
This guide covers files delivered by a channel's Azure Blob Storage destination. There is a companion guide for files written by a Simple FTP Service with an Azure backend - the event behaviour is the same, because both write the way Azure's own tooling expects.
You always pick the one Azure Blob Storage destination when building the channel - DocEvent detects whether the target account has hierarchical namespace enabled and delivers through the right API automatically. Nothing in the endpoint configuration selects this; it follows from the storage account itself.
Flat namespace accounts - one event per delivery
On a storage account without hierarchical namespace, the channel delivers
through the Blob API and commits the file with a single block-list commit.
Azure emits one BlobCreated event, at commit time, with data.api
set to PutBlockList. When you receive it, the file is complete - there is
nothing to filter.
Data Lake Storage Gen2 accounts - two events per delivery
On an account with hierarchical namespace enabled, the channel delivers
through the Data Lake (DFS) API: the file is created, data is appended, and
the file is finally flushed with close to mark it complete. Azure Event
Grid only announces two of those stages -
CreateFile and FlushWithClose -
so one completed delivery produces two BlobCreated events:
data.api: "CreateFile"- the file now exists in the namespace, with zero bytes of contentdata.api: "FlushWithClose"- the delivery is complete and the content is final
The CreateFile event cannot be suppressed - file creation is a namespace
operation on Data Lake Storage, and Azure always announces it. The
two-event pattern is the ecosystem convention: it is what the Spark/Hadoop
ABFS driver used by Databricks, Synapse and Fabric produces too.
Act only on FlushWithClose
If your subscriber must only see completed files, filter on data.api.
This is Microsoft's own recommendation, and the managed integrations
already follow it: Data Factory storage event triggers, Auto Loader file
notification mode and Snowpipe auto-ingest all ignore CreateFile and act
on FlushWithClose.
For your own Event Grid subscription, add an advanced filter on
data.api. Including the Blob API commit values as well makes one filter
correct for both account kinds - and for files written to the same
container by other tools:
"advancedFilters": [
{
"operatorType": "StringIn",
"key": "data.api",
"values": ["FlushWithClose", "PutBlockList", "PutBlob"]
}
]
With this filter in place, every event you receive represents a file whose content is complete.
Interrupted deliveries never fire your trigger
This filtering also protects you from partial files. If a delivery is
interrupted - a network failure mid-transfer, for example - no
FlushWithClose (or PutBlockList) event fires for it: on a Data Lake
account the only trace is the zero-byte CreateFile, and on a flat account
nothing appears at all. The channel retries the delivery, and your
subscriber fires exactly once, when a complete file is finally in place.
A consumer that filters on the completion events therefore never processes
a half-delivered file.
If delivered files never trigger downstream processing
If files land in your container but a FlushWithClose-filtered consumer
never fires, first check the account kind - on a flat account the
completion event is PutBlockList, so a filter listing only
FlushWithClose matches nothing there. The combined filter above covers
both. For the broader missing-close trap with other writers in your
pipeline, see the
companion guide.