As part of defining a command template within the commands module, pre-signed urls can be configured to provide a secure way to download files. In addition, command templates can be configured to allow for devices to request pre-signed urls to upload content relevant to the command.
The following represents a command template that requires the file with alias file001
to be provided as part of the command:
{
"templateId": "ExampleTemplate",
"description": "An example template allowing a file to be downloaded",
"document": "{\"operation\":\"ExampleCommand\", \"file001\":\"${cdf:file:file001}\"}",
"requiredFiles": [
"file001"
],
"presignedUrlExpiresInSeconds": 3600
}
It is recommended that the name of the attribute representing the file in the document json is named the same as the file alias (file001
in the above template). This will make it easier for a device to request a new pre-signed url for a file should the pre-signed url expire.
When a command is created from the above template, and then published, a pre-signed url will be provided for file001
that expires as configured by presignedUrlExpiresInSeconds
.
The required file file001
may be uploaded directly after creating a command, or alternatively a path to an existing file stored on S3 may be provided:
PUT /commands/{commandId}/files/file001 HTTP/1.1
Accept: application/vnd.aws-cdf-v1.0+json
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="myfile.txt"
Content-Type: text/plain
------WebKitFormBoundary7MA4YWxkTrZu0gW--
In this scenario the file will be uploaded to ${aws.s3.bucket}:${aws.s3.prefix}commands/{commandId}/files/{fileAlias}
.
PUT /commands/{commandId}/files/file001 HTTP/1.1
Accept: application/vnd.aws-cdf-v1.0+json
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="s3BucketName"
myBucket
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="s3ObjectKey"
path/to/my/file
------WebKitFormBoundary7MA4YWxkTrZu0gW--
First, to allow file uploads by a device, the command template must be configured as follows:
{
"templateId": "ExampleTemplate",
"description": "An example template allowing files uploaded",
"document": "{\"operation\":\"ExampleCommand\"}",
"allowFileUploads": true,
"presignedUrlExpiresInSeconds": 3600
}
When files are uploaded from a device, they are stored within the root key ${aws.s3.bucket}:${aws.s3.prefix}commands/{commandId}/uploads/{thingName}
.
As pre-signed urls are generated per file, and the specific files to be uploaded may only be known by a device at time of execution, a mechanism to allow devices to request pre-signed urls (via mqtt) for file upload is provided is follows:
Step 1: Set up the subscription to receive a response before making the request itself:
cdf/commands/presignedurl/{commandId}/{thingName}/uploads/accepted
cdf/commands/presignedurl/{commandId}/{thingName}/uploads/rejected
Step 2: Publish a request for a new pre-signed urls:
cdf/commands/presignedurl/{commandId}/{thingName}/uploads
The request payload:
{
"requestedObjectKeys": ["relative/path/to/my/file"]
}
Step 3: Receiving the pre-signed urls:
A response will be published to the accepted/rejected topics that the device subscribed to in step 1 as follows:
{
"thingName": "esdn",
"commandId": "commandId",
"status": "FAILED|SUCCESS",
"presignedUrls": {
"relative/path/to/my/file": "{pre-signed url}"
}
}
The attribute presignedUrls
is a map, where each of its keys correponds to one of the requested object keys.
The relative path provided as requestedObjectKey
is stored within ${aws.s3.bucket}:${aws.s3.prefix}commands/{commandId}/uploads/{thingName}
.
Pre-signed urls expire based on their configured presignedUrlExpiresInSeconds
. It is possible to determine if a pre-signed url is expired before attempting to use by checking its X-Amz-Date
query string parameter. If the pre-signed url expires during use, a 403 Forbidden
http response code is returned.
Devices may only request pre-signed urls for content associated with commands that they are part of.
To request a new pre-signed url for a file to upload, make the same MQTT request as described in the Uploading Files
section.
To request a new pre-signed url for a file to download, perform the following steps:
Step 1: Set up the subscription to receive a response before making the request itself:
cdf/commands/presignedurl/{commandId}/{thingName}/downloads/accepted
cdf/commands/presignedurl/{commandId}/{thingName}/downloads/rejected
Step 2: Publish a request for a new pre-signed url:
cdf/commands/presignedurl/{commandId}/{thingName}/downloads
The request payload:
{
"requestedFileAliases": ["file001"]
}
Step 3: Receiving the pre-signed urls:
A response will be published to the accepted/rejected topics that the device subscribed to in step 1 as follows:
{
"thingName": "esdn",
"commandId": "commandId",
"status": "FAILED|SUCCESS",
"presignedUrls": {
"file001": "{pre-signed url}"
}
}
The attribute presignedUrls
is a map, where each of its keys correponds to one of the requested file aliases.