Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions commands/include/aws/iotcommands/CommandExecutionResult.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#pragma once

/* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*
* This file is generated
*/

#include <aws/iotcommands/Exports.h>

#include <aws/crt/JsonObject.h>
#include <aws/crt/StlAllocator.h>

namespace Aws
{
namespace Iotcommands
{

/**
* The result value of the command execution. The device can use the result field to share additional details
* about the execution such as a return value of a remote function call.
*
*/
class AWS_IOTCOMMANDS_API CommandExecutionResult final
{
public:
CommandExecutionResult() = default;

CommandExecutionResult(const Crt::JsonView &doc);
CommandExecutionResult &operator=(const Crt::JsonView &doc);

void SerializeToObject(Crt::JsonObject &doc) const;

/**
* An attribute of type String.
*
*/
Aws::Crt::Optional<Aws::Crt::String> S;

/**
* An attribute of type Boolean.
*
*/
Aws::Crt::Optional<bool> B;

/**
* An attribute of type Binary.
*
*/
Aws::Crt::Optional<Aws::Crt::Vector<uint8_t>> Bin;

private:
static void LoadFromObject(CommandExecutionResult &obj, const Crt::JsonView &doc);
};
} // namespace Iotcommands
} // namespace Aws
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* This file is generated
*/

#include <aws/iotcommands/CommandExecutionResult.h>
#include <aws/iotcommands/CommandExecutionStatus.h>
#include <aws/iotcommands/DeviceType.h>
#include <aws/iotcommands/StatusReason.h>
Expand Down Expand Up @@ -66,6 +67,14 @@ namespace Aws
*/
Aws::Crt::Optional<Aws::Iotcommands::StatusReason> StatusReason;

/**
* The result value for the current state of the command execution. The status provides information about
* the progress of the command execution. The device can use the result field to share additional details
* about the execution such as a return value of a remote function call.
*
*/
Aws::Crt::Optional<Aws::Crt::Map<Aws::Crt::String, Aws::Iotcommands::CommandExecutionResult>> Result;

private:
static void LoadFromObject(UpdateCommandExecutionRequest &obj, const Crt::JsonView &doc);
};
Expand Down
66 changes: 66 additions & 0 deletions commands/source/CommandExecutionResult.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*
* This file is generated
*/
#include <aws/iotcommands/CommandExecutionResult.h>

namespace Aws
{
namespace Iotcommands
{

void CommandExecutionResult::LoadFromObject(CommandExecutionResult &val, const Aws::Crt::JsonView &doc)
{
(void)val;
(void)doc;

if (doc.ValueExists("s"))
{
val.S = doc.GetString("s");
}

if (doc.ValueExists("b"))
{
val.B = doc.GetBool("b");
}

if (doc.ValueExists("bin"))
{
val.Bin = Aws::Crt::Base64Decode(doc.GetString("bin"));
}
}

void CommandExecutionResult::SerializeToObject(Aws::Crt::JsonObject &object) const
{
(void)object;

if (S)
{
object.WithString("s", *S);
}

if (B)
{
object.WithBool("b", *B);
}

if (Bin)
{
object.WithString("bin", Aws::Crt::Base64Encode(*Bin));
}
}

CommandExecutionResult::CommandExecutionResult(const Crt::JsonView &doc)
{
LoadFromObject(*this, doc);
}

CommandExecutionResult &CommandExecutionResult::operator=(const Crt::JsonView &doc)
{
*this = CommandExecutionResult(doc);
return *this;
}

} // namespace Iotcommands
} // namespace Aws
4 changes: 4 additions & 0 deletions commands/source/IotCommandsClientV2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ namespace Aws
CommandExecutionEvent &modeledEvent)
{
auto segmentExecutionId = s_getSegmentFromTopic(publishEvent.GetTopic(), 5);
if (segmentExecutionId.ptr == nullptr || segmentExecutionId.len == 0)
{
return false;
}
modeledEvent.SetExecutionId(segmentExecutionId);
modeledEvent.SetPayload(publishEvent.GetPayload());
auto contentType = publishEvent.GetContentType();
Expand Down
26 changes: 26 additions & 0 deletions commands/source/UpdateCommandExecutionRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ namespace Aws
{
val.StatusReason = doc.GetJsonObject("statusReason");
}

if (doc.ValueExists("result"))
{
auto resultMap = doc.GetJsonObject("result");
val.Result = Aws::Crt::Map<Aws::Crt::String, Aws::Iotcommands::CommandExecutionResult>();
for (auto &resultMapMember : resultMap.GetAllObjects())
{
Aws::Iotcommands::CommandExecutionResult resultMapValMember;
resultMapValMember = resultMapMember.second.AsObject();
val.Result->emplace(resultMapMember.first, std::move(resultMapValMember));
}
}
}

void UpdateCommandExecutionRequest::SerializeToObject(Aws::Crt::JsonObject &object) const
Expand All @@ -43,6 +55,20 @@ namespace Aws
StatusReason->SerializeToObject(jsonObject);
object.WithObject("statusReason", std::move(jsonObject));
}

if (Result)
{
Aws::Crt::JsonObject resultMap;
for (auto &resultMapMember : *Result)
{
Aws::Crt::JsonObject resultMapValMember;
Aws::Crt::JsonObject jsonObject;
resultMapMember.second.SerializeToObject(jsonObject);
resultMapValMember.AsObject(std::move(jsonObject));
resultMap.WithObject(resultMapMember.first, std::move(resultMapValMember));
}
object.WithObject("result", std::move(resultMap));
}
}

UpdateCommandExecutionRequest::UpdateCommandExecutionRequest(const Crt::JsonView &doc)
Expand Down
2 changes: 2 additions & 0 deletions docsrc/doxygen.config
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,8 @@ INPUT = crt/aws-crt-cpp/include \
iotdevicecommon/source \
jobs/include \
jobs/source \
commands/include \
commands/source \
secure_tunneling/include \
secure_tunneling/source \
shadow/include \
Expand Down
1 change: 1 addition & 0 deletions docsrc/mainpage.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ GitHub: [https://github.com/aws/aws-iot-device-sdk-cpp-v2](https://github.com/aw
* [Iotjobs](https://aws.github.io/aws-iot-device-sdk-cpp-v2/namespace_aws_1_1_iotjobs.html)
* [Iotsecuretunneling](https://aws.github.io/aws-iot-device-sdk-cpp-v2/namespace_aws_1_1_iotsecuretunneling.html)
* [Iotshadow](https://aws.github.io/aws-iot-device-sdk-cpp-v2/namespace_aws_1_1_iotshadow.html)
* [Iotcommands](https://aws.github.io/aws-iot-device-sdk-cpp-v2/namespace_aws_1_1_iotcommands.html)

## AWS Crt C++

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
* SPDX-License-Identifier: Apache-2.0.
*/

#include "command_stream_handler.h"
#include "CommandStreamHandler.h"

#include <aws/crt/Api.h>
#include <aws/iotcommands/CommandExecutionEvent.h>
#include <aws/iotcommands/CommandExecutionResult.h>
#include <aws/iotcommands/CommandExecutionsSubscriptionRequest.h>
#include <aws/iotcommands/RejectedErrorCode.h>
#include <aws/iotcommands/UpdateCommandExecutionRequest.h>
Expand Down Expand Up @@ -101,7 +102,8 @@ namespace Aws
const Crt::String &executionId,
Aws::Iotcommands::CommandExecutionStatus status,
const Aws::Crt::String &reasonCode,
const Aws::Crt::String &reasonDescription)
const Aws::Crt::String &reasonDescription,
const Aws::Crt::Map<Aws::Crt::String, Aws::Iotcommands::CommandExecutionResult> &result)
{
CommandExecutionContext commandExecutionContext;

Expand Down Expand Up @@ -133,6 +135,11 @@ namespace Aws
request.StatusReason->ReasonDescription = reasonDescription;
}

if (!result.empty())
{
request.Result = result;
}

fprintf(stdout, "Updating command execution '%s'\n", commandExecutionContext.event.ExecutionId->c_str());

std::promise<void> updateWaiter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <aws/crt/Types.h>
#include <aws/iotcommands/CommandExecutionEvent.h>
#include <aws/iotcommands/CommandExecutionResult.h>
#include <aws/iotcommands/CommandExecutionStatus.h>
#include <aws/iotcommands/DeviceType.h>
#include <aws/iotcommands/IotCommandsClientV2.h>
Expand All @@ -22,7 +23,7 @@ namespace Aws

/**
* Sample wrapper around client for the AWS IoT command service.
* It helps
* It helps handle all the streaming operations and command execution updates.
*/
class CommandStreamHandler
{
Expand Down Expand Up @@ -55,13 +56,15 @@ namespace Aws
* @param status One of the following statuses: IN_PROGRESS, SUCCEEDED, FAILED, REJECTED, TIMED_OUT.
* @param reasonCode A short code in the [A-Z0-9_-]+ format and not exceeding 64 characters in length.
* @param reasonDescription Detailed description of the reason.
* @param result A map of result entries. Each entry value is either a string or boolean.
* @return Success status.
*/
bool updateCommandExecutionStatus(
const Aws::Crt::String &executionId,
Aws::Iotcommands::CommandExecutionStatus status,
const Aws::Crt::String &reasonCode,
const Aws::Crt::String &reasonDescription);
const Aws::Crt::String &reasonDescription,
const Aws::Crt::Map<Aws::Crt::String, Aws::Iotcommands::CommandExecutionResult> &result);

void listOpenedStreams();

Expand Down
41 changes: 34 additions & 7 deletions samples/service_clients/commands/commands-sandbox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,16 @@ API calls.
Once connected, the sample supports the following commands:

* open-thing-stream <payload-format> - subscribe to a stream of AWS IoT command executions with a specified payload format
targeting the IoT Thing set on the application startup
targeting the IoT Thing set on the application startup. Supported payload formats: `json`, `cbor`, or any other value for `generic`.
* open-client-stream <payload-format> - subscribe to a stream of AWS IoT command executions with a specified payload format
targeting the MQTT client ID set on the application startup
* update-command-execution <execution-id> \<status> \[\<reason-code>] \[\<reason-description>] - update status for specified
targeting the MQTT client ID set on the application startup. Supported payload formats: `json`, `cbor`, or any other value for `generic`.
* update-command-execution <execution-id> \<status> [reason-code=\<value>] [reason-description=\<value>] [result=\<key:value;...>] - update status for specified
execution ID;
* status can be one of the following: IN_PROGRESS, SUCCEEDED, REJECTED, FAILED, TIMED_OUT
* reason-code and reason-description may be optionally provided for the REJECTED, FAILED, or TIMED_OUT statuses
* reason-code is required if reason-description is specified
* result format: `key1:value1;key2:value2`
* values of `true`/`false` are treated as boolean, others as string
* use quotes for values with spaces: `key:"hello world"`

Miscellaneous
* list-streams - list all open streaming operations
Expand Down Expand Up @@ -432,9 +435,17 @@ Take an AWS IoT command execution ID your sample received at the end of the prev
update-command-execution <execution-id> IN_PROGRESS
```

You can also provide a result with the update:
```
update-command-execution <execution-id> IN_PROGRESS result=battery_ok:true;message:"doing something"
```

> [!NOTE]
> You can also pass binary data in the result field using the CommandExecutionResult::Bin member, which is not supported in this sample.

Then this AWS CLI command
```shell
aws iot get-command-execution --target-arn "<thing ARN>" --execution-id <IoT command execution ID>
aws iot get-command-execution --target-arn "<thing ARN>" --execution-id <IoT command execution ID> --include-result
```

should return something like
Expand All @@ -445,6 +456,14 @@ should return something like
"commandArn": "arn:aws:iot:...:command/MyJsonCommand",
"targetArn": "arn:aws:iot:...:thing/MyIotThing",
"status": "IN_PROGRESS",
"result": {
"battery_ok": {
"B": true
},
"message": {
"S": "doing something"
}
},
"executionTimeoutSeconds": 300
}
```
Expand All @@ -463,7 +482,7 @@ update-command-execution <execution-id> SUCCEEDED
```
or
```
update-command-execution <execution-id> FAILED SHORT_FAILURE_CODE A longer description
update-command-execution <execution-id> FAILED reason-code=SHORT_FAILURE_CODE reason-description="A longer description" result=status:"task complete";success:false
```

will yield something like
Expand Down Expand Up @@ -505,6 +524,14 @@ which will yield
"reasonCode": "SHORT_FAILURE_CODE",
"reasonDescription": "A longer description"
},
"result": {
"success": {
"B": false
},
"status": {
"S": "task complete"
}
},
"executionTimeoutSeconds": 300
}
```
Expand Down Expand Up @@ -552,4 +579,4 @@ Additionally, example code might theoretically modify or delete existing AWS res

- Be aware of the resources that these examples create or delete.
- Be aware of the costs that might be charged to your account as a result.
- Back up your important data.
- Back up your important data.
Loading
Loading