graphql maven plugin via proxy - java

for our project we generate graphql source files via the com.expediagroup:graphql-kotlin-maven-plugin:introspect-schema plugin during runtime.
Unfortunately our backend changed and we can no longer reach the graphql endpoint directly. Instead we have to use a proxy.
So the question is how to configure a proxy for this plugin? I checked the documentation but was not successful.
We also configured a http.proxyHost but the plugin seems to ignore it.
Any advice would be much appreciated.
This is the code for the plugin configuration.
<plugin>
<groupId>com.expediagroup</groupId>
<artifactId>graphql-kotlin-maven-plugin</artifactId>
<version>${graphql-kotlin.version}</version>
<executions>
<execution>
<goals>
<goal>introspect-schema</goal>
<goal>generate-client</goal>
</goals>
<configuration>
<endpoint>https://foo.bar.com/graphql</endpoint>
<packageName>com.expediagroup.graphql.generated</packageName>
<schemaFile>${project.build.directory}/schema.graphql</schemaFile>
<allowDeprecatedFields>true</allowDeprecatedFields>
<customScalars>
<customScalar>
<!-- custom scalar Any type -->
<scalar>Any</scalar>
<!-- fully qualified Java class name of a custom scalar type -->
<type>kotlin.Any</type>
<!-- fully qualified Java class name of a custom com.expediagroup.graphql.client.converter.ScalarConverter
used to convert to/from raw JSON and scalar type -->
<converter>example.com.utils.AnyScalarConverter</converter>
</customScalar>
</customScalars>
</configuration>
</execution>
</executions>
</plugin>

Related

Maven - check configured value and stop processing

I have a POM file which includes a property (under properties section) which has an IP value that we use when pushing it to git.
<device.ip>1.2.3.4</device.ip>
But for my builds, I need to use a another IP value, so I should change it to my required IP when I start to work on a new branch.
I'd like to be able to check the variable value at build startup and abort it given the variable value is different from what I need.
Any other solutions also welcomed.
(I hope my question would not be downgraded because of lack of code - there is no really code to write here. The scenario is quite self explanatory)
Than you for your advice.
You could use the maven-enforcer-plugin which support such checks.
The usage looks like this for the requirePropery rule.
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M2</version>
<executions>
<execution>
<id>enforce-property</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireProperty>
<property>device.ip</property>
<message>You must set a device.ip property!</message>
<regex>.*\d.*</regex> <!-- Express the value you need. -->
<regexMessage>The device.ip property contain...</regexMessage>
</requireProperty>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
I would suggest splitting your project in modules.
Module 1 contains your code without any configuration.
Module 2 refers to module 1 and additionally contains what goes into production. For multiple deployments create an additional module for each. This is where your production property goes.
Module 3 refers to module 1 (but not 2) and contains whatever you need for development (configuration like this property and helper classes). For complex scenarios make an additional module for each.
This has worked well for me.

Java 8 + Maven Javadoc plugin: Error fetching URL

I am attempting to generate Javadoc that actually links to the Javadoc for my dependencies. I have tried various means to generate Javadoc which does not produce the fully qualified class names for references to classes from my dependencies. I wanted links to the Java doc with the simplified class names. However, even with Java API classnames, I get NO links and have fully qualified class names. I am working with Java 8. I have the following configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.2</version>
<configuration>
<reportOutputDirectory>${project.basedir}/target</reportOutputDirectory>
<destDir>javadoc</destDir>
<windowtitle>Epiphany</windowtitle>
<doctitle>Epiphany</doctitle>
<show>private</show>
<detectLinks>false</detectLinks>
<detectOfflineLinks>true</detectOfflineLinks>
<linksource>true</linksource>
<detectJavaApiLink>false</detectJavaApiLink>
<additionalparam>-Xdoclint:none</additionalparam>
<links>
<link>http://docs.oracle.com/javase/8/docs/api</link>
</links>
</configuration>
<executions>
<execution>
<goals>
<goal>javadoc</goal>
<goal>test-javadoc</goal>
</goals>
</execution>
</executions>
</plugin>
I have the source set to Java 8 in my maven compiler configuration. I have tried using detectJavaApiLink set to true and leaving out the link to the Java 8 Javadoc, but Javadoc does not generate links to Java API classes and all references to them in my Javadoc are fully qualified class names.
I have tried setting detectJavaApiLink to false and using the above configuration with a specified URL(without and without a trailing slash) and I get the same result, along with this error:
[WARNING] javadoc: warning - Error fetching URL: http://docs.oracle.com/javase/8/docs/api
I have tried detecting links based on my declared dependencies, and I have tried setting it to false and then providing links to the Javadoc and I still get no links and all class names from classes in my dependencies are fully qualified. What the heck am I doing wrong? The package-list files are available at the URLs specified, so I don't get why Javadoc cannot access them or the Javadoc located there.
UPDATE:
Changed my version of the maven javadoc plugin to 2.10.3. Now, if I set detectJavaApiLink to true and remove the link for Java 8 javadoc, the javadoc generated properly links to Java API classes and used the simplified names.
However, I am still having problems with my 3rd party dependencies and linking to their Javadoc. If I set detectLinks to true, it fails to find the javadoc for any of them. If I set it to false and manually configure the location, I still get an error message saying it cannot fetch the URL:
[WARNING] javadoc: warning - Error fetching URL: https://selenium.googlecode.com/git/docs/api/java
My updated pom configuration for the maven javadoc plugin is below:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<configuration>
<reportOutputDirectory>${project.basedir}/target</reportOutputDirectory>
<destDir>javadoc</destDir>
<windowtitle>Epiphany</windowtitle>
<doctitle>Epiphany</doctitle>
<show>private</show>
<detectLinks>false</detectLinks>
<detectOfflineLinks>true</detectOfflineLinks>
<linksource>true</linksource>
<additionalparam>-Xdoclint:none</additionalparam>
<detectJavaApiLink>true</detectJavaApiLink>
<links>
<link>https://selenium.googlecode.com/git/docs/api/java</link>
</links>
</configuration>
<executions>
<execution>
<goals>
<goal>javadoc</goal>
<goal>test-javadoc</goal>
</goals>
</execution>
</executions>
</plugin>
UPDATE 2:
Defect report filed with MJAVADOC:
https://issues.apache.org/jira/browse/MJAVADOC-427

Using Avro schema from different package

We use Avro as our serialization engine in a big Java project.
We use maven plug-in for auto-generating classes from the Avro schemas (we only use avsc, no IDL).
All works nice until we come to cross-packages references.
The plug-in has the option to import schema files using the import tag, which works fine within the package, but when we try to reference a schema outside the package it does not fine it.
This is the plug-in setting:
<build>
<plugins>
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.7.7</version>
<configuration>
<stringType>String</stringType>
</configuration>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
</goals>
<configuration>
<sourceDirectory>${project.basedir}/src/main/resources/</sourceDirectory>
<outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
<fieldVisibility>PRIVATE</fieldVisibility>
<imports>
<import>${project.parent.basedir}/SomeOtherPackagePath/schema1.avsc</import>
<import>${project.basedir}/src/main/resources/schema2.avsc</import>
</imports>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
schema2.avsc contains a record called schema2, and is imported correctly, and all other schemas referencing schema2 are valid.
schema1.avsc contains a record called schema1, and is in another package, so schemas in this packages referencing to it fail when building the maven:
[ERROR] Failed to execute goal org.apache.avro:avro-maven-plugin:1.7.7:schema (default) on
project matching-common: Execution default of goal org.apache.avro:avro-maven-plugin:1.7.7:schema failed: "Schema1" is not a defined name. The type of the "schema1" field must be a defined name or a {"type": ...} expression.
Are we missing something?
Is there any way to use schemas from other packages at all?
Please add the SomeOtherPackagePath in the sourceDirectories like below:
<sourceDirectories>
<sourceDirectory>${project.basedir}/src/main/resources/</sourceDirectory>
<sourceDirectory>${project.parent.basedir}/SomeOtherPackagePath/</sourceDirectory>
</sourceDirectories>

Defining System Properties in Spring Boot Plugin

I would like to specify some system properties in my applicatio (deterined at compile time).
I am using the spring boot maven plugin to compile
Currently, according to this questions: Specify system property to Maven project
I tried the following setup (however this does not work as it is for a different plugin)
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>application.boot.AppStarter</mainClass>
<systemProperties>
<systemProperty>
<name>application.version</name>
<value>${application.version}</value>
</systemProperty>
<systemProperty>
<name>release.date</name>
<value>${timestamp}</value>
</systemProperty>
</systemProperties>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
How can i specify the properties in this plugin?
Java system properties which you add are only accessible by the process they are added to.So even if you manage to add some system properties during the Maven build, it will no longer be there when the build is done.
What will happen if you distribute your jar to someone else. How do you expect these properties to be available?
Solution
Refer this post to see how to access the artifactId and version at runtime
In a similar fashion you can add the timestamp entry as well to the src/main/resources/project.properties
buildTimestamp=${timestamp}
timestamp is not a pre-defined property like project.version or project.artifactId.So you will have to set extract the timestamp from the Maven property ${maven.build.timestamp} and set it as value to your timestamp property. This is already answered in this question.

Which is the best maven's plugin to generate a Web Service Client?

I have to generate a WS Client and I can't decide which plugin to use. Until now my options are: jaxb2-maven-plugin, axistools-maven-plugin and jaxws-maven-plugin.
I have to generate a WS Client and I can't decide wich plugin to use. Until now my options are: jaxb2-maven-plugin, axistools-maven-plugin and jaxws-maven-plugin.
First, the jaxb2-maven-plugin is not really intended to generate WS clients. ELIMINATED.
Second, personally I wouldn't use Axis even for client development only so I won't recommend using the axistools-maven-plugin. ELIMINATED.
This leaves us with the JAX-WS RI and the Apache CXF stacks, and their respective Maven plugins: the JAX-WS Maven Plugin (instructions to use the JAX-WS Maven Plugin can be found on the Usage page) and the cxf-codegen-plugin.
Regarding the pros and cons, I would summarize them like this:
JAX-WS RI is included in Java 6, but the documentation is more "rough" (although you'll find plenty of tutorials about JAX-WS RI too).
Apache CXF is better documentated and provide more flexibility if you want to go beyond the spec.
At the end, both choices are decent so I suggest to browse the links a bit and to make your own opinion.
I use jaxws-maven-plugin. In my opinion, JAX-WS is the de-facto standard implementation for WS. It has much better generated code than AXIS, and easier to config and implement. It has Maven and Spring support.
Generating client-side code from wsdl file, in pom.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<executions>
<execution>
<id>generate-reports-ws-code</id>
<phase>generate-sources</phase>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<!-- This property is used to support having multiple <execution> elements. The plugin has, from some reason, only one timestamp file per the all executions, thus if you have two executions, it doesn't know exactly when to recompile the code. Here we tell it explicitly to have one timestamp file per each execution --> <staleFile>${project.build.directory}/jaxws/stale/.staleFlag.reports</staleFile>
<packageName>com.acme.reports.ws.api</packageName>
<wsdlDirectory>${project.build.directory}/wsdl</wsdlDirectory>
<wsdlFiles>
<wsdlFile>InternalReportsAPIService.wsdl</wsdlFile>
</wsdlFiles>
<verbose>true</verbose>
<sourceDestDir>${wsdl.generated.source.files.dir}</sourceDestDir>
</configuration>
</execution>
</executions>
</plugin>
An interface to create the client service bean (this is not auto generated):
public interface InternalReportsAPIServiceFactory {
public InternalReportsAPIService createInternalReportsAPIService();
}
Its Bean implementation:
public class InternalReportsAPIServiceFactoryBean implements InternalReportsAPIServiceFactory {
private URL acmeReportsWsdlURL;
private final static QName V1_QNAME = new QName("http://internal.reports.api.acme.net/v1","InternalReportsAPIService");
#Override
public InternalReportsAPIService createInternalReportsAPIService() {
return new InternalReportsAPIService(acmeReportsWsdlURL, V1_QNAME);
}
public void setAcmeReportsWsdlUrl(String acmeReportsWsdlUrl) {
try {
this.acmeReportsWsdlURL = new URL(acmeReportsWsdlUrl);
} catch (MalformedURLException ex) {
throw new RuntimeException("Acme Reports WSDL URL is bad: "+ex.getMessage(), ex);
}
}
}
The idea in this bean (used as Spring bean) is to have a singleton for generating a client service code. It requires two inputs: The WSDL url - that is, the actual URL of the server which implements the WSDL. The client service code, upon construction, send a get request for the WSDL at the supplied URL. It then creates the WSDL based on the annotations residing in the auto generated code, and it compares it. I believe this is done to make sure you're running against the correct server version.
So, I've placed the url in a property file accessible to my application, thus I initialize in my Spring application context file.
Here's an example of using the factory to generate a service and then using it:
InternalReportsAPIService internalReportsAPIService = acmeReportsWSFactory.createInternalReportsAPIService();
InternalReportsAPI port = internalReportsAPIService.getInternalReportsAPIPort();
From here, just use the port variable to call any operation available on the wsdl.
Maven plugins required:
cxf-java2ws-plugin (JAX-WS to WSDL)
cxf-codegen-plugin (WSDL to Java)
JAX-WS to WSDL
To generate the WSDL document from the JAX-WS annotated class by configuring cxf-java2ws-plugin with the ‘java2ws’ goal.
Add the cxf-rt-frontend-jaxws dependency and project dependencies required for the JAX-WS annotated class as plugin dependencies.
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-java2ws-plugin</artifactId>
<version>2.5.1</version>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>com.medici.app</groupId>
<artifactId>services</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<className>com.medici.app.services.WebServiceBean</className>
<genWsdl>true</genWsdl>
</configuration>
<goals>
<goal>java2ws</goal>
</goals>
</execution>
</executions>
</plugin>
WSDL 2 Java
To generate the Java client from the WSDL document by configuring cxf-codegen-plugin with ‘wsdl2java’ goal.
The ‘-p’ argument specifies the package classes .
The generated classes will be placed in the target/generated-sources/cxf folder.
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>process-sources</id>
<phase>generate-sources</phase>
<configuration>
<wsdlOptions>
<wsdlOption>
<wsdl>${project.build.directory}/wsdl/WebService.wsdl</wsdl>
<extraargs>
<extraarg>-p</extraarg>
<extraarg>com.medici.app.client.model</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>

Categories