FlexDeploy Plugin SDK
FlexDeploy provides dozens of out of the box plugins for building and deploying software using various technologies and middleware platforms. The FlexDeploy Plugin SDK allows customers or Flexagon partners to develop their own plugins. This guide provides the documentation for creating and managing these plugin implementations.
FlexDeploy plugins are implemented in Java or Docker image 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:
ImplementationÂ
Java (See Plugin SDK API documentation) or
Docker image Â
Metadata describing its operations, properties, and other behavior
Setup scripts (optional) to initialize the environment prior to execution
Required FlexDeploy libraries for Java implementation (download here)
See detailed instructions below.
Development Approach
Decide on implementation type - Java or Docker, depending on your expertise.
Define plugin.xml and properties.xml files. This should help you describe operations that will be developed and project or environment/instance level properties used by each operation. You can also define plugin operation inputs as appropriate. At times, you can just use inputs without properties if it makes sense.
Developer plugin implementation.
Unit test plugin operations.
Package and verify on FlexDeploy server.
Plugin Implementation
Java Plugin
Plugin Lifecycle
Each plugin operation (e.g. build, deploy, start, stop) is implemented by extending AbstractPluginProvider. Â
Apache HTTP Server - AbstractPluginProvider implementation - build operation
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 void validate()
throws FlexCheckedException
{
//TODO
}
@Override
public PluginResult execute()
throws FlexCheckedException
{
//TODO
}
@Override
public void cleanup()
{
//TODO
}
}
Using the XML metadata which is packaged with the plugin, FlexDeploy will manage its lifecycle by invoking the methods implemented by the concrete class.
public abstract void validate() throws FlexCheckedException;
public abstract PluginResult execute()Â throws FlexCheckedException;
public void cleanup();
The validate method is responsible for validating that prerequisites are satisfied prior to performing the execution. As you will see later, the XML metadata identifies basic prerequisites (e.g. required fields) that will be enforced by the plugin framework. Â However, there may be more advanced validation which can be implemented within this method.
Apache HTTP Server - build operation
@Override
public void validate()
throws FlexCheckedException
{
String methodName = "validate";
LOG.logInfoEntering(methodName);
//Let's validate that if a relative path is given, it exists on the file system.
String relativePath = getRelativePathToFiles();
if (relativePath != "")
{
File file = new File(getWorkflowExecutionContext().getTempDirectory() + relativePath);
if (!file.exists())
{
throw new FlexCheckedException(ApacheHttpProperties.FDAH_00001_INVALID_PATH, "The given relative path, [" + relativePath + "] was not found in the FD_TEMP_DIR, or was not a relative path.");
}
}
LOG.logInfoExiting(methodName);
}
The execute method is responsible for performing the actual execution of the plugin operation.
Apache HTTP Server - build operation
@Override
public PluginResult execute()
throws FlexCheckedException
{
String methodName = "execute";
LOG.logInfoEntering(methodName);
String source = getWorkflowExecutionContext().getTempDirectory() + getRelativePathToFiles();
String destination = getWorkflowExecutionContext().getArtifactsDirectory() + File.separator + ApacheHttpProperties.ARTIFACTS_ZIP;
LOG.logInfo("Zipping {0} into an artifact at (1}.", source, destination);
int zipped = new FlexZipUtils(source, new File(destination)).zipFolder();
getWorkflowExecutionContext().getOutputMap().put(ApacheHttpProperties.FDAH_FILE_COUNT, new PropertyValue(zipped, PropertyValue.PropertyTypeEnum.Integer, false));
LOG.logInfo(methodName, "Done!");
LOG.logInfoExiting(methodName);
return PluginResult.createPluginResult(getWorkflowExecutionContext());
}
After performing the execution, the execute method is responsible for setting any outputs into the WorkflowExecutionContext and returning the result using the following code fragment.
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
The Workflow Execution Context provides information related to the current execution. Â This includes properties, inputs, the endpoint working directory (and its sub-directories), and other execution related information. Â The following table summarizes the working directory sub-directories and their purpose.
Directory | WorkflowExecutionContext Method | Physical Endpoint Location | Description |
---|---|---|---|
Working Directory | getWorkingDirectory() | <EndPoint Base Directory>/work/<Project Id>/<Workflow Request Id> | The temporary working area defined for the target endpoint. |
Artifacts Directory | getArtifactsDirectory() | <Working Directory>/artifacts | Build operations which produce artifacts place those files here to have them automatically transferred back to the FlexDeploy server and version in the artifact repository. Deploy operations which consume artifacts will have those files delivered to this directory prior to execution on the endpoint. |
Temp Directory | getTempDirectory() | <Working Directory>/temp | Temporary working area for a plugin operation execution. |
Internal Directory | getInternalDirectroy() | <Working Directory>/internal | Internal working area for a plugin operation execution, which is not to be acessed or written to by workflow developers. |
Reports Directory | getReportsDirectory() | <Working Directory>/reports | Files placed in the reports directory will be automatically be transferred back to the FlexDeploy server. They are displayed in the execution summary. |
Transfer Directory | getTransferDirectory() | <Working Directory>/transfer | Files in the transer directory are automatically transferred back to the FlexDeploy server upon completion of execution, and likewise are transferred to the endpoint for the next workflow step. This provides a mechanism for sharing files between steps in a workflow. |
Test Results Directory | getTestResultsDirectory() | <Working Directory>/test-results | Testing framework plugin executions place an XML document representing the test results into this directory, and they will be automatically be transferred back to the FlexDeploy server. See the xsd for formatting information. Results are displayed in the execution results pages, insights, reporting, and other locations. |
Scan Results Directory | getScanResultsDirectory() | <Working Directory>/scan-results | Scanning framework plugin executions place an XML document representing the scan results into this directory, and they will be automatically be transferred back to the FlexDeploy server. See the xsd for formatting information. Results are displayed in the execution results pages, insights, reporting, and other locations. |
Object Results Directory | getObjectResultsDirectory() | <Working Directory>/object-results | Build and Deployment plugin operations for partial deployment implementations place XML documents into this directory for identifying the objects included in the build, and their execution status at deployment time. |
The AbstractPluginProvider base class has a number of methods for retrieving inputs/properties by type, based on scope, and returning a default if it is not defined.
See https://flexagon.com/plugin-sdk/6.0/flexagon/fd/core/plugin/AbstractPluginProvider.html for a current list of methods that can be used to access the properties and values that you need.
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.
FlexDeployLogger initialization
Log messages can be added using any of the public methods available on FlexDeployLogger.
Logging methods
See https://flexagon.com/plugin-sdk/6.0/flexagon/ff/common/core/logging/FlexLogger.html for a current list of methods that can be used.
Docker image plugin
A plugin can be implemented as a Docker image (instead of Java implementation). In this case the "plugin.jar" file contains plugin.xml file only. The Docker image should be stored in a Docker repository accessible from an endpoint (Docker host or Kubernetes cluster) executing the plugin. The full name of the image including repository should be specified in ImageName element of plugin.xml file.
An example of plugin.xml file for FlexagonADFBuilderPlugin:
Oracle ADF plugin - plugin.xml
While executing a plugin operation on a Docker host, FlexDeploy runs the following command on the target endpoint:
Docker command structure
While executing a plugin operation on a Kubernetes cluster, FlexDeploy runs the following commands
Kubectl command structure
Note that images utilizing an entrypoint will not have their entrypoints called by the Kubernetes framework. This is to allow time for the working directory to be copied before execution starts. Â
FlexDeploy passes into the Docker container or K8 Pod values of the following environment variables (through env.list for docker) or (pod.json for K8):
FD_WORKING_DIR
FD_ARTIFACTS_DIR
FD_TEMP_DIR
FD_INTERNAL_DIR
FD_TEST_RESULTS_DIR
FD_OBJECT_RESULTS_DIR
FD_TRANSFER_DIR
FD_ENVIRONMENT_CODE
FD_ENVIRONMENT_NAME
FD_TARGET_GROUP_CODE
FD_TARGET_GROUP_NAME
FD_PROJECT_NAME
FD_PLUGIN_INSTALL_DIR
FD_ENDPOINT_NAME
FD_ENDPOINT_ADDRESS
FD_PLUGIN
FD_PLUGIN_OPERATION
FD_RESULT_FILE_NAME
All plugin operation inputsÂ
All properties (by Name from metadata) for current project and target
The plugin execution working folder is mounted to the container as /fd_working_dir volume.Â
In order to return outputs the container must create a properties file /fd_working_dir/${FD_RESULT_FILE_NAME} containing output values. For example:
Example of result.dck file
Once the plugin operation finishes its execution, the corresponding Docker container or Kubernetes POD will be removed.
Plugin Metadata
Plugin XML
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.Â
plugin XML metadata schema (XSD)
Details of various elements is described in table below.
Element | Path | Description |
---|---|---|
PluginDefinition | / | The root element for this plugin definition. |
Name | /PluginDefinition | The name of the plugin, which appears on plugins page after upload. |
PluginDisplayName | /PluginDefinition | The display name of the plugin, which appears on workflow page under workflow operations. |
Description | /PluginDefinition | A description for this plugin, which is displayed on the plugins page after upload. |
TechnologyGroup | /PluginDefinition | The name of the technology that is plugin is for, which is displayed on the plugins page after upload. |
SubTechnologyGroup | /PluginDefinition | The name of the sub-technology that is plugin is for, which is displayed on the plugins page after upload. |
Vendor | /PluginDefinition | The name of the vendor which authored the plugin. |
Type | /PluginDefinition | Plugin type. Supported values are java and docker. Optional. Default is java. |
ImageName | /PluginDefinition | Full name of Docker image |
MaxConfurrentThreads | /PluginDefinition | The number of concurrent threads which are allowed to execute plugin operations on any single endpoint. Default is -1, which means unlimited. |
Version | /PluginDefinition | The version of the plugin. |
ResourceTypes | /PluginDefinition | 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 | A server/component types which is applicable for the underlying technology (e.g. NodeManager). |
Operations | /PluginDefinition/ | A list of operations supported by this plugin. |
Operation | /PluginDefinition/Operations | An operation supported by this plugin. |
Name | /PluginDefinition/Operations/Operation | The name of the plugin operation. |
Description | /PluginDefinition/Operations/Operation | A description for the plugin operation. |
Target | /PluginDefinition/Operations/Operation | For Java, the package qualified name of the Java class which implements PluginProvider or extends AbstractPluginProvider. For Docker, the command passed to image when the container is started. |
PropertyKeys | /PluginDefinition/Operations/Operation | The list of properties used by this plugin operation. See Property Definitions section for details. |
PropertyKey | /PluginDefinition/Operations/Operation/PropertyKeys | A reference to a property used by this plugin operation. See Property Definitions section for details. |
Inputs | /PluginDefinition/Operations/Operation | A list of inputs used by this plugin operation. |
AllowsUserDefined | /PluginDefinition/Operations/Operation/Inputs | 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 | An input definition for this plugin operation. |
Name | /PluginDefinition/Operations/Operation/Inputs/Input | 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 | The data type of the input. Must be one of Boolean, Double, Integer, String. |
Description | /PluginDefinition/Operations/Operation/Inputs/Input | The description of the plugin input, which is displayed on the plugin step editor of the workflow. |
DisplayName | /PluginDefinition/Operations/Operation/Inputs/Input | The display name of the plugin input, which is displayed on the plugin step editor of the workflow. |
DefaultValue | /PluginDefinition/Operations/Operation/Inputs/Input | 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 | Identifies whether the default value for this input is an expression or a literal value, if specified. |
SubDataType | /PluginDefinition/Operations/Operation/Inputs/Input | 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 | 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 | 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 | 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 | 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 | 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 | Defines the height of the input field on the plugin step editor. |
DisplayColumns | /PluginDefinition/Operations/Operation/Inputs/Input | Defines the length of the input field on the plugin step editor. |
LengthPrecision | /PluginDefinition/Operations/Operation/Inputs/Input | Defines the required input length. Only applies to String datatype. |
ValidatorScript | /PluginDefinition/Operations/Operation/Inputs/Input | 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 | 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 | A list of outputs returned by this plugin operation's execution. |
AllowsUserDefined | /PluginDefinition/Operations/Operation/Outputs | 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 | The name of the output returned from this plugin operation. |
EndPointSpecification | /PluginDefinition/Operations/Operation | Defines the strategy used for determining the endpoint or endpoints on which a plugin operation will execute on. |
Selection | /PluginDefinition/Operations/Operation/EndPointSpecification | Defines which endpoints will be seleted as candidates to execute on. |
All | /PluginDefinition/Operations/Operation/EndPointSpecification/Selection | Indicates that all endpoints associated to the target should be selected as execution candidates. |
Resource | /PluginDefinition/Operations/Operation/EndPointSpecification/Selection | Indicates that only endpoints having the given resource name should be selected as execution candidates. |
Delegated | /PluginDefinition/Operations/Operation/EndPointSpecification/Selection | 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 | Of the selected endpoint candidates, determines which one(s) to execute on. |
Any | /PluginDefinition/Operations/Operation/EndPointSpecification/Execution | Indicates to execute on one of the selected endpoints (at random). |
All | /PluginDefinition/Operations/Operation/EndPointSpecification/Execution | Indicates to execute on all of the selected endpoints. |
Delegated | /PluginDefinition/Operations/Operation/EndPointSpecification/Execution | 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 | 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 | 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. |
Properties Definition
The PropertyKeys in the plugin.xml file reference properties that are defined externally to the file itself. Â This is done so that multiple plugin operations, and even multiple plugins, are allow to share properties. Â The properties are defined in another XML file, conforming to a different schema, and are bundled with the plugin. Â The schema, a description of its elements, and a sample XML file are provided below.
Plugin XML Properties Schema (XSD)
Details of various elements is described in table below.
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 (target renamed from 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 when the DataType is String. 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. |
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.
Append to the classpath by exporting the FLEXAGON_FD_PLUGIN_CLASSPATH variable.
Append additional JVM arguments to the Java invocation by exporting the FLEXAGON_FD_JAVA_ARGS variable.
Override the JAVA_HOME used to invoke Java by exporting JAVA_HOME variable (do not include bin folder).
The setup scripts have the following variables available to them:
JAVA_HOME (as defined by enpoint defintion's JDK Home)
FD_BASE_WORKING_DIR (as defined by endpoint definition's Base Working Directory)
FD_WORKING_DIR
FD_ARTIFACTS_DIR
FD_TEMP_DIR
FD_INTERNAL_DIR
FD_TEST_RESULTS_DIR
FD_OBJECT_RESULTS_DIR
FD_TRANSFER_DIR
FD_ENVIRONMENT_CODE
FD_ENVIRONMENT_NAME
FD_TARGET_GROUP_CODE
FD_TARGET_GROUP_NAME
FD_PROJECT_NAME
FD_PLUGIN_INSTALL_DIR
FD_ENDPOINT_NAME
FD_ENDPOINT_ADDRESS
FD_PLUGIN
FD_PLUGIN_OPERATION
All properties (by Name from metadata) for current project and target
The unix setup.sh setup script is used when executing on an endpoint using an SSH connection. Â And this is true on Windows 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:
Add the FlexDeploy and 3rd party libaries to your classpath (i.e. adflibFlexFndCommonCore.jar, adflibFlexDeployCore.jar, commons-io-2.4.jar)
Add the following JVM arguments to your run configuration
flexagon.fd.install.root=<FlexDeploy working directory> (can be any directory on your local computer)
flexagon.fd.repository.root=<Directory to host FlexDeploy artifact repository> (can be any directory on yoour local computer)
The following setup must be performed using the JUnit @BeforeClass annotated methed, which will create the necessary FlexDeploy folders:
JUnit - @BeforeClass
Next is the implementation of a test case.
JUnit - @Test
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 <PluginName>-<PluginVersion>.jar *
This will make "<PluginName>-<PluginVersion>.jar" which will contain the files and folders around it.
 The JAR file has the following structure:
Plugin JAR Structure
Reminder
Remember to update the plugin Version in the plugin.xml file when packaging.
Java Plugin Reference Example
A fully functional plugin example for Apache HTTP Server, 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
Apache HTTP Server Plugin XML Metadata
Sample plugin.xml
Apache HTTP Server Properties XML
Apache HTTP Server - AHS_PROPERTY_LISTING.xml (filename is irrelevant)
Installing Plugin on FlexDeploy
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:
Prefix plugin Name with vendor/customer name (e.g. AcmeApacheHttpPlugin)
Set the Vendor to your vendor/customer name (e.g. Acme)
Give some thought to how users may want to sort/filter plugin operations when you set the TechnologyGroup (e.g. Web Servers) and SubTechnologyGroup (e.g. Apache Http Server) .  Review Flexagon plugins for reference.
Prefix the Version of the plugin with the version of FlexDeploy it is compatible with (e.g. 4.0.12). Â The minor version has be updated everytime a new jar is built and available to be loaded onto a server (whether internally or externally). Â The version must be unique for every plugin.
Name plugin operations as <verb><noun> (e.g. stopServer, deployContent).
Name plugin inputs and plugin properties using <Vendor Prefix><Technology Prefiex>_<Some name>, and use all uppercase. Â (e.g. FDAH_START_TIMEOUT). Â In this example, FD is what Flexagon/FlexDeploy uses, and AH is the technology prefix for Apache Http Server. Â This will help ensure names are consistent and greatly reduce the risk of duplicate names across vendors/plugins.
Give careful consideration to the scope of your inputs/properties. Â If an attribute is likely to be fixed for every project and target, then it makes sense to be an input such that it is set once in the workflow. Â On the other hand, is the property likely to be environment specific? Â Is it likely to be project specific?
Limitations
The Plugin SDK has the following limitations:
Partial Deployment plugins are not supported.
SCM plugins can be created, however, they will not have integration with the Configuration tab of the FlexDeploy Project.
- style