

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

# 로컬 섀도와 연동
<a name="ipc-local-shadows"></a>

섀도 IPC 서비스를 사용하여 디바이스의 로컬 섀도와 연동합니다. 연동할 디바이스로 코어 디바이스나 연결된 클라이언트 디바이스를 선택할 수 있습니다.

이러한 IPC 작업을 사용하려면 [섀도 관리자 구성 요소](shadow-manager-component.md)를 사용자 지정 구성 요소의 종속성으로 포함합니다. 그런 다음 사용자 지정 구성 요소에서 IPC 작업을 사용하여 섀도 관리자를 통해 디바이스의 로컬 섀도와 연동할 수 있습니다. 사용자 지정 구성 요소가 로컬 섀도 상태 변경에 대응할 수 있도록 하려면 게시/구독 IPC 서비스를 사용하여 섀도 이벤트를 구독할 수도 있습니다. 게시/구독 서비스 사용에 대한 자세한 내용은 [로컬 메시지 게시/구독](ipc-publish-subscribe.md) 섹션을 참조하세요.

**참고**  <a name="note-requirement-enable-shadow-manager-client-devices"></a>
코어 디바이스가 클라이언트 디바이스 섀도와 연동할 수 있도록 하려면 MQTT 브리지 구성 요소도 구성하고 배포해야 합니다. 자세한 내용은 [섀도 관리자가 클라이언트 디바이스와 통신할 수 있도록 설정](work-with-client-device-shadows.md)을 참조하세요.

**Topics**
+ [최소 SDK 버전](#ipc-local-shadows-sdk-versions)
+ [권한 부여](#ipc-local-shadow-authorization)
+ [GetThingShadow](#ipc-operation-getthingshadow)
+ [UpdateThingShadow](#ipc-operation-updatethingshadow)
+ [DeleteThingShadow](#ipc-operation-deletethingshadow)
+ [ListNamedShadowsForThing](#ipc-operation-listnamedshadowsforthing)

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

다음 표에는 로컬 섀도와 상호 작용하는 데 사용해야 AWS IoT Device SDK 하는의 최소 버전이 나열되어 있습니다.


| SDK | 최소 버전 | 
| --- | --- | 
|  [AWS IoT Device SDK Java v2용](https://github.com/aws/aws-iot-device-sdk-java-v2)  |  v1.4.0  | 
|  [AWS IoT Device SDK Python v2용](https://github.com/aws/aws-iot-device-sdk-python-v2)  |  v1.6.0  | 
|  [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  | 

## 권한 부여
<a name="ipc-local-shadow-authorization"></a>

사용자 지정 구성 요소에서 섀도 IPC 서비스를 사용하려면 구성 요소가 섀도와 연동할 수 있도록 허용하는 권한 부여 정책을 정의해야 합니다. 권한 부여 정책 정의에 대한 자세한 내용은 [구성 요소에 IPC 작업을 수행할 수 있는 권한 부여](interprocess-communication.md#ipc-authorization-policies) 섹션을 참조하세요.

섀도 연동에 대한 권한 부여 정책에는 다음 속성이 있습니다.

**IPC 서비스 식별자:** `aws.greengrass.ShadowManager`


| 연산 | 설명 | 리소스 | 
| --- | --- | --- | 
|  `aws.greengrass#GetThingShadow`  |  구성 요소가 사물의 섀도를 검색할 수 있도록 허용합니다.  |  다음 문자열 중 하나입니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/greengrass/v2/developerguide/ipc-local-shadows.html)  | 
|  `aws.greengrass#UpdateThingShadow`  |  구성 요소가 사물의 섀도를 업데이트할 수 있도록 허용합니다.  |  다음 문자열 중 하나입니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/greengrass/v2/developerguide/ipc-local-shadows.html)  | 
|  `aws.greengrass#DeleteThingShadow`  |  구성 요소가 사물의 섀도를 삭제할 수 있도록 허용합니다.  |  다음 문자열 중 하나입니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/greengrass/v2/developerguide/ipc-local-shadows.html)  | 
|  `aws.greengrass#ListNamedShadowsForThing`  |  구성 요소가 사물의 이름 지정된 섀도 목록을 검색할 수 있도록 허용합니다.  |  섀도를 사물에 액세스하여 해당 섀도를 나열하도록 허용하는 사물 이름 문자열입니다. 모든 사물에 대한 액세스를 허용하려면 `*`를 사용합니다.  | 

**IPC 서비스 식별자:** `aws.greengrass.ipc.pubsub`


| 연산 | 설명 | 리소스 | 
| --- | --- | --- | 
|  `aws.greengrass#SubscribeToTopic`  |  구성 요소가 에서 지정하는 주제에 대한 메시지를 구독할 수 있도록 허용합니다.  |  다음 주제 문자열 중 하나입니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/greengrass/v2/developerguide/ipc-local-shadows.html) 주제 접두사 `shadowTopicPrefix`의 값은 섀도 유형에 따라 달라집니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/greengrass/v2/developerguide/ipc-local-shadows.html) 모든 주제에 대한 액세스를 허용하려면 `*`를 사용합니다. <a name="ipc-local-publish-subscribe-authorization-mqtt-wildcards"></a>[Greengrass nucleus](greengrass-nucleus-component.md) v2.6.0 이상에서는 MQTT 주제 와일드카드(`#` 및 `+`)가 포함된 주제를 구독할 수 있습니다. 이 주제 문자열은 MQTT 주제 와일드카드를 리터럴 문자로 지원합니다. 예를 들어 구성 요소의 권한 부여 정책에서 `test/topic/#`에 대한 액세스 권한을 부여하는 경우 구성 요소는 `test/topic/#`는 구독할 수 있지만 `test/topic/filter`는 구독할 수 없습니다.  | 

### 로컬 섀도 권한 부여 정책의 레시피 변수
<a name="ipc-local-shadow-authorization-recipe-variables"></a>

[Greengrass nucleus](greengrass-nucleus-component.md) v2.6.0 이상을 사용하고 Greengrass nucleus의 [interpolateComponentConfiguration](greengrass-nucleus-component.md#greengrass-nucleus-component-configuration-interpolate-component-configuration) 구성 옵션을 `true`로 설정한 경우 권한 부여 정책에서 `{iot:thingName}` [레시피 변수](component-recipe-reference.md#recipe-variables)를 사용할 수 있습니다. 이 기능을 사용하면 코어 디바이스 그룹에 대해 단일 권한 부여 정책을 구성할 수 있고, 이 경우 각 코어 디바이스는 자체 섀도만 액세스할 수 있습니다. 예를 들어 섀도 IPC 작업을 위해 다음 리소스에 대한 구성 요소 액세스를 허용할 수 있습니다.

```
$aws/things/{iot:thingName}/shadow/
```

### 권한 부여 정책 예제
<a name="ipc-local-shadow-authorization-policy-examples"></a>

다음 권한 부여 정책 예제를 참조하면 구성 요소의 권한 부여 정책을 구성하는 데 도움이 됩니다.

**Example 예: 코어 디바이스 그룹이 로컬 섀도와 연동하도록 허용**  
 <a name="phrase-example-uses-recipe-variables-in-configuration"></a>이 예제에서는 [Greengrass nucleus 구성 요소](greengrass-nucleus-component.md)의 v2.6.0 이상에서 사용할 수 있는 기능을 사용합니다. Greengrass nucleus v2.6.0에서는 구성 요소 구성에서 `{iot:thingName}`과 같은 대부분의 [레시피 변수](component-recipe-reference.md#recipe-variables)에 대한 지원을 추가합니다. 이 기능을 활성화하려면 Greengrass nucleus의 [interpolateComponentConfiguration](greengrass-nucleus-component.md#greengrass-nucleus-component-configuration-interpolate-component-configuration) 구성 옵션을 `true`로 설정합니다. Greengrass nucleus의 모든 버전에서 작동하는 예제는 [단일 코어 디바이스에 대한 예제 권한 부여 정책](#ipc-local-shadows-authorization-example-single-device)을 참조하세요.
다음 예제 권한 부여 정책에서는 구성 요소 `com.example.MyShadowInteractionComponent`가 구성 요소를 실행하는 코어 디바이스의 클래식 디바이스 섀도 및 이름 지정된 섀도 `myNamedShadow`와 연동할 수 있도록 허용합니다. 또한 이 정책에서는 이 구성 요소가 이러한 섀도의 로컬 주제에 대한 메시지를 수신하도록 허용합니다.  

```
{
  "accessControl": {
    "aws.greengrass.ShadowManager": {
      "com.example.MyShadowInteractionComponent:shadow:1": {
        "policyDescription": "Allows access to shadows",
        "operations": [
          "aws.greengrass#GetThingShadow",
          "aws.greengrass#UpdateThingShadow",
          "aws.greengrass#DeleteThingShadow"
        ],
        "resources": [
          "$aws/things/{iot:thingName}/shadow",
          "$aws/things/{iot:thingName}/shadow/name/myNamedShadow"
        ]
      },
      "com.example.MyShadowInteractionComponent:shadow:2": {
        "policyDescription": "Allows access to things with shadows",
        "operations": [
          "aws.greengrass#ListNamedShadowsForThing"
        ],
        "resources": [
          "{iot:thingName}"
        ]
      }    
    },
    "aws.greengrass.ipc.pubsub": {
      "com.example.MyShadowInteractionComponent:pubsub:1": {
        "policyDescription": "Allows access to shadow pubsub topics",
        "operations": [
          "aws.greengrass#SubscribeToTopic"
        ],
        "resources": [
          "$aws/things/{iot:thingName}/shadow/get/accepted",
          "$aws/things/{iot:thingName}/shadow/name/myNamedShadow/get/accepted"
        ]
      }
    }
  }
}
```

```
accessControl:
  aws.greengrass.ShadowManager:
    'com.example.MyShadowInteractionComponent:shadow:1':
      policyDescription: 'Allows access to shadows'
      operations:
        - 'aws.greengrass#GetThingShadow'
        - 'aws.greengrass#UpdateThingShadow'
        - 'aws.greengrass#DeleteThingShadow'
      resources:
        - $aws/things/{iot:thingName}/shadow
        - $aws/things/{iot:thingName}/shadow/name/myNamedShadow
    'com.example.MyShadowInteractionComponent:shadow:2':
      policyDescription: 'Allows access to things with shadows'
      operations:
        - 'aws.greengrass#ListNamedShadowsForThing'
      resources:
        - '{iot:thingName}'
  aws.greengrass.ipc.pubsub:
    'com.example.MyShadowInteractionComponent:pubsub:1':
      policyDescription: 'Allows access to shadow pubsub topics'
      operations:
        - 'aws.greengrass#SubscribeToTopic'
      resources:
        - $aws/things/{iot:thingName}/shadow/get/accepted
        - $aws/things/{iot:thingName}/shadow/name/myNamedShadow/get/accepted
```

**Example 예: 코어 디바이스 그룹이 클라이언트 디바이스 섀도와 연동하도록 허용**  
이 기능에는 [Greengrass nucleus](greengrass-nucleus-component.md) v2.6.0 이상, [섀도 관리자](shadow-manager-component.md) v2.2.0 이상 및 [MQTT 브리지](mqtt-bridge-component.md) v2.2.0 이상이 필요합니다. [섀도 관리자가 클라이언트 디바이스와 통신할 수 있도록](work-with-client-device-shadows.md#enable-shadow-manager-client-devices) MQTT 브리지를 구성해야 합니다.
다음 예제 권한 부여 정책에서는 구성 요소 `com.example.MyShadowInteractionComponent`가 이름이 `MyClientDevice`로 시작하는 클라이언트 디바이스의 모든 디바이스 섀도와 연동할 수 있도록 허용합니다.  
코어 디바이스가 클라이언트 디바이스 섀도와 연동할 수 있도록 하려면 MQTT 브리지 구성 요소도 구성하고 배포해야 합니다. 자세한 내용은 [섀도 관리자가 클라이언트 디바이스와 통신할 수 있도록 설정](work-with-client-device-shadows.md)을 참조하세요.

```
{
  "accessControl": {
    "aws.greengrass.ShadowManager": {
      "com.example.MyShadowInteractionComponent:shadow:1": {
        "policyDescription": "Allows access to shadows",
        "operations": [
          "aws.greengrass#GetThingShadow",
          "aws.greengrass#UpdateThingShadow",
          "aws.greengrass#DeleteThingShadow"
        ],
        "resources": [
          "$aws/things/MyClientDevice*/shadow",
          "$aws/things/MyClientDevice*/shadow/name/*"
        ]
      },
      "com.example.MyShadowInteractionComponent:shadow:2": {
        "policyDescription": "Allows access to things with shadows",
        "operations": [
          "aws.greengrass#ListNamedShadowsForThing"
        ],
        "resources": [
          "MyClientDevice*"
        ]
      }    
    }
  }
}
```

```
accessControl:
  aws.greengrass.ShadowManager:
    'com.example.MyShadowInteractionComponent:shadow:1':
      policyDescription: 'Allows access to shadows'
      operations:
        - 'aws.greengrass#GetThingShadow'
        - 'aws.greengrass#UpdateThingShadow'
        - 'aws.greengrass#DeleteThingShadow'
      resources:
        - $aws/things/MyClientDevice*/shadow
        - $aws/things/MyClientDevice*/shadow/name/*
    'com.example.MyShadowInteractionComponent:shadow:2':
      policyDescription: 'Allows access to things with shadows'
      operations:
        - 'aws.greengrass#ListNamedShadowsForThing'
      resources:
        - MyClientDevice*
```<a name="ipc-local-shadows-authorization-example-single-device"></a>

**Example 예: 단일 코어 디바이스가 로컬 섀도와 연동하도록 허용**  
다음 예제 권한 부여 정책에서는 구성 요소 `com.example.MyShadowInteractionComponent`가 디바이스 `MyThingName`의 클래식 디바이스 섀도 및 이름 지정된 섀도 `myNamedShadow`와 연동할 수 있도록 허용합니다. 또한 이 정책에서는 이 구성 요소가 이러한 섀도의 로컬 주제에 대한 메시지를 수신하도록 허용합니다.  

```
{
  "accessControl": {
    "aws.greengrass.ShadowManager": {
      "com.example.MyShadowInteractionComponent:shadow:1": {
        "policyDescription": "Allows access to shadows",
        "operations": [
          "aws.greengrass#GetThingShadow",
          "aws.greengrass#UpdateThingShadow",
          "aws.greengrass#DeleteThingShadow"
        ],
        "resources": [
          "$aws/things/MyThingName/shadow",
          "$aws/things/MyThingName/shadow/name/myNamedShadow"
        ]
      },
      "com.example.MyShadowInteractionComponent:shadow:2": {
        "policyDescription": "Allows access to things with shadows",
        "operations": [
          "aws.greengrass#ListNamedShadowsForThing"
        ],
        "resources": [
          "MyThingName"
        ]
      }    
    },
    "aws.greengrass.ipc.pubsub": {
      "com.example.MyShadowInteractionComponent:pubsub:1": {
        "policyDescription": "Allows access to shadow pubsub topics",
        "operations": [
          "aws.greengrass#SubscribeToTopic"
        ],
        "resources": [
          "$aws/things/MyThingName/shadow/get/accepted",
          "$aws/things/MyThingName/shadow/name/myNamedShadow/get/accepted"
        ]
      }
    }
  }
}
```

```
accessControl:
  aws.greengrass.ShadowManager:
    'com.example.MyShadowInteractionComponent:shadow:1':
      policyDescription: 'Allows access to shadows'
      operations:
        - 'aws.greengrass#GetThingShadow'
        - 'aws.greengrass#UpdateThingShadow'
        - 'aws.greengrass#DeleteThingShadow'
      resources:
        - $aws/things/MyThingName/shadow
        - $aws/things/MyThingName/shadow/name/myNamedShadow
    'com.example.MyShadowInteractionComponent:shadow:2':
      policyDescription: 'Allows access to things with shadows'
      operations:
        - 'aws.greengrass#ListNamedShadowsForThing'
      resources:
        - MyThingName
  aws.greengrass.ipc.pubsub:
    'com.example.MyShadowInteractionComponent:pubsub:1':
      policyDescription: 'Allows access to shadow pubsub topics'
      operations:
        - 'aws.greengrass#SubscribeToTopic'
      resources:
        - $aws/things/MyThingName/shadow/get/accepted
        - $aws/things/MyThingName/shadow/name/myNamedShadow/get/accepted
```<a name="interact-with-shadows-react-example-authorization-policies"></a>

**Example 예: 코어 디바이스 그룹이 로컬 섀도 상태 변경에 대응하도록 허용**  
 <a name="phrase-example-uses-recipe-variables-in-configuration"></a>이 예제에서는 [Greengrass nucleus 구성 요소](greengrass-nucleus-component.md)의 v2.6.0 이상에서 사용할 수 있는 기능을 사용합니다. Greengrass nucleus v2.6.0에서는 구성 요소 구성에서 `{iot:thingName}`과 같은 대부분의 [레시피 변수](component-recipe-reference.md#recipe-variables)에 대한 지원을 추가합니다. 이 기능을 활성화하려면 Greengrass nucleus의 [interpolateComponentConfiguration](greengrass-nucleus-component.md#greengrass-nucleus-component-configuration-interpolate-component-configuration) 구성 옵션을 `true`로 설정합니다. Greengrass nucleus의 모든 버전에서 작동하는 예제는 [단일 코어 디바이스에 대한 예제 권한 부여 정책](#interact-with-shadows-react-example-authorization-policy-single-device)을 참조하세요.
다음 예제 액세스 제어 정책에서는 구성 요소 `com.example.MyShadowReactiveComponent`가 구성 요소를 실행하는 각 코어 디바이스에서 클래식 디바이스 섀도 및 이름 지정된 섀도 `myNamedShadow`의 `/update/delta` 주제에 대한 메시지를 수신할 수 있도록 허용합니다.  

```
{
  "accessControl": {
    "aws.greengrass.ipc.pubsub": {
      "com.example.MyShadowReactiveComponent:pubsub:1": {
        "policyDescription": "Allows access to shadow pubsub topics",
        "operations": [
          "aws.greengrass#SubscribeToTopic"
        ],
        "resources": [
          "$aws/things/{iot:thingName}/shadow/update/delta",
          "$aws/things/{iot:thingName}/shadow/name/myNamedShadow/update/delta"
        ]
      }
    }
  }
}
```

```
accessControl:
  aws.greengrass.ipc.pubsub:
    "com.example.MyShadowReactiveComponent:pubsub:1":
      policyDescription: Allows access to shadow pubsub topics
      operations:
        - 'aws.greengrass#SubscribeToTopic'
      resources:
        - $aws/things/{iot:thingName}/shadow/update/delta
        - $aws/things/{iot:thingName}/shadow/name/myNamedShadow/update/delta
```<a name="interact-with-shadows-react-example-authorization-policy-single-device"></a>

**Example 예: 단일 코어 디바이스가 로컬 섀도 상태 변경에 대응하도록 허용**  
다음 예제 액세스 제어 정책에서는 구성 요소 `com.example.MyShadowReactiveComponent`가 디바이스 `MyThingName`의 클래식 디바이스 섀도 및 이름 지정된 섀도 `myNamedShadow`의 `/update/delta` 주제에 대한 메시지를 수신할 수 있도록 허용합니다.  

```
{
  "accessControl": {
    "aws.greengrass.ipc.pubsub": {
      "com.example.MyShadowReactiveComponent:pubsub:1": {
        "policyDescription": "Allows access to shadow pubsub topics",
        "operations": [
          "aws.greengrass#SubscribeToTopic"
        ],
        "resources": [
          "$aws/things/MyThingName/shadow/update/delta",
          "$aws/things/MyThingName/shadow/name/myNamedShadow/update/delta"
        ]
      }
    }
  }
}
```

```
accessControl:
  aws.greengrass.ipc.pubsub:
    "com.example.MyShadowReactiveComponent:pubsub:1":
      policyDescription: Allows access to shadow pubsub topics
      operations:
        - 'aws.greengrass#SubscribeToTopic'
      resources:
        - $aws/things/MyThingName/shadow/update/delta
        - $aws/things/MyThingName/shadow/name/myNamedShadow/update/delta
```

## GetThingShadow
<a name="ipc-operation-getthingshadow"></a>

지정된 사물의 섀도를 가져옵니다.

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

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

`thingName`(Python: `thing_name`)  <a name="ipc-local-shadows-thing-name"></a>
 사물의 이름입니다.  
유형: `string`

`shadowName`(Python: `shadow_name`)  <a name="ipc-local-shadows-shadow-name"></a>
섀도의 이름입니다. 사물의 클래식 섀도를 지정하려면 이 파라미터를 빈 문자열(`""`)로 설정합니다.  
 AWS IoT Greengrass 서비스는 `AWSManagedGreengrassV2Deployment`명명된 섀도우를 사용하여 개별 코어 디바이스를 대상으로 하는 배포를 관리합니다. 이 명명된 섀도우는 AWS IoT Greengrass 서비스에서 사용하도록 예약되어 있습니다. 이 이름이 지정된 섀도를 업데이트하거나 삭제하지 마세요.
유형: `string`

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

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

`payload`  
Blob인 응답 상태 문서입니다.  
유형: 다음 정보를 포함하는 `object`입니다.    
`state`  
상태 정보입니다.  
이 객체에는 다음 정보가 포함됩니다.    
`desired`  
디바이스에서 업데이트하도록 요청된 상태 속성 및 값입니다.  
유형: 키-값 페어의 `map`  
`reported`  
디바이스에서 보고한 상태 속성 및 값입니다.  
유형: 키-값 페어의 `map`  
`delta`  
상태 속성 및 값의 원하는 상태와 보고된 상태 사이의 차이입니다. 이 속성은 `desired` 및 `reported` 상태가 다른 경우에만 있습니다.  
유형: 키-값 페어의 `map`  
`metadata`  
언제 상태가 업데이트되었는지 확인할 수 있는 `desired` 및 `reported` 섹션의 각 속성에 대한 타임스탬프입니다.  
유형: `string`  
`timestamp`  
응답이 생성된 epoch 날짜 및 시간입니다.  
유형: `integer`  
`clientToken`(Python: `clientToken`)  
요청과 해당 응답을 일치시키는 데 사용되는 토큰입니다.  
유형: `string`  
`version`  
로컬 섀도 문서의 버전입니다.  
유형: `integer`

### 오류
<a name="ipc-operation-getthingshadow-errors"></a>

이 작업은 다음 오류를 반환할 수 있습니다.

`InvalidArgumentsError`  <a name="ipc-invalidargumentserror"></a>
<a name="ipc-invalidargumentserror-para"></a>로컬 섀도 서비스에서 요청 파라미터를 검증할 수 없습니다. 요청에 잘못된 형식의 JSON 또는 지원되지 않는 문자가 포함된 경우 발생할 수 있습니다.

`ResourceNotFoundError`  <a name="ipc-resourcenotfounderror"></a>
요청된 로컬 섀도 문서를 찾을 수 없습니다.

`ServiceError`  <a name="ipc-serviceerror"></a>
내부 서비스 오류가 발생했거나, IPC 서비스에 대한 요청 수가 섀도 관리자 구성 요소의 `maxLocalRequestsPerSecondPerThing` 및 `maxTotalLocalRequestsRate` 구성 파라미터에 지정된 제한을 초과했습니다.

`UnauthorizedError`  <a name="ipc-unauthorizederror"></a>
구성 요소의 권한 부여 정책에 이 작업에 필요한 권한이 포함되어 있지 않습니다.

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

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

------
#### [ Java (IPC client V1) ]

**Example 예: 사물 섀도 가져오기**  
이 예제에서는 `IPCUtils` 클래스를 사용하여 AWS IoT Greengrass 코어 IPC 서비스에 대한 연결을 생성합니다. 자세한 내용은 [AWS IoT Greengrass 코어 IPC 서비스에 연결](interprocess-communication.md#ipc-service-connect) 단원을 참조하십시오.

```
package com.aws.greengrass.docs.samples.ipc;

import com.aws.greengrass.docs.samples.ipc.util.IPCUtils;
import software.amazon.awssdk.aws.greengrass.GetThingShadowResponseHandler;
import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClient;
import software.amazon.awssdk.aws.greengrass.model.GetThingShadowRequest;
import software.amazon.awssdk.aws.greengrass.model.GetThingShadowResponse;
import software.amazon.awssdk.aws.greengrass.model.ResourceNotFoundError;
import software.amazon.awssdk.aws.greengrass.model.UnauthorizedError;
import software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection;

import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class GetThingShadow {

    public static final int TIMEOUT_SECONDS = 10;

    public static void main(String[] args) {
        // Use the current core device's name if thing name isn't set.
        String thingName = args[0].isEmpty() ? System.getenv("AWS_IOT_THING_NAME") : args[0];
        String shadowName = args[1];
        try (EventStreamRPCConnection eventStreamRPCConnection =
                     IPCUtils.getEventStreamRpcConnection()) {
            GreengrassCoreIPCClient ipcClient =
                    new GreengrassCoreIPCClient(eventStreamRPCConnection);
            GetThingShadowResponseHandler responseHandler =
                    GetThingShadow.getThingShadow(ipcClient, thingName, shadowName);
            CompletableFuture<GetThingShadowResponse> futureResponse =
                    responseHandler.getResponse();
            try {
                GetThingShadowResponse response = futureResponse.get(TIMEOUT_SECONDS,
                        TimeUnit.SECONDS);
                String shadowPayload = new String(response.getPayload(), StandardCharsets.UTF_8);
                System.out.printf("Successfully got shadow %s/%s: %s%n", thingName, shadowName,
                        shadowPayload);
            } catch (TimeoutException e) {
                System.err.printf("Timeout occurred while getting shadow: %s/%s%n", thingName,
                        shadowName);
            } catch (ExecutionException e) {
                if (e.getCause() instanceof UnauthorizedError) {
                    System.err.printf("Unauthorized error while getting shadow: %s/%s%n",
                            thingName, shadowName);
                } else if (e.getCause() instanceof ResourceNotFoundError) {
                    System.err.printf("Unable to find shadow to get: %s/%s%n", thingName,
                            shadowName);
                } else {
                    throw e;
                }
            }
        } catch (InterruptedException e) {
            System.out.println("IPC interrupted.");
        } catch (ExecutionException e) {
            System.err.println("Exception occurred when using IPC.");
            e.printStackTrace();
            System.exit(1);
        }
    }

    public static GetThingShadowResponseHandler getThingShadow(GreengrassCoreIPCClient greengrassCoreIPCClient, String thingName, String shadowName) {
        GetThingShadowRequest getThingShadowRequest = new GetThingShadowRequest();
        getThingShadowRequest.setThingName(thingName);
        getThingShadowRequest.setShadowName(shadowName);
        return greengrassCoreIPCClient.getThingShadow(getThingShadowRequest, Optional.empty());
    }
}
```

------
#### [ Python (IPC client V1) ]

**Example 예: 사물 섀도 가져오기**  

```
import awsiot.greengrasscoreipc
import awsiot.greengrasscoreipc.client as client
from awsiot.greengrasscoreipc.model import GetThingShadowRequest

TIMEOUT = 10

def sample_get_thing_shadow_request(thingName, shadowName):
    try:
        # set up IPC client to connect to the IPC server
        ipc_client = awsiot.greengrasscoreipc.connect()
                
        # create the GetThingShadow request
        get_thing_shadow_request = GetThingShadowRequest()
        get_thing_shadow_request.thing_name = thingName
        get_thing_shadow_request.shadow_name = shadowName
        
        # retrieve the GetThingShadow response after sending the request to the IPC server
        op = ipc_client.new_get_thing_shadow()
        op.activate(get_thing_shadow_request)
        fut = op.get_response()
        
        result = fut.result(TIMEOUT)
        return result.payload
        
    except InvalidArgumentsError as e:
        # add error handling
        ...
    # except ResourceNotFoundError | UnauthorizedError | ServiceError
```

------
#### [ JavaScript ]

**Example 예: 사물 섀도 가져오기**  

```
import {
    GetThingShadowRequest
} from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc/model';
import * as greengrasscoreipc from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc';

class GetThingShadow {
    private ipcClient: greengrasscoreipc.Client;
    private thingName: string;
    private shadowName: string;

    constructor() {
        // Define args parameters here           
        this.thingName = "<define_your_own_thingName>";
        this.shadowName = "<define_your_own_shadowName>";
        this.bootstrap();
    }

    async bootstrap() {
        try {
            this.ipcClient = await getIpcClient();
        } catch (err) {
            // parse the error depending on your use cases
            throw err
        }
        
        try {
            await this.handleGetThingShadowOperation(this.thingName,
                this.shadowName);
        } catch (err) {
            // parse the error depending on your use cases
            throw err
        }
    }

    async handleGetThingShadowOperation(
        thingName: string,
        shadowName: string
    ) {
        const request: GetThingShadowRequest = {
            thingName: thingName,
            shadowName: shadowName
        };
        const response = await this.ipcClient.getThingShadow(request);
    }
}

export async function getIpcClient() {
    try {
        const ipcClient = greengrasscoreipc.createClient();
        await ipcClient.connect()
            .catch(error => {
                // parse the error depending on your use cases
                throw error;
            });
        return ipcClient
    } catch (err) {
        // parse the error depending on your use caseså
        throw err
    }
}

const startScript = new GetThingShadow();
```

------

## UpdateThingShadow
<a name="ipc-operation-updatethingshadow"></a>

지정된 사물의 섀도를 업데이트합니다. 섀도가 존재하지 않을 경우 섀도가 생성됩니다.

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

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

`thingName`(Python: `thing_name`)  <a name="ipc-local-shadows-thing-name"></a>
 사물의 이름입니다.  
유형: `string`

`shadowName`(Python: `shadow_name`)  <a name="ipc-local-shadows-shadow-name"></a>
섀도의 이름입니다. 사물의 클래식 섀도를 지정하려면 이 파라미터를 빈 문자열(`""`)로 설정합니다.  
 AWS IoT Greengrass 서비스는 `AWSManagedGreengrassV2Deployment`명명된 섀도우를 사용하여 개별 코어 디바이스를 대상으로 하는 배포를 관리합니다. 이 명명된 섀도우는 AWS IoT Greengrass 서비스에서 사용하도록 예약되어 있습니다. 이 이름이 지정된 섀도를 업데이트하거나 삭제하지 마세요.
유형: `string`

`payload`  
Blob인 요청 상태 문서입니다.  
유형: 다음 정보를 포함하는 `object`입니다.    
`state`  
업데이트할 상태 정보입니다. 이 IPC 작업은 지정된 필드에만 영향을 미칩니다.  
이 객체에는 다음 정보가 포함됩니다. 일반적으로 `desired` 또는 `reported` 속성 중 하나를 사용하지만 동일한 요청에서는 둘 다 사용하지는 않습니다.    
`desired`  
디바이스에서 업데이트하도록 요청된 상태 속성 및 값입니다.  
유형: 키-값 페어의 `map`  
`reported`  
디바이스에서 보고한 상태 속성 및 값입니다.  
유형: 키-값 페어의 `map`  
`clientToken`(Python: `client_token`)  
(선택 사항) 클라이언트 토큰으로 요청과 해당 응답을 일치시키는 데 사용되는 토큰입니다.  
유형: `string`  
`version`  
(선택 사항) 업데이트할 로컬 섀도 문서의 버전입니다. 섀도 서비스에서는 지정된 버전이 서비스에서 보유하는 최신 버전과 일치하는 경우에만 업데이트를 처리합니다.  
유형: `integer`

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

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

`payload`  
Blob인 응답 상태 문서입니다.  
유형: 다음 정보를 포함하는 `object`입니다.    
`state`  
상태 정보입니다.  
이 객체에는 다음 정보가 포함됩니다.    
`desired`  
디바이스에서 업데이트하도록 요청된 상태 속성 및 값입니다.  
유형: 키-값 페어의 `map`  
`reported`  
디바이스에서 보고한 상태 속성 및 값입니다.  
유형: 키-값 페어의 `map`  
`delta`  
디바이스에서 보고한 상태 속성 및 값입니다.  
유형: 키-값 페어의 `map`  
`metadata`  
언제 상태가 업데이트되었는지 확인할 수 있는 `desired` 및 `reported` 섹션의 각 속성에 대한 타임스탬프입니다.  
유형: `string`  
`timestamp`  
응답이 생성된 epoch 날짜 및 시간입니다.  
유형: `integer`  
`clientToken`(Python: `client_token`)  
요청과 해당 응답을 일치시키는 데 사용되는 토큰입니다.  
유형: `string`  
`version`  
업데이트가 완료된 후 로컬 섀도 문서의 버전입니다.  
유형: `integer`

### 오류
<a name="ipc-operation-updatethingshadow-errors"></a>

이 작업은 다음 오류를 반환할 수 있습니다.

`ConflictError`  
업데이트 작업 중에 로컬 섀도 서비스에서 버전 충돌이 발생했습니다. 요청 페이로드의 버전이 사용 가능한 최신 로컬 섀도 문서의 버전과 일치하지 않을 경우 발생합니다.

`InvalidArgumentsError`  
<a name="ipc-invalidargumentserror-para"></a>로컬 섀도 서비스에서 요청 파라미터를 검증할 수 없습니다. 요청에 잘못된 형식의 JSON 또는 지원되지 않는 문자가 포함된 경우 발생할 수 있습니다.  
유효한 `payload`의 속성은 다음과 같습니다.  
+ `state` 노드가 있고 `desired` 또는 `reported` 상태 정보를 포함하는 객체입니다.
+ `desired` 및 `reported` 노드는 객체 또는 null입니다. 이러한 객체 중 하나 이상에 유효한 상태 정보가 포함되어 있어야 합니다.
+ `desired` 및 `reported` 객체의 깊이는 8개 노드를 초과할 수 없습니다.
+ `clientToken` 값의 길이는 64자를 초과할 수 없습니다.
+  `version` 값은 `1` 이상이어야 합니다.

`ServiceError`  <a name="ipc-serviceerror"></a>
내부 서비스 오류가 발생했거나, IPC 서비스에 대한 요청 수가 섀도 관리자 구성 요소의 `maxLocalRequestsPerSecondPerThing` 및 `maxTotalLocalRequestsRate` 구성 파라미터에 지정된 제한을 초과했습니다.

`UnauthorizedError`  <a name="ipc-unauthorizederror"></a>
구성 요소의 권한 부여 정책에 이 작업에 필요한 권한이 포함되어 있지 않습니다.

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

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

------
#### [ Java (IPC client V1) ]

**Example 예: 사물 섀도 업데이트**  
이 예제에서는 `IPCUtils` 클래스를 사용하여 AWS IoT Greengrass 코어 IPC 서비스에 대한 연결을 생성합니다. 자세한 내용은 [AWS IoT Greengrass 코어 IPC 서비스에 연결](interprocess-communication.md#ipc-service-connect) 단원을 참조하십시오.

```
package com.aws.greengrass.docs.samples.ipc;

import com.aws.greengrass.docs.samples.ipc.util.IPCUtils;
import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClient;
import software.amazon.awssdk.aws.greengrass.UpdateThingShadowResponseHandler;
import software.amazon.awssdk.aws.greengrass.model.UnauthorizedError;
import software.amazon.awssdk.aws.greengrass.model.UpdateThingShadowRequest;
import software.amazon.awssdk.aws.greengrass.model.UpdateThingShadowResponse;
import software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection;

import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class UpdateThingShadow {

    public static final int TIMEOUT_SECONDS = 10;

    public static void main(String[] args) {
        // Use the current core device's name if thing name isn't set.
        String thingName = args[0].isEmpty() ? System.getenv("AWS_IOT_THING_NAME") : args[0];
        String shadowName = args[1];
        byte[] shadowPayload = args[2].getBytes(StandardCharsets.UTF_8);
        try (EventStreamRPCConnection eventStreamRPCConnection =
                     IPCUtils.getEventStreamRpcConnection()) {
            GreengrassCoreIPCClient ipcClient =
                    new GreengrassCoreIPCClient(eventStreamRPCConnection);
            UpdateThingShadowResponseHandler responseHandler =
                    UpdateThingShadow.updateThingShadow(ipcClient, thingName, shadowName,
                            shadowPayload);
            CompletableFuture<UpdateThingShadowResponse> futureResponse =
                    responseHandler.getResponse();
            try {
                futureResponse.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
                System.out.printf("Successfully updated shadow: %s/%s%n", thingName, shadowName);
            } catch (TimeoutException e) {
                System.err.printf("Timeout occurred while updating shadow: %s/%s%n", thingName,
                        shadowName);
            } catch (ExecutionException e) {
                if (e.getCause() instanceof UnauthorizedError) {
                    System.err.printf("Unauthorized error while updating shadow: %s/%s%n",
                            thingName, shadowName);
                } else {
                    throw e;
                }
            }
        } catch (InterruptedException e) {
            System.out.println("IPC interrupted.");
        } catch (ExecutionException e) {
            System.err.println("Exception occurred when using IPC.");
            e.printStackTrace();
            System.exit(1);
        }
    }

    public static UpdateThingShadowResponseHandler updateThingShadow(GreengrassCoreIPCClient greengrassCoreIPCClient, String thingName, String shadowName, byte[] shadowPayload) {
        UpdateThingShadowRequest updateThingShadowRequest = new UpdateThingShadowRequest();
        updateThingShadowRequest.setThingName(thingName);
        updateThingShadowRequest.setShadowName(shadowName);
        updateThingShadowRequest.setPayload(shadowPayload);
        return greengrassCoreIPCClient.updateThingShadow(updateThingShadowRequest,
                Optional.empty());
    }
}
```

------
#### [ Python (IPC client V1) ]

**Example 예: 사물 섀도 업데이트**  

```
import awsiot.greengrasscoreipc
import awsiot.greengrasscoreipc.client as client
from awsiot.greengrasscoreipc.model import UpdateThingShadowRequest

TIMEOUT = 10

def sample_update_thing_shadow_request(thingName, shadowName, payload):
    try:
        # set up IPC client to connect to the IPC server
        ipc_client = awsiot.greengrasscoreipc.connect()
                
        # create the UpdateThingShadow request
        update_thing_shadow_request = UpdateThingShadowRequest()
        update_thing_shadow_request.thing_name = thingName
        update_thing_shadow_request.shadow_name = shadowName
        update_thing_shadow_request.payload = payload
                        
        # retrieve the UpdateThingShadow response after sending the request to the IPC server
        op = ipc_client.new_update_thing_shadow()
        op.activate(update_thing_shadow_request)
        fut = op.get_response()
        
        result = fut.result(TIMEOUT)
        return result.payload
        
    except InvalidArgumentsError as e:
        # add error handling
    ...
    # except ConflictError | UnauthorizedError | ServiceError
```

------
#### [ JavaScript ]

**Example 예: 사물 섀도 업데이트**  

```
import {
    UpdateThingShadowRequest
} from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc/model';
import * as greengrasscoreipc from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc';

class UpdateThingShadow {
    private ipcClient: greengrasscoreipc.Client;
    private thingName: string;
    private shadowName: string;
    private shadowDocumentStr: string;

    constructor() {
        // Define args parameters here

        this.thingName = "<define_your_own_thingName>";
        this.shadowName = "<define_your_own_shadowName>";
        this.shadowDocumentStr = "<define_your_own_payload>";

        this.bootstrap();
    }

    async bootstrap() {
        try {
            this.ipcClient = await getIpcClient();
        } catch (err) {
            // parse the error depending on your use cases
            throw err
        }

        try {
            await this.handleUpdateThingShadowOperation(
                this.thingName,
                this.shadowName,
                this.shadowDocumentStr);
        } catch (err) {
            // parse the error depending on your use cases
            throw err
        }
    }

    async handleUpdateThingShadowOperation(
        thingName: string,
        shadowName: string,
        payloadStr: string
    ) {
        const request: UpdateThingShadowRequest = {
            thingName: thingName,
            shadowName: shadowName,
            payload: payloadStr
        }
        // make the UpdateThingShadow request
        const response = await this.ipcClient.updateThingShadow(request);
    }
}

export async function getIpcClient() {
    try {
        const ipcClient = greengrasscoreipc.createClient();
        await ipcClient.connect()
            .catch(error => {
                // parse the error depending on your use cases
                throw error;
            });
        return ipcClient
    } catch (err) {
        // parse the error depending on your use cases
        throw err
    }
}

const startScript = new UpdateThingShadow();
```

------

## DeleteThingShadow
<a name="ipc-operation-deletethingshadow"></a>

지정된 사물의 섀도를 삭제합니다.

섀도 관리자 v2.0.4부터 섀도를 삭제하면 버전 번호가 증가합니다. 예를 들어 버전 1에서 섀도 `MyThingShadow`를 삭제하면 삭제된 섀도의 버전은 2입니다. 그런 다음 이름이 `MyThingShadow`인 섀도를 다시 생성하면 해당 섀도의 버전은 3입니다.

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

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

`thingName`(Python: `thing_name`)  <a name="ipc-local-shadows-thing-name"></a>
 사물의 이름입니다.  
유형: `string`

`shadowName`(Python: `shadow_name`)  <a name="ipc-local-shadows-shadow-name"></a>
섀도의 이름입니다. 사물의 클래식 섀도를 지정하려면 이 파라미터를 빈 문자열(`""`)로 설정합니다.  
 AWS IoT Greengrass 서비스는 `AWSManagedGreengrassV2Deployment`명명된 섀도우를 사용하여 개별 코어 디바이스를 대상으로 하는 배포를 관리합니다. 이 명명된 섀도우는 AWS IoT Greengrass 서비스에서 사용하도록 예약되어 있습니다. 이 이름이 지정된 섀도를 업데이트하거나 삭제하지 마세요.
유형: `string`

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

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

`payload`  
빈 응답 상태 문서입니다.

### 오류
<a name="ipc-operation-deletethingshadow-errors"></a>

이 작업은 다음 오류를 반환할 수 있습니다.

`InvalidArgumentsError`  <a name="ipc-invalidargumentserror"></a>
<a name="ipc-invalidargumentserror-para"></a>로컬 섀도 서비스에서 요청 파라미터를 검증할 수 없습니다. 요청에 잘못된 형식의 JSON 또는 지원되지 않는 문자가 포함된 경우 발생할 수 있습니다.

`ResourceNotFoundError`  <a name="ipc-resourcenotfounderror"></a>
요청된 로컬 섀도 문서를 찾을 수 없습니다.

`ServiceError`  <a name="ipc-serviceerror"></a>
내부 서비스 오류가 발생했거나, IPC 서비스에 대한 요청 수가 섀도 관리자 구성 요소의 `maxLocalRequestsPerSecondPerThing` 및 `maxTotalLocalRequestsRate` 구성 파라미터에 지정된 제한을 초과했습니다.

`UnauthorizedError`  <a name="ipc-unauthorizederror"></a>
구성 요소의 권한 부여 정책에 이 작업에 필요한 권한이 포함되어 있지 않습니다.

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

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

------
#### [ Java (IPC client V1) ]

**Example 예: 사물 섀도 삭제**  
이 예제에서는 `IPCUtils` 클래스를 사용하여 AWS IoT Greengrass 코어 IPC 서비스에 대한 연결을 생성합니다. 자세한 내용은 [AWS IoT Greengrass 코어 IPC 서비스에 연결](interprocess-communication.md#ipc-service-connect) 단원을 참조하십시오.

```
package com.aws.greengrass.docs.samples.ipc;

import com.aws.greengrass.docs.samples.ipc.util.IPCUtils;
import software.amazon.awssdk.aws.greengrass.DeleteThingShadowResponseHandler;
import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClient;
import software.amazon.awssdk.aws.greengrass.model.DeleteThingShadowRequest;
import software.amazon.awssdk.aws.greengrass.model.DeleteThingShadowResponse;
import software.amazon.awssdk.aws.greengrass.model.ResourceNotFoundError;
import software.amazon.awssdk.aws.greengrass.model.UnauthorizedError;
import software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class DeleteThingShadow {

    public static final int TIMEOUT_SECONDS = 10;

    public static void main(String[] args) {
        // Use the current core device's name if thing name isn't set.
        String thingName = args[0].isEmpty() ? System.getenv("AWS_IOT_THING_NAME") : args[0];
        String shadowName = args[1];
        try (EventStreamRPCConnection eventStreamRPCConnection =
                     IPCUtils.getEventStreamRpcConnection()) {
            GreengrassCoreIPCClient ipcClient =
                    new GreengrassCoreIPCClient(eventStreamRPCConnection);
            DeleteThingShadowResponseHandler responseHandler =
                    DeleteThingShadow.deleteThingShadow(ipcClient, thingName, shadowName);
            CompletableFuture<DeleteThingShadowResponse> futureResponse =
                    responseHandler.getResponse();
            try {
                futureResponse.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
                System.out.printf("Successfully deleted shadow: %s/%s%n", thingName, shadowName);
            } catch (TimeoutException e) {
                System.err.printf("Timeout occurred while deleting shadow: %s/%s%n", thingName,
                        shadowName);
            } catch (ExecutionException e) {
                if (e.getCause() instanceof UnauthorizedError) {
                    System.err.printf("Unauthorized error while deleting shadow: %s/%s%n",
                            thingName, shadowName);
                } else if (e.getCause() instanceof ResourceNotFoundError) {
                    System.err.printf("Unable to find shadow to delete: %s/%s%n", thingName,
                            shadowName);
                } else {
                    throw e;
                }
            }
        } catch (InterruptedException e) {
            System.out.println("IPC interrupted.");
        } catch (ExecutionException e) {
            System.err.println("Exception occurred when using IPC.");
            e.printStackTrace();
            System.exit(1);
        }
    }

    public static DeleteThingShadowResponseHandler deleteThingShadow(GreengrassCoreIPCClient greengrassCoreIPCClient, String thingName, String shadowName) {
        DeleteThingShadowRequest deleteThingShadowRequest = new DeleteThingShadowRequest();
        deleteThingShadowRequest.setThingName(thingName);
        deleteThingShadowRequest.setShadowName(shadowName);
        return greengrassCoreIPCClient.deleteThingShadow(deleteThingShadowRequest,
                Optional.empty());
    }
}
```

------
#### [ Python (IPC client V1) ]

**Example 예: 사물 섀도 삭제**  

```
import awsiot.greengrasscoreipc
import awsiot.greengrasscoreipc.client as client
from awsiot.greengrasscoreipc.model import DeleteThingShadowRequest

TIMEOUT = 10

def sample_delete_thing_shadow_request(thingName, shadowName):
    try:
        # set up IPC client to connect to the IPC server
        ipc_client = awsiot.greengrasscoreipc.connect()
                
        # create the DeleteThingShadow request
        delete_thing_shadow_request = DeleteThingShadowRequest()
        delete_thing_shadow_request.thing_name = thingName
        delete_thing_shadow_request.shadow_name = shadowName
                        
        # retrieve the DeleteThingShadow response after sending the request to the IPC server
        op = ipc_client.new_delete_thing_shadow()
        op.activate(delete_thing_shadow_request)
        fut = op.get_response()
        
        result = fut.result(TIMEOUT)
        return result.payload
        
    except InvalidArgumentsError as e:
        # add error handling
    ...
    # except ResourceNotFoundError | UnauthorizedError | ServiceError
```

------
#### [ JavaScript ]

**Example 예: 사물 섀도 삭제**  

```
import {
    DeleteThingShadowRequest
} from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc/model';
import * as greengrasscoreipc from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc';

class DeleteThingShadow {
    private ipcClient: greengrasscoreipc.Client;
    private thingName: string;
    private shadowName: string;

    constructor() {
        // Define args parameters here
        this.thingName = "<define_your_own_thingName>";
        this.shadowName = "<define_your_own_shadowName>";
        this.bootstrap();
    }

    async bootstrap() {
        try {
            this.ipcClient = await getIpcClient();
        } catch (err) {
            // parse the error depending on your use cases
            throw err
        }

        try {
            await this.handleDeleteThingShadowOperation(this.thingName, this.shadowName)
        } catch (err) {
            // parse the error depending on your use cases
            throw err
        }
    }

    async handleDeleteThingShadowOperation(thingName: string, shadowName: string) {
        const request: DeleteThingShadowRequest = {
            thingName: thingName,
            shadowName: shadowName
        }
        // make the DeleteThingShadow request
        const response = await this.ipcClient.deleteThingShadow(request);
    }
}

export async function getIpcClient() {
    try {
        const ipcClient = greengrasscoreipc.createClient();
        await ipcClient.connect()
            .catch(error => {
                // parse the error depending on your use cases
                throw error;
            });
        return ipcClient
    } catch (err) {
        // parse the error depending on your use cases
        throw err
    }
}

const startScript = new DeleteThingShadow();
```

------

## ListNamedShadowsForThing
<a name="ipc-operation-listnamedshadowsforthing"></a>

지정한 사물에 대한 이름 지정된 섀도를 나열합니다.

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

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

`thingName`(Python: `thing_name`)  <a name="ipc-local-shadows-thing-name"></a>
 사물의 이름입니다.  
유형: `string`

`pageSize`(Python: `page_size`)  
(선택 사항) 각 호출에서 반환할 섀도 이름의 수입니다.  
유형: `integer`  
기본값: 25  
최대: 100

`nextToken`(Python: `next_token`)  
(선택 사항) 다음 결과 집합을 검색하기 위한 토큰입니다. 이 값은 페이징된 결과에서 반환되며 다음 페이지를 반환하는 호출에 사용됩니다.  
유형: `string`

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

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

`results`  
섀도 이름 목록입니다.  
유형: `array`

`timestamp`  
(선택 사항) 응답이 생성된 날짜 및 시간입니다.  
유형: `integer`

`nextToken`(Python: `next_token`)  
(선택 사항) 시퀀스의 다음 페이지를 검색하기 위해 페이징된 요청에 사용할 토큰 값입니다. 반환할 섀도 이름이 더 이상 없는 경우에는 이 속성이 없습니다.  
유형: `string`  
요청된 페이지 크기가 응답의 섀도 이름 수와 정확히 일치하면 이 토큰이 있지만, 사용 시 빈 목록을 반환합니다.

### 오류
<a name="ipc-operation-listnamedshadowsforthing-errors"></a>

이 작업은 다음 오류를 반환할 수 있습니다.

`InvalidArgumentsError`  <a name="ipc-invalidargumentserror"></a>
<a name="ipc-invalidargumentserror-para"></a>로컬 섀도 서비스에서 요청 파라미터를 검증할 수 없습니다. 요청에 잘못된 형식의 JSON 또는 지원되지 않는 문자가 포함된 경우 발생할 수 있습니다.

`ResourceNotFoundError`  <a name="ipc-resourcenotfounderror"></a>
요청된 로컬 섀도 문서를 찾을 수 없습니다.

`ServiceError`  <a name="ipc-serviceerror"></a>
내부 서비스 오류가 발생했거나, IPC 서비스에 대한 요청 수가 섀도 관리자 구성 요소의 `maxLocalRequestsPerSecondPerThing` 및 `maxTotalLocalRequestsRate` 구성 파라미터에 지정된 제한을 초과했습니다.

`UnauthorizedError`  <a name="ipc-unauthorizederror"></a>
구성 요소의 권한 부여 정책에 이 작업에 필요한 권한이 포함되어 있지 않습니다.

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

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

------
#### [ Java (IPC client V1) ]

**Example 예: 사물의 이름 지정된 섀도 나열**  
이 예제에서는 `IPCUtils` 클래스를 사용하여 AWS IoT Greengrass 코어 IPC 서비스에 대한 연결을 생성합니다. 자세한 내용은 [AWS IoT Greengrass 코어 IPC 서비스에 연결](interprocess-communication.md#ipc-service-connect) 단원을 참조하십시오.

```
package com.aws.greengrass.docs.samples.ipc;

import com.aws.greengrass.docs.samples.ipc.util.IPCUtils;
import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClient;
import software.amazon.awssdk.aws.greengrass.ListNamedShadowsForThingResponseHandler;
import software.amazon.awssdk.aws.greengrass.model.ListNamedShadowsForThingRequest;
import software.amazon.awssdk.aws.greengrass.model.ListNamedShadowsForThingResponse;
import software.amazon.awssdk.aws.greengrass.model.ResourceNotFoundError;
import software.amazon.awssdk.aws.greengrass.model.UnauthorizedError;
import software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ListNamedShadowsForThing {

    public static final int TIMEOUT_SECONDS = 10;

    public static void main(String[] args) {
        // Use the current core device's name if thing name isn't set.
        String thingName = args[0].isEmpty() ? System.getenv("AWS_IOT_THING_NAME") : args[0];
        try (EventStreamRPCConnection eventStreamRPCConnection =
                     IPCUtils.getEventStreamRpcConnection()) {
            GreengrassCoreIPCClient ipcClient =
                    new GreengrassCoreIPCClient(eventStreamRPCConnection);
            List<String> namedShadows = new ArrayList<>();
            String nextToken = null;
            try {
                // Send additional requests until there's no pagination token in the response.
                do {
                    ListNamedShadowsForThingResponseHandler responseHandler =
                            ListNamedShadowsForThing.listNamedShadowsForThing(ipcClient, thingName,
                                    nextToken, 25);
                    CompletableFuture<ListNamedShadowsForThingResponse> futureResponse =
                            responseHandler.getResponse();
                    ListNamedShadowsForThingResponse response =
                            futureResponse.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
                    List<String> responseNamedShadows = response.getResults();
                    namedShadows.addAll(responseNamedShadows);
                    nextToken = response.getNextToken();
                } while (nextToken != null);
                System.out.printf("Successfully got named shadows for thing %s: %s%n", thingName,
                        String.join(",", namedShadows));
            } catch (TimeoutException e) {
                System.err.println("Timeout occurred while listing named shadows for thing: " + thingName);
            } catch (ExecutionException e) {
                if (e.getCause() instanceof UnauthorizedError) {
                    System.err.println("Unauthorized error while listing named shadows for " +
                            "thing: " + thingName);
                } else if (e.getCause() instanceof ResourceNotFoundError) {
                    System.err.println("Unable to find thing to list named shadows: " + thingName);
                } else {
                    throw e;
                }
            }
        } catch (InterruptedException e) {
            System.out.println("IPC interrupted.");
        } catch (ExecutionException e) {
            System.err.println("Exception occurred when using IPC.");
            e.printStackTrace();
            System.exit(1);
        }
    }

    public static ListNamedShadowsForThingResponseHandler listNamedShadowsForThing(GreengrassCoreIPCClient greengrassCoreIPCClient, String thingName, String nextToken, int pageSize) {
        ListNamedShadowsForThingRequest listNamedShadowsForThingRequest =
                new ListNamedShadowsForThingRequest();
        listNamedShadowsForThingRequest.setThingName(thingName);
        listNamedShadowsForThingRequest.setNextToken(nextToken);
        listNamedShadowsForThingRequest.setPageSize(pageSize);
        return greengrassCoreIPCClient.listNamedShadowsForThing(listNamedShadowsForThingRequest,
                Optional.empty());
    }
}
```

------
#### [ Python (IPC client V1) ]

**Example 예: 사물의 이름 지정된 섀도 나열**  

```
import awsiot.greengrasscoreipc
import awsiot.greengrasscoreipc.client as client
from awsiot.greengrasscoreipc.model import ListNamedShadowsForThingRequest

TIMEOUT = 10

def sample_list_named_shadows_for_thing_request(thingName, nextToken, pageSize):
    try:
        # set up IPC client to connect to the IPC server
        ipc_client = awsiot.greengrasscoreipc.connect()
                
        # create the ListNamedShadowsForThingRequest request
        list_named_shadows_for_thing_request = ListNamedShadowsForThingRequest()
        list_named_shadows_for_thing_request.thing_name = thingName
        list_named_shadows_for_thing_request.next_token = nextToken
        list_named_shadows_for_thing_request.page_size = pageSize
        
        # retrieve the ListNamedShadowsForThingRequest response after sending the request to the IPC server
        op = ipc_client.new_list_named_shadows_for_thing()
        op.activate(list_named_shadows_for_thing_request)
        fut = op.get_response()
        
        list_result = fut.result(TIMEOUT)
        
        # additional returned fields
        timestamp = list_result.timestamp
        next_token = result.next_token
        named_shadow_list = list_result.results
        
        return named_shadow_list, next_token, timestamp
                
    except InvalidArgumentsError as e:
        # add error handling
    ...
    # except ResourceNotFoundError | UnauthorizedError | ServiceError
```

------
#### [ JavaScript ]

**Example 예: 사물의 이름 지정된 섀도 나열**  

```
import {
    ListNamedShadowsForThingRequest
} from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc/model';
import * as greengrasscoreipc from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc';

class listNamedShadowsForThing {
    private ipcClient: greengrasscoreipc.Client;
    private thingName: string;
    private pageSizeStr: string;
    private nextToken: string;

    constructor() {
        // Define args parameters here
        this.thingName = "<define_your_own_thingName>";
        this.pageSizeStr = "<define_your_own_pageSize>";
        this.nextToken = "<define_your_own_token>";
        this.bootstrap();
    }

    async bootstrap() {
        try {
            this.ipcClient = await getIpcClient();
        } catch (err) {
            // parse the error depending on your use cases
            throw err
        }
        
        try {
            await this.handleListNamedShadowsForThingOperation(this.thingName,
                this.nextToken, this.pageSizeStr);
        } catch (err) {
            // parse the error depending on your use cases
            throw err
        }
    }

    async handleListNamedShadowsForThingOperation(
        thingName: string,
        nextToken: string,
        pageSizeStr: string
    ) {
        let request: ListNamedShadowsForThingRequest = {
            thingName: thingName,
            nextToken: nextToken,
        };
        if (pageSizeStr) {
            request.pageSize = parseInt(pageSizeStr);
        }
        // make the ListNamedShadowsForThing request
        const response = await this.ipcClient.listNamedShadowsForThing(request);
        const shadowNames = response.results;
    }
}

export async function getIpcClient(){
    try {
        const ipcClient = greengrasscoreipc.createClient();
        await ipcClient.connect()
            .catch(error => {
                // parse the error depending on your use cases
                throw error;
            });
        return ipcClient
    } catch (err) {
        // parse the error depending on your use cases
        throw err
    }
}

const startScript = new listNamedShadowsForThing();
```

------