Best Practices for Packaging and Deploying ThingWorx Solutions
Use the following best practices while developing and deploying extensions.
Develop on a Clean Platform Instance
ThingWorx does not provide safeguards or sandboxing for your code. It is possible that sometimes your environment may become unstable. To get the solution out of the unstable state, do the following:
• If you see errors in the development process, restart the Apache Tomcat server.
• You may be prompted to remove the ThingworxStorage directory completely. It is recommended that you develop the solution on a clean instance of the ThingWorx Platform to ensure that no work is lost when you remove the ThingWorxStorage directory.
Structure of an Extension
The artifacts of an extension must be packaged into a ZIP file in the following folder structure:
• /metadata.xml—Information about the extension and details of the various artifacts in the extension.
• /Entities/—Zero or more entity XML files organized in subfolders by entity type.
• /lib/—JAR file that includes the custom Java classes for the extension and third-party JAR files required by the extension.
• /ui/—Files that define custom widgets used to build and run mashups.
Bundle Multiple Extensions in One ZIP File for a Solution
IoT solutions that contain multiple extensions can be bundled as a single ZIP file. The single ZIP file contains individual ZIP files for each extension. This ensures that every extension is independently implemented. Individual extensions are easier to update in subsequent releases.
Extension Name and Version Convention
There are no restrictions on how you name your extension and the ZIP file of an extension. Note that after you specify a name for the extension, you cannot change it. However, the name of the ZIP file can be changed.
Though you can specify different names for the extension and its ZIP file, it is recommended to have the same name for the extension and its ZIP file. The ZIP file name can also contain the version number.
You can have an IoT solution that contains multiple extensions bundled as a ZIP of ZIPs. In this case, it is recommended to have the same release number for all ZIPs. Consider an IoT solution that contains two extensions. Each extension is a single ZIP file with an individual release number. It is good practice to specify the same release number in the name of the two extensions. Also, specify the same release number in the name of the ZIP of ZIPs. For example, if the release number of your IoT solution is 7.9, specify 7.9 as the release number in the name of all the ZIP files.
In the
metadata.xml file, the attribute
packageVersion is used to specify the version of the extension. This is a required attribute, whose value follows the
<major>.<minor>.<patch> format, where each part of the version is numeric. Extensions must follow the semantic versioning rules. See
Semantic Versioning for more information.
HA Compatibility Metadata Attribute
With ThingWorx 9.0; a new metadata attribute, haCompatible is supported to identify if an extension will work correctly in a ThingWorx High Availability cluster. Add haCompatible":"TRUE" to the extension metadata to identify that the extension will work in an HA landscape. You can set the haCompatible attribute to FALSE to identify that the extension is not HA-compliant and should not be imported into an HA landscape.
We strongly recommend using the
haCompatible attribute on all extensions. For more information on configuring the
ThingWorx Platform to control import of extension for HA compatibility, see
platform-settings.json Configuration Details and
Platform Settings for ThingWorx HA.
Dependency of the Extension on Other Extensions
If your extension has a dependency on other extensions, it is recommended to use the dependsOn attribute in the metadata.xml file to specify the dependencies. The value of the attribute is a comma-separated list of extension names and versions in the <name>:<major>.<minor>.<patch> format, where versions are specified only in numbers. For example, dependsOn= "ExtensionOne:2.5.1,ExtensionTwo:1.2.0".
It is a good practice to avoid too many dependencies. If there are upgrades to any of the extensions, dependent extensions are also affected.
Avoid Tight Coupling to Other Extensions
You must avoid tight coupling of your extension to other extensions.
• If your extension is tightly coupled to another extension that must be upgraded to a new major version, you are prompted to delete your extension and its entire chain of dependencies before you can perform the upgrade.
• The best way to do avoid tight coupling is to create Things and Thing Templates of the functionality you require. These Things and Thing Templates are not part of your extension, and therefore, are not included in the extension upgrades.
• Occasionally, it can be difficult to avoid tight coupling when you use widgets from other extensions in your extension mashups.
Size of an Extension
Large and complex extensions can be difficult to maintain and upgrade. A better approach it to split extensions into smaller components based on functionality for easier maintenance and upgrade. You can bundle multiple extensions in a single ZIP file. See the section
Bundle Multiple Extensions in One ZIP File for a Solution, for more information.
Use of External JAR Files in an Extension
ThingWorx enables users to include third-party libraries in their code. However, it is recommended that you avoid using the common JAR files. Instead, use the JAR files that are packaged with the SDK in your solution. Consider the following:
• You can use existing JAR files from the /Thingworx/WEB-INF/lib folder in your extension. However, if you want to use an external JAR file in your extension, then ensure that the JAR file must not have the same root name as any of the other JAR files present in the /Thingworx/WEB-INF/lib folder.
The root name of a JAR file is its name from the first character until the first numeric character in the file name. The table provides the root names of the following JAR files that are present in the /Thingworx/WEB-INF/lib folder:
JAR File Name
|
Root Name
|
postgresql-42.2.5.jar
|
postgresql-
|
log4j-1.2.17.jar
|
log
|
metrics-core-3.1.2.jar
|
metrics-core-
|
• The ThingWorx Platform enables multiple sources to use the same JAR files.
• When multiple sources use the same JAR files, a conflict can occur when uploading an extension to the ThingWorx Platform, or when an incorrect JAR version is used while building the extension.
• Future versions of the ThingWorx Platform may require updates to extensions to continue working.
• A customer cannot use two extensions that require the same JAR files at the same time.
Make Your Entities Non-Editable
When you create entities, such as mashups, style definitions, and so on, make sure that the entities of the extension are non-editable. Only non-editable entities can be upgraded in place. Editable entities cannot be upgraded. By default, new entities are non-editable.
• If you want to have some entities editable, bundle these entities in a separate extension, so that you can easily upgrade the other components of the extension.
• For editable entities, it is recommended to minimize the editable locations on a mashup. Use embedded mashups to minimize editable locations.
If you want to provide the ability to customize the extension, for example, adding a custom logo, consider whether an alternative approach can work:
• Can configuration of a Thing be used instead? A non-editable Thing can still have configuration table changes.
• Can a service be used to look up a configuration to provide a media entity or an embedded mashup?
|
Thing Templates, which are based on Java classes, should never be edited. Hence, setting the aspect.isEditableExtensionObject attribute on a Thing Template is not supported.
|
Duplicating Extension Entities
When an entity is duplicated, everything except the name is cloned. The same is true when duplicating extension entities, but if an extension entity has an extension project set, this field gets carried over as well. If you attempt to save this entity, it will fail because it is attempting to assign the entity to the extension project, which is not allowed.
If you duplicate an extension entity that has an extension project assigned, you must clear that field and set a new, non-extension project. If you use the CloneThing API, you must use the SetProject service to set a project. If a project is not assigned, it will automatically get assigned to the PTCDefaultProject.
If an editable extension entity is imported into 9.1 and later, the project field for the entity will be read-only after importing the extension, and will retain its project setting from before the upgrade. Whether a project is assigned or the Project field is blank, that value is retained.
Upgrade an Extension with Editable Entities
While upgrading an extension with editable entities, perform a migration test to check if any information, such as tags, is lost during the upgrade process.
Organize Entities
It is recommended to group entities using projects and model tags. You must use one project for all the entities of the extension. Create at least one model tag that can be used to tag all the entities of your extension.
Back Up the Storage Before Deleting
It is recommended that you back up your current ThingworxStorage folder before deleting it.
Eclipse Plugin
The Eclipse Plugin makes it easier to develop and build extensions. It provides actions that automatically generate source files, annotations, and methods. The actions also update the metadata file to ensure proper configuration of the extension. The plugin also ensures that the syntax and format of annotations and the metadata file are correct.
For more information about the Eclipse Plugin, see
Using the Eclipse Plugin.