Gridwich request-response messages

Azure Logic Apps
Azure Storage

This article details the specific Event Grid events that form the request-response sequence for different Gridwich operations.

Gridwich events

Gridwich Acknowledgment and Gridwich Failure are different from other Gridwich events. Specifically:

  • Gridwich Acknowledgment (ACK) indicates that Gridwich has received, but not necessarily processed, the request in a Request-ACK-Response sequence.
  • Each operation has one or more unique Success response events, but almost all operations use the same Gridwich Failure event to communicate failure.

Encoding events

Blob and container storage events

Storage keys

Operation context

Gridwich accepts a JSON operationContext object as part of request messages. In general, Gridwich echoes a corresponding object in response messages and isn't concerned with the specific internal structure or content of the context object.

The exception is that the response context object may have extra JSON properties compared to the request equivalent. These extra properties are internal to Gridwich, and their names always start with the tilde ~ character. The request properties are always present on the response context object.

As in normal JSON, the response object properties may appear in a different order than in the request object.

For more information about operation context, see Operation context in the Gridwich Architecture article.

Event Grid messages

For more information about request-response message flow, see the architecture request flow.

In the following event descriptions, the JSON property values are the usual string, number, or boolean types. The descriptions use the following specific string content types. If the description includes "opaque," the content and format of the value are arbitrary.

  • GUID-string, like "b621f33d-d01e-0002-7ae5-4008f006664e" is a 16-byte ID value spelled out to 36 characters (32 hex digits, plus 4 dashes). Note the lack of curly braces. The value is case-insensitive. This format corresponds to the result of System.GUID.ToString("D").
  • Topic-string, like "/subscriptions/5edeadbe-ef64-4022-a3aa-133bfef1d7a2/resourceGroups/gws-shared-rg-sb/providers/Microsoft.EventGrid/topics/gws-gws-egt-sb", is a string of opaque content.
  • Subject-string, like "/blobServices/default/containers/telestreamoutput/blobs/db08122195b66be71db9e54ae04c58df/503220533TAGHD23976fps16x990266772067587.mxf", is a string of opaque content.
  • EventType-string, like "request.operation.requested" is generally a string of the form: {"request"|"response"}.operation[.qualifier].
  • DataVersion-string, like "1.0", is a versioning indicator that message processors use to distinguish different evolutions of the same operation. Gridwich requires this field. The HandlesEvent method determines which versions an individual Event Grid Handler can process.
  • URL-string is an absolute URL that often points to Application Insights logs. These strings are usually a SAS URL, due to target authorization requirements.
  • StorageURL-string is an absolute URL that often points to an Azure Storage Blob or container. This string isn't usually a SAS URL.
  • StorageURL-SAS-string is an absolute SAS URL that often points to an Azure Storage Blob or container.
  • OperationContextObject, like { "prodID": 10, "dc": "abc" }, is an arbitrary JSON object that is accepted on incoming requests and echoed back as part of Gridwich response events.
  • Metadata-Dictionary is a string-to-string JSON object dictionary with the name-value pairs representing Azure Storage Blob metadata.
  • Encoder-Context is an opaque JSON object of properties specific to a particular encoder.

Gridwich generic ACK response

Gridwich > Requester, uses ResponseAcknowledgeDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "eventType": "request.blob.metadata.create"
    },
    "eventType": "response.acknowledge"
}

The data.eventType string value is the top level eventType property from the Request event. For example, for a blob analysis request, the data.eventType string value isrequest.blob.analysis.create.

Gridwich generic Failure response

Gridwich > Requester, uses ResponseFailureDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "logEventId": 30001,
        "logEventMessage": "the message text for eventId 30001",
        "logRecordId": "GUID-string",
        "logRecordUrl": "URL-string", // AppInsight URL to the logRecordId
        "eventHandlerClassName": "string",
        "handlerId": "GUID-string"
    },
    "eventType": "response.failure"
}

The Failure event doesn't include the original request eventType value, but does include the operation context and the handler name that was processing the request. The log* properties relate to the problem information that the configured Application Insights instance recorded.

For a limited set of operations, the Failure event object differs significantly from the preceding message. For more information, see Roll storage keys.

Requester asks Gridwich to place some metadata onto a blob

Requester > Gridwich uses RequestBlobMetadataCreateDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "blobUri": "StorageURL-string",
        "blobMetadata": <Metadata-Dictionary>
    },
    "eventType": "request.blob.metadata.create"
}

The blobMetadata is an object of string-valued properties representing all of the name-value pairs of the desired blob metadata.

Gridwich > Requester uses ResponseBlobMetadataSuccessDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "blobUri": "StorageURL-string",
        "blobMetadata": <Metadata-Dictionary>
    },
    "eventType": "response.blob.metadata.success"
}

To later retrieve the current metadata for a blob, see the Analyze blob request.

Requester asks Gridwich to perform an analysis of a blob via MediaInfo

Requester > Gridwich uses RequestBlobAnalysisCreateDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "blobUri": "StorageURL-string",
        "analyzerSpecificData": {
            "mediaInfo": {
                  "commandLineOptions": {
                    "Complete": "1",
                    "Output": "JSON"
                  }
            }
        }
    },
    "eventType": "request.blob.analysis.create"
}

Gridwich > Requester uses ResponseBlobAnalysisSuccessDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "blobUri": "StorageURL-string",
        "blobMetadata": <Metadata-Dictionary>,
        "analysisResults": <Analysis-Result-Object>
    },
    "eventType": "response.blob.analysis.success"
}

The analysisResults object's content isn't specified. In the current project, it's the MediaInfo output.

The blobMetadata value is a string > string dictionary.object of string-valued properties representing all of the name-value pairs of the specified blob's metadata.

As usual with Azure Storage, metadata item names must conform to C# identifier naming rules. For more information, see the Azure SetBlobMetadata REST API and the C# naming rules.

Requester asks Gridwich to copy a blob to a new destination

Requester > Gridwich uses RequestBlobCopyDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "sourceUri": "StorageURL-string",
        "destinationUri": "StorageURL-string"
    },
    "eventType": "request.blob.copy"
}

Gridwich > Requester uses ResponseBlobCopyScheduledDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "sourceUri": "URL-string",
        "blobMetadata": <Metadata-Dictionary>,
        "destinationUri": "StorageURL-string"
    },
    "eventType": "response.blob.copy.scheduled"
}

Gridwich tells requester that it created a blob

Gridwich could have created the blob from any source, like a copy result, inbox arrival, or encode result.

Gridwich > Requester, uses ResponseBlobCreatedSuccessDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "blobUri": "StorageURL-string",
        "blobMetadata": <Metadata-Dictionary>
    },
    "eventType": "response.blob.created.success"
}

Requester asks Gridwich to delete a blob

Requester > Gridwich uses RequestBlobDeleteDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "blobUri": "StorageURL-string",
    },
    "eventType": "request.blob.delete"
}

Gridwich > Requester uses ResponseBlobDeleteScheduledDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "blobUri": "StorageURL-string",
        "blobMetadata": <Metadata-Dictionary>
    },
    "eventType": "response.blob.delete.scheduled"
}

Gridwich informs requester that it deleted a blob

The blob deletion can come from any source, like an explicit request from a requester or a result of internal operations.

Gridwich > Requester, uses ResponseBlobDeleteSuccessDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "blobUri": "StorageURL-string"
    },
    "eventType": "response.blob.delete.success"
}

Requester asks Gridwich to return a time-expiration content SAS URL

Requester > Gridwich uses RequestBlobSasUrlCreateDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "blobUri": "StorageURL-string",
        "secToLive": 1200
    },
    "eventType": "request.blob.sas-url.create"
}

Gridwich > Requester uses ResponseBlobSasUrlSuccessDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "sasUrl": "StorageURL-SAS-string"
    },
    "eventType": "response.blob.sas-url.success"
}

Requester asks Gridwich to encode via CloudPort Workflow

Requester > Gridwich, uses RequestCloudPortEncodeCreateDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
          "inputs": [
                {"blobUri": "StorageURL-string" }
          ],
          "outputContainer": "https://<storageaccountname>.blob.core.windows.net/<containername>/",
          "workflowName": "TestWorkflow2",
          "parameters": [ { "prop1": "value1" } ],
           "secToLive": 18000
  },
  "eventType": "request.encode.cloudport.create",
}

Requester asks Gridwich to encode via Flip

Requester > Gridwich, uses RequestFlipEncodeCreateDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
          "inputs": [
                {"blobUri": "StorageURL-string" }
          ],
          "outputContainer": "StorageURL-string", // of the Storage container
          "factoryName": "gws-dev-flip",
          "profiles": "h264",
          "parameters": [ { "prop1": "value1" } ],
           "secToLive": 18000
      },
      "eventType": "request.encode.flip.create"
}

Example of RequestFlipEncodeCreateDTO

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": { "progId": 1234 },
          "inputs": [
            {
                "blobUri": "https://gws-sa1.blob.core.windows.net/Vid0001Container/input.mp4"
            }
          ],
          "outputContainer": "https://gws-sa22out.blob.core.windows.net/Out0004/",
          "factoryName": "gws-dev-flip",
          "profiles": "h264",
          "parameters": [ { "someProperty1": "someValue1" } ],
          "secToLive": 18000
      },
      "eventType": "request.encode.flip.create"
}

Gridwich encoders common request successful dispatch response

Gridwich > Requester, uses ResponseEncodeDispatchedDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "encoderContext": <EncoderContext>,
        "workflowJobName": "CloudPort or Flip assigned job name for workflow instance."
    },
    "eventType": "response.encode.<encodername>.dispatched"
}

The <encodername> is one of cloudport or flip.

Gridwich encoder asynchronous status messages

The Gridwich encoders generate four kinds of events during or at the end of encoding:

  • Scheduled
  • Processing
  • Success
  • Canceled

An encode request failure generates a Gridwich Failure event.

Encoding status scheduled

Gridwich > Requester, uses ResponseEncodeScheduledDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "encoderContext":  <EncoderContext>,
        "workflowJobName": "CloudPort or Flip assigned job name for workflow instance."
    },
    "eventType": "response.encode.<encodername>.scheduled"
}

Encoding status processing

Gridwich > Requester, uses ResponseEncodeProcessingDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "encoderContext": <EncoderContext>,
        "workflowJobName": "CloudPort or Flip assigned job name for workflow instance.",
        "currentStatus": "string",
        "percentComplete": 50,
    },
    "eventType": "response.encode.<encodername>.processing"
}

Encoding status success

Gridwich > Requester, uses ResponseEncodeSuccessDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,,
        "encoderContext": <EncoderContext>,
        "workflowJobName": "CloudPort or Flip assigned job name for workflow instance.",
        "outputs":[
            { "blobUri": "StorageURL-string" }
        ]
    },
    "eventType": "response.encode.<encodername>.success"
}

Encoding status canceled

Gridwich > Requester, uses ResponseEncodeCanceledDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "encoderContext": <EncoderContext>,
        "workflowJobName": "CloudPort or Flip assigned job name for workflow instance."
    },
    "eventType": "response.encode.<encodername>.canceled"
}

Requester asks Gridwich to change a blob's storage tier

Requester > Gridwich uses RequestBlobTierChangeDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "blobUri": "StorageURL-string",
        "accessTier": "string",
        "rehydratePriority": "string"
    },
    "eventType": "request.blob.tier.change"
}
  • The accessTier property is Hot, Cool, or Archive.
  • The rehydratePriority property is Standard or High.

Gridwich > Requester uses ResponseBlobTierChangeSuccessDTO

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "blobUri": "StorageURL-string",
        "accessTier": "string",
        "rehydratePriority": "string"
    },
    "eventType":"response.blob.tier.success"
}

Requester asks Gridwich to create a blob container

The request provides the Storage Account and container name.

Requester > Gridwich uses RequestContainerCreateDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "storageAccountName": "string", // e.g. mySA1
        "containerName": "string"       // e.g. mycontainer
    },
    "eventType": "request.blob.container.create"
}

Gridwich > Requester uses ResponseContainerCreatedSuccessDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "storageAccountName": "string",
        "containerName": "string"
    },
    "eventType": "response.blob.container.create.success"
}

Requester asks Gridwich to delete a blob container

The request provides the Storage Account and container name.

Requester > Gridwich uses RequestContainerDeleteDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "storageAccountName": "string",
        "containerName": "string"
    },
    "eventType": "request.blob.container.delete"
}

Gridwich > Requester uses ResponseContainerDeleteSuccessDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "storageAccountName": "string",
        "containerName": "string"
    },
    "eventType": "response.blob.container.delete.success"
}

Requester asks Gridwich to change the public access of a container

The request provides the container name and an accessType of Blob, BlobContainer, or None.

Requester > Gridwich uses RequestContainerAccessChangeDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "storageAccountName": "string",
        "containerName": "string",
        "accessType": "string"
    },
    "eventType": "request.blob.container.access.change"
}

Gridwich > Requester uses ResponseContainerAccessChangeSuccessDTO.

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "storageAccountName": "string",
        "containerName": "string",
        "accessType": "string"
    },
    "eventType": "response.blob.container.access.change.success"
}

Requester asks Gridwich to rotate to a new storage key

The Rollkey event family differs from others in Gridwich in that, while the request accepts an operationContext value, none of the response events include it.

Failure events aren't of the normal response.failure event type, but instead have a type value of response.rollkey.storage.failure.

The response.rollkey.storage.failure failure events:

  • Don't include any of the normal failure event logging information log data properties.
  • Contain an additional data property named error that contains error message text. Other Gridwich failures carry that text on the logEventMessage data property.

These points reflect the current state of the Azure Logic App that performs the RollKey operation. The definition of the Logic App is in the infrastructure/terraform/keyroller/main.tf Terraform file.

The keyName corresponds to the key name that Azure Storage defines in its Get Keys operation.

Requester > Gridwich

{
    "id": "GUID-string",
    "topic": "Topic-string",
    "subject": "Subject-string",
    "dataVersion": "DataVersion-string",
    "data": {
        "operationContext": <OperationContextObject>,
        "account": "storageAccountName",
        "keyName": "key1"
    },
    "eventType": "request.rollkey.storage"
}

Gridwich > Requester

  • Success:

    {
        "id": "GUID-string",
        "topic": "Topic-string",
        "subject": "Subject-string",
        "dataVersion": "DataVersion-string",
        "data": {
            "account": "storageAccountName",
            "keyName": "key1"
        },
        "eventType": "response.rollkey.storage.success"
    }
    
  • Failure:

    {
        "id": "GUID-string",
        "topic": "Topic-string",
        "subject": "Subject-string",
        "dataVersion": "1.0",
        "data": {
           "account": "storageAccountName1",
            "keyName": "key1",
            "error": "error message text"
        },
        "eventType": "response.rollkey.storage.failure"
    }
    

    Failure results for this operation aren't as complete as normal Gridwich failures.

Next steps

Product documentation:

Microsoft Learn modules: