Defining Data to and from an Adapter

Schema is used to define the data that an adapter sends to and receives from the system it is integrating with. It does not define the type of data (see datatype in action.json). It is only utilized when the datatype is something that can be translated; for example, JSON.

Multiple schema files can be utilized by an adapter. Every action within the adapter can have a:

  • Request schema which defines the data the adapter will send to the other system on the API request.
  • Response schema which will define the data that the other system will send to the adapter on the response.

The request and response do not have to be separate schemas; on CRUD operations they will often be the same schema. When building an adapter from Swagger, each action within the Swagger will have query or body parameters defined. These are inserted into the schema files.

There is a good reason to define your schema files. Multiple systems often have a different way of defining entities. Itential Automation Platform (IAP) will have its way and often the other systems will not conform to that. Thus, you need the ability to translate data between them.

Take the following example:

  • If System A defines a device IP address as ip_addr and System B defines it as ipaddress and IAP defines it as ip_address then something needs to map the fields so that when we get a device from System A it takes ip_addr and puts it into ip_address for IAP.
  • Similarly, when IAP wants to add a new device to System B we take ip_address and put it in ipaddress. This translation happens automatically in the adapter libraries based on the information that you put in the schemas.

SCHEMA

{
  "$id": "reqTokenSchema.json",
  "type": "object",
  "schema": "http://json-schema.org/draft-07/schema#",
  "translate": true,
  "dynamicfields": true,
  "properties": {
    "ph_request_type": {
      "type": "string",
      "description": "type of request (internal to adapter)",
      "default": "getToken",
      "enum": [
        "getToken",
        "healthcheck"
      ],
      "external_name": "ph_request_type"
    },
    "username": {
      "type": "string",
      "description": "username to log in with",
      "external_name": "user_name"
    },
    "password": {
      "type": "string",
      "description": "password to log in with",
      "external_name": "passwd"
    }
  },
  "definitions": {}
}

  • parse (optional): This field is added by the adapter. It tells the adapter if this field needs to be independently parsed (maybe it was stringified within the object that was sent). The default is false.
  • encode (optional): This field is added by the adapter. It tells the adapter whether to endode/decode the data contained within this field. Encoding is base 64. The default is not to encode.
  • encrypt (optional): This field is added by the adapter. It tells the adapter whether to encrypt/decrypt the data contained within this individual field.
    • Different encryption types are supported in the type field, but at the current time only AES encryption is used.
  • The key field contains the key used to encrypt/decrypt the data in the field.
    The default is not to encrypt.

SCHEMA

{
  "$id": "reqTokenSchema.json",
  "properties": {
    ….
    "username": {
      "type": "string",
      "description": "username to log in with",
      "parse": true,
      "encode": false,
      "encrypt": {
        "type": "AES",
        "key": "sfhgjhajlgsfhjlaghlshdg"
      },
      "external_name": "user_name"
    },
     ….
  },
  "definitions": {}
}

  • Required fields: You can have required fields within the schema using standard JSON schema techniques like having a list of “required” properties using a required value. You can also use more complex techniques for “required” properties based on the action.
  • One advantage of using required properties is that invalid requests will not be sent to the other system, thereby causing the system to error. Instead, the error will be returned by the adapter. This technique is not only efficient but saves time!

SCHEMA

{
  "$id": "sevone_alert",
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "ph_request_type": {
      "type": "string",
      "description": "type of request (internal to adapter)",
      "default": "getAlerts",
      "enum": [
        "getAlerts", "getAlertsFiltered", "getAlertsForDevice",
        "getAlertsForMapConnection", "getAlertsForMapNode",
        "createAlert", "updateAlert", "assignAlert", "ignoreAlert",
        "clearAlert", "deleteAlert"
      ],
      "external_name": "ph_request_type"
    },
    "id": {
      "type": "integer",
      "description": "id of the alert in sevone",
      "minimum": 0,
      "maximum": 999999999999,
      "external_name": “sys_id"
    },
    "origin": {
      "type": "string",
      "description": "where this alert was originated from",
      "external_name": "origin"
    }
  },
  "allOf": [
    {
      "if" : { "properties" : { "ph_request_type": { "enum": ["createAlert"] } } },
      "then" : { "required" : ["origin"] }
    }
  ],
  "definitions": {}
}

Know Your Network. Automate Your Network.

Get Started with Itential Today.