-
Notifications
You must be signed in to change notification settings - Fork 1
The Execution Context
An ExecutionContext is in the primary execution method of the step as well as the rollback methods available. This context is mainly intended to be used by generic steps, so-called processing hooks, that can be deliverd independently from fully functional plugin implementations. Those hooks can then be used when overriding the default workflow of a plugin goal in order to extend its behavior. The context can truely also be used by standard step impelentations but developers are encouraged to use Maven's standard parameter-based configuration features instead.
As stated above the main reason for the introduction of the processing context was to provide configuration data to generic steps (hooks) that are delivered separately and are thus not foreseen in the Mojo's configuration parameters. A hook can f.i. execute a shell command or a HTTP-based REST request for which it necessarily needs some configuration data. Some standard hook implementations can be found here: mavenplugins/maven-cdi-plugin-hooks
Since the Mojo, whose workflow shall be overridden by adding a hook, does not know of the hook and its required configuration parameters the Mojo cannot provide any parameters for it coming from the POM configuration. Instead the configuration data is retrieved from appropriate system properties that can be passed when executing the Maven build. For each hook there can be two system properties, one for providing data for the main execution logic and one providing further data for a possible rollback execution of the step. Assuming the id of the step is exec, the following properties can be used:
-Dexec=...-Dexec-rollback=...
When it is necessary to embed a hook into the workflow multiple times the hooks can be qualified to distinguish them at runtime. More about this in the workflow section. Now it is also necessary to provide the respective data for each hook instance. Assuming that there are two instances of the exec hook, qualified by simply renumbering them, the workflow would contain the following entries: exec[1] and exec[2]. Data can then be passed in using the following system properties:
-Dexec[1]=...-Dexec[1]-rollback=...-Dexec[2]=...-Dexec[2]-rollback=...
Note that from version 3.2.0 it is now also possible to declare default execution and rollback data for hooks in the workflow descriptor that is used to override the default workflow of the goal. More about default execution data can be found in the workflow format section. In order to stay flexible it is of course also possible to override default execution data by the appropriate system properties as shown above.
An ExecutionContext object can contain mapped and unmapped execution and rollback data for the hook. Depending on the hook's requirements it can work with both or only one of the data types. The difference between mapped and unmapped data is only that mapped data consist of key-value pairs and unmapped data simply consists of a number of values.
Passing hook configuration data to the context is possible using system properties for execution an rollback execution. The individual data values are separated by commas , and can be map entries or list entries for unmapped data. Mapped data entries are keys and values separated by =>.
For the following example let's assume we have two hooks with the following ids http and exec.
The HTTP hook requires some mapped configuration data with the following data keys: url and method.
The Exec hook takes unmapped data entries representing the commands to be executed and optionally consumes mapped data determining environment variables to be set for the execution environment.
Both hooks are reversible and watch the rollback data of the context. In case of appropriate data bein present, the hooks call their rollback logic.
So here is how to pass the data using system properties when calling maven:
mvn ... -Dhttp="url=>http://example.com/doSomething,method=>POST" -Dexec="echo @{project.version} > version.txt,JAVA_HOME=>/opt/Java/default" -Dexec-rollback="rm version.txt"
The call did not pass any rollback data to the HTTP hook instance but does so for the Exec hook. Here are the sample implementations of the hooks and how to retrieve data from the context.
@ProcessingStep(id = "http", description = "Executes HTTP requests", requiresOnline = true)
public class HttpHook implements CDIMojoProcessingStep {
@Override
public void execute(ExecutionContext context) throws MojoExecutionException, MojoFailureException {
if (!context.hasMappedData()) {
return;
}
String url = context.getMappedDate("url");
HTTPMethod method = HTTPMethod.valueOf(context.getMappedDate("method");
System.out.println("HTTP-Hook (execute)");
System.out.println("URL: " + url);
System.out.println("METHOD: " + method);
}
@RollbackOnError
public void rollback(ExecutionContext context) {
if (!context.hasMappedRollbackData()) {
return;
}
String url = context.getMappedDate("url");
HTTPMethod method = HTTPMethod.valueOf(context.getMappedDate("method");
System.out.println("HTTP-Hook (rollback)");
System.out.println("URL: " + url);
System.out.println("METHOD: " + method);
}
}@ProcessingStep(id = "exec", description = "Executes shell commands", requiresOnline = false)
public class ExecHook implements CDIMojoProcessingStep {
@Override
public void execute(ExecutionContext context) throws MojoExecutionException, MojoFailureException {
if (!context.hasUnmappedData()) {
return;
}
System.out.println("Exec-Hook (execute)");
for (String date : context.getUnmappedData()) {
System.out.println("COMMAND: " + date);
}
if (context.hasMappedData()) {
for(String envKey : context.getMappedDataKeys()) {
System.out.println("ENV-ENTRY: " + envKey + '=' + context.getMappedDate(envKey));
}
}
}
@RollbackOnError
public void rollback(ExecutionContext context) {
if (!context.hasUnmappedRollbackData()) {
return;
}
System.out.println("Exec-Hook (rollback)");
for (String date : context.getUnmappedData()) {
System.out.println("COMMAND: " + date);
}
if (context.hasMappedRollbackData()) {
for(String envKey : context.getMappedDataKeys()) {
System.out.println("ENV-ENTRY: " + envKey + '=' + context.getMappedDate(envKey));
}
}
}
}This is the execution output produced by the hooks:
HTTP-Hook (execute)
URL: http://example.com/doSomething
METHOD: POST
Exec-Hook (execute)
COMMAND: echo 1.0.0-SNAPSHOT > version.txt
ENV-ENTRY: JAVA_HOME=/opt/Java/default
This is the rollback execution output produced by the hooks:
Exec-Hook (rollback)
COMMAND: rm version.txt
It is also possible to use Maven variable references for hook data declaration. These variables are expanded just before the step is executed within the workflow. Variables are referenced by the following expression: @{key} instead of Maven's standard reference notation `${key}.
When referring to the project version use @{project.version} instead of ${project.version}. You can also refer to the final name of the produced artifact using @{project.build.finalName} or even environment variables using @{env.key}.
© 2016 itemis AG, © 2024 mavenplugins