Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Server staging in maven and some useful newly developed plugins

DZone's Guide to

Server staging in maven and some useful newly developed plugins

· DevOps Zone ·
Free Resource

Automatic continuous monitoring keeps continuous deployment pipelines flowing smoothly and efficiently. Try Instana APM to automatically monitor containers and microservices!

Sometimes in projects happens that there are various stages and each stage needs its own configuration and also there are few common configurations too. These stages can be like these items:

  • local (developer machine)
  • Test (TST)
  • User Acceptance Test (UAT)
  • Performance Test (POT)
  • Production (PRD)
  • and etc

Usually these configurations happens mainly by property files. 

How we have implemented was like having a separate maven project that we call it: Properties. Then:

Step 1

For each server stage (apart from common) we have created a maven profile. So whenever we run any maven commands we will pass the stage name. By default local is the active profile. 

Step 2

Now how we add the content of a specific stage to a class-path? It is very simple. There is a very useful plugin called: build-helper-maven-plugin which will help you.

Hence, each maven profile will look like this:

        <profile>
            <id>local</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <env>local</env>
            </properties>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.codehaus.mojo</groupId>
                        <artifactId>build-helper-maven-plugin</artifactId>
                        <version>1.7</version>
                        <executions>
                            <execution>
                                <phase>generate-resources</phase>
                                <goals>
                                    <goal>add-resource</goal>
                                </goals>
                                <configuration>
                                    <resources>
                                        <resource>
                                            <directory>src/main/java/local</directory>
                                        </resource>
                                    </resources>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
        <profile>
            <id>tst</id>
            <properties>
                <env>tst</env>
            </properties>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.codehaus.mojo</groupId>
                        <artifactId>build-helper-maven-plugin</artifactId>
                        <version>1.7</version>
                        <executions>
                            <execution>
                                <phase>generate-resources</phase>
                                <goals>
                                    <goal>add-resource</goal>
                                </goals>
                                <configuration>
                                    <resources>
                                        <resource>
                                            <directory>src/main/java/tst</directory>
                                        </resource>
                                    </resources>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>

How did we handled the common configurations was like below within main build tag:

        <resources>
            <resource>
                <directory>src/main/java/common</directory>
            </resource>
        </resources>		


Now there are two problems (as far as I recognized) which are:

  1. If there is any file under common, the same exact name should not be in any stages. For example if we have: common/log4j.xml we should never have tst/logj4.xml
  2. Assume we are having local/webServicesAddress.properties so (A) if we do have stages like PRD or others, they must have the same file too, (B) all the key entries of these property files should be available in each stage either.

I failed to find a ready maven plugin to help me to validate these concerns and make it a compile level error, hence we developed these plugins:

The usage is very simple like this:
        <plugins>
            <plugin>
                <groupId>com.maven.plugins</groupId>
                <artifactId>CommonResourcesValidator</artifactId>
                <version>1.0</version>
                <configuration>
                    <commonResourceDirectory>${basedir}/src/main/java/common</commonResourceDirectory>
                    <environmentsDirectory>
                        <local>${basedir}/src/main/java/local</local>
                        <prd>${basedir}/src/main/java/prd</prd>
                        <tst>${basedir}/src/main/java/tst</tst>
                    </environmentsDirectory>
                </configuration>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>commonResourcesValidateMojoGoal</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>com.maven.plugins</groupId>
                <artifactId>MultiEnvironmentResourcesValidator</artifactId>
                <version>1.0</version>
                <configuration>
                    <environments>
                        <param>${basedir}/src/main/java/local</param>
                        <param>${basedir}/src/main/java/prd</param>
                        <param>${basedir}/src/main/java/tst</param>
                    </environments>
                    <master>local</master>
                    <excludes>
                        <param>**\.svn\**</param>
                        <param>mock.properties</param>
                    </excludes>
                </configuration>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>multiEnvironmentResourcesValidatorGoal</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>

Configuration of CommonResourcesValidator plugin:

  • commonResourceDirectory specifies which resource folder specifies the shared resources
  • environmentsDirectory is list of stages

Configuration of MultiEnvironmentResourcesValidator plugin:

  • environments determines the stages that need to be validated
  • master determines which stage should be taken as master to validate other stages compare to it
  • excludes determine which files should be excluded from this validation


Automatic real-time observability is critical to getting the full benefit of CI/CD. Hear @DevOpsDon discuss how Franklin American Mortgage Company cut their new application deployment time from 6-12 months to 2 weeks with the help of Instana APM.

Topics:

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}