Execute plugin only if another execution succeeds - maven

I have two executions of a plugin to run in two different phases.
For instance:
<executions>
<execution>
<id>A</id>
<phase>pre-integration-test</phase>
</execution>
<execution>
<id>B</id>
<phase>post-integration-test</phase>
</execution>
</executions>
I want to execute B only if A succeeds. How do I do that?

Resolved it using Antrun Maven plugin with the DELETE operations set to run on post-integration-test, INSERT operations set to run on pre-integration-test phase and using ant-contrib library. I've put the INSERT operations on a trycatch block. If an exception is caught, the DELETE operations are used and then I fail the build.
Here's a code example for the insertOperation.xml ant script (I won't put "project" and "target" tags, but "target" name is "dbunit-insert"):
// Classpath used is Maven's Test scope classpath
<taskdef resource="net/sf/antcontrib/antcontrib.properties"
classpathref="maven.test.classpath"/>
// Classpath used is Maven's Test scope classpath
<taskdef name="dbunit" classname="org.dbunit.ant.DbUnitTask"
classpathref="maven.test.classpath"/>
<trycatch>
<try>
<dbunit driver="your.driver" url="your.database.url"
userid="your.database.username" password="your.database.password"
schema="your.database.schema">
<operation type="INSERT" src="src/main/resources/insertYourDataSet.flat"
format="flat"/>
// I know it has flat format as default but I define it so it won't
// appear NULL on the console during the execution. And although
// you can define the "transaction" parameter on "operation", it will
// only rollback the "operation" in which it is defined. This means
// that if a second file is set for INSERT and you get a problem with it,
// even setting the "transaction" parameter to "true" it won't rollback
// the first INSERT made.
</dbunit>
</try>
<catch>
// XML with DELETE operations
// This XML was created based on the inserted data
// e.g.: if you insert a String with "abc", this will delete it
// This works as a rollback for ALL INSERT operations
// So, if you get a trouble on a second file
// it grants that the first inserted dataset will be deleted.
<ant antfile="src/main/resources/ant/deleteOperation.xml"
inheritrefs="true"/>
// This command will fail Maven build
// print the message you've set and prevent it from running tests
// that rely on the data you tried to insert
<fail message="Failed build due to problem on an INSERT operation"/>
</catch>
</trycatch>
And here's a code example for the deleteOperation.xml ant script (I won't put "project" and "target" tags, but "target" name is "dbunit-delete"):
// Notice that I don't need the ant-contrib library
// That's because DELETE operations are simply ignored if the data
// doesn't exist.
// You won't need a trycatch block, so no ant-contrib here
<taskdef name="dbunit" classname="org.dbunit.ant.DbUnitTask"/>
<dbunit driver="your.driver" url="your.database.url"
userid="your.database.username" password="your.database.password"
schema="your.database.schema">
<operation type="DELETE" src="src/main/resources/deleteYourDataSet.flat"
format="flat"/>
</dbunit>
Hope I help someone with this.

Related

Maven replacing key value and filtering in one step

Can maven (maven-antrun-plugin) run operations in one profile, operations like:
replace key value in properties file,
filter file with new keys.
What do I mean I have some.properties file with structure like
...
app.title=#app.title#
...
My profile in pom.xml looks like
<profile>
<id>myApp</id>
<properties>
<app.title>App1</app.title>
<app.title.dev1>App1</app.title.dev1>
...
</properties>
</profile>
I know how to replace in properties file key value on #app.title.dev1# but right now i end up with two files
one contains app.title=App1 and second (wtith diffreant name) app.title=#app.title.dev1#.
Is it possible to filter files in target directory or somehow do operations:
replace key in properties file,
filtering key in properties file
in one step?
I need two files because there are for different environments.
Problem solved.
I had to add one more plugin with
<phase>process-resources</phase>
<goals>
<goal>resources</goal>
</goals>
...
befor plug responsible for overwriting key values.

Maven: how to invoke a plugin with execution specific config

I have written a plugin and want to treat the goal vrs (check versions) differently,
depending on execution/command line.
In my code I added
#Parameter(name = "versionsWarnOnly", defaultValue = "true")
private boolean versionsWarnOnly;
public boolean getVersionsWarnOnly() {
System.out.println("invoked get");
return this.versionsWarnOnly;
}
public void setVersionsWarnOnly(boolean versionsWarnOnly) {
System.out.println("invoked set");
this.versionsWarnOnly = versionsWarnOnly;
}
I would expect, that without specifying versionsWarnOnly in the configuration in the pom, i just get the defaultValue specified.
The problem is, that does not happen, it is always false in that case.
If i configure in the configuration
of the plugin in the pom
<versionsWarnOnly>true</versionsWarnOnly>
Then this is done (well some success) if I build the phase mvn validate.
It is even true if I invoke the goal from the command line by goal mvn latex:vrs.
But if i specify that in an execution that like,
<execution>
<id>validate_converters</id>
<phase>validate</phase>
<configuration>
<versionsWarnOnly>true</versionsWarnOnly>
</configuration>
<goals>
<goal>vrs</goal>
</goals>
</execution>
again it has no effect.
I have no idea what i do wrong
or what kind of information you need to help me.
The problem is resolved and the question could be deleted altogether.
The problem was that I put almost all of the config into a class Settings.
On the other hand, I added the new parameter outside and so it had no effect.
Thats all.
Now all works fine.

How do I access environment variables in xquery?

My program in xquery has a few variables that are based on the environment where the function is being run. For example, dev points to "devserver", test to "testserver", prod to "server", etc.
How do I set this up in my application.xml file and how do I reference these in my .xqy functions?
"workaround" solution 1
use "switch" to determine host:
switch (xdmp:host-name(xdmp:host()))
case <dev environment as string> return "devserver"
case <test environment as string> return "testserver"
.
.
.
default return fn:error(xs:QName("ERROR"), "Unknown host: " || xdmp:host-name(xdmp:host()))
"workaround" solution 2
create an xml file in your project for each host, update your application.xml to place the xml file in a directory depending on the environment name, then refer to the document now built on installation.
application.xml:
<db dbName="!mydata-database">
<dir name="/config/" permissionsMode="set">
<uriPrivilege roles="*_uberuser"/>
<permissions roles="*_uberuser" access="riu"/>
<load env="DEV" root="/config/DEV/" merge="true" include="*.xml"/>
<load env="TEST" root="/config/TEST/" merge="true" include="*.xml"/>
documents located in project directory /config//environment.xml
<environment>
<services>
<damApi>https://stage.mydam.org</damApi>
<dimeApi>https://stage.mydime.org/api/Services</dimeApi>
</services>
</environment>
usage when I need to get the value
fn:doc("/config/environment.xml")/environment/services/damApi/fn:string()
neither solution seems the best to me.
If you use ml-gradle to deploy your project, it can do substitutions in your code. That means you can set up an XQuery library with code like this:
declare variable $ENV = "%%environmentName%%";
You can then import that library wherever you need.
Don't know if MarkLogic supports it, but XQuery 3.1 has functions available-environment-variables() and environment-variable().
You can consider using the tiny “properties” library at https://github.com/marklogic-community/commons/tree/master/properties
We wrote it long, long ago for MarkMail.org with the belief we didn’t want to put the configuration into a database document because configuration should be separate from data. Data get backed up, restored somewhere else, and the new location may not be the same environment as the old.
So instead we did a little hack and put config into the static namespace context (which each group and app server has). The configured prefix is the property name. The configured value is the property value (including type information). Here’s a screen shot from a MarkMail deployment showing it’s a production server, to email on errors, what static file version to serve, and what domain to output as its base.
This approach lets you configure properties administratively (via the Red GUI or REST) and they’re kept separate from the data. They’re statically available to the execution context without extra cost. You can configure them at the Group level or App Server level or both. The library is a convenience wrapper to pull the typed values.
Maybe by now there’s a better way like the XQuery 3.1 functions, but this one has been working well for 10+ years.
Not yet using gradle in our project, I managed to work out how to use maven profiles to find/replace the values I needed based on the environment it was deployed into. I just have to add to the proper profile the plugin to include, the files to update, and what to replace.
pom.xml:
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.2</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>**/modules/runTasks.xqy</include>
<include>**/imports/resetKey.xqy</include>
</includes>
<replacements>
<replacement>
<token>https://stage.mydime.org/api/Services</token>
<value>https://www.mydime.org/api/Services</value>
</replacement>
</replacements>
</configuration>
</plugin>

Ant propertyregex task to replace special character in string

My string is C:\tools\jenkins\HOME\workspace\MAL1793_Driver_DIO
I want to replace windows-style directory path "\" with UNIX style path "/"
I have used an Ant propertyregex task in my pom file to achieve this as below.
<execution>
<id>ReplaceWSPath</id>
<phase>process-resources</phase>
<configuration>
<tasks>
<echo>"Updating workspace path"</echo>
<propertyregex
property="WSPath"
input="C:\tools\jenkins\HOME\workspace\MAL1793_Driver_DIO"
regexp="\"
replace="/"
global="true" />
<echo>"workspace Path = ${WSPath}"</echo>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
But after execution I am getting this error:
Problem: failed to create task or type propertyregex
[ERROR] Cause: The name is undefined.
[ERROR] Action: Check the spelling.
[ERROR] Action: Check that any custom tasks/types have been declared.
[ERROR] Action: Check that any <presetdef>/<macrodef> declarations have taken place.
I am using Ant version 1.7. Are there any settings missing?
The <propertyregex> task is not part of Ant, it's part of the third-party Ant-Contrib collection of Ant tasks. The error message you quote indicates that you're at least missing the <taskdef> needed to use Ant-Contrib in your buildfile.
Instructions on how to set up and use Ant-Contrib are available at SourceForge:
First you must install Apache Ant itself, most of the Ant-Contrib
tasks require Ant 1.5 or higher to work properly. You can download Ant
from Apache.
Ant-contrib releases are available at the downloads page. Mailing
lists, CVS and bug trackers can be accessed from the project page.
See the cc tasks for installation instructions for cpptasks. To
install ant-contrib:
Copy ant-contrib-0.3.jar to the lib directory of your Ant
installation. If you want to use one of the tasks in your own project,
add the lines
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
to your build file.
Keep ant-contrib-0.3.jar in a separate location. You now have to
tell Ant explicitly where to find it (say in /usr/share/java/lib):
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="/usr/share/java/lib/ant-contrib-0.3.jar"/>
</classpath>
</taskdef>
You might consider using the built-in Ant <pathconvert> task as an alternative to the <propertyregex> if you don't already have Ant-Contrib or need it for anything else in your build.
I feel using ant script-javascript for this is much simpler
<property name="wsPath" value="C:\tools\jenkins\HOME\workspace\MAL1793_Driver_DIO" />
<script language="javascript">
var wsPath_BackSlash = project.getProperty("wsPath");
println("before: " + wsPath_BackSlash);
var wsPath_FrwdSlash= wsPath_BackSlash.replace("\\", "/");
println("wsPath_FrwdSlash: "+wsPath_FrwdSlash);
project.setProperty("wsPath", wsPath_FrwdSlash);
</script>
<echo message="${wsPath}" />
note: that naming your variable same as argument e.g var wsPath may give error, it gave to me!
courtesy: https://stackoverflow.com/a/16099717/4979331

Custom values in Maven pom.properties file

I'm trying to add custom values in the pom.properties file that Maven generates in the META-INF/maven/${groupId}/${artifactId} location
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifestEntries>
<build>${BUILD_TAG}</build>
</manifestEntries>
<addMavenDescriptor>true</addMavenDescriptor>
<pomPropertiesFile>${project.build.directory}\interface.properties</pomPropertiesFile>
</archive>
</configuration>
</plugin>
The content of the interface.properties files is
# Build Properties
buildId=746
Using the documentation I have pointed the pomPropertiesFile element to an external properties, but the generated pom.properties file still has the default content after running mvn install
What's the correct usage of the pomPropertiesFile element?
EDIT
I believe that the problem lies in org.apache.maven.archiver.PomPropertiesUtil. If you look at the method sameContents in the source it returns true if the properties in the external file are the same as the defaults and false if different. If the result of sameContents is false, then the contents of the external file are ignored.
Sure enough, this has already been logged as a bug
I think you need to place a file under src/main/resources/META-INF/${groupId}/${artifactId}/interface.properties and let maven do the filtering job (configure the filtering). The file will automatically be copied to target/META-INF/maven/${groupId}/${artifactId}/ location.
See https://issues.apache.org/jira/browse/MNG-4998
Maven 3 will resolve property placeholders eagerly when reading pom.xml for all properties values that are available at this time. Modifying these properties at a later time will not affect the values that are already resolved in pom.xml.
However, if property value is not available (there's no default), then placeholder will not be replaced by the value and it can still be processed later as a placeholder. For example, if a plugin will generate some property during the build, or if placeholder is read and processed by a plugin during some build step.

Resources