Spring Contract Maven Plugin pushStubsToScm does not work - spring

I tried to use Spring Contract Maven Plugin in a producer side to upload the stubs jar and share it with consumers.
I am using Spring Cloud Contract 2.0.0.
I configured the spring-cloud-contract-maven-plugin in my project, the codes is uploaded to Github.
<plugin>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<version>${spring-cloud-contract.version}</version>
<extensions>true</extensions>
<configuration>
<basePackageForTests>com.example.demo</basePackageForTests>
<baseClassMappings>
<baseClassMapping>
<contractPackageRegex>.*rest.*</contractPackageRegex>
<baseClassFQN>com.example.demo.RestVerifierBase</baseClassFQN>
</baseClassMapping>
</baseClassMappings>
<!-- We want to pick contracts from a Git repository -->
<!--<contractsRepositoryUrl>git://file://${project.basedir}/target/contract_git/</contractsRepositoryUrl>-->
<!-- Example of URL via git protocol -->
<!--<contractsRepositoryUrl>git://git#github.com:spring-cloud-samples/spring-cloud-contract-samples.git</contractsRepositoryUrl>-->
<!-- Example of URL via http protocol -->
<!--<contractsRepositoryUrl>git://https://github.com/spring-cloud-samples/spring-cloud-contract-samples.git</contractsRepositoryUrl>-->
<contractsRepositoryUrl>git://https://github.com/hantsy/contracts-git.git</contractsRepositoryUrl>
<!-- We reuse the contract dependency section to set up the path
to the folder that contains the contract definitions. In our case the
path will be /groupId/artifactId/version/contracts -->
<contractDependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
</contractDependency>
<!-- The mode can't be classpath -->
<contractsMode>REMOTE</contractsMode>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<!-- By default we will not push the stubs back to SCM,
you have to explicitly add it as a goal -->
<goal>pushStubsToScm</goal>
</goals>
</execution>
</executions>
</plugin>
When I ran command mvn clean install -DskipTests -DcontractsRepositoryUsername=hantsy -DcontractsRepositoryPassword=mypassword and got the failure.
Caused by: org.eclipse.jgit.errors.TransportException: https://github.com/hantsy/contracts-git.git: Authentication is required but no CredentialsProvider has been registered
Update: If I set contractsMode to LOCAL, it will fail with downloading stubs jar error, maybe similar with this issue, in the new version 2.0.0, Spring Cloud contracts can not resolve jars from Local maven repos as expected when stubsMode is set to LOCAL.
Update 2: I also tried to add contractsRepositoryUsername and contractsRepositoryPassword in spring contract maven plugin config, it does not work.

contractsMode needs to be REMOTE. I've taken your example and it works well with:
<contractsRepositoryUrl>git://git#github.com:marcingrzejszczak/contracts-git.git</contractsRepositoryUrl>
<contractsMode>REMOTE</contractsMode>
with passing the credentials manually I see sth absolutely bizarre...
I see [INFO] Passed username and password - will set a custom credentials provider which means that username and password got passed and I'm using them. But actually what I get is Authentication is required but no CredentialsProvider has been registered, which makes no sense. Can you file another bug for that? The workaround is to use the agent.
UPDATE:
The issue got fixed here https://github.com/spring-cloud/spring-cloud-contract/issues/678

Related

Quarkus Endpoints in dependency jars

I have a quarkus application which has dependencies to another maven module within the same project
within that module are REST endpoints
For some strange reason i cannot access those endpoints tho.. It seems quarkus will only accept endpoints of java classes within the quarkus module, or am I mistaken?
I foudn a solution:
if yopu add the jandex, endpoiints of other modules are being scanned, and can thus be found :
<build>
<plugins>
<plugin>
<groupId>org.jboss.jandex</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>1.1.0</version>
<executions>
<execution>
<id>make-index</id>
<goals>
<goal>jandex</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
You can do this by creating a dummy extended class:
Lets assume your imported jar has this pattern, app\proto-gen\1.0-SNAPSHOT\proto-gen-1.0-SNAPSHOT.jar
Add the below to application.properties,
quarkus.index-dependency.mygrpc.group-id=app
quarkus.index-dependency.mygrpc.artifact-id=proto-gen
#Singleton
MyGrpc extends XImplBase{
//your implementation
}
beans you extended/implemented in your current project will be started.
Check https://quarkus.io/guides/cdi-reference. You need to add a beans.xml to external models, create an index or reference the dependency using quarkus.index-dependency in the application.properties.
Then it will work when running tests or using the runner. But not in dev, because there is a probably in the current version (1.1.1Final). This problem has been fixed in the master, though, and will be available in the next release next month.
Please check ClassCastException in Quarkus multi-module project for more details.

Required to create Maven plugin or 'some kind of wrapper' or should I use a parent pom

We are using the frontend-maven-plugin in several (10+) projects.
These projects are build in combination with our own CMS. These projects are using a specific 'parent' in the pom, such as:
<parent>
<groupId>nl.companyname</groupId>
<artifactId>companyname-corporate-pom</artifactId>
<version>2.0.13</version>
</parent>
In this 'corporate pom', we have some predefined configuration and 'plugin management', such as:
<project.frontendmavenplugin.version>1.3</project.frontendmavenplugin.version>
<project.frontendmavenplugin.workingDirectory>./</project.frontendmavenplugin.workingDirectory>
<project.node.downloadRoot>http://nodejs.COMPANYURL.nl/dist/</project.node.downloadRoot>
<project.node.version>v6.9.1</project.node.version>
<project.yarn.version>v0.17.9</project.yarn.version>
<project.yarn.downloadRoot>http://yarnpkg.COMPANYURL.nl/</project.yarn.downloadRoot>
<project.npm.registryUrl>http://nexus.COMPANYURL.nl/content/groups/npm-all/</project.npm.registryUrl>
and
<build>
<pluginManagement>
<!-- Generic configuration for plugins used by (almost) all projects. -->
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>${project.frontendmavenplugin.version}</version>
<executions>
<execution>
<id>install node and yarn</id>
<goals>
<goal>install-node-and-yarn</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<workingDirectory>${project.frontendmavenplugin.workingDirectory}</workingDirectory>
<nodeVersion>${project.node.version}</nodeVersion>
<nodeDownloadRoot>${project.node.downloadRoot}</nodeDownloadRoot>
<yarnVersion>${project.yarn.version}</yarnVersion>
<yarnDownloadRoot>${project.yarn.downloadRoot}</yarnDownloadRoot>
</configuration>
</execution>
etc.
This way we don't have to copy/manage all configuration in each project.
This works great.
But: we are now also creating more and more new applications (based on Spring Boot) which are independent from our CMS and where we cannot use this 'parent pom' because Spring Boot has it's own (spring-boot-starter-parent) and our 'corporate pom' also contains very specific plugins / configuration which only applies to our CMS (which we are not including in these Spring Boot projects).
So what I need is something more 'standalone' for the frontend-maven-plugin configuration (and maybe in the future more 'platform' independent config/plugins). As far as I know, it's not possible to have more then 1 parent, so are there any other options?
I thought of creating a new 'companyname-frontend-maven-plugin' which both contains the PluginManagement as all the (extendable) configuration for the Frontend Maven Plugin. But I don't know if this will work and also it's a lot of work creating and maintaining this in git / Jenkins etc.
Are there any other options I could look in to?
Thank you all for your time!
maybe you can use a profile.
You can create a "corporate" pom that inherit from spring-boot-starter-parent and that contains a maven profile with all the properties and plugins required by your cms. So, when you are working on the CMS you will enable the "cms-profile".
Kind regards.

Heroku DATABASE_URL as a JDBC Url for Maven

My apps on Heroku use a DATABASE_URL. This is simple to parse with Java into a JDBC URL with a user name and password. There's no issue there. However, I have a JOOQ generator and Flyway migrator that have maven plugins and I can't figure out how to get the JDBC URL, User Name, and Password that these plugins require into maven. So currently I do it on app startup which is not ideal. When my app starts I get the DATABASE_URL, parse it, then do the flyway migration and jOOQ code generation. But I would like this to happen during the actual build process, not during application startup.
Basically I need the Heroku Environment variable formatted like (postgres://user:pass#ec2-host:1234/path-to-db) to be accessible in maven as a property like this (jdbc:postgresql://ec2-host:1234?user=user&password=pass).
I think the solution may lie with the maven build helper plugin but I can't get the regex properties specification quite right.
Thanks
I have solved this thanks to heroku support. Lukas and Axel you may want to document this for any of your users that are using heroku, want to run your tools in their build (vs code startup), and do not want to hand maintain different environment variables.
We will be using the GMavin Plus Plugin to run some code to parse the DATABASE_URL environment variable into properties prior to running the flyway migration or jOOQ code generation.
First off you need to add Groovy as a dependency:
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.3.9</version>
<scope>compile</scope>
</dependency>
Then the GMaven plus plugin:
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>execute</goal>
</goals>
</execution>
</executions>
<configuration>
<scripts>
<script><![CDATA[
URI dbUri = new URI(System.getenv("DATABASE_URL"));
String username = dbUri.getUserInfo().split(":")[0];
String password = dbUri.getUserInfo().split(":")[1];
int port = dbUri.getPort();
String dbUrl = "jdbc:postgresql://" + dbUri.getHost() + ":" + port + dbUri.getPath();
project.properties['database.jdbcUrl']=dbUrl
project.properties['database.username']=username
project.properties['database.password']=password
]]></script>
</scripts>
</configuration>
</plugin>
Now you can use ${database.jdbcUrl}, ${database.username}, and ${database.password} in your flyway, jOOQ, or whatever else configurations.
There are probably myriad ways to solve this with Maven, but one option is to keep a single properties file in your /src/main/resources path, load it using the properties-maven-plugin (an example can be seen in the jOOQ-Spring example), and then compose URLs using the individual parts, e.g. jOOQ and Flyway:
<url>jdbc:postgresql://${db.host}:${db.port}/${db.database}</url>
<user>${db.username}</user>
<password>${db.password}</password>
Heroku:
<database_url>postgres://${db.username}:${db.password}#${db.host}:${db.port}/${db.database}</database_url>

How to hot redeploy non-active maven project via jetty-maven-plugin

I'm trying to evaluate jetty for rapid development or project which is currently running on tomcat. My configuration looks like
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.3.v20140905</version>
<configuration>
<scanIntervalSeconds>3</scanIntervalSeconds>
<webApp>
<descriptor>${project.build.directory}/${project.build.finalName}/WEB-INF/web.xml</descriptor>
<resourceBases>
<directory>${basedir}/src/main/webapp</directory>
<directory>${basedir}/../SharedWeb/src/main/webapp</directory>
</resourceBases>
<allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>
<contextPath>/test</contextPath>
</webApp>
</configuration>
</plugin>
I have main war depending on SharedWeb war via war overlay mechanism. I specify resourceBases for both maven projects so changes in resources are scanned automatically and reloaded on the fly and all working fine. Also when I compile classes in main war, jetty restarts automatically, reloading the latest changes. But when I try to change any class in SharedWeb project and compile it, the class is not reloaded. I'm just wondering if there is a way to make embed jetty to reload classes from SharedWeb automatically? I understand that jetty-maven-plugin uses SharedWeb war from local maven repository, so I need to install SharedWeb artifact before I can see any changes. So I don't have high expectations, but maybe I'm missing something.
Ivan,
The plugin is using the classes and resources from your dependency
war, NOT from the that you have added. The
simply tells jetty to watch that location and redeploy if something in
it changes - it does NOT put it onto the classpath.
You need to tell jetty to use the classes and resources from your
dependency war's project, NOT the war artifact.
So do something like:
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.3.v20140905</version>
<configuration>
<webApp>
<!-- tell jetty to use the classes from the dependency
webapp project directly -->
<extraClassPath>${basedir}/../SharedWeb/target/classes</extraClassPath>
<!-- tell jetty to use both this project's static
resources, and those of the dependency webapp project -->
<resourceBases>
<directory>${basedir}/src/main/webapp</directory>
<directory>${basedir}/../SharedWeb/src/main/webapp</directory>
</resourceBases>
</webApp>
<scanIntervalSeconds>3</scanIntervalSeconds>
<!-- tell jetty to watch the dependency webapp project classes
dir for changes -->
<scanTargets>
<scanTarget>${basedir}/../SharedWeb/target/classes/</scanTarget>
</scanTargets>
</configuration>
</plugin>
Jan
Since there doesn't seem to be a good prior answer that is specific enough for this question (aka <scanTarget>) I'll just post this new one and tweak the title to make it easier to find in the future.
What you are looking for is <scanTarget>, as that will allow you to customize the scanning locations for changed content that will trigger a hot redeploy.
The jetty-maven-plugin intentionally does not set this up for custom <resourceBases> as there are far to many legitimate use cases where this can cause aggressive / too often / or infinite redeploys. It was decided that it was best to break from "convention over configuration" for <scanTarget> entries and allow the developers to decide what should be scanned for changes.
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.3.v20140905</version>
<configuration>
...
<scanIntervalSeconds>3</scanIntervalSeconds>
<scanTargets>
<scanTarget>${basedir}/../SharedWeb/src/main/webapp/</scanTarget>
<scanTarget>${basedir}/../SharedWeb/target/classes/</scanTarget>
</scanTargets>
</configuration>
</plugin>

Configure Maven to use CXF wsdl2java with Basic Authentication

I have an application that needs to integrate with one of SharePoint's web services. This web service cannot be accessed freely and needs authentication.
As such, the standard wsdl2java Maven plugin in my application gives an HTTP 401 error when the generate-sources phase is executed.
Is there a way to setup Maven/POM so that I can provide a user/password that will generate the stubs?
I have come across some answers saying this is not possible but all answers are older than 1 year. I haven't found if Maven have issued an update on this. One option is to save a local copy of the WSDL (as suggested here) but I would like to avoid having local copies.
Because you mentioned CXF then I suppose you meant cxf-codegen-plugin. It's a bit of a hack but it works.
HTTP authentication credentials can be provided using java.net.Authenticator. One need to just define his own Authenticator class which overrides getPasswordAuthentication(..) method. Then it has to be set as default Authenticator. As far as I know it can't be done declaratively (for instance using environment properties) only programatically using Authenticator.setDefault(..).
In order to call Authenticator.setDefault(..) I would use CXF extension mechanism. Create separate maven project with similar class:
public class AuthenticatorReplacer {
public AuthenticatorReplacer(Bus bus) {
java.net.Authenticator.setDefault(new java.net.Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("test", "test123"
.toCharArray());
}
});
}
}
and file src\main\resources\META-INF\cxf\bus-extensions.txt with contents:
org.example.AuthenticatorReplacer::false
Then add newly created project as a dependency to cxf-codegen-plugin:
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${project.version}</version>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>cxf-authenticator-replacer</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
...
</plugin>
This way AuthenticatorReplacer is initialized by CXF extension mechanism and replaces default Authenticator with ours.
An clean alternative to #Dawid Pytel's solution would be to run this class during lifecycle of wsdl class auto generation:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>path.to.AuthenticatorReplacer</mainClass>
</configuration>
</plugin>
Important: your AuthenticatorReplacer has to be a main(String[] args) class and running the code inside.
I verified that Dawid's solution works. Alternatively, you can use SoapUI to pull down and cache the wsdl and then use SoapUi code generation support to use cxf to generate the code.
http://java.dzone.com/tips/generating-client-java-code
Dawid's solution works for me too. It is a little tricky though. In Eclipse, the pom.xml keeps complaining that "wsdl2java failed: Could not load extension class AuthenticatorReplacer". You have to ignore this error message and use the command line:
mvn generate-sources
The Java classes will then be generated successfully.

Resources