

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Úselo SDK para dispositivos con AWS IoT para comunicarse con el núcleo de Greengrass, otros componentes y AWS IoT Core
<a name="interprocess-communication"></a>

Los componentes que se ejecutan en su dispositivo principal pueden utilizar la biblioteca de comunicación entre procesos (IPC) del AWS IoT Greengrass núcleo SDK para dispositivos con AWS IoT para comunicarse con el AWS IoT Greengrass núcleo y otros componentes de Greengrass. Para desarrollar y ejecutar componentes personalizados que utilicen la IPC, debe utilizarla SDK para dispositivos con AWS IoT para conectarse al servicio AWS IoT Greengrass Core IPC y realizar las operaciones de IPC.

La interfaz de IPC admite dos tipos de operaciones:
+ **Solicitud/respuesta**

  Los componentes envían una solicitud al servicio de IPC y reciben una respuesta que contiene el resultado de la solicitud.
+ **Suscripción**

  Los componentes envían una solicitud de suscripción al servicio de IPC y esperan recibir un flujo de mensajes de eventos como respuesta. Los componentes proporcionan un controlador de suscripciones que gestiona los mensajes de eventos, los errores y el cierre del flujo. SDK para dispositivos con AWS IoT Incluye una interfaz de controlador con la respuesta y los tipos de eventos correctos para cada operación de IPC. Para obtener más información, consulte [Suscripción a los flujos de eventos de IPC](#ipc-subscribe-operations).

**Topics**
+ [Versiones de cliente de IPC](#ipc-client-versions)
+ [Compatible con SDKs la comunicación entre procesos](#ipc-requirements)
+ [Conéctese al AWS IoT Greengrass servicio Core IPC](#ipc-service-connect)
+ [Autorización de los componentes para realizar operaciones de IPC](#ipc-authorization-policies)
+ [Suscripción a los flujos de eventos de IPC](#ipc-subscribe-operations)
+ [Prácticas recomendadas de IPC](#ipc-best-practices)
+ [Publicar/suscribir mensajes locales](ipc-publish-subscribe.md)
+ [Publicar/suscribir mensajes MQTT AWS IoT Core](ipc-iot-core-mqtt.md)
+ [Interacción con el ciclo de vida del componente](ipc-component-lifecycle.md)
+ [Interacción con la configuración de componentes](ipc-component-configuration.md)
+ [Recupere valores secretos](ipc-secret-manager.md)
+ [Interactúe con las sombras locales](ipc-local-shadows.md)
+ [Administre las implementaciones y los componentes locales](ipc-local-deployments-components.md)
+ [Autenticación y autorización de los dispositivos de cliente](ipc-client-device-auth.md)

## Versiones de cliente de IPC
<a name="ipc-client-versions"></a>

En versiones posteriores de Java y Python SDKs, AWS IoT Greengrass proporciona una versión mejorada del cliente IPC, denominada cliente IPC V2. Cliente de IPC V2:
+ Reduce la cantidad de código que debe escribirse para utilizar las operaciones de IPC y ayuda a evitar errores habituales que pueden producirse con el cliente de IPC V1.
+ Realiza devoluciones de llamadas a los controladores de suscripciones en un subproceso independiente, por lo que ahora puede ejecutar código de bloqueo, incluidas las llamadas a funciones de IPC adicionales, en las devoluciones de llamadas a los controladores de suscripciones. El cliente de IPC V1 utiliza el mismo subproceso para comunicarse con el servidor de IPC y para llamar al controlador de suscripciones.
+ Permite llamar a las operaciones de suscripción mediante expresiones Lambda (Java) o funciones (Python). El cliente de IPC V1 requiere que defina las clases de controladores de suscripciones.
+ Proporciona versiones sincrónicas y asincrónicas de cada operación de IPC. El cliente de IPC V1 proporciona solo versiones asíncronas de cada operación.

Recomendamos utilizar el cliente de IPC V2 para aprovechar estas mejoras. Sin embargo, muchos ejemplos de esta documentación y de algunos contenidos en línea muestran únicamente cómo utilizar el cliente de IPC V1. Puede utilizar los siguientes ejemplos y tutoriales para ver ejemplos de componentes que utilizan el cliente de IPC V2:
+ [PublishToTopicejemplos](ipc-publish-subscribe.md#ipc-operation-publishtotopic-examples)
+ [SubscribeToTopicejemplos](ipc-publish-subscribe.md#ipc-operation-subscribetotopic-examples)
+ [Tutorial: Desarrollo de un componente de Greengrass que aplace las actualizaciones de los componentes](defer-component-updates-tutorial.md)
+ [Tutorial: interactúe con dispositivos IoT locales a través de MQTT](client-devices-tutorial.md)

Actualmente, la versión 2 SDK para dispositivos con AWS IoT para C\$1\$1 solo admite el cliente IPC V1.

## Compatible con SDKs la comunicación entre procesos
<a name="ipc-requirements"></a>

Las bibliotecas AWS IoT Greengrass Core IPC se incluyen en las siguientes SDK para dispositivos con AWS IoT versiones.


| SDK | Versión mínima | De uso | 
| --- | --- | --- | 
|  [SDK para dispositivos con AWS IoT para Java v2](https://github.com/aws/aws-iot-device-sdk-java-v2)  |  Versión 1.6.0  |  Consulte [Úselo SDK para dispositivos con AWS IoT para Java v2 (cliente IPC V2)](#ipc-java-v2)  | 
|  [SDK para dispositivos con AWS IoT para Python v2](https://github.com/aws/aws-iot-device-sdk-python-v2)  |  Versión 1.9.0  |  Consulte [Uso SDK para dispositivos con AWS IoT para Python v2 (cliente IPC V2)](#ipc-python-v2)  | 
|  [SDK para dispositivos con AWS IoT para C\$1\$1 v2](https://github.com/aws/aws-iot-device-sdk-cpp-v2)  |  Versión 1.17.0  |  Consulte [Úselo SDK para dispositivos con AWS IoT para C\$1\$1 v2](#ipc-cpp)  | 
|  [SDK para dispositivos con AWS IoT para JavaScript v2](https://github.com/aws/aws-iot-device-sdk-js-v2)  |  Versión 1.12.0  |  Consulte [Úselo SDK para dispositivos con AWS IoT para la JavaScript versión 2 (cliente IPC V1)](#ipc-nodejs)  | 

## Conéctese al AWS IoT Greengrass servicio Core IPC
<a name="ipc-service-connect"></a>

Para utilizar la comunicación entre procesos en su componente personalizado, debe crear una conexión a un socket de servidor IPC que ejecute el software AWS IoT Greengrass Core. Realice las siguientes tareas para descargarlo y usarlo SDK para dispositivos con AWS IoT en el idioma que prefiera. 

### Úselo SDK para dispositivos con AWS IoT para Java v2 (cliente IPC V2)
<a name="ipc-java-v2"></a>

**Para usar la versión 2 SDK para dispositivos con AWS IoT para Java (cliente IPC V2)**

1. Descargue el [SDK para dispositivos con AWS IoT para Java v2](https://github.com/aws/aws-iot-device-sdk-java-v2) (versión 1.6.0 o posterior).

1. <a name="use-ipc-java-component-install-step"></a>Tome alguna de las siguientes medidas para ejecutar el código personalizado en su componente:
   + Cree el componente como un archivo JAR que incluya el SDK para dispositivos con AWS IoT archivo JAR y ejecútelo en la receta del componente.
   + Defina el SDK para dispositivos con AWS IoT JAR como un artefacto de componente y añada ese artefacto a la ruta de clases cuando ejecute la aplicación en la receta de su componente.

1. Utilice el siguiente código para crear el cliente de IPC.

   ```
   try (GreengrassCoreIPCClientV2 ipcClient = GreengrassCoreIPCClientV2.builder().build()) {
       // Use client.
   } catch (Exception e) {
       LOGGER.log(Level.SEVERE, "Exception occurred when using IPC.", e);
       System.exit(1);
   }
   ```

### Uso SDK para dispositivos con AWS IoT para Python v2 (cliente IPC V2)
<a name="ipc-python-v2"></a>

**Para usar SDK para dispositivos con AWS IoT para Python v2 (cliente IPC V2)**

1. Descargue el [SDK para dispositivos con AWS IoT para Python](https://github.com/aws/aws-iot-device-sdk-python-v2) (versión 1.9.0 o posterior).

1. <a name="use-ipc-python-component-install-step"></a>Agregue los [pasos de instalación](https://github.com/aws/aws-iot-device-sdk-python-v2#installation) del SDK al ciclo de vida de instalación en la receta de su componente.

1. Cree una conexión con el servicio AWS IoT Greengrass Core IPC. Utilice el siguiente código para crear el cliente de IPC.

   ```
   from awsiot.greengrasscoreipc.clientv2 import GreengrassCoreIPCClientV2
   
   try:
       ipc_client = GreengrassCoreIPCClientV2()
       # Use IPC client.
   except Exception:
       print('Exception occurred when using IPC.', file=sys.stderr)
       traceback.print_exc()
       exit(1)
   ```

### Úselo SDK para dispositivos con AWS IoT para C\$1\$1 v2
<a name="ipc-cpp"></a>

<a name="iot-device-sdk-cpp-v2-build-requirements-intro"></a>Para compilar la SDK para dispositivos con AWS IoT versión 2 para C\$1\$1, un dispositivo debe tener las siguientes herramientas:<a name="iot-device-sdk-cpp-v2-build-requirements"></a>
+ C\$1\$1 11 o posterior
+ CMake 3.1 o posterior
+ Uno de los siguientes copiladores:
  + GCC 4.8 o posterior
  + Clang 3.9 o posterior
  + MSVC 2015 o posterior

**Para usar la versión 2 SDK para dispositivos con AWS IoT para C\$1\$1**

1. Descargue el [SDK para dispositivos con AWS IoT para C\$1\$1 v2](https://github.com/aws/aws-iot-device-sdk-cpp-v2) (versión 1.17.0 o posterior).

1. Siga las [instrucciones de instalación del archivo README](https://github.com/aws/aws-iot-device-sdk-cpp-v2#Installation) para compilar la versión 2 SDK para dispositivos con AWS IoT para C\$1\$1 a partir del código fuente.

1. En la herramienta de compilación de C\$1\$1, vincule la biblioteca de IPC de Greengrass, `AWS::GreengrassIpc-cpp`, que creó en el paso anterior. El siguiente `CMakeLists.txt` ejemplo vincula la biblioteca IPC de Greengrass a un proyecto con el que se crea. CMake

   ```
   cmake_minimum_required(VERSION 3.1)
   project (greengrassv2_pubsub_subscriber)
   
   file(GLOB MAIN_SRC
           "*.h"
           "*.cpp"
           )
   add_executable(${PROJECT_NAME} ${MAIN_SRC})
   
   set_target_properties(${PROJECT_NAME} PROPERTIES
           LINKER_LANGUAGE CXX
           CXX_STANDARD 11)
   find_package(aws-crt-cpp PATHS ~/sdk-cpp-workspace/build)
   find_package(EventstreamRpc-cpp PATHS ~/sdk-cpp-workspace/build)
   find_package(GreengrassIpc-cpp PATHS ~/sdk-cpp-workspace/build)
   target_link_libraries(${PROJECT_NAME} AWS::GreengrassIpc-cpp)
   ```

1. En el código del componente, cree una conexión al servicio AWS IoT Greengrass Core IPC para crear un cliente IPC (). `Aws::Greengrass::GreengrassCoreIpcClient` Debe definir un controlador del ciclo de vida de las conexiones de IPC que gestione los eventos de conexión, desconexión y error de IPC. El siguiente ejemplo crea un cliente de IPC y un controlador del ciclo de vida de las conexiones de IPC que se imprimen cuando el cliente de IPC se conecta, se desconecta y detecta errores.

   ```
   #include <iostream>
   
   #include <aws/crt/Api.h>
   #include <aws/greengrass/GreengrassCoreIpcClient.h>
   
   using namespace Aws::Crt;
   using namespace Aws::Greengrass;
   
   class IpcClientLifecycleHandler : public ConnectionLifecycleHandler {
       void OnConnectCallback() override {
           std::cout << "OnConnectCallback" << std::endl;
       }
   
       void OnDisconnectCallback(RpcError error) override {
           std::cout << "OnDisconnectCallback: " << error.StatusToString() << std::endl;
           exit(-1);
       }
   
       bool OnErrorCallback(RpcError error) override {
           std::cout << "OnErrorCallback: " << error.StatusToString() << std::endl;
           return true;
       }
   };
   
   int main() {
       // Create the IPC client.
       ApiHandle apiHandle(g_allocator);
       Io::EventLoopGroup eventLoopGroup(1);
       Io::DefaultHostResolver socketResolver(eventLoopGroup, 64, 30);
       Io::ClientBootstrap bootstrap(eventLoopGroup, socketResolver);
       IpcClientLifecycleHandler ipcLifecycleHandler;
       GreengrassCoreIpcClient ipcClient(bootstrap);
       auto connectionStatus = ipcClient.Connect(ipcLifecycleHandler).get();
       if (!connectionStatus) {
           std::cerr << "Failed to establish IPC connection: " << connectionStatus.StatusToString() << std::endl;
           exit(-1);
       }
       
       // Use the IPC client to create an operation request.
       
       // Activate the operation request.
       auto activate = operation.Activate(request, nullptr);
       activate.wait();
   
       // Wait for Greengrass Core to respond to the request.
       auto responseFuture = operation.GetResult();
       if (responseFuture.wait_for(std::chrono::seconds(timeout)) == std::future_status::timeout) {
           std::cerr << "Operation timed out while waiting for response from Greengrass Core." << std::endl;
           exit(-1);
       }
   
       // Check the result of the request.
       auto response = responseFuture.get();
       if (response) {
           std::cout << "Successfully published to topic: " << topic << std::endl;
       } else {
           // An error occurred.
           std::cout << "Failed to publish to topic: " << topic << std::endl;
           auto errorType = response.GetResultType();
           if (errorType == OPERATION_ERROR) {
               auto *error = response.GetOperationError();
               std::cout << "Operation error: " << error->GetMessage().value() << std::endl;
           } else {
               std::cout << "RPC error: " << response.GetRpcError() << std::endl;
           }
           exit(-1);
       }
       
       return 0;
   }
   ```

1. Para ejecutar el código personalizado en el componente, cree el código como un artefacto binario y ejecute el artefacto binario en la receta del componente. Establezca el `Execute` permiso del artefacto para `OWNER` permitir que el software AWS IoT Greengrass principal ejecute el artefacto binario.

   La sección `Manifests` de la receta de su componente podría parecerse al siguiente ejemplo.

------
#### [ JSON ]

   ```
   {
     ...
     "Manifests": [
       {
         "Lifecycle": {
           "Run": "{artifacts:path}/greengrassv2_pubsub_subscriber"
         },
         "Artifacts": [
           {
             "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.PubSubSubscriberCpp/1.0.0/greengrassv2_pubsub_subscriber",
             "Permission": {
               "Execute": "OWNER"
             }
           }
         ]
       }
     ]
   }
   ```

------
#### [ YAML ]

   ```
   ...
   Manifests:
     - Lifecycle:
         Run: {artifacts:path}/greengrassv2_pubsub_subscriber
       Artifacts:
         - URI: s3://amzn-s3-demo-bucket/artifacts/com.example.PubSubSubscriberCpp/1.0.0/greengrassv2_pubsub_subscriber
           Permission:
             Execute: OWNER
   ```

------

### Úselo SDK para dispositivos con AWS IoT para la JavaScript versión 2 (cliente IPC V1)
<a name="ipc-nodejs"></a>

<a name="iot-device-sdk-nodejs-build-requirements-intro"></a>Para compilar la JavaScript versión 2 SDK para dispositivos con AWS IoT para usarla con Nodejs, un dispositivo debe tener las siguientes herramientas:<a name="iot-device-sdk-nodejs-build-requirements"></a>
+ Node.JS 10.0 o posterior
  + Ejecute `node -v` para comprobar la versión de Node.
+ CMake 3.1 o posterior

**Para usar la SDK para dispositivos con AWS IoT JavaScript versión 2 (cliente IPC V1)**

1. Descargue la [ JavaScript versión SDK para dispositivos con AWS IoT para la versión 2](https://github.com/aws/aws-iot-device-sdk-js-v2) (v1.12.10 o posterior).

1. Siga las [instrucciones de instalación del archivo README para compilar la versión](https://github.com/aws/aws-iot-device-sdk-js-v2/tree/v1.12.1#installation) para la versión 2 a partir del código SDK para dispositivos con AWS IoT fuente JavaScript.

1. Cree una conexión al servicio AWS IoT Greengrass Core IPC. Realice los siguientes pasos para crear el cliente de IPC y establecer una conexión.

1. Utilice el siguiente código para crear el cliente de IPC.

   ```
   import * as greengrascoreipc from 'aws-iot-device-sdk-v2';
   
   let client = greengrascoreipc.createClient();
   ```

1. Utilice el siguiente código para establecer una conexión entre el componente y el núcleo de Greengrass.

   ```
   await client.connect();
   ```

## Autorización de los componentes para realizar operaciones de IPC
<a name="ipc-authorization-policies"></a>

Para permitir que sus componentes personalizados utilicen algunas operaciones de IPC, debe definir *políticas de autorización* que permitan al componente realizar la operación en determinados recursos. Cada política de autorización define una lista de operaciones y una lista de recursos que la política permite. Por ejemplo, el servicio IPC de publish/subscribe mensajería define las operaciones de publicación y suscripción de los recursos temáticos. Puede utilizar el comodín `*` para permitir el acceso a todas las operaciones o a todos los recursos.

Las políticas de autorización se definen con el parámetro de configuración `accessControl`, que se puede establecer en la receta del componente o al implementar el componente. El objeto `accessControl` asigna los identificadores del servicio de IPC a listas de políticas de autorización. Puede definir varias políticas de autorización para cada servicio de IPC a fin de controlar el acceso. Cada política de autorización tiene un identificador de política, que debe ser único entre todos los componentes.

**sugerencia**  
Para crear una política única IDs, puede combinar el nombre del componente, el nombre del servicio de IPC y un contador. Por ejemplo, un componente denominado `com.example.HelloWorld` podría definir dos políticas de publish/subscribe autorización con lo siguiente: IDs  
`com.example.HelloWorld:pubsub:1`
`com.example.HelloWorld:pubsub:2`

Las políticas de autorización utilizan el siguiente formato. Este objeto es el parámetro de configuración `accessControl`.

------
#### [ JSON ]

```
{
  "IPC service identifier": {
    "policyId": {
      "policyDescription": "description",
      "operations": [
        "operation1",
        "operation2"
      ],
      "resources": [
        "resource1",
        "resource2"
      ]
    }
  }
}
```

------
#### [ YAML ]

```
IPC service identifier:
  policyId:
    policyDescription: description
    operations:
      - operation1
      - operation2
    resources:
      - resource1
      - resource2
```

------

### Comodines en las políticas de autorización
<a name="ipc-authorization-policy-wildcards"></a>

Puede utilizar el comodín `*` en el elemento `resources` de las políticas de autorización del IPC para permitir el acceso a varios recursos en una única política de autorización.
+ En todas las versiones del [núcleo de Greengrass](greengrass-nucleus-component.md), puede especificar un solo carácter `*` como recurso para permitir el acceso a todos los recursos.
+ En [el núcleo de Greengrass](greengrass-nucleus-component.md) versión 2.6.0 y versiones posteriores, puede especificar el carácter `*` de un recurso para que coincida con cualquier combinación de caracteres. Por ejemplo, puede especificar `factory/1/devices/Thermostat*/status` para permitir el acceso a un tema de estado para todos los dispositivos de termostato de una fábrica, donde el nombre de cada dispositivo comience con `Thermostat`.

Al definir políticas de autorización para el servicio IPC de AWS IoT Core MQTT, también puede utilizar los caracteres comodín (`+`y`#`) de MQTT para hacer coincidir varios recursos. Para obtener más información, consulte los [caracteres comodín de MQTT en las políticas de autorización de IPC de MQTT](ipc-iot-core-mqtt.md#ipc-iot-core-mqtt-authorization-mqtt-wildcards). AWS IoT Core 

### Variables de receta en las políticas de autorización
<a name="ipc-authorization-policy-recipe-variables"></a>

[Si usa [Greengrass nucleus](greengrass-nucleus-component.md) v2.6.0 o posterior y establece la opción de [interpolateComponentConfiguration](greengrass-nucleus-component.md#greengrass-nucleus-component-configuration-interpolate-component-configuration)configuración del núcleo de Greengrass en`true`, puede usar la variable de receta en las políticas de autorización. `{iot:thingName}`](component-recipe-reference.md#recipe-variables) Cuando necesite una política de autorización que incluya el nombre del dispositivo principal, como en el caso de temas de MQTT o sombras de dispositivo, puede utilizar esta variable de receta para configurar una política de autorización única para un grupo de dispositivos principales. Por ejemplo, puede permitir que un componente acceda al siguiente recurso para realizar operaciones de IPC de sombra.

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

### Caracteres especiales en las políticas de autorización
<a name="ipc-authorization-policy-special-characters"></a>

Para especificar un literal `*` o un carácter `?` en una política de autorización, debe utilizar una secuencia de escape. Las siguientes secuencias de escape indican al software AWS IoT Greengrass Core que utilice el valor literal en lugar del significado especial del carácter. Por ejemplo, el carácter `*` es un [comodín](#ipc-authorization-policy-wildcards) que coincide con cualquier combinación de caracteres.


| Carácter literal | Secuencia de escape | Notas | 
| --- | --- | --- | 
|  `*`  |  `${*}`  |  | 
|  `?`  |  `${?}`  |  AWS IoT Greengrass actualmente no admite el `?` comodín, que coincide con cualquier carácter individual.  | 
|  `$`  |  `${$}`  |  Use esta secuencia de escape para hacer coincidir un recurso que contenga `${`. Por ejemplo, para que coincida con un recurso denominado `${resourceName}`, debe especificar `${$}{resourceName}`. De lo contrario, para que coincida con un recurso que contiene `$`, puede usar un literal `$`, por ejemplo, para permitir el acceso a un tema que comience por `$aws`.  | 

### Ejemplos de políticas de autorización
<a name="ipc-authorization-policy-examples"></a>

Puede consultar los siguientes ejemplos de políticas de autorización con el fin de configurar las políticas de autorización para sus componentes.

**Example Ejemplo de receta de componentes con una política de autorización**  
El siguiente ejemplo de receta de componentes incluye un objeto `accessControl` que define una política de autorización. Esta política autoriza al componente `com.example.HelloWorld` a publicar en el tema `test/topic`.  

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.HelloWorld",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that publishes messages.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.HelloWorld:pubsub:1": {
            "policyDescription": "Allows access to publish to test/topic.",
            "operations": [
              "aws.greengrass#PublishToTopic"
            ],
            "resources": [
              "test/topic"
            ]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Lifecycle": {
        "Run": "java -jar {artifacts:path}/HelloWorld.jar"
      }
    }
  ]
}
```

```
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.HelloWorld
ComponentVersion: '1.0.0'
ComponentDescription: A component that publishes messages.
ComponentPublisher: Amazon
ComponentConfiguration:
  DefaultConfiguration:
    accessControl:
      aws.greengrass.ipc.pubsub:
        "com.example.HelloWorld:pubsub:1":
          policyDescription: Allows access to publish to test/topic.
          operations:
            - "aws.greengrass#PublishToTopic"
          resources:
            - "test/topic"
Manifests:
  - Lifecycle:
      Run: |-
        java -jar {artifacts:path}/HelloWorld.jar
```

**Example Ejemplo de actualización de la configuración de un componente con una política de autorización**  
El siguiente ejemplo de actualización de configuración en una implementación especifica la configuración de un componente con un objeto `accessControl` que define una política de autorización. Esta política autoriza al componente `com.example.HelloWorld` a publicar en el tema `test/topic`.    
**Configuración de combinación**  

```
{
  "accessControl": {
    "aws.greengrass.ipc.pubsub": {
      "com.example.HelloWorld:pubsub:1": {
        "policyDescription": "Allows access to publish to test/topic.",
        "operations": [
          "aws.greengrass#PublishToTopic"
        ],
        "resources": [
          "test/topic"
        ]
      }
    }
  }
}
```
El siguiente comando crea una implementación a un dispositivo principal.  

```
aws greengrassv2 create-deployment --cli-input-json file://hello-world-deployment.json
```
El archivo `hello-world-deployment.json` contiene el siguiente documento JSON.  

```
{
  "targetArn": "arn:aws:iot:us-west-2:123456789012:thing/MyGreengrassCore",
  "deploymentName": "Deployment for MyGreengrassCore",
  "components": {
    "com.example.HelloWorld": {
      "componentVersion": "1.0.0",
      "configurationUpdate": {
        "merge": "{\"accessControl\":{\"aws.greengrass.ipc.pubsub\":{\"com.example.HelloWorld:pubsub:1\":{\"policyDescription\":\"Allows access to publish to test/topic.\",\"operations\":[\"aws.greengrass#PublishToTopic\"],\"resources\":[\"test/topic\"]}}}}"
      }
    }
  }
}
```
El siguiente comando de la [CLI de Greengrass](greengrass-cli-component.md) crea una implementación local en un dispositivo principal.  

```
sudo greengrass-cli deployment create \
  --recipeDir recipes \
  --artifactDir artifacts \
  --merge "com.example.HelloWorld=1.0.0" \
  --update-config hello-world-configuration.json
```
El archivo `hello-world-configuration.json` contiene el siguiente documento JSON.  

```
{
  "com.example.HelloWorld": {
    "MERGE": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.HelloWorld:pubsub:1": {
            "policyDescription": "Allows access to publish to test/topic.",
            "operations": [
              "aws.greengrass#PublishToTopic"
            ],
            "resources": [
              "test/topic"
            ]
          }
        }
      }
    }
  }
}
```

## Suscripción a los flujos de eventos de IPC
<a name="ipc-subscribe-operations"></a>

Puede utilizar las operaciones de IPC para suscribirse a los flujos de eventos en un dispositivo principal de Greengrass. Para utilizar una operación de suscripción, defina un *controlador de suscripciones* y cree una solicitud al servicio de IPC. A continuación, el cliente de IPC ejecuta las funciones del controlador de suscripciones cada vez que el dispositivo principal transmite un mensaje de evento a su componente.

Puede cerrar una suscripción para dejar de procesar los mensajes de eventos. Para ello, llame a `closeStream()` (Java), `close()` (Python) o `Close()` (C\$1\$1) en el objeto de operación de suscripción que utilizó para abrir la suscripción.

El servicio AWS IoT Greengrass Core IPC admite las siguientes operaciones de suscripción:
+ [SubscribeToTopic](ipc-publish-subscribe.md#ipc-operation-subscribetotopic)
+ [SubscribeToIoTCore](ipc-iot-core-mqtt.md#ipc-operation-subscribetoiotcore)
+ [SubscribeToComponentUpdates](ipc-component-lifecycle.md#ipc-operation-subscribetocomponentupdates)
+ [SubscribeToConfigurationUpdate](ipc-component-configuration.md#ipc-operation-subscribetoconfigurationupdate)
+ [SubscribeToValidateConfigurationUpdates](ipc-component-configuration.md#ipc-operation-subscribetovalidateconfigurationupdates)

**Topics**
+ [Definición de controladores de suscripción](#ipc-define-subscription-handlers)
+ [Ejemplos de controladores de suscripciones](#ipc-subscription-handler-examples)

### Definición de controladores de suscripción
<a name="ipc-define-subscription-handlers"></a>

Para definir un controlador de suscripciones, defina las funciones de devolución de llamada que gestionen los mensajes de eventos, los errores y el cierre de flujos. Si utiliza el cliente de IPC V1, debe definir estas funciones en una clase. Si usa el cliente IPC V2, que está disponible en versiones posteriores de Java y Python SDKs, puede definir estas funciones sin crear una clase de controlador de suscripciones.

------
#### [ Java ]

Si utiliza el cliente IPC V1, debe implementar la interfaz genérica. `software.amazon.awssdk.eventstreamrpc.StreamResponseHandler<StreamEventType>` *StreamEventType*es el tipo de mensaje de evento para la operación de suscripción. Defina las siguientes funciones para gestionar los mensajes de eventos, los errores y el cierre de flujos.

Si usa el cliente de IPC V2, puede definir estas funciones fuera de una clase de controlador de suscripciones o usar [expresiones lambda](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html).

`void onStreamEvent(StreamEventType event)`  
La llamada de retorno a la que llama el cliente de IPC cuando recibe un mensaje de evento, como un mensaje MQTT o una notificación de actualización de un componente.

`boolean onStreamError(Throwable error)`  
La devolución de la llamada a la que llama el cliente de IPC cuando se produce un error de flujo.  
<a name="ipc-subscription-handler-on-stream-error-return-value"></a>Devuelve true para cerrar el flujo de suscripción como resultado del error, o devuelve false para mantener el flujo abierto.

`void onStreamClosed()`  
La devolución de llamada a la que llama el cliente de IPC cuando se cierra el flujo.

------
#### [ Python ]

Si utiliza el cliente de IPC V1, debe ampliar la clase de controlador de respuesta de flujo que corresponde a la operación de suscripción. SDK para dispositivos con AWS IoT Incluye una clase de controlador de suscripciones para cada operación de suscripción. *StreamEventType*es el tipo de mensaje de evento para la operación de suscripción. Defina las siguientes funciones para gestionar los mensajes de eventos, los errores y el cierre de flujos.

Si usa el cliente de IPC V2, puede definir estas funciones fuera de una clase de controlador de suscripciones o usar [expresiones lambda](https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions).

`def on_stream_event(self, event: StreamEventType) -> None`  
La llamada de retorno a la que llama el cliente de IPC cuando recibe un mensaje de evento, como un mensaje MQTT o una notificación de actualización de un componente.

`def on_stream_error(self, error: Exception) -> bool`  
La devolución de la llamada a la que llama el cliente de IPC cuando se produce un error de flujo.  
<a name="ipc-subscription-handler-on-stream-error-return-value"></a>Devuelve true para cerrar el flujo de suscripción como resultado del error, o devuelve false para mantener el flujo abierto.

`def on_stream_closed(self) -> None`  
La devolución de llamada a la que llama el cliente de IPC cuando se cierra el flujo.

------
#### [ C\$1\$1 (IPC client V1) ]

Implemente una clase que se derive de la clase del controlador de respuesta de flujo que corresponde a la operación de suscripción. SDK para dispositivos con AWS IoT Incluye una clase base de controlador de suscripciones para cada operación de suscripción. *StreamEventType*es el tipo de mensaje de evento para la operación de suscripción. Defina las siguientes funciones para gestionar los mensajes de eventos, los errores y el cierre de flujos.

`void OnStreamEvent(StreamEventType *event)`  
La llamada de retorno a la que llama el cliente de IPC cuando recibe un mensaje de evento, como un mensaje MQTT o una notificación de actualización de un componente.

`bool OnStreamError(OperationError *error)`  
La devolución de la llamada a la que llama el cliente de IPC cuando se produce un error de flujo.  
<a name="ipc-subscription-handler-on-stream-error-return-value"></a>Devuelve true para cerrar el flujo de suscripción como resultado del error, o devuelve false para mantener el flujo abierto.

`void OnStreamClosed()`  
La devolución de llamada a la que llama el cliente de IPC cuando se cierra el flujo.

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

Implemente una clase que se derive de la clase del controlador de respuesta de flujo que corresponde a la operación de suscripción. SDK para dispositivos con AWS IoT Incluye una clase base de controlador de suscripciones para cada operación de suscripción. *StreamEventType*es el tipo de mensaje de evento para la operación de suscripción. Defina las siguientes funciones para gestionar los mensajes de eventos, los errores y el cierre de flujos.

`on(event: 'ended', listener: StreamingOperationEndedListener)`  
La devolución de llamada a la que llama el cliente de IPC cuando se cierra el flujo.

`on(event: 'streamError', listener: StreamingRpcErrorListener)`  
La devolución de la llamada a la que llama el cliente de IPC cuando se produce un error de flujo.  
<a name="ipc-subscription-handler-on-stream-error-return-value"></a>Devuelve true para cerrar el flujo de suscripción como resultado del error, o devuelve false para mantener el flujo abierto.

`on(event: 'message', listener: (message: InboundMessageType) => void)`  
La llamada de retorno a la que llama el cliente de IPC cuando recibe un mensaje de evento, como un mensaje MQTT o una notificación de actualización de un componente.

------

### Ejemplos de controladores de suscripciones
<a name="ipc-subscription-handler-examples"></a>

En el siguiente ejemplo, se muestra cómo utilizar la operación [SubscribeToTopic](ipc-publish-subscribe.md#ipc-operation-subscribetotopic) y un controlador de suscripciones para suscribirse a la mensajería de publicación y suscripción local.

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

**Example Ejemplo: suscríbase a los publish/subscribe mensajes locales**  <a name="ipc-operation-subscribetotopic-example-java-v2"></a>

```
package com.aws.greengrass.docs.samples.ipc;

import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClientV2;
import software.amazon.awssdk.aws.greengrass.SubscribeToTopicResponseHandler;
import software.amazon.awssdk.aws.greengrass.model.*;

import java.nio.charset.StandardCharsets;
import java.util.Optional;

public class SubscribeToTopicV2 {

    public static void main(String[] args) {
        String topic = args[0];
        try (GreengrassCoreIPCClientV2 ipcClient = GreengrassCoreIPCClientV2.builder().build()) {
            SubscribeToTopicRequest request = new SubscribeToTopicRequest().withTopic(topic);
            GreengrassCoreIPCClientV2.StreamingResponse<SubscribeToTopicResponse,
                    SubscribeToTopicResponseHandler> response =
                    ipcClient.subscribeToTopic(request, SubscribeToTopicV2::onStreamEvent,
                            Optional.of(SubscribeToTopicV2::onStreamError),
                            Optional.of(SubscribeToTopicV2::onStreamClosed));
            SubscribeToTopicResponseHandler responseHandler = response.getHandler();
            System.out.println("Successfully subscribed to topic: " + topic);

            // Keep the main thread alive, or the process will exit.
            try {
                while (true) {
                    Thread.sleep(10000);
                }
            } catch (InterruptedException e) {
                System.out.println("Subscribe interrupted.");
            }

            // To stop subscribing, close the stream.
            responseHandler.closeStream();
        } catch (Exception e) {
            if (e.getCause() instanceof UnauthorizedError) {
                System.err.println("Unauthorized error while publishing to topic: " + topic);
            } else {
                System.err.println("Exception occurred when using IPC.");
            }
            e.printStackTrace();
            System.exit(1);
        }
    }

    public static void onStreamEvent(SubscriptionResponseMessage subscriptionResponseMessage) {
        try {
            BinaryMessage binaryMessage = subscriptionResponseMessage.getBinaryMessage();
            String message = new String(binaryMessage.getMessage(), StandardCharsets.UTF_8);
            String topic = binaryMessage.getContext().getTopic();
            System.out.printf("Received new message on topic %s: %s%n", topic, message);
        } catch (Exception e) {
            System.err.println("Exception occurred while processing subscription response " +
                    "message.");
            e.printStackTrace();
        }
    }

    public static boolean onStreamError(Throwable error) {
        System.err.println("Received a stream error.");
        error.printStackTrace();
        return false; // Return true to close stream, false to keep stream open.
    }

    public static void onStreamClosed() {
        System.out.println("Subscribe to topic stream closed.");
    }
}
```

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

**Example Ejemplo: suscríbase a los publish/subscribe mensajes locales**  <a name="ipc-operation-subscribetotopic-example-python-v2"></a>

```
import sys
import time
import traceback

from awsiot.greengrasscoreipc.clientv2 import GreengrassCoreIPCClientV2
from awsiot.greengrasscoreipc.model import (
    SubscriptionResponseMessage,
    UnauthorizedError
)


def main():
    args = sys.argv[1:]
    topic = args[0]

    try:
        ipc_client = GreengrassCoreIPCClientV2()
        # Subscription operations return a tuple with the response and the operation.
        _, operation = ipc_client.subscribe_to_topic(topic=topic, on_stream_event=on_stream_event,
                                                     on_stream_error=on_stream_error, on_stream_closed=on_stream_closed)
        print('Successfully subscribed to topic: ' + topic)

        # Keep the main thread alive, or the process will exit.
        try:
            while True:
                time.sleep(10)
        except InterruptedError:
            print('Subscribe interrupted.')

        # To stop subscribing, close the stream.
        operation.close()
    except UnauthorizedError:
        print('Unauthorized error while subscribing to topic: ' +
              topic, file=sys.stderr)
        traceback.print_exc()
        exit(1)
    except Exception:
        print('Exception occurred', file=sys.stderr)
        traceback.print_exc()
        exit(1)


def on_stream_event(event: SubscriptionResponseMessage) -> None:
    try:
        message = str(event.binary_message.message, 'utf-8')
        topic = event.binary_message.context.topic
        print('Received new message on topic %s: %s' % (topic, message))
    except:
        traceback.print_exc()


def on_stream_error(error: Exception) -> bool:
    print('Received a stream error.', file=sys.stderr)
    traceback.print_exc()
    return False  # Return True to close stream, False to keep stream open.


def on_stream_closed() -> None:
    print('Subscribe to topic stream closed.')


if __name__ == '__main__':
    main()
```

------
#### [ C\$1\$1 (IPC client V1) ]

**Example Ejemplo: suscríbase a los publish/subscribe mensajes locales**  <a name="ipc-operation-subscribetotopic-example-cpp"></a>

```
#include <iostream>

#include </crt/Api.h>
#include <aws/greengrass/GreengrassCoreIpcClient.h>

using namespace Aws::Crt;
using namespace Aws::Greengrass;

class SubscribeResponseHandler : public SubscribeToTopicStreamHandler {
    public:
        virtual ~SubscribeResponseHandler() {}

    private:
        void OnStreamEvent(SubscriptionResponseMessage *response) override {
            auto jsonMessage = response->GetJsonMessage();
            if (jsonMessage.has_value() && jsonMessage.value().GetMessage().has_value()) {
                auto messageString = jsonMessage.value().GetMessage().value().View().WriteReadable();
                // Handle JSON message.
            } else {
                auto binaryMessage = response->GetBinaryMessage();
                if (binaryMessage.has_value() && binaryMessage.value().GetMessage().has_value()) {
                    auto messageBytes = binaryMessage.value().GetMessage().value();
                    std::string messageString(messageBytes.begin(), messageBytes.end());
                    // Handle binary message.
                }
            }
        }

        bool OnStreamError(OperationError *error) override {
            // Handle error.
            return false; // Return true to close stream, false to keep stream open.
        }

        void OnStreamClosed() override {
            // Handle close.
        }
};

class IpcClientLifecycleHandler : public ConnectionLifecycleHandler {
    void OnConnectCallback() override {
        // Handle connection to IPC service.
    }

    void OnDisconnectCallback(RpcError error) override {
        // Handle disconnection from IPC service.
    }

    bool OnErrorCallback(RpcError error) override {
        // Handle IPC service connection error.
        return true;
    }
};

int main() {
    ApiHandle apiHandle(g_allocator);
    Io::EventLoopGroup eventLoopGroup(1);
    Io::DefaultHostResolver socketResolver(eventLoopGroup, 64, 30);
    Io::ClientBootstrap bootstrap(eventLoopGroup, socketResolver);
    IpcClientLifecycleHandler ipcLifecycleHandler;
    GreengrassCoreIpcClient ipcClient(bootstrap);
    auto connectionStatus = ipcClient.Connect(ipcLifecycleHandler).get();
    if (!connectionStatus) {
        std::cerr << "Failed to establish IPC connection: " << connectionStatus.StatusToString() << std::endl;
        exit(-1);
    }

    String topic("my/topic");
    int timeout = 10;

    SubscribeToTopicRequest request;
    request.SetTopic(topic);

    //SubscribeResponseHandler streamHandler;
    auto streamHandler = MakeShared<SubscribeResponseHandler>(DefaultAllocator());
    auto operation = ipcClient.NewSubscribeToTopic(streamHandler);
    auto activate = operation->Activate(request, nullptr);
    activate.wait();

    auto responseFuture = operation->GetResult();
    if (responseFuture.wait_for(std::chrono::seconds(timeout)) == std::future_status::timeout) {
        std::cerr << "Operation timed out while waiting for response from Greengrass Core." << std::endl;
        exit(-1);
    }

    auto response = responseFuture.get();
    if (!response) {
        // Handle error.
        auto errorType = response.GetResultType();
        if (errorType == OPERATION_ERROR) {
            auto *error = response.GetOperationError();
            (void)error;
            // Handle operation error.
        } else {
            // Handle RPC error.
        }
        exit(-1);
    }

    // Keep the main thread alive, or the process will exit.
    while (true) {
        std::this_thread::sleep_for(std::chrono::seconds(10));
    }

    operation->Close();
    return 0;
}
```

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

**Example Ejemplo: suscríbase a los publish/subscribe mensajes locales**  <a name="ipc-operation-subscribetotopic-example-nodejs"></a>

```
import * as greengrasscoreipc from "aws-iot-device-sdk-v2/dist/greengrasscoreipc";
import {SubscribeToTopicRequest, SubscriptionResponseMessage} from "aws-iot-device-sdk-v2/dist/greengrasscoreipc/model";
import {RpcError} from "aws-iot-device-sdk-v2/dist/eventstream_rpc";
 
class SubscribeToTopic {
    private ipcClient : greengrasscoreipc.Client
    private readonly topic : string;
 
    constructor() {
        // define your own constructor, e.g.
        this.topic = "<define_your_topic>";
        this.subscribeToTopic().then(r => console.log("Started workflow"));
    }
 
    private async subscribeToTopic() {
        try {
            this.ipcClient = await getIpcClient();
 
            const subscribeToTopicRequest : SubscribeToTopicRequest = {
                topic: this.topic,
            }
 
            const streamingOperation = this.ipcClient.subscribeToTopic(subscribeToTopicRequest, undefined); // conditionally apply options
 
            streamingOperation.on("message", (message: SubscriptionResponseMessage) => {
                // parse the message depending on your use cases, e.g.
                if(message.binaryMessage && message.binaryMessage.message) {
                    const receivedMessage = message.binaryMessage?.message.toString();
                }
            });
 
            streamingOperation.on("streamError", (error : RpcError) => {
                // define your own error handling logic
            })
 
            streamingOperation.on("ended", () => {
                // define your own logic
            })
 
            await streamingOperation.activate();
 
            // Keep the main thread alive, or the process will exit.
            await new Promise((resolve) => setTimeout(resolve, 10000))
        } catch (e) {
            // parse the error depending on your use cases
            throw e
        }
    }
}
 
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
    }
}
 
// starting point
const subscribeToTopic = new SubscribeToTopic();
```

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

**Example Ejemplo: suscríbase a los publish/subscribe mensajes locales**  

```
use gg_sdk::{Sdk, SubscribeToTopicPayload};
use std::{thread, time::Duration};

fn main() {
    let sdk = Sdk::init();
    sdk.connect().expect("Failed to establish IPC connection");

    let topic = "my/topic";

    let callback = |topic: &str, payload: SubscribeToTopicPayload| match payload
    {
        SubscribeToTopicPayload::Binary(message) => {
            let message = String::from_utf8_lossy(message);
            println!("Received new message on topic {topic}: {message}");
        }
        SubscribeToTopicPayload::Json(_) => {
            println!("Received new message on topic {topic}: (JSON message)");
        }
    };

    let _sub = sdk
        .subscribe_to_topic(topic, &callback)
        .expect("Failed to subscribe to topic");

    println!("Successfully subscribed to topic: {topic}");

    // Keep the main thread alive, or the process will exit.
    loop {
        thread::sleep(Duration::from_secs(10));
    }
}
```

------
#### [ C ]

**Example Ejemplo: suscríbase a los publish/subscribe mensajes locales**  

```
#include <assert.h>
#include <gg/error.h>
#include <gg/ipc/client.h>
#include <gg/object.h>
#include <gg/sdk.h>
#include <gg/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

static void on_subscription_response(
    void *ctx, GgBuffer topic, GgObject payload, GgIpcSubscriptionHandle handle
) {
    (void) ctx;
    (void) handle;

    if (gg_obj_type(payload) == GG_TYPE_BUF) {
        GgBuffer message = gg_obj_into_buf(payload);
        printf(
            "Received new message on topic %.*s: %.*s\n",
            (int) topic.len,
            topic.data,
            (int) message.len,
            message.data
        );
    } else {
        assert(gg_obj_type(payload) == GG_TYPE_MAP);
        printf(
            "Received new message on topic %.*s: (JSON message)\n",
            (int) topic.len,
            topic.data
        );
    }
}

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);
    }

    GgBuffer topic = GG_STR("my/topic");

    GgIpcSubscriptionHandle handle;
    err = ggipc_subscribe_to_topic(
        topic, on_subscription_response, NULL, &handle
    );
    if (err != GG_ERR_OK) {
        fprintf(
            stderr,
            "Failed to subscribe to topic: %.*s\n",
            (int) topic.len,
            topic.data
        );
        exit(-1);
    }

    printf(
        "Successfully subscribed to topic: %.*s\n", (int) topic.len, topic.data
    );

    // 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 Ejemplo: suscríbase a los publish/subscribe mensajes locales**  

```
#include <gg/ipc/client.hpp>
#include <gg/object.hpp>
#include <unistd.h>
#include <cassert>
#include <iostream>

class ResponseHandler : public gg::ipc::LocalTopicCallback {
    void operator()(
        std::string_view topic,
        gg::Object payload,
        gg::ipc::Subscription &handle
    ) override {
        (void) handle;
        if (payload.index() == GG_TYPE_BUF) {
            std::cout << "Received new message on topic " << topic << ": "
                      << get<gg::Buffer>(payload) << "\n";
        } else {
            assert(payload.index() == GG_TYPE_MAP);
            std::cout << "Received new message on topic " << topic
                      << ": (JSON message)\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);
    }

    std::string_view topic = "my/topic";

    static ResponseHandler handler;
    error = client.subscribe_to_topic(topic, handler);
    if (error) {
        std::cerr << "Failed to subscribe to topic: " << topic << "\n";
        exit(-1);
    }

    std::cout << "Successfully subscribed to topic: " << topic << "\n";

    // Keep the main thread alive, or the process will exit.
    while (1) {
        sleep(10);
    }
}
```

------

## Prácticas recomendadas de IPC
<a name="ipc-best-practices"></a>

Las prácticas recomendadas para utilizar el IPC en los componentes personalizados difieren entre el cliente de IPC V1 y el cliente de IPC V2. Siga las prácticas recomendadas para la versión del cliente de IPC que se utilice.

------
#### [ IPC client V2 ]

El cliente de IPC V2 ejecuta las funciones de devolución de llamadas en un subproceso independiente, por lo que, en comparación con el cliente de IPC V1, hay menos pautas que seguir cuando utiliza IPC y funciones del controlador de suscripciones.
+ <a name="ipc-best-practice-reuse-one-client"></a>**Reutilización de un cliente de IPC**

  Después de crear un cliente de IPC, manténgalo abierto y reutilícelo para todas las operaciones de IPC. La creación de varios clientes utiliza recursos adicionales y puede provocar pérdidas de recursos.
+ **Tratamiento de excepciones**

  El cliente de IPC V2 registra las excepciones no detectadas en las funciones del controlador de suscripciones. Debe detectar las excepciones en las funciones de su controlador para gestionar los errores que se producen en su código.

------
#### [ IPC client V1 ]

El cliente de IPC V1 utiliza un único subproceso que se comunica con el servidor de IPC y llama a los controladores de suscripciones. Debe tener en cuenta este comportamiento sincrónico al escribir las funciones del controlador de suscripciones.
+ <a name="ipc-best-practice-reuse-one-client"></a>**Reutilización de un cliente de IPC**

  Después de crear un cliente de IPC, manténgalo abierto y reutilícelo para todas las operaciones de IPC. La creación de varios clientes utiliza recursos adicionales y puede provocar pérdidas de recursos.
+ **Ejecución del código de bloqueo de forma asincrónica**

  El cliente deI PC V1 no puede enviar nuevas solicitudes ni procesar nuevos mensajes de eventos mientras el subproceso está bloqueado. Debe ejecutar el código de bloqueo en un subproceso independiente que ejecute desde la función de controlador. El código de bloqueo incluye `sleep` llamadas, bucles que se ejecutan de forma continua y I/O solicitudes sincrónicas que tardan en completarse.
+ **Envío de nuevas solicitudes de IPC de forma asincrónica**

  El cliente de IPC V1 no puede enviar una nueva solicitud desde las funciones del controlador de suscripciones, ya que la solicitud bloquea la función del controlador si se espera una respuesta. Debe enviar las solicitudes de IPC en un subproceso independiente que ejecute desde la función de controlador.
+ **Tratamiento de excepciones**

  El cliente de IPC V1 no controla las excepciones no detectadas en las funciones del controlador de suscripciones. Si su función de controlador genera una excepción, la suscripción se cierra y la excepción no aparece en los registros de sus componentes. Debe detectar las excepciones en las funciones de su controlador para mantener la suscripción abierta y registrar los errores que se produzcan en el código.

------

# Publicar/suscribir mensajes locales
<a name="ipc-publish-subscribe"></a>

La mensajería de publicación y suscripción (pubsub) le permite enviar y recibir mensajes sobre temas. Los componentes pueden publicar mensajes en los temas para enviar mensajes a otros componentes. A continuación, los componentes que están suscritos a ese tema pueden actuar en función de los mensajes que reciben.

**nota**  
No puede utilizar este servicio de publish/subscribe IPC para publicar o suscribirse a AWS IoT Core MQTT. Para obtener más información sobre cómo intercambiar mensajes con AWS IoT Core MQTT, consulte. [Publicar/suscribir mensajes MQTT AWS IoT Core](ipc-iot-core-mqtt.md)

**Topics**
+ [Versiones mínimas de SDK](#ipc-publish-subscribe-sdk-versions)
+ [Autorización](#ipc-publish-subscribe-authorization)
+ [PublishToTopic](#ipc-operation-publishtotopic)
+ [SubscribeToTopic](#ipc-operation-subscribetotopic)
+ [Ejemplos](#ipc-publish-subscribe-examples)

## Versiones mínimas de SDK
<a name="ipc-publish-subscribe-sdk-versions"></a>

En la siguiente tabla se enumeran las versiones mínimas de las SDK para dispositivos con AWS IoT que debe utilizar para publicar y suscribirse a los mensajes de temas locales y desde ellos.


| SDK | Versión mínima | 
| --- | --- | 
|  [SDK para dispositivos con AWS IoT para Java v2](https://github.com/aws/aws-iot-device-sdk-java-v2)  |  Versión 1.2.10  | 
|  [SDK para dispositivos con AWS IoT para Python v2](https://github.com/aws/aws-iot-device-sdk-python-v2)  |  Versión 1.5.3  | 
|  [SDK para dispositivos con AWS IoT para C\$1\$1 v2](https://github.com/aws/aws-iot-device-sdk-cpp-v2)  |  Versión 1.17.0  | 
|  [SDK de AWS IoT Device para JavaScript  ](https://github.com/aws/aws-iot-device-sdk-js-v2) v2  |  Versión 1.12.0  | 

## Autorización
<a name="ipc-publish-subscribe-authorization"></a>

Para utilizar la publish/subscribe mensajería local en un componente personalizado, debe definir políticas de autorización que permitan a su componente enviar y recibir mensajes sobre los temas. Para obtener información sobre cómo definir las políticas de autorización, consulte [Autorización de los componentes para realizar operaciones de IPC](interprocess-communication.md#ipc-authorization-policies).

Las políticas de autorización publish/subscribe de mensajería tienen las siguientes propiedades.

**Identificador de servicio IPC:** `aws.greengrass.ipc.pubsub`


| Operación | Description (Descripción) | Recursos | 
| --- | --- | --- | 
|  `aws.greengrass#PublishToTopic`  |  Permite que un componente publique mensajes en los temas que especifique.  |  Una cadena de tema, como `test/topic`. Use un `*` para hacer coincidir cualquier combinación de caracteres de un tema. Esta cadena de tema no admite los caracteres comodín (`#` y `+`) de los temas MQTT.  | 
|  `aws.greengrass#SubscribeToTopic`  |  Permite que un componente se suscriba a los mensajes de los temas que especifique.  |  Una cadena de tema, como `test/topic`. Use un `*` para hacer coincidir cualquier combinación de caracteres de un tema. <a name="ipc-local-publish-subscribe-authorization-mqtt-wildcards"></a>En el [núcleo de Greengrass ](greengrass-nucleus-component.md) versión 2.6.0 y versiones posteriores, puede suscribirse a temas que contengan comodines de temas MQTT (`#` y `+`). Esta cadena de tema admite los comodines de los temas MQTT como caracteres literales. Por ejemplo, si la política de autorización de un componente permite el acceso a `test/topic/#`, el componente se puede suscribir a `test/topic/#`, pero no se puede suscribir a `test/topic/filter`.  | 
|  `*`  |  Permite que un componente publique y se suscriba a los mensajes de los temas que especifique.  |  Una cadena de tema, como `test/topic`. Use un `*` para hacer coincidir cualquier combinación de caracteres de un tema. <a name="ipc-local-publish-subscribe-authorization-mqtt-wildcards"></a>En el [núcleo de Greengrass ](greengrass-nucleus-component.md) versión 2.6.0 y versiones posteriores, puede suscribirse a temas que contengan comodines de temas MQTT (`#` y `+`). Esta cadena de tema admite los comodines de los temas MQTT como caracteres literales. Por ejemplo, si la política de autorización de un componente permite el acceso a `test/topic/#`, el componente se puede suscribir a `test/topic/#`, pero no se puede suscribir a `test/topic/filter`.  | 

### Ejemplos de políticas de autorización
<a name="ipc-publish-subscribe-authorization-policy-examples"></a>

Puede consultar el siguiente ejemplo de política de autorización con el fin de configurar las políticas de autorización para sus componentes.

**Example Ejemplo de política de autorización**  
El siguiente ejemplo de política de autorización permite a un componente publicar y suscribirse a todos los temas.  

```
{
  "accessControl": {
    "aws.greengrass.ipc.pubsub": {
      "com.example.MyLocalPubSubComponent:pubsub:1": {
        "policyDescription": "Allows access to publish/subscribe to all topics.",
        "operations": [
          "aws.greengrass#PublishToTopic",
          "aws.greengrass#SubscribeToTopic"
        ],
        "resources": [
          "*"
        ]
      }
    }
  }
}
```

## PublishToTopic
<a name="ipc-operation-publishtotopic"></a>

Publique un mensaje en un tema

### Solicitud
<a name="ipc-operation-publishtotopic-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`topic`  
El tema en el que se va a publicar el mensaje.

`publishMessage` (Python: `publish_message`)  
El mensaje a publicar. Este objeto, `PublishMessage`, contiene la siguiente información. Debe especificar uno entre `jsonMessage` y `binaryMessage`.  <a name="ipc-publish-subscribe-message-shape"></a>  
`jsonMessage` (Python: `json_message`)  
(Opcional) Un mensaje JSON. Este objeto, `JsonMessage`, contiene la siguiente información:    
`message`  
El mensaje JSON como un objeto.  
`context`  <a name="ipc-publish-subscribe-message-context-variable"></a>
El contexto del mensaje, como el tema en el que se publicó el mensaje.  
Esta característica está disponible para la versión 2.6.0 y versiones posteriores del [componente núcleo de Greengrass](greengrass-nucleus-component.md). En la siguiente tabla, se enumeran las versiones mínimas de SDK para dispositivos con AWS IoT que debe utilizar para acceder al contexto del mensaje.      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/greengrass/v2/developerguide/ipc-publish-subscribe.html)
El software AWS IoT Greengrass Core utiliza los mismos objetos de mensaje en las `SubscribeToTopic` operaciones `PublishToTopic` y. El software AWS IoT Greengrass Core establece este objeto de contexto en los mensajes cuando te suscribes e ignora este objeto de contexto en los mensajes que publicas.
Este objeto, `MessageContext`, contiene la siguiente información:    
`topic`  
El tema donde se publicó el mensaje.  
`binaryMessage` (Python: `binary_message`)  
(Opcional) Un mensaje binario. Este objeto, `BinaryMessage`, contiene la siguiente información:    
`message`  
El mensaje binario es un blob.  
`context`  <a name="ipc-publish-subscribe-message-context-variable"></a>
El contexto del mensaje, como el tema en el que se publicó el mensaje.  
Esta característica está disponible para la versión 2.6.0 y versiones posteriores del [componente núcleo de Greengrass](greengrass-nucleus-component.md). En la siguiente tabla, se enumeran las versiones mínimas de SDK para dispositivos con AWS IoT que debe utilizar para acceder al contexto del mensaje.      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/greengrass/v2/developerguide/ipc-publish-subscribe.html)
El software AWS IoT Greengrass Core utiliza los mismos objetos de mensaje en las `SubscribeToTopic` operaciones `PublishToTopic` y. El software AWS IoT Greengrass Core establece este objeto de contexto en los mensajes cuando te suscribes e ignora este objeto de contexto en los mensajes que publicas.
Este objeto, `MessageContext`, contiene la siguiente información:    
`topic`  
El tema donde se publicó el mensaje.

### Respuesta
<a name="ipc-operation-publishtotopic-response"></a>

Esta operación no proporciona ninguna información en su respuesta.

### Ejemplos
<a name="ipc-operation-publishtotopic-examples"></a>

En los ejemplos siguientes, se muestra cómo llamar a esta operación en código de componente personalizado.

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

**Example Ejemplo: publicar un mensaje binario**  

```
package com.aws.greengrass.docs.samples.ipc;

import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClientV2;
import software.amazon.awssdk.aws.greengrass.model.BinaryMessage;
import software.amazon.awssdk.aws.greengrass.model.PublishMessage;
import software.amazon.awssdk.aws.greengrass.model.PublishToTopicRequest;
import software.amazon.awssdk.aws.greengrass.model.PublishToTopicResponse;
import software.amazon.awssdk.aws.greengrass.model.UnauthorizedError;

import java.nio.charset.StandardCharsets;

public class PublishToTopicV2 {

    public static void main(String[] args) {
        String topic = args[0];
        String message = args[1];
        try (GreengrassCoreIPCClientV2 ipcClient = GreengrassCoreIPCClientV2.builder().build()) {
            PublishToTopicV2.publishBinaryMessageToTopic(ipcClient, topic, message);
            System.out.println("Successfully published to topic: " + topic);
        } catch (Exception e) {
            if (e.getCause() instanceof UnauthorizedError) {
                System.err.println("Unauthorized error while publishing to topic: " + topic);
            } else {
                System.err.println("Exception occurred when using IPC.");
            }
            e.printStackTrace();
            System.exit(1);
        }
    }

    public static PublishToTopicResponse publishBinaryMessageToTopic(
            GreengrassCoreIPCClientV2 ipcClient, String topic, String message) throws InterruptedException {
        BinaryMessage binaryMessage =
                new BinaryMessage().withMessage(message.getBytes(StandardCharsets.UTF_8));
        PublishMessage publishMessage = new PublishMessage().withBinaryMessage(binaryMessage);
        PublishToTopicRequest publishToTopicRequest =
                new PublishToTopicRequest().withTopic(topic).withPublishMessage(publishMessage);
        return ipcClient.publishToTopic(publishToTopicRequest);
    }
}
```

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

**Example Ejemplo: publicar un mensaje binario**  

```
import sys
import traceback

from awsiot.greengrasscoreipc.clientv2 import GreengrassCoreIPCClientV2
from awsiot.greengrasscoreipc.model import (
    PublishMessage,
    BinaryMessage
)


def main():
    args = sys.argv[1:]
    topic = args[0]
    message = args[1]

    try:
        ipc_client = GreengrassCoreIPCClientV2()
        publish_binary_message_to_topic(ipc_client, topic, message)
        print('Successfully published to topic: ' + topic)
    except Exception:
        print('Exception occurred', file=sys.stderr)
        traceback.print_exc()
        exit(1)


def publish_binary_message_to_topic(ipc_client, topic, message):
    binary_message = BinaryMessage(message=bytes(message, 'utf-8'))
    publish_message = PublishMessage(binary_message=binary_message)
    return ipc_client.publish_to_topic(topic=topic, publish_message=publish_message)


if __name__ == '__main__':
    main()
```

------
#### [ C\$1\$1 (IPC client V1) ]

**Example Ejemplo: publicar un mensaje binario**  

```
#include <iostream>

#include <aws/crt/Api.h>
#include <aws/greengrass/GreengrassCoreIpcClient.h>

using namespace Aws::Crt;
using namespace Aws::Greengrass;

class IpcClientLifecycleHandler : public ConnectionLifecycleHandler {
    void OnConnectCallback() override {
        // Handle connection to IPC service.
    }

    void OnDisconnectCallback(RpcError error) override {
        // Handle disconnection from IPC service.
    }

    bool OnErrorCallback(RpcError error) override {
        // Handle IPC service connection error.
        return true;
    }
};

int main() {
    ApiHandle apiHandle(g_allocator);
    Io::EventLoopGroup eventLoopGroup(1);
    Io::DefaultHostResolver socketResolver(eventLoopGroup, 64, 30);
    Io::ClientBootstrap bootstrap(eventLoopGroup, socketResolver);
    IpcClientLifecycleHandler ipcLifecycleHandler;
    GreengrassCoreIpcClient ipcClient(bootstrap);
    auto connectionStatus = ipcClient.Connect(ipcLifecycleHandler).get();
    if (!connectionStatus) {
        std::cerr << "Failed to establish IPC connection: " << connectionStatus.StatusToString() << std::endl;
        exit(-1);
    }

    String topic("my/topic");
    String message("Hello, World!");
    int timeout = 10;

    PublishToTopicRequest request;
    Vector<uint8_t> messageData({message.begin(), message.end()});
    BinaryMessage binaryMessage;
    binaryMessage.SetMessage(messageData);
    PublishMessage publishMessage;
    publishMessage.SetBinaryMessage(binaryMessage);
    request.SetTopic(topic);
    request.SetPublishMessage(publishMessage);

    auto operation = ipcClient.NewPublishToTopic();
    auto activate = operation->Activate(request, nullptr);
    activate.wait();

    auto responseFuture = operation->GetResult();
    if (responseFuture.wait_for(std::chrono::seconds(timeout)) == std::future_status::timeout) {
        std::cerr << "Operation timed out while waiting for response from Greengrass Core." << std::endl;
        exit(-1);
    }

    auto response = responseFuture.get();
    if (!response) {
        // Handle error.
        auto errorType = response.GetResultType();
        if (errorType == OPERATION_ERROR) {
            auto *error = response.GetOperationError();
            (void)error;
            // Handle operation error.
        } else {
            // Handle RPC error.
        }
    }
    return 0;
}
```

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

**Example Ejemplo: publicar un mensaje binario**  

```
    
import * as greengrasscoreipc from "aws-iot-device-sdk-v2/dist/greengrasscoreipc";
import {BinaryMessage, PublishMessage, PublishToTopicRequest} from "aws-iot-device-sdk-v2/dist/greengrasscoreipc/model";
 
class PublishToTopic {
    private ipcClient : greengrasscoreipc.Client
    private readonly topic : string;
    private readonly messageString : string;
 
    constructor() {
        // define your own constructor, e.g.
        this.topic = "<define_your_topic>";
        this.messageString = "<define_your_message_string>";
        this.publishToTopic().then(r => console.log("Started workflow"));
    }
 
    private async publishToTopic() {
        try {
            this.ipcClient = await getIpcClient();
 
            const binaryMessage : BinaryMessage = {
                message: this.messageString
            }
 
            const publishMessage : PublishMessage = {
                binaryMessage: binaryMessage
            }
 
            const request : PublishToTopicRequest = {
                topic: this.topic,
                publishMessage: publishMessage
            }
 
            this.ipcClient.publishToTopic(request).finally(() => console.log(`Published message ${publishMessage.binaryMessage?.message} to topic`))
 
        } catch (e) {
            // parse the error depending on your use cases
            throw e
        }
    }
}
 
 
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
    }
}
 
// starting point
const publishToTopic = new PublishToTopic();
```

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

**Example Ejemplo: publicar un mensaje binario**  

```
use gg_sdk::Sdk;

fn main() {
    let sdk = Sdk::init();
    sdk.connect().expect("Failed to establish IPC connection");

    let message = b"Hello, World";
    let topic = "my/topic";

    sdk.publish_to_topic_binary(topic, message)
        .expect("Failed to publish to topic");

    println!("Successfully published to topic: {topic}");
}
```

------
#### [ C ]

**Example Ejemplo: publicar un mensaje binario**  

```
#include <gg/error.h>
#include <gg/ipc/client.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);
    }

    GgBuffer message = GG_STR("Hello, World");
    GgBuffer topic = GG_STR("my/topic");

    err = ggipc_publish_to_topic_binary(topic, message);
    if (err != GG_ERR_OK) {
        fprintf(
            stderr,
            "Failed to publish to topic: %.*s\n",
            (int) topic.len,
            topic.data
        );
        exit(-1);
    }

    printf(
        "Successfully published to topic: %.*s\n", (int) topic.len, topic.data
    );
}
```

------
#### [ C\$1\$1 (Component SDK) ]

**Example Ejemplo: publicar un mensaje binario**  

```
#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);
    }

    std::string_view message = "Hello, World";
    std::string_view topic = "my/topic";

    error = client.publish_to_topic(topic, message);
    if (error) {
        std::cerr << "Failed to publish to topic: " << topic << "\n";
        exit(-1);
    }

    std::cout << "Successfully published to topic: " << topic << "\n";
}
```

------

## SubscribeToTopic
<a name="ipc-operation-subscribetotopic"></a>

Suscripción a los mensajes sobre un tema.

<a name="ipc-subscribe-operation-note"></a>Esta es una operación de suscripción en la que se suscribe a un flujo de mensajes de eventos. Para usar esta operación, defina un identificador de respuesta de flujo con funciones que gestionen los mensajes de eventos, los errores y el cierre del flujo. Para obtener más información, consulte [Suscripción a los flujos de eventos de IPC](interprocess-communication.md#ipc-subscribe-operations).

**Tipo de mensaje del evento:** `SubscriptionResponseMessage`

### Solicitud
<a name="ipc-operation-subscribetotopic-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`topic`  
El tema al que se suscribe.  
En el [núcleo de Greengrass ](greengrass-nucleus-component.md) versión 2.6.0 y versiones posteriores, este tema admite los comodines (`#` y `+`) de los temas MQTT.

`receiveMode` (Python: `receive_mode`)  
(Opcional) El comportamiento que especifica si el componente recibe mensajes de sí mismo. Puede cambiar este comportamiento para permitir que un componente actúe sobre sus propios mensajes. El comportamiento predeterminado depende de si el tema contiene un comodín MQTT. Puede elegir entre las siguientes opciones:  
+ `RECEIVE_ALL_MESSAGES`: reciba todos los mensajes que coincidan con el tema, incluidos los mensajes del componente al que se suscribe.

  Este modo es la opción por defecto cuando se suscribe a un tema que no contiene un comodín MQTT.
+ `RECEIVE_MESSAGES_FROM_OTHERS`: reciba todos los mensajes que coincidan con el tema, excepto los del componente al que se suscribe.

  Este modo es la opción por defecto cuando se suscribe a un tema que contiene un comodín MQTT.
Esta característica está disponible para la versión 2.6.0 y versiones posteriores del [componente núcleo de Greengrass](greengrass-nucleus-component.md). En la siguiente tabla se enumeran las versiones mínimas del SDK para dispositivos con AWS IoT que debe utilizar para configurar el modo de recepción.      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/greengrass/v2/developerguide/ipc-publish-subscribe.html)

### Respuesta
<a name="ipc-operation-subscribetotopic-response"></a>

Esta respuesta de operación contiene la siguiente información:

`messages`  
El flujo de mensajes. Este objeto, `SubscriptionResponseMessage`, contiene la siguiente información. Cada mensaje contiene `jsonMessage` o `binaryMessage`.  <a name="ipc-publish-subscribe-message-shape"></a>  
`jsonMessage` (Python: `json_message`)  
(Opcional) Un mensaje JSON. Este objeto, `JsonMessage`, contiene la siguiente información:    
`message`  
El mensaje JSON como un objeto.  
`context`  <a name="ipc-publish-subscribe-message-context-variable"></a>
El contexto del mensaje, como el tema en el que se publicó el mensaje.  
Esta característica está disponible para la versión 2.6.0 y versiones posteriores del [componente núcleo de Greengrass](greengrass-nucleus-component.md). En la siguiente tabla, se enumeran las versiones mínimas de SDK para dispositivos con AWS IoT que debe utilizar para acceder al contexto del mensaje.      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/greengrass/v2/developerguide/ipc-publish-subscribe.html)
El software AWS IoT Greengrass Core utiliza los mismos objetos de mensaje en las `SubscribeToTopic` operaciones `PublishToTopic` y. El software AWS IoT Greengrass Core establece este objeto de contexto en los mensajes cuando te suscribes e ignora este objeto de contexto en los mensajes que publicas.
Este objeto, `MessageContext`, contiene la siguiente información:    
`topic`  
El tema donde se publicó el mensaje.  
`binaryMessage` (Python: `binary_message`)  
(Opcional) Un mensaje binario. Este objeto, `BinaryMessage`, contiene la siguiente información:    
`message`  
El mensaje binario es un blob.  
`context`  <a name="ipc-publish-subscribe-message-context-variable"></a>
El contexto del mensaje, como el tema en el que se publicó el mensaje.  
Esta característica está disponible para la versión 2.6.0 y versiones posteriores del [componente núcleo de Greengrass](greengrass-nucleus-component.md). En la siguiente tabla, se enumeran las versiones mínimas de SDK para dispositivos con AWS IoT que debe utilizar para acceder al contexto del mensaje.      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/greengrass/v2/developerguide/ipc-publish-subscribe.html)
El software AWS IoT Greengrass Core utiliza los mismos objetos de mensaje en las `SubscribeToTopic` operaciones `PublishToTopic` y. El software AWS IoT Greengrass Core establece este objeto de contexto en los mensajes cuando te suscribes e ignora este objeto de contexto en los mensajes que publicas.
Este objeto, `MessageContext`, contiene la siguiente información:    
`topic`  
El tema donde se publicó el mensaje.

`topicName` (Python: `topic_name`)  
El tema en el que se publicó el mensaje.  
En la actualidad, esta propiedad no se utiliza. En el [núcleo de Greengrass](greengrass-nucleus-component.md) versión 2.6.0 y versiones posteriores, puede obtener el valor `(jsonMessage|binaryMessage).context.topic` de un `SubscriptionResponseMessage` para obtener el tema en el que se publicó el mensaje.

### Ejemplos
<a name="ipc-operation-subscribetotopic-examples"></a>

En los ejemplos siguientes, se muestra cómo llamar a esta operación en código de componente personalizado.

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

**Example Ejemplo: suscríbase a los mensajes locales publish/subscribe**  <a name="ipc-operation-subscribetotopic-example-java-v2"></a>

```
package com.aws.greengrass.docs.samples.ipc;

import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClientV2;
import software.amazon.awssdk.aws.greengrass.SubscribeToTopicResponseHandler;
import software.amazon.awssdk.aws.greengrass.model.*;

import java.nio.charset.StandardCharsets;
import java.util.Optional;

public class SubscribeToTopicV2 {

    public static void main(String[] args) {
        String topic = args[0];
        try (GreengrassCoreIPCClientV2 ipcClient = GreengrassCoreIPCClientV2.builder().build()) {
            SubscribeToTopicRequest request = new SubscribeToTopicRequest().withTopic(topic);
            GreengrassCoreIPCClientV2.StreamingResponse<SubscribeToTopicResponse,
                    SubscribeToTopicResponseHandler> response =
                    ipcClient.subscribeToTopic(request, SubscribeToTopicV2::onStreamEvent,
                            Optional.of(SubscribeToTopicV2::onStreamError),
                            Optional.of(SubscribeToTopicV2::onStreamClosed));
            SubscribeToTopicResponseHandler responseHandler = response.getHandler();
            System.out.println("Successfully subscribed to topic: " + topic);

            // Keep the main thread alive, or the process will exit.
            try {
                while (true) {
                    Thread.sleep(10000);
                }
            } catch (InterruptedException e) {
                System.out.println("Subscribe interrupted.");
            }

            // To stop subscribing, close the stream.
            responseHandler.closeStream();
        } catch (Exception e) {
            if (e.getCause() instanceof UnauthorizedError) {
                System.err.println("Unauthorized error while publishing to topic: " + topic);
            } else {
                System.err.println("Exception occurred when using IPC.");
            }
            e.printStackTrace();
            System.exit(1);
        }
    }

    public static void onStreamEvent(SubscriptionResponseMessage subscriptionResponseMessage) {
        try {
            BinaryMessage binaryMessage = subscriptionResponseMessage.getBinaryMessage();
            String message = new String(binaryMessage.getMessage(), StandardCharsets.UTF_8);
            String topic = binaryMessage.getContext().getTopic();
            System.out.printf("Received new message on topic %s: %s%n", topic, message);
        } catch (Exception e) {
            System.err.println("Exception occurred while processing subscription response " +
                    "message.");
            e.printStackTrace();
        }
    }

    public static boolean onStreamError(Throwable error) {
        System.err.println("Received a stream error.");
        error.printStackTrace();
        return false; // Return true to close stream, false to keep stream open.
    }

    public static void onStreamClosed() {
        System.out.println("Subscribe to topic stream closed.");
    }
}
```

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

**Example Ejemplo: suscríbase a los publish/subscribe mensajes locales**  <a name="ipc-operation-subscribetotopic-example-python-v2"></a>

```
import sys
import time
import traceback

from awsiot.greengrasscoreipc.clientv2 import GreengrassCoreIPCClientV2
from awsiot.greengrasscoreipc.model import (
    SubscriptionResponseMessage,
    UnauthorizedError
)


def main():
    args = sys.argv[1:]
    topic = args[0]

    try:
        ipc_client = GreengrassCoreIPCClientV2()
        # Subscription operations return a tuple with the response and the operation.
        _, operation = ipc_client.subscribe_to_topic(topic=topic, on_stream_event=on_stream_event,
                                                     on_stream_error=on_stream_error, on_stream_closed=on_stream_closed)
        print('Successfully subscribed to topic: ' + topic)

        # Keep the main thread alive, or the process will exit.
        try:
            while True:
                time.sleep(10)
        except InterruptedError:
            print('Subscribe interrupted.')

        # To stop subscribing, close the stream.
        operation.close()
    except UnauthorizedError:
        print('Unauthorized error while subscribing to topic: ' +
              topic, file=sys.stderr)
        traceback.print_exc()
        exit(1)
    except Exception:
        print('Exception occurred', file=sys.stderr)
        traceback.print_exc()
        exit(1)


def on_stream_event(event: SubscriptionResponseMessage) -> None:
    try:
        message = str(event.binary_message.message, 'utf-8')
        topic = event.binary_message.context.topic
        print('Received new message on topic %s: %s' % (topic, message))
    except:
        traceback.print_exc()


def on_stream_error(error: Exception) -> bool:
    print('Received a stream error.', file=sys.stderr)
    traceback.print_exc()
    return False  # Return True to close stream, False to keep stream open.


def on_stream_closed() -> None:
    print('Subscribe to topic stream closed.')


if __name__ == '__main__':
    main()
```

------
#### [ C\$1\$1 (IPC client V1) ]

**Example Ejemplo: suscríbase a los publish/subscribe mensajes locales**  <a name="ipc-operation-subscribetotopic-example-cpp"></a>

```
#include <iostream>

#include </crt/Api.h>
#include <aws/greengrass/GreengrassCoreIpcClient.h>

using namespace Aws::Crt;
using namespace Aws::Greengrass;

class SubscribeResponseHandler : public SubscribeToTopicStreamHandler {
    public:
        virtual ~SubscribeResponseHandler() {}

    private:
        void OnStreamEvent(SubscriptionResponseMessage *response) override {
            auto jsonMessage = response->GetJsonMessage();
            if (jsonMessage.has_value() && jsonMessage.value().GetMessage().has_value()) {
                auto messageString = jsonMessage.value().GetMessage().value().View().WriteReadable();
                // Handle JSON message.
            } else {
                auto binaryMessage = response->GetBinaryMessage();
                if (binaryMessage.has_value() && binaryMessage.value().GetMessage().has_value()) {
                    auto messageBytes = binaryMessage.value().GetMessage().value();
                    std::string messageString(messageBytes.begin(), messageBytes.end());
                    // Handle binary message.
                }
            }
        }

        bool OnStreamError(OperationError *error) override {
            // Handle error.
            return false; // Return true to close stream, false to keep stream open.
        }

        void OnStreamClosed() override {
            // Handle close.
        }
};

class IpcClientLifecycleHandler : public ConnectionLifecycleHandler {
    void OnConnectCallback() override {
        // Handle connection to IPC service.
    }

    void OnDisconnectCallback(RpcError error) override {
        // Handle disconnection from IPC service.
    }

    bool OnErrorCallback(RpcError error) override {
        // Handle IPC service connection error.
        return true;
    }
};

int main() {
    ApiHandle apiHandle(g_allocator);
    Io::EventLoopGroup eventLoopGroup(1);
    Io::DefaultHostResolver socketResolver(eventLoopGroup, 64, 30);
    Io::ClientBootstrap bootstrap(eventLoopGroup, socketResolver);
    IpcClientLifecycleHandler ipcLifecycleHandler;
    GreengrassCoreIpcClient ipcClient(bootstrap);
    auto connectionStatus = ipcClient.Connect(ipcLifecycleHandler).get();
    if (!connectionStatus) {
        std::cerr << "Failed to establish IPC connection: " << connectionStatus.StatusToString() << std::endl;
        exit(-1);
    }

    String topic("my/topic");
    int timeout = 10;

    SubscribeToTopicRequest request;
    request.SetTopic(topic);

    //SubscribeResponseHandler streamHandler;
    auto streamHandler = MakeShared<SubscribeResponseHandler>(DefaultAllocator());
    auto operation = ipcClient.NewSubscribeToTopic(streamHandler);
    auto activate = operation->Activate(request, nullptr);
    activate.wait();

    auto responseFuture = operation->GetResult();
    if (responseFuture.wait_for(std::chrono::seconds(timeout)) == std::future_status::timeout) {
        std::cerr << "Operation timed out while waiting for response from Greengrass Core." << std::endl;
        exit(-1);
    }

    auto response = responseFuture.get();
    if (!response) {
        // Handle error.
        auto errorType = response.GetResultType();
        if (errorType == OPERATION_ERROR) {
            auto *error = response.GetOperationError();
            (void)error;
            // Handle operation error.
        } else {
            // Handle RPC error.
        }
        exit(-1);
    }

    // Keep the main thread alive, or the process will exit.
    while (true) {
        std::this_thread::sleep_for(std::chrono::seconds(10));
    }

    operation->Close();
    return 0;
}
```

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

**Example Ejemplo: suscríbase a los publish/subscribe mensajes locales**  <a name="ipc-operation-subscribetotopic-example-nodejs"></a>

```
import * as greengrasscoreipc from "aws-iot-device-sdk-v2/dist/greengrasscoreipc";
import {SubscribeToTopicRequest, SubscriptionResponseMessage} from "aws-iot-device-sdk-v2/dist/greengrasscoreipc/model";
import {RpcError} from "aws-iot-device-sdk-v2/dist/eventstream_rpc";
 
class SubscribeToTopic {
    private ipcClient : greengrasscoreipc.Client
    private readonly topic : string;
 
    constructor() {
        // define your own constructor, e.g.
        this.topic = "<define_your_topic>";
        this.subscribeToTopic().then(r => console.log("Started workflow"));
    }
 
    private async subscribeToTopic() {
        try {
            this.ipcClient = await getIpcClient();
 
            const subscribeToTopicRequest : SubscribeToTopicRequest = {
                topic: this.topic,
            }
 
            const streamingOperation = this.ipcClient.subscribeToTopic(subscribeToTopicRequest, undefined); // conditionally apply options
 
            streamingOperation.on("message", (message: SubscriptionResponseMessage) => {
                // parse the message depending on your use cases, e.g.
                if(message.binaryMessage && message.binaryMessage.message) {
                    const receivedMessage = message.binaryMessage?.message.toString();
                }
            });
 
            streamingOperation.on("streamError", (error : RpcError) => {
                // define your own error handling logic
            })
 
            streamingOperation.on("ended", () => {
                // define your own logic
            })
 
            await streamingOperation.activate();
 
            // Keep the main thread alive, or the process will exit.
            await new Promise((resolve) => setTimeout(resolve, 10000))
        } catch (e) {
            // parse the error depending on your use cases
            throw e
        }
    }
}
 
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
    }
}
 
// starting point
const subscribeToTopic = new SubscribeToTopic();
```

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

**Example Ejemplo: suscríbase a los publish/subscribe mensajes locales**  

```
use gg_sdk::{Sdk, SubscribeToTopicPayload};
use std::{thread, time::Duration};

fn main() {
    let sdk = Sdk::init();
    sdk.connect().expect("Failed to establish IPC connection");

    let topic = "my/topic";

    let callback = |topic: &str, payload: SubscribeToTopicPayload| match payload
    {
        SubscribeToTopicPayload::Binary(message) => {
            let message = String::from_utf8_lossy(message);
            println!("Received new message on topic {topic}: {message}");
        }
        SubscribeToTopicPayload::Json(_) => {
            println!("Received new message on topic {topic}: (JSON message)");
        }
    };

    let _sub = sdk
        .subscribe_to_topic(topic, &callback)
        .expect("Failed to subscribe to topic");

    println!("Successfully subscribed to topic: {topic}");

    // Keep the main thread alive, or the process will exit.
    loop {
        thread::sleep(Duration::from_secs(10));
    }
}
```

------
#### [ C ]

**Example Ejemplo: suscríbase a los publish/subscribe mensajes locales**  

```
#include <assert.h>
#include <gg/error.h>
#include <gg/ipc/client.h>
#include <gg/object.h>
#include <gg/sdk.h>
#include <gg/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

static void on_subscription_response(
    void *ctx, GgBuffer topic, GgObject payload, GgIpcSubscriptionHandle handle
) {
    (void) ctx;
    (void) handle;

    if (gg_obj_type(payload) == GG_TYPE_BUF) {
        GgBuffer message = gg_obj_into_buf(payload);
        printf(
            "Received new message on topic %.*s: %.*s\n",
            (int) topic.len,
            topic.data,
            (int) message.len,
            message.data
        );
    } else {
        assert(gg_obj_type(payload) == GG_TYPE_MAP);
        printf(
            "Received new message on topic %.*s: (JSON message)\n",
            (int) topic.len,
            topic.data
        );
    }
}

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);
    }

    GgBuffer topic = GG_STR("my/topic");

    GgIpcSubscriptionHandle handle;
    err = ggipc_subscribe_to_topic(
        topic, on_subscription_response, NULL, &handle
    );
    if (err != GG_ERR_OK) {
        fprintf(
            stderr,
            "Failed to subscribe to topic: %.*s\n",
            (int) topic.len,
            topic.data
        );
        exit(-1);
    }

    printf(
        "Successfully subscribed to topic: %.*s\n", (int) topic.len, topic.data
    );

    // 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 Ejemplo: suscríbase a los publish/subscribe mensajes locales**  

```
#include <gg/ipc/client.hpp>
#include <gg/object.hpp>
#include <unistd.h>
#include <cassert>
#include <iostream>

class ResponseHandler : public gg::ipc::LocalTopicCallback {
    void operator()(
        std::string_view topic,
        gg::Object payload,
        gg::ipc::Subscription &handle
    ) override {
        (void) handle;
        if (payload.index() == GG_TYPE_BUF) {
            std::cout << "Received new message on topic " << topic << ": "
                      << get<gg::Buffer>(payload) << "\n";
        } else {
            assert(payload.index() == GG_TYPE_MAP);
            std::cout << "Received new message on topic " << topic
                      << ": (JSON message)\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);
    }

    std::string_view topic = "my/topic";

    static ResponseHandler handler;
    error = client.subscribe_to_topic(topic, handler);
    if (error) {
        std::cerr << "Failed to subscribe to topic: " << topic << "\n";
        exit(-1);
    }

    std::cout << "Successfully subscribed to topic: " << topic << "\n";

    // Keep the main thread alive, or the process will exit.
    while (1) {
        sleep(10);
    }
}
```

------

## Ejemplos
<a name="ipc-publish-subscribe-examples"></a>

Utilice los siguientes ejemplos para aprender a utilizar el servicio publish/subscribe IPC en sus componentes.

### Ejemplo de publish/subscribe editor (Java, cliente IPC V1)
<a name="ipc-publish-subscribe-example-publisher-java"></a>

La siguiente receta de ejemplo permite que el componente publique en todos los temas.

------
#### [ JSON ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.PubSubPublisherJava",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that publishes messages.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.PubSubPublisherJava:pubsub:1": {
            "policyDescription": "Allows access to publish to all topics.",
            "operations": [
              "aws.greengrass#PublishToTopic"
            ],
            "resources": [
              "*"
            ]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Lifecycle": {
        "Run": "java -jar {artifacts:path}/PubSubPublisher.jar"
      }
    }
  ]
}
```

------
#### [ YAML ]

```
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.PubSubPublisherJava
ComponentVersion: '1.0.0'
ComponentDescription: A component that publishes messages.
ComponentPublisher: Amazon
ComponentConfiguration:
  DefaultConfiguration:
    accessControl:
      aws.greengrass.ipc.pubsub:
        'com.example.PubSubPublisherJava:pubsub:1':
          policyDescription: Allows access to publish to all topics.
          operations:
            - 'aws.greengrass#PublishToTopic'
          resources:
            - '*'
Manifests:
  - Lifecycle:
      Run: |-
        java -jar {artifacts:path}/PubSubPublisher.jar
```

------

El siguiente ejemplo de aplicación Java demuestra cómo utilizar el servicio IPC de publicación/suscripción para publicar mensajes en otros componentes.

```
/* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0 */

package com.example.ipc.pubsub;

import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClient;
import software.amazon.awssdk.aws.greengrass.model.*;
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 PubSubPublisher {

    public static void main(String[] args) {
        String message = "Hello from the pub/sub publisher (Java).";
        String topic = "test/topic/java";

        try (EventStreamRPCConnection eventStreamRPCConnection = IPCUtils.getEventStreamRpcConnection()) {
            GreengrassCoreIPCClient ipcClient = new GreengrassCoreIPCClient(eventStreamRPCConnection);

            while (true) {
                PublishToTopicRequest publishRequest = new PublishToTopicRequest();
                PublishMessage publishMessage = new PublishMessage();
                BinaryMessage binaryMessage = new BinaryMessage();
                binaryMessage.setMessage(message.getBytes(StandardCharsets.UTF_8));
                publishMessage.setBinaryMessage(binaryMessage);
                publishRequest.setPublishMessage(publishMessage);
                publishRequest.setTopic(topic);
                CompletableFuture<PublishToTopicResponse> futureResponse = ipcClient
                        .publishToTopic(publishRequest, Optional.empty()).getResponse();

                try {
                    futureResponse.get(10, TimeUnit.SECONDS);
                    System.out.println("Successfully published to topic: " + topic);
                } catch (TimeoutException e) {
                    System.err.println("Timeout occurred while publishing to topic: " + topic);
                } catch (ExecutionException e) {
                    if (e.getCause() instanceof UnauthorizedError) {
                        System.err.println("Unauthorized error while publishing to topic: " + topic);
                    } else {
                        System.err.println("Execution exception while publishing to topic: " + topic);
                    }
                    throw e;
                }
                Thread.sleep(5000);
            }
        } catch (InterruptedException e) {
            System.out.println("Publisher interrupted.");
        } catch (Exception e) {
            System.err.println("Exception occurred when using IPC.");
            e.printStackTrace();
            System.exit(1);
        }
    }
}
```

### Ejemplo de publish/subscribe suscriptor (Java, cliente IPC V1)
<a name="ipc-publish-subscribe-example-subscriber-java"></a>

La siguiente receta de ejemplo permite que el componente se suscriba a todos los temas.

------
#### [ JSON ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.PubSubSubscriberJava",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that subscribes to messages.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.PubSubSubscriberJava:pubsub:1": {
            "policyDescription": "Allows access to subscribe to all topics.",
            "operations": [
              "aws.greengrass#SubscribeToTopic"
            ],
            "resources": [
              "*"
            ]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Lifecycle": {
        "Run": "java -jar {artifacts:path}/PubSubSubscriber.jar"
      }
    }
  ]
}
```

------
#### [ YAML ]

```
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.PubSubSubscriberJava
ComponentVersion: '1.0.0'
ComponentDescription: A component that subscribes to messages.
ComponentPublisher: Amazon
ComponentConfiguration:
  DefaultConfiguration:
    accessControl:
      aws.greengrass.ipc.pubsub:
        'com.example.PubSubSubscriberJava:pubsub:1':
          policyDescription: Allows access to subscribe to all topics.
          operations:
            - 'aws.greengrass#SubscribeToTopic'
          resources:
            - '*'
Manifests:
  - Lifecycle:
      Run: |-
        java -jar {artifacts:path}/PubSubSubscriber.jar
```

------

El siguiente ejemplo de aplicación Java muestra cómo utilizar el servicio IPC de publicación/suscripción para suscribirse a los mensajes de otros componentes.

```
/* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0 */

package com.example.ipc.pubsub;

import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClient;
import software.amazon.awssdk.aws.greengrass.SubscribeToTopicResponseHandler;
import software.amazon.awssdk.aws.greengrass.model.SubscribeToTopicRequest;
import software.amazon.awssdk.aws.greengrass.model.SubscribeToTopicResponse;
import software.amazon.awssdk.aws.greengrass.model.SubscriptionResponseMessage;
import software.amazon.awssdk.aws.greengrass.model.UnauthorizedError;
import software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection;
import software.amazon.awssdk.eventstreamrpc.StreamResponseHandler;

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 PubSubSubscriber {

    public static void main(String[] args) {
        String topic = "test/topic/java";

        try (EventStreamRPCConnection eventStreamRPCConnection = IPCUtils.getEventStreamRpcConnection()) {
            GreengrassCoreIPCClient ipcClient = new GreengrassCoreIPCClient(eventStreamRPCConnection);

            SubscribeToTopicRequest subscribeRequest = new SubscribeToTopicRequest();
            subscribeRequest.setTopic(topic);
            SubscribeToTopicResponseHandler operationResponseHandler = ipcClient
                    .subscribeToTopic(subscribeRequest, Optional.of(new SubscribeResponseHandler()));
            CompletableFuture<SubscribeToTopicResponse> futureResponse = operationResponseHandler.getResponse();

            try {
                futureResponse.get(10, TimeUnit.SECONDS);
                System.out.println("Successfully subscribed to topic: " + topic);
            } catch (TimeoutException e) {
                System.err.println("Timeout occurred while subscribing to topic: " + topic);
                throw e;
            } catch (ExecutionException e) {
                if (e.getCause() instanceof UnauthorizedError) {
                    System.err.println("Unauthorized error while subscribing to topic: " + topic);
                } else {
                    System.err.println("Execution exception while subscribing to topic: " + topic);
                }
                throw e;
            }

            // Keep the main thread alive, or the process will exit.
            try {
                while (true) {
                    Thread.sleep(10000);
                }
            } catch (InterruptedException e) {
                System.out.println("Subscribe interrupted.");
            }
        } catch (Exception e) {
            System.err.println("Exception occurred when using IPC.");
            e.printStackTrace();
            System.exit(1);
        }
    }

    private static class SubscribeResponseHandler implements StreamResponseHandler<SubscriptionResponseMessage> {

        @Override
        public void onStreamEvent(SubscriptionResponseMessage subscriptionResponseMessage) {
            try {
                String message = new String(subscriptionResponseMessage.getBinaryMessage()
                        .getMessage(), StandardCharsets.UTF_8);
                System.out.println("Received new message: " + message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public boolean onStreamError(Throwable error) {
            System.err.println("Received a stream error.");
            error.printStackTrace();
            return false; // Return true to close stream, false to keep stream open.
        }

        @Override
        public void onStreamClosed() {
            System.out.println("Subscribe to topic stream closed.");
        }
    }
}
```

### Ejemplo de publish/subscribe editor (Python, cliente IPC V1)
<a name="ipc-publish-subscribe-example-publisher-python"></a>

La siguiente receta de ejemplo permite que el componente publique en todos los temas.

------
#### [ JSON ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.PubSubPublisherPython",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that publishes messages.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.PubSubPublisherPython:pubsub:1": {
            "policyDescription": "Allows access to publish to all topics.",
            "operations": [
              "aws.greengrass#PublishToTopic"
            ],
            "resources": [
              "*"
            ]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux"
      },
      "Lifecycle": {
        "install": "python3 -m pip install --user awsiotsdk",
        "Run": "python3 -u {artifacts:path}/pubsub_publisher.py"
      }
    },
    {
      "Platform": {
        "os": "windows"
      },
      "Lifecycle": {
        "install": "py -3 -m pip install --user awsiotsdk",
        "Run": "py -3 -u {artifacts:path}/pubsub_publisher.py"
      }
    }
  ]
}
```

------
#### [ YAML ]

```
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.PubSubPublisherPython
ComponentVersion: 1.0.0
ComponentDescription: A component that publishes messages.
ComponentPublisher: Amazon
ComponentConfiguration:
  DefaultConfiguration:
    accessControl:
      aws.greengrass.ipc.pubsub:
        com.example.PubSubPublisherPython:pubsub:1:
          policyDescription: Allows access to publish to all topics.
          operations:
            - aws.greengrass#PublishToTopic
          resources:
            - "*"
Manifests:
  - Platform:
      os: linux
    Lifecycle:
      install: python3 -m pip install --user awsiotsdk
      Run: python3 -u {artifacts:path}/pubsub_publisher.py
  - Platform:
      os: windows
    Lifecycle:
      install: py -3 -m pip install --user awsiotsdk
      Run: py -3 -u {artifacts:path}/pubsub_publisher.py
```

------

El siguiente ejemplo de aplicación de Python demuestra cómo utilizar el servicio IPC de publicación/suscripción para publicar mensajes en otros componentes.

```
import concurrent.futures
import sys
import time
import traceback

import awsiot.greengrasscoreipc
from awsiot.greengrasscoreipc.model import (
    PublishToTopicRequest,
    PublishMessage,
    BinaryMessage,
    UnauthorizedError
)

                    
topic = "test/topic/python"
message = "Hello from the pub/sub publisher (Python)."
TIMEOUT = 10

try:
    ipc_client = awsiot.greengrasscoreipc.connect()

    while True:
        request = PublishToTopicRequest()
        request.topic = topic
        publish_message = PublishMessage()
        publish_message.binary_message = BinaryMessage()
        publish_message.binary_message.message = bytes(message, "utf-8")
        request.publish_message = publish_message
        operation = ipc_client.new_publish_to_topic()
        operation.activate(request)
        future_response = operation.get_response()

        try:
            future_response.result(TIMEOUT)
            print('Successfully published to topic: ' + topic)
        except concurrent.futures.TimeoutError:
            print('Timeout occurred while publishing to topic: ' + topic, file=sys.stderr)
        except UnauthorizedError as e:
            print('Unauthorized error while publishing to topic: ' + topic, file=sys.stderr)
            raise e
        except Exception as e:
            print('Exception while publishing to topic: ' + topic, file=sys.stderr)
            raise e
        time.sleep(5)
except InterruptedError:
    print('Publisher interrupted.')
except Exception:
    print('Exception occurred when using IPC.', file=sys.stderr)
    traceback.print_exc()
    exit(1)
```

### Ejemplo de publish/subscribe suscriptor (Python, cliente IPC V1)
<a name="ipc-publish-subscribe-example-subscriber-python"></a>

La siguiente receta de ejemplo permite que el componente se suscriba a todos los temas.

------
#### [ JSON ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.PubSubSubscriberPython",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that subscribes to messages.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.PubSubSubscriberPython:pubsub:1": {
            "policyDescription": "Allows access to subscribe to all topics.",
            "operations": [
              "aws.greengrass#SubscribeToTopic"
            ],
            "resources": [
              "*"
            ]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux"
      },
      "Lifecycle": {
        "install": "python3 -m pip install --user awsiotsdk",
        "Run": "python3 -u {artifacts:path}/pubsub_subscriber.py"
      }
    },
    {
      "Platform": {
        "os": "windows"
      },
      "Lifecycle": {
        "install": "py -3 -m pip install --user awsiotsdk",
        "Run": "py -3 -u {artifacts:path}/pubsub_subscriber.py"
      }
    }
  ]
}
```

------
#### [ YAML ]

```
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.PubSubSubscriberPython
ComponentVersion: 1.0.0
ComponentDescription: A component that subscribes to messages.
ComponentPublisher: Amazon
ComponentConfiguration:
  DefaultConfiguration:
    accessControl:
      aws.greengrass.ipc.pubsub:
        com.example.PubSubSubscriberPython:pubsub:1:
          policyDescription: Allows access to subscribe to all topics.
          operations:
            - aws.greengrass#SubscribeToTopic
          resources:
            - "*"
Manifests:
  - Platform:
      os: linux
    Lifecycle:
      install: python3 -m pip install --user awsiotsdk
      Run: python3 -u {artifacts:path}/pubsub_subscriber.py
  - Platform:
      os: windows
    Lifecycle:
      install: py -3 -m pip install --user awsiotsdk
      Run: py -3 -u {artifacts:path}/pubsub_subscriber.py
```

------

El siguiente ejemplo de aplicación de Python demuestra cómo utilizar el servicio IPC de publicación/suscripción para suscribirse a los mensajes de otros componentes.

```
import concurrent.futures
import sys
import time
import traceback

import awsiot.greengrasscoreipc
import awsiot.greengrasscoreipc.client as client
from awsiot.greengrasscoreipc.model import (
    SubscribeToTopicRequest,
    SubscriptionResponseMessage,
    UnauthorizedError
)

topic = "test/topic/python"
TIMEOUT = 10

                    
class StreamHandler(client.SubscribeToTopicStreamHandler):
    def __init__(self):
        super().__init__()

    def on_stream_event(self, event: SubscriptionResponseMessage) -> None:
        try:
            message = str(event.binary_message.message, "utf-8")
            print("Received new message: " + message)
        except:
            traceback.print_exc()

    def on_stream_error(self, error: Exception) -> bool:
        print("Received a stream error.", file=sys.stderr)
        traceback.print_exc()
        return False  # Return True to close stream, False to keep stream open.

    def on_stream_closed(self) -> None:
        print('Subscribe to topic stream closed.')


try:
    ipc_client = awsiot.greengrasscoreipc.connect()

    request = SubscribeToTopicRequest()
    request.topic = topic
    handler = StreamHandler()
    operation = ipc_client.new_subscribe_to_topic(handler)
    operation.activate(request)
    future_response = operation.get_response()
    
    try:
        future_response.result(TIMEOUT)
        print('Successfully subscribed to topic: ' + topic)
    except concurrent.futures.TimeoutError as e:
        print('Timeout occurred while subscribing to topic: ' + topic, file=sys.stderr)
        raise e
    except UnauthorizedError as e:
        print('Unauthorized error while subscribing to topic: ' + topic, file=sys.stderr)
        raise e
    except Exception as e:
        print('Exception while subscribing to topic: ' + topic, file=sys.stderr)
        raise e

    # Keep the main thread alive, or the process will exit.
    try:
        while True:
            time.sleep(10)
    except InterruptedError:
        print('Subscribe interrupted.')
except Exception:
    print('Exception occurred when using IPC.', file=sys.stderr)
    traceback.print_exc()
    exit(1)
```

### Ejemplo de publish/subscribe editor (C\$1\$1, cliente IPC V1)
<a name="ipc-publish-subscribe-example-publisher-cpp"></a>

La siguiente receta de ejemplo permite que el componente publique en todos los temas.

------
#### [ JSON ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.PubSubPublisherCpp",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that publishes messages.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.PubSubPublisherCpp:pubsub:1": {
            "policyDescription": "Allows access to publish to all topics.",
            "operations": [
              "aws.greengrass#PublishToTopic"
            ],
            "resources": [
              "*"
            ]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Lifecycle": {
        "Run": "{artifacts:path}/greengrassv2_pubsub_publisher"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.PubSubPublisherCpp/1.0.0/greengrassv2_pubsub_publisher",
          "Permission": {
            "Execute": "OWNER"
          }
        }
      ]
    }
  ]
}
```

------
#### [ YAML ]

```
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.PubSubPublisherCpp
ComponentVersion: 1.0.0
ComponentDescription: A component that publishes messages.
ComponentPublisher: Amazon
ComponentConfiguration:
  DefaultConfiguration:
    accessControl:
      aws.greengrass.ipc.pubsub:
        com.example.PubSubPublisherCpp:pubsub:1:
          policyDescription: Allows access to publish to all topics.
          operations:
            - aws.greengrass#PublishToTopic
          resources:
            - "*"
Manifests:
  - Lifecycle:
      Run: "{artifacts:path}/greengrassv2_pubsub_publisher"
    Artifacts:
      - URI: s3://amzn-s3-demo-bucket/artifacts/com.example.PubSubPublisherCpp/1.0.0/greengrassv2_pubsub_publisher
        Permission:
          Execute: OWNER
```

------

El siguiente ejemplo de aplicación de C\$1\$1 demuestra cómo utilizar el servicio IPC de publicación/suscripción para publicar mensajes en otros componentes.

```
#include <iostream>

#include <aws/crt/Api.h>
#include <aws/greengrass/GreengrassCoreIpcClient.h>

using namespace Aws::Crt;
using namespace Aws::Greengrass;

class IpcClientLifecycleHandler : public ConnectionLifecycleHandler {
    void OnConnectCallback() override {
        std::cout << "OnConnectCallback" << std::endl;
    }

    void OnDisconnectCallback(RpcError error) override {
        std::cout << "OnDisconnectCallback: " << error.StatusToString() << std::endl;
        exit(-1);
    }

    bool OnErrorCallback(RpcError error) override {
        std::cout << "OnErrorCallback: " << error.StatusToString() << std::endl;
        return true;
    }
};

int main() {
    String message("Hello from the pub/sub publisher (C++).");
    String topic("test/topic/cpp");
    int timeout = 10;

    ApiHandle apiHandle(g_allocator);
    Io::EventLoopGroup eventLoopGroup(1);
    Io::DefaultHostResolver socketResolver(eventLoopGroup, 64, 30);
    Io::ClientBootstrap bootstrap(eventLoopGroup, socketResolver);
    IpcClientLifecycleHandler ipcLifecycleHandler;
    GreengrassCoreIpcClient ipcClient(bootstrap);
    auto connectionStatus = ipcClient.Connect(ipcLifecycleHandler).get();
    if (!connectionStatus) {
        std::cerr << "Failed to establish IPC connection: " << connectionStatus.StatusToString() << std::endl;
        exit(-1);
    }

    while (true) {
        PublishToTopicRequest request;
        Vector<uint8_t> messageData({message.begin(), message.end()});
        BinaryMessage binaryMessage;
        binaryMessage.SetMessage(messageData);
        PublishMessage publishMessage;
        publishMessage.SetBinaryMessage(binaryMessage);
        request.SetTopic(topic);
        request.SetPublishMessage(publishMessage);

        auto operation = ipcClient.NewPublishToTopic();
        auto activate = operation->Activate(request, nullptr);
        activate.wait();

        auto responseFuture = operation->GetResult();
        if (responseFuture.wait_for(std::chrono::seconds(timeout)) == std::future_status::timeout) {
            std::cerr << "Operation timed out while waiting for response from Greengrass Core." << std::endl;
            exit(-1);
        }

        auto response = responseFuture.get();
        if (response) {
            std::cout << "Successfully published to topic: " << topic << std::endl;
        } else {
            // An error occurred.
            std::cout << "Failed to publish to topic: " << topic << std::endl;
            auto errorType = response.GetResultType();
            if (errorType == OPERATION_ERROR) {
                auto *error = response.GetOperationError();
                std::cout << "Operation error: " << error->GetMessage().value() << std::endl;
            } else {
                std::cout << "RPC error: " << response.GetRpcError() << std::endl;
            }
            exit(-1);
        }

        std::this_thread::sleep_for(std::chrono::seconds(5));
    }

    return 0;
}
```

### Ejemplo de publish/subscribe suscriptor (C\$1\$1, cliente IPC V1)
<a name="ipc-publish-subscribe-example-subscriber-cpp"></a>

La siguiente receta de ejemplo permite que el componente se suscriba a todos los temas.

------
#### [ JSON ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.PubSubSubscriberCpp",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that subscribes to messages.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.PubSubSubscriberCpp:pubsub:1": {
            "policyDescription": "Allows access to subscribe to all topics.",
            "operations": [
              "aws.greengrass#SubscribeToTopic"
            ],
            "resources": [
              "*"
            ]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Lifecycle": {
        "Run": "{artifacts:path}/greengrassv2_pub_sub_subscriber"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.PubSubSubscriberCpp/1.0.0/greengrassv2_pub_sub_subscriber",
          "Permission": {
            "Execute": "OWNER"
          }
        }
      ]
    }
  ]
}
```

------
#### [ YAML ]

```
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.PubSubSubscriberCpp
ComponentVersion: 1.0.0
ComponentDescription: A component that subscribes to messages.
ComponentPublisher: Amazon
ComponentConfiguration:
  DefaultConfiguration:
    accessControl:
      aws.greengrass.ipc.pubsub:
        com.example.PubSubSubscriberCpp:pubsub:1:
          policyDescription: Allows access to subscribe to all topics.
          operations:
            - aws.greengrass#SubscribeToTopic
          resources:
            - "*"
Manifests:
  - Lifecycle:
      Run: "{artifacts:path}/greengrassv2_pub_sub_subscriber"
    Artifacts:
      - URI: s3://amzn-s3-demo-bucket/artifacts/com.example.PubSubSubscriberCpp/1.0.0/greengrassv2_pub_sub_subscriber
        Permission:
          Execute: OWNER
```

------

El siguiente ejemplo de aplicación de C\$1\$1 demuestra cómo utilizar el servicio IPC de publicación/suscripción para suscribirse a los mensajes de otros componentes.

```
#include <iostream>

#include <aws/crt/Api.h>
#include <aws/greengrass/GreengrassCoreIpcClient.h>

using namespace Aws::Crt;
using namespace Aws::Greengrass;

class SubscribeResponseHandler : public SubscribeToTopicStreamHandler {
    public:
        virtual ~SubscribeResponseHandler() {}

    private:
        void OnStreamEvent(SubscriptionResponseMessage *response) override {
            auto jsonMessage = response->GetJsonMessage();
            if (jsonMessage.has_value() && jsonMessage.value().GetMessage().has_value()) {
                auto messageString = jsonMessage.value().GetMessage().value().View().WriteReadable();
                std::cout << "Received new message: " << messageString << std::endl;
            } else {
                auto binaryMessage = response->GetBinaryMessage();
                if (binaryMessage.has_value() && binaryMessage.value().GetMessage().has_value()) {
                    auto messageBytes = binaryMessage.value().GetMessage().value();
                    std::string messageString(messageBytes.begin(), messageBytes.end());
                    std::cout << "Received new message: " << messageString << std::endl;
                }
            }
        }

        bool OnStreamError(OperationError *error) override {
            std::cout << "Received an operation error: ";
            if (error->GetMessage().has_value()) {
                std::cout << error->GetMessage().value();
            }
            std::cout << std::endl;
            return false; // Return true to close stream, false to keep stream open.
        }

        void OnStreamClosed() override {
            std::cout << "Subscribe to topic stream closed." << std::endl;
        }
};

class IpcClientLifecycleHandler : public ConnectionLifecycleHandler {
    void OnConnectCallback() override {
        std::cout << "OnConnectCallback" << std::endl;
    }

    void OnDisconnectCallback(RpcError error) override {
        std::cout << "OnDisconnectCallback: " << error.StatusToString() << std::endl;
        exit(-1);
    }

    bool OnErrorCallback(RpcError error) override {
        std::cout << "OnErrorCallback: " << error.StatusToString() << std::endl;
        return true;
    }
};

int main() {
    String topic("test/topic/cpp");
    int timeout = 10;

    ApiHandle apiHandle(g_allocator);
    Io::EventLoopGroup eventLoopGroup(1);
    Io::DefaultHostResolver socketResolver(eventLoopGroup, 64, 30);
    Io::ClientBootstrap bootstrap(eventLoopGroup, socketResolver);
    IpcClientLifecycleHandler ipcLifecycleHandler;
    GreengrassCoreIpcClient ipcClient(bootstrap);
    auto connectionStatus = ipcClient.Connect(ipcLifecycleHandler).get();
    if (!connectionStatus) {
        std::cerr << "Failed to establish IPC connection: " << connectionStatus.StatusToString() << std::endl;
        exit(-1);
    }

    SubscribeToTopicRequest request;
    request.SetTopic(topic);
    auto streamHandler = MakeShared<SubscribeResponseHandler>(DefaultAllocator());
    auto operation = ipcClient.NewSubscribeToTopic(streamHandler);
    auto activate = operation->Activate(request, nullptr);
    activate.wait();

    auto responseFuture = operation->GetResult();
    if (responseFuture.wait_for(std::chrono::seconds(timeout)) == std::future_status::timeout) {
        std::cerr << "Operation timed out while waiting for response from Greengrass Core." << std::endl;
        exit(-1);
    }

    auto response = responseFuture.get();
    if (response) {
        std::cout << "Successfully subscribed to topic: " << topic << std::endl;
    } else {
        // An error occurred.
        std::cout << "Failed to subscribe to topic: " << topic << std::endl;
        auto errorType = response.GetResultType();
        if (errorType == OPERATION_ERROR) {
            auto *error = response.GetOperationError();
            std::cout << "Operation error: " << error->GetMessage().value() << std::endl;
        } else {
            std::cout << "RPC error: " << response.GetRpcError() << std::endl;
        }
        exit(-1);
    }

    // Keep the main thread alive, or the process will exit.
    while (true) {
        std::this_thread::sleep_for(std::chrono::seconds(10));
    }

    operation->Close();
    return 0;
}
```

### Ejemplo de publish/subscribe editor (Rust)
<a name="ipc-publish-subscribe-example-publisher-rust"></a>

La siguiente receta de ejemplo permite que el componente publique en todos los temas.

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.PubSubPublisherRust",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that publishes messages.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.PubSubPublisherRust:pubsub:1": {
            "policyDescription": "Allows access to publish to all topics.",
            "operations": ["aws.greengrass#PublishToTopic"],
            "resources": ["*"]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "{artifacts:path}/publish_to_topic"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.PubSubPublisherRust/1.0.0/publish_to_topic",
          "Permission": {
            "Execute": "OWNER"
          }
        }
      ]
    }
  ]
}
```

El siguiente ejemplo de aplicación Rust demuestra cómo utilizar el servicio IPC de publicación/suscripción para publicar mensajes en otros componentes.

```
use gg_sdk::Sdk;

fn main() {
    let sdk = Sdk::init();
    sdk.connect().expect("Failed to establish IPC connection");

    let message = b"Hello, World";
    let topic = "my/topic";

    sdk.publish_to_topic_binary(topic, message)
        .expect("Failed to publish to topic");

    println!("Successfully published to topic: {topic}");
}
```

### Ejemplo de publish/subscribe suscriptor (Rust)
<a name="ipc-publish-subscribe-example-subscriber-rust"></a>

La siguiente receta de ejemplo permite que el componente se suscriba a todos los temas.

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.PubSubSubscriberRust",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that subscribes to messages.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.PubSubSubscriberRust:pubsub:1": {
            "policyDescription": "Allows access to subscribe to all topics.",
            "operations": ["aws.greengrass#SubscribeToTopic"],
            "resources": ["*"]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "{artifacts:path}/subscribe_to_topic"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.PubSubSubscriberRust/1.0.0/subscribe_to_topic",
          "Permission": {
            "Execute": "OWNER"
          }
        }
      ]
    }
  ]
}
```

El siguiente ejemplo de aplicación Rust demuestra cómo utilizar el servicio IPC de publicación/suscripción para suscribirse a mensajes de otros componentes.

```
use gg_sdk::{Sdk, SubscribeToTopicPayload};
use std::{thread, time::Duration};

fn main() {
    let sdk = Sdk::init();
    sdk.connect().expect("Failed to establish IPC connection");

    let topic = "my/topic";

    let callback = |topic: &str, payload: SubscribeToTopicPayload| match payload
    {
        SubscribeToTopicPayload::Binary(message) => {
            let message = String::from_utf8_lossy(message);
            println!("Received new message on topic {topic}: {message}");
        }
        SubscribeToTopicPayload::Json(_) => {
            println!("Received new message on topic {topic}: (JSON message)");
        }
    };

    let _sub = sdk
        .subscribe_to_topic(topic, &callback)
        .expect("Failed to subscribe to topic");

    println!("Successfully subscribed to topic: {topic}");

    // Keep the main thread alive, or the process will exit.
    loop {
        thread::sleep(Duration::from_secs(10));
    }
}
```

### Ejemplo de publish/subscribe editor (C)
<a name="ipc-publish-subscribe-example-publisher-c"></a>

La siguiente receta de ejemplo permite que el componente publique en todos los temas.

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.PubSubPublisherC",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that publishes messages.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.PubSubPublisherC:pubsub:1": {
            "policyDescription": "Allows access to publish to all topics.",
            "operations": ["aws.greengrass#PublishToTopic"],
            "resources": ["*"]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "{artifacts:path}/sample_publish_to_topic"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.PubSubPublisherC/1.0.0/sample_publish_to_topic",
          "Permission": {
            "Execute": "OWNER"
          }
        }
      ]
    }
  ]
}
```

El siguiente ejemplo de aplicación en C muestra cómo utilizar el servicio IPC de publicación/suscripción para publicar mensajes en otros componentes.

```
#include <gg/error.h>
#include <gg/ipc/client.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);
    }

    GgBuffer message = GG_STR("Hello, World");
    GgBuffer topic = GG_STR("my/topic");

    err = ggipc_publish_to_topic_binary(topic, message);
    if (err != GG_ERR_OK) {
        fprintf(
            stderr,
            "Failed to publish to topic: %.*s\n",
            (int) topic.len,
            topic.data
        );
        exit(-1);
    }

    printf(
        "Successfully published to topic: %.*s\n", (int) topic.len, topic.data
    );
}
```

### Ejemplo de publish/subscribe suscriptor (C)
<a name="ipc-publish-subscribe-example-subscriber-c"></a>

La siguiente receta de ejemplo permite que el componente se suscriba a todos los temas.

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.PubSubSubscriberC",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that subscribes to messages.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.PubSubSubscriberC:pubsub:1": {
            "policyDescription": "Allows access to subscribe to all topics.",
            "operations": ["aws.greengrass#SubscribeToTopic"],
            "resources": ["*"]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "{artifacts:path}/sample_subscribe_to_topic"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.PubSubSubscriberC/1.0.0/sample_subscribe_to_topic",
          "Permission": {
            "Execute": "OWNER"
          }
        }
      ]
    }
  ]
}
```

El siguiente ejemplo de aplicación en C muestra cómo utilizar el servicio IPC de publicación/suscripción para suscribirse a los mensajes de otros componentes.

```
#include <assert.h>
#include <gg/error.h>
#include <gg/ipc/client.h>
#include <gg/object.h>
#include <gg/sdk.h>
#include <gg/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

static void on_subscription_response(
    void *ctx, GgBuffer topic, GgObject payload, GgIpcSubscriptionHandle handle
) {
    (void) ctx;
    (void) handle;

    if (gg_obj_type(payload) == GG_TYPE_BUF) {
        GgBuffer message = gg_obj_into_buf(payload);
        printf(
            "Received new message on topic %.*s: %.*s\n",
            (int) topic.len,
            topic.data,
            (int) message.len,
            message.data
        );
    } else {
        assert(gg_obj_type(payload) == GG_TYPE_MAP);
        printf(
            "Received new message on topic %.*s: (JSON message)\n",
            (int) topic.len,
            topic.data
        );
    }
}

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);
    }

    GgBuffer topic = GG_STR("my/topic");

    GgIpcSubscriptionHandle handle;
    err = ggipc_subscribe_to_topic(
        topic, on_subscription_response, NULL, &handle
    );
    if (err != GG_ERR_OK) {
        fprintf(
            stderr,
            "Failed to subscribe to topic: %.*s\n",
            (int) topic.len,
            topic.data
        );
        exit(-1);
    }

    printf(
        "Successfully subscribed to topic: %.*s\n", (int) topic.len, topic.data
    );

    // Keep the main thread alive, or the process will exit.
    while (1) {
        sleep(10);
    }

    // To stop subscribing, close the stream.
    ggipc_close_subscription(handle);
}
```

### Ejemplo de publish/subscribe editor (C\$1\$1, SDK de componentes)
<a name="ipc-publish-subscribe-example-publisher-cpp-component-sdk"></a>

La siguiente receta de ejemplo permite que el componente publique en todos los temas.

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.PubSubPublisherCpp",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that publishes messages.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.PubSubPublisherCpp:pubsub:1": {
            "policyDescription": "Allows access to publish to all topics.",
            "operations": ["aws.greengrass#PublishToTopic"],
            "resources": ["*"]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "{artifacts:path}/sample_cpp_publish_to_topic"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.PubSubPublisherCpp/1.0.0/sample_cpp_publish_to_topic",
          "Permission": {
            "Execute": "OWNER"
          }
        }
      ]
    }
  ]
}
```

El siguiente ejemplo de aplicación de C\$1\$1 demuestra cómo utilizar el servicio IPC de publicación/suscripción para publicar mensajes en otros componentes.

```
#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);
    }

    std::string_view message = "Hello, World";
    std::string_view topic = "my/topic";

    error = client.publish_to_topic(topic, message);
    if (error) {
        std::cerr << "Failed to publish to topic: " << topic << "\n";
        exit(-1);
    }

    std::cout << "Successfully published to topic: " << topic << "\n";
}
```

### Ejemplo de publish/subscribe suscriptor (C\$1\$1, SDK de componentes)
<a name="ipc-publish-subscribe-example-subscriber-cpp-component-sdk"></a>

La siguiente receta de ejemplo permite que el componente se suscriba a todos los temas.

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.PubSubSubscriberCpp",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that subscribes to messages.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.PubSubSubscriberCpp:pubsub:1": {
            "policyDescription": "Allows access to subscribe to all topics.",
            "operations": ["aws.greengrass#SubscribeToTopic"],
            "resources": ["*"]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "{artifacts:path}/sample_cpp_subscribe_to_topic"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.PubSubSubscriberCpp/1.0.0/sample_cpp_subscribe_to_topic",
          "Permission": {
            "Execute": "OWNER"
          }
        }
      ]
    }
  ]
}
```

El siguiente ejemplo de aplicación de C\$1\$1 demuestra cómo utilizar el servicio IPC de publicación/suscripción para suscribirse a los mensajes de otros componentes.

```
#include <gg/ipc/client.hpp>
#include <gg/object.hpp>
#include <unistd.h>
#include <cassert>
#include <iostream>

class ResponseHandler : public gg::ipc::LocalTopicCallback {
    void operator()(
        std::string_view topic,
        gg::Object payload,
        gg::ipc::Subscription &handle
    ) override {
        (void) handle;
        if (payload.index() == GG_TYPE_BUF) {
            std::cout << "Received new message on topic " << topic << ": "
                      << get<gg::Buffer>(payload) << "\n";
        } else {
            assert(payload.index() == GG_TYPE_MAP);
            std::cout << "Received new message on topic " << topic
                      << ": (JSON message)\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);
    }

    std::string_view topic = "my/topic";

    static ResponseHandler handler;
    error = client.subscribe_to_topic(topic, handler);
    if (error) {
        std::cerr << "Failed to subscribe to topic: " << topic << "\n";
        exit(-1);
    }

    std::cout << "Successfully subscribed to topic: " << topic << "\n";

    // Keep the main thread alive, or the process will exit.
    while (1) {
        sleep(10);
    }
}
```

# Publicar/suscribir mensajes MQTT AWS IoT Core
<a name="ipc-iot-core-mqtt"></a>

El servicio IPC de mensajería AWS IoT Core MQTT le permite enviar y recibir mensajes MQTT de ida y vuelta. AWS IoT Core Los componentes pueden publicar mensajes en los temas AWS IoT Core y suscribirse a ellos para actuar en función de los mensajes MQTT de otras fuentes. *Para obtener más información sobre la AWS IoT Core implementación de MQTT, consulte [MQTT](https://docs.aws.amazon.com/iot/latest/developerguide/mqtt.html) en la AWS IoT Core Guía para desarrolladores.*

**nota**  
Este servicio IPC de mensajería MQTT le permite intercambiar mensajes con. AWS IoT Core Para obtener más información sobre cómo intercambiar mensajes entre componentes, consulte [Publicar/suscribir mensajes locales](ipc-publish-subscribe.md).

**Topics**
+ [Versiones mínimas de SDK](#ipc-iot-core-mqtt-sdk-versions)
+ [Autorización](#ipc-iot-core-mqtt-authorization)
+ [PublishToIoTCore](#ipc-operation-publishtoiotcore)
+ [SubscribeToIoTCore](#ipc-operation-subscribetoiotcore)
+ [Ejemplos](#ipc-iot-core-mqtt-examples)

## Versiones mínimas de SDK
<a name="ipc-iot-core-mqtt-sdk-versions"></a>

En la siguiente tabla se enumeran las versiones mínimas de las SDK para dispositivos con AWS IoT que debe utilizar para publicar y recibir mensajes MQTT y suscribirse a ellos. AWS IoT Core


| SDK | Versión mínima | 
| --- | --- | 
|  [SDK para dispositivos con AWS IoT para Java v2](https://github.com/aws/aws-iot-device-sdk-java-v2)  |  Versión 1.2.10  | 
|  [SDK para dispositivos con AWS IoT para Python v2](https://github.com/aws/aws-iot-device-sdk-python-v2)  |  Versión 1.5.3  | 
|  [SDK para dispositivos con AWS IoT para C\$1\$1 v2](https://github.com/aws/aws-iot-device-sdk-cpp-v2)  |  Versión 1.17.0  | 
|  [SDK para dispositivos con AWS IoT para JavaScript v2](https://github.com/aws/aws-iot-device-sdk-js-v2)  |  Versión 1.12.0  | 

## Autorización
<a name="ipc-iot-core-mqtt-authorization"></a>

Para utilizar la mensajería AWS IoT Core MQTT en un componente personalizado, debe definir políticas de autorización que permitan a su componente enviar y recibir mensajes sobre temas. Para obtener información sobre cómo definir las políticas de autorización, consulte [Autorización de los componentes para realizar operaciones de IPC](interprocess-communication.md#ipc-authorization-policies).

Las políticas de autorización para la mensajería AWS IoT Core MQTT tienen las siguientes propiedades.

**Identificador de servicio IPC:** `aws.greengrass.ipc.mqttproxy`


| Operación | Description (Descripción) | Recursos | 
| --- | --- | --- | 
|  `aws.greengrass#PublishToIoTCore`  |  Permite que un componente publique mensajes AWS IoT Core en los temas de MQTT que especifique.  |  Una cadena de temas, por ejemplo, `test/topic`, o `*` para permitir el acceso a todos los temas. Puede utilizar los caracteres comodín (`#` y `+`) de los temas de MQTT para hacer coincidir varios recursos.  | 
|  `aws.greengrass#SubscribeToIoTCore`  |  Permite que un componente se suscriba a los mensajes AWS IoT Core de los temas que especifique.  |  Una cadena de temas, por ejemplo, `test/topic`, o `*` para permitir el acceso a todos los temas. Puede utilizar los caracteres comodín (`#` y `+`) de los temas de MQTT para hacer coincidir varios recursos.  | 
|  `*`  |  Permite que un componente publique y se suscriba a los mensajes de AWS IoT Core MQTT para los temas que especifique.  |  Una cadena de temas, por ejemplo, `test/topic`, o `*` para permitir el acceso a todos los temas. Puede utilizar los caracteres comodín (`#` y `+`) de los temas de MQTT para hacer coincidir varios recursos.  | 

### Comodín de MQTT en AWS IoT Core las políticas de autorización de MQTT
<a name="ipc-iot-core-mqtt-authorization-mqtt-wildcards"></a>

Puede utilizar caracteres comodín de MQTT en AWS IoT Core las políticas de autorización de IPC de MQTT. Los componentes pueden publicar y suscribirse a temas que coincidan con el filtro de temas que usted permita en una política de autorización. Por ejemplo, si la política de autorización de un componente concede acceso a `test/topic/#`, el componente puede suscribirse a `test/topic/#`, publicar y suscribirse a `test/topic/filter`.

### Variables de receta en las políticas de autorización de MQTT AWS IoT Core
<a name="ipc-iot-core-mqtt-authorization-recipe-variables"></a>

Si usa la versión 2.6.0 o posterior del [núcleo de Greengrass](greengrass-nucleus-component.md), puede usar la variable de receta `{iot:thingName}` en las políticas de autorización. Esta característica le permite configurar una política de autorización única para un grupo de dispositivos principales, de forma que cada dispositivo principal solo pueda acceder a los temas que contengan su propio nombre. Por ejemplo, puede permitir que un componente acceda al siguiente recurso de tema.

```
devices/{iot:thingName}/messages
```

Para obtener más información, consulte [Variables de receta](component-recipe-reference.md#recipe-variables) y [Uso de variables de receta en las actualizaciones de combinación](update-component-configurations.md#merge-configuration-update-recipe-variables).

### Ejemplos de políticas de autorización
<a name="ipc-iot-core-mqtt-authorization-policy-examples"></a>

Puede consultar los siguientes ejemplos de políticas de autorización con el fin de configurar las políticas de autorización para sus componentes.

**Example Ejemplo de política de autorización con acceso ilimitado**  
El siguiente ejemplo de política de autorización permite a un componente publicar y suscribirse a todos los temas.  

```
{
  "accessControl": {
    "aws.greengrass.ipc.mqttproxy": {
      "com.example.MyIoTCorePubSubComponent:mqttproxy:1": {
        "policyDescription": "Allows access to publish/subscribe to all topics.",
        "operations": [
          "aws.greengrass#PublishToIoTCore",
          "aws.greengrass#SubscribeToIoTCore"
        ],
        "resources": [
          "*"
        ]
      }
    }
  }
}
```

```
---
accessControl:
  aws.greengrass.ipc.mqttproxy:
    com.example.MyIoTCorePubSubComponent:mqttproxy:1:
      policyDescription: Allows access to publish/subscribe to all topics.
      operations:
        - aws.greengrass#PublishToIoTCore
        - aws.greengrass#SubscribeToIoTCore
      resources:
        - "*"
```

**Example Ejemplo de política de autorización con acceso limitado**  
El siguiente ejemplo de política de autorización permite a un componente publicar y suscribirse a dos temas denominados `factory/1/events` y `factory/1/actions`.  

```
{
  "accessControl": {
    "aws.greengrass.ipc.mqttproxy": {
      "com.example.MyIoTCorePubSubComponent:mqttproxy:1": {
        "policyDescription": "Allows access to publish/subscribe to factory 1 topics.",
        "operations": [
          "aws.greengrass#PublishToIoTCore",
          "aws.greengrass#SubscribeToIoTCore"
        ],
        "resources": [
          "factory/1/actions",
          "factory/1/events"
        ]
      }
    }
  }
}
```

```
---
accessControl:
  aws.greengrass.ipc.mqttproxy:
    "com.example.MyIoTCorePubSubComponent:mqttproxy:1":
      policyDescription: Allows access to publish/subscribe to factory 1 topics.
      operations:
        - aws.greengrass#PublishToIoTCore
        - aws.greengrass#SubscribeToIoTCore
      resources:
        - factory/1/actions
        - factory/1/events
```

**Example Ejemplo de política de autorización para un grupo de dispositivos principales**  
En este ejemplo, se utiliza una característica que está disponible para la versión 2.6.0 y versiones posteriores del [componente núcleo de Greengrass](greengrass-nucleus-component.md). El núcleo de Greengrass versión 2.6.0 suma compatibilidad con la mayoría de las [variables de receta](component-recipe-reference.md#recipe-variables), por ejemplo: `{iot:thingName}`, en las configuraciones de componentes.
El siguiente ejemplo de política de autorización permite a un componente publicar y suscribirse a un tema que contenga el nombre del dispositivo principal que ejecuta el componente.  

```
{
  "accessControl": {
    "aws.greengrass.ipc.mqttproxy": {
      "com.example.MyIoTCorePubSubComponent:mqttproxy:1": {
        "policyDescription": "Allows access to publish/subscribe to all topics.",
        "operations": [
          "aws.greengrass#PublishToIoTCore",
          "aws.greengrass#SubscribeToIoTCore"
        ],
        "resources": [
          "factory/1/devices/{iot:thingName}/controls"
        ]
      }
    }
  }
}
```

```
---
accessControl:
  aws.greengrass.ipc.mqttproxy:
    "com.example.MyIoTCorePubSubComponent:mqttproxy:1":
      policyDescription: Allows access to publish/subscribe to all topics.
      operations:
        - aws.greengrass#PublishToIoTCore
        - aws.greengrass#SubscribeToIoTCore
      resources:
        - factory/1/devices/{iot:thingName}/controls
```

## PublishToIoTCore
<a name="ipc-operation-publishtoiotcore"></a>

Publica un mensaje de MQTT AWS IoT Core sobre un tema.

Al publicar mensajes MQTT en AWS IoT Core, hay una cuota de 100 transacciones por segundo. Si supera esta cuota, los mensajes se ponen en cola para su procesamiento en el dispositivo de Greengrass. También hay una cuota de 512 KB de datos por segundo y una cuota de 20 000 publicaciones por segundo en toda la cuenta (2 000 en algunos casos). Regiones de AWS Para obtener más información sobre el límite del agente de mensajes MQTT en AWS IoT Core, consulte [Límites de protocolo y cuotas del agente de mensajes de AWS IoT Core](https://docs.aws.amazon.com/general/latest/gr/iot-core.html#message-broker-limits). 

Si superas estas cuotas, el dispositivo Greengrass limita la publicación de mensajes a. AWS IoT Core Los mensajes se almacenan en un spooler de memoria. De forma predeterminada, la memoria asignada al spooler es de 2,5 Mb. Si el spooler se llena, se rechazan los mensajes nuevos. Puede aumentar el tamaño del spooler. Para obtener más información, consulte [Configuración](greengrass-nucleus-component.md#greengrass-nucleus-component-configuration) en la documentación del [Núcleo de Greengrass](greengrass-nucleus-component.md). Para evitar llenar el espacio y tener que aumentar la memoria asignada, limite las solicitudes de publicación a no más de 100 solicitudes por segundo.

Si su aplicación necesita enviar mensajes a una velocidad mayor o mensajes más grandes, considere utilizar el [Administrador de flujos](stream-manager-component.md) para enviar mensajes a Kinesis Data Streams. El componente administrador de flujos está diseñado para transferir grandes volúmenes de datos a la Nube de AWS. Para obtener más información, consulte [Administración de flujos de datos en los dispositivos principales de Greengrass](manage-data-streams.md).

### Solicitud
<a name="ipc-operation-publishtoiotcore-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`topicName` (Python: `topic_name`)  
El tema en el que se va a publicar el mensaje.

`qos`  <a name="ipc-iot-core-mqtt-qos"></a>
La QoS de MQTT que se va a utilizar. Esta enumeración, `QOS`, tiene los siguientes valores:  
+ `AT_MOST_ONCE`: QoS 0. El mensaje MQTT se entrega como máximo una vez.
+ `AT_LEAST_ONCE`: QoS 1. El mensaje MQTT se entrega como máximo una vez.

`payload`  
(Opcional) El mensaje se carga como un blob.

Las siguientes características están disponibles para la versión 2.10.0 y versiones posteriores del [Núcleo de Greengrass](greengrass-nucleus-component.md) cuando se utiliza MQTT 5. Estas características no se tienen en cuenta al utilizar MQTT 3.1.1. La siguiente tabla muestra la versión mínima del SDK del AWS IoT dispositivo que debe usar para acceder a estas funciones.


| SDK | Versión mínima | 
| --- | --- | 
| [AWS IoT Device SDK para Python  ](https://github.com/aws/aws-iot-device-sdk-python-v2) v2 | Versión 1.15.0 | 
| [AWS IoT Device SDK para Java  ](https://github.com/aws/aws-iot-device-sdk-java-v2) v2 | Versión 1.13.0 | 
| [AWS IoT Device SDK para C\$1\$1  ](https://github.com/aws/aws-iot-device-sdk-cpp-v2) v2 | Versión 1.24.0 | 
| [SDK de AWS IoT Device para JavaScript  ](https://github.com/aws/aws-iot-device-sdk-js-v2) v2  | Versión 1.13.0 | 

`payloadFormat`  
(Opcional) El formato de la carga útil del mensaje. Si no establece el `payloadFormat`, se supone que el tipo es `BYTES`. Esta enumeración tiene los siguientes valores:   
+ `BYTES`: el contenido de la carga útil es un blob binario.
+ `UTF8`— El contenido de la carga útil es una UTF8 cadena de caracteres.

`retain`  
(Opcional) Indica si se debe configurar la opción de retención de MQTT en `true` durante la publicación.

`userProperties`  
(Opcional) Una lista de objetos `UserProperty` específicos de la aplicación para enviar. El objeto `UserProperty` se define de la siguiente manera:  

```
UserProperty:
  key: string
  value: string
```

`messageExpiryIntervalSeconds`  
(Opcional) La cantidad de segundos antes de que el mensaje venza y el servidor lo elimine. Si no se establece este valor, el mensaje no vence.

`correlationData`  
(Opcional) Información agregada a la solicitud que se puede usar para asociar una solicitud a una respuesta.

`responseTopic`  
(Opcional) El tema que debe usarse para el mensaje de respuesta.

`contentType`  
(Opcional) Un identificador específico de la aplicación del tipo de contenido del mensaje.

### Respuesta
<a name="ipc-operation-publishtoiotcore-response"></a>

Esta operación no proporciona ninguna información en su respuesta.

### Ejemplos
<a name="ipc-operation-publishtoiotcore-examples"></a>

En los ejemplos siguientes, se muestra cómo llamar a esta operación en código de componente personalizado.

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

**Example Ejemplo: publicar un mensaje**  

```
package com.aws.greengrass.docs.samples.ipc;

import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClientV2;
import software.amazon.awssdk.aws.greengrass.model.PublishToIoTCoreRequest;
import software.amazon.awssdk.aws.greengrass.model.QOS;
import java.nio.charset.StandardCharsets;

public class PublishToIoTCore {

    public static void main(String[] args) {
        String topic = args[0];
        String message = args[1];
        QOS qos = QOS.get(args[2]);

        try (GreengrassCoreIPCClientV2 ipcClientV2 = GreengrassCoreIPCClientV2.builder().build()) {
            ipcClientV2.publishToIoTCore(new PublishToIoTCoreRequest()
                    .withTopicName(topic)
                    .withPayload(message.getBytes(StandardCharsets.UTF_8))
                    .withQos(qos));
            System.out.println("Successfully published to topic: " + topic);
        } catch (Exception e) {
            System.err.println("Exception occurred.");
            e.printStackTrace();
            System.exit(1);
        }
    }
}
```

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

**Example Ejemplo: publicar un mensaje**  
En este ejemplo se supone que está utilizando la versión 1.5.4 o posterior de SDK para dispositivos con AWS IoT para Python v2. 

```
import awsiot.greengrasscoreipc.clientv2 as clientV2
                    
topic = 'my/topic'
qos = '1'
payload = 'Hello, World'

ipc_client = clientV2.GreengrassCoreIPCClientV2()
resp = ipc_client.publish_to_iot_core(topic_name=topic, qos=qos, payload=payload)
ipc_client.close()
```

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

**Example Ejemplo: publicar un mensaje**  
En este ejemplo, se utiliza una `IPCUtils` clase para crear una conexión con el servicio AWS IoT Greengrass Core IPC. Para obtener más información, consulte [Conéctese al AWS IoT Greengrass servicio Core 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.PublishToIoTCoreResponseHandler;
import software.amazon.awssdk.aws.greengrass.model.PublishToIoTCoreRequest;
import software.amazon.awssdk.aws.greengrass.model.PublishToIoTCoreResponse;
import software.amazon.awssdk.aws.greengrass.model.QOS;
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 PublishToIoTCore {

    public static final int TIMEOUT_SECONDS = 10;

    public static void main(String[] args) {
        String topic = args[0];
        String message = args[1];
        QOS qos = QOS.get(args[2]);
        try (EventStreamRPCConnection eventStreamRPCConnection =
                     IPCUtils.getEventStreamRpcConnection()) {
            GreengrassCoreIPCClient ipcClient =
                    new GreengrassCoreIPCClient(eventStreamRPCConnection);
            PublishToIoTCoreResponseHandler responseHandler =
                    PublishToIoTCore.publishBinaryMessageToTopic(ipcClient, topic, message, qos);
            CompletableFuture<PublishToIoTCoreResponse> futureResponse =
                    responseHandler.getResponse();
            try {
                futureResponse.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
                System.out.println("Successfully published to topic: " + topic);
            } catch (TimeoutException e) {
                System.err.println("Timeout occurred while publishing to topic: " + topic);
            } catch (ExecutionException e) {
                if (e.getCause() instanceof UnauthorizedError) {
                    System.err.println("Unauthorized error while publishing to topic: " + topic);
                } 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 PublishToIoTCoreResponseHandler publishBinaryMessageToTopic(GreengrassCoreIPCClient greengrassCoreIPCClient, String topic, String message, QOS qos) {
        PublishToIoTCoreRequest publishToIoTCoreRequest = new PublishToIoTCoreRequest();
        publishToIoTCoreRequest.setTopicName(topic);
        publishToIoTCoreRequest.setPayload(message.getBytes(StandardCharsets.UTF_8));
        publishToIoTCoreRequest.setQos(qos);
        return greengrassCoreIPCClient.publishToIoTCore(publishToIoTCoreRequest, Optional.empty());
    }
}
```

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

**Example Ejemplo: publicar un mensaje**  
En este ejemplo se supone que está utilizando la versión 1.5.4 o posterior de SDK para dispositivos con AWS IoT para Python v2. 

```
import awsiot.greengrasscoreipc
import awsiot.greengrasscoreipc.client as client
from awsiot.greengrasscoreipc.model import (
    QOS,
    PublishToIoTCoreRequest
)

TIMEOUT = 10

ipc_client = awsiot.greengrasscoreipc.connect()
                    
topic = "my/topic"
message = "Hello, World"
qos = QOS.AT_LEAST_ONCE

request = PublishToIoTCoreRequest()
request.topic_name = topic
request.payload = bytes(message, "utf-8")
request.qos = qos
operation = ipc_client.new_publish_to_iot_core()
operation.activate(request)
future_response = operation.get_response()
future_response.result(TIMEOUT)
```

------
#### [ C\$1\$1 (IPC client V1) ]

**Example Ejemplo: publicar un mensaje**  

```
#include <iostream>

#include <aws/crt/Api.h>
#include <aws/greengrass/GreengrassCoreIpcClient.h>

using namespace Aws::Crt;
using namespace Aws::Greengrass;

class IpcClientLifecycleHandler : public ConnectionLifecycleHandler {
    void OnConnectCallback() override {
        // Handle connection to IPC service.
    }

    void OnDisconnectCallback(RpcError error) override {
        // Handle disconnection from IPC service.
    }

    bool OnErrorCallback(RpcError error) override {
        // Handle IPC service connection error.
        return true;
    }
};

int main() {
    ApiHandle apiHandle(g_allocator);
    Io::EventLoopGroup eventLoopGroup(1);
    Io::DefaultHostResolver socketResolver(eventLoopGroup, 64, 30);
    Io::ClientBootstrap bootstrap(eventLoopGroup, socketResolver);
    IpcClientLifecycleHandler ipcLifecycleHandler;
    GreengrassCoreIpcClient ipcClient(bootstrap);
    auto connectionStatus = ipcClient.Connect(ipcLifecycleHandler).get();
    if (!connectionStatus) {
        std::cerr << "Failed to establish IPC connection: " << connectionStatus.StatusToString() << std::endl;
        exit(-1);
    }

    String message("Hello, World!");
    String topic("my/topic");
    QOS qos = QOS_AT_MOST_ONCE;
    int timeout = 10;

    PublishToIoTCoreRequest request;
    Vector<uint8_t> messageData({message.begin(), message.end()});
    request.SetTopicName(topic);
    request.SetPayload(messageData);
    request.SetQos(qos);

    auto operation = ipcClient.NewPublishToIoTCore();
    auto activate = operation->Activate(request, nullptr);
    activate.wait();

    auto responseFuture = operation->GetResult();
    if (responseFuture.wait_for(std::chrono::seconds(timeout)) == std::future_status::timeout) {
        std::cerr << "Operation timed out while waiting for response from Greengrass Core." << std::endl;
        exit(-1);
    }

    auto response = responseFuture.get();
    if (!response) {
        // Handle error.
        auto errorType = response.GetResultType();
        if (errorType == OPERATION_ERROR) {
            auto *error = response.GetOperationError();
            (void)error;
            // Handle operation error.
        } else {
            // Handle RPC error.
        }
    }

    return 0;
}
```

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

**Example Ejemplo: publicar un mensaje**  

```
    
import * as greengrasscoreipc from "aws-iot-device-sdk-v2/dist/greengrasscoreipc";
import {QOS, PublishToIoTCoreRequest} from "aws-iot-device-sdk-v2/dist/greengrasscoreipc/model";
 
class PublishToIoTCore {
    private ipcClient: greengrasscoreipc.Client
    private readonly topic: string;
 
    constructor() {
        // define your own constructor, e.g.
        this.topic = "<define_your_topic>";
        this.publishToIoTCore().then(r => console.log("Started workflow"));
    }
 
    private async publishToIoTCore() {
        try {
            const request: PublishToIoTCoreRequest = {
                topicName: this.topic,
                qos: QOS.AT_LEAST_ONCE, // you can change this depending on your use case
            }
 
            this.ipcClient = await getIpcClient();
 
            await this.ipcClient.publishToIoTCore(request);
        } catch (e) {
            // parse the error depending on your use cases
            throw e
        }
    }
}
 
 
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
    }
}
 
// starting point
const publishToIoTCore = new PublishToIoTCore();
```

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

**Example Ejemplo: publicar un mensaje**  

```
use gg_sdk::{Qos, Sdk};

fn main() {
    let sdk = Sdk::init();
    sdk.connect().expect("Failed to establish IPC connection");

    let message = b"Hello, World";
    let topic = "my/topic";
    let qos = Qos::AtLeastOnce;

    sdk.publish_to_iot_core(topic, message, qos)
        .expect("Failed to publish to topic");

    println!("Successfully published to topic: {topic}");
}
```

------
#### [ C ]

**Example Ejemplo: publicar un mensaje**  

```
#include <gg/error.h>
#include <gg/ipc/client.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);
    }

    GgBuffer message = GG_STR("Hello, World");
    GgBuffer topic = GG_STR("my/topic");
    uint8_t qos = 1;

    err = ggipc_publish_to_iot_core(topic, message, qos);
    if (err != GG_ERR_OK) {
        fprintf(
            stderr,
            "Failed to publish to topic: %.*s\n",
            (int) topic.len,
            topic.data
        );
        exit(-1);
    }

    printf(
        "Successfully published to topic: %.*s\n", (int) topic.len, topic.data
    );
}
```

------
#### [ C\$1\$1 (Component SDK) ]

**Example Ejemplo: publicar un mensaje**  

```
#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);
    }

    std::string_view message = "Hello, World";
    std::string_view topic = "my/topic";
    uint8_t qos = 1;

    error = client.publish_to_iot_core(topic, message, qos);
    if (error) {
        std::cerr << "Failed to publish to topic: " << topic << "\n";
        exit(-1);
    }

    std::cout << "Successfully published to topic: " << topic << "\n";
}
```

------

## SubscribeToIoTCore
<a name="ipc-operation-subscribetoiotcore"></a>

Suscríbase a los mensajes de MQTT AWS IoT Core de un tema o filtro de temas. El software AWS IoT Greengrass Core elimina las suscripciones cuando el componente llega al final de su ciclo de vida.

<a name="ipc-subscribe-operation-note"></a>Esta es una operación de suscripción en la que se suscribe a un flujo de mensajes de eventos. Para usar esta operación, defina un identificador de respuesta de flujo con funciones que gestionen los mensajes de eventos, los errores y el cierre del flujo. Para obtener más información, consulte [Suscripción a los flujos de eventos de IPC](interprocess-communication.md#ipc-subscribe-operations).

**Tipo de mensaje del evento:** `IoTCoreMessage`

### Solicitud
<a name="ipc-operation-subscribetoiotcore-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`topicName` (Python: `topic_name`)  
El tema al que se suscribe. Puede utilizar los comodines (`#` y `+`) de los temas de MQTT para suscribirse a varios temas.

`qos`  <a name="ipc-iot-core-mqtt-qos"></a>
La QoS de MQTT que se va a utilizar. Esta enumeración, `QOS`, tiene los siguientes valores:  
+ `AT_MOST_ONCE`: QoS 0. El mensaje MQTT se entrega como máximo una vez.
+ `AT_LEAST_ONCE`: QoS 1. El mensaje MQTT se entrega como máximo una vez.

### Respuesta
<a name="ipc-operation-subscribetoiotcore-response"></a>

Esta respuesta de operación contiene la siguiente información:

`messages`  
El flujo de mensajes MQTT. Este objeto, `IoTCoreMessage`, contiene la siguiente información:    
`message`  
El mensaje MQTT. Este objeto, `MQTTMessage`, contiene la siguiente información:    
`topicName` (Python: `topic_name`)  
El tema en el que se publicó el mensaje.  
`payload`  
(Opcional) El mensaje se carga como un blob.
Las siguientes características están disponibles para la versión 2.10.0 y versiones posteriores del [Núcleo de Greengrass](greengrass-nucleus-component.md) cuando se utiliza MQTT 5. Estas características no se tienen en cuenta al utilizar MQTT 3.1.1. En la siguiente tabla se muestra la versión mínima del SDK del AWS IoT dispositivo que debes usar para acceder a estas funciones.      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/greengrass/v2/developerguide/ipc-iot-core-mqtt.html)  
`payloadFormat`  
(Opcional) El formato de la carga útil del mensaje. Si no establece el `payloadFormat`, se supone que el tipo es `BYTES`. Esta enumeración tiene los siguientes valores:   
+ `BYTES`: el contenido de la carga útil es un blob binario.
+ `UTF8`— El contenido de la carga útil es una UTF8 cadena de caracteres.  
`retain`  
(Opcional) Indica si se debe configurar la opción de retención de MQTT en `true` durante la publicación.  
`userProperties`  
(Opcional) Una lista de objetos `UserProperty` específicos de la aplicación para enviar. El objeto `UserProperty` se define de la siguiente manera:  

```
UserProperty:
  key: string
  value: string
```  
`messageExpiryIntervalSeconds`  
(Opcional) La cantidad de segundos antes de que el mensaje venza y el servidor lo elimine. Si no se establece este valor, el mensaje no vence.  
`correlationData`  
(Opcional) Información agregada a la solicitud que se puede usar para asociar una solicitud a una respuesta.  
`responseTopic`  
(Opcional) El tema que debe usarse para el mensaje de respuesta.  
`contentType`  
(Opcional) Un identificador específico de la aplicación del tipo de contenido del mensaje.

### Ejemplos
<a name="ipc-operation-subscribetoiotcore-examples"></a>

En los ejemplos siguientes, se muestra cómo llamar a esta operación en código de componente personalizado.

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

**Example Ejemplo: suscribirse a los mensajes**  

```
package com.aws.greengrass.docs.samples.ipc;

import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClientV2;
import software.amazon.awssdk.aws.greengrass.SubscribeToIoTCoreResponseHandler;
import software.amazon.awssdk.aws.greengrass.model.QOS;
import software.amazon.awssdk.aws.greengrass.model.IoTCoreMessage;
import software.amazon.awssdk.aws.greengrass.model.SubscribeToIoTCoreRequest;
import software.amazon.awssdk.aws.greengrass.model.SubscribeToIoTCoreResponse;

import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;


public class SubscribeToIoTCore {

    public static void main(String[] args) {
        String topic = args[0];
        QOS qos = QOS.get(args[1]);

        Consumer<IoTCoreMessage> onStreamEvent = ioTCoreMessage ->
                System.out.printf("Received new message on topic %s: %s%n",
                        ioTCoreMessage.getMessage().getTopicName(),
                        new String(ioTCoreMessage.getMessage().getPayload(), StandardCharsets.UTF_8));

        Optional<Function<Throwable, Boolean>> onStreamError =
                Optional.of(e -> {
                    System.err.println("Received a stream error.");
                    e.printStackTrace();
                    return false;
                });

        Optional<Runnable> onStreamClosed = Optional.of(() ->
                System.out.println("Subscribe to IoT Core stream closed."));

        try (GreengrassCoreIPCClientV2 ipcClientV2 = GreengrassCoreIPCClientV2.builder().build()) {
            SubscribeToIoTCoreRequest request = new SubscribeToIoTCoreRequest()
                    .withTopicName(topic)
                    .withQos(qos);

            GreengrassCoreIPCClientV2.StreamingResponse<SubscribeToIoTCoreResponse, SubscribeToIoTCoreResponseHandler>
                    streamingResponse = ipcClientV2.subscribeToIoTCore(request, onStreamEvent, onStreamError, onStreamClosed);

            streamingResponse.getResponse();
            System.out.println("Successfully subscribed to topic: " + topic);

            // Keep the main thread alive, or the process will exit.
            while (true) {
                Thread.sleep(10000);
            }

            // To stop subscribing, close the stream.
            streamingResponse.getHandler().closeStream();
        } catch (InterruptedException e) {
            System.out.println("Subscribe interrupted.");
        } catch (Exception e) {
            System.err.println("Exception occurred.");
            e.printStackTrace();
            System.exit(1);
        }
    }
}
```

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

**Example Ejemplo: suscribirse a los mensajes**  
En este ejemplo se supone que está utilizando la versión 1.5.4 o posterior de SDK para dispositivos con AWS IoT para Python v2. 

```
import threading
import traceback

import awsiot.greengrasscoreipc.clientv2 as clientV2
                    
topic = 'my/topic'
qos = '1'

def on_stream_event(event):
    try:
        topic_name = event.message.topic_name
        message = str(event.message.payload, 'utf-8')
        print(f'Received new message on topic {topic_name}:  {message}')
    except:
        traceback.print_exc()

def on_stream_error(error):
    # Return True to close stream, False to keep stream open.
    return True  

def on_stream_closed():
    pass

ipc_client = clientV2.GreengrassCoreIPCClientV2()
resp, operation = ipc_client.subscribe_to_iot_core(
    topic_name=topic,
    qos=qos, 
    on_stream_event=on_stream_event,
    on_stream_error=on_stream_error,
    on_stream_closed=on_stream_closed
)

# Keep the main thread alive, or the process will exit.
event = threading.Event()
event.wait()

# To stop subscribing, close the operation stream.
operation.close()
ipc_client.close()
```

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

**Example Ejemplo: suscribirse a los mensajes**  
En este ejemplo, se utiliza una `IPCUtils` clase para crear una conexión con el servicio AWS IoT Greengrass Core IPC. Para obtener más información, consulte [Conéctese al AWS IoT Greengrass servicio Core 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.SubscribeToIoTCoreResponseHandler;
import software.amazon.awssdk.aws.greengrass.model.*;
import software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection;
import software.amazon.awssdk.eventstreamrpc.StreamResponseHandler;

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 SubscribeToIoTCore {

    public static final int TIMEOUT_SECONDS = 10;

    public static void main(String[] args) {
        String topic = args[0];
        QOS qos = QOS.get(args[1]);
        try (EventStreamRPCConnection eventStreamRPCConnection =
                     IPCUtils.getEventStreamRpcConnection()) {
            GreengrassCoreIPCClient ipcClient =
                    new GreengrassCoreIPCClient(eventStreamRPCConnection);
            StreamResponseHandler<IoTCoreMessage> streamResponseHandler =
                    new SubscriptionResponseHandler();
            SubscribeToIoTCoreResponseHandler responseHandler =
                    SubscribeToIoTCore.subscribeToIoTCore(ipcClient, topic, qos,
                            streamResponseHandler);
            CompletableFuture<SubscribeToIoTCoreResponse> futureResponse =
                    responseHandler.getResponse();
            try {
                futureResponse.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
                System.out.println("Successfully subscribed to topic: " + topic);
            } catch (TimeoutException e) {
                System.err.println("Timeout occurred while subscribing to topic: " + topic);
            } catch (ExecutionException e) {
                if (e.getCause() instanceof UnauthorizedError) {
                    System.err.println("Unauthorized error while subscribing to topic: " + topic);
                } else {
                    throw e;
                }
            }

            // Keep the main thread alive, or the process will exit.
            try {
                while (true) {
                    Thread.sleep(10000);
                }
            } catch (InterruptedException e) {
                System.out.println("Subscribe interrupted.");
            }

            // To stop subscribing, close the stream.
            responseHandler.closeStream();
        } 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 SubscribeToIoTCoreResponseHandler subscribeToIoTCore(GreengrassCoreIPCClient greengrassCoreIPCClient, String topic, QOS qos, StreamResponseHandler<IoTCoreMessage> streamResponseHandler) {
        SubscribeToIoTCoreRequest subscribeToIoTCoreRequest = new SubscribeToIoTCoreRequest();
        subscribeToIoTCoreRequest.setTopicName(topic);
        subscribeToIoTCoreRequest.setQos(qos);
        return greengrassCoreIPCClient.subscribeToIoTCore(subscribeToIoTCoreRequest,
                Optional.of(streamResponseHandler));
    }

    public static class SubscriptionResponseHandler implements StreamResponseHandler<IoTCoreMessage> {

        @Override
        public void onStreamEvent(IoTCoreMessage ioTCoreMessage) {
            try {
                String topic = ioTCoreMessage.getMessage().getTopicName();
                String message = new String(ioTCoreMessage.getMessage().getPayload(),
                        StandardCharsets.UTF_8);
                System.out.printf("Received new message on topic %s: %s%n", topic, message);
            } catch (Exception e) {
                System.err.println("Exception occurred while processing subscription response " +
                        "message.");
                e.printStackTrace();
            }
        }

        @Override
        public boolean onStreamError(Throwable error) {
            System.err.println("Received a stream error.");
            error.printStackTrace();
            return false;
        }

        @Override
        public void onStreamClosed() {
            System.out.println("Subscribe to IoT Core stream closed.");
        }
    }
}
```

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

**Example Ejemplo: suscribirse a los mensajes**  
En este ejemplo se supone que está utilizando la versión 1.5.4 o posterior de SDK para dispositivos con AWS IoT para Python v2. 

```
import time
import traceback

import awsiot.greengrasscoreipc
import awsiot.greengrasscoreipc.client as client
from awsiot.greengrasscoreipc.model import (
    IoTCoreMessage,
    QOS,
    SubscribeToIoTCoreRequest
)

TIMEOUT = 10

ipc_client = awsiot.greengrasscoreipc.connect()

class StreamHandler(client.SubscribeToIoTCoreStreamHandler):
    def __init__(self):
        super().__init__()

    def on_stream_event(self, event: IoTCoreMessage) -> None:
        try:
            message = str(event.message.payload, "utf-8")
            topic_name = event.message.topic_name
            # Handle message.
        except:
            traceback.print_exc()

    def on_stream_error(self, error: Exception) -> bool:
        # Handle error.
        return True  # Return True to close stream, False to keep stream open.

    def on_stream_closed(self) -> None:
        # Handle close.
        pass


topic = "my/topic"
qos = QOS.AT_MOST_ONCE

request = SubscribeToIoTCoreRequest()
request.topic_name = topic
request.qos = qos
handler = StreamHandler()
operation = ipc_client.new_subscribe_to_iot_core(handler)
operation.activate(request)
future_response = operation.get_response() 
future_response.result(TIMEOUT)

# Keep the main thread alive, or the process will exit.
while True:
    time.sleep(10)
                  
# To stop subscribing, close the operation stream.
operation.close()
```

------
#### [ C\$1\$1 (IPC client V1) ]

**Example Ejemplo: suscribirse a los mensajes**  

```
#include <iostream>

#include <aws/crt/Api.h>
#include <aws/greengrass/GreengrassCoreIpcClient.h>

using namespace Aws::Crt;
using namespace Aws::Greengrass;

class IoTCoreResponseHandler : public SubscribeToIoTCoreStreamHandler {

    public:
        virtual ~IoTCoreResponseHandler() {}

    private:
        void OnStreamEvent(IoTCoreMessage *response) override {
            auto message = response->GetMessage();
            if (message.has_value() && message.value().GetPayload().has_value()) {
                auto messageBytes = message.value().GetPayload().value();
                std::string messageString(messageBytes.begin(), messageBytes.end());
                std::string topicName = message.value().GetTopicName().value().c_str();
                // Handle message.
            }
        }

        bool OnStreamError(OperationError *error) override {
            // Handle error.
            return false; // Return true to close stream, false to keep stream open.
        }

        void OnStreamClosed() override {
            // Handle close.
        }
};

class IpcClientLifecycleHandler : public ConnectionLifecycleHandler {
    void OnConnectCallback() override {
        // Handle connection to IPC service.
    }

    void OnDisconnectCallback(RpcError error) override {
        // Handle disconnection from IPC service.
    }

    bool OnErrorCallback(RpcError error) override {
        // Handle IPC service connection error.
        return true;
    }
};

int main() {
    ApiHandle apiHandle(g_allocator);
    Io::EventLoopGroup eventLoopGroup(1);
    Io::DefaultHostResolver socketResolver(eventLoopGroup, 64, 30);
    Io::ClientBootstrap bootstrap(eventLoopGroup, socketResolver);
    IpcClientLifecycleHandler ipcLifecycleHandler;
    GreengrassCoreIpcClient ipcClient(bootstrap);
    auto connectionStatus = ipcClient.Connect(ipcLifecycleHandler).get();
    if (!connectionStatus) {
        std::cerr << "Failed to establish IPC connection: " << connectionStatus.StatusToString() << std::endl;
        exit(-1);
    }

    String topic("my/topic");
    QOS qos = QOS_AT_MOST_ONCE;
    int timeout = 10;

    SubscribeToIoTCoreRequest request;
    request.SetTopicName(topic);
    request.SetQos(qos);
    auto streamHandler = MakeShared<IoTCoreResponseHandler>(DefaultAllocator());
    auto operation = ipcClient.NewSubscribeToIoTCore(streamHandler);
    auto activate = operation->Activate(request, nullptr);
    activate.wait();

    auto responseFuture = operation->GetResult();
    if (responseFuture.wait_for(std::chrono::seconds(timeout)) == std::future_status::timeout) {
        std::cerr << "Operation timed out while waiting for response from Greengrass Core." << std::endl;
        exit(-1);
    }

    auto response = responseFuture.get();
    if (!response) {
        // Handle error.
        auto errorType = response.GetResultType();
        if (errorType == OPERATION_ERROR) {
            auto *error = response.GetOperationError();
            (void)error;
            // Handle operation error.
        } else {
            // Handle RPC error.
        }
        exit(-1);
    }

    // Keep the main thread alive, or the process will exit.
    while (true) {
        std::this_thread::sleep_for(std::chrono::seconds(10));
    }

    operation->Close();
    return 0;
}
```

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

**Example Ejemplo: suscribirse a los mensajes**  

```
import * as greengrasscoreipc from "aws-iot-device-sdk-v2/dist/greengrasscoreipc";
import {IoTCoreMessage, QOS, SubscribeToIoTCoreRequest} from "aws-iot-device-sdk-v2/dist/greengrasscoreipc/model";
import {RpcError} from "aws-iot-device-sdk-v2/dist/eventstream_rpc";
 
class SubscribeToIoTCore {
    private ipcClient: greengrasscoreipc.Client
    private readonly topic: string;
 
    constructor() {
        // define your own constructor, e.g.
        this.topic = "<define_your_topic>";
        this.subscribeToIoTCore().then(r => console.log("Started workflow"));
    }
 
    private async subscribeToIoTCore() {
        try {
            const request: SubscribeToIoTCoreRequest = {
                topicName: this.topic,
                qos: QOS.AT_LEAST_ONCE, // you can change this depending on your use case
            }
 
            this.ipcClient = await getIpcClient();
 
            const streamingOperation = this.ipcClient.subscribeToIoTCore(request);
 
            streamingOperation.on('message', (message: IoTCoreMessage) => {
                // parse the message depending on your use cases, e.g.
                if (message.message && message.message.payload) {
                    const receivedMessage = message.message.payload.toString();
                }
            });
 
            streamingOperation.on('streamError', (error : RpcError) => {
                // define your own error handling logic
            });
 
            streamingOperation.on('ended', () => {
                // define your own logic
            });
 
            await streamingOperation.activate();
 
            // Keep the main thread alive, or the process will exit.
            await new Promise((resolve) => setTimeout(resolve, 10000))
        } catch (e) {
            // parse the error depending on your use cases
            throw e
        }
    }
}
 
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
    }
}
 
// starting point
const subscribeToIoTCore = new SubscribeToIoTCore();
```

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

**Example Ejemplo: suscribirse a los mensajes**  

```
use gg_sdk::{Qos, Sdk};
use std::{thread, time::Duration};

fn main() {
    let sdk = Sdk::init();
    sdk.connect().expect("Failed to establish IPC connection");

    let topic = "my/topic";
    let qos = Qos::AtLeastOnce;

    let callback = |topic: &str, payload: &[u8]| {
        let message = String::from_utf8_lossy(payload);
        println!("Received new message on topic {topic}: {message}");
    };

    let _sub = sdk
        .subscribe_to_iot_core(topic, qos, &callback)
        .expect("Failed to subscribe to topic");

    println!("Successfully subscribed to topic: {topic}");

    // Keep the main thread alive, or the process will exit.
    loop {
        thread::sleep(Duration::from_secs(10));
    }
}
```

------
#### [ C ]

**Example Ejemplo: suscribirse a los mensajes**  

```
#include <gg/error.h>
#include <gg/ipc/client.h>
#include <gg/sdk.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

static void on_subscription_response(
    void *ctx, GgBuffer topic, GgBuffer payload, GgIpcSubscriptionHandle handle
) {
    (void) ctx;
    (void) handle;

    printf(
        "Received new message on topic %.*s: %.*s\n",
        (int) topic.len,
        topic.data,
        (int) payload.len,
        payload.data
    );
}

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);
    }

    GgBuffer topic = GG_STR("my/topic");
    uint8_t qos = 1;

    GgIpcSubscriptionHandle handle;
    err = ggipc_subscribe_to_iot_core(
        topic, qos, on_subscription_response, NULL, &handle
    );
    if (err != GG_ERR_OK) {
        fprintf(
            stderr,
            "Failed to subscribe to topic: %.*s\n",
            (int) topic.len,
            topic.data
        );
        exit(-1);
    }

    printf(
        "Successfully subscribed to topic: %.*s\n", (int) topic.len, topic.data
    );

    // Keep the main thread alive, or the process will exit.
    while (1) {
        sleep(10);
    }

    // To stop subscribing, close the subscription handle.
    ggipc_close_subscription(handle);
}
```

------
#### [ C\$1\$1 (Component SDK) ]

**Example Ejemplo: suscribirse a los mensajes**  

```
#include <gg/ipc/client.hpp>
#include <unistd.h>
#include <iostream>

class ResponseHandler : public gg::ipc::IotTopicCallback {
    void operator()(
        std::string_view topic,
        gg::Buffer payload,
        gg::ipc::Subscription &handle
    ) override {
        (void) handle;
        std::cout << "Received new message on topic " << topic << ": "
                  << payload << "\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);
    }

    std::string_view topic = "my/topic";
    uint8_t qos = 1;

    static ResponseHandler handler;
    error = client.subscribe_to_iot_core(topic, qos, handler);
    if (error) {
        std::cerr << "Failed to subscribe to topic: " << topic << "\n";
        exit(-1);
    }

    std::cout << "Successfully subscribed to topic: " << topic << "\n";

    // Keep the main thread alive, or the process will exit.
    while (1) {
        sleep(10);
    }
}
```

------

## Ejemplos
<a name="ipc-iot-core-mqtt-examples"></a>

Utilice los siguientes ejemplos para aprender a utilizar el servicio IPC de AWS IoT Core MQTT en sus componentes.

### Ejemplo de editor AWS IoT Core MQTT (C\$1\$1, cliente IPC V1)
<a name="ipc-iot-core-mqtt-example-publisher-cpp"></a>

La siguiente receta de ejemplo permite que el componente publique en todos los temas.

------
#### [ JSON ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.IoTCorePublisherCpp",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that publishes MQTT messages to IoT Core.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.mqttproxy": {
          "com.example.IoTCorePublisherCpp:mqttproxy:1": {
            "policyDescription": "Allows access to publish to all topics.",
            "operations": [
              "aws.greengrass#PublishToIoTCore"
            ],
            "resources": [
              "*"
            ]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Lifecycle": {
        "Run": "{artifacts:path}/greengrassv2_iotcore_publisher"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.IoTCorePublisherCpp/1.0.0/greengrassv2_iotcore_publisher",
          "Permission": {
            "Execute": "OWNER"
          }
        }
      ]
    }
  ]
}
```

------
#### [ YAML ]

```
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.IoTCorePublisherCpp
ComponentVersion: 1.0.0
ComponentDescription: A component that publishes MQTT messages to IoT Core.
ComponentPublisher: Amazon
ComponentConfiguration:
  DefaultConfiguration:
    accessControl:
      aws.greengrass.ipc.mqttproxy:
        com.example.IoTCorePublisherCpp:mqttproxy:1:
          policyDescription: Allows access to publish to all topics.
          operations:
            - aws.greengrass#PublishToIoTCore
          resources:
            - "*"
Manifests:
  - Lifecycle:
      Run: "{artifacts:path}/greengrassv2_iotcore_publisher"
    Artifacts:
      - URI: s3://amzn-s3-demo-bucket/artifacts/com.example.IoTCorePublisherCpp/1.0.0/greengrassv2_iotcore_publisher
        Permission:
          Execute: OWNER
```

------

El siguiente ejemplo de aplicación de C\$1\$1 demuestra cómo utilizar el servicio IPC de AWS IoT Core MQTT para publicar mensajes en. AWS IoT Core

```
#include <iostream>

#include <aws/crt/Api.h>
#include <aws/greengrass/GreengrassCoreIpcClient.h>

using namespace Aws::Crt;
using namespace Aws::Greengrass;

class IpcClientLifecycleHandler : public ConnectionLifecycleHandler {
    void OnConnectCallback() override {
        std::cout << "OnConnectCallback" << std::endl;
    }

    void OnDisconnectCallback(RpcError error) override {
        std::cout << "OnDisconnectCallback: " << error.StatusToString() << std::endl;
        exit(-1);
    }

    bool OnErrorCallback(RpcError error) override {
        std::cout << "OnErrorCallback: " << error.StatusToString() << std::endl;
        return true;
    }
};

int main() {
    String message("Hello from the Greengrass IPC MQTT publisher (C++).");
    String topic("test/topic/cpp");
    QOS qos = QOS_AT_LEAST_ONCE;
    int timeout = 10;

    ApiHandle apiHandle(g_allocator);
    Io::EventLoopGroup eventLoopGroup(1);
    Io::DefaultHostResolver socketResolver(eventLoopGroup, 64, 30);
    Io::ClientBootstrap bootstrap(eventLoopGroup, socketResolver);
    IpcClientLifecycleHandler ipcLifecycleHandler;
    GreengrassCoreIpcClient ipcClient(bootstrap);
    auto connectionStatus = ipcClient.Connect(ipcLifecycleHandler).get();
    if (!connectionStatus) {
        std::cerr << "Failed to establish IPC connection: " << connectionStatus.StatusToString() << std::endl;
        exit(-1);
    }

    while (true) {
        PublishToIoTCoreRequest request;
        Vector<uint8_t> messageData({message.begin(), message.end()});
        request.SetTopicName(topic);
        request.SetPayload(messageData);
        request.SetQos(qos);

        auto operation = ipcClient.NewPublishToIoTCore();
        auto activate = operation->Activate(request, nullptr);
        activate.wait();

        auto responseFuture = operation->GetResult();
        if (responseFuture.wait_for(std::chrono::seconds(timeout)) == std::future_status::timeout) {
            std::cerr << "Operation timed out while waiting for response from Greengrass Core." << std::endl;
            exit(-1);
        }

        auto response = responseFuture.get();
        if (response) {
            std::cout << "Successfully published to topic: " << topic << std::endl;
        } else {
            // An error occurred.
            std::cout << "Failed to publish to topic: " << topic << std::endl;
            auto errorType = response.GetResultType();
            if (errorType == OPERATION_ERROR) {
                auto *error = response.GetOperationError();
                std::cout << "Operation error: " << error->GetMessage().value() << std::endl;
            } else {
                std::cout << "RPC error: " << response.GetRpcError() << std::endl;
            }
            exit(-1);
        }

        std::this_thread::sleep_for(std::chrono::seconds(5));
    }

    return 0;
}
```

### Ejemplo de suscriptor AWS IoT Core MQTT (C\$1\$1, cliente IPC V1)
<a name="ipc-iot-core-mqtt-example-subscriber-cpp"></a>

La siguiente receta de ejemplo permite que el componente se suscriba a todos los temas.

------
#### [ JSON ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.IoTCoreSubscriberCpp",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that subscribes to MQTT messages from IoT Core.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.mqttproxy": {
          "com.example.IoTCoreSubscriberCpp:mqttproxy:1": {
            "policyDescription": "Allows access to subscribe to all topics.",
            "operations": [
              "aws.greengrass#SubscribeToIoTCore"
            ],
            "resources": [
              "*"
            ]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Lifecycle": {
        "Run": "{artifacts:path}/greengrassv2_iotcore_subscriber"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.IoTCoreSubscriberCpp/1.0.0/greengrassv2_iotcore_subscriber",
          "Permission": {
            "Execute": "OWNER"
          }
        }
      ]
    }
  ]
}
```

------
#### [ YAML ]

```
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.IoTCoreSubscriberCpp
ComponentVersion: 1.0.0
ComponentDescription: A component that subscribes to MQTT messages from IoT Core.
ComponentPublisher: Amazon
ComponentConfiguration:
  DefaultConfiguration:
    accessControl:
      aws.greengrass.ipc.mqttproxy:
        com.example.IoTCoreSubscriberCpp:mqttproxy:1:
          policyDescription: Allows access to subscribe to all topics.
          operations:
            - aws.greengrass#SubscribeToIoTCore
          resources:
            - "*"
Manifests:
  - Lifecycle:
      Run: "{artifacts:path}/greengrassv2_iotcore_subscriber"
    Artifacts:
      - URI: s3://amzn-s3-demo-bucket/artifacts/com.example.IoTCoreSubscriberCpp/1.0.0/greengrassv2_iotcore_subscriber
        Permission:
          Execute: OWNER
```

------

El siguiente ejemplo de aplicación de C\$1\$1 demuestra cómo utilizar el servicio IPC de AWS IoT Core MQTT para suscribirse a los mensajes de. AWS IoT Core

```
#include <iostream>

#include <aws/crt/Api.h>
#include <aws/greengrass/GreengrassCoreIpcClient.h>

using namespace Aws::Crt;
using namespace Aws::Greengrass;

class IoTCoreResponseHandler : public SubscribeToIoTCoreStreamHandler {

    public:
        virtual ~IoTCoreResponseHandler() {}

    private:

        void OnStreamEvent(IoTCoreMessage *response) override {
            auto message = response->GetMessage();
            if (message.has_value() && message.value().GetPayload().has_value()) {
                auto messageBytes = message.value().GetPayload().value();
                std::string messageString(messageBytes.begin(), messageBytes.end());
                std::string messageTopic = message.value().GetTopicName().value().c_str();
                std::cout << "Received new message on topic: " << messageTopic << std::endl;
                std::cout << "Message: " << messageString << std::endl;
            }
        }

        bool OnStreamError(OperationError *error) override {
            std::cout << "Received an operation error: ";
            if (error->GetMessage().has_value()) {
                std::cout << error->GetMessage().value();
            }
            std::cout << std::endl;
            return false; // Return true to close stream, false to keep stream open.
        }

        void OnStreamClosed() override {
            std::cout << "Subscribe to IoT Core stream closed." << std::endl;
        }
};

class IpcClientLifecycleHandler : public ConnectionLifecycleHandler {
    void OnConnectCallback() override {
        std::cout << "OnConnectCallback" << std::endl;
    }

    void OnDisconnectCallback(RpcError error) override {
        std::cout << "OnDisconnectCallback: " << error.StatusToString() << std::endl;
        exit(-1);
    }

    bool OnErrorCallback(RpcError error) override {
        std::cout << "OnErrorCallback: " << error.StatusToString() << std::endl;
        return true;
    }
};

int main() {
    String topic("test/topic/cpp");
    QOS qos = QOS_AT_LEAST_ONCE;
    int timeout = 10;

    ApiHandle apiHandle(g_allocator);
    Io::EventLoopGroup eventLoopGroup(1);
    Io::DefaultHostResolver socketResolver(eventLoopGroup, 64, 30);
    Io::ClientBootstrap bootstrap(eventLoopGroup, socketResolver);
    IpcClientLifecycleHandler ipcLifecycleHandler;
    GreengrassCoreIpcClient ipcClient(bootstrap);
    auto connectionStatus = ipcClient.Connect(ipcLifecycleHandler).get();
    if (!connectionStatus) {
        std::cerr << "Failed to establish IPC connection: " << connectionStatus.StatusToString() << std::endl;
        exit(-1);
    }

    SubscribeToIoTCoreRequest request;
    request.SetTopicName(topic);
    request.SetQos(qos);
    auto streamHandler = MakeShared<IoTCoreResponseHandler>(DefaultAllocator());
    auto operation = ipcClient.NewSubscribeToIoTCore(streamHandler);
    auto activate = operation->Activate(request, nullptr);
    activate.wait();

    auto responseFuture = operation->GetResult();
    if (responseFuture.wait_for(std::chrono::seconds(timeout)) == std::future_status::timeout) {
        std::cerr << "Operation timed out while waiting for response from Greengrass Core." << std::endl;
        exit(-1);
    }

    auto response = responseFuture.get();
    if (response) {
        std::cout << "Successfully subscribed to topic: " << topic << std::endl;
    } else {
        // An error occurred.
        std::cout << "Failed to subscribe to topic: " << topic << std::endl;
        auto errorType = response.GetResultType();
        if (errorType == OPERATION_ERROR) {
            auto *error = response.GetOperationError();
            std::cout << "Operation error: " << error->GetMessage().value() << std::endl;
        } else {
            std::cout << "RPC error: " << response.GetRpcError() << std::endl;
        }
        exit(-1);
    }

    // Keep the main thread alive, or the process will exit.
    while (true) {
        std::this_thread::sleep_for(std::chrono::seconds(10));
    }

    operation->Close();
    return 0;
}
```

### Ejemplo de editor AWS IoT Core MQTT (Rust)
<a name="ipc-iot-core-mqtt-example-publisher-rust"></a>

La siguiente receta de ejemplo permite que el componente publique en todos los temas.

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.IoTCorePublisherRust",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that publishes MQTT messages to IoT Core.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.mqttproxy": {
          "com.example.IoTCorePublisherRust:mqttproxy:1": {
            "policyDescription": "Allows access to publish to all topics.",
            "operations": ["aws.greengrass#PublishToIoTCore"],
            "resources": ["*"]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "{artifacts:path}/publish_to_iot_core"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.IoTCorePublisherRust/1.0.0/publish_to_iot_core",
          "Permission": {
            "Execute": "OWNER"
          }
        }
      ]
    }
  ]
}
```

El siguiente ejemplo de aplicación Rust demuestra cómo utilizar el servicio IPC de AWS IoT Core MQTT para publicar mensajes en. AWS IoT Core

```
use gg_sdk::{Qos, Sdk};

fn main() {
    let sdk = Sdk::init();
    sdk.connect().expect("Failed to establish IPC connection");

    let message = b"Hello, World";
    let topic = "my/topic";
    let qos = Qos::AtLeastOnce;

    sdk.publish_to_iot_core(topic, message, qos)
        .expect("Failed to publish to topic");

    println!("Successfully published to topic: {topic}");
}
```

### Ejemplo de suscriptor de AWS IoT Core MQTT (Rust)
<a name="ipc-iot-core-mqtt-example-subscriber-rust"></a>

La siguiente receta de ejemplo permite que el componente se suscriba a todos los temas.

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.IoTCoreSubscriberRust",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that subscribes to MQTT messages from IoT Core.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.mqttproxy": {
          "com.example.IoTCoreSubscriberRust:mqttproxy:1": {
            "policyDescription": "Allows access to subscribe to all topics.",
            "operations": ["aws.greengrass#SubscribeToIoTCore"],
            "resources": ["*"]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "{artifacts:path}/subscribe_to_iot_core"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.IoTCoreSubscriberRust/1.0.0/subscribe_to_iot_core",
          "Permission": {
            "Execute": "OWNER"
          }
        }
      ]
    }
  ]
}
```

El siguiente ejemplo de aplicación Rust demuestra cómo utilizar el servicio IPC de AWS IoT Core MQTT para suscribirse a los mensajes de. AWS IoT Core

```
use gg_sdk::{Qos, Sdk};
use std::{thread, time::Duration};

fn main() {
    let sdk = Sdk::init();
    sdk.connect().expect("Failed to establish IPC connection");

    let topic = "my/topic";
    let qos = Qos::AtLeastOnce;

    let callback = |topic: &str, payload: &[u8]| {
        let message = String::from_utf8_lossy(payload);
        println!("Received new message on topic {topic}: {message}");
    };

    let _sub = sdk
        .subscribe_to_iot_core(topic, qos, &callback)
        .expect("Failed to subscribe to topic");

    println!("Successfully subscribed to topic: {topic}");

    // Keep the main thread alive, or the process will exit.
    loop {
        thread::sleep(Duration::from_secs(10));
    }
}
```

### Ejemplo de editor AWS IoT Core MQTT (C)
<a name="ipc-iot-core-mqtt-example-publisher-c"></a>

La siguiente receta de ejemplo permite que el componente publique en todos los temas.

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.IoTCorePublisherC",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that publishes MQTT messages to IoT Core.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.mqttproxy": {
          "com.example.IoTCorePublisherC:mqttproxy:1": {
            "policyDescription": "Allows access to publish to all topics.",
            "operations": ["aws.greengrass#PublishToIoTCore"],
            "resources": ["*"]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "{artifacts:path}/sample_publish_to_iot_core"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.IoTCorePublisherC/1.0.0/sample_publish_to_iot_core",
          "Permission": {
            "Execute": "OWNER"
          }
        }
      ]
    }
  ]
}
```

El siguiente ejemplo de aplicación en C muestra cómo utilizar el servicio IPC de AWS IoT Core MQTT para publicar mensajes en. AWS IoT Core

```
#include <gg/error.h>
#include <gg/ipc/client.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);
    }

    GgBuffer message = GG_STR("Hello, World");
    GgBuffer topic = GG_STR("my/topic");
    uint8_t qos = 1;

    err = ggipc_publish_to_iot_core(topic, message, qos);
    if (err != GG_ERR_OK) {
        fprintf(
            stderr,
            "Failed to publish to topic: %.*s\n",
            (int) topic.len,
            topic.data
        );
        exit(-1);
    }

    printf(
        "Successfully published to topic: %.*s\n", (int) topic.len, topic.data
    );
}
```

### Ejemplo de suscriptor AWS IoT Core MQTT (C)
<a name="ipc-iot-core-mqtt-example-subscriber-c"></a>

La siguiente receta de ejemplo permite que el componente se suscriba a todos los temas.

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.IoTCoreSubscriberC",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that subscribes to MQTT messages from IoT Core.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.mqttproxy": {
          "com.example.IoTCoreSubscriberC:mqttproxy:1": {
            "policyDescription": "Allows access to subscribe to all topics.",
            "operations": ["aws.greengrass#SubscribeToIoTCore"],
            "resources": ["*"]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "{artifacts:path}/sample_subscribe_to_iot_core"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.IoTCoreSubscriberC/1.0.0/sample_subscribe_to_iot_core",
          "Permission": {
            "Execute": "OWNER"
          }
        }
      ]
    }
  ]
}
```

El siguiente ejemplo de aplicación en C muestra cómo utilizar el servicio IPC de AWS IoT Core MQTT para suscribirse a los mensajes de. AWS IoT Core

```
#include <gg/error.h>
#include <gg/ipc/client.h>
#include <gg/sdk.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

static void on_subscription_response(
    void *ctx, GgBuffer topic, GgBuffer payload, GgIpcSubscriptionHandle handle
) {
    (void) ctx;
    (void) handle;

    printf(
        "Received new message on topic %.*s: %.*s\n",
        (int) topic.len,
        topic.data,
        (int) payload.len,
        payload.data
    );
}

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);
    }

    GgBuffer topic = GG_STR("my/topic");
    uint8_t qos = 1;

    GgIpcSubscriptionHandle handle;
    err = ggipc_subscribe_to_iot_core(
        topic, qos, on_subscription_response, NULL, &handle
    );
    if (err != GG_ERR_OK) {
        fprintf(
            stderr,
            "Failed to subscribe to topic: %.*s\n",
            (int) topic.len,
            topic.data
        );
        exit(-1);
    }

    printf(
        "Successfully subscribed to topic: %.*s\n", (int) topic.len, topic.data
    );

    // Keep the main thread alive, or the process will exit.
    while (1) {
        sleep(10);
    }

    // To stop subscribing, close the subscription handle.
    ggipc_close_subscription(handle);
}
```

### Ejemplo de editor AWS IoT Core MQTT (C\$1\$1, SDK de componentes)
<a name="ipc-iot-core-mqtt-example-publisher-cpp-component-sdk"></a>

La siguiente receta de ejemplo permite que el componente publique en todos los temas.

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.IoTCorePublisherCpp",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that publishes MQTT messages to IoT Core.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.mqttproxy": {
          "com.example.IoTCorePublisherCpp:mqttproxy:1": {
            "policyDescription": "Allows access to publish to all topics.",
            "operations": ["aws.greengrass#PublishToIoTCore"],
            "resources": ["*"]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "{artifacts:path}/sample_cpp_publish_to_iot_core"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.IoTCorePublisherCpp/1.0.0/sample_cpp_publish_to_iot_core",
          "Permission": {
            "Execute": "OWNER"
          }
        }
      ]
    }
  ]
}
```

El siguiente ejemplo de aplicación de C\$1\$1 demuestra cómo utilizar el servicio AWS IoT Core MQTT IPC para publicar mensajes en. AWS IoT Core

```
#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);
    }

    std::string_view message = "Hello, World";
    std::string_view topic = "my/topic";
    uint8_t qos = 1;

    error = client.publish_to_iot_core(topic, message, qos);
    if (error) {
        std::cerr << "Failed to publish to topic: " << topic << "\n";
        exit(-1);
    }

    std::cout << "Successfully published to topic: " << topic << "\n";
}
```

### Ejemplo de suscriptor de AWS IoT Core MQTT (C\$1\$1, SDK de componentes)
<a name="ipc-iot-core-mqtt-example-subscriber-cpp-component-sdk"></a>

La siguiente receta de ejemplo permite que el componente se suscriba a todos los temas.

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.IoTCoreSubscriberCpp",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that subscribes to MQTT messages from IoT Core.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.mqttproxy": {
          "com.example.IoTCoreSubscriberCpp:mqttproxy:1": {
            "policyDescription": "Allows access to subscribe to all topics.",
            "operations": ["aws.greengrass#SubscribeToIoTCore"],
            "resources": ["*"]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "{artifacts:path}/sample_cpp_subscribe_to_iot_core"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.IoTCoreSubscriberCpp/1.0.0/sample_cpp_subscribe_to_iot_core",
          "Permission": {
            "Execute": "OWNER"
          }
        }
      ]
    }
  ]
}
```

El siguiente ejemplo de aplicación de C\$1\$1 demuestra cómo utilizar el servicio AWS IoT Core MQTT IPC para suscribirse a los mensajes de. AWS IoT Core

```
#include <gg/ipc/client.hpp>
#include <unistd.h>
#include <iostream>

class ResponseHandler : public gg::ipc::IotTopicCallback {
    void operator()(
        std::string_view topic,
        gg::Buffer payload,
        gg::ipc::Subscription &handle
    ) override {
        (void) handle;
        std::cout << "Received new message on topic " << topic << ": "
                  << payload << "\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);
    }

    std::string_view topic = "my/topic";
    uint8_t qos = 1;

    static ResponseHandler handler;
    error = client.subscribe_to_iot_core(topic, qos, handler);
    if (error) {
        std::cerr << "Failed to subscribe to topic: " << topic << "\n";
        exit(-1);
    }

    std::cout << "Successfully subscribed to topic: " << topic << "\n";

    // Keep the main thread alive, or the process will exit.
    while (1) {
        sleep(10);
    }
}
```

# Interacción con el ciclo de vida del componente
<a name="ipc-component-lifecycle"></a>

Utilice el servicio IPC del ciclo de vida de los componentes para:
+ Actualizar el estado del componente en el dispositivo principal.
+ Suscribirse a las actualizaciones del estado de los componentes.
+ Evitar que el núcleo detenga el componente para aplicar una actualización durante una implementación.
+ Pausar y reanudar los procesos de los componentes.

**Topics**
+ [Versiones mínimas de SDK](#ipc-component-lifecycle-sdk-versions)
+ [Autorización](#ipc-component-lifecycle-authorization)
+ [UpdateState](#ipc-operation-updatestate)
+ [SubscribeToComponentUpdates](#ipc-operation-subscribetocomponentupdates)
+ [DeferComponentUpdate](#ipc-operation-defercomponentupdate)
+ [PauseComponent](#ipc-operation-pausecomponent)
+ [ResumeComponent](#ipc-operation-resumecomponent)

## Versiones mínimas de SDK
<a name="ipc-component-lifecycle-sdk-versions"></a>

En la siguiente tabla se enumeran las versiones mínimas de las SDK para dispositivos con AWS IoT que debe utilizar para interactuar con el ciclo de vida de los componentes.


| SDK | Versión mínima | 
| --- | --- | 
|  [SDK para dispositivos con AWS IoT para Java v2](https://github.com/aws/aws-iot-device-sdk-java-v2)  |  Versión 1.2.10  | 
|  [SDK para dispositivos con AWS IoT para Python v2](https://github.com/aws/aws-iot-device-sdk-python-v2)  |  Versión 1.5.3  | 
|  [SDK para dispositivos con AWS IoT para C\$1\$1 v2](https://github.com/aws/aws-iot-device-sdk-cpp-v2)  |  Versión 1.17.0  | 
|  [SDK para dispositivos con AWS IoT para JavaScript v2](https://github.com/aws/aws-iot-device-sdk-js-v2)  |  Versión 1.12.0  | 

## Autorización
<a name="ipc-component-lifecycle-authorization"></a>

Para pausar o reanudar otros componentes de un componente personalizado, debe definir políticas de autorización que permitan a su componente administrar otros componentes. Para obtener información sobre cómo definir las políticas de autorización, consulte [Autorización de los componentes para realizar operaciones de IPC](interprocess-communication.md#ipc-authorization-policies).

Las políticas de autorización para la administración del ciclo de vida de los componentes tienen las siguientes propiedades.

**Identificador de servicio IPC:** `aws.greengrass.ipc.lifecycle`


| Operación | Description (Descripción) | Recursos | 
| --- | --- | --- | 
|  `aws.greengrass#PauseComponent`  |  Permite que un componente detenga los componentes que especifique.  |  Un nombre de componente o `*` para permitir el acceso a todos los componentes.  | 
|  `aws.greengrass#ResumeComponent`  |  Permite que un componente reanude los componentes que especifique.  |  Un nombre de componente o `*` para permitir el acceso a todos los componentes.  | 
|  `*`  |  Permite que un componente pause y reanude los componentes que especifique.  |  Un nombre de componente o `*` para permitir el acceso a todos los componentes.  | 

### Ejemplos de políticas de autorización
<a name="ipc-component-lifecycle-authorization-policy-examples"></a>

Puede consultar el siguiente ejemplo de política de autorización con el fin de configurar las políticas de autorización para sus componentes.

**Example Ejemplo de política de autorización**  
El siguiente ejemplo de política de autorización permite a un componente pausar y reanudar todos los componentes.  

```
{
  "accessControl": {
    "aws.greengrass.ipc.lifecycle": {
      "com.example.MyLocalLifecycleComponent:lifecycle:1": {
        "policyDescription": "Allows access to pause/resume all components.",
        "operations": [
          "aws.greengrass#PauseComponent",
          "aws.greengrass#ResumeComponent"
        ],
        "resources": [
          "*"
        ]
      }
    }
  }
}
```

## UpdateState
<a name="ipc-operation-updatestate"></a>

Actualice el estado del componente en el dispositivo principal.

### Solicitud
<a name="ipc-operation-updatestate-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`state`  
El estado que se va a establecer. Esta enumeración, `LifecycleState`, tiene los siguientes valores:  
+ `RUNNING`
+ `ERRORED`

### Respuesta
<a name="ipc-operation-updatestate-response"></a>

Esta operación no proporciona ninguna información en su respuesta.

### Ejemplos
<a name="ipc-operation-updatestate-examples"></a>

En los ejemplos siguientes, se muestra cómo llamar a esta operación en código de componente personalizado.

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

**Example Ejemplo: estado de actualización**  

```
use gg_sdk::{ComponentState, Sdk};

fn main() {
    let sdk = Sdk::init();
    sdk.connect().expect("Failed to establish IPC connection");

    // Update component state to RUNNING
    sdk.update_state(ComponentState::Running)
        .expect("Failed to update component state");

    println!("Successfully updated component state to RUNNING.");
}
```

------
#### [ C ]

**Example Ejemplo: estado de actualización**  

```
#include <gg/error.h>
#include <gg/ipc/client.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 component state to RUNNING
    err = ggipc_update_state(GG_COMPONENT_STATE_RUNNING);
    if (err != GG_ERR_OK) {
        fprintf(stderr, "Failed to update component state.\n");
        exit(-1);
    }

    printf("Successfully updated component state to RUNNING.\n");
}
```

------
#### [ C\$1\$1 (Component SDK) ]

**Example Ejemplo: estado de actualización**  

```
#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 component state to RUNNING
    error = client.update_component_state(GG_COMPONENT_STATE_RUNNING);
    if (error) {
        std::cerr << "Failed to update component state.\n";
        exit(-1);
    }

    std::cout << "Successfully updated component state to RUNNING.\n";
}
```

------

## SubscribeToComponentUpdates
<a name="ipc-operation-subscribetocomponentupdates"></a>

Suscríbase para recibir notificaciones antes de que el software AWS IoT Greengrass principal actualice un componente. La notificación especifica si el núcleo se reiniciará o no como parte de la actualización.

El núcleo envía notificaciones de actualización solo si la política de actualización de componentes de la implementación especifica que se notifique a los componentes. El comportamiento predeterminado es notificar a los componentes. Para obtener más información, consulte [Crear implementaciones](create-deployments.md) el [DeploymentComponentUpdatePolicy](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_DeploymentComponentUpdatePolicy.html)objeto que puede proporcionar al llamar a la [CreateDeployment](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_CreateDeployment.html)operación.

**importante**  
Las implementaciones locales no notifican a los componentes antes de las actualizaciones.

<a name="ipc-subscribe-operation-note"></a>Esta es una operación de suscripción en la que se suscribe a un flujo de mensajes de eventos. Para usar esta operación, defina un identificador de respuesta de flujo con funciones que gestionen los mensajes de eventos, los errores y el cierre del flujo. Para obtener más información, consulte [Suscripción a los flujos de eventos de IPC](interprocess-communication.md#ipc-subscribe-operations).

**Tipo de mensaje del evento:** `ComponentUpdatePolicyEvents`

**sugerencia**  
Puede seguir un tutorial para aprender a desarrollar un componente que aplace condicionalmente las actualizaciones de los componentes. Para obtener más información, consulte [Tutorial: Desarrollo de un componente de Greengrass que aplace las actualizaciones de los componentes](defer-component-updates-tutorial.md).

### Solicitud
<a name="ipc-operation-subscribetocomponentupdates-request"></a>

Esta solicitud de la operación no tiene parámetros.

### Respuesta
<a name="ipc-operation-subscribetocomponentupdates-response"></a>

Esta respuesta de operación contiene la siguiente información:

`messages`  
El flujo de mensajes de notificación. Este objeto, `ComponentUpdatePolicyEvents`, contiene la siguiente información:    
`preUpdateEvent` (Python: `pre_update_event`)  
(Opcional) Un evento que indica que el núcleo quiere actualizar un componente. Puede responder con la operación [DeferComponentUpdate](#ipc-operation-defercomponentupdate) para confirmar o aplazar la actualización hasta que el componente esté listo para reiniciarse. Este objeto, `PreComponentUpdateEvent`, contiene la siguiente información:    
`deploymentId` (Python: `deployment_id`)  
El ID de la AWS IoT Greengrass implementación que actualiza el componente.  
`isGgcRestarting` (Python: `is_ggc_restarting`)  
Si el núcleo necesita reiniciarse o no después de aplicar la actualización.  
`postUpdateEvent` (Python: `post_update_event`)  
(Opcional) Un evento que indica que el núcleo actualizó un componente. Este objeto, `PostComponentUpdateEvent`, contiene la siguiente información:    
`deploymentId` (Python: `deployment_id`)  
El ID de la AWS IoT Greengrass implementación que actualizó el componente.  
Esta característica requiere la versión 2.7.0 o posterior del componente núcleo de Greengrass.

## DeferComponentUpdate
<a name="ipc-operation-defercomponentupdate"></a>

Confirme o aplace la actualización de un componente que detecte con [SubscribeToComponentUpdates](#ipc-operation-subscribetocomponentupdates). Debe especificar el tiempo que debe transcurrir antes de que el núcleo vuelva a comprobar si el componente está preparado para continuar con la actualización del componente. También puede utilizar esta operación para indicar al núcleo que su componente está listo para la actualización.

Si un componente no responde a la notificación de actualización del componente, el núcleo espera el tiempo que especifique en la política de actualización de componentes de la implementación. Transcurrido ese tiempo de espera, el núcleo continúa con la implementación. El tiempo de espera predeterminado de la actualización del componente es de 60 segundos. Para obtener más información, consulte [Crear implementaciones](create-deployments.md) y el [DeploymentComponentUpdatePolicy](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_DeploymentComponentUpdatePolicy.html)objeto que puede proporcionar al llamar a la [CreateDeployment](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_CreateDeployment.html)operación.

**sugerencia**  
Puede seguir un tutorial para aprender a desarrollar un componente que aplace condicionalmente las actualizaciones de los componentes. Para obtener más información, consulte [Tutorial: Desarrollo de un componente de Greengrass que aplace las actualizaciones de los componentes](defer-component-updates-tutorial.md).

### Solicitud
<a name="ipc-operation-defercomponentupdate-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`deploymentId` (Python: `deployment_id`)  
El identificador del AWS IoT Greengrass despliegue que se va a aplazar.

`message`  
(Opcional) El nombre del componente cuyas actualizaciones se van a aplazar.  
Toma el valor predeterminado del componente que realiza la solicitud.

`recheckAfterMs` (Python: `recheck_after_ms`)  
El tiempo en milisegundos durante el que se debe aplazar la actualización. El núcleo espera esa cantidad de tiempo y luego envía otro `PreComponentUpdateEvent` que puede detectar con [SubscribeToComponentUpdates](#ipc-operation-subscribetocomponentupdates).  
Especifique `0` si desea confirmar la actualización. Esto indica al núcleo que el componente está listo para la actualización.  
El valor predeterminado es cero milisegundos, lo que significa confirmar la actualización.

### Respuesta
<a name="ipc-operation-defercomponentupdate-response"></a>

Esta operación no proporciona ninguna información en su respuesta.

## PauseComponent
<a name="ipc-operation-pausecomponent"></a>

Esta función está disponible para la versión 2.4.0 y versiones posteriores del componente núcleo de [Greengrass](greengrass-nucleus-component.md). AWS IoT Greengrass actualmente no admite esta función en los dispositivos principales de Windows. 

Pausa los procesos de un componente en el dispositivo principal. Para reanudar un componente, utilice la [ResumeComponent](#ipc-operation-resumecomponent)operación.

Solo puede pausar los componentes genéricos. Si intenta pausar cualquier otro tipo de componente, esta operación arroja un `InvalidRequestError`.

**nota**  
Esta operación no puede pausar los procesos contenerizados, como los contenedores de Docker. Para pausar y reanudar un contenedor de Docker, puede usar los comandos [docker pause](https://docs.docker.com/engine/reference/commandline/pause/) y [dockerunpause](https://docs.docker.com/engine/reference/commandline/unpause/).

Esta operación no detiene las dependencias de los componentes ni los componentes que dependen del componente que se pausa. Tenga en cuenta este comportamiento al pausar un componente que es una dependencia de otro componente, ya que el componente dependiente puede tener problemas cuando su dependencia está en pausa.

Al reiniciar o apagar un componente en pausa, por ejemplo, durante una implementación, el núcleo de Greengrass reanuda el componente y ejecuta su ciclo de vida de apagado. Para obtener más información sobre reiniciar un componente, consulte [RestartComponent](ipc-local-deployments-components.md#ipc-operation-restartcomponent).

**importante**  
Para usar esta operación, debe definir una política de autorización que otorgue permiso para usar esta operación. Para obtener más información, consulte [Autorización](#ipc-component-lifecycle-authorization).

### Versiones mínimas de SDK
<a name="ipc-operation-pausecomponent-sdk-versions"></a>

En la siguiente tabla se enumeran las versiones mínimas de las SDK para dispositivos con AWS IoT que debe utilizar para pausar y reanudar los componentes.


| SDK | Versión mínima | 
| --- | --- | 
|  [SDK para dispositivos con AWS IoT para Java v2](https://github.com/aws/aws-iot-device-sdk-java-v2)  |  Versión 1.4.3  | 
|  [SDK para dispositivos con AWS IoT para Python v2](https://github.com/aws/aws-iot-device-sdk-python-v2)  |  Versión 1.6.2  | 
|  [SDK para dispositivos con AWS IoT para C\$1\$1 v2](https://github.com/aws/aws-iot-device-sdk-cpp-v2)  |  Versión 1.13.1  | 
|  [SDK para dispositivos con AWS IoT para JavaScript v2](https://github.com/aws/aws-iot-device-sdk-js-v2)  |  versión 1.12.0  | 

### Solicitud
<a name="ipc-operation-defercomponentupdate-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`componentName` (Python: `component_name`)  
El nombre del componente que se va a pausar, que debe ser un componente genérico. Para obtener más información, consulte [Tipos de componentes](develop-greengrass-components.md#component-types).

### Respuesta
<a name="ipc-operation-defercomponentupdate-response"></a>

Esta operación no proporciona ninguna información en su respuesta.

## ResumeComponent
<a name="ipc-operation-resumecomponent"></a>

Esta función está disponible para la versión 2.4.0 y versiones posteriores del componente núcleo de [Greengrass](greengrass-nucleus-component.md). AWS IoT Greengrass actualmente no admite esta función en los dispositivos principales de Windows. 

Reanuda los procesos de un componente en el dispositivo principal. Para pausar un componente, utilice la [PauseComponent](#ipc-operation-pausecomponent)operación.

Solo puede reanudar los componentes pausados. Si intenta reanudar un componente que no está en pausa, esta operación arroja un `InvalidRequestError`.

**importante**  
Para utilizar esta operación, debe definir una política de autorización que conceda permiso para hacerlo. Para obtener más información, consulte [Autorización](#ipc-component-lifecycle-authorization).

### Versiones mínimas de SDK
<a name="ipc-operation-resumecomponent-sdk-versions"></a>

En la siguiente tabla se enumeran las versiones mínimas de las SDK para dispositivos con AWS IoT que debe utilizar para pausar y reanudar los componentes.


| SDK | Versión mínima | 
| --- | --- | 
|  [SDK para dispositivos con AWS IoT para Java v2](https://github.com/aws/aws-iot-device-sdk-java-v2)  |  Versión 1.4.3  | 
|  [SDK para dispositivos con AWS IoT para Python v2](https://github.com/aws/aws-iot-device-sdk-python-v2)  |  Versión 1.6.2  | 
|  [SDK para dispositivos con AWS IoT para C\$1\$1 v2](https://github.com/aws/aws-iot-device-sdk-cpp-v2)  |  Versión 1.13.1  | 
|  [SDK para dispositivos con AWS IoT para JavaScript v2](https://github.com/aws/aws-iot-device-sdk-js-v2)  |  versión 1.12.0  | 

### Solicitud
<a name="ipc-operation-defercomponentupdate-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`componentName` (Python: `component_name`)  
El nombre del componente a reanudar.

### Respuesta
<a name="ipc-operation-defercomponentupdate-response"></a>

Esta operación no proporciona ninguna información en su respuesta.

# Interacción con la configuración de componentes
<a name="ipc-component-configuration"></a>

El servicio IPC de configuración de componentes le permite hacer lo siguiente:
+ Obtener y establecer los parámetros de configuración de los componentes.
+ Suscribirse a las actualizaciones de configuración de los componentes.
+ Validar las actualizaciones de configuración de los componentes antes de que el núcleo las aplique.

**Topics**
+ [Versiones mínimas de 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)

## Versiones mínimas de SDK
<a name="ipc-component-configuration-sdk-versions"></a>

En la siguiente tabla se enumeran las versiones mínimas de las SDK para dispositivos con AWS IoT que debe utilizar para interactuar con la configuración de los componentes.


| SDK | Versión mínima | 
| --- | --- | 
|  [SDK para dispositivos con AWS IoT para Java v2](https://github.com/aws/aws-iot-device-sdk-java-v2)  |  Versión 1.2.10  | 
|  [SDK para dispositivos con AWS IoT para Python v2](https://github.com/aws/aws-iot-device-sdk-python-v2)  |  Versión 1.5.3  | 
|  [SDK para dispositivos con AWS IoT para C\$1\$1 v2](https://github.com/aws/aws-iot-device-sdk-cpp-v2)  |  Versión 1.17.0  | 
|  [SDK para dispositivos con AWS IoT para JavaScript v2](https://github.com/aws/aws-iot-device-sdk-js-v2)  |  Versión 1.12.0  | 

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

Obtiene un valor de configuración para un componente del dispositivo principal. Usted especifica la ruta clave para la que se va a obtener un valor de configuración.

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

Esta solicitud de operación tiene los siguientes parámetros:

`componentName` (Python: `component_name`)  <a name="ipc-configuration-request-component-name"></a>
(Opcional) El nombre del componente.  
Toma el valor predeterminado del componente que realiza la solicitud.

`keyPath` (Python: `key_path`)  
La ruta clave al valor de configuración. Especifique una lista en la que cada entrada sea la clave de un único nivel del objeto de configuración. Por ejemplo, especifique `["mqtt", "port"]` si desea obtener el valor de `port` en la siguiente configuración.  

```
{
  "mqtt": {
    "port": 443
  }
}
```
Para obtener la configuración completa del componente, especifique una lista vacía.

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

Esta respuesta de operación contiene la siguiente información:

`componentName` (Python: `component_name`)  <a name="ipc-configuration-response-component-name"></a>
El nombre del componente.

`value`  
La configuración solicitada como objeto.

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

En los ejemplos siguientes, se muestra cómo llamar a esta operación en código de componente personalizado.

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

**Example Ejemplo: Obtener configuración**  

```
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 Ejemplo: Obtener la configuración**  

```
#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 Ejemplo: Obtener la configuración**  

```
#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>

Actualiza un valor de configuración para este componente en el dispositivo principal.

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

Esta solicitud de operación tiene los siguientes parámetros:

`keyPath` (Python: `key_path`)  
(Opcional) La ruta clave al nodo del contenedor (el objeto) que se va a actualizar. Especifique una lista en la que cada entrada sea la clave de un único nivel del objeto de configuración. Por ejemplo, especifique la ruta clave `["mqtt"]` y el valor de combinación `{ "port": 443 }` para establecer el valor `port` en la siguiente configuración.  

```
{
  "mqtt": {
    "port": 443
  }
}
```
La ruta clave debe especificar un nodo del contenedor (un objeto) en la configuración. Si el nodo no existe en la configuración del componente, esta operación lo crea y establece su valor en el objeto de `valueToMerge`.  
Toma el valor predeterminado raíz del objeto de configuración.

`timestamp`  
Tiempo actual de Unix en milisegundos. Esta operación utiliza esta marca temporal para resolver las actualizaciones simultáneas de la clave. Si la clave de la configuración del componente tiene una marca temporal mayor que la marca temporal de la solicitud, la solicitud falla.

`valueToMerge` (Python: `value_to_merge`)  
El objeto de configuración que se va a combinar en la ubicación que especifique en `keyPath`. Para obtener más información, consulte [Actualización de las configuraciones de los componentes](update-component-configurations.md).

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

Esta operación no proporciona ninguna información en su respuesta.

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

En los ejemplos siguientes, se muestra cómo llamar a esta operación en código de componente personalizado.

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

**Example Ejemplo: actualizar la configuración**  

```
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 Ejemplo: actualizar la configuración**  

```
#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 Ejemplo: actualizar la configuración**  

```
#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>

Suscríbase para recibir notificaciones cuando se actualice la configuración de un componente. Al suscribirse a una clave, recibirá una notificación cada vez que alguna de las claves secundarias se actualice.

<a name="ipc-subscribe-operation-note"></a>Esta es una operación de suscripción en la que se suscribe a un flujo de mensajes de eventos. Para usar esta operación, defina un identificador de respuesta de flujo con funciones que gestionen los mensajes de eventos, los errores y el cierre del flujo. Para obtener más información, consulte [Suscripción a los flujos de eventos de IPC](interprocess-communication.md#ipc-subscribe-operations).

**Tipo de mensaje del evento:** `ConfigurationUpdateEvents`

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

Esta solicitud de operación tiene los siguientes parámetros:

`componentName` (Python: `component_name`)  <a name="ipc-configuration-request-component-name"></a>
(Opcional) El nombre del componente.  
Toma el valor predeterminado del componente que realiza la solicitud.

`keyPath` (Python: `key_path`)  
La ruta clave al valor de configuración al que se va a suscribir. Especifique una lista en la que cada entrada sea la clave de un único nivel del objeto de configuración. Por ejemplo, especifique `["mqtt", "port"]` si desea obtener el valor de `port` en la siguiente configuración.  

```
{
  "mqtt": {
    "port": 443
  }
}
```
Para suscribirse a las actualizaciones de todos los valores de la configuración del componente, especifique una lista vacía.

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

Esta respuesta de operación contiene la siguiente información:

`messages`  
El flujo de mensajes de notificación. Este objeto, `ConfigurationUpdateEvents`, contiene la siguiente información:    
`configurationUpdateEvent` (Python: `configuration_update_event`)  
El evento de actualización de la configuración. Este objeto, `ConfigurationUpdateEvent`, contiene la siguiente información:    
`componentName` (Python: `component_name`)  <a name="ipc-configuration-response-component-name"></a>
El nombre del componente.  
`keyPath` (Python: `key_path`)  
La ruta clave al valor de configuración que actualizó.

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

En los ejemplos siguientes, se muestra cómo llamar a esta operación en código de componente personalizado.

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

**Example Ejemplo: suscríbase a las actualizaciones de configuración**  

```
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 Ejemplo: suscríbase a las actualizaciones de configuración**  

```
#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 Ejemplo: suscríbase a las actualizaciones de configuración**  

```
#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>

Suscríbase para recibir notificaciones antes de que se actualice la configuración de este componente. Esto permite a los componentes validar las actualizaciones de su propia configuración. Utilice la operación [SendConfigurationValidityReport](#ipc-operation-sendconfigurationvalidityreport) para indicar al núcleo si la configuración es válida o no.

**importante**  
Las implementaciones locales no notifican a los componentes de las actualizaciones.

<a name="ipc-subscribe-operation-note"></a>Esta es una operación de suscripción en la que se suscribe a un flujo de mensajes de eventos. Para usar esta operación, defina un identificador de respuesta de flujo con funciones que gestionen los mensajes de eventos, los errores y el cierre del flujo. Para obtener más información, consulte [Suscripción a los flujos de eventos de IPC](interprocess-communication.md#ipc-subscribe-operations).

**Tipo de mensaje del evento:** `ValidateConfigurationUpdateEvents`

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

Esta solicitud de la operación no tiene parámetros.

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

Esta respuesta de operación contiene la siguiente información:

`messages`  
El flujo de mensajes de notificación. Este objeto, `ValidateConfigurationUpdateEvents`, contiene la siguiente información:    
`validateConfigurationUpdateEvent` (Python: `validate_configuration_update_event`)  
El evento de actualización de la configuración. Este objeto, `ValidateConfigurationUpdateEvent`, contiene la siguiente información:    
`deploymentId` (Python: `deployment_id`)  
El ID de la AWS IoT Greengrass implementación que actualiza el componente.  
`configuration`  
El objeto que contiene la nueva configuración.

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

Indique al núcleo si una actualización de configuración de este componente es válida o no. La implementación falla si le dice al núcleo que la nueva configuración no es válida. Utilice la operación [SubscribeToValidateConfigurationUpdates](#ipc-operation-subscribetovalidateconfigurationupdates) de suscripción para validar las actualizaciones de configuración.

Si un componente no responde a una notificación de esta validación, el núcleo espera el tiempo que especifique en la política de validación de la configuración de la implementación. Transcurrido ese tiempo de espera, el núcleo continúa con la implementación. El tiempo de espera predeterminado de la validación del componente es de 20 segundos. Para obtener más información, consulte [Crear implementaciones](create-deployments.md) y el [DeploymentConfigurationValidationPolicy](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_DeploymentConfigurationValidationPolicy.html)objeto que puede proporcionar al llamar a la [CreateDeployment](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_CreateDeployment.html)operación.

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

Esta solicitud de operación tiene los siguientes parámetros:

`configurationValidityReport` (Python: `configuration_validity_report`)  
El informe que indica al núcleo si la actualización de configuración es válida o no. Este objeto, `ConfigurationValidityReport`, contiene la siguiente información:    
`status`  
El estado de validez. Esta enumeración, `ConfigurationValidityStatus`, tiene los siguientes valores:  
+ `ACCEPTED`: la configuración es válida y el núcleo puede aplicarla a este componente.
+ `REJECTED`: la configuración no es válida y la implementación falla.  
`deploymentId` (Python: `deployment_id`)  
El ID de la AWS IoT Greengrass implementación que solicitó la actualización de la configuración.  
`message`  
(Opcional) Un mensaje que informa de los motivos por los que la configuración no es válida.

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

Esta operación no proporciona ninguna información en su respuesta.

# Recupere valores secretos
<a name="ipc-secret-manager"></a>

Utilice el servicio IPC del administrador secreto para recuperar los valores secretos de los secretos del dispositivo principal. El [componente administrador de secretos](secret-manager-component.md) se utiliza para implementar secretos cifrados en los dispositivos principales. A continuación, puede utilizar una operación de IPC para descifrar el secreto y utilizar su valor en los componentes personalizados.

**Topics**
+ [Versiones mínimas de SDK](#ipc-secret-manager-sdk-versions)
+ [Autorización](#ipc-secret-manager-authorization)
+ [GetSecretValue](#ipc-operation-getsecretvalue)
+ [Ejemplos](#ipc-secret-manager-examples)

## Versiones mínimas de SDK
<a name="ipc-secret-manager-sdk-versions"></a>

En la siguiente tabla se enumeran las versiones mínimas de las SDK para dispositivos con AWS IoT que debe utilizar para recuperar los valores secretos de los secretos del dispositivo principal.


| SDK | Versión mínima | 
| --- | --- | 
|  [SDK para dispositivos con AWS IoT para Java v2](https://github.com/aws/aws-iot-device-sdk-java-v2)  |  Versión 1.2.10  | 
|  [SDK para dispositivos con AWS IoT para Python v2](https://github.com/aws/aws-iot-device-sdk-python-v2)  |  Versión 1.5.3  | 
|  [SDK para dispositivos con AWS IoT para C\$1\$1 v2](https://github.com/aws/aws-iot-device-sdk-cpp-v2)  |  Versión 1.17.0  | 
|  [SDK para dispositivos con AWS IoT para JavaScript v2](https://github.com/aws/aws-iot-device-sdk-js-v2)  |  Versión 1.12.0  | 

## Autorización
<a name="ipc-secret-manager-authorization"></a>

Para usar el administrador de secretos en un componente personalizado, debe definir políticas de autorización que permitan a su componente obtener el valor de los secretos que almacena en el dispositivo principal. Para obtener información sobre cómo definir las políticas de autorización, consulte [Autorización de los componentes para realizar operaciones de IPC](interprocess-communication.md#ipc-authorization-policies).

Las políticas de autorización del administrador de secretos tienen las siguientes propiedades.

**Identificador de servicio IPC:** `aws.greengrass.SecretManager`


| Operación | Description (Descripción) | Recursos | 
| --- | --- | --- | 
|  `aws.greengrass#GetSecretValue` o `*`  |  Permite que un componente obtenga el valor de los secretos que están cifrados en el dispositivo principal.  |  Un ARN secreto de Secrets Manager, o `*` para permitir el acceso a todos los secretos.  | 

### Ejemplos de políticas de autorización
<a name="ipc-secret-manager-authorization-policy-examples"></a>

Puede consultar el siguiente ejemplo de política de autorización con el fin de configurar las políticas de autorización para sus componentes.

**Example Ejemplo de política de autorización**  
El siguiente ejemplo de política de autorización permite a un componente obtener el valor de cualquier secreto del dispositivo principal.  
En un entorno de producción, se recomienda reducir el alcance de la política de autorización para que el componente recupere solo los secretos que utiliza. Puede cambiar el `*` comodín por una lista de secretos ARNs al implementar el componente.

```
{
  "accessControl": {
    "aws.greengrass.SecretManager": {
      "com.example.MySecretComponent:secrets:1": {
        "policyDescription": "Allows access to a secret.",
        "operations": [
          "aws.greengrass#GetSecretValue"
        ],
        "resources": [
          "*"
        ]
      }
    }
  }
}
```

## GetSecretValue
<a name="ipc-operation-getsecretvalue"></a>

Obtiene el valor de un secreto que se almacena en el dispositivo principal.

Esta operación es similar a la operación de Secrets Manager, que puede utilizar para obtener el valor de un secreto en Nube de AWS. Para obtener más información, consulta [GetSecretValue](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html) en la *AWS Secrets Manager Referencia de la API de *.

### Solicitud
<a name="ipc-operation-getsecretvalue-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`refresh` (Python: `refresh`)  
(opcional): si se debe sincronizar el secreto solicitado con su último valor del AWS Secrets Manager servicio.  
Si se establece en true, el administrador de secretos solicitará al AWS Secrets Manager servicio el valor más reciente de la etiqueta secreta especificada y devolverá ese valor como respuesta. De lo contrario, se devolverá el valor secreto que estaba almacenado localmente.  
 Este parámetro no funcionará junto con el parámetro `versionId` en la solicitud. Este parámetro funciona cuando se utiliza junto con la versión 2.13.0 y posteriores del núcleo.

`secretId` (Python: `secret_id`)  
El nombre del secreto que se obtendrá. Puede especificar el Nombre de recurso de Amazon (ARN) o el nombre fácil de recordar del secreto.

`versionId` (Python: `version_id`)  
(Opcional) El ID de versión que se obtendrá.  
Puede especificar `versionId` o `versionStage`.  
Si no especifica `versionId` o `versionStage`, esta operación se establece de forma predeterminada en la versión con la etiqueta `AWSCURRENT`.

`versionStage` (Python: `version_stage`)  
(Opcional) La etiqueta de fase de la versión que se obtendrá.  
Puede especificar `versionId` o `versionStage`.  
Si no especifica `versionId` o `versionStage`, esta operación se establece de forma predeterminada en la versión con la etiqueta `AWSCURRENT`.

### Respuesta
<a name="ipc-operation-getsecretvalue-response"></a>

Esta respuesta de operación contiene la siguiente información:

`secretId` (Python: `secret_id`)  
El ID del secreto.

`versionId` (Python: `version_id`)  
El ID de esta versión del secreto.

`versionStage` (Python: `version_stage`)  
La lista de etiquetas de fase adjunta a la versión del secreto.

`secretValue` (Python: `secret_value`)  
El valor de esta versión del secreto. Este objeto, `SecretValue`, contiene la siguiente información.    
`secretString` (Python: `secret_string`)  
La parte descifrada de la información secreta protegida que proporcionó a Secrets Manager en forma de cadena.  
`secretBinary` (Python: `secret_binary`)  
(Opcional) La parte descifrada de la información secreta protegida que proporcionó a Secrets Manager como datos binarios en forma de matriz de bytes. Esta propiedad contiene los datos binarios como una cadena codificada en base64.  
Esta propiedad no se utiliza si creó el secreto en la consola de Secrets Manager.

### Ejemplos
<a name="ipc-operation-getsecretvalue-examples"></a>

En los ejemplos siguientes, se muestra cómo llamar a esta operación en código de componente personalizado.

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

**Example Ejemplo: obtener un valor secreto**  
En este ejemplo, se utiliza una `IPCUtils` clase para crear una conexión con el servicio AWS IoT Greengrass Core IPC. Para obtener más información, consulte [Conéctese al AWS IoT Greengrass servicio Core 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.GetSecretValueResponseHandler;
import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClient;
import software.amazon.awssdk.aws.greengrass.model.GetSecretValueRequest;
import software.amazon.awssdk.aws.greengrass.model.GetSecretValueResponse;
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 GetSecretValue {

    public static final int TIMEOUT_SECONDS = 10;

    public static void main(String[] args) {
        String secretArn = args[0];
        String versionStage = args[1];
        try (EventStreamRPCConnection eventStreamRPCConnection =
                     IPCUtils.getEventStreamRpcConnection()) {
            GreengrassCoreIPCClient ipcClient =
                    new GreengrassCoreIPCClient(eventStreamRPCConnection);
            GetSecretValueResponseHandler responseHandler =
                    GetSecretValue.getSecretValue(ipcClient, secretArn, versionStage);
            CompletableFuture<GetSecretValueResponse> futureResponse =
                    responseHandler.getResponse();
            try {
                GetSecretValueResponse response = futureResponse.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
                response.getSecretValue().postFromJson();
                String secretString = response.getSecretValue().getSecretString();
                System.out.println("Successfully retrieved secret value: " + secretString);
            } catch (TimeoutException e) {
                System.err.println("Timeout occurred while retrieving secret: " + secretArn);
            } catch (ExecutionException e) {
                if (e.getCause() instanceof UnauthorizedError) {
                    System.err.println("Unauthorized error while retrieving secret: " + secretArn);
                } 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 GetSecretValueResponseHandler getSecretValue(GreengrassCoreIPCClient greengrassCoreIPCClient, String secretArn, String versionStage) {
        GetSecretValueRequest getSecretValueRequest = new GetSecretValueRequest();
        getSecretValueRequest.setSecretId(secretArn);
        getSecretValueRequest.setVersionStage(versionStage);
        return greengrassCoreIPCClient.getSecretValue(getSecretValueRequest, Optional.empty());
    }
}
```

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

**Example Ejemplo: obtener un valor secreto**  
En este ejemplo se supone que está utilizando la versión 1.5.4 o posterior de SDK para dispositivos con AWS IoT para Python v2. 

```
import json

import awsiot.greengrasscoreipc
from awsiot.greengrasscoreipc.model import (
    GetSecretValueRequest,
    GetSecretValueResponse,
    UnauthorizedError
)

secret_id = 'arn:aws:secretsmanager:us-west-2:123456789012:secret:MyGreengrassSecret-abcdef'
TIMEOUT = 10

ipc_client = awsiot.greengrasscoreipc.connect()

request = GetSecretValueRequest()
request.secret_id = secret_id
request.version_stage = 'AWSCURRENT'
operation = ipc_client.new_get_secret_value()
operation.activate(request)
future_response = operation.get_response()
response = future_response.result(TIMEOUT)
secret_json = json.loads(response.secret_value.secret_string)
# Handle secret value.
```

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

**Example Ejemplo: obtener un valor secreto**  

```
import {
    GetSecretValueRequest,
} from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc/model';
import * as greengrasscoreipc from "aws-iot-device-sdk-v2/dist/greengrasscoreipc";
 
class GetSecretValue {
    private readonly secretId : string;
    private readonly versionStage : string;
    private ipcClient : greengrasscoreipc.Client
 
    constructor() {
        this.secretId = "<define_your_own_secretId>"
        this.versionStage = "<define_your_own_versionStage>"
 
        this.getSecretValue().then(r => console.log("Started workflow"));
    }
 
    private async getSecretValue() {
        try {
            this.ipcClient = await getIpcClient();
 
            const getSecretValueRequest : GetSecretValueRequest = {
                secretId: this.secretId,
                versionStage: this.versionStage,
            };
 
            const result = await this.ipcClient.getSecretValue(getSecretValueRequest);
            const secretString = result.secretValue.secretString;
            console.log("Successfully retrieved secret value: " + secretString)
        } catch (e) {
            // parse the error depending on your use cases
            throw e
        }
    }
}
 
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 getSecretValue = new GetSecretValue();
```

------

## Ejemplos
<a name="ipc-secret-manager-examples"></a>

Utilice los siguientes ejemplos para aprender a utilizar el servicio IPC del administrador de secretos en sus componentes.

### Ejemplo: impresión del secreto (Python, cliente IPC V1)
<a name="ipc-secret-manager-example-print-secret-python"></a>

Este componente de ejemplo imprime el valor de un secreto que se implementa en el dispositivo principal.

**importante**  
Este componente de ejemplo imprime el valor de un secreto, así que utilícelo solo con los secretos que almacenan datos de prueba. No utilice este componente para imprimir el valor de un secreto que almacena información importante.

**Topics**
+ [Fórmula](#ipc-secret-manager-example-print-secret-python-recipe)
+ [Artefactos](#ipc-secret-manager-example-print-secret-python-artifacts)
+ [De uso](#ipc-secret-manager-example-print-secret-python-usage)

#### Fórmula
<a name="ipc-secret-manager-example-print-secret-python-recipe"></a>

La siguiente receta de ejemplo define un parámetro de configuración de ARN oculto y permite que el componente obtenga el valor de cualquier secreto del dispositivo principal.

**nota**  <a name="ipc-secret-manager-authorization-policy-resource-wildcard"></a>
En un entorno de producción, se recomienda reducir el alcance de la política de autorización para que el componente recupere solo los secretos que utiliza. Puede cambiar el `*` comodín por una lista de secretos ARNs al implementar el componente.

------
#### [ JSON ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.PrintSecret",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "Prints the value of an AWS Secrets Manager secret.",
  "ComponentPublisher": "Amazon",
  "ComponentDependencies": {
    "aws.greengrass.SecretManager": {
      "VersionRequirement": "^2.0.0",
      "DependencyType": "HARD"
    }
  },
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "SecretArn": "",
      "accessControl": {
        "aws.greengrass.SecretManager": {
          "com.example.PrintSecret:secrets:1": {
            "policyDescription": "Allows access to a secret.",
            "operations": [
              "aws.greengrass#GetSecretValue"
            ],
            "resources": [
              "*"
            ]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux"
      },
      "Lifecycle": {
        "install": "python3 -m pip install --user awsiotsdk",
        "Run": "python3 -u {artifacts:path}/print_secret.py \"{configuration:/SecretArn}\""
      }
    },
    {
      "Platform": {
        "os": "windows"
      },
      "Lifecycle": {
        "install": "py -3 -m pip install --user awsiotsdk",
        "Run": "py -3 -u {artifacts:path}/print_secret.py \"{configuration:/SecretArn}\""
      }
    }
  ]
}
```

------
#### [ YAML ]

```
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.PrintSecret
ComponentVersion: 1.0.0
ComponentDescription: Prints the value of a Secrets Manager secret.
ComponentPublisher: Amazon
ComponentDependencies:
  aws.greengrass.SecretManager:
    VersionRequirement: "^2.0.0"
    DependencyType: HARD
ComponentConfiguration:
  DefaultConfiguration:
    SecretArn: ''
    accessControl:
      aws.greengrass.SecretManager:
        com.example.PrintSecret:secrets:1:
          policyDescription: Allows access to a secret.
          operations:
            - aws.greengrass#GetSecretValue
          resources:
            - "*"
Manifests:
  - Platform:
      os: linux
    Lifecycle:
      install: python3 -m pip install --user awsiotsdk
      Run: python3 -u {artifacts:path}/print_secret.py "{configuration:/SecretArn}"
  - Platform:
      os: windows
    Lifecycle:
      install: py -3 -m pip install --user awsiotsdk
      Run: py -3 -u {artifacts:path}/print_secret.py "{configuration:/SecretArn}"
```

------

#### Artefactos
<a name="ipc-secret-manager-example-print-secret-python-artifacts"></a>

El siguiente ejemplo de aplicación de Python demuestra cómo utilizar el servicio IPC del administrador de secretos para obtener el valor de un secreto en el dispositivo principal.

```
import concurrent.futures
import json
import sys
import traceback

import awsiot.greengrasscoreipc
from awsiot.greengrasscoreipc.model import (
    GetSecretValueRequest,
    GetSecretValueResponse,
    UnauthorizedError
)

TIMEOUT = 10

if len(sys.argv) == 1:
    print('Provide SecretArn in the component configuration.', file=sys.stdout)
    exit(1)

secret_id = sys.argv[1]

try:
    ipc_client = awsiot.greengrasscoreipc.connect()

    request = GetSecretValueRequest()
    request.secret_id = secret_id
    operation = ipc_client.new_get_secret_value()
    operation.activate(request)
    future_response = operation.get_response()

    try:
        response = future_response.result(TIMEOUT)
        secret_json = json.loads(response.secret_value.secret_string)
        print('Successfully got secret: ' + secret_id)
        print('Secret value: ' + str(secret_json))
    except concurrent.futures.TimeoutError:
        print('Timeout occurred while getting secret: ' + secret_id, file=sys.stderr)
    except UnauthorizedError as e:
        print('Unauthorized error while getting secret: ' + secret_id, file=sys.stderr)
        raise e
    except Exception as e:
        print('Exception while getting secret: ' + secret_id, file=sys.stderr)
        raise e
except Exception:
    print('Exception occurred when using IPC.', file=sys.stderr)
    traceback.print_exc()
    exit(1)
```

#### De uso
<a name="ipc-secret-manager-example-print-secret-python-usage"></a>

Puede usar este componente de ejemplo con el [componente de administrador de secretos](secret-manager-component.md) para implementar e imprimir el valor de un secreto en su dispositivo principal.

**Cómo crear, implementar e imprimir un secreto de prueba**

1. Crear un secreto en Secrets Manager con datos de prueba.

------
#### [ Linux or Unix ]

   ```
   aws secretsmanager create-secret \
     --name MyTestGreengrassSecret \
     --secret-string '{"my-secret-key": "my-secret-value"}'
   ```

------
#### [ Windows Command Prompt (CMD) ]

   ```
   aws secretsmanager create-secret ^
     --name MyTestGreengrassSecret ^
     --secret-string '{"my-secret-key": "my-secret-value"}'
   ```

------
#### [ PowerShell ]

   ```
   aws secretsmanager create-secret `
     --name MyTestGreengrassSecret `
     --secret-string '{"my-secret-key": "my-secret-value"}'
   ```

------

   Guarde el ARN del secreto para utilizarlo en los pasos siguientes.

   Para obtener más información, consulte [Creación de un secreto](https://docs.aws.amazon.com/secretsmanager/latest/userguide/manage_create-basic-secret.html) en la *Guía del usuario de AWS Secrets Manager *.

1. Implemente el [componente de administrador de secretos](secret-manager-component.md) (`aws.greengrass.SecretManager`) con la siguiente actualización de combinación de configuraciones. Especifique el ARN del secreto que creó anteriormente.

   ```
   {
     "cloudSecrets": [
       {
         "arn": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestGreengrassSecret-abcdef"
       }
     ]
   }
   ```

   Para obtener más información, consulte [Implemente AWS IoT Greengrass componentes en los dispositivos](manage-deployments.md) o el [comando de implementación de la CLI de Greengrass](gg-cli-deployment.md).

1. Cree e implemente el componente de ejemplo de esta sección con la siguiente actualización de combinación de configuraciones. Especifique el ARN del secreto que creó anteriormente.

   ```
   {
     "SecretArn": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestGreengrassSecret",
     "accessControl": {
       "aws.greengrass.SecretManager": {
         "com.example.PrintSecret:secrets:1": {
           "policyDescription": "Allows access to a secret.",
           "operations": [
             "aws.greengrass#GetSecretValue"
           ],
           "resources": [
             "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestGreengrassSecret-abcdef"
           ]
         }
       }
     }
   }
   ```

   Para obtener más información, consulte [Creación de componentes de AWS IoT Greengrass](create-components.md)

1. Consulte los registros del software AWS IoT Greengrass principal para comprobar que las implementaciones se han realizado correctamente y consulte el registro de `com.example.PrintSecret` componentes para ver impreso el valor secreto. Para obtener más información, consulte [Supervisión de los registros de AWS IoT Greengrass](monitor-logs.md).

# Interactúe con las sombras locales
<a name="ipc-local-shadows"></a>

Utilice el servicio IPC de sombra para interactuar con las sombras locales de un dispositivo. El dispositivo con el que elija interactuar puede ser su dispositivo principal o un dispositivo de cliente conectado. 

Para utilizar estas operaciones de IPC, incluya el [componente administrador de sombras](shadow-manager-component.md) como una dependencia en su componente personalizado. A continuación, puede utilizar las operaciones de IPC en sus componentes personalizados para interactuar con las sombras locales del dispositivo a través del administrador de sombras. Para permitir que los componentes personalizados reaccionen a los cambios en los estados paralelos locales, también puede utilizar el servicio publish/subscribe IPC para suscribirse a eventos paralelos. Para obtener más información sobre el uso del publish/subscribe servicio, consulte la[Publicar/suscribir mensajes locales](ipc-publish-subscribe.md).

**nota**  <a name="note-requirement-enable-shadow-manager-client-devices"></a>
Para permitir que un dispositivo principal interactúe con las sombras de dispositivos de cliente, también debe configurar e implementar el componente puente MQTT. Para obtener más información, consulte [Habilitación del administrador de sombras para que se comunique con los dispositivos de cliente](work-with-client-device-shadows.md).

**Topics**
+ [Versiones mínimas de SDK](#ipc-local-shadows-sdk-versions)
+ [Autorización](#ipc-local-shadow-authorization)
+ [GetThingShadow](#ipc-operation-getthingshadow)
+ [UpdateThingShadow](#ipc-operation-updatethingshadow)
+ [DeleteThingShadow](#ipc-operation-deletethingshadow)
+ [ListNamedShadowsForThing](#ipc-operation-listnamedshadowsforthing)

## Versiones mínimas de SDK
<a name="ipc-local-shadows-sdk-versions"></a>

En la siguiente tabla se enumeran las versiones mínimas del SDK para dispositivos con AWS IoT que debe utilizar para interactuar con las sombras locales.


| SDK | Versión mínima | 
| --- | --- | 
|  [SDK para dispositivos con AWS IoT para Java v2](https://github.com/aws/aws-iot-device-sdk-java-v2)  |  v1.4.0  | 
|  [SDK para dispositivos con AWS IoT para Python v2](https://github.com/aws/aws-iot-device-sdk-python-v2)  |  Versión 1.6.0  | 
|  [SDK para dispositivos con AWS IoT para C\$1\$1 v2](https://github.com/aws/aws-iot-device-sdk-cpp-v2)  |  Versión 1.17.0  | 
|  [SDK para dispositivos con AWS IoT para JavaScript v2](https://github.com/aws/aws-iot-device-sdk-js-v2)  |  Versión 1.12.0  | 

## Autorización
<a name="ipc-local-shadow-authorization"></a>

Para utilizar el servicio IPC de sombra en un componente personalizado, debe definir políticas de autorización que permitan a su componente interactuar con las sombras. Para obtener información sobre cómo definir las políticas de autorización, consulte [Autorización de los componentes para realizar operaciones de IPC](interprocess-communication.md#ipc-authorization-policies).

Las políticas de autorización para la interacción con las sombra tienen las siguientes propiedades.

**Identificador de servicio IPC:** `aws.greengrass.ShadowManager`


| Operación | Description (Descripción) | Recursos | 
| --- | --- | --- | 
|  `aws.greengrass#GetThingShadow`  |  Permite que un componente recupere la sombra de un objeto.  |  Una de las siguientes cadenas:  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/greengrass/v2/developerguide/ipc-local-shadows.html)  | 
|  `aws.greengrass#UpdateThingShadow`  |  Permite que un componente actualice la sombra de un objeto.  |  Una de las siguientes cadenas:  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/greengrass/v2/developerguide/ipc-local-shadows.html)  | 
|  `aws.greengrass#DeleteThingShadow`  |  Permite a un componente eliminar la sombra de un objeto.  |  Una de las siguientes cadenas:  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/greengrass/v2/developerguide/ipc-local-shadows.html)  | 
|  `aws.greengrass#ListNamedShadowsForThing`  |  Permite que un componente recupere la lista de sombras con nombre de un objeto.  |  Cadena con el nombre de un objeto que permite acceder al objeto para enumerar sus sombras. Se usa `*` para permitir el acceso a todos los objetos.  | 

**Identificador de servicio IPC:** `aws.greengrass.ipc.pubsub`


| Operación | Description (Descripción) | Recursos | 
| --- | --- | --- | 
|  `aws.greengrass#SubscribeToTopic`  |  Permite que un componente se suscriba a los mensajes de los temas que especifique.  |  Una de las siguientes cadenas de temas: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/greengrass/v2/developerguide/ipc-local-shadows.html) El valor del prefijo del tema `shadowTopicPrefix` depende del tipo de sombra:  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/greengrass/v2/developerguide/ipc-local-shadows.html) Se usa `*` para permitir el acceso a todos los temas. <a name="ipc-local-publish-subscribe-authorization-mqtt-wildcards"></a>En el [núcleo de Greengrass ](greengrass-nucleus-component.md) versión 2.6.0 y versiones posteriores, puede suscribirse a temas que contengan comodines de temas MQTT (`#` y `+`). Esta cadena de tema admite los comodines de los temas MQTT como caracteres literales. Por ejemplo, si la política de autorización de un componente permite el acceso a `test/topic/#`, el componente se puede suscribir a `test/topic/#`, pero no se puede suscribir a `test/topic/filter`.  | 

### Variables de receta en las políticas de autorización de sombras locales
<a name="ipc-local-shadow-authorization-recipe-variables"></a>

[Si usa la versión 2.6.0 o posterior del núcleo de [Greengrass y establece la opción de [interpolateComponentConfiguration](greengrass-nucleus-component.md#greengrass-nucleus-component-configuration-interpolate-component-configuration)configuración del núcleo](greengrass-nucleus-component.md) de Greengrass en`true`, puede usar la variable de receta en las políticas de autorización. `{iot:thingName}`](component-recipe-reference.md#recipe-variables) Esta característica le permite configurar una política de autorización única para un grupo de dispositivos principales, de forma que cada dispositivo principal solo pueda acceder a su propia sombra. Por ejemplo, puede permitir que un componente acceda al siguiente recurso para realizar operaciones de IPC de sombra.

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

### Ejemplos de políticas de autorización
<a name="ipc-local-shadow-authorization-policy-examples"></a>

Puede consultar los siguientes ejemplos de políticas de autorización con el fin de configurar las políticas de autorización para sus componentes.

**Example Ejemplo: permitir que un grupo de dispositivos principales interactúe con las sombras locales**  
 <a name="phrase-example-uses-recipe-variables-in-configuration"></a>En este ejemplo, se utiliza una característica que está disponible para la versión 2.6.0 y versiones posteriores del [componente núcleo de Greengrass](greengrass-nucleus-component.md). El núcleo de Greengrass versión 2.6.0 suma compatibilidad con la mayoría de las [variables de receta](component-recipe-reference.md#recipe-variables), por ejemplo: `{iot:thingName}`, en las configuraciones de componentes. Para activar esta función, defina la opción de [interpolateComponentConfiguration](greengrass-nucleus-component.md#greengrass-nucleus-component-configuration-interpolate-component-configuration)configuración del núcleo de Greengrass en. `true` Si desea ver un ejemplo que funcione en todas las versiones del núcleo de Greengrass, consulte el [ejemplo de política de autorización para un dispositivo de un núcleo principal](#ipc-local-shadows-authorization-example-single-device).
El siguiente ejemplo de política de autorización permite que el componente `com.example.MyShadowInteractionComponent` interactúe con la sombra de dispositivo clásico y con la sombra con nombre `myNamedShadow` del dispositivo principal que ejecuta el componente. Esta política también permite que este componente reciba mensajes sobre temas locales relacionados con estas sombras.  

```
{
  "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 Ejemplo: permitir que un grupo de dispositivos principales interactúe con sombra de dispositivo del cliente**  
Esta característica requiere la versión 2.6.0 o versiones posteriores del [núcleo de Greengrass](greengrass-nucleus-component.md), la versión 2.2.0 y versiones posteriores del [administrador de sombras](shadow-manager-component.md) y la versión 2.2.0 o versiones posteriores del [puente de MQTT](mqtt-bridge-component.md). Debe configurar el puente MQTT para [permitir que el administrador de sombra se comunique con los dispositivos de cliente.](work-with-client-device-shadows.md#enable-shadow-manager-client-devices)
El siguiente ejemplo de política de autorización permite que el componente `com.example.MyShadowInteractionComponent` interactúe con todas las sombras de dispositivos de los dispositivos de cliente cuyos nombres comiencen con `MyClientDevice`.  
Para permitir que un dispositivo principal interactúe con las sombras de dispositivos de cliente, también debe configurar e implementar el componente puente MQTT. Para obtener más información, consulte [Habilitación del administrador de sombras para que se comunique con los dispositivos de cliente](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 Ejemplo: permitir que un solo dispositivo principal interactúe con las sombras locales**  
El siguiente ejemplo de política de autorización permite que el componente `com.example.MyShadowInteractionComponent` interactúe con la sombra de dispositivo clásico y con la sombra con nombre `myNamedShadow` para el dispositivo `MyThingName`. Esta política también permite que este componente reciba mensajes sobre temas locales relacionados con estas sombras.   

```
{
  "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 Ejemplo: permitir que un grupo de dispositivos principales reaccione a los cambios en el estado de la sombra local**  
 <a name="phrase-example-uses-recipe-variables-in-configuration"></a>En este ejemplo, se utiliza una característica que está disponible para la versión 2.6.0 y versiones posteriores del [componente núcleo de Greengrass](greengrass-nucleus-component.md). El núcleo de Greengrass versión 2.6.0 suma compatibilidad con la mayoría de las [variables de receta](component-recipe-reference.md#recipe-variables), por ejemplo: `{iot:thingName}`, en las configuraciones de componentes. Para activar esta función, defina la opción de [interpolateComponentConfiguration](greengrass-nucleus-component.md#greengrass-nucleus-component-configuration-interpolate-component-configuration)configuración del núcleo de Greengrass en. `true` Si desea ver un ejemplo que funcione en todas las versiones del núcleo de Greengrass, consulte el [ejemplo de política de autorización para un dispositivo de un núcleo principal](#interact-with-shadows-react-example-authorization-policy-single-device).
El siguiente ejemplo de política de control de acceso permite personalizar `com.example.MyShadowReactiveComponent` para recibir mensajes sobre el tema `/update/delta` de la sombra de dispositivo clásico y de la sombra con nombre `myNamedShadow` en cada dispositivo principal en el que se ejecute el componente.  

```
{
  "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 Ejemplo: permitir que un solo dispositivo principal reaccione a los cambios en el estado de la sombra local**  
El siguiente ejemplo de política de control de acceso permite personalizar `com.example.MyShadowReactiveComponent` para recibir mensajes sobre el tema `/update/delta` de la sombra de dispositivo clásico y de la sombra con nombre `myNamedShadow` para el dispositivo `MyThingName`.  

```
{
  "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>

Obtenga la sombra de objeto especificado.

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

Esta solicitud de operación tiene los siguientes parámetros:

`thingName` (Python: `thing_name`)  <a name="ipc-local-shadows-thing-name"></a>
El nombre del objeto.  
Tipo: `string`

`shadowName` (Python: `shadow_name`)  <a name="ipc-local-shadows-shadow-name"></a>
El nombre de la sombra. Para especificar la sombra clásica del objeto, defina este parámetro en una cadena vacía (`""`).  
El AWS IoT Greengrass servicio usa el `AWSManagedGreengrassV2Deployment` nombre shadow para administrar las implementaciones que se dirigen a dispositivos principales individuales. Esta sombra denominada está reservada para que la utilice el AWS IoT Greengrass servicio. No actualice ni elimine esta sombra con nombre.
Tipo: `string`

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

Esta respuesta de operación contiene la siguiente información:

`payload`  
El documento de estado de la respuesta en forma de blob.  
Tipo: `object` que contiene la siguiente información:    
`state`  
La información del estado.  
Este objeto contiene la siguiente información:    
`desired`  
Las propiedades y los valores de estado que se solicitan actualizar en el dispositivo.  
Tipo: `map` de pares clave-valor  
`reported`  
Las propiedades y los valores de estado informados por el dispositivo.  
Tipo: `map` de pares clave-valor  
`delta`  
La diferencia entre las propiedades y los valores de estado deseados e informados. Esta propiedad solo está presente si los estados `desired` y `reported` son diferentes.  
Tipo: `map` de pares clave-valor  
`metadata`  
Las marcas temporales de cada atributo de las secciones `desired` y `reported` para que se pueda determinar cuándo se actualizó el estado.   
Tipo: `string`  
`timestamp`  
La fecha y hora de inicio en que se generó la respuesta.  
Tipo: `integer`  
`clientToken` (Python: `clientToken`)  
El token que se usa para hacer coincidir la solicitud y la respuesta correspondiente.  
Tipo: `string`  
`version`  
La versión del documento de sombra local.  
Tipo: `integer`

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

Esta operación puede devolver los siguientes errores.

`InvalidArgumentsError`  <a name="ipc-invalidargumentserror"></a>
<a name="ipc-invalidargumentserror-para"></a>El servicio de sombra local no puede validar los parámetros de la solicitud. Esto puede ocurrir si la solicitud contiene un formato incorrecto de JSON o caracteres no admitidos. 

`ResourceNotFoundError`  <a name="ipc-resourcenotfounderror"></a>
No se encuentra el documento de sombra local solicitado.

`ServiceError`  <a name="ipc-serviceerror"></a>
Se ha producido un error de servicio interno o la cantidad de solicitudes al servicio de IPC ha superado los límites especificados en los parámetros de configuración de `maxLocalRequestsPerSecondPerThing` y `maxTotalLocalRequestsRate` del componente del administrador de sombra.

`UnauthorizedError`  <a name="ipc-unauthorizederror"></a>
La política de autorización del componente no incluye los permisos necesarios para esta operación.

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

En los ejemplos siguientes, se muestra cómo llamar a esta operación en código de componente personalizado.

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

**Example Ejemplo: obtener la sombra de un objeto**  
En este ejemplo, se utiliza una `IPCUtils` clase para crear una conexión con el servicio AWS IoT Greengrass Core IPC. Para obtener más información, consulte [Conéctese al AWS IoT Greengrass servicio Core 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 Ejemplo: obtener la sombra de un objeto**  

```
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 Ejemplo: obtener la sombra de un objeto**  

```
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>

Actualice la sombra del objeto especificado. Si la sombra no existe, se crea una.

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

Esta solicitud de operación tiene los siguientes parámetros:

`thingName` (Python: `thing_name`)  <a name="ipc-local-shadows-thing-name"></a>
El nombre del objeto.  
Tipo: `string`

`shadowName` (Python: `shadow_name`)  <a name="ipc-local-shadows-shadow-name"></a>
El nombre de la sombra. Para especificar la sombra clásica del objeto, defina este parámetro en una cadena vacía (`""`).  
El AWS IoT Greengrass servicio usa el `AWSManagedGreengrassV2Deployment` nombre shadow para administrar las implementaciones que se dirigen a dispositivos principales individuales. Esta sombra denominada está reservada para que la utilice el AWS IoT Greengrass servicio. No actualice ni elimine esta sombra con nombre.
Tipo: `string`

`payload`  
El documento del estado de solicitud es un blob.  
Tipo: `object` que contiene la siguiente información:    
`state`  
La información del estado que se va a actualizar. Esta operación de IPC afecta únicamente a los campos especificados.  
Este objeto contiene la siguiente información: Normalmente, utilizará la propiedad `desired` o la propiedad `reported`, pero no ambas en la misma solicitud.    
`desired`  
Las propiedades y los valores de estado que se solicitan actualizar en el dispositivo.  
Tipo: `map` de pares clave-valor  
`reported`  
Las propiedades y los valores de estado informados por el dispositivo.  
Tipo: `map` de pares clave-valor  
`clientToken` (Python: `client_token`)  
(Opcional) El token que se usa para hacer coincidir la solicitud y la respuesta correspondiente con el token del cliente.  
Tipo: `string`  
`version`  
(Opcional) La versión del documento de sombra local que se va a actualizar. El servicio de sombra procesa la actualización solo si la versión especificada coincide con la versión más reciente que tiene.  
Tipo: `integer`

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

Esta respuesta de operación contiene la siguiente información:

`payload`  
El documento de estado de la respuesta en forma de blob.  
Tipo: `object` que contiene la siguiente información:    
`state`  
La información del estado.  
Este objeto contiene la siguiente información:    
`desired`  
Las propiedades y los valores de estado que se solicitan actualizar en el dispositivo.  
Tipo: `map` de pares clave-valor  
`reported`  
Las propiedades y los valores de estado informados por el dispositivo.  
Tipo: `map` de pares clave-valor  
`delta`  
Las propiedades y los valores de estado informados por el dispositivo.  
Tipo: `map` de pares clave-valor  
`metadata`  
Las marcas temporales de cada atributo de las secciones `desired` y `reported` para que se pueda determinar cuándo se actualizó el estado.   
Tipo: `string`  
`timestamp`  
La fecha y hora de inicio en que se generó la respuesta.  
Tipo: `integer`  
`clientToken` (Python: `client_token`)  
El token que se usa para hacer coincidir la solicitud y la respuesta correspondiente.  
Tipo: `string`  
`version`  
La versión del documento de sombra local una vez finalizada la actualización.  
Tipo: `integer`

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

Esta operación puede devolver los siguientes errores.

`ConflictError`  
El servicio de sombra local detectó un conflicto de versiones durante la operación de actualización. Esto ocurre cuando la versión de la carga útil de la solicitud no coincide con la versión del último documento de sombra local disponible.

`InvalidArgumentsError`  
<a name="ipc-invalidargumentserror-para"></a>El servicio de sombra local no puede validar los parámetros de la solicitud. Esto puede ocurrir si la solicitud contiene un formato incorrecto de JSON o caracteres no admitidos.   
Un `payload` válido incluye las siguientes propiedades:  
+ El nodo `state` existe y es un objeto que contiene la información de estado `desired` o `reported`. 
+ Los nodos `desired` y `reported` son objetos o nulos. Al menos uno de estos objetos debe contener información de estado válida. 
+ La profundidad de los objetos `desired` y `reported` no puede superar los ocho nodos. 
+ La longitud del valor `clientToken` no puede superar los 64 caracteres. 
+  El valor `version` debe ser `1` o superior. 

`ServiceError`  <a name="ipc-serviceerror"></a>
Se ha producido un error de servicio interno o la cantidad de solicitudes al servicio de IPC ha superado los límites especificados en los parámetros de configuración de `maxLocalRequestsPerSecondPerThing` y `maxTotalLocalRequestsRate` del componente del administrador de sombra.

`UnauthorizedError`  <a name="ipc-unauthorizederror"></a>
La política de autorización del componente no incluye los permisos necesarios para esta operación.

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

En los ejemplos siguientes, se muestra cómo llamar a esta operación en código de componente personalizado.

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

**Example Ejemplo: actualizar una sombra de objeto**  
En este ejemplo, se utiliza una `IPCUtils` clase para crear una conexión con el servicio AWS IoT Greengrass Core IPC. Para obtener más información, consulte [Conéctese al AWS IoT Greengrass servicio Core 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 Ejemplo: actualizar una sombra de objeto**  

```
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 Ejemplo: actualizar una sombra de objeto**  

```
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>

Elimina la sombra de objeto especificado. 

A partir de la versión 2.0.4 de administrador de sombra, cuando se elimina una sombra se incrementa el número de versión. Por ejemplo, si elimina la sombra `MyThingShadow` en la versión 1, la versión de la sombra eliminada es 2. Si después vuelve a crear una sombra con el nombre `MyThingShadow`, la versión de esa sombra es 3. 

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

Esta solicitud de operación tiene los siguientes parámetros:

`thingName` (Python: `thing_name`)  <a name="ipc-local-shadows-thing-name"></a>
El nombre del objeto.  
Tipo: `string`

`shadowName` (Python: `shadow_name`)  <a name="ipc-local-shadows-shadow-name"></a>
El nombre de la sombra. Para especificar la sombra clásica del objeto, defina este parámetro en una cadena vacía (`""`).  
El AWS IoT Greengrass servicio usa el `AWSManagedGreengrassV2Deployment` nombre shadow para administrar las implementaciones que se dirigen a dispositivos principales individuales. Esta sombra denominada está reservada para que la utilice el AWS IoT Greengrass servicio. No actualice ni elimine esta sombra con nombre.
Tipo: `string`

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

Esta respuesta de operación contiene la siguiente información:

`payload`  
Un documento de estado de respuesta vacío.

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

Esta operación puede devolver los siguientes errores.

`InvalidArgumentsError`  <a name="ipc-invalidargumentserror"></a>
<a name="ipc-invalidargumentserror-para"></a>El servicio de sombra local no puede validar los parámetros de la solicitud. Esto puede ocurrir si la solicitud contiene un formato incorrecto de JSON o caracteres no admitidos. 

`ResourceNotFoundError`  <a name="ipc-resourcenotfounderror"></a>
No se encuentra el documento de sombra local solicitado.

`ServiceError`  <a name="ipc-serviceerror"></a>
Se ha producido un error de servicio interno o la cantidad de solicitudes al servicio de IPC ha superado los límites especificados en los parámetros de configuración de `maxLocalRequestsPerSecondPerThing` y `maxTotalLocalRequestsRate` del componente del administrador de sombra.

`UnauthorizedError`  <a name="ipc-unauthorizederror"></a>
La política de autorización del componente no incluye los permisos necesarios para esta operación.

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

En los ejemplos siguientes, se muestra cómo llamar a esta operación en código de componente personalizado.

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

**Example Ejemplo: eliminar una sombra de objeto**  
En este ejemplo, se utiliza una `IPCUtils` clase para crear una conexión con el servicio AWS IoT Greengrass Core IPC. Para obtener más información, consulte [Conéctese al AWS IoT Greengrass servicio Core 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 Ejemplo: eliminar una sombra de objeto**  

```
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 Ejemplo: eliminar una sombra de objeto**  

```
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>

Enumera las sombras con nombre del objeto especificado.

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

Esta solicitud de operación tiene los siguientes parámetros:

`thingName` (Python: `thing_name`)  <a name="ipc-local-shadows-thing-name"></a>
El nombre del objeto.  
Tipo: `string`

`pageSize` (Python: `page_size`)  
(Opcional) La cantidad de nombres de sombra que se devuelve en cada llamada.   
Tipo: `integer`  
Predeterminado: 25  
Máximo: 100

`nextToken` (Python: `next_token`)  
(Opcional) El token para recuperar el siguiente grupo de resultados. Este valor se devuelve en los resultados paginados y se utiliza en la llamada que devuelve la página siguiente.  
Tipo: `string`

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

Esta respuesta de operación contiene la siguiente información:

`results`  
La lista de sombras con nombre.   
Tipo: `array`

`timestamp`  
(Opcional) La fecha y hora en que se generó la respuesta.   
Tipo: `integer`

`nextToken` (Python: `next_token`)  
(Opcional) El valor del token que se utilizará en las solicitudes paginadas para recuperar la siguiente página de la secuencia. Este token no está presente cuando no hay más sombras con nombre que devolver.  
Tipo: `string`  
Si el tamaño de página solicitado coincide exactamente con la cantidad de nombres de sombra de la respuesta, entonces este token está presente; sin embargo, cuando se usa, devuelve una lista vacía.

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

Esta operación puede devolver los siguientes errores.

`InvalidArgumentsError`  <a name="ipc-invalidargumentserror"></a>
<a name="ipc-invalidargumentserror-para"></a>El servicio de sombra local no puede validar los parámetros de la solicitud. Esto puede ocurrir si la solicitud contiene un formato incorrecto de JSON o caracteres no admitidos. 

`ResourceNotFoundError`  <a name="ipc-resourcenotfounderror"></a>
No se encuentra el documento de sombra local solicitado.

`ServiceError`  <a name="ipc-serviceerror"></a>
Se ha producido un error de servicio interno o la cantidad de solicitudes al servicio de IPC ha superado los límites especificados en los parámetros de configuración de `maxLocalRequestsPerSecondPerThing` y `maxTotalLocalRequestsRate` del componente del administrador de sombra.

`UnauthorizedError`  <a name="ipc-unauthorizederror"></a>
La política de autorización del componente no incluye los permisos necesarios para esta operación.

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

En los ejemplos siguientes, se muestra cómo llamar a esta operación en código de componente personalizado.

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

**Example Ejemplo: enumerar las sombras con nombre de un objeto**  
En este ejemplo, se utiliza una `IPCUtils` clase para crear una conexión con el servicio AWS IoT Greengrass Core IPC. Para obtener más información, consulte [Conéctese al AWS IoT Greengrass servicio Core 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 Ejemplo: enumerar las sombras con nombre de un objeto**  

```
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 Ejemplo: enumerar las sombras con nombre de un objeto**  

```
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();
```

------

# Administre las implementaciones y los componentes locales
<a name="ipc-local-deployments-components"></a>

**nota**  
Esta característica está disponible para la versión 2.6.0 y versiones posteriores del [componente núcleo de Greengrass](greengrass-nucleus-component.md).

Utilice el servicio CLI IPC de Greengrass para administrar las implementaciones locales y los componentes de Greengrass en el dispositivo principal.

Para utilizar estas operaciones de IPC, incluya la versión 2.6.0 o posterior del [componente CLI de Greengrass](greengrass-cli-component.md) como dependencia en su componente personalizado. A continuación, puede utilizar las operaciones de IPC en sus componentes personalizados para hacer lo siguiente:
+ Cree implementaciones locales para modificar y configurar los componentes de Greengrass en el dispositivo principal.
+ Reinicie y detenga los componentes de Greengrass en el dispositivo principal.
+ Genere una contraseña que pueda usar para iniciar sesión en la [consola de depuración local](local-debug-console-component.md).

**Topics**
+ [Versiones mínimas de SDK](#ipc-local-deployments-components-sdk-versions)
+ [Autorización](#ipc-local-deployments-components-authorization)
+ [CreateLocalDeployment](#ipc-operation-createlocaldeployment)
+ [ListLocalDeployments](#ipc-operation-listlocaldeployments)
+ [GetLocalDeploymentStatus](#ipc-operation-getlocaldeploymentstatus)
+ [ListComponents](#ipc-operation-listcomponents)
+ [GetComponentDetails](#ipc-operation-getcomponentdetails)
+ [RestartComponent](#ipc-operation-restartcomponent)
+ [StopComponent](#ipc-operation-stopcomponent)
+ [CreateDebugPassword](#ipc-operation-createdebugpassword)

## Versiones mínimas de SDK
<a name="ipc-local-deployments-components-sdk-versions"></a>

En la siguiente tabla se enumeran las versiones mínimas de las SDK para dispositivos con AWS IoT que debe utilizar para interactuar con el servicio CLI IPC de Greengrass.


| SDK | Versión mínima | 
| --- | --- | 
|  [SDK para dispositivos con AWS IoT para Java v2](https://github.com/aws/aws-iot-device-sdk-java-v2)  |  Versión 1.2.10  | 
|  [SDK para dispositivos con AWS IoT para Python v2](https://github.com/aws/aws-iot-device-sdk-python-v2)  |  Versión 1.5.3  | 
|  [SDK para dispositivos con AWS IoT para C\$1\$1 v2](https://github.com/aws/aws-iot-device-sdk-cpp-v2)  |  Versión 1.17.0  | 
|  [SDK para dispositivos con AWS IoT para JavaScript v2](https://github.com/aws/aws-iot-device-sdk-js-v2)  |  Versión 1.12.0  | 

## Autorización
<a name="ipc-local-deployments-components-authorization"></a>

Para utilizar el servicio CLI IPC de Greengrass en un componente personalizado, debe definir políticas de autorización que permitan a su componente administrar las implementaciones y los componentes locales. Para obtener información sobre cómo definir las políticas de autorización, consulte [Autorización de los componentes para realizar operaciones de IPC](interprocess-communication.md#ipc-authorization-policies).

Las políticas de autorización de la CLI de Greengrass tienen las siguientes propiedades.

**Identificador de servicio IPC:** `aws.greengrass.Cli`


| Operación | Description (Descripción) | Recursos | 
| --- | --- | --- | 
|  `aws.greengrass#CreateLocalDeployment`  |  Permite que un componente cree una implementación local en el dispositivo principal.  |  `*`  | 
|  `aws.greengrass#ListLocalDeployments`  |  Permite que un componente enumere las implementaciones locales en el dispositivo principal.  |  `*`  | 
|  `aws.greengrass#GetLocalDeploymentStatus`  |  Permite que un componente obtenga el estado de una implementación local en el dispositivo principal.  |  Un ID de implementación local, o `*`, que permita el acceso a todas las implementaciones locales.  | 
|  `aws.greengrass#ListComponents`  |  Permite que un componente enumere los componentes del dispositivo principal.  |  `*`  | 
|  `aws.greengrass#GetComponentDetails`  |  Permite que un componente obtenga detalles sobre un componente del dispositivo principal.  |  Un nombre de componente, por ejemplo: `com.example.HelloWorld` o `*`, que permita el acceso a todos los componentes.  | 
|  `aws.greengrass#RestartComponent`  |  Permite que un componente reinicie un componente del dispositivo principal.  |  Un nombre de componente, por ejemplo: `com.example.HelloWorld` o `*`, que permita el acceso a todos los componentes.  | 
|  `aws.greengrass#StopComponent`  |  Permite que un componente detenga a un componente del dispositivo principal.  |  Un nombre de componente, por ejemplo: `com.example.HelloWorld` o `*`, que permita el acceso a todos los componentes.  | 
|  `aws.greengrass#CreateDebugPassword`  |  Permite que un componente genere una contraseña para iniciar sesión en el [componente de la consola de depuración local](local-debug-console-component.md).  |  `*`  | 

**Example Ejemplo de política de autorización**  
Los siguientes ejemplos de políticas de autorización permiten a un componente crear implementaciones locales, ver todas las implementaciones y componentes locales, además de reiniciar y detener un componente denominado `com.example.HelloWorld`.  

```
{
  "accessControl": {
    "aws.greengrass.Cli": {
      "com.example.MyLocalManagerComponent:cli:1": {
        "policyDescription": "Allows access to create local deployments and view deployments and components.",
        "operations": [
          "aws.greengrass#CreateLocalDeployment",
          "aws.greengrass#ListLocalDeployments",
          "aws.greengrass#GetLocalDeploymentStatus",
          "aws.greengrass#ListComponents",
          "aws.greengrass#GetComponentDetails"
        ],
        "resources": [
          "*"
        ]
      }
    },
    "aws.greengrass.Cli": {
      "com.example.MyLocalManagerComponent:cli:2": {
        "policyDescription": "Allows access to restart and stop the Hello World component.",
        "operations": [
          "aws.greengrass#RestartComponent",
          "aws.greengrass#StopComponent"
        ],
        "resources": [
          "com.example.HelloWorld"
        ]
      }
    }
  }
}
```

## CreateLocalDeployment
<a name="ipc-operation-createlocaldeployment"></a>

Cree o actualice una implementación local mediante recetas de componentes, artefactos y argumentos de tiempo de ejecución específicos.

Esta operación ofrece la misma funcionalidad que el [comando crear implementación](gg-cli-deployment.md#deployment-create) de la CLI de Greengrass.

### Solicitud
<a name="ipc-operation-createlocaldeployment-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`recipeDirectoryPath` (Python: `recipe_directory_path`)  
(Opcional) La ruta absoluta a la carpeta que contiene los archivos de recetas de los componentes.

`artifactDirectoryPath` (Python: `artifact_directory_path`)  
(Opcional) La ruta absoluta a la carpeta que contiene los archivos de artefactos que se incluirán en la implementación. La carpeta de artefactos debe contener la siguiente estructura de carpetas:  

```
/path/to/artifact/folder/component-name/component-version/artifacts
```

`rootComponentVersionsToAdd` (Python: `root_component_versions_to_add`)  
(Opcional) Las versiones de los componentes que se van a instalar en el dispositivo principal. Este objeto, `ComponentToVersionMap`, es un mapa que contiene los siguientes pares clave-valor:    
`key`  
El nombre del componente.  
`value`  
Esta es la versión del componente.

`rootComponentsToRemove` (Python: `root_components_to_remove`)  
(Opcional) Los componentes que se van a desinstalar del dispositivo principal. Especifique una lista en la que cada entrada sea el nombre de un componente.

`componentToConfiguration` (Python: `component_to_configuration`)  
(opcional) La configuración se actualiza para cada componente en la implementación. Este objeto, `ComponentToConfiguration`, es un mapa que contiene los siguientes pares clave-valor:    
`key`  
El nombre del componente.  
`value`  
La configuración actualiza el objeto JSON para el componente. El objeto JSON debe incluir el siguiente formato.  

```
{ 
  "MERGE": {
    "config-key": "config-value"
  },
  "RESET": [
    "path/to/reset/"
  ]
}
```
Para obtener más información acerca de las actualizaciones de configuración, consulte [Actualización de las configuraciones de los componentes](update-component-configurations.md).

`componentToRunWithInfo` (Python: `component_to_run_with_info`)  
(Opcional) La configuración del tiempo de ejecución de cada componente de la implementación. Esta configuración incluye el usuario del sistema que es propietario de los procesos de cada componente y los límites del sistema que se aplican a cada componente. Este objeto, `ComponentToRunWithInfo`, es un mapa que contiene los siguientes pares clave-valor:    
`key`  
El nombre del componente.  
`value`  
La configuración de tiempo de ejecución del componente. Si omite un parámetro de configuración del tiempo de ejecución, el software AWS IoT Greengrass principal utilizará los valores predeterminados que configure en el núcleo de [Greengrass](greengrass-nucleus-component.md). Este objeto, `RunWithInfo`, contiene la siguiente información:    
`posixUser` (Python: `posix_user`)  
(Opcional) <a name="deployment-posix-user-definition"></a>El usuario del sistema POSIX y, opcionalmente, el grupo que se utilizarán para ejecutarse en dispositivos principales de Linux. El usuario y el grupo, si se especifica, deben existir en cada dispositivo principal de Linux. Especifique el usuario y el grupo separados por dos puntos (`:`) con el siguiente formato: `user:group`. El grupo es opcional. Si no especifica un grupo, el software AWS IoT Greengrass Core utiliza el grupo principal para el usuario. Para obtener más información, consulte [Configuración del usuario que ejecuta los componentes](configure-greengrass-core-v2.md#configure-component-user).   
`windowsUser` (Python: `windows_user`)  
(Opcional) <a name="deployment-windows-user-definition"></a>El usuario de Windows que se utilizará para ejecutar este componente en los dispositivos principales de Windows. El usuario debe estar en todos los dispositivos principales de Windows y su nombre y contraseña deben almacenarse en la instancia del administrador de credenciales de la LocalSystem cuenta. Para obtener más información, consulte [Configuración del usuario que ejecuta los componentes](configure-greengrass-core-v2.md#configure-component-user).   
`systemResourceLimits` (Python: `system_resource_limits`)  
(Opcional) <a name="deployment-system-resource-limits-definition"></a>Los límites de recursos del sistema que se aplicarán a los procesos de este componente. Puede aplicar límites de recursos del sistema a los componentes de Lambda genéricos y no contenerizados. Para obtener más información, consulte [Configuración de los límites de recursos del sistema para los componentes](configure-greengrass-core-v2.md#configure-component-system-resource-limits).   
AWS IoT Greengrass actualmente no admite esta función en los dispositivos principales de Windows.   
Este objeto, `SystemResourceLimits`, contiene la siguiente información:    
`cpus`  
(Opcional) <a name="system-resource-limits-cpu-definition-this"></a>La cantidad máxima de tiempo de CPU que los procesos de un componente pueden utilizar en el dispositivo principal. El tiempo total de CPU de un dispositivo principal equivale a la cantidad de núcleos de CPU del dispositivo. Por ejemplo, en un dispositivo principal con 4 núcleos de CPU, puede establecer este valor en `2` para limitar los procesos del componente al 50 % de uso de cada núcleo de CPU. En un dispositivo con 1 núcleo de CPU, puede establecer este valor en `0.25` para limitar los procesos del componente al 25 % de uso de la CPU. Si establece este valor en un número superior al número de núcleos de la CPU, el software AWS IoT Greengrass Core no limita el uso de la CPU del componente.   
`memory`  
(Opcional) <a name="system-resource-limits-memory-definition-this"></a>La cantidad máxima de RAM, expresada en kilobytes, que los procesos de un componente pueden utilizar en el dispositivo principal. 

`groupName` (Python: `group_name`)  
(Opcional) El nombre del grupo de elementos al que se va a dirigir esta implementación.

### Respuesta
<a name="ipc-operation-createlocaldeployment-response"></a>

Esta respuesta de operación contiene la siguiente información:

`deploymentId` (Python: `deployment_id`)  
El ID de la implementación local que creó la solicitud.

## ListLocalDeployments
<a name="ipc-operation-listlocaldeployments"></a>

Obtiene el estado de las últimas 10 implementaciones locales.

Esta operación ofrece la misma funcionalidad que el [comando enumerar implementación](gg-cli-deployment.md#deployment-list) de la CLI de Greengrass.

### Solicitud
<a name="ipc-operation-listlocaldeployments-request"></a>

Esta solicitud de la operación no tiene parámetros.

### Respuesta
<a name="ipc-operation-listlocaldeployments-response"></a>

Esta respuesta de operación contiene la siguiente información:

`localDeployments` (Python: `local_deployments`)  
La lista de implementaciones locales. Cada objeto de esta lista es un objeto `LocalDeployment` que contiene la siguiente información:  <a name="ipc-local-deployment-object-shape"></a>  
`deploymentId` (Python: `deployment_id`)  
El ID de la implementación local.  
`status`  
El estado de la implementación local. Esta enumeración, `DeploymentStatus`, tiene los siguientes valores:  
+ `QUEUED`
+ `IN_PROGRESS`
+ `SUCCEEDED`
+ `FAILED`

## GetLocalDeploymentStatus
<a name="ipc-operation-getlocaldeploymentstatus"></a>

Obtiene el estado de una implementación local.

Esta operación ofrece la misma funcionalidad que el [comando estado de implementación](gg-cli-deployment.md#deployment-status) de la CLI de Greengrass.

### Solicitud
<a name="ipc-operation-getlocaldeploymentstatus-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`deploymentId` (Python: `deployment_id`)  
El ID de la implementación local que se va a obtener.

### Respuesta
<a name="ipc-operation-getlocaldeploymentstatus-response"></a>

Esta respuesta de operación contiene la siguiente información:

`deployment`  
La implementación local. Este objeto, `LocalDeployment`, contiene la siguiente información:  <a name="ipc-local-deployment-object-shape"></a>  
`deploymentId` (Python: `deployment_id`)  
El ID de la implementación local.  
`status`  
El estado de la implementación local. Esta enumeración, `DeploymentStatus`, tiene los siguientes valores:  
+ `QUEUED`
+ `IN_PROGRESS`
+ `SUCCEEDED`
+ `FAILED`

## ListComponents
<a name="ipc-operation-listcomponents"></a>

Obtiene el nombre, la versión, el estado y la configuración de cada componente raíz del dispositivo principal. Un *componente raíz* es un componente que se especifica en una implementación. Esta respuesta no incluye los componentes que se instalan como dependencias de otros componentes.

Esta operación ofrece la misma funcionalidad que el [comando component list](gg-cli-component.md#component-list) de la CLI de Greengrass.

### Solicitud
<a name="ipc-operation-listcomponents-request"></a>

Esta solicitud de la operación no tiene parámetros.

### Respuesta
<a name="ipc-operation-listcomponents-response"></a>

Esta respuesta de operación contiene la siguiente información:

`components`  
La lista de componentes raíz del dispositivo principal. Cada objeto de esta lista es un objeto `ComponentDetails` que contiene la siguiente información:  <a name="ipc-component-details-object-shape"></a>  
`componentName` (Python: `component_name`)  
El nombre del componente.  
`version`  
Esta es la versión del componente.  
`state`  
El estado del componente. Este estado puede ser uno de los siguientes:  
+ `BROKEN`
+ `ERRORED`
+ `FINISHED`
+ `INSTALLED`
+ `NEW`
+ `RUNNING`
+ `STARTING`
+ `STOPPING`  
`configuration`  
La configuración del componente como objeto JSON.

## GetComponentDetails
<a name="ipc-operation-getcomponentdetails"></a>

Obtiene la versión, el estado y la configuración de un componente del dispositivo principal.

Esta operación ofrece la misma funcionalidad que el [comando detallar implementación](gg-cli-component.md#component-details) de la CLI de Greengrass.

### Solicitud
<a name="ipc-operation-getcomponentdetails-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`componentName` (Python: `component_name`)  
El nombre del componente que se obtendrá.

### Respuesta
<a name="ipc-operation-getcomponentdetails-response"></a>

Esta respuesta de operación contiene la siguiente información:

`componentDetails` (Python: `component_details`)  
Los detalles del componente. Este objeto, `ComponentDetails`, contiene la siguiente información:  <a name="ipc-component-details-object-shape"></a>  
`componentName` (Python: `component_name`)  
El nombre del componente.  
`version`  
Esta es la versión del componente.  
`state`  
El estado del componente. Este estado puede ser uno de los siguientes:  
+ `BROKEN`
+ `ERRORED`
+ `FINISHED`
+ `INSTALLED`
+ `NEW`
+ `RUNNING`
+ `STARTING`
+ `STOPPING`  
`configuration`  
La configuración del componente como objeto JSON.

## RestartComponent
<a name="ipc-operation-restartcomponent"></a>

Reinicia un componente en el dispositivo principal.

**nota**  
Si bien puede reiniciar cualquier componente, le recomendamos que reinicie solo los [componentes genéricos](develop-greengrass-components.md#component-types).

Esta operación ofrece la misma funcionalidad que el [comando reiniciar implementación](gg-cli-component.md#component-restart) de la CLI de Greengrass.

### Solicitud
<a name="ipc-operation-restartcomponent-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`componentName` (Python: `component_name`)  
El nombre del componente.

### Respuesta
<a name="ipc-operation-restartcomponent-response"></a>

Esta respuesta de operación contiene la siguiente información:

`restartStatus` (Python: `restart_status`)  
El estado de la solicitud reiniciada. El estado de la solicitud puede ser uno de los siguientes:  
+ `SUCCEEDED`
+ `FAILED`

`message`  
Un mensaje sobre por qué el componente no se pudo reiniciar, si la solicitud falló.

### Ejemplos
<a name="ipc-operation-restartcomponent-examples"></a>

En los ejemplos siguientes, se muestra cómo llamar a esta operación en código de componente personalizado.

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

**Example Ejemplo: reiniciar un componente**  

```
use gg_sdk::Sdk;

fn main() {
    let sdk = Sdk::init();
    sdk.connect().expect("Failed to establish IPC connection");

    let component_name = "com.example.HelloWorld";

    sdk.restart_component(component_name)
        .expect("Failed to restart component");

    println!("Successfully requested restart for component: {component_name}");
}
```

------
#### [ C ]

**Example Ejemplo: reiniciar un componente**  

```
#include <gg/error.h>
#include <gg/ipc/client.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);
    }

    GgBuffer component_name = GG_STR("com.example.HelloWorld");

    err = ggipc_restart_component(component_name);
    if (err != GG_ERR_OK) {
        fprintf(
            stderr,
            "Failed to restart component: %.*s\n",
            (int) component_name.len,
            component_name.data
        );
        exit(-1);
    }

    printf(
        "Successfully requested restart for component: %.*s\n",
        (int) component_name.len,
        component_name.data
    );
}
```

------
#### [ C\$1\$1 (Component SDK) ]

**Example Ejemplo: reiniciar un componente**  

```
#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);
    }

    std::string_view component_name = "com.example.HelloWorld";

    error = client.restart_component(component_name);
    if (error) {
        std::cerr << "Failed to restart component: " << component_name << "\n";
        exit(-1);
    }

    std::cout << "Successfully requested restart for component: "
              << component_name << "\n";
}
```

------

## StopComponent
<a name="ipc-operation-stopcomponent"></a>

Detiene los procesos de un componente en el dispositivo principal.

**nota**  
Si bien puede detener cualquier componente, le recomendamos que detenga solo los [componentes genéricos](develop-greengrass-components.md#component-types).

Esta operación ofrece la misma funcionalidad que el [comando detener implementación](gg-cli-component.md#component-stop) de la CLI de Greengrass.

### Solicitud
<a name="ipc-operation-stopcomponent-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`componentName` (Python: `component_name`)  
El nombre del componente.

### Respuesta
<a name="ipc-operation-stopcomponent-response"></a>

Esta respuesta de operación contiene la siguiente información:

`stopStatus` (Python: `stop_status`)  
El estado de la solicitud de detención. El estado de la solicitud puede ser uno de los siguientes:  
+ `SUCCEEDED`
+ `FAILED`

`message`  
Un mensaje sobre por qué el componente no se pudo detener, si la solicitud falló.

## CreateDebugPassword
<a name="ipc-operation-createdebugpassword"></a>

Genera una contraseña asignada al azar que puede usar para iniciar sesión en el [componente de la consola de depuración local](local-debug-console-component.md). La contraseña caduca 8 horas después de generarse.

Esta operación proporciona la misma funcionalidad que el [get-debug-password comando](gg-cli-get-debug-password.md) de la CLI de Greengrass.

### Solicitud
<a name="ipc-operation-createdebugpassword-request"></a>

Esta solicitud de la operación no tiene parámetros.

### Respuesta
<a name="ipc-operation-createdebugpassword-response"></a>

Esta respuesta de operación contiene la siguiente información:

`username`  
El nombre de usuario que se utilizará para iniciar sesión.

`password`  
La contraseña que se utilizará para iniciar sesión.

`passwordExpiration` (Python: `password_expiration`)  
La hora en que caduca la contraseña.

`certificateSHA256Hash` (Python: `certificate_sha256_hash`)  
La huella digital SHA-256 del certificado autofirmado que utiliza la consola de depuración local cuando HTTPS está activado. Cuando abra la consola de depuración local, utilice esta huella digital para comprobar que el certificado es legítimo y que la conexión es segura.

`certificateSHA1Hash` (Python: `certificate_sha1_hash`)  
La huella digital SHA-1 del certificado autofirmado que utiliza la consola de depuración local cuando HTTPS está activado. Cuando abra la consola de depuración local, utilice esta huella digital para comprobar que el certificado es legítimo y que la conexión es segura.

# Autenticación y autorización de los dispositivos de cliente
<a name="ipc-client-device-auth"></a>

**nota**  
Esta característica está disponible para la versión 2.6.0 y versiones posteriores del [componente núcleo de Greengrass](greengrass-nucleus-component.md).

Utilice el servicio IPC de autenticación de dispositivos de cliente para desarrollar un componente de agente local personalizado al que puedan conectarse los dispositivos IoT locales, como los dispositivos de cliente.

Para utilizar estas operaciones de IPC, incluya la versión 2.2.0 o posterior del [componente de autorización del dispositivo de cliente](client-device-auth-component.md) como dependencia en su componente personalizado. A continuación, puede utilizar las operaciones de IPC en sus componentes personalizados para hacer lo siguiente:
+ Compruebe la identidad de los dispositivos de cliente que se conectan al dispositivo principal.
+ Cree una sesión para que un dispositivo de cliente se conecte al dispositivo principal.
+ Compruebe si un dispositivo de cliente tiene permiso para realizar una acción.
+ Reciba una notificación cuando el certificado del servidor del dispositivo principal cambie.

**Topics**
+ [Versiones mínimas de SDK](#ipc-client-device-auth-sdk-versions)
+ [Autorización](#ipc-client-device-auth-authorization)
+ [VerifyClientDeviceIdentity](#ipc-operation-verifyclientdeviceidentity)
+ [GetClientDeviceAuthToken](#ipc-operation-getclientdeviceauthtoken)
+ [AuthorizeClientDeviceAction](#ipc-operation-authorizeclientdeviceaction)
+ [SubscribeToCertificateUpdates](#ipc-operation-subscribetocertificateupdates)

## Versiones mínimas de SDK
<a name="ipc-client-device-auth-sdk-versions"></a>

En la siguiente tabla se enumeran las versiones mínimas del SDK para dispositivos con AWS IoT que debe utilizar para interactuar con el servicio IPC de autenticación del dispositivo cliente.


| SDK | Versión mínima | 
| --- | --- | 
|  [SDK para dispositivos con AWS IoT para Java v2](https://github.com/aws/aws-iot-device-sdk-java-v2)  |  Versión 1.9.3  | 
|  [SDK para dispositivos con AWS IoT para Python v2](https://github.com/aws/aws-iot-device-sdk-python-v2)  |  Versión 1.11.3  | 
|  [SDK para dispositivos con AWS IoT para C\$1\$1 v2](https://github.com/aws/aws-iot-device-sdk-cpp-v2)  |  Versión 1.18.3  | 
|  [SDK para dispositivos con AWS IoT para JavaScript v2](https://github.com/aws/aws-iot-device-sdk-js-v2)  |  Versión 1.12.0  | 

## Autorización
<a name="ipc-client-device-auth-authorization"></a>

Para utilizar el servicio IPC de autenticación del dispositivo de cliente en un componente personalizado, debe definir políticas de autorización que permitan a su componente realizar estas operaciones. Para obtener información sobre cómo definir las políticas de autorización, consulte [Autorización de los componentes para realizar operaciones de IPC](interprocess-communication.md#ipc-authorization-policies).

Las políticas de autorización para la autenticación y autorización de los dispositivos de cliente tienen las siguientes propiedades.

**Identificador de servicio IPC:** `aws.greengrass.clientdevices.Auth`


| Operación | Description (Descripción) | Recursos | 
| --- | --- | --- | 
|  `aws.greengrass#VerifyClientDeviceIdentity`  |  Permite que un componente verifique la identidad de un dispositivo de cliente.  |  `*`  | 
|  `aws.greengrass#GetClientDeviceAuthToken`  |  Permite que un componente valide las credenciales de un dispositivo de cliente y cree una sesión para ese dispositivo de cliente.  |  `*`  | 
|  `aws.greengrass#AuthorizeClientDeviceAction`  |  Permite que un componente verifique si un dispositivo de cliente tiene permiso para realizar una acción.  |  `*`  | 
|  `aws.greengrass#SubscribeToCertificateUpdates`  |  Permite que un componente reciba notificaciones cuando el certificado del servidor del dispositivo principal rota.  |  `*`  | 
|  `*`  |  Permite que un componente realice todas las operaciones del servicio IPC de autenticación del dispositivo de cliente.  |  `*`  | 

### Ejemplos de políticas de autorización
<a name="ipc-client-device-auth-authorization-policy-examples"></a>

Puede consultar el siguiente ejemplo de política de autorización con el fin de configurar las políticas de autorización para sus componentes.

**Example Ejemplo de política de autorización**  
El siguiente ejemplo de política de autorización permite a un componente realizar todas las operaciones de IPC de autenticación del dispositivo de cliente.  

```
{
  "accessControl": {
    "aws.greengrass.clientdevices.Auth": {
      "com.example.MyLocalBrokerComponent:clientdevices:1": {
        "policyDescription": "Allows access to authenticate and authorize client devices.",
        "operations": [
          "aws.greengrass#VerifyClientDeviceIdentity",
          "aws.greengrass#GetClientDeviceAuthToken",
          "aws.greengrass#AuthorizeClientDeviceAction",
          "aws.greengrass#SubscribeToCertificateUpdates"
        ],
        "resources": [
          "*"
        ]
      }
    }
  }
}
```

## VerifyClientDeviceIdentity
<a name="ipc-operation-verifyclientdeviceidentity"></a>

Compruebe la identidad de un dispositivo de cliente. Esta operación verifica si el dispositivo cliente es válido AWS IoT .

### Solicitud
<a name="ipc-operation-verifyclientdeviceidentity-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`credential`  
Las credenciales del dispositivo de cliente. Este objeto, `ClientDeviceCredential`, contiene la siguiente información:    
`clientDeviceCertificate` (Python: `client_device_certificate`)  
El certificado de dispositivo X.509 del dispositivo de cliente.

### Respuesta
<a name="ipc-operation-verifyclientdeviceidentity-response"></a>

Esta respuesta de operación contiene la siguiente información:

`isValidClientDevice` (Python: `is_valid_client_device`)  
Si la identidad del dispositivo de cliente es válida.

## GetClientDeviceAuthToken
<a name="ipc-operation-getclientdeviceauthtoken"></a>

Valida las credenciales de un dispositivo de cliente y crea una sesión para el dispositivo de cliente. Esta operación devuelve un token de sesión que puede usar en solicitudes posteriores para [autorizar acciones del dispositivo de cliente](#ipc-operation-authorizeclientdeviceaction).

Para conectar correctamente un dispositivo de cliente, el [componente de autenticación del dispositivo de cliente](client-device-auth-component.md#client-device-auth-component-configuration) debe conceder el permiso `mqtt:connect` para el ID de cliente que utiliza el dispositivo de cliente.

### Solicitud
<a name="ipc-operation-getclientdeviceauthtoken-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`credential`  
Las credenciales del dispositivo de cliente. Este objeto, `CredentialDocument`, contiene la siguiente información:    
`mqttCredential` (Python: `mqtt_credential`)  
Las credenciales MQTT del dispositivo de cliente. Especifique el ID de cliente y el certificado que el dispositivo de cliente utiliza para conectarse. Este objeto, `MQTTCredential`, contiene la siguiente información:    
`clientId` (Python: `client_id`)  
El ID de cliente que se utilizará para conectarse.  
`certificatePem` (Python: `certificate_pem`)  
El certificado del dispositivo X.509 que se utilizará para conectarse.  
`username`  
En la actualidad, esta propiedad no se utiliza.  
`password`  
En la actualidad, esta propiedad no se utiliza.

### Respuesta
<a name="ipc-operation-getclientdeviceauthtoken-response"></a>

Esta respuesta de operación contiene la siguiente información:

`clientDeviceAuthToken` (Python: `client_device_auth_token`)  
El token de sesión del dispositivo de cliente. Puede usar este token de sesión en solicitudes posteriores para autorizar las acciones de este dispositivo de cliente.

## AuthorizeClientDeviceAction
<a name="ipc-operation-authorizeclientdeviceaction"></a>

Compruebe si un dispositivo de cliente tiene permiso para realizar una acción en un recurso. *Las políticas de autorización de los dispositivos de cliente* especifican los permisos que los dispositivos de cliente pueden realizar mientras están conectados a un dispositivo principal. Las políticas de autorización de los dispositivos de cliente se definen al configurar el [componente de autenticación del dispositivo de cliente](client-device-auth-component.md#client-device-auth-component-configuration).

### Solicitud
<a name="ipc-operation-authorizeclientdeviceaction-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`clientDeviceAuthToken` (Python: `client_device_auth_token`)  
El token de sesión del dispositivo de cliente.

`operation`  
La operación que se va a autorizar.

`resource`  
El recurso en el que el dispositivo de cliente realiza la operación.

### Respuesta
<a name="ipc-operation-authorizeclientdeviceaction-response"></a>

Esta respuesta de operación contiene la siguiente información:

`isAuthorized` (Python: `is_authorized`)  
Si el dispositivo de cliente está autorizado a realizar la operación en el recurso.

## SubscribeToCertificateUpdates
<a name="ipc-operation-subscribetocertificateupdates"></a>

Suscríbase para recibir el nuevo certificado de servidor del dispositivo principal cada vez que vaya rotando. Cuando el certificado de servidor rota, los agentes deben volver a cargarlo con el nuevo certificado de servidor.

De forma predeterminada, el [componente de autenticación del dispositivo de cliente](client-device-auth-component.md) rota los certificados de servidor cada 7 días. Puede configurar el intervalo de rotación entre 2 y 10 días.

<a name="ipc-subscribe-operation-note"></a>Esta es una operación de suscripción en la que se suscribe a un flujo de mensajes de eventos. Para usar esta operación, defina un identificador de respuesta de flujo con funciones que gestionen los mensajes de eventos, los errores y el cierre del flujo. Para obtener más información, consulte [Suscripción a los flujos de eventos de IPC](interprocess-communication.md#ipc-subscribe-operations).

**Tipo de mensaje del evento:** `CertificateUpdateEvent`

### Solicitud
<a name="ipc-operation-subscribetocertificateupdates-request"></a>

Esta solicitud de operación tiene los siguientes parámetros:

`certificateOptions` (Python: `certificate_options`)  
Los tipos de actualizaciones de certificados a las que debe suscribirse. Este objeto, `CertificateOptions`, contiene la siguiente información:    
`certificateType` (Python: `certificate_type`)  
El tipo de actualizaciones de certificado a las que se debe suscribir. Elija la opción siguiente:  
+ `SERVER`

### Respuesta
<a name="ipc-operation-subscribetocertificateupdates-response"></a>

Esta respuesta de operación contiene la siguiente información:

`messages`  
El flujo de mensajes. Este objeto, `CertificateUpdateEvent`, contiene la siguiente información:    
`certificateUpdate` (Python: `certificate_update`)  
La información acerca del nuevo certificado. Este objeto, `CertificateUpdate`, contiene la siguiente información:    
`certificate`  
El certificado.  
`privateKey` (Python: `private_key`)  
La clave privada del certificado.  
`publicKey` (Python: `public_key`)  
La clave pública del certificado.  
`caCertificates` (Python: `ca_certificates`)  
La lista de los certificados de la autoridad de certificación (CA) de la cadena de certificados de la CA del certificado.