Configuring and Deploying External Plugins
This section details how to configure and deploy external plugins.
Extension Configuration
Extension Configuration can be used for multiple purposes:
- To disable extensions that are normally activated by an
@XPFAssignment
annotation. - To override the priority of an extension.
- To assign extensions to extension points, optionally based on criteria specified in selectors.
- To pass setting values to extensions.
Add the extensions file
To add an extensions.json
file to extensions/plugins/ext-plugin-config/src/main/resources
, use the following example:
{
"extensions": [
{
"identifier": {
"pluginId": "elasticpath-collectipinorderdata-*",
"extensionClass": "com.elasticpath.plugins.collectipinorderdata.extensions.IPOrderDataPopulator",
"extensionPointKey": "ORDER_DATA_POPULATOR"
},
"enabled": true,
"priority": 50,
"defaultSelectorMode": "DEFAULT_NONE",
"selectors": [
{
"type": "XPFExtensionSelectorByStoreCode",
"value": "mobee"
}
],
"settings": [
{
"settingKey": "IP_ADDRESS_HEADER",
"dataType": "SHORT_TEXT",
"collectionType": "SINGLE",
"settingValues": [
{
"value": "X-Forwarded-For"
}
]
},
{
"settingKey": "SAMPLE_MAP",
"dataType": "INTEGER",
"collectionType": "MAP",
"settingValues": [
{
"key": "mobee",
"value": 10
},
{
"key": "kobee",
"value": 20
}
]
}
]
}
]
}
Fields
Field | Purpose | Required? |
---|---|---|
extensions[*].identifier.pluginId | Specifies the plugin ID of the plugin that contains the extension class being configured. Note: The * character can be used as a wildcard to allow the configuration to match all plugin versions. If not specified, then the Extension Point Framework assumes that you are configuring an embedded extension. | No |
extensions[*].identifier.extensionClass | Specifies the fully-qualified name of the extension class being configured. If not specified, then the Extension Point Framework assumes that you are configuring an embedded extension. | Yes |
extensions[*].identifier.extensionPointKey | Specifies the name of the XPFExtensionPointEnum enum that the extension class is (or should be) assigned to. | Yes |
extensions[*].enabled | If set to false , the extension class will not be assigned to the Extension Point even if it contains an @XPFAssignment annotation. If not defined, the value will only be enabled if there is an @XPFAssignment annotation on the extension class. | No |
extensions[*].priority | Specifies the priority for the extension. Overrides any value specified by the @XPFAssignment annotation. If not defined, the value will default based on the priority value from the @XPFAssignment annotation on the extension, or Integer.MAX_INT (the lowest priority) if no annotation exists. | No |
extensions[*].defaultSelectorMode | If set to DEFAULT_ALL , then the extension is automatically assigned to all selectors EXCEPT the ones specified in the selectors list. If set to DEFAULT_NONE , then the extension is only assigned to the selectors specified in the selectors list. | Yes |
extensions[*].selectors[*].type | The type of selector to use to determine if the extension should be invoked. Currently Elastic Path Commerce only supports XPFExtensionSelectorByStoreCode which uses the current Cortex scope to determine which extensions to activate. | Yes |
extensions[*].selectors[*].value | The selector value to use to determine if the extension should be invoked. If the type is set to XPFExtensionSelectorByStoreCode , then this represents the Cortex scope (aka store code). | Yes |
extensions[*].settings[*].settingKey | The identifier for a setting value that the extension expects to receive. | Yes |
extensions[*].settings[*].dataType | The data type of the setting value. The following data types are supported: SHORT_TEXT , INTEGER , DECIMAL , BOOLEAN , DATE | Yes |
extensions[*].settings[*].collectionType | The collection type (cardinality) of the setting value. The following data types are supported: SINGLE , LIST , SET , MAP | Yes |
extensions[*].settings[*].settingValues[*].key | The key for the setting value. Only supported for settings with collection type MAP . | No |
extensions[*].settings[*].settingValues[*].value | The setting value. | Yes |
Plugin Configuration
Plugin Configuration is typically used to pass setting values to extensions. Any plugins found in the plugin folder will be loaded regardless of whether a plugins.json
folder exists or if an entry exists for the plugin.
Add the plugins file
To add a plugins.json
file to extensions/plugins/ext-plugin-config/src/main/resources
, use the following example:
{
"plugins": [
{
"identifier": {
"pluginId": "elasticpath-collectipinorderdata-*"
},
"settings": [
{
"settingKey": "IP_ADDRESS_HEADER",
"dataType": "SHORT_TEXT",
"collectionType": "SINGLE",
"settingValues": [
{
"value": "X-Forwarded-For"
}
]
},
{
"settingKey": "SAMPLE_MAP",
"dataType": "INTEGER",
"collectionType": "MAP",
"settingValues": [
{
"key": "mobee",
"value": 10
},
{
"key": "kobee",
"value": 20
}
]
}
]
}
]
}
Fields
Field | Purpose | Required? |
---|---|---|
plugins[*].identifier.pluginId | Specifies the plugin ID of the plugin that you are configuring. Note: The * character can be used as a wildcard to allow the configuration to match all plugin versions. | No |
plugins[*].settings[*].settingKey | The identifier for a setting value that the plugin expects to receive. | Yes |
plugins[*].settings[*].dataType | The data type of the setting value. The following data types are supported: SHORT_TEXT , INTEGER , DECIMAL , BOOLEAN , DATE | Yes |
plugins[*].settings[*].collectionType | The collection type (cardinality) of the setting value. The following data types are supported: SINGLE , LIST , SET , MAP | Yes |
plugins[*].settings[*].settingValues[*].key | The key for the setting value. Only supported for settings with collection type MAP . | No |
plugins[*].settings[*].settingValues[*].value | The setting value. | Yes |
Placeholders
The value
field for plugin and extension settings can be specified as a placeholder. This can be useful if the values are environment-specific or if the values are sensitive. If the values are sensitive so we don’t want them included in the configuration files directly.
For these circumstances, the value can be replaced with a placeholder key that is specified by enclosing the key with ${
and }
, as in the following example:
{
"settingKey": "PAYMENT_USERNAME",
"dataType": "SHORT_TEXT",
"collectionType": "SINGLE",
"settingValues": [
{
"value": "${payment.username}"
}
]
}
You can resolve placeholder values through any of the following means:
JVM
parameter, such as-Dpayment.username=bob
.- System environment variable, such as
export payment.username=bob
. ep.properties
, in any of the locations documented here.
note
For local development, one convenient place to store placeholders is in extensions/database/ext-data/src/main/resources/environments/local/files/conf/ep.properties
. Ensure that you run mvn install -Preset-conf
from the extensions/database
module to copy this file to your local ${user.home}/ep/conf/ep.properties
.
If a placeholder key can’t be resolved, the Elastic Path Commerce service will throw an exception at startup.
Plugin Deployments
To add new external plugins to your project, add a Maven dependency to the ext-plugin-config
module.
note
This dependency could come from a public repository hosted by Elastic Path or another vendor, or it could come from a custom plugin build that publishes to your project Nexus.
The following is an example of this plugin definition:
<dependencies>
<dependency>
<groupId>com.elasticpath.plugins</groupId>
<artifactId>vip-only-products</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
Advanced Deployment Details
At startup, all Elastic Path Commerce services scan a specific folder for plugin JARs, extension configuration, such as extensions.json
and plugin configuration, such as plugins.json
. Any JARs found in this folder that contain the expected manifest entries will be loaded and started automatically. The plugin folder is determined by the value of the ep.plugins.folder
JVM
parameter. If this parameter is not set, ${user.home}/ep/plugins
will be used by default.
The ext-plugin-config
project is a convenient mechanism for ensuring that both project developers starting services locally and deployed Docker images have access to the same plugins and configuration. All of the plugin JARs and configuration files are collected into the target
folder when mvn install
is executed. When the deployment package is generated, the contents of the ext-plugin-config
module assembly are included in a plugins
folder within the deployment package assembly.
For local services started with mvn tomcat8:run-war
, the ep.plugins.folder
parameter is set to extensions/core/ext-plugin-config/target/plugins
by default. This causes the local services to automatically load all artifacts from that folder at startup.
For CloudOps deployments, the Deployment Package assembly is downloaded from Nexus during the Docker Image Build step, and the contents of the plugins
folder is copied into the /ep/plugins
folder of the Docker image. CloudOps also sets the ep.plugins.folder
JVM
parameter to the same folder. This causes the service within the Docker image to find and load the External Plugins at startup. To rollback to a previous state without the plugin or with a prior version of the plugin, simply deploy the previous version of the service Docker images.