asyncapi: 3.0.0
id: urn:ie:ai:assetmanager
info:
  title: AI Asset Manager Cloud API
  version: "2.3.0"
  description: |
    AI Asset Manager Cloud API defines channels and messages for cloud clients of AI Asset Manager.

    **General**
    - All channels (topics) listed in this document are prefixed with a server dependent part marked as `{channelPrefix}`.
    The actual value of the {channelPrefix} is specified under the "URL variables" section of the given server.

    **Publish Query requests, Commands**
    - AI Asset Manager subscribes to a (single) wild card channel `{channelPrefix}/messages/devicebound/#` in order to receive
    all messages published by Producers.
    - Actual channels contain a Property Bag in last section of the channel,
    composed of one or more key-value pairs i.e. `{channelPrefix}/messages/devicebound/{property_bag}`.
    - Property Bag is formed as: `RFC2396-encoded(<PropertyName1>)=RFC2396-encoded(<PropertyValue1>)&RFC2396-encoded(<PropertyName2>)=RFC2396-encoded(<PropertyValue2>)...`
    Each property (key) is allowed to have a single value.
    Example: {channelPrefix}/messages/devicebound/resourceType=deployment&operation=list
    - Topics listed below depicts the minimum set of key-value pairs. AI Asset Manager handles further not listed pairs gracefully
    (i.e. ignores them).
    - AI Asset Manager distinguishes received messages by checking received key-value pairs against
    pairs described in this document.
    - The channel sturcture described below is adapted to the requirements and capabilities of Azure IoT Hub.
    In case of sending cloud-to-device messages from an IoT hub, parameters of the property bag can be set as user-defined properties of the message.

    **Subscribe to (Reply) channels for receiving messages emitted (in response to requests)**
    - AI Asset Manager publishes all messages on a wildcard channel `{channelPrefix}/messages/events/+`
    - Actual channels contain a Property Bag in last section of the channel,
    composed of one or more key-value pairs i.e. {channelPrefix}/messages/events/{property_bag}.
    - Property Bag is formed as: `RFC2396-encoded(<PropertyName1>)=RFC2396-encoded(<PropertyValue1>)...`
    Each property (key) is allowed to have a single value.
    - Each reply channel is individually named and paired with its respective request channel. A client can subscribe to
    the reply channels in order to receive reply messages to its requests.

servers:
  aws-tls:
    host: "{account-specific-prefix}.iot.{aws-region}.amazonaws.com:443"
    protocol: tls
    description: AWS IoT Core Broker
    protocolVersion: 3.1.1
    variables:
      account-specific-prefix:
        description: Unique identifier defined by the AWS account
      aws-region:
        description: AWS Region
      channelPrefix:
        description: |
          {projectId}/{targetId}
          - projectId is a unique id identifying a project in the cloud
          - targetId is a unique id to represent an AIMM workspace on the cloud side.  1-project_N-targets

  azure-tls:
    host: "<azure-iot-hub-name>.azure-devices.net:8883"
    protocol: tls
    protocolVersion: 3.1.1
    description: Azure IoTHub
    bindings:
      mqtt:
        clientId: "{deviceId}"
    variables:
      channelPrefix:
        default: devices/{deviceId}
  azure-wss:
    host: "<azure-iot-hub-name>.azure-devices.net:443/$iothub/websocket"
    protocol: wss
    protocolVersion: 3.1.1
    description: Azure IoTHub
    bindings:
      mqtt:
        clientId: "{deviceId}"
    variables:
      channelPrefix:
        default: devices/<deviceId>

channels:

  "{channelPrefix}/messages/events/apiVersion=1&type=log":
    parameters:
      $ref: '#/components/schemas/DefaultChannelPrefixParameter'
    # subscribe:
    #   operationId: emitLogV1
    #   summary: Log messages
    #   description: Client can subscribe to this channel to receive log messages. The log level and thus the amount of log messages can be configured in AI Asset Manager via IEM configuration.
    #   message:
    #     $ref: '#/components/messages/GenericLogMsg'

  "{channelPrefix}/messages/events/apiVersion=1&type=error":
    parameters:
      $ref: '#/components/schemas/DefaultChannelPrefixParameter'
    # subscribe:
    #   operationId: emitErrorV1
    #   summary: Error channel
    #   description: Client can subscribe to this channel to receive error messages in general or related to a specific request
    #   message:
    #     $ref: '#/components/messages/GenericCompositeErrorMsg'

  "{channelPrefix}/messages/devicebound/apiVersion=1&type=resource&resourceType=deployment&operation=list":
    parameters:
      $ref: '#/components/schemas/DefaultChannelPrefixParameter'
    # publish:
    #   operationId: onQueryDeploymentListV1
    #   summary: Query a List of deployments
    #   description: Client can publish a message on this channel to Query a list of deployments
    #   tags:
    #     - name: deployments
    #   message:
    #     $ref: '#/components/messages/QueryDeploymentListMsg'

  "{channelPrefix}/messages/events/apiVersion=1&type=resource&resourceType=deployment&operation=list":
    parameters:
      $ref: '#/components/schemas/DefaultChannelPrefixParameter'
    # subscribe:
    #   operationId: emitDeploymentListV1
    #   summary: Reply to `Query a List of deployments` request
    #   description: Client can subscribe to this channel to receive reply message of the `Query a List of deployments` request
    #   tags:
    #     - name: deployments
    #   message:
    #     $ref: '#/components/messages/EmitDeploymentListMsg'

  "{channelPrefix}/messages/devicebound/apiVersion=1&type=resource&resourceType=deploymentStatus&operation=get&deploymentId={deploymentId}":
    parameters:
      $ref: '#/components/schemas/DefaultChannelPrefixParameter'
      deploymentId:
        description: Id that uniquely identifies the requested resource
        schema:
          type: string
          format: uuid
    # publish:
    #   operationId: onQueryDeploymentStatusV1
    #   summary: Query status of a deployment
    #   description: Client can publish a message on this channel to Query latest reported status of a deployment
    #   tags:
    #     - name: deployments
    #   message:
    #     $ref: '#/components/messages/QueryDeploymentStatusMsg'

  "{channelPrefix}/messages/events/apiVersion=1&type=resource&resourceType=deploymentStatus&operation=get&deploymentId={deploymentId}":
    parameters:
      $ref: '#/components/schemas/DefaultChannelPrefixParameter'
      deploymentId:
        description: Id that uniquely identifies the replied resource
        schema:
          type: string
          format: uuid
    # subscribe:
    #   operationId: emitDeploymentStatusV1
    #   summary: Reply to `Query status of a deployment` request
    #   description: Client can subscribe to this channel to receive reply message of the `Query status of a deployment` request
    #   tags:
    #     - name: deployments
    #   message:
    #     $ref: '#/components/messages/EmitDeploymentStatusMsg'

  "{channelPrefix}/messages/devicebound/apiVersion=1&type=resource&resourceType=delivery&operation=list":
    parameters:
      $ref: '#/components/schemas/DefaultChannelPrefixParameter'
    # publish:
    #   operationId: onQueryDeliveryListV1
    #   summary: Query a List of deliveries
    #   description: Client can publish a message on this channel to Query a List of deliveries
    #   tags:
    #     - name: deliveries
    #   message:
    #     $ref: '#/components/messages/QueryDeliveryListMsg'

  "{channelPrefix}/messages/events/apiVersion=1&type=resource&resourceType=delivery&operation=list":
    parameters:
      $ref: '#/components/schemas/DefaultChannelPrefixParameter'
    # subscribe:
    #   operationId: emitDeliveryListV1
    #   summary: Reply to `Query a List of deliveries` request
    #   description: Client can subscribe to this channel to receive reply message of the `Query a List of deliveries` request
    #   tags:
    #     - name: deliveries
    #   message:
    #     $ref: '#/components/messages/EmitDeliveryListMsg'

  "{channelPrefix}/messages/devicebound/apiVersion=1&type=resource&resourceType=package&operation=list":
    parameters:
      $ref: '#/components/schemas/DefaultChannelPrefixParameter'
    # publish:
    #   operationId: onQueryPackageListV1
    #   summary: Query a List of packages
    #   description: Client can publish a message on this channel to Query a List of packages
    #   tags:
    #     - name: packages
    #   message:
    #     $ref: '#/components/messages/QueryPackageListMsg'

  "{channelPrefix}/messages/events/apiVersion=1&type=resource&resourceType=package&operation=list":
    parameters:
      $ref: '#/components/schemas/DefaultChannelPrefixParameter'
    # subscribe:
    #   operationId: emitPackageListV1
    #   summary: Reply to `Query a List of packages` request
    #   description: Client can subscribe to this channel to receive reply message of the `Query a List of packagess` request
    #   tags:
    #     - name: packages
    #   message:
    #     $ref: '#/components/messages/EmitPackageListMsg'

components:
  messages:
    GenericLogMsg:
      contentType: application/json
      payload:
        $ref: '#/components/schemas/GenericLogMsgPayload'

    GenericCompositeErrorMsg:
      name: GenericCompositeError
      contentType: application/json
      payload:
        $ref: '#/components/schemas/GenericCompositeErrorMsgPayload'

    QueryPackageListMsg:
      name: QueryPackageListMsg
      title: Message to query list of packages
      contentType: application/json
      payload:
        $ref: '#/components/schemas/QueryPackageListMsgPayload'
      tags:
        - name: packages

    EmitPackageListMsg:
      name: EmitPackageList
      title: Message to emit list of packages
      contentType: application/json
      payload:
        $ref: '#/components/schemas/EmitPackageListMsgPayload'
      tags:
        - name: packages

    QueryDeploymentListMsg:
      name: QueryDeploymentListMsg
      title: Message to query list of deployments
      contentType: application/json
      payload:
        $ref: '#/components/schemas/QueryDeploymentListMsgPayload'
      tags:
        - name: deployments

    EmitDeploymentListMsg:
      name: EmitDeploymentList
      title: Message to emit list of deployments
      contentType: application/json
      payload:
        $ref: '#/components/schemas/EmitDeploymentListMsgPayload'
      tags:
        - name: deployments

    QueryDeploymentStatusMsg:
      name: QueryDeploymentStatusMsg
      title: Message to query latest reported status of a deployment
      payload:
        $ref: '#/components/schemas/QueryDeploymentStatusMsgPayload'
      tags:
        - name: deployments

    EmitDeploymentStatusMsg:
      name: EmitDeploymentStatusMsg
      title: Message to emit a deployment status
      contentType: application/json
      payload:
        $ref: '#/components/schemas/EmitDeploymentStatusMsgPayload'
      tags:
        - name: deployments

    QueryDeliveryListMsg:
      name: QueryDeliveryListsMsg
      title: Message to query a list of package deliveries from the cloud to the AI Asset Manager
      payload:
        $ref: '#/components/schemas/QueryDeliveryListMsgPayload'
      tags:
        - name: deliveries

    EmitDeliveryListMsg:
      name: EmitDeliveryListMsg
      title: Message to emit a list of package deliveries from the cloud to the AI Asset Manager
      contentType: application/json
      payload:
        $ref: '#/components/schemas/EmitDeliveryListMsgPayload'
      tags:
        - name: deliveries

  schemas:
    Timestamp:
      type: string
      format: dateTime
      description: Timestamp when the message was sent using RFC3339 standard date-time format.

    RequestId:
      type: string
      format: uuid
      description: Identifier generated by the client in order to uniquely identify the Request.

    CorrelationId:
      type: string
      format: uuid
      description: Identifier given by the client so that the Reply message can be uniquely associated with a request.

    DefaultChannelPrefixParameter:
      channelPrefix:
        description: Server dependent parameter, actual value is specified under the "URL variables" section of the server block.

    DeliveryState:
      type: string
      enum:
        - NewDelivery
        - PresignedUrlRequested
        - PresignedUrlCreated
        - Downloading
        - Importing
        - Success
        - Error

    GenericLogMsgPayload:
      type: object
      required: [ timestamp, level, location, text ]
      properties:
        timestamp:
          type: string
          format: dateTime
        level:
          type: string
          enum:
            - Trace
            - Debug
            - Info
            - Warn
            - Error
        location:
          type: string
        text:
          type: string

    GenericCompositeErrorMsgPayload:
      type: object
      required: [ timestamp, errors ]
      properties:
        correlationId:
          $ref: '#/components/schemas/CorrelationId'
        timestamp:
          $ref: '#/components/schemas/Timestamp'
        errors:
          type: array
          items:
            $ref: '#/components/schemas/GenericErrorPayload'

    GenericErrorPayload:
      type: object
      properties:
        logRef:
          type: string
          format: uuid
        message:
          type: string
        details:
          type: object
          additionalProperties:
            type: string
        code:
          type: string
        cause:
          type: array
          items:
            $ref: '#/components/schemas/GenericErrorPayload'

    DeploymentStatus:
      type: object
      properties:
        id:
          type: string
          format: uuid
        deploymentId:
          type: string
          format: uuid
        status:
          type: string
          enum:
            - New
            - Ready
            - Invalid
            - ErrorSendingAction
            - DeployActionSent
            - UnDeployActionSent
            - ActivateActionSent
            - StartActionSent
            - StopActionSent
            - PauseActionSent
            - AgentActionReceived
            - AgentFetchingDeployment
            - AgentUnpackingDeployment
            - AgentActionExecuted
            - AgentActionExecutionError
            - Embedder*
        message:
          type: string
        code:
          type: string
        details:
          type: object
          additionalProperties:
            type: string

    Deployment:
      type: object
      required: [ createdAt, modifiedAt, createdBy, modifiedBy, id, name, packageId, deviceId, ruleId, status ]
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        packageId:
          type: string
          format: uuid
        deviceId:
          type: string
          format: uuid
        ruleId:
          type: string
        status:
          $ref: '#/components/schemas/DeploymentStatus'
        createdAt:
          type: string
          format: dateTime
        modifiedAt:
          type: string
          format: dateTime
        createdBy:
          type: string
        modifiedBy:
          type: string

    Package:
      type: object
      required: [ createdAt, modifiedAt, createdBy, modifiedBy, id, name, workspaceId, status ]
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        packageId:
          type: string
          format: uuid
        version:
          type: string
        workspaceId:
          type: string
          format: uuid
        type:
          type: string
        status:
          type: string
        steps:
          type: array
          items:
            $ref: '#/components/schemas/Step'
        deployments:
          type: array
          items:
            $ref: '#/components/schemas/Deployment'
        createdAt:
          type: string
          format: dateTime
        modifiedAt:
          type: string
          format: dateTime
        createdBy:
          type: string
        modifiedBy:
          type: string

    Step:
      type: object
      required: [ createdAt, modifiedAt, createdBy, modifiedBy, id, packageId ]
      properties:
        createdAt:
          type: string
          format: dateTime
        modifiedAt:
          type: string
          format: dateTime
        createdBy:
          type: string
        modifiedBy:
          type: string
        id:
          type: string
          format: uuid
        name:
          type: string
        version:
          type: string
        packageId:
          type: string
          format: uuid
        description:
          type: string
        runtimeType:
          type: string
        runtimeVersion:
          type: string
        replicas:
          type: integer
        hardwareType:
          type: string
        entryPoint:
          type: string

    Delivery:
      type: object
      required: [ createdAt, modifiedAt, createdBy, modifiedBy, id, cloudProjectId, targetId, State, workspaceId ]
      properties:
        createdAt:
          type: string
          format: dateTime
        modifiedAt:
          type: string
          format: dateTime
        createdBy:
          type: string
        modifiedBy:
          type: string
        id:
          type: string
          format: uuid
        cloudProjectId:
          type: string
        targetId:
          type: string
        packageId:
          type: string
          format: uuid
        packageVersion:
          type: string
        packageVersionId:
          type: string
          format: uuid
        State:
          $ref: '#/components/schemas/DeliveryState'
        workspaceId:
          type: string
          format: uuid

    QueryDeploymentListMsgPayload:
      type: object
      required: [ requestId, timestamp ]
      properties:
        requestId:
          $ref: '#/components/schemas/RequestId'
        timestamp:
          $ref: '#/components/schemas/Timestamp'
        packageId:
          type: string
          format: uuid
          description: Optional parameter to list only those deployments that were created from the referenced package

    EmitDeploymentListMsgPayload:
      type: object
      required: [ correlationId, timestamp, deployments ]
      properties:
        correlationId:
          $ref: '#/components/schemas/CorrelationId'
        timestamp:
          $ref: '#/components/schemas/Timestamp'
        deployments:
          type: array
          items:
            $ref: '#/components/schemas/Deployment'

    QueryPackageListMsgPayload:
      type: object
      required: [ requestId, timestamp ]
      properties:
        requestId:
          $ref: '#/components/schemas/RequestId'
        timestamp:
          $ref: '#/components/schemas/Timestamp'

    EmitPackageListMsgPayload:
      type: object
      required: [ correlationId, timestamp, packages ]
      properties:
        correlationId:
          $ref: '#/components/schemas/CorrelationId'
        timestamp:
          $ref: '#/components/schemas/Timestamp'
        packages:
          type: array
          items:
            $ref: '#/components/schemas/Package'

    QueryDeploymentStatusMsgPayload:
      type: object
      required: [ requestId ]
      properties:
        requestId:
          $ref: '#/components/schemas/RequestId'
        timestamp:
          $ref: '#/components/schemas/Timestamp'

    EmitDeploymentStatusMsgPayload:
      type: object
      required: [ correlationId, timestamp, deploymentStatus ]
      properties:
        correlationId:
          $ref: '#/components/schemas/CorrelationId'
        timestamp:
          $ref: '#/components/schemas/Timestamp'
        deploymentStatus:
          $ref: '#/components/schemas/DeploymentStatus'

    QueryDeliveryListMsgPayload:
      type: object
      required: [ requestId, timestamp ]
      properties:
        requestId:
          $ref: '#/components/schemas/RequestId'
        timestamp:
          $ref: '#/components/schemas/Timestamp'
        state:
          $ref: '#/components/schemas/DeliveryState'
          description: Optional parameter to list only those deliveries which has the given state

    EmitDeliveryListMsgPayload:
      type: object
      required: [ correlationId, timestamp, packages ]
      properties:
        correlationId:
          $ref: '#/components/schemas/CorrelationId'
        timestamp:
          $ref: '#/components/schemas/Timestamp'
        deliveries:
          type: array
          items:
            $ref: '#/components/schemas/Delivery'

