inugamiio / inugami-project-analysis-maven-plugin-parent

Maven plugin for analyze your project and produce complet release notes
http://inugami.io
GNU General Public License v3.0
2 stars 0 forks source link
java maven neo4j springboot

= Inugami Project analysis maven plugin :toc: :source-highlighter: pygments

Inugami project analysis maven plugin have for target to generate a release note on your project. Detect hidden dependencies on microservices is not easy. This plugin use Neo4J to resolve them. You can find a generated release note example here : link:doc/release-note-example.adoc[release-note]

== Last Release:

[source,xml]

io.inugami.maven.plugin.analysis inugami-project-analysis-maven-plugin 1.5.2 check analyze check info info retrieveInformation

== Quick start :

This maven plugin use Neo4J database to store information and resolve them. If you don't have Neo4J you can test on your local environment or run a Neo4J with docker.

.docker-compose.yml [source,yaml]

version: "3" services: neo4j: image: neo4j:4.1.1 ports:

In your project pom.xml (or settings) we need to add some properties :

[source,xml]

your.base.package bolt://localhost:7687 neo4j password

You can also define Neo4J configuration into your maven settings :

[source,xml]

neo4j neo4j {Yt5nGluOZ0sHzEiL7Le2IHFjtuTonkfx4yVEG3CYzZ8=} bolt://localhost:7687

In this case, your maven settings will override your pom.xml properties.

In your project build definition :

[source,xml]

io.inugami.maven.plugin.analysis inugami-project-analysis-maven-plugin 1.4.2 true check analyze check info info retrieveInformation

First you need to analyse your project to send data into NEO4J:

[source,bash]

mvn analyze

image::doc/analyze-01.png[] image::doc/analyze-02.png[]

After this analyse you can see in Neo4j your project information or just execute maven phase info

[source,bash]

mvn info

image::doc/info.png[]

This phase requires to specify an action to display information

== Neo4j data structure :

image::doc/nodes.png[]

[source,cql]

CALL db.schema.visualization

== Retrieve information :

After analyze, all information is present into Neo4J. We can now query Neo4J to retrieve information. Attention : in some commons use cases it's easier to invoke the plugin to display result.

All additional properties can be defined in properties section of pom.xml or via command line invocation (with -D prefix).

=== restServices

One of common problems in microservice architecture is to known interconnections between services. What's happen if I change my service ? Who consume a service and which version is currently in use ? To address this issue, the inugami analysis plugin will analyze all Springboot Rest endpoint and feign clients to detect interdependencies between projects.

REST endpoints can be defined in current project or as a transitive dependency. The plugin retrieve transitive dependencies over 10 sub levels.

[source,bash]

mvn info -Daction=restServices

The color code is the same as Swagger, all GET endpoints are blue, green for POST, and red for DELETE.

image::doc/restServices-01.png[]

In case where some projects consume an endpoint these will be described in the result :

image::doc/restServices-02.png[]

=== queryDisplay

Query display allows the generation of a Neo4J cypher query from the current projet.

[source,bash]

mvn info -Daction=queryDisplay

image::doc/queryDisplay-01.png[]

Different queries are available, so it's required to specify the one in use.


mvn info -Daction=queryDisplay -Dquery=search_services_rest

[source,bash]

mvn info -Daction=queryDisplay -Dquery=search_error_codes

image::doc/queryDisplay-02.png[]

=== properties

Properties action displays project properties. This action retrieves also dependencies properties. At this moment these properties are extracted from Spring properties (@Value, bean properties, conditionals beans, properties usages on JMS or RabbitMQ listeners)

If a property has no default value, it will be displayed in red. In yellow, we have properties who enable some beans. If a property have bean validator constraints, these will be displayed too.

[source,bash]

mvn info -Daction=properties

image::doc/properties.png[]

=== queueInfo

Queue information have the same approach as restServices but for JMS and RabbitMQ. It's able to detect producers and listeners, tracing event payload and all information on queue binding.

Like restServices, the queueInfo retrieves information over 10 levels of transitive dependencies.

[source,bash]

mvn info -Daction=queueInfo

image::doc/queue.png[]

To track all JMS senders and RabbitMQ sender it's required to add annotations in your source code.

For JMS :

[source,java]

@JmsSender(destination = "${my.activeMq.onUserCreated.queue}", id = "create.user.queue") public void sendCreateUser(final String someParameter, @JmsEvent final User user) { // process sending event }

For RabbitMQ :

[source,bash]

@RabbitMqSender(echangeName = "${events.exchangeName}", queue = "${events.method.user.queueName}", routingKey = "${events.user.method.created.routingKey}" ) public void fireEvent(@RabbitMqEvent final UserCreatedEvent event) { // process sending event }

If you use multi-handler on RabbitLister you need to add an annotation specifying which routing key is in use :

[source,java]

@RabbitMqHandlerInfo(routingKey = "${events.user.authenticated.routingKey}", typeId = "${events.user.authenticated.typeId}") @RabbitHandler public void onAuthenticated(final UserAuthenticatedEvent event) { // process listen }

All specific annotations are contained into an inugami artifact :

[source,xml]

io.inugami.maven.plugin.analysis inugami-project-analysis-maven-plugin-annotations ${io.inugami.maven.plugin.analysis.version}

This artifact contains only annotations, nothing else.

=== errorDisplay

Error management is essential to make better applications. Interteam communication is a must. Writing wiki is not our way, it's time-consuming and quickly outdate. Inugami generates errors directly from code.

[source,bash]

mvn info -Daction=errorDisplay

Per default Inugami plugin use the Inugami error interface to detect error code :

[source,java]

package io.inugami.api.exceptions; import java.util.function.BiConsumer;

public interface ErrorCode { public ErrorCode getCurrentErrorCode();

default int getStatusCode() {
    return getCurrentErrorCode() == null ? 500 : getCurrentErrorCode().getStatusCode();
}

default String getErrorCode() {
    return getCurrentErrorCode() == null ? "undefine" : getCurrentErrorCode().getErrorCode();
}

default String getMessage() {
    return getCurrentErrorCode() == null ? "error" : getCurrentErrorCode().getMessage();
}

default String getMessageDetail() {
    return getCurrentErrorCode() == null ? null : getCurrentErrorCode().getMessageDetail();
}

default String getErrorType() {
    return getCurrentErrorCode() == null ? "technical" : getCurrentErrorCode().getErrorType();
}

default String getPayload() {
    return getCurrentErrorCode() == null ? null : getCurrentErrorCode().getPayload();
}

default BiConsumer<String, Exception> getErrorHandler() {
    return getCurrentErrorCode() == null ? null : getCurrentErrorCode().getErrorHandler();
}

}

This interface is present in inugami_api artifact :

[source,xml]

io.inugami inugami_api 2.0.0

This interface can be used over enum types or on static class fields.

[source,java]

public enum IssuesError implements ErrorCode {

ISSUES_1(newBuilder()
        .setStatusCode(400)
        .setMessage("issues request invalid")
        .setErrorType("input")),

ISSUES_1_1(newBuilder()
        .setStatusCode(400)
        .setMessage("issue uid is mandatory")
        .setFonctionnalError());

private final ErrorCode errorCode;

private IssuesError(final ErrorCodeBuilder errorBuilder) {
    errorCode = errorBuilder.setErrorCode(this.name()).build();
}

@Override
public ErrorCode getCurrentErrorCode() {
    return errorCode;
}

}

You can define your error code interface, to do so just add a property in your pom.xml

[source,java]

io.inugami.demo.spring.boot.training.api.exceptions.ErrorCode

In this case the plugin will retrieve all values defined in your interface.

image::doc/errorCode.png[]

.Additional configuration |=== |Property | type | default value | description

|-Dinugami.maven.plugin.analysis.analyzer.errorCode.interface |String |io.inugami.api.exceptions.ErrorCode |The error code interface to use

|-Dexport | boolean | false | allow exporting results as CSV files |===

=== specificsQuery

The plugin is able to retrieve information from Neo4J and display them. If you need to execute a specific cypher query is possible to use this plugin to do that.

[source,bash]

mvn info -Daction=specificsQuery -Dexport=true

image::doc/specificQuery.png[]

.Additional configuration |=== |Property | type | default value | description

|-Dinugami.query.path |String |null |Path to cypher query, if isn't define the plugin will ask for this one in prompt.

|-Dinugami.skip.properties |String (Regex Pattern) |null |for not display some nodes properties

|-Dexport |boolean |false |Allow to export result as CSV file

|===

=== importData

To import some data into Neo4J it's possible to call the importData action. This action is able to execute a cypher query or to import a JSON model.

For both it's required to specify the property inugami.query.path to define the import script path

[source,bash]

mvn info -Daction=importData

For cypher query is just a basic .cql script. This one must juste have for extension .cql. Neo4j has great documentation on cypher language : https://neo4j.com/docs/cypher-manual/current/

For the JSON model, is the internal plugin model as JSON :

[source,json]

{ "nodes": [ { "type": "String", "uid": "String", "name": "String", "properties": { "": "Serializable", "": 42 } } ], "nodesToDeletes": ["String"], "createScripts" : ["String(Cypher)"], "relationships": [ { "from": "String", "to": "String", "type": "String", "properties": { "": "Serializable" } } ], "relationshipsToDeletes": [ { "from": "String", "to": "String", "type": "String", "properties": { "": "Serializable" } } ], "deleteScripts": ["String(Cypher)"] }

.Additional configuration |=== |Property | type | default value | description

|-Dinugami.query.path |String |null |Path to cypher or JSON import script query, if it's not defined the plugin will prompt for a value.

|===

=== Deployment management

Microservices complicate the deployment process. It's very important to know which microservice is on which environment.

==== publish

You need to pass some additional information to Neo4J to detect which artifact is on wich environment. The easiest way is to use the "publish action".

[source,bash]

mvn info -Daction=publish

image::doc/publish-01.png[]

image::doc/publish-02.png[]

On DEPLOY we can see that the plugin has added the deployment date (on ISO date and timestamp, both are on system time zone and on UTC) .Additional configuration

|=== |Property | type | default value | description

|-DuseMavenProject |Boolean | null |Allow using current project GAV, if null the plugin will prompt for a value.

|-Denv |String | null |Destination environment, if null the plugin will prompt for a value.

|-DenvLevel |int | 0 |To sort environments it's necessary to add weight, if null the plugin will prompt for a value.

|-DenvType |String | null |The environment type (like DEV, INT, PREP, PROD..), if null the plugin will prompt for a value.

|-DautoUnpublish |boolean |false |Allow remove relationship between an artifact and an environment node

|-DjustThisVersion |boolean |false |If you want to clean all version relationship between an artifact and an environment node

|-DpreviousEnv |boolean |false |For cleaning previous staging environment, this value will be prompted if not defined on an enabled autoPublish. |===

==== unpublish

It's very closer than publish but in this action we will remove deployments relationship on a specific version and an environment.

[source,bash]

mvn info -Daction=unpublish

.Additional configuration |=== |Property | type | default value | description

|-DuseMavenProject |boolean |false |Allow using current project GAV and not ask for this information

|-Denv |String | null |Destination environment, if null the plugin will prompt for a value.

|-DenvLevel |int | 0 |To sort environments it's necessary to add weight, if null the plugin will prompt for a value.

|-DenvType |String | null |The environment type (like DEV, INT, PREP, PROD..), if null the plugin will prompt for a value.

|-DjustThisVersion |boolean |false |If you want to clean all version relationship between an artifact and an environment node

|===

==== versionEnv

The action versionEnv is able to verify if your project have all dependencies available on all environments.

[source,bash]

mvn info -Daction=versionEnv

In this example, the project project-consumer is using a REST endpoint produced by spring-boot-training-lifecycle. PREP_2 is not deployed. The service project project-consumer can't work correctly on this environment.

Also, this project use a REST endpoint [GET]/comments/comments but no producer have been detected

image::doc/versionEnv.png[]

.Additional configuration |=== |Property | type | default value | description

|-Dexport |boolean |false |Allow exporting result as CSV file

|-DuseMavenProject |boolean |false |Allow using current project GAV and not ask for this information |===

==== envInfo

This action is a quick representation of an environment deployment status. It's able to retrieve which artifacts are present on which environments.

[source,bash]

mvn info -Daction=envInfo

image::doc/envInfo.png[]

.Additional configuration |=== |Property | type | default value | description

|-Dexport |boolean |false |Allow to export result as CSV file |===

=== encodePassword

This action is just a small tool to encode a password or sensible value in AES.

[source,bash]

mvn info -Daction=encodePassword

image::doc/password.png[]

.Additional configuration |=== |Property | type | default value | description

|-Dinugami.maven.plugin.analysis.secret |String (16 chars) |null |AES passphrase |===

== Analyzers :

=== Feign clients

Feign clients analyzer scan all feign client interface to resolve project consuming REST endpoints;

.Properties |=== |Property | type | default value | description

|inugami.maven.plugin.analysis.analyzer.feign.enable |boolean |true |Allow to disable feign client analyzer

|inugami.maven.plugin.analysis.analyzer.restControllers.strict |boolean |true |if this mode isn't enable, only mandatory fields in models have been used for identify REST endpoint |===

=== SpringBoot RestControllers

To resolve project REST endpoint exposition, this analyzer scan all SpringBoot RestController.

.Properties |=== |Property | type | default value | description

|inugami.maven.plugin.analysis.analyzer.restControllers.enable |boolean |true |Allow disabling feign client analyzer

|inugami.maven.plugin.analysis.analyzer.restControllers.strict |boolean |true |if this mode isn't enable, only mandatory fields in models have been used for identify REST endpoint |===

=== Spring properties

Bad properties configuration is the source of most problems on a spring project. This analyzer scan all properties injected by @Value annotation or Bean configuration definition.

.Properties |=== |Property | type | default value | description

|inugami.maven.plugin.analysis.analyzer.properties.enable |boolean |true |Allow disabling feign client analyzer |===

=== ActiveMQ

To resolve activeMQ consumers and listeners, this analyzer is scanning all Spring @JmsListener annotation.

.Properties |=== |Property | type | default value | description

|inugami.maven.plugin.analysis.analyzer.jms.enable |boolean |true |Allow disabling feign client analyzer |===

=== Error code

To resolve activeMQ consumers and listeners, this analyzer is scanning all Spring @JmsListener annotation.

.Properties |=== |Property | type | default value | description

|inugami.maven.plugin.analysis.analyzer.errorCode.enable |boolean |true |Allow disabling error code analyzer

|inugami.maven.plugin.analysis.analyzer.errorCode.interface |String |io.inugami.api.exceptions.ErrorCode |Allow to specify the error code interface, configured by default with inugami error code interface

|inugami.maven.plugin.analysis.analyzer.errorCode.fieldName |String |errorCode |Allow to override the default error code "field". The method defined in error code interface resolves this field. Accessor prefix is ignored |===

=== Flyway

this analyze allow to reference all flyway script. In release note you will see all them as differential.

.Properties |=== |Property | type | default value | description

|inugami.maven.plugin.analysis.analyzer.flyway.enabled |boolean |false |Allow to enable or disable flyway analyzer

|inugami.maven.plugin.analysis.analyzer.flyway.paths |String (path) |null |To define all root folders who contains flyway scripts. Semicolon is use for split each path

|inugami.maven.plugin.analysis.analyzer.flyway.defaultDb |String |{{folder name}} |Allow force default Database name

|inugami.maven.plugin.analysis.analyzer.flyway.scriptTypes |String |sql |Allow to define scripts type |===

=== Git SCM

Git scm analyzer allow to extract all commit since last project tag. If your project haven't tag yet, this analyzer retrieve all commit since repository creation.

After analyze, new nodes types appear :

image::doc/git_scm.png[]

image::doc/github_issues.png[]

image::doc/github_merge_request.png[]

To display the release note you can invoke task mvn info -Daction=releaseNote -PpreviousVersion={previousVersion}

image::doc/release_note_light.png[]

You can see on this example generated release-note as asciidoc : link:doc/release-note-example.adoc[release-note]

==== Issue Management

the Git scm analyzer will extract issues and merge request from commit message. On each it will call your issue management to retrieve more information on tickets.

To enable this behavior it's require to add issueManagement with link to SCM API in your pom.xml :

For GitLab :

[source,xml]

gitlab https://gitlab.com/api/v4/projects/123457890

For GitHub :

[source,xml]

github https://api.github.com/repos/inugamiio/inugami-project-analysis-maven-plugin-parent

For Jira :

[source,xml]

jira https://jira.url

All issue management need credentials to grant access on REST API. To configure these you will add server tag in your maven settings.xml :

[source,xml]

gitlab {MIAuTFbZUxsHC0aBub3Frxr1d/kik/yafcVYW6KDzqU=} github {s5Ydy14rYAwHekKyJxAYAFnFO6igA9/lykiQCT+ct8U=} jira {1Jur5y14rYAwHekKyJxAYAFnFO6igA9/lyki+ct8U=} {s5Ydy14rYAwHekKyJxAYAFnFO6igA9/lykiQCT+ct8U=}

It's possible to encrypt your password with maven standard encryption mechanism (https://maven.apache.org/guides/mini/guide-encryption.html)

.Properties |=== |Property | type | default value | description

|inugami.maven.plugin.analysis.git |boolean |false |Allow to enable git scanning and retrieve information from issues manager

|inugami.maven.plugin.analysis.issue.tracker.pr.url |String |${issueManagement.url} |If you use another repository to manage your project backlog, issueManagement.url must be configure on it. But to trace merge request you should define inugami.maven.plugin.analysis.issue.tracker.pr.url with the issue management of your source code repository

|===

===== Jira custom fields

Jira allow to define custom fields on your issues. To extract these you can create a SPI implementation of interface i.inugami.maven.plugin.analysis.api.scan.issue.tracker.JiraCustomFieldsAppender

[source,java]

public interface JiraCustomFieldsAppender { void append(String issueId, JsonNode json, LinkedHashMap<String, Serializable> issueProperties, ScanNeo4jResult neo4jResult); }

.Parameters |=== |Property | type | description

|issueId |String |Current issue uid

|json |com.fasterxml.jackson.databind.JsonNode |Tree representation of current Json response. For more information on Jira Rest API see https://docs.atlassian.com/software/jira/docs/api/REST/8.13.2/#api/2/issue-getIssue

|issueProperties |LinkedHashMap<String, Serializable> |Current properties

|neo4jResult |io.inugami.maven.plugin.analysis.api.models.ScanNeo4jResult |Allow to create another nodes or relationships |===

Your implementation can be in classpath or linked on plugin dependencies. All implementation must be declare into src/resources/META-INF/services/io.inugami.maven.plugin.analysis.api.scan.issue.tracker.JiraCustomFieldsAppender

Example :

src/resources/META-INF/services/io.inugami.maven.plugin.analysis.api.scan.issue.tracker.JiraCustomFieldsAppender :

[source]

io.app.JiraCustomFieldExtractor

[source,java]

package io.app;

public class JiraCustomFieldExtractor implements JiraCustomFieldsAppender { public void append(String issueId, JsonNode json, LinkedHashMap<String, Serializable> issueProperties, ScanNeo4jResult neo4jResult){ // implementation } }

=== ReleaseNote

Plugin main target is to generate a release note from current project. By default this release note will be generate as Json file.

An ASCIIDOC implementation is present to generate a documentation more human friendly.

To display the release note you can invoke task mvn info -Daction=releaseNote -PpreviousVersion={previousVersion}

.Properties |=== |Property | type | default value | description

|inugami.maven.plugin.analysis.display.release.note.full |boolean |false |Allow to append more information on your release note

|previousVersion |String |null |To be able to compute the difference between two version; it's require to specify previous version.

|interactive |boolean |true |If you doesn't need JSON release note; you can disable this feature with this parameter.

|inugami.maven.plugin.analysis.display.release.note.asciidoc |boolean |false |Allow to generate release note as ASCIIDOC

|inugami.maven.plugin.analysis.display.release.note.asciidoc.baseDir |String (path) |{builddir}/src/doc/releases |Allow to specify target folder

|inugami.maven.plugin.analysis.display.release.note.asciidoc.splitFile |boolean |false |Allow to generate the release note with one document or multi document parts |===

==== ReleaseNote UI

Since version 1.6.0 a spring boot module allow to display current project release notes. To include this ui you should add this dependency :

[source,xml]

io.inugami.maven.plugin.analysis.front inugami-project-analysis-front-springboot 1.6.2

By default the ui is accessible on URL : http://localhost:8080/release-note-app/

.Properties |=== |Property | type | default value | Require | description

|inugami.release.note.artifactName |String |null |true | Release note list json file name. This property is mandatory

After the release note building, two file will be created in your project :

|===

image::doc/ui-01.png[ui global,920,500]

image::doc/ui-02.png[ui detail,920,500]

https://www.youtube.com/watch?v=dJlF4RYd4eI&ab_channel=inugami

===== Update & ban dependencies

The inugami front ui is able to display information about dependencies baned or deprecated. The scan process doesn't check this information at this moment.

But you can create new DependenciesCheckService implementation:

[source,java]

public interface DependenciesCheckService { DependenciesCheck getDependenciesCheckData(); }

To implement this one you need to create a newer service and define it into a configuration bean :

[source,java]

public class MyDependenciesCheckService { public DependenciesCheck getDependenciesCheckData(){ return DependenciesCheck.builder() .deprecated(resolveDeprecatedArtifacts()) .ban(resolveBanedArtifacts()) .ban(resolveSecurityIssues()) .build(); } }

[source,java]

@Configuration public class MyProjectConfiguration {

@Primary
@Bean
public DependenciesCheck buildDependenciesCheck(){
    return new MyDependenciesCheckService();
}

}

This interface requires to return a DependenciesCheck object. This object is a basic DTO :

[source,java]

@ToString @Builder(toBuilder = true) @Setter @Getter public class DependenciesCheck { private List deprecated; private List ban; private List securityIssue; }

Each list contains a DependencyRule object like :

[source,java]

@ToString @Builder(toBuilder = true) @EqualsAndHashCode(onlyExplicitlyIncluded = true) @Setter @Getter public class DependencyRule { @EqualsAndHashCode.Include private String groupId; @EqualsAndHashCode.Include private String artifactId; @EqualsAndHashCode.Include private VersionRules rules; private String comment; private String link; private Level level; }

== Others goals :

=== mkdirs

This goal allow to create basic folders

[source,xml]

io.inugami.maven.plugin.analysis inugami-project-analysis-maven-plugin 1.6.3 mkdirs validate mkdirs ${basedir}/target/test ${basedir}/target/test2

=== delete

This goal allow to delete folder or files

[source,xml]

io.inugami.maven.plugin.analysis inugami-project-analysis-maven-plugin 1.6.3 mkdirs validate delete ${basedir}/target/test.* ${basedir}/target/generate/.*log

=== loadProperties

This goal allow to load maven properties. All loaded properties will be accessible in nextmaven phase.

==== Global properties

The goal loadProperties can have global properties. All of them will added in maven properties context.

[source,xml]

io.inugami.maven.plugin.analysis inugami-project-analysis-maven-plugin 1.6.3 loadProperties validate loadProperties joe

==== Local file properties

In most of time, we need to add properties from local file. This files can be properties file or json file (another file will be supported in next release). To do that you can specify resources. Each one need to specify the path (this path can have maven properties to templatize this one). Also it's require to specify the file type (properties or json)

[source,properties]

application.name=demo-app application.title=My application

[source,xml]

io.inugami.maven.plugin.analysis inugami-project-analysis-maven-plugin 1.6.3 loadProperties validate loadProperties joe properties ${basedir}/src/test/resources/simple.properties specific value

After properties loaded, you can use properties in maven context.

In case of JSON file, all properties will be render as flat value. For example :

[source,json]

{ "version": "0.0.1-SNAPSHOT", "app": { "name": "my application" }, "rules": [ { "type": "json", "enabled": "true" }, { "type": "yaml", "enabled": "false" } ], "authors": [ "john", "smith" ] }

Will be rendered in maven context as :

[source,json]

{ "version" : "0.0.1-SNAPSHOT", "app.name" : "my application", "rules.0.type" : "json", "rules.0.enabled" : "true", "rules.1.type" : "yaml", "rules.1.enabled" : "false", "authors.0" : "john", "authors.1" : "smith" }

==== Properties convertors

All properties convertors are SPI implementation. You can create easly one and enable its by including your jar dependency in inugami plugin. Inugami use a strategy partner to resolve right implementation. All of them need to implement the PropertiesConvertorSPI interface.

[source,java]

public interface PropertiesConvertorSpi { boolean accept(final String type);

Map<String, String> convert(final String content);

}

As all SPI implementation you need to declare its in the specific file /META-INF/services/io.inugami.maven.plugin.analysis.api.convertors.PropertiesConvertorSpi

[source]

io.inugami.maven.plugin.analysis.plugin.services.build.convertors.MyConvertor

After that you can create your implementation :

[source,java]

@SpiPriority(10) public class MyConvertor implements PropertiesConvertorSpi {

public static final String PROPERTIES = "properties";

@Override
public boolean accept(final String type) {
    return PROPERTIES.equalsIgnoreCase(type);
}

@Override
public Map<String, String> convert(final String content) {
    // implementation
}

}

Inugami order all implementation by higher SpiPriority. You can use this annotation if you need to override existing implementation.

==== External URL properties

If you need to retrieve properties from external source, like springboot cloud config, you can specify corresponding url to load this resource.

[source,xml]

io.inugami.maven.plugin.analysis inugami-project-analysis-maven-plugin 1.6.3 loadProperties validate loadProperties http://localhost:8888/demo.json Basic YWRtaW46cGFzc3dvcmQ=

In this example, the endpoint will give us a response like :

[source,json]

{ "external": { "applicationName": "externalJson" } }

It will be accessible in maven context by flatten value :

[source,json]

{ "external.applicationName" : "externalJson" }

=== writeFile

WriteFile goal allw to write file by using mustache template. By default, maven properties will be transform to mustache values.

For example :

[source,xml]

io.inugami.maven.plugin.analysis inugami-project-analysis-maven-plugin 1.6.3 loadProperties generate-resources writeFile true ${basedir}/target/file.from.innerTemplate.html Simple inner template rendering

Will write in ${basedir}/target/file.from.innerTemplate.html this content :

[source,xml]

demo

Simple inner template rendering


You can also create external template file :

[source,xml]

io.inugami.maven.plugin.analysis inugami-project-analysis-maven-plugin 1.6.3 loadProperties generate-resources writeFile true ${basedir}/target/file.from.externalTemplate.html ${basedir}/src/test/resources/simple.template.html Simple external template rendering With external template, you can create more complex file without pollute your maven pom.xml

with template like :

[source,xml]

demo

Simple external template rendering

With external template, you can create more complex file without pollute your maven pom.xml


Will generate this file :

[source,xml]

${project.artifactId}

{{subtitle}}

{{description}}


=== copy

This goal allow to copy file. It's also allow to filtering resource. This goal will inject properties only on text file, binary file will only be copy to target file.

==== copy simple file

In this example we have a simple file in ${basedir}/src/test/resources/simple.template.html

[source,xml]

${project.artifactId}

{{subtitle}}

{{description}}


This file will be copy to ${basedir}/src/test/resources/simple.template.html and all maven context properties will be injected :

[source,xml]

io.inugami.maven.plugin.analysis inugami-project-analysis-maven-plugin 1.6.3 loadProperties generate-resources copy true ${basedir}/target/generated/file.from.externalTemplate.html ${basedir}/src/test/resources/simple.template.html Simple copy Lorem ipsum

The file result will be :

[source,xml]

demo

Simple copy

Lorem ipsum


==== copy folder

The copy goal can also copy folder. To do that you need only to specify folder path and target as directories:

[source,xml]

io.inugami.maven.plugin.analysis inugami-project-analysis-maven-plugin 1.6.3 loadProperties generate-resources copy true ${basedir}/target/generated/template ${basedir}/src/test/resources/template Simple copy Lorem ipsum

==== maven dependencies

The copy goal can copy maven dependencies. In this case you need to specify the artifact GAV to copy in target destination :

[source,xml]

io.inugami.maven.plugin.analysis inugami-project-analysis-maven-plugin 1.6.3 loadProperties generate-resources copy true ${basedir}/target/maven/io.inugami.maven.plugin.analysis.front.jar io.inugami.maven.plugin.analysis.front:inugami-project-analysis-front-plugins:1.6.2-SNAPSHOT

=== unpack

Unpack goal can unzip resources into folder. When resources are write on filesystem, if it's text resources, the filtering is apply. This behavior can be disabled by configuration.

[source,xml]

io.inugami.maven.plugin.analysis inugami-project-analysis-maven-plugin 1.6.3 loadProperties generate-resources unpack true true ${basedir}/target/unpack io.inugami.maven.plugin.analysis.front:inugami-project-analysis-front-plugins:1.6.2-SNAPSHOT