openapi: 3.0.0
info:
  description: Public API documentation for IE Runtime Service Registry. Service Registry serves as a centralized directory where information about available services and their locations is stored.
  title: IE Runtime Service Registry Public APIs
  version: '2.0'
  contact:
    name: Team Abhiyanta
  license:
    name: 'Industrial Edge © 2024, Siemens AG. All rights reserved.'
servers:
  - url: 'https://edge-iot-core.proxy-redirect:8443/b.service/api/v2/service-registry'
    description: Application with proxy-redirect network 
  - url: 'https://localhost:9443/b.service/api/v2/service-registry'
    description: Application with network mode host
tags:
  - name: service registry
paths:
  /services:
    get:
      summary: Retrieves information about available service(s).
      description:  |- 
        - This API retrieves metadata information about available service(s) and their locations, from the Service Registry.
        - The metadata information is added to Service Registry either via Publisher or PUT API
        - If the app has registered dynamic metadata (via PUT API) then it will be returned to requesting clients
        - If the dynamic metadata is not available then static metadata (which is added via Publisher) in IED shall be looked and returned if available
        - The returned information can be filtered using JMESPath expressions. <a href='https://jmespath.org'> See details.</a>
        - Currently only first level filtering in the JSON hierarchy is guaranteed, refer the PUT API example for the structure of the JSON hierarchy.
      tags:
        - service registry
      security:
        - JwtAuth: []
      parameters:
        - $ref: '#/components/parameters/Authorization'
        - in: query
          name: jmespath
          schema:
            type: string
          description: Filter services by a specific JMESPath expression
          examples:
            jmespathExample1:
              $ref: '#/components/examples/jmespathExample1'
            jmespathExample2:
              $ref: '#/components/examples/jmespathExample2'
            jmespathExample3:
              $ref: '#/components/examples/jmespathExample3'
            jmespathExample4:
              $ref: '#/components/examples/jmespathExample4'
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceObjectWithIdTime'
              examples:
                Without filters:
                  $ref: '#/components/examples/WithoutFilters'
                With appId filter:
                  $ref: '#/components/examples/WithAppIdFilter'
                With app_instance_id filter:
                  $ref: '#/components/examples/WithAppInstanceIdFilter'
                With app_types filter:
                  $ref: '#/components/examples/WithAppTypesFilter'
                With driver_schema_uris filter:
                  $ref: '#/components/examples/WithDriverSchemaUrisFilter'
        '204':
          description: |- 
           operation is successful, but there is no content:
           - The query is valid, but there is no data that matches the query.
        '401':
          $ref: '#/components/responses/401'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                InternalServerError:
                  $ref: '#/components/examples/InternalServerError'
        '503':
          description: Service Unavailable
          headers:
            Retry-After:
              description: Indicates how long (seconds) the client should wait before retrying the request.
              schema:
                type: integer
                format: int32
                example: 30
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                ExampleServiceNotRunningError:
                  $ref: '#/components/examples/ExampleServiceNotRunningError'

  /services/{appId}:  
    put:
      summary: Adds information about available service(s).
      description: |- 
        - This API updates the metadata information about available service(s) and their locations, into the Service Registry.
        - If there is no existing metadata information availale then it will be added into the registry.
        - The metadata information object, encapsulates the service and its locations, is structured dynamically.
        - On successful operation, the updated/added information is returned in the same format as returned by GET API
      tags:
        - service registry
      security:
        - JwtAuth: []
      parameters:
        - schema:
            type: string
          name: appId
          in: path
          required: true
          description: Application ID
        - $ref: '#/components/parameters/Authorization'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ServiceObject'
        required: true

      responses:
        '200':
          description: Successful operation   
          content:
            application/json:
              schema:
                type: object
                properties:
                  services:
                    type: string
              examples:
                Example:
                  $ref: '#/components/examples/ExampleAddService'
        '400':
          description: |- 
            Bad Request: 
            - Unable to parse body data
            - Missing service info
            - Missing AppId 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                UnableToParseBodyMapError:
                  $ref: '#/components/examples/UnableToParseBodyMapError'
                MissingServiceInfoError:
                  $ref: '#/components/examples/MissingServiceInfoError'
                MissingAppIdError:
                  $ref: '#/components/examples/MissingAppIdError'
        '401':
          $ref: '#/components/responses/401'
        '404':
          description: App does not have permission to modify metadata of another app
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                KeyNotFound:
                  value:
                    errors:
                      - code: edge.serviceRegistry.unauthorizedApp
                        logref: c105072b-39cb-49d9-999f-3873b10e3db1
                        message: App does not have permission to perform this action.
        '500':
          description: |- 
            Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                InternalServerError:
                  $ref: '#/components/examples/InternalServerError'
        '503':
          description: Service Unavailable
          headers:
            Retry-After:
              description: Indicates how long (seconds) the client should wait before retrying the request.
              schema:
                type: integer
                format: int32
                example: 30 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                ExampleServiceNotRunningError:
                  $ref: '#/components/examples/ExampleServiceNotRunningError'

components:
  securitySchemes:
    JwtAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

  schemas:
    Error:
      title: Error
      type: object
      description: An error object containing a code, message, and unique identifier (logref).
      properties:
        code:
          type: string
          minLength: 2
        logref:
          type: string
          format: uuid
          minLength: 1
          description: Unique identifier for each error
        message:
          type: string
          minLength: 1
      required:
        - code
        - message
    ErrorResponse:
      title: ErrorResponse
      description: An object containing an array of error objects.
      type: object
      properties:
        errors:
          type: array
          items:
            $ref: '#/components/schemas/Error'
    AppId:
      properties:
        id:
          type: string
          example: "2c963f66afa6-5717-4562-b3fc-3fa85f64"
    ServiceInfo:
      properties:
        info:
          type: object
          additionalProperties: true
          example:
            dns_domainname: "mb_dns"
            grpc_ip_port_number: 5001
            app_instance_id: "mb1c1"
            app_types: ["cs-driver1", "noncs-driver"]
            driver_schema_uris: "schema_Uri1"
    ModifiedTime:
      properties:
        lastModified:
          type: integer
          example: 1257894000
    ServiceObjectWithIdTime:
      title: ResponseObject
      description: An object containing an array of endpoint(s) information of app(s)
      type: object
      properties:
        services:
          type: array
          items:
            allOf:
            - $ref: '#/components/schemas/AppId'
            - $ref: '#/components/schemas/ServiceInfo'
            - $ref: '#/components/schemas/ModifiedTime'
    ServiceObject:
      title: ServiceObject
      description: An object containing service information.
      example:
        dns_domainname: "mb_dns"
        grpc_ip_port_number: 5001
        app_instance_id: "mb1c1"
        app_types: ["cs-driver1", "noncs-driver"]
        driver_schema_uris: "schema_Uri1"

  parameters:
    Authorization:
      name: Authorization
      in: header
      required: true
      schema:
        type: string
      description: Authorization token with the prefix - JWT
      examples:
        JWTExample1:
          value: jwt <the_token>
          summary: JWT Token

  examples:
    jmespathExample1:
      value: services[?id=='3fa85f64-5717-4562-b3fc-2c963f66afa6']
      summary: Filtering for appId
    jmespathExample2:
      value: services[?info.app_instance_id=='pn1c1']
      summary: Filtering for app_instance_id
    jmespathExample3:
      value: services[?info.app_types.contains(@, 'cs-driver2')]
      summary: Filtering for app_types
    jmespathExample4:
      value: services[?info.driver_schema_uris=='schema_Uri2']
      summary: Filtering for driver_schema_uris
    WithoutFilters:
      description: curl -k -H "Authorization:jwt <the_token>" -X GET https://edge-iot-core.proxy-redirect:8443/b.service/api/v2/service-registry/services
      value:
        services:
          - id: "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            info:
              dns_domainname: "mb_dns"
              grpc_ip_port_number: 5001
              app_instance_id: "mb1c1"
              app_types: ["cs-driver1", "noncs-driver"]
              driver_schema_uris: "schema_Uri1"
            lastModified: 12345678
          - id: "2c963f66afa6-5717-4562-b3fc-3fa85f64"
            info:
              dns_domainname: "pnio_dns"
              grpc_ip_port_number: 5002
              app_instance_id: "pn1c1"
              app_types: ["cs-driver2", "noncs-driver"]
              driver_schema_uris: "schema_Uri2"
            lastModified: 12345678
    WithAppIdFilter:
      description: curl -k -H "Authorization:jwt <the_token>" -X GET https://edge-iot-core.proxy-redirect:8443/b.service/api/v2/service-registry/services?jmespath=services[?id=='3fa85f64-5717-4562-b3fc-2c963f66afa6']
      value:
        services:
          - id: "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            info:
              dns_domainname: "mb_dns"
              grpc_ip_port_number: 5001
              app_instance_id: "pn1c1"
              app_types: ["cs-driver1", "noncs-driver"]
              driver_schema_uris: "schema_Uri1"
            lastModified: 12345678
    WithAppInstanceIdFilter:
      description: curl -k -H "Authorization:jwt <the_token>" -X GET https://edge-iot-core.proxy-redirect:8443/b.service/api/v2/service-registry/services?jmespath=services[?info.app_instance_id=='pn1c1']
      value:
        services:
          - id: "2c963f66afa6-5717-4562-b3fc-3fa85f64"
            info:
              dns_domainname: "pnio_dns"
              grpc_ip_port_number: 5002
              app_instance_id: "pn1c1"
              app_types: ["cs-driver2", "noncs-driver"]
              driver_schema_uris: "schema_Uri2"
            lastModified: 12345678
    WithAppTypesFilter:
      description: curl -k -H "Authorization:jwt <the_token>" -X GET https://edge-iot-core.proxy-redirect:8443/b.service/api/v2/service-registry/services?jmespath=services[?info.app_types.contains(@, 'cs-driver2')]
      value:
        services:
          - id: "2c963f66afa6-5717-4562-b3fc-3fa85f64"
            info:
              dns_domainname: "pnio_dns"
              grpc_ip_port_number: 5002
              app_instance_id: "pn1c1"
              app_types: ["cs-driver2", "noncs-driver"]
              driver_schema_uris: "schema_Uri2"
            lastModified: 12345678
    WithDriverSchemaUrisFilter:
      description: curl -k -H "Authorization:jwt <the_token>" -X GET https://edge-iot-core.proxy-redirect:8443/b.service/api/v2/service-registry/services?jmespath=services[?info.driver_schema_uris=='schema_Uri2']
      value:
        services:
          - id: "2c963f66afa6-5717-4562-b3fc-3fa85f64"
            info:
              dns_domainname: "pnio_dns"
              grpc_ip_port_number: 5002
              app_instance_id: "pn1c1"
              app_types: ["cs-driver2", "noncs-driver"]
              driver_schema_uris: "schema_Uri2"
            lastModified: 12345678
    ExampleAddService:
      description: curl -k -H "Authorization:jwt <the_token>" -X PUT https://edge-iot-core.proxy-redirect:8443/b.service/api/v2/service-registry/services/3fa85f64-5717-4562-b3fc-2c963f66afa6 -d {...}
      value:
        services:
          - id: "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            info:
              dns_domainname: "mb_dns"
              grpc_ip_port_number: 5001
              app_instance_id: "pn1c1"
              app_types: ["cs-driver1", "noncs-driver"]
              driver_schema_uris: "schema_Uri1"
            lastModified: 12345678
    UnableToParseBodyMapError:
      value:
        errors:
          - code: edge.unableToParseBodyData
            logref: c105072b-39cb-49d9-999f-3873b10e3db1
            message: Invalid request body supplied.
    MissingServiceInfoError:
      value:
        errors:
          - code: edge.serviceRegistry.serviceInfoMissing
            logref: c105072b-39cb-49d9-999f-3873b10e3db1
            message: Service info is missing.
    MissingAppIdError:
      value:
        errors:
          - code: edge.serviceRegistry.missingAppId
            logref: c105072b-39cb-49d9-999f-3873b10e3db1
            message: App ID is required.
    InternalServerError:
      value:
        errors:
          - code: edge.internalServerError
            logref: c105072b-39cb-49d9-999f-3873b10e3db1
            message: The server encountered an unknown error.
    ExampleServiceNotRunningError:
      value:
        errors:
          - code: edge.serviceNotRunning
            logref: c105072b-39cb-49d9-999f-3873b10e3db1
            message: Job service process is not running.
    ExpiredToken:
      value:
        errors:
          - code: edge.auth.expiredToken
            message: Token expired.
            logref: 5432e1d8-5916-4619-88ec-a507f83331bd
    InvalidToken:
      value:
        errors:
          - code: edge.auth.invalidToken
            message: Token is invalid.
            logref: 5432e1d8-5916-4619-88ec-a507f83331bd
    MissingToken:
      value:
        errors:
          - code: edge.auth.missingToken
            message: Token is required.
            logref: 3505f6bd-30cd-4deb-981d-02e89f82aa8f
  responses:
    '401':
      description: |-
        Unauthorized:
        - Missing the auth token
        - Invalid auth token
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            MissingTokenError:
              $ref: '#/components/examples/MissingToken'
            InvalidTokenError:
              $ref: '#/components/examples/InvalidToken'