Interact with component configuration - Amazon IoT Greengrass
Services or capabilities described in Amazon Web Services documentation might vary by Region. To see the differences applicable to the China Regions, see Getting Started with Amazon Web Services in China (PDF).

Interact with component configuration

The component configuration IPC service lets you do the following:

  • Get and set component configuration parameters.

  • Subscribe to component configuration updates.

  • Validate component configuration updates before the nucleus applies them.

Minimum SDK versions

The following table lists the minimum versions of the SDKs that you can use to interact with component configuration.

GetConfiguration

Gets a configuration value for a component on the core device. You specify the key path for which to get a configuration value.

Request

This operation's request has the following parameters:

componentName (Python: component_name)

(Optional) The name of the component.

Defaults to the name of the component that makes the request.

keyPath (Python: key_path)

The key path to the configuration value. Specify a list where each entry is the key for a single level in the configuration object. For example, specify ["mqtt", "port"] to get the value of port in the following configuration.

{ "mqtt": { "port": 443 } }

To get the component's complete configuration, specify an empty list.

Response

This operation's response has the following information:

componentName (Python: component_name)

The name of the component.

value

The requested configuration as an object.

Examples

The following examples demonstrate how to call this operation in custom component code.

Rust
Example: Get configuration
use core::mem::MaybeUninit; use gg_sdk::{Sdk, UnpackedObject}; fn main() { let sdk = Sdk::init(); sdk.connect().expect("Failed to establish IPC connection"); // Get a configuration value at key path ["mqtt", "port"] let mut buf = [MaybeUninit::uninit(); 1024]; let value = sdk .get_config(&["mqtt", "port"], None, &mut buf) .expect("Failed to get configuration"); if let UnpackedObject::I64(port) = value.unpack() { println!("Configuration value: {port}"); } }
C
Example: Get configuration
#include <gg/error.h> #include <gg/ipc/client.h> #include <gg/object.h> #include <gg/sdk.h> #include <inttypes.h> #include <stdio.h> #include <stdlib.h> int main(void) { gg_sdk_init(); GgError err = ggipc_connect(); if (err != GG_ERR_OK) { fprintf(stderr, "Failed to establish IPC connection.\n"); exit(-1); } // Get a configuration value at key path ["mqtt", "port"] uint8_t response_mem[1024]; GgObject value; err = ggipc_get_config( GG_BUF_LIST(GG_STR("mqtt"), GG_STR("port")), NULL, // component_name (NULL = current component) GG_BUF(response_mem), &value ); if (err != GG_ERR_OK) { fprintf(stderr, "Failed to get configuration.\n"); exit(-1); } if (gg_obj_type(value) == GG_TYPE_I64) { printf("Configuration value: %" PRId64 "\n", gg_obj_into_i64(value)); } else if (gg_obj_type(value) == GG_TYPE_BUF) { GgBuffer buf = gg_obj_into_buf(value); printf("Configuration value: %.*s\n", (int) buf.len, buf.data); } else { printf("Configuration value is of unexpected type.\n"); } }
C++ (Component SDK)
Example: Get configuration
#include <gg/ipc/client.hpp> #include <iostream> int main() { auto &client = gg::ipc::Client::get(); auto error = client.connect(); if (error) { std::cerr << "Failed to establish IPC connection.\n"; exit(-1); } // Get a configuration value at key path ["mqtt", "port"] std::array key_path = { gg::Buffer { "mqtt" }, gg::Buffer { "port" } }; int64_t value = 0; error = client.get_config(key_path, std::nullopt, value); if (error) { std::cerr << "Failed to get configuration.\n"; exit(-1); } std::cout << "Configuration value: " << value << "\n"; }

UpdateConfiguration

Updates a configuration value for this component on the core device.

Request

This operation's request has the following parameters:

keyPath (Python: key_path)

(Optional) The key path to the container node (the object) to update. Specify a list where each entry is the key for a single level in the configuration object. For example, specify the key path ["mqtt"] and the merge value { "port": 443 } to set the value of port in the following configuration.

{ "mqtt": { "port": 443 } }

The key path must specify a container node (an object) in the configuration. If the node doesn't exist in the component's configuration, this operation creates it and sets its value to the object in valueToMerge.

Defaults to the root of the configuration object.

timestamp

The current Unix epoch time in milliseconds. This operation uses this timestamp to resolve concurrent updates to the key. If the key in the component configuration has a greater timestamp than the timestamp in the request, then the request fails.

valueToMerge (Python: value_to_merge)

The configuration object to merge at the location that you specify in keyPath. For more information, see Update component configurations.

Response

This operation doesn't provide any information in its response.

Examples

The following examples demonstrate how to call this operation in custom component code.

Rust
Example: Update configuration
use gg_sdk::Sdk; fn main() { let sdk = Sdk::init(); sdk.connect().expect("Failed to establish IPC connection"); // Update configuration value at key path ["mqtt", "port"] to 443 sdk.update_config(&["mqtt", "port"], None, 443) .expect("Failed to update configuration"); println!("Successfully updated configuration."); }
C
Example: Update configuration
#include <gg/error.h> #include <gg/ipc/client.h> #include <gg/object.h> #include <gg/sdk.h> #include <stdio.h> #include <stdlib.h> int main(void) { gg_sdk_init(); GgError err = ggipc_connect(); if (err != GG_ERR_OK) { fprintf(stderr, "Failed to establish IPC connection.\n"); exit(-1); } // Update configuration value at key path ["mqtt", "port"] to 443 err = ggipc_update_config( GG_BUF_LIST(GG_STR("mqtt"), GG_STR("port")), NULL, // timestamp (NULL = current time) gg_obj_i64(443) ); if (err != GG_ERR_OK) { fprintf(stderr, "Failed to update configuration.\n"); exit(-1); } printf("Successfully updated configuration.\n"); }
C++ (Component SDK)
Example: Update configuration
#include <gg/ipc/client.hpp> #include <iostream> int main() { auto &client = gg::ipc::Client::get(); auto error = client.connect(); if (error) { std::cerr << "Failed to establish IPC connection.\n"; exit(-1); } // Update configuration value at key path ["mqtt", "port"] to 443 std::array key_path = { gg::Buffer { "mqtt" }, gg::Buffer { "port" } }; error = client.update_config(key_path, 443); if (error) { std::cerr << "Failed to update configuration.\n"; exit(-1); } std::cout << "Successfully updated configuration.\n"; }

SubscribeToConfigurationUpdate

Subscribe to receive notifications when a component's configuration updates. When you subscribe to a key, you receive a notification when any child of that key updates.

This operation is a subscription operation where you subscribe to a stream of event messages. To use this operation, define a stream response handler with functions that handle event messages, errors, and stream closure. For more information, see Subscribe to IPC event streams.

Event message type: ConfigurationUpdateEvents

Request

This operation's request has the following parameters:

componentName (Python: component_name)

(Optional) The name of the component.

Defaults to the name of the component that makes the request.

keyPath (Python: key_path)

The key path to the configuration value for which to subscribe. Specify a list where each entry is the key for a single level in the configuration object. For example, specify ["mqtt", "port"] to get the value of port in the following configuration.

{ "mqtt": { "port": 443 } }

To subscribe to updates for all values in the component's configuration, specify an empty list.

Response

This operation's response has the following information:

messages

The stream of notification messages. This object, ConfigurationUpdateEvents, contains the following information:

configurationUpdateEvent (Python: configuration_update_event)

The configuration update event. This object, ConfigurationUpdateEvent, contains the following information:

componentName (Python: component_name)

The name of the component.

keyPath (Python: key_path)

The key path to the configuration value that updated.

Examples

The following examples demonstrate how to call this operation in custom component code.

Rust
Example: Subscribe to configuration updates
use gg_sdk::Sdk; use std::{thread, time::Duration}; fn main() { let sdk = Sdk::init(); sdk.connect().expect("Failed to establish IPC connection"); // Subscribe to configuration updates for key path ["mqtt"] let callback = |component_name: &str, key_path: &[&str]| { println!( "Received configuration update for component: {component_name}" ); println!("Key path: {key_path:?}"); }; let _sub = sdk .subscribe_to_configuration_update(None, &["mqtt"], &callback) .expect("Failed to subscribe to configuration updates"); println!("Successfully subscribed to configuration updates."); // Keep the main thread alive, or the process will exit. loop { thread::sleep(Duration::from_secs(10)); } }
C
Example: Subscribe to configuration updates
#include <gg/error.h> #include <gg/ipc/client.h> #include <gg/object.h> #include <gg/sdk.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> static void on_subscription_response( void *ctx, GgBuffer component_name, GgList key_path, GgIpcSubscriptionHandle handle ) { (void) ctx; (void) handle; printf( "Received configuration update for component: %.*s\n", (int) component_name.len, component_name.data ); printf("Key path: ["); for (size_t i = 0; i < key_path.len; i++) { if (i > 0) { printf(", "); } GgObject *obj = &key_path.items[i]; if (gg_obj_type(*obj) == GG_TYPE_BUF) { GgBuffer key = gg_obj_into_buf(*obj); printf("\"%.*s\"", (int) key.len, key.data); } } printf("]\n"); } int main(void) { gg_sdk_init(); GgError err = ggipc_connect(); if (err != GG_ERR_OK) { fprintf(stderr, "Failed to establish IPC connection.\n"); exit(-1); } // Subscribe to configuration updates for key path ["mqtt"] GgIpcSubscriptionHandle handle; err = ggipc_subscribe_to_configuration_update( NULL, // component_name (NULL = current component) GG_BUF_LIST(GG_STR("mqtt")), on_subscription_response, NULL, &handle ); if (err != GG_ERR_OK) { fprintf(stderr, "Failed to subscribe to configuration updates.\n"); exit(-1); } printf("Successfully subscribed to configuration updates.\n"); // Keep the main thread alive, or the process will exit. while (1) { sleep(10); } // To stop subscribing, close the stream. ggipc_close_subscription(handle); }
C++ (Component SDK)
Example: Subscribe to configuration updates
#include <gg/ipc/client.hpp> #include <unistd.h> #include <iostream> class ResponseHandler : public gg::ipc::ConfigurationUpdateCallback { void operator()( std::string_view component_name, gg::List key_path, gg::ipc::Subscription &handle ) override { (void) handle; std::cout << "Received configuration update for component: " << component_name << "\n"; std::cout << "Key path: ["; for (size_t i = 0; i < key_path.size(); i++) { if (i > 0) { std::cout << ", "; } std::cout << "\"" << get<gg::Buffer>(key_path[i]) << "\""; } std::cout << "]\n"; } }; int main() { auto &client = gg::ipc::Client::get(); auto error = client.connect(); if (error) { std::cerr << "Failed to establish IPC connection.\n"; exit(-1); } // Subscribe to configuration updates for key path ["mqtt"] std::array key_path = { gg::Buffer { "mqtt" } }; static ResponseHandler handler; error = client.subscribe_to_configuration_update( key_path, std::nullopt, handler ); if (error) { std::cerr << "Failed to subscribe to configuration updates.\n"; exit(-1); } std::cout << "Successfully subscribed to configuration updates.\n"; // Keep the main thread alive, or the process will exit. while (1) { sleep(10); } }

SubscribeToValidateConfigurationUpdates

Subscribe to receive notifications before this component's configuration updates. This lets components validate updates to their own configuration. Use the SendConfigurationValidityReport operation to tell the nucleus whether or not the configuration is valid.

Important

Local deployments don't notify components of updates.

This operation is a subscription operation where you subscribe to a stream of event messages. To use this operation, define a stream response handler with functions that handle event messages, errors, and stream closure. For more information, see Subscribe to IPC event streams.

Event message type: ValidateConfigurationUpdateEvents

Request

This operation's request doesn't have any parameters.

Response

This operation's response has the following information:

messages

The stream of notification messages. This object, ValidateConfigurationUpdateEvents, contains the following information:

validateConfigurationUpdateEvent (Python: validate_configuration_update_event)

The configuration update event. This object, ValidateConfigurationUpdateEvent, contains the following information:

deploymentId (Python: deployment_id)

The ID of the Amazon IoT Greengrass deployment that updates the component.

configuration

The object that contains the new configuration.

SendConfigurationValidityReport

Tell the nucleus whether or not a configuration update to this component is valid. The deployment fails if you tell the nucleus that the new configuration isn't valid. Use the SubscribeToValidateConfigurationUpdates operation to subscribe to validate configuration updates.

If a component doesn't respond to a validate configuration update notification, the nucleus waits the amount of time that you specify in the deployment's configuration validation policy. After that timeout, the nucleus proceeds with the deployment. The default component validation timeout is 20 seconds. For more information, see Create deployments and the DeploymentConfigurationValidationPolicy object that you can provide when you call the CreateDeployment operation.

Request

This operation's request has the following parameters:

configurationValidityReport (Python: configuration_validity_report)

The report that tells the nucleus whether or not the configuration update is valid. This object, ConfigurationValidityReport, contains the following information:

status

The validity status. This enum, ConfigurationValidityStatus, has the following values:

  • ACCEPTED – The configuration is valid and the nucleus can apply it to this component.

  • REJECTED – The configuration isn't valid and the deployment fails.

deploymentId (Python: deployment_id)

The ID of the Amazon IoT Greengrass deployment that requested the configuration update.

message

(Optional) A message that reports why the configuration isn't valid.

Response

This operation doesn't provide any information in its response.