ThingWorx Extension Development Guide 1
ThingWorx Extension Development Guide 1
ThingWorx Extension
Development Guide
Version 4.5
June 2018
3
Contents
5 7
2 3
Introduction to Extensions Creating Extensions
What is an Extension? ...............................................................................................10
Extension Zip File Structure .......................................................................................12
Why Build an Extension? ...........................................................................................10
Metadata.xml File ......................................................................................................12
Entities Created in ThingWorx Composer ....................................................................24
Java-Based Entities...................................................................................................25
Extension Migrators...................................................................................................46
Third-Party JAR Files.................................................................................................47
Adding Custom Widgets ............................................................................................48
Extension Import and Management ............................................................................49
Entity Characteristic Support ......................................................................................51
You can create ThingWorx extensions using common editors and development
tools, as long as the artifacts are created following the expected convention and
are packaged in the expected structure. This section explains how these artifacts
must be created so they work correctly after being imported into ThingWorx.
Tip
Because it can be challenging to correctly build the various pieces of an
extension, the Eclipse Plugin for ThingWorx Extension Development (Eclipse
Plugin) has been created to help developers build extensions quickly and
concentrate on developing their features rather than worrying about getting the
extension structured correctly. The productivity improvements provided by the
Eclipse Plugin make it a compelling tool to use when building ThingWorx
extensions. For more information, see Use the Eclipse Plugin.
9 11
<ExtensionPackage For example:
name=”MyExtension” <Entities>
packageVersion="1.0.0" <ThingPackages>
vendor="ThingWorx – A PTC Business" <ThingPackage name="MyThingPackage"
description="My Extension description" description="A description"
minimumThingWorxVersion="7.1.0" className="com.acmecorp.things.MyThingTemplate" />
dependsOn="ExtensionOne:2.5.1,ExtensionTwo:1.2.0"> </ThingPackages>
</ExtensionPackage> <ThingTemplates>
</ExtensionPackages> <ThingTemplate name="MyThingTemplate"
</Entities> description="My Thing Template description"
thingPackage="MyThingPackage">
</ThingTemplates>
</Entities>
Tip
If you are using the Eclipse Plugin, the New ThingWorx Project action will
generate a new metadata.xml file and fill in the details. For more Tip
information, see Creating an Extension Project.
If you are using the Eclipse Plugin, the New Thing Template action will
generate the necessary elements in the metadata.xml file and fill in the
<ExtensionPackage> details. For more information, see Creating Entities.
Attribute Description
name The name of the extension. This is a required
attribute whose value must follow the naming
convention for ThingWorx entities.
Note
packageVersion The version of the extension. This is a required
attribute whose value must follow the If a Java-based extension defines a thing template as Java classes using
<major>.<minor>.<patch> format, annotations but they are not included in the entity’s metadata.xml file,
where each part of the version is numeric. ThingWorx cannot detect if the entity’s base template changed and the import
Extensions should follow the semantic of the extension will fail.
versioning rules outlined at http://www.semver.
org. <ThingPackage> Attribute Description
vendor The name of the organization that created the name The name of the thing package. This is a
extension. This is an optional attribute. required attribute whose value must follow
description Information about what the extension does. the naming convention for ThingWorx
This is an optional attribute that is displayed in entities.
the Manage Extensions screen of Composer. description Provides information about the thing
package. This is an optional attribute.
minimumThingWorxVersion Specifies the minimum version of ThingWorx
with which the extension is compatible. This is className The fully-qualified Java class name of the
a required attribute whose value must follow ThingTemplate class that corresponds to
the <major>.<minor>.<patch> format, the thing package. This is a required
where each part of the version is numeric. If attribute.
you try to import the extension into a version of
ThingWorx that is older than what is specified
in this attribute, it will fail.
You can override the following methods from the thing superclass to add custom
functionality in the thing template (see the Javadoc documentation for the com.
Tip thingworx.things.Thing class for more information):
If you are using the Eclipse Plugin, the Import ThingWorx Entities action places • protected void cleanupThing() throws Exception;
the files in the correct location in the project. For more information, see • protected void initializeThing() throws Exception;
Importing Composer-Created Entities.
• protected void
preprocessSetPropertyVTQ(ThingProperty, VTQ, boolean)
throws Exception;
Java-Based Entities • protected void processStartNotification();
Java-based entities created in an extension are basically the same as those created • protected void startThing() throws Exception;
in ThingWorx Composer. They can also define services, properties, events, • protected void stopThing() throws Exception;
configuration parameters, and so on.
For example, you can override the initializeThing() method. This method
The main difference between the two types of entities is that Composer-created is called when the thing is created or saved. It is used to set up any functionality
entities use JavaScript for services, and their source code is visible in Composer. needed for your Java code to function properly. It may be used to create a data
Java-based entities use Java for services, and the source code is not visible in table and associate it with your thing when the thing is created. This is
Composer. Java-based entities can also define configuration values and lifecycle accomplished by checking for the existence of the data table before creating it,
behavior. since the same method is called when the thing is saved.
Tip
Note
If you are using the Eclipse Plugin, the New Script Function Library action will
The parameter classes and exceptions used in these methods are part of the
generate the Java source file with the appropriate annotations and
javax.servlet third-party JAR, which must be in the build path for the custom
automatically update the metadata.xml file. For more information, see
authenticator to compile. However, this JAR is a compile-time dependency
Creating Entities.
only and must not be added as part of the extension itself.
Note
If you are using the Eclipse Plugin, the Add Property action will add the
necessary property annotations described below to the Java source file. See
Adding Services, Properties, Configuration Tables, Subscriptions, and Events
for more information.
XML Import/Export
You can also define configuration tables on things, thing templates, thing shapes,
and mashups through XML imports. The following is a configuration table
definition for an entity exported as XML:
<ConfigurationTableDefinitions>
<ConfigurationTableDefinition category="TemplateConfigTables"
dataShapeName="MyDS" description="Template Config Table" isHidden=
"false"
isMultiRow="true" name="ConfigTableOnTemplate" ordinal="2" source=
"REST"/>
</ConfigurationTableDefinitions>
Note
Configuration table defintions created by annotations do not appear in exported
XML.
@ ThingworxSubscription Description
Attribute Note
source The name of the entity, which is the source of Extension migrators are designed for migrating entities only. Stream data
the event. A blank value indicates that the associated with extension entities must be updated by other means before
event originates from the entity itself. importing into the new system.
eventName The name of the event to which you want to
subscribe.
sourceProperty The name of the property associated with the
event. It’s only applicable for the Alert, Third-Party JAR Files
AlertAck, AlertReset, and DataChange events. The /lib folder contains the JAR file including the custom Java classes written
handler The name of the service that should be for the extension and additional third-party JAR files required by the extension.
invoked whenever the subscription receives an
For example:
event. /lib
The service should have the following /MyExtension.jar
signature and be annotated appropriately as a /ThirdPartyLib.jar
ThingWorx service: For each of these JAR files, you must create an entry in the metadata.xml file. For
public void more information, see metadata.xml File.
HandleEvent(InfoTable eventData,
String eventName, DateTime
eventTime, String source, String Tip
sourceProperty)
If you are using the Eclipse Plugin, the New Jar Resource action will update
enabled Indicates if the subscription should listen for the metadata.xml file automatically. For more information, see Adding Third-
events Party JAR Files.
For more information, see the Javadoc documentation for
com.thingworx.metadata.annotations.ThingworxSubscrip
tion.
For example: Caution
@ThingworxSubscriptions( subscriptions = { Do not include third-party JAR files from your extension that are already
@ThingworxSubscription( source = "", eventName = "MyEvent", included in the ThingWorx Platform.
sourceProperty = "", handler = "MyService", enabled = "true" )
})
To get started using the Eclipse Plugin for ThingWorx Extension Development, do In the Java editor of the entity, right-click to access the ThingWorx Source
the following: menu.
1. In Eclipse, choose File ▶ New ▶ Project.... From the submenu, you can choose to add a service, property, configuration
table, subscription, or event.
2. In the New Project screen, expand the ThingWorx menu, select ThingWorx
Extension Project, and click Next. 2. Enter the necessary information in the wizard and click Finish.
3. Enter a project name and browse to and select the latest ThingWorx- The Java and metadata.xml files are updated with the necessary annotations
Extension-SDK-[version]-latest.zip file. and XML elements.
4. Select Gradle or Ant as the build framework for the extension.
Ant Build
In the Package Explorer, right-click build-extension.xml and choose Run As ▶ Ant
Build.
After refreshing your project, a zip file appears under build ▶ distributions. This is
a working extension that you can import into ThingWorx.
7
Appendix A: Examples
Platform Integration Example using Twitter..................................................................70
Example using Tomcat Monitor GUI and Eclipse ..........................................................70
HelloWorldThing .......................................................................................................71
GoodByeThing..........................................................................................................73
Common Code Snippets ............................................................................................76
HelloWorldThing
package com.helloinc.things.helloworld;
69 Appendix A: Examples 71
public void initializeThing() throws Exception {
} super.initializeThing();
@ThingworxServiceDefinition(name = "SayHello", description = "Hello world") _logger.warn("****** Initializing GoodByeThingInstance " + getName());
@ThingworxServiceResult(name = "Result",
description = "Result", baseType = "STRING")
// Examples of getting the configuration table values
public String SayHello() throws Exception {
String field1Value = (String)getConfigurationSetting("ConfigTableExample1", "field1");
File Management
The file system for ThingWorx does not have a guaranteed static path that can be
referenced. For this purpose, there is a FileRepositoryThing template that is used
to store and access files. The File Repository thing has services, such as
openFileForWrite() and openFileForRead(), that allow you to access files that are
stored in unique locations based on the file repository thing you are using.
Similarly, if you need to upload a file with an extension, then it should be done
through a JAR on the classpath, since the location of an uploaded file may not be
known. Here is an example using the file repository thing and a file pulled from
the classpath:
public String exportResource(String resourceName,
FileRepositoryThing repo) throws Exception {
try {