

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 구성 요소 구성과 연동
<a name="ipc-component-configuration"></a>

구성 요소 구성 IPC 서비스를 사용하여 다음을 수행할 수 있습니다.
+ 구성 요소 구성 파라미터를 가져오고 설정합니다.
+ 구성 요소 구성 업데이트를 구독합니다.
+ nucleus에서 구성 요소 구성 업데이트를 적용하기 전에 검증합니다.

**Topics**
+ [최소 SDK 버전](#ipc-component-configuration-sdk-versions)
+ [GetConfiguration](#ipc-operation-getconfiguration)
+ [UpdateConfiguration](#ipc-operation-updateconfiguration)
+ [SubscribeToConfigurationUpdate](#ipc-operation-subscribetoconfigurationupdate)
+ [SubscribeToValidateConfigurationUpdates](#ipc-operation-subscribetovalidateconfigurationupdates)
+ [SendConfigurationValidityReport](#ipc-operation-sendconfigurationvalidityreport)

## 최소 SDK 버전
<a name="ipc-component-configuration-sdk-versions"></a>

다음 표에는 구성 요소 구성과 상호 작용하는 데 사용할 수 있는 SDKs의 최소 버전이 나열되어 있습니다.


| SDK | 최소 버전 | 
| --- | --- | 
|  [AWS IoT Greengrass 구성 요소 SDK(C, C\$1\$1, Rust)](https://github.com/aws-greengrass/aws-greengrass-component-sdk)  |  v1.0.0  | 
|  [AWS IoT Device SDK Java v2용](https://github.com/aws/aws-iot-device-sdk-java-v2)  |  v1.2.10  | 
|  [AWS IoT Device SDK Python v2용](https://github.com/aws/aws-iot-device-sdk-python-v2)  |  v1.5.3  | 
|  [AWS IoT Device SDK C\$1\$1 v2용](https://github.com/aws/aws-iot-device-sdk-cpp-v2)  |  v1.17.0  | 
|  [AWS IoT Device SDK JavaScript v2용](https://github.com/aws/aws-iot-device-sdk-js-v2)  |  v1.12.0  | 

## GetConfiguration
<a name="ipc-operation-getconfiguration"></a>

코어 디바이스의 구성 요소에 대한 구성 값을 가져옵니다. 구성 값을 가져올 키 경로를 지정합니다.

### 요청
<a name="ipc-operation-getconfiguration-request"></a>

이 작업의 요청에서는 다음 파라미터를 사용합니다.

`componentName`(Python: `component_name`)  <a name="ipc-configuration-request-component-name"></a>
(선택 사항) 구성 요소의 이름입니다.  
기본값은 요청을 하는 구성 요소의 이름입니다.

`keyPath`(Python: `key_path`)  
구성 값의 키 경로입니다. 각 항목이 구성 객체에서 단일 수준에 대한 키인 목록을 지정합니다. 예를 들어 다음 구성에서 `port`의 값을 가져오려면 `["mqtt", "port"]`를 지정합니다.  

```
{
  "mqtt": {
    "port": 443
  }
}
```
구성 요소의 전체 구성을 가져오려면 빈 목록을 지정합니다.

### 응답
<a name="ipc-operation-getconfiguration-response"></a>

이 작업의 응답에는 다음 정보가 포함됩니다.

`componentName`(Python: `component_name`)  <a name="ipc-configuration-response-component-name"></a>
구성 요소의 이름입니다.

`value`  
객체인 요청된 구성입니다.

### 예제
<a name="ipc-operation-getconfiguration-examples"></a>

다음 예제에서는 사용자 지정 구성 요소 코드에서 이 작업을 직접 호출하는 방법을 보여줍니다.

------
#### [ Rust ]

**Example 예: 구성 가져오기**  

```
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 예: 구성 가져오기**  

```
#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\$1\$1 (Component SDK) ]

**Example 예: 구성 가져오기**  

```
#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
<a name="ipc-operation-updateconfiguration"></a>

코어 디바이스에서 이 구성 요소에 대한 구성 값을 업데이트합니다.

### 요청
<a name="ipc-operation-updateconfiguration-request"></a>

이 작업의 요청에서는 다음 파라미터를 사용합니다.

`keyPath`(Python: `key_path`)  
(선택 사항) 업데이트할 컨테이너 노드(객체)의 키 경로입니다. 각 항목이 구성 객체에서 단일 수준에 대한 키인 목록을 지정합니다. 예를 들어 다음 구성에서 `port`의 값을 설정하려면 키 경로 `["mqtt"]` 및 병합 값 `{ "port": 443 }`을 지정합니다.  

```
{
  "mqtt": {
    "port": 443
  }
}
```
키 경로는 구성의 컨테이너 노드(객체)를 지정해야 합니다. 노드가 구성 요소의 구성에 없는 경우 이 작업은 노드를 생성하고 해당 값을 `valueToMerge`의 객체로 설정합니다.  
기본값은 구성 객체의 루트입니다.

`timestamp`  
현재 Unix epoch 시간(밀리초)입니다. 이 작업은 이 타임스탬프를 사용하여 키에 대한 동시 업데이트를 해결합니다. 구성 요소 구성의 키의 타임스탬프가 요청의 타임스탬프보다 크면 요청이 실패합니다.

`valueToMerge`(Python: `value_to_merge`)  
`keyPath`에서 지정하는 위치에서 병합할 구성 객체입니다. 자세한 내용은 [구성 요소 구성 업데이트](update-component-configurations.md) 단원을 참조하십시오.

### 응답
<a name="ipc-operation-updateconfiguration-response"></a>

이 작업의 응답에는 어떠한 정보도 제공하지 않습니다.

### 예제
<a name="ipc-operation-updateconfiguration-examples"></a>

다음 예제에서는 사용자 지정 구성 요소 코드에서 이 작업을 직접 호출하는 방법을 보여줍니다.

------
#### [ Rust ]

**Example 예: 구성 업데이트**  

```
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 예: 구성 업데이트**  

```
#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\$1\$1 (Component SDK) ]

**Example 예: 구성 업데이트**  

```
#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
<a name="ipc-operation-subscribetoconfigurationupdate"></a>

구성 요소의 구성이 업데이트될 때 알림을 수신하려면 구독합니다. 키를 구독하는 경우 해당 키의 하위 키가 업데이트되면 알림을 받습니다.

<a name="ipc-subscribe-operation-note"></a>이 작업은 이벤트 메시지 스트림을 구독하는 구독 작업입니다. 이 작업을 사용하려면 이벤트 메시지, 오류 및 스트림 종료를 처리하는 함수를 사용하여 스트림 응답 핸들러를 정의합니다. 자세한 내용은 [IPC 이벤트 스트림 구독](interprocess-communication.md#ipc-subscribe-operations) 단원을 참조하십시오.

**이벤트 메시지 유형:** `ConfigurationUpdateEvents`

### 요청
<a name="ipc-operation-subscribetoconfigurationupdate-request"></a>

이 작업의 요청에서는 다음 파라미터를 사용합니다.

`componentName`(Python: `component_name`)  <a name="ipc-configuration-request-component-name"></a>
(선택 사항) 구성 요소의 이름입니다.  
기본값은 요청을 하는 구성 요소의 이름입니다.

`keyPath`(Python: `key_path`)  
구독할 구성 값의 키 경로입니다. 각 항목이 구성 객체에서 단일 수준에 대한 키인 목록을 지정합니다. 예를 들어 다음 구성에서 `port`의 값을 가져오려면 `["mqtt", "port"]`를 지정합니다.  

```
{
  "mqtt": {
    "port": 443
  }
}
```
구성 요소 구성에서 모든 값에 대한 업데이트를 구독하려면 빈 목록을 지정합니다.

### 응답
<a name="ipc-operation-subscribetoconfigurationupdate-response"></a>

이 작업의 응답에는 다음 정보가 포함됩니다.

`messages`  
알림 메시지의 스트림입니다. 이 객체 `ConfigurationUpdateEvents`에는 다음 정보가 포함됩니다.    
`configurationUpdateEvent`(Python: `configuration_update_event`)  
구성 업데이트 이벤트입니다. 이 객체 `ConfigurationUpdateEvent`에는 다음 정보가 포함됩니다.    
`componentName`(Python: `component_name`)  <a name="ipc-configuration-response-component-name"></a>
구성 요소의 이름입니다.  
`keyPath`(Python: `key_path`)  
업데이트된 구성 값의 키 경로입니다.

### 예제
<a name="ipc-operation-subscribetoconfigurationupdate-examples"></a>

다음 예제에서는 사용자 지정 구성 요소 코드에서 이 작업을 직접 호출하는 방법을 보여줍니다.

------
#### [ Rust ]

**Example 예: 구성 업데이트 구독**  

```
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 예: 구성 업데이트 구독**  

```
#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\$1\$1 (Component SDK) ]

**Example 예: 구성 업데이트 구독**  

```
#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
<a name="ipc-operation-subscribetovalidateconfigurationupdates"></a>

이 구성 요소의 구성이 업데이트되기 전에 알림을 수신하려면 구독합니다. 그러면 구성 요소가 자체 구성에 대한 업데이트를 검증할 수 있습니다. [SendConfigurationValidityReport](#ipc-operation-sendconfigurationvalidityreport) 작업을 사용하면 구성이 유효한지 여부를 nucleus에 알립니다.

**중요**  
로컬 배포에서는 업데이트에 대해 구성 요소에 알리지 않습니다.

<a name="ipc-subscribe-operation-note"></a>이 작업은 이벤트 메시지 스트림을 구독하는 구독 작업입니다. 이 작업을 사용하려면 이벤트 메시지, 오류 및 스트림 종료를 처리하는 함수를 사용하여 스트림 응답 핸들러를 정의합니다. 자세한 내용은 [IPC 이벤트 스트림 구독](interprocess-communication.md#ipc-subscribe-operations) 단원을 참조하십시오.

**이벤트 메시지 유형:** `ValidateConfigurationUpdateEvents`

### 요청
<a name="ipc-operation-subscribetovalidateconfigurationupdates-request"></a>

이 작업의 요청에는 파라미터가 없습니다.

### 응답
<a name="ipc-operation-subscribetovalidateconfigurationupdates-response"></a>

이 작업의 응답에는 다음 정보가 포함됩니다.

`messages`  
알림 메시지의 스트림입니다. 이 객체 `ValidateConfigurationUpdateEvents`에는 다음 정보가 포함됩니다.    
`validateConfigurationUpdateEvent`(Python: `validate_configuration_update_event`)  
구성 업데이트 이벤트입니다. 이 객체 `ValidateConfigurationUpdateEvent`에는 다음 정보가 포함됩니다.    
`deploymentId`(Python: `deployment_id`)  
구성 요소를 업데이트하는 AWS IoT Greengrass 배포의 ID입니다.  
`configuration`  
새 구성을 포함하는 객체입니다.

## SendConfigurationValidityReport
<a name="ipc-operation-sendconfigurationvalidityreport"></a>

이 구성 요소에 대한 구성 업데이트가 유효한지 여부를 nucleus에 알립니다. 새 구성이 유효하지 않다고 nucleus에 알리면 배포가 실패합니다. [SubscribeToValidateConfigurationUpdates](#ipc-operation-subscribetovalidateconfigurationupdates) 작업을 사용하면 구성 업데이트 검증을 구독할 수 있습니다.

구성 요소가 구성 업데이트 검증 알림에 응답하지 않으면 nucleus는 배포의 구성 검증 정책에 지정한 시간을 기다립니다. 이 제한 시간이 지나면 nucleus는 배포를 진행합니다. 기본 구성 요소 검증 제한 시간은 20초입니다. 자세한 내용은 [배포 만들기](create-deployments.md) 섹션 및 [CreateDeployment](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_CreateDeployment.html) 작업을 직접 호출할 때 제공할 수 있는 [DeploymentConfigurationValidationPolicy](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_DeploymentConfigurationValidationPolicy.html) 객체를 참조하세요.

### 요청
<a name="ipc-operation-sendconfigurationvalidityreport-request"></a>

이 작업의 요청에서는 다음 파라미터를 사용합니다.

`configurationValidityReport`(Python: `configuration_validity_report`)  
구성 업데이트가 유효한지 여부를 nucleus에 알려주는 보고서입니다. 이 객체 `ConfigurationValidityReport`에는 다음 정보가 포함됩니다.    
`status`  
유효성 상태입니다. 이 열거형 `ConfigurationValidityStatus`의 값은 다음과 같습니다.  
+ `ACCEPTED` - 구성이 유효하며 nucleus가 이 구성 요소에 적용할 수 있습니다.
+ `REJECTED` - 구성이 유효하지 않고 배포가 실패합니다.  
`deploymentId`(Python: `deployment_id`)  
구성 업데이트를 요청한 AWS IoT Greengrass 배포의 ID입니다.  
`message`  
(선택 사항) 구성이 유효하지 않은 이유를 보고하는 메시지입니다.

### 응답
<a name="ipc-operation-sendconfigurationvalidityreport-response"></a>

이 작업의 응답에는 어떠한 정보도 제공하지 않습니다.