Skip to content

Connector SDK UI Components

Connectors and the Cloud Studio UI

The Cloud Studio UI for a connector created with the Jitterbit Harmony Connector SDK is defined by a JSON file included in the JAR file that packages the connector. By default, this is named adapter.json.

Here is an overall schematic of the JSON file that defines a connector UI, with placeholder values shown as <name>:

{
  "name": <name>,
  "sandbox": true,
  "defaultActivityIcon": <path-to-SVG-file>,
  "endpoint": {
    "displayName": <display-name>,
    "icon": <path-to-SVG-file>,
    "properties": [ <properties> ]
  },
  "activities": {
    "activity-1": {
      "displayName": <display-name-1>,
      "icon": <path-to-SVG-file>,
      "properties": [ <properties> ]
    },
    "activity-2": {
      "displayName": <display-name-2>,
      "properties": [ <properties> ]
    },
    . . .
  }
}

In this schematic, a connector has been defined with properties for the endpoint and its first two activities. Additional activities can be added as required.

For the connection (which is what appears when an end user first configures the connector in the Cloud Studio UI), a set of properties can be defined that will be used to generate one or more steps that the end user completes to configure the connection to the endpoint.

Note that the name used must be the same name that the connector is registered under (see Connector Registration).

The sandbox property can be set to true or false. Set to true means that the connector is in development, and will not be cached by Jitterbit Harmony. Instead, each invocation will reload the connector from the Jitterbit Harmony Private Agent. Once you have a production version, you can set this to false so that caching can be used to speed use.

A set of properties is defined for each activity, generating steps for configuring the activity after it is added to an operation in Cloud Studio.

Endpoint Icons

As can be seen in the above schematic, you can define icons for the connection and each of the activities (together referred to as an endpoint). Icons are defined using SVG, and are provided as a path to an SVG file.

These keys can be provided in the adapter.json:

Key Description
defaultActivityIcon Path to an SVG file, used as the icon if an icon is not defined for the endpoint or an activity
icon Path to an SVG file, used as the icon for the endpoint or for an activity

In the schematic example above, a default icon has been defined, with the connection and the first activity using other—perhaps different—icons. The second activity does not have an icon defined, and instead uses the default icon.

This screen capture of the Dropbox connector shows how different icons can be used:

One icon (a folder) is used for the connection with a different icon used for the activities. It’s possible to have a different icon for each activity, though a common theme of colors and shapes for an endpoint is advised. Note that text describing the activity is overlaid on the icon. It’s best to leave the bottom half of the icon a solid color so that the white text has a background to appear against.

Notice that the order of the icons in the UI follows the order of the activities in the JSON. If the number of activities exceeds three, additional rows of activities are added in the UI underneath the original one.

Our recommendation for the order of activities is to follow these common patterns:

  • Read, Write
  • Query (or Search), Create, Update, Upsert, Delete
  • Get, Post, Put, Delete
  • Request, Response
  • Download, Upload

If there are any custom, special, or entity-specific activities outside of the above examples (such as Get List), put them toward the beginning of the order if they are intended to provide data as a source in an operation, and toward the end if they are intended to receive data as a target in an operation.

Pagination

For the connection and each activity, properties are defined in a JSON structure. These create the configuration steps (pages) that an end user goes through to configure the connection and each of the particular activities that they choose to use.

For connections, there is often only one step, though the developer may add as many as needed.

For activities, there are at least two steps: a beginning page with a name field and an ending page showing the data schemas for review. Both of these pages are created automatically by the infrastructure and are not included or defined in the JSON file.

Default Pagination

Connections do not have any pagination by default.

For activities, here are typical examples of starting (page 1) and ending (page 2) steps. Each activity configuration has a name field (on the first page) and a data schema (on the last page). These are not defined or included in the JSON file that specifies the UI; instead, they are automatically generated and included by the framework:

Single Page

If the connection or activity can be configured on a single page and pagination is not required, a simpler structure can be used:

. . .
"properties": [
  {
    "name": <name-1>,
    "displayName": <display-name-1>,
    "type": "string",
    "validators": [
      {
        "name": "required"
      }
    ]
  },
  {
    "name": <name-2>,
    "displayName": <display-name-2>,
    "type": "string",
    "validators": [
      {
        "name": "required"
      }
    ]
  }
]
. . .

Multiple Pages

However, if the configuration is longer, with multiple values to be set or reviewed, pagination is recommended to keep the views smaller in depth:

. . .
"properties": [
  {
    "name": "page1",
    "displayName": <display-name-page-1>,
    "type": "pagination",
    "children": [
      {
        "name": <name-1-1>,
        "displayName": <display-name-1-1>,
        . . .
      },
      . . .
    ]
  },
  {
    "name": "page2",
    "displayName": <display-name-page-2>,
    "type": "pagination",
    "children": [
      {
        "name": <name-2-1>,
        "displayName": <display-name-2-1>,
        . . .
      },
      . . .
    ]
  }
]
. . .

Note

Though pagination is supported, the display name is not currently displayed in the Cloud Studio UI for each step. Instead, this can be used by the developer to distinguish the pages in the JSON file.

Available UI Components

These UI components are available:

All UI components can have validators and a defaultValue; see the first string field for an example.

Fields that show a variable icon Variable icon are UI component examples that support variable replacement. When a user enters an opening square bracket ([), a list of possible variable completions (Jitterbit, project, and global variables) will be displayed. Currently, only the String Entry UI component supports variable replacement.

This sample shows the available components, with detailed code fragments in the examples that follow:

String Entry With Default Value

{
  "name": "example_string_with_default",
  "type": "string",
  "defaultValue": "/",
  "displayName": "Example string...required validator",
  "validators": [
    {
      "name": "required"
    }
  ]
}

String Entry Without Default Value

{
  "name": "example_string_without_default",
  "type": "string",
  "displayName": "Example string without a default value"
}

String Entry With Obscured Entry (“Password”)

{
  "name": "example_password_string",
  "type": "string",
  "displayName": "Example password string",
  "multiple": false,
  "widgetHint": "password"
}

String Entry With Hidden Entry (No Visible UI Element)

In this case, no visible UI element is displayed. A value is available for setting, either as a default value or programmatically by other components.

{
  "name": "example_hidden_string",
  "type": "string",
  "displayName": "Example hidden string",
  "defaultValue": "hidden_value",
  "hidden": true,
  "multiple": false
}

Text Area

Designed for multiple lines of text.

{
  "name": "example_textarea",
  "type": "textarea",
  "displayName": "Example text area",
  "location": "last",
  "multiple": false,
  "widgetHint": "textarea"
}

Number Entry

For entering numbers, with increment/decrement arrows (visible either on mouse-over or when the field is in focus) and keyboard arrow activation (up and down arrow keys increase and decrease the value).

{
  "name": "example_number",
  "type": "number",
  "displayName": "Example number",
  "multiple": false
}

Boolean Entry (Checkbox)

{
  "name": "example_boolean",
  "type": "boolean",
  "displayName": "Example boolean",
  "defaultValue": true,
  "multiple": false
}

Radio Choice

Used to create radio button groups.

{
  "type": "string",
  "multiple": false,
  "name": "radio_choice_example",
  "widgetHint": "radio-choice",
  "displayName": "Example radio choice",
  "enumValues": [
    {
      "enumValue": "Binary",
      "realValue": "1"
    },
    {
      "enumValue": "ASCII",
      "realValue": "2"
    },
    {
      "enumValue": "Other",
      "realValue": "3"
    }
  ],
  "defaultValue": "2"
}

Used to create dropdown menu groups.

{
  "name": "enum_example",
  "displayName": "Example menu using enum of values",
  "enumValues": [
    {
      "enumValue": "First Item",
      "realValue": "0"
    },
    {
      "enumValue": "Second Item (default)",
      "realValue": "1"
    },
    {
      "enumValue": "Third Item",
      "realValue": "2"
    }
  ],
  "defaultValue": "1"
}

AWS Region Dropdown Menu Example

This is a longer example showing how properties that a user will need to provide when configuring a connection or activity are not hard-coded. In this sample, the AWS Region for connecting to the Amazon S3 endpoint is something that the user will need to provide. To specify it in the adapter.json and in the UI you could provide a dropdown selection for specifying this:

This code fragment defines the dropdown menu:

{
    "name": "region",
    "displayName": "AWS Region",
    "type": "string",
    "defaultValue": "us-east-1",
    "enumValues": [
        {"realValue": "us-gov-west-1",  "enumValue": "AWS GovCloud (US)"},
        {"realValue": "us-east-1",      "enumValue": "US East (N. Virginia)"},
        {"realValue": "us-east-2",      "enumValue": "US East (Ohio)"},
        {"realValue": "us-west-1",      "enumValue": "US West (N. California)"},
        {"realValue": "us-west-2",      "enumValue": "US West (Oregon)"},
        {"realValue": "eu-west-1",      "enumValue": "EU (Ireland)"},
        {"realValue": "eu-west-2",      "enumValue": "EU (London)"},
        {"realValue": "eu-west-3",      "enumValue": "EU (Paris)"},
        {"realValue": "eu-central-1",   "enumValue": "EU (Frankfurt)"},
        {"realValue": "eu-north-1",     "enumValue": "EU (Stockholm)"},
        {"realValue": "ap-south-1",     "enumValue": "Asia Pacific (Mumbai)"},
        {"realValue": "ap-southeast-1", "enumValue": "Asia Pacific (Singapore)"},
        {"realValue": "ap-southeast-2", "enumValue": "Asia Pacific (Sydney)"},
        {"realValue": "ap-northeast-1", "enumValue": "Asia Pacific (Tokyo)"},
        {"realValue": "ap-northeast-2", "enumValue": "Asia Pacific (Seoul)"},
        {"realValue": "sa-east-1",      "enumValue": "South America (Sao Paulo)"},
        {"realValue": "cn-north-1",     "enumValue": "China (Beijing)"},
        {"realValue": "cn-northwest-1", "enumValue": "China (Ningxia)"},
        {"realValue": "ca-central-1",   "enumValue": "Canada (Central)"}
    ],
    "validators": [{
        "name": "required"
    }]
}

List Object

The List Object is a more sophisticated UI component. At configuration time, it can dynamically generate a list and use a user selection to determine the behavior of the connector:

{
  "name": "list-object",
  "displayName": "Select an XML Schema structure for validating the file",
  "type": "list-object",
  "use": {
    "ui": {
      "pageDescription": "Select an XML Schema structure for validating the file",
      "selectObjectLabel": "Selected Dropbox Object: ",
      "tableHeaders": ["Name", "Description", "Type"],
      "tableItems": ["name", "description", "type"]
     },
     "discoveryType": "provided",
     "orientation": "output",
     "documentIdPath": "this"
   },
   "validators": [{"name": "required"}]
 }

In this code sample, from ProcessFileActivity of the Dropbox connector, the discoverable objects are mapped to data for display. In this example, the values are hard-coded strings. However, they could be dynamically generated and pulled from a database or other data source. The results of the selection at configuration time are used to determine which XSD schema file is used to process the data the connector receives.

  @Override
  public List<DiscoverableObject> getObjectList(DiscoverContextRequest<DiscoverableObjectRequest> objectListRequest)
      throws DiscoveryException {
    List result = new ArrayList<DiscoverableObject>();
    DiscoverableObject obj = new DiscoverableObject();
    obj.setObjectName("account")
      .setObjectType("xsd")
      .setObjectDesc("XML schema associated with Account objects");
    result.add(obj);
    obj = new DiscoverableObject();
    obj.setObjectName("contacts")
      .setObjectType("xml")
      .setObjectDesc("XML schema associated with Contact objects");
    result.add(obj);
    obj = new DiscoverableObject();
    obj.setObjectName("customer")
      .setObjectType("json")
      .setObjectDesc("JSON schema associated with Customer objects");
    result.add(obj);
    return result;
  }

Key-Value Pairs

Used to define a set of properties that a user configuring a connector can enter as a set of key and value pairs.

In this example, from the Jitterbit Harmony Cloud Studio Zendesk Connector, a key (jobStatusMaxRetries) is associated with a display value (enumValue). The Add and Remove buttons are automatically added by the Cloud Studio UI. Note that when first displayed, there will be no values until a user adds them using the Add button.

{
  "name": "key_value_pairs_example",
  "displayName": "Example Key Value Pairs",
  "type": "object",
  "default": "",
  "multiple": true,
  "properties": [
    {
      "name": "name",
      "displayName": "Name",
      "enumValues": [
        {
          "enumValue": "Job Status Maximum Retries",
          "realValue": "jobStatusMaxRetries"
        }
      ],
      "validators": [
        {
          "name": "required"
        }
      ]
    },
    {
      "name": "value",
      "displayName": "Value",
      "type": "number",
      "defaultValue": "300",
      "validators": [
        {
          "name": "required"
        }
      ]
    }
  ]
}

To use this value in a connector, you obtain the value by passing in the connector properties to code such as this:

private String getJobStatusMaxRetries(Map<String, String> props) {
  if (!Objects.isNull(props.get(OPTIONAL_SETTINGS_CONFIGURATION + "." + JOB_STATUS_MAX_RETRIES))) {
    return props.get(OPTIONAL_SETTINGS_CONFIGURATION + "." + JOB_STATUS_MAX_RETRIES);
  } else {
    String config = props.get(OPTIONAL_SETTINGS_CONFIGURATION);
    if (StringUtils.isEmpty(config) || config.equals("[]")) {
      return null;
    }
    config = config.substring(1, config.length() - 1);
    ObjectMapper mapper = createMapper();
    try {
      NameValue nv = mapper.readValue(config, NameValue.class);
      return nv.getValue();
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }
}

This code relies on the use of a JSON parser (such as Jackson), returned by the call to createMapper(), to convert JSON into a Java object. The properties are organized and called using “dot” notation, passing the name of the UI element and the name of the enum’s realvalue field. In the above example, the strings OPTIONAL_SETTINGS_CONFIGURATION and JOB_STATUS_MAX_RETRIES would be:

String OPTIONAL_SETTINGS_CONFIGURATION = "key_value_pairs_example";
String JOB_STATUS_MAX_RETRIES = "jobStatusMaxRetries";

Grouping

Items can be grouped, as shown below. When the checkbox is false, the group that follows it is inactive:

Selecting the checkbox activates the group, allowing entry in both the second and third items:

The code fragment for this:

{
  "name": "example_group",
  "type": "group",
  "displayName": "Example Group",
  "children": [
    {
      "name": "example_group_first_item",
      "type": "boolean",
      "multiple": false,
      "displayName": "Example Group First Item",
      "defaultValue": false
    },
    {
      "name": "example_group_second_item",
      "type": "string",
      "multiple": false,
      "displayName": "Example Group Second Item",
      "location": "last",
      "defaultValue": "1",
      "enumValues": [
        {
          "enumValue": "Postal Code",
          "realValue": "0"
        },
        {
          "enumValue": "ZIP",
          "realValue": "1"
        }
      ],
      "deps": {
        "disabled": {
          "op": "not",
          "args": {
            "op": "prop",
            "args": "example_group_first_item"
          }
        }
      }
    },
    {
      "name": "example_group_third_item",
      "type": "string",
      "multiple": false,
      "displayName": "Example Group Third Item",
      "widgetHint": "password",
      "defaultValue": "",
      "deps": {
        "disabled": {
          "op": "not",
          "args": {
            "op": "prop",
            "args": "example_group_first_item"
          }
        }
      }
    }
  ]
}

Working Example

See the Dropbox connector’s adapter.json file for a working example using many of these UI components.