Introduction

Vantiq constantly strives to make developers successful as quickly and easily as possible. Assemblies allow developers to construct reusable solutions that can be easily integrated and applied in many contexts.
This powerful tool allows developers to raise the level of abstraction and complete full scale applications faster than ever before.

Assemblies are Vantiq Projects that are configurable and customizable to each user’s individual requirements. Assemblies provide higher level functionality than any individual Vantiq resource. They work as a black box, abstracting away any implementation details and only exposing what will be directly used by its consumers.

Developers can now build full scale Applications by composing existing Assemblies, weaving them together through general interfaces, to create custom solutions.

Tutorial

To walk through building your first assembly, check out the tutorial.

Assembly Terminology

Below is a brief glossary of terms used to define Assemblies and how they are used:

  • Assembly: A reusable, shareable, and configurable Vantiq Project
  • Project: A Vantiq Project is a named collection of resources defined in a Namespace
  • Author: The creator of an Assembly is known as its author. This is the person who either built the Project from scratch, or otherwise took an existing project and generalized it into a configurable, reusable Assembly.
  • Publisher: The publisher of an Assembly is the person who publishes an Assembly to the Vantiq Catalog. This is usually the Assembly Author.
  • Consumer: A Consumer is a Vantiq user who installs an Assembly from the Catalog. Consumers configure installed Assemblies and integrate them into their own Projects.

Authoring an Assembly

Assemblies are special instances of Projects (system.projects) with the following properties:

  • name (String): the unique name for the assembly
  • resources (Array of Objects): An array of objects each of the form {resourceReference: </resource>/<resourceId>} defining each of the resources contained by the Assembly.
  • isAssembly (boolean): a boolean flag that must be set to true if the project is an Assembly
  • configurationProperties (Object): A map where each key is the name of the configuration property and the value is the property description. See below for how to define Configuration Properties
  • configurationMappings (Object): An object describing how each configuration property is applied to the Assembly resources. See below for how to define Configuration Properties mappings or usage.
  • visibleResources (Array of Strings): A list of resource references describing which of the Assembly resources are visible to Assembly Consumers. The Services in this list are considered the Assembly Interface.

Assembly Pane

Note: It is highly recommended that Assemblies and all of their resources are contained in Packages. This significantly decreases the likelihood that the Assembly resource names collide with resource names in the consumer’s namespace.

Assembly Interface

An Assembly author’s goal must be to abstract away as many implementation details of the Assembly as possible. While all Assembly resources are always copied into the consumer’s Namespace on Assembly install, by default all resources within the Assembly are hidden from the Consumer. The author must explicitly select which resources to make visible or available for the Consumer.

The resources consumers directly interact with within an Assembly come in two flavors: the Interface and other Visible Resources. The Interface for the Assembly is a list of Event Driven Services that the author exposes. Event Driven Services contain Event Types and Procedures. The Event Types, either inbound or outbound, define how the Consumer communicates with the asynchronous pieces of the Assembly. Consumers send events to the Assembly by publishing to any inbound Event Type. Consumers use Outbound events to trigger any local Rules, Apps, or Collaboration Types. Consumers can also invoke Procedures defined in any of the exposed Services.

Because the Interface is the only mechanism by which Consumers directly interact with any of the Assembly resources, it represents a kind of contract. Best practice highly discourages breaking the contract by removing Services from the Interface or changing how they are defined, once the Assembly is published. Consumers expect and rely on the Event Types and Procedures used to integrate the Assembly into their Project. Removing or modifying existing connection points is almost guaranteed to break consumer Applications. While authors may update Assemblies to change their internal implementations, it is highly encouraged to maintain the Interface or only to add to the Interface between versions.

The Assembly pane allows authors and consumers to view the Interface as either a flat list of Events and Procedures or by Service.

The pane displays the Interface by Events and Procedures by default. Users browse the inbound and outbound Event Types as well as Service Procedures using the left-hand tree. The center of the pane displays information about the selected Event Type or Procedure.

Assembly Interface

Select View By Services in the upper right-hand corner to display the Interface by Service instead. The pane then shows the Service names on the left-hand side, while the center of the pane shows each of the Event Types and Procedures defined by that Service.

Assembly Interface By Service

Services in the Assembly Interface are listed in the Assembly’s visibleResources property by ResourceReference.

For example, the screenshot above shows an Assembly that has two Services in the Interface: WeatherService and apps.services.DetectDangerousWeather. These are added to the visibleResources property as:

 {
    "resourceReference": "/system.services/WeatherService"
 },
 {
    "resourceReference": "/system.services/apps.services.DetectWeatherEmergency"
 }

Visible Resources

The Interface contains the exposed Services within the Assembly that represent the direct integration points. Assembly authors may choose to expose other Assembly resources to the Consumer as Visible Resources. Visible Resources are read-only from the Consumer’s point of view. Any changes to visible Assembly resources are overwritten on Assembly update.

The only resource types that can be exposed as Visible Resources are:

  • App Components
  • Clients
  • Client Components
  • Tests
  • Test Suites
  • Event Generators
  • Documents
  • Storage Managers

The consumer can run, execute, or reuse these resources without considering any of the implementation details of the Assembly itself.

Note: The best practice for Test, Test Suites, and Event Generators made visible to Assembly Consumers is to exclusively use Service Event Types as the Test inputs/outputs and Generator events. This mimics how the Consumers interact with the Assembly and maintains the correct abstractions.

Visible Resources

The visibleResources property of the Assembly instance contains both the Services in the Interface and any other resources that have been made visible. Given the two Services that were added to the Interface in the above section and the two resources shown as visible in the screenshot above, the visibleResources property of the Assembly instance is:

{
"resourceReference": "/system.services/WeatherService"
},
{
"resourceReference": "/system.services/apps.services.DetectWeatherEmergency"
},
{
"resourceReference": "/system.collaborationtypes/isDangerousWeather"
},
{
"resourceReference": "/system.clients/ResidentNotificationSystem"
}

Configuration Properties

Configuration Properties define what is configurable by the Consumer of the Assembly. After a Consumer installs an Assembly they customize the behavior of the Assembly to their requirements by supplying configuration values for each configuration property.

The author of an Assembly must carefully choose which aspects of the Project to make configurable by consumers. This is always a balancing act; too much configuration makes the Assembly hard to use or understand for a consumer, but too little configuration makes the Assembly too specific to be reusable.

Each Configuration Property contains the following properties:

  • type: (String, required): The type of value that the Consumer must provide at configuration time to set this property. The type must be one of the following: String, Integer, Decimal, Real, DateTime, Boolean, Object, User Defined Schema Type, App Component, Client Theme, Secret.
  • description (String, optional): A description of the configuration property
  • required (Boolean, optional): A boolean representing whether the Consumer is required to provide a value for this property at configuration time
  • default (any, optional): For configuration properties that are not required, the author may set a default value that is used if the consumer does not provide a configuration value
  • multi (boolean, optional): A boolean representing whether the Consumer must provide a list of values for this property

Example: If the Assembly exposes a property called sourceTopics that is used to override the topics used by an MQTT source, the configurationProperties property of the Assembly looks like:

{
    "sourceTopics": {
        "description": "topics used by the weather MQTT source to subscribe to",
        "multi": true,
        "required": false,
        "type": "String",
        "default": []
     }
}

Source topics property

Using Configuration Properties to Customize Resources

The author of the Assembly also defines how each Configuration Property is applied to Assembly resources.

In the Usage section of the Configuration Tab, authors specify the resource, resourceId, and property to which the Configuration Property is applied. A Configuration Property may be applied to zero, one, or many resources or properties of a resource.

Source topics property with usage

The Usage section is stored in the configurationMappings property of the Assembly definition. The configurationMappings property of the Assembly definition is a map of the configuration property name to the list of resource properties that it is applied to.

For example the following is a configurationMappings that applies:

  • clientThemeName to the WeatherDisplay and EmergencyNotifications Clients
  • sourceTopics to the topics used by a Source called weather
  • detectionComponent to the App Component used by the isDangerousWeather Task in the DetectDangerousConditions App.
{
    "clientThemeName": [
        {
            "resource":"clients",
            "resourceId": "WeatherDisplay",
            "property": "options.themeName"
        },
        {
             "resource": "clients",
             "resourceId": "EmergencyNotifications",
             "property": "options.themeName"
        }
    ],
    "sourceTopics": [
        {
             "resource": "sources",
             "resourceId": "weather",
             "property": "config.topics"
        }
    ],
    "detectionComponent": [
        {
             "resource": "collaborationtypes",
             "resourceId": "DetectDangerousConditions",
             "property": "assembly.isDangerousWeather.pattern"
        }
    ],
}

It is important to note that not all properties of all resources are configurable. In time, the configuration space for Assembly resources will grow. The properties available for configuration are:

  • App Components: The App Component used within an App may be swapped out for another App Component with the same interface
  • Client Theme. The name of a theme to be applied to a particular client
  • Source Active Property: Sources may be activated or deactivated via configuration
  • Source Configuration: The full config object or any known sub-property of the config object for a given Source. See the Source Configurations section for more details.
  • Scheduled Procedure Interval: The interval (in milliseconds) used by a Scheduled Procedure in a Service contained by the Assembly
  • VAIL Property: A String property referenced in a Procedure or Rule fetched using the ResourceConfig.get(<property>) utility Procedure. See the VAIL Configurations section for more details.
  • Nested Assembly Property: A Configuration Property defined in an Assembly that is a resource of the current Assembly

The configuration properties available for a resource instance may be queried using the following REST call:

Method: GET
URL: /api/v1/resources/<resource>/<resourceId>/_configProperties

This returns a list of properties. Below are a few examples:

  • App Components in an App: assembly.<taskName>.pattern
  • Source configuration: config.<configProperty>
  • Source activate flag: active
  • Client Theme: options.themeName
  • Scheduled Procedure Interval: scheduledProcedures.<procedureName>.interval
  • Nested Assembly Configuration: <nested configuration property name>

Assembly authors may view the configuration by resource by selecting View by Resource in the upper right-hand corner of the Configuration Tab. This view shows each of the configurable Assembly resources in the left-hand tree. Selecting any resource in the tree displays all of its configurable properties and whether that property currently has a Configuration Property that overrides it.