...
FlexDeploy plugins are implemented in Java and are installed on the FlexDeploy server for use within workflows. These plugins are automatically distributed to the endpoints where they are defined to execute. A plugin consists of four components:
- Java Implementation (See Plugin SDK API documentation)
- XML metadata describing its operations, properties, and other behavior
- Setup scripts (optional) to initialize the environment prior to execution
- Required 4.5.0 .3 FlexDeploy libraries (download here)
Reference Example
A fully functional plugin example for Apache HTTP Server, including source code, is provided for reference throughout this documentation. This plugin provides four operations
- build - packages web server content into a zip file artifact
- deploy - deploys the zip file artifact produced during build to an Apache HTTP Server
- start - starts an Apache HTTP Server
- stop - stops an Apache HTTP Server
...
Plugin Lifecycle
Each plugin operation (e.g. build, deploy, start, stop) is implemented by extending AbstractPluginProvider.
Code Block | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
public class Build extends AbstractPluginProvider { private static final String CLZ_NAM = Build.class.getName(); private static final FlexLogger LOG = FlexLogger.getLogger(CLZ_NAM); public Build() { super(); } @Override public PluginResultvoid executevalidate() throws FlexCheckedException { //TODO } @Override public voidPluginResult validateexecute() throws FlexCheckedException { //TODO } @Override public void cleanup() { //TODO } } |
...
The cleanup method is responsible for freeing any resources utilized by the plugin operation. Examples would be closing connections, deleting files, etc. Note that the cleanup method is provided as an empty implementation by the abstract class, and can be overridden by the concrete subclasses as needed.
...
Workflow Execution Context
...
Code Block | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
protected Boolean getBooleanInput(String pInputName) protected Boolean getBooleanInputOrDefault(String pInputName, Boolean pDefault) protected Double getDoubleInput(String pInputName) protected Double getDoubleInputOrDefault(String pInputName, Double pDefault) protected String getStringInput(String pInputName) protected String getStringInputOrDefault(String pInputName, String pDefault) protected Integer getIntegerInput(String pInputName) protected Integer getIntegerInputOrDefault(String pInputName, Integer pDefault) protected Long getLongInput(String pInputName) protected Long getLongInputOrDefault(String pInputName, Long pDefault) protected String getStringProjectPropertyValue(String pKey) protected String getStringProjectPropertyValueOrDefault(String pKey, String pDefault) protected String getStringInstancePropertyValue(String pInstanceCode, String pKey) protected String getStringInstancePropertyValueOrDefault(String pInstanceCode, String pKey, String pDefault) protected String getStringCurrentInstancePropertyValue(String pKey) protected String getStringCurrentInstancePropertyValueOrDefault(String pKey, String pDefault) protected Double getDoubleProjectPropertyValue(String pKey) protected Double getDoubleProjectPropertyValueOrDefault(String pKey, Double pDefault) protected Double getDoubleInstancePropertyValue(String pInstanceCode, String pKey) protected Double getDoubleInstancePropertyValueOrDefault(String pInstanceCode, String pKey, Double pDefault) protected Double getDoubleCurrentInstancePropertyValue(String pKey) protected Double getDoubleCurrentInstancePropertyValueOrDefault(String pKey, Double pDefault) protected Integer getIntegerProjectPropertyValue(String pKey) protected Integer getIntegerProjectPropertyValueOrDefault(String pKey, Integer pDefault) protected Integer getIntegerInstancePropertyValue(String pInstanceCode, String pKey) protected Integer getIntegerInstancePropertyValueOrDefault(String pInstanceCode, String pKey, Integer pDefault) protected Integer getIntegerCurrentInstancePropertyValue(String pKey) protected Integer getIntegerCurrentInstancePropertyValueOrDefault(String pKey, Integer pDefault) protected Boolean getBooleanProjectPropertyValue(String pKey) protected Boolean getBooleanProjectPropertyValueOrDefault(String pKey, Boolean pDefault) protected Boolean getBooleanInstancePropertyValue(String pInstanceCode, String pKey) protected Boolean getBooleanInstancePropertyValueOrDefault(String pInstanceCode, String pKey, Boolean pDefault) protected Boolean getBooleanCurrentInstancePropertyValue(String pKey) protected Boolean getBooleanCurrentInstancePropertyValueOrDefault(String pKey, Boolean pDefault) protected Long getLongProjectPropertyValue(String pKey) protected Long getLongProjectPropertyValueOrDefault(String pKey, Long pDefault) protected Long getLongInstancePropertyValue(String pInstanceCode, String pKey) protected Long getLongInstancePropertyValueOrDefault(String pInstanceCode, String pKey, Long pDefault) protected Long getLongCurrentInstancePropertyValue(String pKey) protected Long getLongCurrentInstancePropertyValueOrDefault(String pKey, Long pDefault) |
Logging
Logging can be performed in plugin implementations by using the FlexDeployLogger class. The logger is statically initialized using the following two lines of code. Note that in this example Build would be replaced by the actual class name of the current class.
...
Code Block | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
public void logInfo(String pMethodName, String pMessage) public void logInfo(String pMethodName, String pMessage, Object... pParams) public void logInfo(String pMethodName, String pMessage, Throwable pThrowable) public void logSevere(String pMethodName, String pMessage) public void logSevere(String pMethodName, String pMessage, Object... pParams) public void logSevere(String pMethodName, String pMessage, Throwable pThrowable) public void logWarning(String pMethodName, String pMessage) public void logWarning(String pMethodName, String pMessage, Object... pParams) public void logWarning(String pMethodName, String pMessage, Throwable pThrowable) public void logConfig(String pMethodName, String pMessage) public void logConfig(String pMethodName, String pMessage, Object... pParams) public void logConfig(String pMethodName, String pMessage, Throwable pThrowable) public void logFine(String pMethodName, String pMessage) public void logFine(String pMethodName, String pMessage, Object... pParams) public void logFine(String pMethodName, String pMessage, Throwable pThrowable) public void logFiner(String pMethodName, String pMessage) public void logFiner(String pMethodName, String pMessage, Object... pParams) public void logFiner(String pMethodName, String pMessage, Throwable pThrowable) public void logFinest(String pMethodName, String pMessage) public void logFinest(String pMethodName, String pMessage, Object... pParams) public void logFinest(String pMethodName, String pMessage, Throwable pThrowable) public void logInfoEntering(String pMethodName) public void logInfoExiting(String pMethodName) public void logInfoEntering(String pMethodName, Object... pParams) public void logInfoExiting(String pMethodName, Object pParam) public void logFinerEntering(String pMethodName) public void logFinerExiting(String pMethodName) public void logFinerEntering(String pMethodName, Object... pParams) public void logFinerExiting(String pMethodName, Object pParam) public void logFineEntering(String pMethodName) public void logFineExiting(String pMethodName) public void logFineEntering(String pMethodName, Object... pParams) public void logFineExiting(String pMethodName, Object pParam) public void logFinestEntering(String pMethodName) public void logFinestExiting(String pMethodName) public void logFinestEntering(String pMethodName, Object... pParams) public void logFinestExiting(String pMethodName, Object pParam) |
Plugin XML Metadata
The plugin XML metadata (plugin.xml) defines information about the plugin, its operations, and its behavior. This XML file is bundled with the plugin Java class files and is used to integrate into the FlexDeploy platform.
Code Block | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
<xsd:schema targetNamespace="http://flexagon.com/deploy/plugin" xmlns="http://flexagon.com/deploy/plugin" xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified"> <xsd:element name="PluginDefinition"> <xsd:complexType> <xsd:sequence> <xsd:element type="xsd:string" name="Name"/> <xsd:element type="xsd:string" name="PluginDisplayName" minOccurs="0" maxOccurs="1"/> <xsd:element type="xsd:string" name="Description"/> <xsd:element type="xsd:string" name="TechnologyGroup"/> <xsd:element type="xsd:string" name="SubTechnologyGroup"/> <xsd:element type="xsd:string" name="Vendor"/> <xsd:element type="xsd:int" name="MaxConcurrentThreads"/> <xsd:element type="xsd:string" name="Version"/> <xsd:element name="ResourceTypes" minOccurs="0" maxOccurs="1"> <xsd:complexType> <xsd:sequence> <xsd:element type="xsd:string" name="Resource" maxOccurs="unbounded" minOccurs="1"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="Operations"> <xsd:complexType> <xsd:sequence> <xsd:element name="Operation" maxOccurs="unbounded" minOccurs="1"> <xsd:complexType> <xsd:sequence> <xsd:element type="xsd:string" name="Name"/> <xsd:element type="xsd:string" name="Description"/> <xsd:element type="xsd:string" name="Target"/> <xsd:element name="PropertyKeys"> <xsd:complexType> <xsd:sequence> <xsd:element type="xsd:string" name="PropertyKey" maxOccurs="unbounded" minOccurs="0"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="Inputs"> <xsd:complexType> <xsd:sequence> <xsd:element type="xsd:boolean" name="AllowsUserDefined" maxOccurs="1" minOccurs="1"/> <xsd:element name="Input" maxOccurs="unbounded" minOccurs="0"> <xsd:complexType> <xsd:sequence> <xsd:element type="xsd:string" name="Name" maxOccurs="1" minOccurs="1"/> <xsd:element type="InputDataTypeEnum" name="DataType" maxOccurs="1" minOccurs="1"/> <xsd:element type="xsd:string" name="Description" maxOccurs="1" minOccurs="1"/> <xsd:element type="xsd:string" name="DisplayName" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:string" name="DefaultValue" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:string" name="IsDefaultValueExpression" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:string" name="SubDataType" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:string" name="IsRequired" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:string" name="IsEncrypted" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:long" name="MinValue" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:long" name="MaxValue" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:string" name="ListData" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:int" name="DisplayRows" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:int" name="DisplayColumns" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:int" name="LengthPrecision" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:string" name="ValidatorScript" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:string" name="IsMultiselect" maxOccurs="1" minOccurs="0"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="Outputs"> <xsd:complexType> <xsd:sequence> <xsd:element type="xsd:boolean" name="AllowsUserDefined" maxOccurs="1" minOccurs="1"/> <xsd:element type="xsd:string" name="Output" maxOccurs="unbounded" minOccurs="0"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="EndPointSpecification"> <xsd:complexType> <xsd:sequence> <xsd:element name="Selection"> <xsd:complexType> <xsd:choice> <xsd:element type="xsd:string" name="All"/> <xsd:element type="xsd:string" name="Resource"/> <xsd:element type="xsd:string" name="Delegated"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="Execution"> <xsd:complexType> <xsd:choice> <xsd:element type="xsd:string" name="Any"/> <xsd:element type="xsd:string" name="All"/> <xsd:element type="xsd:string" name="Delegated"/> </xsd:choice> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element type="ConsumesArtifactsEnum" name="ConsumesArtifacts"/> <xsd:element type="ProducesArtifactsEnum" name="ProducesArtifacts"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:simpleType name="ConsumesArtifactsEnum"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="true"/> <xsd:enumeration value="false"/> <xsd:enumeration value="DELEGATED"/> </xsd:restriction> </xsd:simpleType> <xsd:simpleType name="ProducesArtifactsEnum"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="true"/> <xsd:enumeration value="false"/> <xsd:enumeration value="DELEGATED"/> </xsd:restriction> </xsd:simpleType> <xsd:simpleType name="InputDataTypeEnum"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="Boolean"/> <xsd:enumeration value="Double"/> <xsd:enumeration value="Integer"/> <xsd:enumeration value="String"/> </xsd:restriction> </xsd:simpleType> </xsd:schema> |
Plugin XML Metadata Elements
Element | Path | XSD Line Number | Description |
---|---|---|---|
PluginDefinition | / | 3 | The root element for this plugin definition. |
Name | /PluginDefinition | 6 | The name of the plugin, which appears on plugins page after upload. |
PluginDisplayName | /PluginDefinition | 7 | The display name of the plugin, which appears on workflow page under workflow operations. |
Description | /PluginDefinition | 8 | A description for this plugin, which is displayed on the plugins page after upload. |
TechnologyGroup | /PluginDefinition | 9 | The name of the technology that is plugin is for, which is displayed on the plugins page after upload. |
SubTechnologyGroup | /PluginDefinition | 10 | The name of the sub-technology that is plugin is for, which is displayed on the plugins page after upload. |
Vendor | /PluginDefinition | 11 | The name of the vendor which authored the plugin. |
MaxConfurrentThreads | /PluginDefinition | 12 | The number of concurrent threads which are allowed to execute plugin operations on any single endpoint. Default is -1, which means unlimited. |
Version | /PluginDefinition | 13 | The version of the plugin. |
ResourceTypes | /PluginDefinition | 14 | A list of server/component types which are applicable for the underlying technology. This helps identify the endpoint to run a particular operation on. (e.g. for WebLogic - NodeManager, AdminServer, ManagedServer). |
Resource | /PluginDefinition/ResourceTypes | 17 | A server/component types which is applicable for the underlying technology (e.g. NodeManager). |
Operations | /PluginDefinition/ | 21 | A list of operations supported by this plugin. |
Operation | /PluginDefinition/Operations | 24 | An operation supported by this plugin. |
Name | /PluginDefinition/Operations/Operation | 27 | The name of the plugin operation. |
Description | /PluginDefinition/Operations/Operation | 28 | A description for the plugin operation. |
Target | /PluginDefinition/Operations/Operation | 29 | The package qualified name of the Java class which implements PluginProvider or extends AbstractPluginProvider. |
PropertyKeys | /PluginDefinition/Operations/Operation | 30 | The list of properties used by this plugin operation. See Property Definitions section for details. |
PropertyKey | /PluginDefinition/Operations/Operation/PropertyKeys | 33 | A reference to a property used by this plugin operation. See Property Definitions section for details. |
Inputs | /PluginDefinition/Operations/Operation | 37 | A list of inputs used by this plugin operation. |
AllowsUserDefined | /PluginDefinition/Operations/Operation/Inputs | 40 | Whether or not this plugin operation allows user defined inputs. User defined inputs are useful for low-level technology plugins (e.g. shell) where the user is essentially providing the implementation via source or scripting code. |
Input | /PluginDefinition/Operations/Operation/Inputs | 41 | An input definition for this plugin operation. |
Name | /PluginDefinition/Operations/Operation/Inputs/Input | 44 | The name of the input. Must be alpha-numeric, and be free of whitespace or special characters (except underscore). This name may be used in shell scripts or Groovy scripts and therefore must adhere to these variable naming standards. |
DataType | /PluginDefinition/Operations/Operation/Inputs/Input | 45 | The data type of the input. Must be one of Boolean, Double, Integer, String. |
Description | /PluginDefinition/Operations/Operation/Inputs/Input | 46 | The description of the plugin input, which is displayed on the plugin step editor of the workflow. |
DisplayName | /PluginDefinition/Operations/Operation/Inputs/Input | 47 | The display name of the plugin input, which is displayed on the plugin step editor of the workflow. |
DefaultValue | /PluginDefinition/Operations/Operation/Inputs/Input | 48 | The default value for the plugin input if no value is specified by the user. This value will also be displayed by default on the plugin step editor of the workflow. |
IsDefaultValueExpression | /PluginDefinition/Operations/Operation/Inputs/Input | 49 | Identifies whether the default value for this input is an expression or a literal value, if specified. |
SubDataType | /PluginDefinition/Operations/Operation/Inputs/Input | 50 | An optional sub-datatype for this input. Valid options are DIRECTORY, JDBCURL, and URL. Setting the SubDataType adds additional validation when user enters value. |
IsRequired | /PluginDefinition/Operations/Operation/Inputs/Input | 51 | Indicates whether this input is required or not. Required inputs are enforced by the plugin step editor and at runtime. |
IsEncrypted | /PluginDefinition/Operations/Operation/Inputs/Input | 52 | Indicates whether the input is encrypted or not. Encrypted values are masked on the editor, and their values are not displayed in log files. |
MinValue | /PluginDefinition/Operations/Operation/Inputs/Input | 53 | Identifies the minimum required value for this input, and is enforced by the plugin step editor and at runtime. This value is only applicable for Integer and Double input types. |
MaxValue | /PluginDefinition/Operations/Operation/Inputs/Input | 54 | Identifies the maximum required value for this input, and is enforced by the plugin step editor and at runtime. This value is only applicable for Integer and Double input types. |
ListData | /PluginDefinition/Operations/Operation/Inputs/Input | 55 | Provides a list of values for this input which may be selected by the user on the plugin step editor. When ListData is provided the plugin step editor will render the value using a drop down component. |
DisplayRows | /PluginDefinition/Operations/Operation/Inputs/Input | 56 | Defines the height of the input field on the plugin step editor. |
DisplayColumns | /PluginDefinition/Operations/Operation/Inputs/Input | 57 | Defines the length of the input field on the plugin step editor. |
LengthPrecision | /PluginDefinition/Operations/Operation/Inputs/Input | 58 | Defines the required input length. Only applies to String datatype. |
ValidatorScript | /PluginDefinition/Operations/Operation/Inputs/Input | 59 | An optional Groovy script which is executed to determine whether this input's value is valid. The Value bind variable is set to the current value of this input, while every other input is available by it's name. The script must return true if validation passes, and false otherwise. When returning false, the variable ValidationMessage should be set to the message to display at runtime when validation fails. |
IsMultiselect | /PluginDefinition/Operations/Operation/Inputs/Input | 60 | If the ListData attribute is provided, the IsMultiselect identifies whether the user can select more than one value. As such, the input component for this input on the plugin step editor behaves accordingly. |
Outputs | /PluginDefinition/Operations/Operation | 67 | A list of outputs returned by this plugin operation's execution. |
AllowsUserDefined | /PluginDefinition/Operations/Operation/Outputs | 70 | Whether or not this plugin operation allows user defined outputs. User defined outputs are useful for low-level technology plugins (e.g. shell) where the user is essentially providing the implementation via source or scripting code. |
Output | /PluginDefinition/Operations/Operation/Outputs | 71 | The name of the output returned from this plugin operation. |
EndPointSpecification | /PluginDefinition/Operations/Operation | 75 | Defines the strategy used for determining the endpoint or endpoints on which a plugin operation will execute on. |
Selection | /PluginDefinition/Operations/Operation/EndPointSpecification | 78 | Defines which endpoints will be seleted as candidates to execute on. |
All | /PluginDefinition/Operations/Operation/EndPointSpecification/Selection | 81 | Indicates that all endpoints associated to the target environment instance should be selected as execution candidates. |
Resource | /PluginDefinition/Operations/Operation/EndPointSpecification/Selection | 82 | Indicates that only endpoints having the given resource name should be selected as execution candidates. |
Delegated | /PluginDefinition/Operations/Operation/EndPointSpecification/Selection | 83 | Indicates that the endpoint selection is delegated to the workflow developer (within the plugin step editor). In this case, the plugin step editor will present options of All and Resource. |
Execution | /PluginDefinition/Operations/Operation/EndPointSpecification | 87 | Of the selected endpoint candidates, determines which one(s) to execute on. |
Any | /PluginDefinition/Operations/Operation/EndPointSpecification/Execution | 90 | Indicates to execute on one of the selected endpoints (at random). |
All | /PluginDefinition/Operations/Operation/EndPointSpecification/Execution | 91 | Indicates to execute on all of the selected endpoints. |
Delegated | /PluginDefinition/Operations/Operation/EndPointSpecification/Execution | 92 | Indicates that execution strategy is delegated to the workflow developer (within the plugin step editor). In this case, the plugin step editor will present options of Any and All. |
ConsumesArtifacts | /PluginDefinition/Operations/Operation | 99 | Identifies whether this plugin operation consumes an artifact. Valid values are true, false, DELEGATED. In the case of DELEGATED, the plugin step editor will present a checkbox for the workflow developer to determine. When a plugin operation consumes artifacts, the associated artifacts from the artifact repository are copied to the artifact directory within the working directory on the endpoint prior to execution. |
ProducesArtifacts | /PluginDefinition/Operations/Operation | 100 | Identifies whether this plugin operation produces an artifact. Valid values are true, false, DELEGATED. In the case of DELEGATED, the plugin step editor will present a checkbox for the workflow developer to determine. When a plugin operation produces artifacts, the associated artifacts from the artifact directory on the endpoint are copied back to the server and stored in the artifact repository. |
Apache HTTP Server Plugin XML Metadata
Code Block | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
<?xml version="1.0" encoding="UTF-8"?> <PluginDefinition xmlns="http://flexagon.com/deploy/plugin"> <Name>FlexagonApacheHttpPlugin</Name> <PluginDisplayName>Apache HTTP</PluginDisplayName> <Description>A plugin to manage Apache Http Servers and deployment.</Description> <TechnologyGroup>Web Servers</TechnologyGroup> <SubTechnologyGroup>Apache Http Server</SubTechnologyGroup> <Vendor>Flexagon</Vendor> <MaxConcurrentThreads>-1</MaxConcurrentThreads> <Version>0.7</Version> <Operations> <Operation> <Name>build</Name> <Description>Build an artifact to deploy to an Apache Http Server</Description> <Target>flexagon.fd.plugin.apache.http.operations.Build</Target> <PropertyKeys/> <Inputs> <AllowsUserDefined>false</AllowsUserDefined> <Input> <Name>FDAH_PATH_TO_FILES</Name> <DataType>String</DataType> <Description>Relative path to files inside the FD_TEMP_DIR to collect into a build artifact</Description> <DisplayName>Path to Files</DisplayName> <IsDefaultValueExpression>false</IsDefaultValueExpression> <IsRequired>false</IsRequired> <IsEncrypted>false</IsEncrypted> <DisplayRows>1</DisplayRows> <DisplayColumns>120</DisplayColumns> </Input> </Inputs> <Outputs> <AllowsUserDefined>false</AllowsUserDefined> </Outputs> <EndPointSpecification> <Selection> <All/> </Selection> <Execution> <Any/> </Execution> </EndPointSpecification> <ConsumesArtifacts>false</ConsumesArtifacts> <ProducesArtifacts>true</ProducesArtifacts> </Operation> <Operation> <Name>deploy</Name> <Description>Deploy to Apache Http Server artifact</Description> <Target>flexagon.fd.plugin.apache.http.operations.Deploy</Target> <PropertyKeys> <PropertyKey>FDAH_PATH_TO_DOCUMENT_ROOT</PropertyKey> </PropertyKeys> <Inputs> <AllowsUserDefined>false</AllowsUserDefined> </Inputs> <Outputs> <AllowsUserDefined>false</AllowsUserDefined> </Outputs> <EndPointSpecification> <Selection> <All/> </Selection> <Execution> <Any/> </Execution> </EndPointSpecification> <ConsumesArtifacts>true</ConsumesArtifacts> <ProducesArtifacts>false</ProducesArtifacts> </Operation> <Operation> <Name>stopServer</Name> <Description>Stop an Apache Http Server</Description> <Target>flexagon.fd.plugin.apache.http.operations.Stop</Target> <PropertyKeys/> <Inputs> <AllowsUserDefined>false</AllowsUserDefined> </Inputs> <Outputs> <AllowsUserDefined>false</AllowsUserDefined> </Outputs> <EndPointSpecification> <Selection> <All/> </Selection> <Execution> <Any/> </Execution> </EndPointSpecification> <ConsumesArtifacts>false</ConsumesArtifacts> <ProducesArtifacts>true</ProducesArtifacts> </Operation> <Operation> <Name>startServer</Name> <Description>Start an Apache Http Server</Description> <Target>flexagon.fd.plugin.apache.http.operations.Start</Target> <PropertyKeys> <PropertyKey>FDAH_START_TIMEOUT</PropertyKey> </PropertyKeys> <Inputs> <AllowsUserDefined>false</AllowsUserDefined> </Inputs> <Outputs> <AllowsUserDefined>false</AllowsUserDefined> </Outputs> <EndPointSpecification> <Selection> <All/> </Selection> <Execution> <Any/> </Execution> </EndPointSpecification> <ConsumesArtifacts>false</ConsumesArtifacts> <ProducesArtifacts>true</ProducesArtifacts> </Operation> </Operations> </PluginDefinition> |
...
Plugin XML Properties Definition
...
Code Block | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
<?xml version="1.0" encoding="windows-1252" ?> <xsd:schema targetNamespace="http://flexagon.com/deploy/propertylist" xmlns="http://flexagon.com/deploy/propertylist" xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified"> <xsd:element name="PropertyList"> <xsd:complexType> <xsd:sequence> <xsd:element type="xsd:string" name="Name"/> <xsd:element name="Property" maxOccurs="unbounded" minOccurs="1"> <xsd:complexType> <xsd:sequence> <xsd:element type="xsd:string" name="Name" maxOccurs="1" minOccurs="1"/> <xsd:element type="xsd:string" name="Description" maxOccurs="1" minOccurs="1"/> <xsd:element type="xsd:string" name="Scope" maxOccurs="1" minOccurs="1"/> <xsd:element type="xsd:string" name="DataType" maxOccurs="1" minOccurs="1"/> <xsd:element type="xsd:string" name="SubDataType" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:string" name="IsRequired" maxOccurs="1" minOccurs="1"/> <xsd:element type="xsd:string" name="IsEncrypted" maxOccurs="1" minOccurs="1"/> <xsd:element type="xsd:long" name="MinValue" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:long" name="MaxValue" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:string" name="ListData" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:int" name="DisplayRows" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:int" name="DisplayColumns" maxOccurs="1" minOccurs="0"/> <xsd:element name="Validators" maxOccurs="1" minOccurs="0"> <xsd:complexType> <xsd:sequence> <xsd:element type="xsd:string" name="Validator" maxOccurs="5" minOccurs="0"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element type="xsd:string" name="DisplayName" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:string" name="DefaultValue" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:string" name="IsDefaultValueExpression" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:string" name="IsAllowsVariant" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:int" name="LengthPrecision" maxOccurs="1" minOccurs="0"/> <xsd:element type="xsd:string" name="IsMultiselect" maxOccurs="1" minOccurs="0"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> |
Plugin Properties XML Elements
Element | Path | XSD Line Number | Description |
---|---|---|---|
PropertyList | / | 4 | The root element for this properties definition. |
Name | /PropertyList | 7 | The name of the properties definition. |
Property | /PropertyList | 8 | A plugin property definition. |
Name | /PropertyList/Property | 11 | The name of the property. Must be alpha-numeric, and be free of whitespace or special characters (except underscore). This name may be used in shell scripts or Groovy scripts and therefore must adhere to these variable naming standards. |
Description | /PropertyList/Property | 12 | A description for the property. |
Scope | /PropertyList/Property | 13 | The scope of the property. Must be one of PROJECT, ENVINST (Environment Instance). |
DataType | /PropertyList/Property | 14 | The data type of the property. Must be one of Boolean, Double, Integer, String. |
SubDataType | /PropertyList/Property | 15 | An optional sub-datatype for this property. Valid options are DIRECTORY, JDBCURL, and URL. Setting the SubDataType adds additional validation when user enters value. |
IsRequired | /PropertyList/Property | 16 | Indicates whether this property is required or not. Required properties are enforced at runtime. |
IsEncrypted | /PropertyList/Property | 17 | Indicates whether the property is encrypted or not. Encrypted values are masked when entered by the user, and their values are not displayed in log files. |
MinValue | /PropertyList/Property | 18 | Identifies the minimum required value for this property, and is enforced at runtime. This value is only applicable for Integer and Double input types. |
MaxValue | /PropertyList/Property | 19 | Identifies the maximum required value for this property, and is enforced at runtime. This value is only applicable for Integer and Double input types. |
ListData | /PropertyList/Property | 20 | Provides a list of values for this property which may be selected by the user on the various properties pages. When ListData is provided the editor will render the value using a drop down component. |
DisplayRows | /PropertyList/Property | 21 | Defines the height of the property field on the editor. |
DisplayColumns | /PropertyList/Property | 22 | Defines the length of the property field on the editor. |
Validators | /PropertyList/Property | 23 | RESERVED FOR FUTURE USE |
Validator | /PropertyList/Property/Validators | 26 | RESERVED FOR FUTURE USE |
DisplayName | /PropertyList/Property | 30 | The display name of the plugin property, which is displayed on the editor where property values are entered. |
DefaultValue | /PropertyList/Property | 31 | The default value for the plugin property if no value is specified by the user. This value will also be displayed by default on the editor where values are entered. |
IsDefaultValueExpression | /PropertyList/Property | 32 | Identifies whether the default value for this property is an expression or a literal value, if specified. |
IsAllowsVariant | /PropertyList/Property | 33 | RESERVED FOR FUTURE USE |
LengthPrecision | /PropertyList/Property | 34 | Defines the required property length. Only applies to String datatype. |
IsMultiselect | /PropertyList/Property | 35 | If the ListData attribute is provided, the IsMultiselect identifies whether the user can select more than one value. As such, the input component for this property on the various editors behave accordingly. |
Apache HTTP Server Properties XML
Code Block | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
<?xml version="1.0" encoding="UTF-8"?> <PropertyList xmlns="http://flexagon.com/deploy/propertylist"> <Name>FDAH_PLUGIN</Name> <Property> <Name>FDAH_PATH_TO_DOCUMENT_ROOT</Name> <Description>Path to the document root of the server, such as htdocs.</Description> <Scope>ENVINST</Scope> <DataType>String</DataType> <SubDataType>DIRECTORY</SubDataType> <IsEncrypted>false</IsEncrypted> <IsRequired>true</IsRequired> <Validators/> </Property> <Property> <Name>FDAH_START_TIMEOUT</Name> <Description>How many milliseconds to wait for the server to start before failing the workflow step. Defaults to 300000 (5 minutes)</Description> <Scope>ENVINST</Scope> <DataType>Integer</DataType> <IsEncrypted>false</IsEncrypted> <IsRequired>true</IsRequired> <Validators/> </Property> </PropertyList> |
Plugin Setup Scripts
A plugin is executed on an endpoint by a wrapper java program, which is launched by a wrapper shell script. This wrapper shell script optionally sources in a setup script which is provided by the plugin. This setup script may perform initialization activities for the plugin. The following are examples of useful activities.
...
The unix setup.sh setup script is used when executing on an endpoint using an SSH connection. And this is true on Winodws platforms as well, since cygwin is used in that case. The setup.bat setup script is used only when executing on an endpoint using a localhost connection (and only in the event that the FlexDeploy server is running on Windows).
...
Plugin Unit Testing
To fully test your plugin you will ultimately need to upload it to a FlexDeploy Server. However, for unit testing purposes, it will be useful to test it a standalone testcase (e.g. using JUnit). To help provide the setup which is required to test your plugin, the MockWorkflowExecutionContext class is provided. This class manages manages some of the conext attributes that are otherwise handled by the FlexDeploy framwork. You will first need to satisfy the following prerequisites to test your plugin:
...
A full example is provided with the source code for the Apache Http Server plugin.
...
Packaging a Plugin Version for Delivery
After you have finished developing and unit testing your plugin, you are ready to package it up into a JAR file in preparation for loading onto a FlexDeploy server.
To do that, cd to the folder that contains the files, and execute the following command: jar cvfM0 plugin.jar *
This will make "plugin.jar" which will contain the files and folders around it.
The JAR file has the following structure:
...
You can download the sample jar file for the Apache HTTP Server Plugin here.
Installing a Plugin Version
Once you have packaged your plugin into a JAR file, go to FlexDeploy and navigate to Administration → Plugins. Upload your JAR file, and activate the new version.
Best Practices
Use the following best practices when defining the Plugin XML Metadata/Properties for your plugin:
...
- Be sure not to log secure properties!
...
Limitations
The Plugin SDK has the following limitations:
...