openapi: '3.0.1'
info:
  version: '3.3.0'
  x-visibility: external
  title: Commanding
  description: |
    Commanding is a service that provides the APIs to manage delivery jobs to send commands to MQTT clients for execution.
    
    ## Limitations
    - The maximum number of clients to which a command can be published is 20.
    - Command data size is restricted to 10kB.
    
    ## Generic Errors
    
    The following generic error codes (with status codes) can occur at the operations of this API. Generic error codes are prefixed with 'mdsp.core.generic.'.
    - missingParameter (400)
    - invalidParameter (400)
    - missingRequestBody (400)
    - invalidRequestBody (400) 
    - unauthorized (401)
    - forbidden (403)
    - conflict (409)
    - preconditionFailed (412)
    - unsupportedMediaType (415)
    - preconditionRequired (428)
    - tooManyRequests (429)
    - internalServerError (500)

servers:
  - url: https://api.eu1.siemens.app/commanding-1000001700/v3
    description: Xcelerator compliant URL

tags:
  - name: MQTT Delivery Job
    description: Manage jobs to publish MQTT commands to clients.

paths:
  /deliveryJobs:
    post:
      tags:
        - MQTT Delivery Job
      security:
        - jobs:
            - msg.c
      summary: Create a delivery job
      description: |
        Creates a delivery job. A delivery job is used to send an MQTT command to a list of clients for execution.
        The following validations are performed when a delivery job is created. 
      
        1. The provided clients must be valid.
        2. Maximum number of clients can be 20 in a delivery job.
        3. Command data size is restricted to 10kB.
      requestBody:
        description: Object describing the Job request
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JobRequest'
      responses:
        '201':
          description: 'Sample response: Details of the job'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Job'
        '400':
          $ref: '#/components/responses/InvalidClientIdList'
        '401':
          description: User is not authenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '403':
          description: User is not authorized for request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '429':
          description: Too Many Requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '500':
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        default:
          $ref: '#/components/responses/Default'

    get:
      tags:
        - MQTT Delivery Job
      security:
        - jobs:
            - msg.r
      summary: Get all delivery jobs
      description: 'Get all delivery jobs'
      parameters:
        - $ref: '#/components/parameters/deliveryJobParameterFilter'
        - $ref: '#/components/parameters/size'
        - $ref: '#/components/parameters/page'
      responses:
        '200':
          description: 'Sample response: Details of the delivery jobs'
          content:
            application/json:
              schema:
                type: object
                properties:
                  _embedded:
                    type: object
                    properties:
                      deliveryJobs:
                        type: array
                        items:
                          $ref: '#/components/schemas/JobListView'
                  page:
                    $ref: '#/components/schemas/Page'
                  _links:
                    type: object
                    properties:
                      self:
                        $ref: '#/components/schemas/rel.self'
                      first:
                        $ref: '#/components/schemas/rel.first'
                      prev:
                        $ref: '#/components/schemas/rel.prev'
                      next:
                        $ref: '#/components/schemas/rel.next'
                      last:
                        $ref: '#/components/schemas/rel.last'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '401':
          description: User is not authenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '403':
          description: User is not authorized for request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '429':
          description: Too Many Requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '500':
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        default:
          $ref: '#/components/responses/Default'

  /deliveryJobs/{id}:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    get:
      tags:
        - MQTT Delivery Job
      security:
        - jobs:
            - msg.r
      summary: Get the delivery job by Id
      description: 'Get the delivery job by Id'
      responses:
        '200':
          description: 'Sample response: Details of the delivery job'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Job'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '401':
          description: User is not authenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '403':
          description: User is not authorized for request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '404':
          $ref: '#/components/responses/DeliveryJobNotFound'
        '429':
          description: Too Many Requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '500':
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        default:
          $ref: '#/components/responses/Default'

    delete:
      tags:
        - MQTT Delivery Job
      security:
        - jobs:
            - msg.d
      summary: Deletes a delivery job and its related commands.
      description: Delete the job and its related commands.
      responses:
        '204':
          description: 'Delivery job and its related commands are deleted successfully.'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '401':
          description: User is not authenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '403':
          description: User is not authorized for request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '404':
          $ref: '#/components/responses/DeliveryJobNotFound'
        '429':
          description: Too Many Requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '500':
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        default:
          $ref: '#/components/responses/Default'

  /deliveryJobs/{id}/commands:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - $ref: '#/components/parameters/commandParameterFilter'
      - $ref: '#/components/parameters/size'
      - $ref: '#/components/parameters/page'
    get:
      tags:
        - MQTT Delivery Job
      security:
        - jobs:
            - msg.r
      summary: Get all the commands related with a delivery job.
      description: |
        Get all the commands for the given delivery job Id.
      responses:
        '200':
          description: 'Sample response: Details about a command'
          content:
            application/json:
              schema:
                type: object
                properties:
                  _embedded:
                    type: object
                    properties:
                      commands:
                        type: array
                        items:
                          $ref: '#/components/schemas/CommandListView'
                  page:
                    $ref: '#/components/schemas/Page'
                  _links:
                    type: object
                    properties:
                      self:
                        $ref: '#/components/schemas/rel.self'
                      first:
                        $ref: '#/components/schemas/rel.first'
                      prev:
                        $ref: '#/components/schemas/rel.prev'
                      next:
                        $ref: '#/components/schemas/rel.next'
                      last:
                        $ref: '#/components/schemas/rel.last'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '401':
          description: User is not authenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '403':
          description: User is not authorized for request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '404':
          $ref: '#/components/responses/DeliveryJobNotFound'
        '429':
          description: Too Many Requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '500':
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        default:
          $ref: '#/components/responses/Default'

  /deliveryJobs/{id}/commands/{commandId}:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: commandId
        in: path
        required: true
        schema:
          type: string
    get:
      tags:
        - MQTT Delivery Job
      security:
        - jobs:
            - msg.r
      summary: Get the command associated with a delivery job by command Id
      description: |
        Get the command associated with a delivery job by command Id
      responses:
        '200':
          description: 'Sample response: Details of the Command'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Command'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '401':
          description: User is not authenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '403':
          description: User is not authorized for request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '404':
          $ref: '#/components/responses/CommandNotFound'
        '429':
          description: Too Many Requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        '500':
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        default:
          $ref: '#/components/responses/Default'

components:
  schemas:
    Page:
      type: object
      properties:
        size:
          description: the service might decide to return fewer elements per page than requested
          type: integer
        totalElements:
          type: integer
        totalPages:
          type: integer
        number:
          type: integer
    rel.self:
      type: object
      title: self link
      properties:
        href:
          type: string
    rel.first:
      type: object
      title: link to first page
      properties:
        href:
          type: string
    rel.prev:
      type: object
      title: link to previous page
      properties:
        href:
          type: string
    rel.next:
      type: object
      title: link to next page
      properties:
        href:
          type: string
    rel.last:
      type: object
      title: link to last page
      properties:
        href:
          type: string
    JobRequest:
      type: object
      required:
        - name
        - clientIds
        - data
      properties:
        name:
          type: string
          description: |
            Name of the delivery job.
            Minimum allowed length is 1.
            Maximum allowed length is 128.
          example: firmware update
        clientIds:
          type: array
          description: List of MQTT client Id's to which the command will be sent.
          items:
            type: string
            example: mytenant_201541ad38a4495a96e2021c762b647f
        data:
          description: Command data to be sent to MQTT client.
          type: object
          additionalProperties:
            type: string
        createdBy:
          type: string
          example: user's email address
          description: |
            Email address of the user creating the delivery job. If the field is empty then it will be populated from the token.
            Minimum allowed length is 0.
            Maximum allowed length is 255.
    Job:
      type: object
      required:
        - id
        - name
        - clientIds
        - tenantId
        - status
        - data
        - createdAt
        - createdBy
      properties:
        id:
          type: string
          readOnly: true
          description: Unique identifier of the delivery job.
          example: 21349765fe45652c8e126814c283a114
        name:
          type: string
          readOnly: true
          description: |
            Name of the delivery job.
            Minimum allowed length is 1.
            Maximum allowed length is 128.
          example: firmware update
        clientIds:
          type: array
          description: List of MQTT client Id's to which the command needs to be sent.
          items:
            type: string
            example: mytenant_201541ad38a4495a96e2021c762b647f
        tenantId:
          type: string
          readOnly: true
          description: Id of tenant which client belongs to.
          example: mytenant
        status:
          type: string
          enum:
            - EXECUTING
            - EXECUTED
            - CANCELED
          readOnly: true
          description: |
            The status of the delivery job.
        data:
          description: Command data to be sent to agent.
          type: object
          additionalProperties:
            type: string
        createdAt:
          type: string
          format: date-time
          readOnly: true
          description: The time at which the job was created. (In UTC format).
          example: "2011-08-12T20:17:46.384Z"
        createdBy:
          type: string
          readOnly: true
          description: Email address of the user creating the delivery job. If the field is empty then it will be populated from the token.
          example: user's email address
    JobListView:
      type: object
      required:
        - id
        - name
        - status
        - createdAt
      properties:
        id:
          type: string
          readOnly: true
          description: Unique identifier of the delivery job.
          example: 21349765fe45652c8e126814c283a114
        name:
          type: string
          readOnly: true
          description: |
            Name of the delivery job.
            Minimum allowed length is 1.
            Maximum allowed length is 128.
          example: firmware update
        clientIds:
          type: array
          description: List of MQTT client Id's to which the command is being sent.
          items:
            type: string
            example: mytenant_201541ad38a4495a96e2021c762b647f
        status:
          type: string
          enum:
            - EXECUTING
            - EXECUTED
            - CANCELED
          readOnly: true
          description: |
            The status of the delivery job.
        createdAt:
          type: string
          format: date-time
          readOnly: true
          description: The time at which the job was created. (In UTC format).
          example: "2011-08-12T20:17:46.384Z"
        createdBy:
          type: string
          readOnly: true
          description: Email address of the user creating the delivery job. If the field is empty then it will be populated from the token.
          example: user's email address
    Command:
      type: object
      required:
        - id
        - clientId
        - tenantId
        - updatedAt
        - status
      properties:
        id:
          type: string
          description: Unique identifier of the command.
          example: 21349765fe45652c8e126814c283a114
        clientId:
          type: string
          description: Mqtt client Id. It is the unique identifier of the device.
          example: mytenant_201541ad38a4495a96e2021c762b647f
        tenantId:
          type: string
          readOnly: true
          description: Id of tenant which client belongs to.
          example: mytenant
        status:
          type: string
          enum:
            - EXECUTING
            - EXECUTED
            - FAILED
            - CANCELED
          readOnly: true
          description: |
            The status of the command received from the agent.
        response:
          description: The response data received from the MQTT client after the command execution.
          type: object
          additionalProperties:
            type: string
        updatedAt:
          type: string
          format: date-time
          readOnly: true
          description: The last time command response was received and updated (In UTC format).
          example: "2011-08-12T20:17:46.384Z"
    CommandListView:
      type: object
      required:
        - id
        - clientId
        - tenantId
        - updatedAt
        - status
      properties:
        id:
          type: string
          description: Unique identifier of the command.
          example: 21349765fe45652c8e126814c283a114
        clientId:
          type: string
          description: Mqtt client Id.
          example: mytenant_201541ad38a4495a96e2021c762b647f
        tenantId:
          type: string
          readOnly: true
          description: Id of tenant which client belongs to.
          example: mytenant
        status:
          type: string
          enum:
            - EXECUTING
            - EXECUTED
            - FAILED
            - CANCELED
          readOnly: true
          description: |
            The status of the command received from the agent.
        updatedAt:
          type: string
          format: date-time
          readOnly: true
          description: The last time command response was received and updated (In UTC format).
          example: "2011-08-12T20:17:46.384Z"
    Errors:
      type: object
      description: Error response body model.
      properties:
        errors:
          type: array
          description: "Concrete error codes and messages are defined at operation error response descriptions in this API specification."
          items:
            type: object
            properties:
              code:
                type: string
                description: "Unique error code. Every code is bound to one (parametrized) message."
                format: "mdsp.core.template.<suffix>"
                example: "mdsp.core.mqttcommanding.exampleCode"
              logref:
                type: string
                description: "Logging correlation ID for debugging purposes."
                example: "0bff7e7a-cd25-4576-9908-4180ef086174"
              message:
                type: string
                description: "Human readable error message in English."
                example: "Example error message with parameter value"

  responses:
    DeliveryJobNotFound:
      description: |
        Not found. Possible errors:
        <br>
        <table>
          <colgroup>
            <col span="1" style="width: 30%;">
            <col span="1" style="width: 70%;">
          </colgroup>
          <tr>
            <th align="left">Code Suffix</th>
            <th align="left">Message (parametrized)</th>
          </tr>
          <tr>
            <td>deliveryJobNotFound</td>
            <td>Delivery job id {value} not found</td>
          </tr>
        </table>
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Errors'
    CommandNotFound:
      description: |
        Not found. Possible errors:
        <br>
        <table>
          <colgroup>
            <col span="1" style="width: 30%;">
            <col span="1" style="width: 70%;">
          </colgroup>
          <tr>
            <th align="left">Code Suffix</th>
            <th align="left">Message (parametrized)</th>
          </tr>
          <tr>
            <td>deliveryJobNotFound</td>
            <td>Delivery job id {value} not found</td>
          </tr>
          <tr>
            <td>commandNotFound</td>
            <td>Command id {value} not found</td>
          </tr>
        </table>
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Errors'
    InvalidClientIdList:
      description: |
        Not found. Possible errors:
        <br>
        <table>
          <colgroup>
            <col span="1" style="width: 30%;">
            <col span="1" style="width: 70%;">
          </colgroup>
          <tr>
            <th align="left">Code Suffix</th>
            <th align="left">Message (parametrized)</th>
          </tr>
          <tr>
            <td>invalidClientIdList</td>
            <td>The following clientId's are not valid {value}</td>
          </tr>
        </table>
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Errors'
    Default:
      description: "Other error with any status code and response body format."

  parameters:
    size:
      name: size
      in: query
      description: |
        The maximum number of elements returned in one page. 
        Default value is 20. 
        Maxium allowed value is 100.
      schema:
        type: integer
        default: 20
        maximum: 100
    page:
      name: page
      in: query
      description: The (0-based) index of the page
      schema:
        type: integer
        format: int32
        default: 0
    deliveryJobParameterFilter:
      name: filter
      in: query
      description: >
        JSON string describing filter operations performed on delivery jobs to be returned. The following fields and operations are supported


          ## Filter
          
          ```
          name: eq, in, endsWith, startsWith, contains
          
          ```
          ```
          createdAt: before, after, between
          
          ```
          ```
          createdBy: eq, in, endsWith, startsWith, contains
          
          ```
          ```
          clientIds: contains, in
          ```

          ## Examples

          Unencoded example filter value to fetch all delivery jobs for name "test":

          
          ```

          { "name": "test" }
          
          { "name": { "startsWith" : "test" }}
          
          ```
          Unencoded example filter value to fetch all delivery jobs based on createdAt:

          ```
          {"createdAt": {"between": "[2021-11-06T13:46:00Z, 2021-11-11T13:46:00Z]"}}
          
          {"createdAt": {"after": "2021-11-06T13:46:00Z"}}
          
          {"createdAt": {"before": "2021-11-06T13:46:00Z"}}
          
          ```
          Unencoded example filter value to fetch all delivery jobs based on createdBy:

          ```
          {"createdBy": {"contains": "test"}}

          {"createdBy": {"endsWith": "test"}}

          ```
          Unencoded example filter value to fetch all delivery jobs based on clientIds:
          Search all delivery jobs which has client id like *mytenant_mqttagentv1*
          ```
          {"clientIds": {"contains": "mytenant_mqttagentv1"}}
          ```

          Search all delivery jobs which exactly matches client id *mytenant_mqttagentv1*
          ```
          {"clientIds": {"in": [ "mytenant_mqttagentv1"]}}
          ```
          
          Search all delivery jobs which exactly matches any client id from list *mytenant_mqttagentv1* and *mytenant_mqttagentv2*
          ```
          {"clientIds": {"in": [ "mytenant_mqttagentv1", "mytenant_mqttagentv2" ]}}
          ```
      schema:
        type: string
    commandParameterFilter:
      name: filter
      in: query
      description: >
        JSON string describing filter operations performed on commands associated with a delivery job to be returned. The following fields and operations are supported


          ## Filter
          
          ```
          clientId: eq, in, endsWith,startsWith, contains
          ```
          
          ```
          status: eq, in, endsWith,startsWith, contains
          ```
          ```
          updatedAt: before, after, between
          ```

          ## Examples

          Unencoded example filter value to fetch all commands associated with delivery job for clientId "punint05_testDevice":

          
          ```
          
          { "clientId": "punint05_testDevice" }
          
          { "clientId": { "startsWith" : "punint05" }}
          
          ```
          
          Unencoded example filter value to fetch all commands associated with delivery job for status "EXECUTED":

          
          ```
          
          { "status": "EXECUTED" }
          
          { "status": { "startsWith" : "EXE" }}

          ```
          Unencoded example filter value to fetch all commands associated with delivery job based on updatedAt:

          ```
          
          {"updatedAt": {"between": "[2021-08-06T13:46:00Z, 2021-11-11T13:46:00Z]"}}
          
          {"updatedAt": {"after": "2021-11-06T13:46:00Z"}}
          
          {"updatedAt": {"before": "2021-11-06T13:46:00Z"}}
          
          ```
      schema:
        type: string

  securitySchemes:
    jobs:
      type: oauth2
      description: |
        For **Xcelerator** compliance, please use **authorizationUrl** = https://1000001700.eu1.sws.siemens.com/oauth/authorize and **tokenUrl** = https://1000001700.eu1.sws.siemens.com/oauth/token
      flows:
        authorizationCode:
          authorizationUrl: 'https://1000001700.eu1.sws.siemens.com/oauth/authorize'
          tokenUrl: 'https://1000001700.eu1.sws.siemens.com/oauth/token'
          scopes:
            msg.r: Permission to read a delivery job and its related command.
            msg.c: Permission to create a delivery job.
            msg.d: Permission to delete a delivery job and its related command.
