Spring Boot: OpenApi Generator Plugin creates unwanted test file - spring-boot

I use OpenApi 3.0 and the maven plugin openapi-generator-maven-plugin to generate my api + objects.
This is my maven config:
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/BookingService.yaml</inputSpec>
<generatorName>spring</generatorName>
<modelPackage>${clientPackage}.model</modelPackage>
<invokerPackage>${clientPackage}.invoker</invokerPackage>
<apiPackage>${clientPackage}.api</apiPackage>
<generateApis>true</generateApis>
<generateApiTests>false</generateApiTests>
<generateModelTests>false</generateModelTests>
<configOptions>
<delegatePattern>true</delegatePattern>
</configOptions>
</configuration>
</execution>
It works as expected, however its also generating tests that I do not want. As you can see in my config i disabled the tests for Api tests + Model tests..
The compilation of these tests fail bc it "Cannot resolve symbol 'SpringBootTest'" in the build target folder...
These tests do not have any sense, how can I disable them?

Note this is a workaround. It would be better to get a property to not generate this testcase, but for now this seems to work...
Add this maven plugin to your pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<!-- remove the unwanted generated testcases by the spring generator of openapi -->
<delete dir="${project.build.directory}/generated-sources/openapi/src/test" />
</target>
</configuration>
</execution>
</executions>
</plugin>
It will delete that entire test package after the sources have been generated in the process-sources phase

We can skip the generation by enabling <interfaceOnly>true</interfaceOnly> but delegatePattern will not consider.
Here is the source code from openapi-generator...
Source Code
if (!interfaceOnly) {
if (SPRING_BOOT.equals(library)) {
if (useSwaggerUI && selectedDocumentationProviderRequiresSwaggerUiBootstrap()) {
supportingFiles.add(new SupportingFile("swagger-ui.mustache", "src/main/resources/static", "swagger-ui.html"));
}
// rename template to SpringBootApplication.mustache
supportingFiles.add(new SupportingFile("openapi2SpringBoot.mustache",
(sourceFolder + File.separator + basePackage).replace(".", java.io.File.separator),
"OpenApiGeneratorApplication.java"));
supportingFiles.add(new SupportingFile("SpringBootTest.mustache",
(testFolder + File.separator + basePackage).replace(".", java.io.File.separator),
"OpenApiGeneratorApplicationTests.java"));
supportingFiles.add(new SupportingFile("RFC3339DateFormat.mustache",
(sourceFolder + File.separator + basePackage).replace(".", java.io.File.separator),
"RFC3339DateFormat.java"));
}
....
You can always exclude the generated test package in Intellij IDE for local compilation issue.

Related

Kotlin exclude ktlint directories in maven

I am trying to remove generate-sources directory from giving klint errors, else adding a few scripts in exclude as an alternative
From here I figured we could do this in gradle
https://github.com/JLLeitschuh/ktlint-gradle/issues/97
This feature in gradle is shown as follows
ktlint {
filter {
exclude("**/generated/**")
include("**/kotlin/**")
}
}
So far I have tried doing this in Maven, but it still does linting on some unavoidable generated sources.
https://github.com/gantsign/ktlint-maven-plugin/issues/341
<sourcesExcludes>
<sourcesExcludes>directoryToExclude<sourcesExclude>
</sourcesExcludes>
Using above in maven plugin
<plugin>
<groupId>com.github.gantsign.maven</groupId>
<artifactId>ktlint-maven-plugin</artifactId>
<version>1.7.0</version>
<executions>
<execution>
<configuration>
<sourcesExcludes>
<sourcesExclude>**/generated-sources/graphql/com/expediagroup/dataquality/api/utils/**</sourcesExclude>
</sourcesExcludes>
</configuration>
<phase>prepare-package</phase>
<goals>
<goal>format</goal>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
Any help on how I can exclude generated-sources directory is appreciated.
I found the solution here
https://github.com/gantsign/ktlint-maven-plugin/issues/341
And we just have to use below to avoid target files.
<configuration>
<sourceRoots>${project.build.sourceDirectory}</sourceRoots>
</configuration>

How can I compile a project that implements interfaces in generated sources folder from openapi generator?

I am using the OpenAPI generator maven plugin with kotlin-spring generator to generate interfaces for my API based on the specification.
As an example, I used the specification by this blog post and the following plugin configuration:
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>5.1.0</version>
<executions>
<execution>*
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>
${project.basedir}/src/main/resources/petstore.yml
</inputSpec>
<generatorName>kotlin-spring</generatorName>
<modelNameSuffix>Dto</modelNameSuffix>
<configOptions>
<basePackage>com.example</basePackage>
<apiPackage>com.example.api</apiPackage>
<modelPackage>com.example.model</modelPackage>
<configPackage>com.example.config</configPackage>
<delegatePattern>true</delegatePattern>
<interfaceOnly>true</interfaceOnly>
<supportingFilesToGenerate>
ApiUtil.kt
</supportingFilesToGenerate>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
When I run mvn clean generate-sources then the files are properly generated in target/generated-sources/openapi/....
I then create an implementation of the delegate in my src folder where I can override the methods of the generated interface:
package com.example.api
class PetsApiDelegateImpl : PetsApiDelegate {
}
Up to now, everything is good and IntelliJ is also happy with it. However, when I run mvn clean compile the target folder is deleted and re-generated again as expected but I still receive an error:
[ERROR] Failed to execute goal org.jetbrains.kotlin:kotlin-maven-plugin:1.5.31:compile (compile) on project choreographer: Compilation failure
[ERROR] /path/to/example/src/main/kotlin/com/example/api/PetsApiDelegateImpl.kt:[3,29] Unresolved reference: PetsApiDelegate
In other words, the files are generated as part of mvn clean compile but compilation still fails because the interface is not found.
How can I successfully compile this project?
We can resolve the compilation failure by adding an execution for the compile goal to the kotlin-maven-plugin that configures the generated directory as source directory.
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>${project.build.directory}/generated-sources/kotlin/src/main/kotlin</sourceDir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>

Using sonar.test.exclusions with Sonarqube 6.3

I'm currently evaluating Sonarqube 6.3 (a big upgrade from my current 5.5 instance) and I'm getting confused trying to work out the functionality of the sonar.test.exclusions setting.
There's this question: Sonar Maven Plugin: How do I exclude test source directories? which seems to indicate that it is used to exclude test files from analysis (which is what I'm after - I don't want my sonar ruleset run over my unit tests). The documentation https://docs.sonarqube.org/display/SONAR/Narrowing+the+Focus also indicates that it is used to 'exclude unit test files' (perhaps this can be expanded upon to make it clearer?)
Thing is, when I add sonar.test.exclusions with a value of **/src/test/** and then run my analysis, I'm still getting code smells and the like being found for:
Foo/src/test/java/foo/bar/BarTest.java
Foo/src/test/java/lah/LahTest.java
etc.
When I use sonar.exclusions instead, they don't show up. Why is sonar.test.exclusions not doing what I expect?
First of all: if you have a Maven project, you should use the scanner for Maven (mvn sonar:sonar). It will simplify your configuration, and will automatically register src/test/java folder as a test directory.
Now if you want to do the configuration manually, or understand what is going on under the hood, here is the explanation: SonarQube scanner work with 2 sets of files, main and test. Main source files are configured using the property sonar.sources. Test source files are configured using sonar.tests.
On top of that, you can filter some content using the sonar.[test.]exclusions properties.
In you case your problem is that Foo/src/test/java/foo/bar/BarTest.java seems to be considered as a main source file. That's why sonar.test.exclusions has no effect.
Using maven with verfication goal (mvn clean verify sonar:sonar install), I have used this configuration without problems:
...
<properties>
....
<sonar.exclusions>
**/generated/**/*,
**/model/**/*
</sonar.exclusions>
<sonar.test.exclusions>
src/test/**/*
</sonar.test.exclusions>
....
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
<sonar.coverage.exclusions>
**/generated/**/*,
**/model/**/*
</sonar.coverage.exclusions>
<jacoco.version>0.7.5.201505241946</jacoco.version>
....
</properties>
....
Coverage exclusion configuration, inside properties (up) and jacoco plugin configuracion:
.....
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>target/jacoco.exec</dataFile>
<outputDirectory>target/jacoco-ut</outputDirectory>
</configuration>
</execution>
</executions>
<configuration>
<systemPropertyVariables>
<jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
....

jmeter-maven-plugin libraries management

I have such plugin configuration in my pom.xml
<plugins>
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<version>${jmeter.maven.plugin.version}</version>
<configuration>
<jmeterExtensions>
<artifact>kg.apc:jmeter-plugins-json:2.4</artifact>
<artifact>kg.apc:jmeter-plugins-casutg:2.1</artifact>
</jmeterExtensions>
<junitLibraries>
<artifact>com.microsoft.sqlserver:sqljdbc4:4.0</artifact>
</junitLibraries>
<testFilesIncluded>
<jMeterTestFile>${tests.include}</jMeterTestFile>
</testFilesIncluded>
<jMeterProcessJVMSettings>
<xms>2048</xms>
<xmx>2048</xmx>
</jMeterProcessJVMSettings>
<customPropertiesFiles>
<!-- Custom property file -->
</customPropertiesFiles>
<propertiesJMeter>
<!-- Some properties that I pass into jmeter -->
</propertiesJMeter>
</configuration>
<executions>
<execution>
<id>jmeter-tests</id>
<phase>verify</phase>
<goals>
<goal>jmeter</goal>
</goals>
</execution>
</executions>
</plugin>
After I run mvn clean verify I get such libsat /target/jmeter/lib/:
json-path-2.1.0.jar
json-path-2.2.0.jar
and in log file I see that jmeter fails from time to time with such exception:
jmeter.extractor.json.jsonpath.JSONPostProcessor: Error processing JSON content in Select Team Name, message:Could not compile inline filter : [?(#.id=="29011")]
Note that this [?(#.id=="29011")] is only a part of expression. Full expression is looks like similar to this: $.teamData[?(#.id=="29011")].name
I expect that this error somehow related to this multiple libs
Use last version of the plugin which has solved this issue as described in release notes:
https://github.com/jmeter-maven-plugin/jmeter-maven-plugin/blob/master/CHANGELOG.md

Maven: custom assembly deployment

Due to need for heavy customization I did developed my own Groovy plugin, which creates ZIP archive, which is 100% ready for deployment (like Maven assembly plugin does). Still, if I run
mvn clean install ...
command it creates an assembly (single ZIP file), puts it to ${project.build.directory} (.../target) and that's it.
How do I tell Maven, that it's now part of deployment and I would like to deploy this ZIP file?
You have two options:
Use buildhelper:attach-artifact:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>some file</file>
<type>extension of your file </type>
<classifier>optional</classifier>
</artifact>
...
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
Alternatively (and better), you could include the necessary code in your own plugin:
#Component
protected MavenProject project;
#Component
protected MavenProjectHelper projectHelper;
...
projectHelper.attachArtifact(project, "jar", resource.getClassifier(), targetArchive);
Actually it worked in Groovy too (running from groovy-maven-plugin):
def helper =
session.lookup("org.apache.maven.project.MavenProjectHelper");
helper.attachArtifact(project, "zip", _classifier, new File(_archiveFilename));
N.B.:
Both _classifier and _archiveFilename should be declared and initialized by your code.

Resources