Onboarding build optimization incl Qual Control
Sonar fixes, incremental build enhancements and Quality control mechanism integration.
Change-Id: I118d7fc0cc50c1eddb94137310c00afaaa3aaffb
Issue-ID: SDC-1189
Signed-off-by: GAUTAMS <gautams@amdocs.com>
diff --git a/openecomp-be/tools/artifact-copy-plugin/pom.xml b/openecomp-be/tools/artifact-copy-plugin/pom.xml
new file mode 100644
index 0000000..03301a7
--- /dev/null
+++ b/openecomp-be/tools/artifact-copy-plugin/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.openecomp.sdc.onboarding</groupId>
+ <artifactId>artifact-copy-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <parent>
+ <artifactId>sdc-onboarding</artifactId>
+ <groupId>org.openecomp.sdc</groupId>
+ <version>1.2.0-SNAPSHOT</version>
+ <relativePath>../../../onboarding</relativePath>
+ </parent>
+ <properties>
+ <skipPMD>true</skipPMD>
+ <classes>classes/**/*.class</classes>
+ <mavenStatus>maven-status/**</mavenStatus>
+ <skipTestRun>true</skipTestRun>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>${maven-core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.plugin-tools</groupId>
+ <artifactId>maven-plugin-annotations</artifactId>
+ <version>${maven-plugin-annotations.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>${maven-plugin-plugin.version}</version>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
diff --git a/openecomp-be/tools/artifact-copy-plugin/src/main/java/org/openecomp/sdc/onboarding/util/ArtifactHelper.java b/openecomp-be/tools/artifact-copy-plugin/src/main/java/org/openecomp/sdc/onboarding/util/ArtifactHelper.java
new file mode 100644
index 0000000..e7ad5da
--- /dev/null
+++ b/openecomp-be/tools/artifact-copy-plugin/src/main/java/org/openecomp/sdc/onboarding/util/ArtifactHelper.java
@@ -0,0 +1,56 @@
+package org.openecomp.sdc.onboarding.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.project.MavenProject;
+
+public class ArtifactHelper {
+
+ private MavenProject project;
+
+ List<ArtifactRepository> getRepositories(boolean snapshotRepo) {
+ List<ArtifactRepository> list = new ArrayList<>();
+ for (ArtifactRepository artRepo : project.getRemoteArtifactRepositories()) {
+ if (snapshotRepo) {
+ if (artRepo.getSnapshots().isEnabled()) {
+ list.add(artRepo);
+ }
+ } else {
+ if (artRepo.getReleases().isEnabled()) {
+ list.add(artRepo);
+ }
+ }
+ }
+ return list;
+ }
+
+ String getContents(URL path) throws IOException {
+ try (InputStream is = path.openStream(); Scanner scnr = new Scanner(is).useDelimiter("\\A")) {
+ return scnr.hasNext() ? scnr.next() : "";
+ }
+ }
+
+ String getChecksum(String filePath, String hashType) throws NoSuchAlgorithmException, IOException {
+ MessageDigest md = MessageDigest.getInstance(hashType);
+ md.update(Files.readAllBytes(Paths.get(filePath)));
+ byte[] hashBytes = md.digest();
+
+ StringBuffer buffer = new StringBuffer();
+ for (byte hashByte : hashBytes) {
+ buffer.append(Integer.toString((hashByte & 0xff) + 0x100, 16).substring(1));
+ }
+ return buffer.toString();
+ }
+
+}
+
+
diff --git a/openecomp-be/tools/artifact-copy-plugin/src/main/java/org/openecomp/sdc/onboarding/util/CalibrateArtifactPlugin.java b/openecomp-be/tools/artifact-copy-plugin/src/main/java/org/openecomp/sdc/onboarding/util/CalibrateArtifactPlugin.java
new file mode 100644
index 0000000..4838608
--- /dev/null
+++ b/openecomp-be/tools/artifact-copy-plugin/src/main/java/org/openecomp/sdc/onboarding/util/CalibrateArtifactPlugin.java
@@ -0,0 +1,82 @@
+package org.openecomp.sdc.onboarding.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.MavenProjectHelper;
+
+@Mojo(name = "calibrate-artifact-helper", threadSafe = true, defaultPhase = LifecyclePhase.INSTALL,
+ requiresDependencyResolution = ResolutionScope.TEST)
+public class CalibrateArtifactPlugin extends AbstractMojo {
+
+ private static final String ARTIFACT_COPY_PATH = "artifactPathToCopy";
+
+ @Parameter(defaultValue = "${session}")
+ private MavenSession session;
+ @Parameter(defaultValue = "${project}", readonly = true)
+ private MavenProject project;
+ @Component
+ private MavenProjectHelper projectHelper;
+ @Parameter
+ private String groupId;
+ @Parameter
+ private String artifactId;
+ @Parameter
+ private String version;
+ @Parameter
+ private String targetLocation;
+ @Parameter
+ private String name;
+ @Parameter
+ private String excludePackaging;
+ @Parameter
+ private ArtifactHelper artifactHelper;
+
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ if (project.getPackaging().equals(excludePackaging)) {
+ return;
+ }
+ if (project.getProperties().containsKey(ARTIFACT_COPY_PATH)
+ && project.getProperties().getProperty(ARTIFACT_COPY_PATH) != null) {
+ File f = null;
+ String artifactPath = project.getProperties().getProperty(ARTIFACT_COPY_PATH)
+ .startsWith(session.getLocalRepository().getBasedir()) ?
+ project.getProperties().getProperty(ARTIFACT_COPY_PATH) :
+ project.getProperties().getProperty(ARTIFACT_COPY_PATH)
+ .replace(groupId, groupId.replace('.', '/'));
+ if (artifactPath.startsWith(session.getLocalRepository().getBasedir())) {
+ f = new File(artifactPath);
+ } else {
+ f = new File(session.getLocalRepository().getBasedir(), artifactPath);
+ }
+ if (f.exists()) {
+ project.getArtifact().setFile(f);
+ }
+ }
+ File file = new File(project.getBuild().getDirectory(), project.getBuild().getFinalName() + ".unicorn");
+ if (file.exists()) {
+ try {
+ Files.copy(file.toPath(), Paths.get(
+ session.getLocalRepository().getBasedir() + File.separator + project.getGroupId().replace(".",
+ File.separator) + File.separator + project.getArtifactId() + File.separator
+ + project.getVersion(), project.getBuild().getFinalName() + ".unicorn"),
+ StandardCopyOption.REPLACE_EXISTING);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+ }
+}
diff --git a/openecomp-be/tools/artifact-copy-plugin/src/main/java/org/openecomp/sdc/onboarding/util/CopyArtifactPlugin.java b/openecomp-be/tools/artifact-copy-plugin/src/main/java/org/openecomp/sdc/onboarding/util/CopyArtifactPlugin.java
new file mode 100644
index 0000000..20b1a7c
--- /dev/null
+++ b/openecomp-be/tools/artifact-copy-plugin/src/main/java/org/openecomp/sdc/onboarding/util/CopyArtifactPlugin.java
@@ -0,0 +1,141 @@
+package org.openecomp.sdc.onboarding.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.StandardOpenOption;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.List;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.project.MavenProject;
+
+@Mojo(name = "copy-helper", threadSafe = true, defaultPhase = LifecyclePhase.CLEAN,
+ requiresDependencyResolution = ResolutionScope.NONE)
+public class CopyArtifactPlugin extends AbstractMojo {
+
+ @Parameter(defaultValue = "${session}")
+ private MavenSession session;
+ @Parameter(defaultValue = "${project}", readonly = true)
+ private MavenProject project;
+ @Parameter
+ private String groupId;
+ @Parameter
+ private String artifactId;
+ @Parameter
+ private String version;
+ @Parameter
+ private String targetLocation;
+ @Parameter
+ private String name;
+ @Parameter
+ private ArtifactHelper artifactHelper;
+
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ if (!project.getProperties().containsKey("resolvedVersion")) {
+ return;
+ }
+ boolean isSnapshot = version.contains("SNAPSHOT");
+ List<ArtifactRepository> artRepoList = artifactHelper.getRepositories(isSnapshot);
+ String resolvedVersion =
+ project.getProperties().getProperty("resolvedVersion");
+ try {
+ if (!version.equals(resolvedVersion)) {
+ if(copyResolvedArtifact(artRepoList, resolvedVersion) && getLog().isInfoEnabled()){
+ getLog().info("Data Artifact Copied with "+resolvedVersion);
+ }
+
+ }
+ File orgFile = new File(
+ session.getLocalRepository().getBasedir() + File.separator + (groupId.replace(".", File.separator))
+ + File.separator + artifactId + File.separator + version);
+ if (!orgFile.exists()) {
+ return;
+ }
+ File[] list = orgFile.listFiles(t -> t.getName().equals(artifactId + "-" + version + ".jar"));
+ if (list != null && list.length > 0) {
+ String directory = session.getLocalRepository().getBasedir() + File.separator + (groupId.replace(".",
+ File.separator)) + File.separator + targetLocation + File.separator + version;
+ if (!Paths.get(directory, name).toFile().exists()) {
+ return;
+ }
+ Files.copy(list[0].toPath(), Paths.get(directory, name), StandardCopyOption.REPLACE_EXISTING);
+ copyTargetArtifact(directory, list[0]);
+ }
+ } catch (IOException | NoSuchAlgorithmException e) {
+ throw new MojoFailureException(e.getMessage());
+ }
+ }
+
+ private void copyTargetArtifact(String directory, File source) throws IOException, NoSuchAlgorithmException {
+ File[] files = new File(directory).listFiles(
+ f -> f.getName().endsWith(".jar") && !f.getName().equals(name) && f.getName().startsWith(
+ name.substring(0, name.lastIndexOf('-'))));
+ if (files == null || files.length == 0) {
+ return;
+ }
+ Arrays.sort(files, this::compare);
+ File tgtFile = files[files.length - 1];
+ Files.copy(source.toPath(), tgtFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
+ for (String checksumType : Arrays.asList("sha1", "md5")) {
+ File potentialFile = new File(tgtFile.getAbsolutePath() + "." + checksumType);
+ if (potentialFile.exists()) {
+ Files.write(potentialFile.toPath(),
+ artifactHelper.getChecksum(source.getAbsolutePath(), checksumType).getBytes(),
+ StandardOpenOption.CREATE);
+ }
+ }
+ }
+
+
+ private boolean copyResolvedArtifact(List<ArtifactRepository> list, String resolvedVersion){
+ for (ArtifactRepository repo : list) {
+ try {
+ writeContents(
+ new URL(repo.getUrl() + (groupId.replace('.', '/')) + '/' + artifactId + '/' + version + '/'
+ + artifactId + "-" + (version.equals(resolvedVersion) ? version :
+ version.replace("SNAPSHOT", resolvedVersion))
+ + ".jar"));
+ return true;
+ } catch (IOException e) {
+ getLog().warn(e);
+ }
+ }
+ return false;
+ }
+
+
+ private void writeContents(URL path) throws IOException {
+ String directory =
+ session.getLocalRepository().getBasedir() + File.separator + (groupId.replace(".", File.separator))
+ + File.separator + artifactId + File.separator + version;
+ try (InputStream is = path.openStream()) {
+ Files.copy(is, Paths.get(directory, artifactId + "-" + version + ".jar"),
+ StandardCopyOption.REPLACE_EXISTING);
+ }
+
+ }
+
+ private int compare(File file1, File file2) {
+ if (file1.lastModified() > file2.lastModified()) {
+ return 1;
+ }
+ if (file1.lastModified() < file2.lastModified()) {
+ return -1;
+ }
+ return 0;
+ }
+
+}
diff --git a/openecomp-be/tools/artifact-copy-plugin/src/main/java/org/openecomp/sdc/onboarding/util/InitializationHelperMojo.java b/openecomp-be/tools/artifact-copy-plugin/src/main/java/org/openecomp/sdc/onboarding/util/InitializationHelperMojo.java
new file mode 100644
index 0000000..0675175
--- /dev/null
+++ b/openecomp-be/tools/artifact-copy-plugin/src/main/java/org/openecomp/sdc/onboarding/util/InitializationHelperMojo.java
@@ -0,0 +1,88 @@
+package org.openecomp.sdc.onboarding.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.project.MavenProject;
+
+@Mojo(name = "init-artifact-helper", threadSafe = true, defaultPhase = LifecyclePhase.PRE_CLEAN,
+ requiresDependencyResolution = ResolutionScope.NONE)
+public class InitializationHelperMojo extends AbstractMojo {
+
+ private static final String SKIP_GET = "skipGet";
+
+ @Parameter(defaultValue = "${session}")
+ private MavenSession session;
+ @Parameter(defaultValue = "${project}", readonly = true)
+ private MavenProject project;
+ @Parameter
+ private String groupId;
+ @Parameter
+ private String artifactId;
+ @Parameter
+ private String version;
+ @Parameter
+ private String targetLocation;
+ @Parameter
+ private String name;
+ @Parameter
+ private String excludePackaging;
+ @Parameter
+ private ArtifactHelper artifactHelper;
+
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ if (System.getProperties().containsKey(SKIP_GET)) {
+ project.getProperties()
+ .setProperty(SKIP_GET, Boolean.valueOf(System.getProperties().containsKey(SKIP_GET)).toString());
+ return;
+ } else {
+ File orgFile = new File(
+ session.getLocalRepository().getBasedir() + File.separator + (groupId.replace(".", File.separator))
+ + File.separator + artifactId + File.separator + version);
+ String resolvedVersion = getResolvedVersion(artifactHelper.getRepositories(version.contains("SNAPSHOT")));
+ project.getProperties().setProperty("resolvedVersion", resolvedVersion);
+ System.getProperties().setProperty(SKIP_GET, Boolean.TRUE.toString());
+ if (resolvedVersion.equals(version) && !orgFile.exists()) {
+ project.getProperties().setProperty(SKIP_GET, Boolean.TRUE.toString());
+ }
+ }
+ }
+
+ private String getResolvedVersion(List<ArtifactRepository> list) {
+ Pattern timestampPattern = Pattern.compile(".*<timestamp>(.*)</timestamp>.*");
+ Pattern buildNumberPattern = Pattern.compile(".*<buildNumber>(.*)</buildNumber>.*");
+ String timestamp = null;
+ String buildNumber = null;
+ for (ArtifactRepository repo : list) {
+ try {
+ String content = artifactHelper.getContents(
+ new URL(repo.getUrl() + (groupId.replace('.', '/')) + '/' + artifactId + '/' + version
+ + "/maven-metadata.xml"));
+ Matcher m = timestampPattern.matcher(content);
+ if (m.find()) {
+ timestamp = m.group(1);
+ }
+ m = buildNumberPattern.matcher(content);
+ if (m.find()) {
+ buildNumber = m.group(1);
+ }
+ } catch (IOException e) {
+ continue;
+ }
+ }
+ return timestamp != null && buildNumber != null ? timestamp + "-" + buildNumber : version;
+ }
+
+}
diff --git a/openecomp-be/tools/build-data-helper/pom.xml b/openecomp-be/tools/build-data-helper/pom.xml
new file mode 100644
index 0000000..a5f55c3
--- /dev/null
+++ b/openecomp-be/tools/build-data-helper/pom.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.openecomp.sdc</groupId>
+ <artifactId>build-data-helper</artifactId>
+
+ <parent>
+ <artifactId>sdc-onboarding</artifactId>
+ <groupId>org.openecomp.sdc</groupId>
+ <version>1.2.0-SNAPSHOT</version>
+ <relativePath>../../../onboarding</relativePath>
+ </parent>
+ <properties>
+ <skipPMD>true</skipPMD>
+ <artifactPathToCopy>${project.groupId}/${project.artifactId}/${project.version}/${project.artifactId}-${project.version}.jar</artifactPathToCopy>
+ </properties>
+<build>
+ <plugins>
+ <plugin>
+ <groupId>org.openecomp.sdc.onboarding</groupId>
+ <artifactId>artifact-copy-plugin</artifactId>
+ <version>${project.version}</version>
+ <executions>
+ <execution>
+ <id>id3</id>
+ <goals>
+ <goal>copy-helper</goal>
+ <goal>calibrate-artifact-helper</goal>
+ </goals>
+ <phase>install</phase>
+ </execution>
+ <execution>
+ <id>id4</id>
+ <goals>
+ <goal>init-artifact-helper</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <groupId>org.openecomp.sdc</groupId>
+ <artifactId>build-data-installer</artifactId>
+ <version>${project.version}</version>
+ <targetLocation>build-data-helper</targetLocation>
+ <name>build-data-helper-${project.version}.jar</name>
+ <artifactHelper>
+ <project>${project}</project>
+ </artifactHelper>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>3.1.0</version>
+ <executions>
+ <execution>
+ <id>id1</id>
+ <goals>
+ <goal>get</goal>
+ </goals>
+ <phase>clean</phase>
+ <configuration>
+ <artifactId>build-data-helper</artifactId>
+ </configuration>
+ </execution>
+ <execution>
+ <id>id2</id>
+ <goals>
+ <goal>get</goal>
+ </goals>
+ <phase>clean</phase>
+ <configuration>
+ <artifactId>build-data-installer</artifactId>
+ </configuration>
+ </execution>
+ </executions>
+ <configuration>
+ <groupId>org.openecomp.sdc</groupId>
+ <version>${project.version}</version>
+ <skip>${skipGet}</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+</build>
+
+</project>
\ No newline at end of file
diff --git a/openecomp-be/tools/build-data-installer/pom.xml b/openecomp-be/tools/build-data-installer/pom.xml
new file mode 100644
index 0000000..94121b5
--- /dev/null
+++ b/openecomp-be/tools/build-data-installer/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.openecomp.sdc</groupId>
+ <artifactId>build-data-installer</artifactId>
+
+ <parent>
+ <artifactId>sdc-onboarding</artifactId>
+ <groupId>org.openecomp.sdc</groupId>
+ <version>1.2.0-SNAPSHOT</version>
+ <relativePath>../../../onboarding</relativePath>
+ </parent>
+ <properties>
+ <skipPMD>true</skipPMD>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.openecomp.sdc.onboarding</groupId>
+ <artifactId>pmd-helper-plugin</artifactId>
+ <version>${project.version}</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.sdc</groupId>
+ <artifactId>build-data-helper</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <goals>
+ <goal>init-pmd-helper</goal>
+ <goal>post-verify-helper</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <excludePackaging>pom</excludePackaging>
+ <pmdTargetLocation>${project.build.directory}/pmd/pmd.xml</pmdTargetLocation>
+ <pmdReportFile>${project.build.directory}/pmd/pmd.csv</pmdReportFile>
+ <pmdFailureReportLocation>${project.build.directory}/pmd.txt</pmdFailureReportLocation>
+ <persistingModuleCoordinates>org.openecomp.sdc:build-data-installer</persistingModuleCoordinates>
+ <pmdCurrentStateFilePath>org.openecomp.sdc:sdc-onboarding/target/build-data/pmdState.dat</pmdCurrentStateFilePath>
+ <pmdStateFile>${project.build.outputDirectory}/pmd.dat</pmdStateFile>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
diff --git a/openecomp-be/tools/compile-helper-plugin/pom.xml b/openecomp-be/tools/compile-helper-plugin/pom.xml
index 3891558..73513f6 100644
--- a/openecomp-be/tools/compile-helper-plugin/pom.xml
+++ b/openecomp-be/tools/compile-helper-plugin/pom.xml
@@ -14,7 +14,12 @@
<version>1.2.0-SNAPSHOT</version>
<relativePath>../../../onboarding</relativePath>
</parent>
-
+ <properties>
+ <skipPMD>true</skipPMD>
+ <classes>classes/**/*.class</classes>
+ <mavenStatus>maven-status/**</mavenStatus>
+ <skipTestRun>true</skipTestRun>
+ </properties>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
diff --git a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/BuildHelper.java b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/BuildHelper.java
new file mode 100644
index 0000000..42f3166
--- /dev/null
+++ b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/BuildHelper.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright © 2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on a "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.onboarding;
+
+import static org.openecomp.sdc.onboarding.Constants.JAVA_EXT;
+import static org.openecomp.sdc.onboarding.Constants.UNICORN;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.UncheckedIOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.RecursiveTask;
+import java.util.stream.Collectors;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+
+class BuildHelper {
+
+ private BuildHelper() {
+ // donot remove.
+ }
+
+ static long getChecksum(File file, String fileType) {
+ try {
+ return readSources(file, fileType).hashCode();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ static String getSourceChecksum(String data, String hashType) throws NoSuchAlgorithmException {
+ MessageDigest md = MessageDigest.getInstance(hashType);
+ md.update(data.getBytes());
+ byte[] hashBytes = md.digest();
+
+ StringBuffer buffer = new StringBuffer();
+ for (byte hashByte : hashBytes) {
+ buffer.append(Integer.toString((hashByte & 0xff) + 0x100, 16).substring(1));
+ }
+ return buffer.toString();
+ }
+
+
+ private static Map<String, String> readSources(File file, String fileType) throws IOException {
+ Map<String, String> source = new HashMap<>();
+ if (file.exists()) {
+ List<File> list = Files.walk(Paths.get(file.getAbsolutePath()))
+ .filter(JAVA_EXT.equals(fileType) ? BuildHelper::isRegularJavaFile :
+ Files::isRegularFile).map(p -> p.toFile())
+ .collect(Collectors.toList());
+ source.putAll(ForkJoinPool.commonPool()
+ .invoke(new FileReadTask(list.toArray(new File[0]), file.getAbsolutePath())));
+ }
+ return source;
+ }
+
+ private static boolean isRegularJavaFile(Path path) {
+ File file = path.toFile();
+ return file.isFile() && file.getName().endsWith(JAVA_EXT);
+ }
+
+ private static String getData(File file, byte[] buffer) {
+ try (FileInputStream fis = new FileInputStream(file);
+ BufferedInputStream bis = new BufferedInputStream(fis, 64 * 1024)) {
+ bis.read(buffer, 0, ((int) file.length()));
+ if (file.getAbsolutePath().contains(File.separator + "generated-sources" + File.separator)) {
+ StringBuffer sb = new StringBuffer();
+ List<String> coll = Files.readAllLines(file.toPath());
+ for (String s : coll) {
+ if (s != null && !s.trim().startsWith("/") && !s.trim().startsWith("*")) {
+ sb.append(s);
+ }
+ }
+ return sb.toString();
+ }
+ } catch (IOException ioe) {
+ throw new UncheckedIOException(ioe);
+ }
+ return new String(buffer, 0, ((int) file.length()));
+ }
+
+
+ private static class FileReadTask extends RecursiveTask<Map<String, String>> {
+
+ Map<String, String> store = new HashMap<>();
+ private byte[] buffer = new byte[1024 * 1024];
+ File[] files;
+ String pathPrefix;
+ private final int MAX_FILES = 10;
+
+ FileReadTask(File[] files, String pathPrefix) {
+ this.files = files;
+ this.pathPrefix = pathPrefix;
+ }
+
+ @Override
+ protected Map<String, String> compute() {
+ if (files.length > MAX_FILES) {
+ FileReadTask task1 = new FileReadTask(Arrays.copyOfRange(files, 0, files.length / 2), pathPrefix);
+ FileReadTask task2 =
+ new FileReadTask(Arrays.copyOfRange(files, files.length / 2, files.length), pathPrefix);
+ task1.fork();
+ task2.fork();
+ store.putAll(task1.join());
+ store.putAll(task2.join());
+ } else {
+ for (File toRead : files) {
+ store.put(toRead.getAbsolutePath().substring(pathPrefix.length()), getData(toRead, buffer));
+ }
+ }
+
+ return store;
+ }
+ }
+
+ static Optional<String> getArtifactPathInLocalRepo(String repoPath, MavenProject project, byte[] sourceChecksum)
+ throws MojoFailureException {
+
+ URI uri = null;
+ try {
+ uri = new URI(repoPath + (project.getGroupId().replace('.', '/')) + '/' + project.getArtifactId() + '/'
+ + project.getVersion());
+ } catch (URISyntaxException e) {
+ throw new MojoFailureException(e.getMessage());
+ }
+ File f = new File(uri);
+ File[] list = f.listFiles(t -> t.getName().equals(project.getArtifactId() + "-" + project.getVersion() + "."
+ + project.getPackaging()));
+ if (list != null && list.length > 0) {
+ File checksumFile = new File(list[0].getParentFile(), project.getBuild().getFinalName() + "." + UNICORN);
+ try {
+ if (checksumFile.exists() && Arrays.equals(sourceChecksum, Files.readAllBytes(checksumFile.toPath()))) {
+ return Optional.of(list[0].getAbsolutePath());
+ }
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+ return Optional.empty();
+ }
+
+ static <T> Optional<T> readState(String fileName, Class<T> clazz) {
+ try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
+ ObjectInputStream ois = new ObjectInputStream(is)) {
+ return Optional.of(clazz.cast(ois.readObject()));
+ } catch (Exception ignored) {
+ //ignore. it is taken care.
+ return Optional.empty();
+ }
+ }
+
+}
diff --git a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/BuildState.java b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/BuildState.java
index 888622f..17ff7c9 100644
--- a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/BuildState.java
+++ b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/BuildState.java
@@ -16,7 +16,16 @@
package org.openecomp.sdc.onboarding;
+import static org.openecomp.sdc.onboarding.BuildHelper.readState;
+import static org.openecomp.sdc.onboarding.Constants.ANSI_COLOR_RESET;
+import static org.openecomp.sdc.onboarding.Constants.ANSI_YELLOW;
+import static org.openecomp.sdc.onboarding.Constants.FULL_BUILD_DATA;
+import static org.openecomp.sdc.onboarding.Constants.FULL_RESOURCE_BUILD_DATA;
+import static org.openecomp.sdc.onboarding.Constants.JAR;
+import static org.openecomp.sdc.onboarding.Constants.MODULE_BUILD_DATA;
import static org.openecomp.sdc.onboarding.Constants.RESOURCES_CHANGED;
+import static org.openecomp.sdc.onboarding.Constants.RESOURCE_BUILD_DATA;
+import static org.openecomp.sdc.onboarding.Constants.SKIP_MAIN_SOURCE_COMPILE;
import java.io.File;
import java.io.FileInputStream;
@@ -24,64 +33,65 @@
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.Collection;
import java.util.HashMap;
-import java.util.Iterator;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
-import java.util.stream.Stream;
+import org.apache.maven.artifact.Artifact;
import org.apache.maven.project.MavenProject;
public class BuildState {
- private static Map<String, Long> fullBuildData = new HashMap<>();
- private static Map<String, Long> fullResourceBuildData = new HashMap<>();
+ private static Map<String, Map> compileDataStore = new HashMap<>();
private static Map<String, Object> moduleBuildData = new HashMap<>();
private static Map<String, Object> resourceBuildData = new HashMap<>();
+ private static Map<String, Artifact> artifacts = new HashMap<>();
+ private static Set<String> executeTestsIfDependsOnStore = new HashSet<>();
+ private static Set<String> pmdExecutedInRun = new HashSet<>();
- private static File buildStateFile;
- private static File resourceStateFile;
- private File moduleBuildDataFile;
- private File resourceBuildDataFile;
+ private static File compileStateFile;
private MavenProject project;
- private String buildStateFilePath;
- private String resourceStateFilePath;
+ private String compileStateFilePath;
- private void readFullBuildState() {
- buildStateFile = initialize(this::getBuildStateFile, fullBuildData,
- buildStateFilePath.substring(0, buildStateFilePath.indexOf('/')), project);
+ static {
+ initializeStore();
+ Optional<HashMap> masterStore = readState("compile.dat", HashMap.class);
+ compileDataStore = masterStore.isPresent() ? masterStore.get() : compileDataStore;
}
- private void readResourceBuildState() {
- resourceStateFile = initialize(this::getResourceStateFile, fullResourceBuildData,
- resourceStateFilePath.substring(0, resourceStateFilePath.indexOf('/')), project);
-
- }
-
- private File initialize(BiFunction<String, MavenProject, File> funct, Map store, String moduleCoordinate,
- MavenProject proj) {
- File file = funct.apply(moduleCoordinate, proj);
- file.getParentFile().mkdirs();
- try (FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis);) {
- if (store.isEmpty()) {
- store.putAll(HashMap.class.cast(ois.readObject()));
+ void init() {
+ artifacts.clear();
+ for (Artifact artifact : project.getArtifacts()) {
+ if (artifact.isSnapshot() && JAR.equals(artifact.getType())) {
+ artifacts.put(artifact.getGroupId() + ":" + artifact.getArtifactId(), artifact);
}
- } catch (Exception e) {
- store.clear();
}
- return file;
+ compileStateFile =
+ getCompileStateFile(compileStateFilePath.substring(0, compileStateFilePath.indexOf('/')), project);
}
- private void writeFullBuildState() throws IOException {
- writeState(buildStateFile, fullBuildData);
+ static void initializeStore() {
+ compileDataStore.put(FULL_BUILD_DATA, new HashMap<>());
+ compileDataStore.put(FULL_RESOURCE_BUILD_DATA, new HashMap<>());
+ compileDataStore.put(MODULE_BUILD_DATA, new HashMap<>());
+ compileDataStore.put(RESOURCE_BUILD_DATA, new HashMap<>());
}
- private void writeFullResourceBuildState() throws IOException {
- writeState(resourceStateFile, fullResourceBuildData);
+
+ static void recordPMDRun(String moduleCoordinates) {
+ pmdExecutedInRun.add(moduleCoordinates);
+ }
+
+ static boolean isPMDRun(String moduleCoordintes) {
+ return pmdExecutedInRun.contains(moduleCoordintes);
+ }
+
+ private void writeCompileState() throws IOException {
+ writeState(compileStateFile, compileDataStore);
}
private void writeState(File file, Map store) throws IOException {
@@ -90,20 +100,18 @@
}
}
- private File getBuildStateFile(String moduleCoordinate, MavenProject proj) {
- return getStateFile(moduleCoordinate, proj, buildStateFilePath);
+
+ private File getCompileStateFile(String moduleCoordinate, MavenProject proj) {
+ return getStateFile(moduleCoordinate, proj, compileStateFilePath);
}
- private File getResourceStateFile(String moduleCoordinate, MavenProject proj) {
- return getStateFile(moduleCoordinate, proj, resourceStateFilePath);
- }
private File getStateFile(String moduleCoordinate, MavenProject proj, String filePath) {
return new File(getTopParentProject(moduleCoordinate, proj).getBasedir(),
filePath.substring(filePath.indexOf('/') + 1));
}
- private MavenProject getTopParentProject(String moduleCoordinate, MavenProject proj) {
+ MavenProject getTopParentProject(String moduleCoordinate, MavenProject proj) {
if (getModuleCoordinate(proj).equals(moduleCoordinate) || proj.getParent() == null) {
return proj;
} else {
@@ -116,10 +124,12 @@
}
void addModuleBuildTime(String moduleCoordinates, Long buildTime) {
- Long lastTime = fullBuildData.put(moduleCoordinates, buildTime);
+ Long lastTime = Long.class.cast(compileDataStore.get(FULL_BUILD_DATA).put(moduleCoordinates, buildTime));
try {
if (lastTime == null || !lastTime.equals(buildTime)) {
- writeFullBuildState();
+ if (!project.getProperties().containsKey(SKIP_MAIN_SOURCE_COMPILE)) {
+ writeCompileState();
+ }
}
} catch (IOException ignored) {
// ignored. No need to handle. System will take care.
@@ -127,10 +137,11 @@
}
void addResourceBuildTime(String moduleCoordinates, Long buildTime) {
- if (project.getProperties().containsKey(RESOURCES_CHANGED)) {
- Long lastTime = fullResourceBuildData.put(moduleCoordinates, buildTime);
+ if (project.getProperties().containsKey(RESOURCES_CHANGED)
+ || compileDataStore.get(FULL_RESOURCE_BUILD_DATA).get(moduleCoordinates) == null) {
try {
- writeFullResourceBuildState();
+ compileDataStore.get(FULL_RESOURCE_BUILD_DATA).put(moduleCoordinates, buildTime);
+ writeCompileState();
} catch (IOException ignored) {
// ignored. No need to handle. System will take care.
}
@@ -142,15 +153,29 @@
}
Map<String, Object> readModuleBuildData() {
- return readBuildData(moduleBuildDataFile);
+ return HashMap.class.cast(compileDataStore.get(MODULE_BUILD_DATA).get(getModuleCoordinate(project)));
}
void saveModuleBuildData(String moduleCoordinate) {
- saveBuildData(moduleBuildDataFile, moduleBuildData.get(moduleCoordinate));
+ if (moduleBuildData.get(moduleCoordinate) != null) {
+ compileDataStore.get(MODULE_BUILD_DATA).put(moduleCoordinate, moduleBuildData.get(moduleCoordinate));
+ }
+ saveCompileData();
}
void saveResourceBuildData(String moduleCoordinate) {
- saveBuildData(resourceBuildDataFile, resourceBuildData.get(moduleCoordinate));
+ if (resourceBuildData.get(moduleCoordinate) != null) {
+ compileDataStore.get(RESOURCE_BUILD_DATA).put(moduleCoordinate, resourceBuildData.get(moduleCoordinate));
+ }
+ saveCompileData();
+ }
+
+ void saveCompileData() {
+ saveBuildData(compileStateFile, compileDataStore);
+ }
+
+ void markTestsMandatoryModule(String moduleCoordinates) {
+ executeTestsIfDependsOnStore.add(moduleCoordinates);
}
private void saveBuildData(File file, Object dataToSave) {
@@ -166,41 +191,50 @@
}
Map<String, Object> readResourceBuildData() {
- return readBuildData(resourceBuildDataFile);
+ return HashMap.class.cast(compileDataStore.get(RESOURCE_BUILD_DATA).get(getModuleCoordinate(project)));
}
- private Map<String, Object> readBuildData(File file) {
- try (FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis)) {
- return HashMap.class.cast(ois.readObject());
- } catch (Exception e) {
- return new HashMap<>();
- }
- }
void addResourceBuildData(String moduleCoordinates, Map currentModuleResourceBuildData) {
resourceBuildData.put(moduleCoordinates, currentModuleResourceBuildData);
}
Long getBuildTime(String moduleCoordinates) {
- if (fullBuildData.isEmpty()) {
- readFullBuildState();
- readResourceBuildState();
- }
- Long buildTime = fullBuildData.get(moduleCoordinates);
+ Long buildTime = Long.class.cast(compileDataStore.get(FULL_BUILD_DATA).get(moduleCoordinates));
return buildTime == null ? 0 : buildTime;
}
Long getResourceBuildTime(String moduleCoordinates) {
- Long resourceBuildTime = fullResourceBuildData.get(moduleCoordinates);
+ Long resourceBuildTime = Long.class.cast(compileDataStore.get(FULL_RESOURCE_BUILD_DATA).get(moduleCoordinates));
return resourceBuildTime == null ? 0 : resourceBuildTime;
}
boolean isCompileMust(String moduleCoordinates, Collection<String> dependencies) {
+ for (String d : dependencies) {
+ if (artifacts.containsKey(d) && JAR.equals(artifacts.get(d).getType())) {
+ if (artifacts.get(d).getVersion().equals(project.getVersion()) && getBuildTime(d) == 0) {
+ System.out.println(ANSI_YELLOW + "[WARNING:]" + "You have module[" + d
+ + "] not locally compiled even once, please compile your project once daily from root to have reliable build results."
+ + ANSI_COLOR_RESET);
+ return true;
+ }
+ }
+ }
return isMust(this::getBuildTime, moduleCoordinates, dependencies);
}
- boolean isTestMust(String moduleCoordinates, Collection<String> dependencies) {
- return isMust(this::getResourceBuildTime, moduleCoordinates, dependencies);
+ boolean isTestExecutionMandatory() {
+ for (String d : artifacts.keySet()) {
+ if (executeTestsIfDependsOnStore.contains(d)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean isTestMust(String moduleCoordinates) {
+ return getBuildTime(moduleCoordinates) > getResourceBuildTime(moduleCoordinates) || isMust(
+ this::getResourceBuildTime, moduleCoordinates, artifacts.keySet());
}
private boolean isMust(Function<String, Long> funct, String moduleCoordinates, Collection<String> dependencies) {
@@ -217,22 +251,4 @@
return false;
}
- void markModuleDirty(File file) throws IOException {
- if (file.exists()) {
- Stream<String> lines = Files.lines(file.toPath());
- Iterator<String> itr = lines.iterator();
- while (itr.hasNext()) {
- String line = itr.next();
- Path path = Paths.get(line);
- if (path.toFile().exists()) {
- if (path.toFile().setLastModified(System.currentTimeMillis())) {
- break;
- } else {
- continue;
- }
- }
- }
- }
- }
-
}
diff --git a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/Constants.java b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/Constants.java
index 96abc47..c639c6d 100644
--- a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/Constants.java
+++ b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/Constants.java
@@ -2,14 +2,44 @@
public class Constants {
+ private Constants() {
+ }
+
public static final String JACOCO_SKIP = "jacoco.skip";
public static final String FORK_COUNT = "fork.count";
+ public static final String FORK_MODE = "fork.mode";
+ public static final String SKIP_PMD = "skipPMD";
public static final String JAVA_EXT = ".java";
- public static final String CLASS_EXT = ".class";
+ public static final String ANY_EXT = "*";
public static final String SKIP_TEST_RUN = "skipTestRun";
+ public static final String SKIP_TESTS = "skipTests";
public static final String MAIN = "main";
public static final String TEST = "test";
- public static final String JAVA = "java";
public static final String RESOURCES_CHANGED = "resourcesChanged";
public static final String UNICORN = "unicorn";
+ public static final String ANSI_YELLOW = "\u001B[43m";
+ public static final String ANSI_COLOR_RESET = "\u001B[0m";
+ public static final String SKIP_MAIN_SOURCE_COMPILE = "skipMainSourceCompile";
+ public static final String SKIP_TEST_SOURCE_COMPILE = "skipTestSourceCompile";
+ public static final String MAIN_CHECKSUM = "mainChecksum";
+ public static final String TEST_CHECKSUM = "testChecksum";
+ public static final String RESOURCE_CHECKSUM = "resourceChecksum";
+ public static final String MAIN_SOURCE_CHECKSUM = "mainSourceChecksum";
+ public static final String TEST_SOURCE_CHECKSUM = "testSourceChecksum";
+ public static final String GENERATED_SOURCE_CHECKSUM = "generatedSourceChecksum";
+ public static final String EMPTY_JAR = "emptyJAR";
+ public static final String JAR = "jar";
+ public static final String SHA1 = "sha1";
+ public static final String COLON = ":";
+ public static final String DOT = ".";
+ public static final String FULL_BUILD_DATA = "fullBuildData";
+ public static final String FULL_RESOURCE_BUILD_DATA = "fullResourceBuildData";
+ public static final String MODULE_BUILD_DATA = "moduleBuildData";
+ public static final String RESOURCE_BUILD_DATA = "resourceBuildData";
+ public static final String RESOURCE_ONLY = "resourceOnly";
+ public static final String TEST_RESOURCE_ONLY = "testResourceOnly";
+ public static final String INSTRUMENT_WITH_TEST_ONLY = "instrumentWithTestOnly";
+ public static final String RESOURCE_WITH_TEST_ONLY = "resourceWithTestOnly";
+ public static final String INSTRUMENT_ONLY = "instrumentOnly";
+ public static final String TEST_ONLY = "testOnly";
}
diff --git a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/InitializationHelperMojo.java b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/InitializationHelperMojo.java
index cbf6f69..8b0ff0e 100644
--- a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/InitializationHelperMojo.java
+++ b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/InitializationHelperMojo.java
@@ -17,7 +17,9 @@
package org.openecomp.sdc.onboarding;
import static org.openecomp.sdc.onboarding.Constants.FORK_COUNT;
+import static org.openecomp.sdc.onboarding.Constants.FORK_MODE;
import static org.openecomp.sdc.onboarding.Constants.JACOCO_SKIP;
+import static org.openecomp.sdc.onboarding.Constants.SKIP_PMD;
import static org.openecomp.sdc.onboarding.Constants.UNICORN;
import org.apache.maven.plugin.AbstractMojo;
@@ -29,29 +31,39 @@
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
-@Mojo(name = "init-helper", threadSafe = true, defaultPhase = LifecyclePhase.PRE_CLEAN,
- requiresDependencyResolution = ResolutionScope.NONE)
+@Mojo(name = "init-helper", threadSafe = true, defaultPhase = LifecyclePhase.GENERATE_RESOURCES,
+ requiresDependencyResolution = ResolutionScope.TEST)
public class InitializationHelperMojo extends AbstractMojo {
@Parameter(defaultValue = "${project}", readonly = true)
private MavenProject project;
+ @Parameter
+ private BuildState buildState;
+ @Parameter
+ private String excludePackaging;
public void execute() throws MojoExecutionException, MojoFailureException {
+ if (project.getPackaging().equals(excludePackaging)) {
+ return;
+ }
+ project.getProperties().setProperty("skipGet", "false");
if (System.getProperties().containsKey(JACOCO_SKIP) && Boolean.FALSE.equals(Boolean.valueOf(
System.getProperties().getProperty(JACOCO_SKIP)))) {
project.getProperties().setProperty(FORK_COUNT, "1");
+ project.getProperties().setProperty(FORK_MODE, "once");
} else {
project.getProperties().setProperty(FORK_COUNT, "0");
+ project.getProperties().setProperty(FORK_MODE, "never");
}
- if (System.getProperties().containsKey(UNICORN)) {
- project.getProperties().setProperty("classes", "classes/**/*.class");
- project.getProperties().setProperty("testClasses", "test-classes/**/*.class");
- project.getProperties().setProperty("mavenStatus", "maven-status/**");
- project.getProperties().setProperty("pmd", "pmd/**");
- project.getProperties().setProperty("customGeneratedSources", "generated-sources/custom/**");
+ project.getProperties().setProperty(SKIP_PMD, Boolean.TRUE.toString());
+ if (System.getProperties().containsKey(UNICORN)) {
+ buildState.init();
+ } else {
+ project.getProperties().setProperty("skipMainSourceCompile", "false");
+ project.getProperties().setProperty("skipTestSourceCompile", "false");
}
}
diff --git a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PostCompileHelperMojo.java b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PostCompileHelperMojo.java
index 9ab3735..04e0ca8 100644
--- a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PostCompileHelperMojo.java
+++ b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PostCompileHelperMojo.java
@@ -16,26 +16,18 @@
package org.openecomp.sdc.onboarding;
-import static org.openecomp.sdc.onboarding.Constants.CLASS_EXT;
-import static org.openecomp.sdc.onboarding.Constants.JAVA_EXT;
-import static org.openecomp.sdc.onboarding.Constants.MAIN;
-import static org.openecomp.sdc.onboarding.Constants.RESOURCES_CHANGED;
-import static org.openecomp.sdc.onboarding.Constants.SKIP_TEST_RUN;
+import static org.openecomp.sdc.onboarding.Constants.INSTRUMENT_ONLY;
+import static org.openecomp.sdc.onboarding.Constants.INSTRUMENT_WITH_TEST_ONLY;
+import static org.openecomp.sdc.onboarding.Constants.RESOURCE_ONLY;
+import static org.openecomp.sdc.onboarding.Constants.RESOURCE_WITH_TEST_ONLY;
+import static org.openecomp.sdc.onboarding.Constants.SKIP_MAIN_SOURCE_COMPILE;
+import static org.openecomp.sdc.onboarding.Constants.SKIP_PMD;
+import static org.openecomp.sdc.onboarding.Constants.SKIP_TEST_SOURCE_COMPILE;
+import static org.openecomp.sdc.onboarding.Constants.TEST_ONLY;
+import static org.openecomp.sdc.onboarding.Constants.TEST_RESOURCE_ONLY;
import static org.openecomp.sdc.onboarding.Constants.UNICORN;
import java.io.File;
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
@@ -44,7 +36,7 @@
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
-@Mojo(name = "post-compile-helper", threadSafe = true, defaultPhase = LifecyclePhase.PROCESS_TEST_CLASSES,
+@Mojo(name = "post-compile-helper", threadSafe = true, defaultPhase = LifecyclePhase.TEST_COMPILE,
requiresDependencyResolution = ResolutionScope.TEST)
public class PostCompileHelperMojo extends AbstractMojo {
@@ -53,89 +45,15 @@
@Parameter(defaultValue = "${project.artifact.groupId}:${project.artifact.artifactId}")
private String moduleCoordinates;
@Parameter
- private Long staleThreshold;
- @Parameter
private String excludePackaging;
@Parameter
- private List<String> excludeDependencies;
- @Parameter
- private File mainSourceLocation;
- @Parameter
- private File testSourceLocation;
- @Parameter
- private File mainCompiledLocation;
- @Parameter
- private File testCompiledLocation;
- @Parameter
- private File inputSourceFilesList;
- @Parameter
- private File inputTestFilesList;
- @Parameter
private BuildState buildState;
@Parameter
private File mainResourceLocation;
@Parameter
private File testResourceLocation;
- @Parameter
- private File compiledTestFilesList;
- private File[] getCompiledClasses(File compiledFiles) {
- if (!compiledFiles.exists()) {
- return new File[0];
- }
- File[] list = null;
- try {
- list = Files.walk(Paths.get(compiledFiles.getAbsolutePath()))
- .filter(p -> p.toFile().getAbsolutePath().endsWith(CLASS_EXT)).map(p -> p.toFile())
- .sorted(this::compare).collect(Collectors.toList()).toArray(new File[0]);
- } catch (IOException e) {
- e.printStackTrace();
- }
- if (list == null || list.length == 0) {
- return new File[0];
- }
- return list;
- }
-
- private int compare(File file1, File file2) {
- if (file1.lastModified() > file2.lastModified()) {
- return 1;
- }
- if (file1.lastModified() < file2.lastModified()) {
- return -1;
- }
- return 0;
- }
-
- private File[] getStaleCompiledClasses(File[] compiledClasses, File javaSourceLocation) {
- List<File> staleFiles = new ArrayList<>();
- for (File file : compiledClasses) {
- String classLocation = file.getAbsolutePath().replace(
- project.getBasedir().getAbsolutePath() + File.separator + "target" + File.separator, "");
- String classLocationWithPackageOnly =
- classLocation.substring(classLocation.indexOf(File.separatorChar) + 1);
- String sourceFilePath = javaSourceLocation.getAbsolutePath() + File.separator + classLocationWithPackageOnly
- .replace(CLASS_EXT,
- JAVA_EXT);
- if (Paths.get(sourceFilePath).toFile().exists()) {
- return staleFiles.toArray(new File[0]);
- } else {
- staleFiles.add(file);
- }
- }
- return staleFiles.toArray(new File[0]);
- }
-
- private boolean deleteAll(File[] files) {
- for (File file : files) {
- if (!file.delete()) {
- return false;
- }
- }
- return true;
- }
-
public void execute() throws MojoExecutionException {
if (!System.getProperties().containsKey(UNICORN)) {
return;
@@ -143,93 +61,40 @@
if (project.getPackaging().equals(excludePackaging)) {
return;
}
- String moduleLocation = project.getBasedir().getAbsolutePath();
-
- File[] mainClasses = getCompiledClasses(mainCompiledLocation);
- processStaleClassesIfAny(mainClasses, mainSourceLocation, inputSourceFilesList);
-
- File[] testClasses = getCompiledClasses(testCompiledLocation);
- processStaleClassesIfAny(testClasses, testSourceLocation, inputTestFilesList);
-
- if (mainClasses.length == 0 && testClasses.length == 0) {
- return;
+ if (project.getProperties().containsKey(TEST_ONLY)) {
+ project.getProperties().setProperty(SKIP_MAIN_SOURCE_COMPILE, Boolean.TRUE.toString());
+ project.getProperties().remove(TEST_ONLY);
}
- buildState.addModuleBuildTime(project.getGroupId() + ":" + project.getArtifactId(),
- mainClasses.length > 0 ? mainClasses[mainClasses.length - 1].lastModified() :
- testClasses.length > 0 ? testClasses[testClasses.length - 1].lastModified() : 0);
+ if (project.getProperties().containsKey(INSTRUMENT_ONLY)) {
+ project.getProperties().setProperty(SKIP_MAIN_SOURCE_COMPILE, Boolean.TRUE.toString());
+ project.getProperties().setProperty(SKIP_TEST_SOURCE_COMPILE, Boolean.TRUE.toString());
+ project.getProperties().remove(INSTRUMENT_ONLY);
+ }
+ if (project.getProperties().containsKey(INSTRUMENT_WITH_TEST_ONLY)) {
+ project.getProperties().setProperty(SKIP_MAIN_SOURCE_COMPILE, Boolean.TRUE.toString());
+ project.getProperties().remove(INSTRUMENT_WITH_TEST_ONLY);
+ }
+ if (project.getProperties().containsKey(RESOURCE_WITH_TEST_ONLY)) {
+ project.getProperties().setProperty(SKIP_MAIN_SOURCE_COMPILE, Boolean.TRUE.toString());
+ project.getProperties().remove(RESOURCE_WITH_TEST_ONLY);
+ }
+ if (project.getProperties().containsKey(RESOURCE_ONLY)) {
+ project.getProperties().setProperty(SKIP_MAIN_SOURCE_COMPILE, Boolean.TRUE.toString());
+ project.getProperties().setProperty(SKIP_TEST_SOURCE_COMPILE, Boolean.TRUE.toString());
+ project.getProperties().remove(RESOURCE_ONLY);
+ }
+ if (project.getProperties().containsKey(TEST_RESOURCE_ONLY)) {
+ project.getProperties().setProperty(SKIP_MAIN_SOURCE_COMPILE, Boolean.TRUE.toString());
+ project.getProperties().setProperty(SKIP_TEST_SOURCE_COMPILE, Boolean.TRUE.toString());
+ project.getProperties().remove(TEST_RESOURCE_ONLY);
+ }
+ if (!project.getProperties().containsKey(SKIP_MAIN_SOURCE_COMPILE)) {
+ buildState.addModuleBuildTime(moduleCoordinates, System.currentTimeMillis());
+ project.getProperties().setProperty(SKIP_PMD, Boolean.FALSE.toString());
+ }
+ if (!project.getProperties().containsKey(SKIP_TEST_SOURCE_COMPILE)) {
+ project.getProperties().setProperty(SKIP_PMD, Boolean.FALSE.toString());
+ }
buildState.saveModuleBuildData(moduleCoordinates);
- Map<String, Object> resourceBuildData = getCurrentResourceBuildData();
- Map<String, Object> lastTimeResourceBuildData = buildState.readResourceBuildData();
- boolean resourceDataSame = resourceBuildData.equals(lastTimeResourceBuildData);
- if (!resourceDataSame) {
- buildState.addResourceBuildData(moduleCoordinates, resourceBuildData);
- project.getProperties().setProperty(SKIP_TEST_RUN, Boolean.FALSE.toString());
- }
- boolean resourceMainBuildDataSameWithPreviousBuild =
- lastTimeResourceBuildData.get(MAIN) != null && resourceBuildData.get(MAIN)
- .equals(lastTimeResourceBuildData
- .get(MAIN));
- if (!resourceMainBuildDataSameWithPreviousBuild) {
- project.getProperties().setProperty(RESOURCES_CHANGED, Boolean.TRUE.toString());
- }
- if (!project.getProperties().containsKey(SKIP_TEST_RUN)) {
- if (compiledTestFilesList.exists()
- && compiledTestFilesList.lastModified() > System.currentTimeMillis() - staleThreshold) {
- project.getProperties().setProperty(SKIP_TEST_RUN, Boolean.FALSE.toString());
- }
- }
- }
-
- private void processStaleClassesIfAny(File[] classes, File sourceLocation, File listFile)
- throws MojoExecutionException {
- if (classes.length > 0) {
- List<File> list = new ArrayList<>(Arrays.asList(classes));
- File[] staleClasses = null;
- boolean allStale = listFile.isFile() && listFile.length() == 0;
- if (allStale) {
- staleClasses = classes;
- listFile.delete();
- } else {
- list.removeIf(f -> f.lastModified() > classes[classes.length - 1].lastModified() - staleThreshold);
- staleClasses = getStaleCompiledClasses(list.toArray(new File[0]), sourceLocation);
- }
- if (!deleteAll(staleClasses)) {
- throw new MojoExecutionException(
- "****** Please remove 'target' directory manually under path " + project.getBasedir()
- .getAbsolutePath());
- }
- }
- }
-
- private Map<String, Object> getCurrentResourceBuildData() {
- HashMap<String, Object> resourceBuildStateData = new HashMap<>();
- try {
- resourceBuildStateData.put("main", readResources(mainResourceLocation));
- resourceBuildStateData.put("test", readResources(testResourceLocation));
- resourceBuildStateData.put("dependency", getDependencies());
- } catch (IOException ioException) {
- throw new UncheckedIOException(ioException);
- }
- return resourceBuildStateData;
- }
-
- private Map<String, Long> readResources(File file) throws IOException {
- Map<String, Long> resources = new HashMap<>();
- if (file.exists()) {
- List<Path> list = Files.walk(Paths.get(file.getAbsolutePath())).filter(Files::isRegularFile)
- .collect(Collectors.toList());
- for (Path path : list) {
- resources.put(path.toFile().getAbsolutePath(), path.toFile().lastModified());
- }
- }
- return resources;
- }
-
- private Map<String, String> getDependencies() {
- Map<String, String> dependencies = new HashMap<>();
- for (Artifact d : project.getArtifacts()) {
- dependencies.put(d.getGroupId() + ":" + d.getArtifactId(), d.getVersion());
- }
- return dependencies;
}
}
diff --git a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PostSourceGeneratorMojo.java b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PostSourceGeneratorMojo.java
new file mode 100644
index 0000000..36e5f8a
--- /dev/null
+++ b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PostSourceGeneratorMojo.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on a "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.onboarding;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+
+
+@Mojo(name = "post-source-generator-helper", threadSafe = true, defaultPhase = LifecyclePhase.GENERATE_RESOURCES,
+ requiresDependencyResolution = ResolutionScope.TEST)
+public class PostSourceGeneratorMojo extends PreCompileHelperMojo {
+
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ if (isCodeGenerator()) {
+ super.execute();
+ }
+ }
+
+ // @Override
+ void deleteAllClasses(File file) {
+ if (!file.exists()) {
+ return;
+ }
+ try {
+ List<File> list =
+ Files.walk(Paths.get(file.getAbsolutePath())).filter(Files::isRegularFile).map(p -> p.toFile())
+ .collect(Collectors.toList());
+ for (File f : list) {
+ f.delete();
+ }
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+
+ }
+}
diff --git a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PostTestRunHelperMojo.java b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PostTestRunHelperMojo.java
index 5b326f3..c2816db 100644
--- a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PostTestRunHelperMojo.java
+++ b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PostTestRunHelperMojo.java
@@ -16,6 +16,7 @@
package org.openecomp.sdc.onboarding;
+import static org.openecomp.sdc.onboarding.Constants.SKIP_TESTS;
import static org.openecomp.sdc.onboarding.Constants.SKIP_TEST_RUN;
import static org.openecomp.sdc.onboarding.Constants.UNICORN;
@@ -49,11 +50,13 @@
if (project.getPackaging().equals(excludePackaging)) {
return;
}
- buildState.saveResourceBuildData(moduleCoordinates);
+
if (project.getProperties().containsKey(SKIP_TEST_RUN) && !Boolean.valueOf(
project.getProperties().getProperty(SKIP_TEST_RUN))) {
- if (!System.getProperties().containsKey("skipTests")) {
+ if (!System.getProperties().containsKey(SKIP_TESTS)) {
+ buildState.saveResourceBuildData(moduleCoordinates);
buildState.addResourceBuildTime(moduleCoordinates, System.currentTimeMillis());
+
}
}
diff --git a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PreCompileHelperMojo.java b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PreCompileHelperMojo.java
index faa3167..854ef7f 100644
--- a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PreCompileHelperMojo.java
+++ b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PreCompileHelperMojo.java
@@ -16,127 +16,417 @@
package org.openecomp.sdc.onboarding;
+import static org.openecomp.sdc.onboarding.BuildHelper.getArtifactPathInLocalRepo;
+import static org.openecomp.sdc.onboarding.BuildHelper.getChecksum;
+import static org.openecomp.sdc.onboarding.BuildHelper.getSourceChecksum;
+import static org.openecomp.sdc.onboarding.BuildHelper.readState;
+import static org.openecomp.sdc.onboarding.Constants.ANY_EXT;
+import static org.openecomp.sdc.onboarding.Constants.COLON;
+import static org.openecomp.sdc.onboarding.Constants.DOT;
+import static org.openecomp.sdc.onboarding.Constants.EMPTY_JAR;
+import static org.openecomp.sdc.onboarding.Constants.GENERATED_SOURCE_CHECKSUM;
+import static org.openecomp.sdc.onboarding.Constants.INSTRUMENT_ONLY;
+import static org.openecomp.sdc.onboarding.Constants.INSTRUMENT_WITH_TEST_ONLY;
+import static org.openecomp.sdc.onboarding.Constants.JAR;
+import static org.openecomp.sdc.onboarding.Constants.JAVA_EXT;
import static org.openecomp.sdc.onboarding.Constants.MAIN;
+import static org.openecomp.sdc.onboarding.Constants.MAIN_CHECKSUM;
+import static org.openecomp.sdc.onboarding.Constants.MAIN_SOURCE_CHECKSUM;
+import static org.openecomp.sdc.onboarding.Constants.RESOURCES_CHANGED;
+import static org.openecomp.sdc.onboarding.Constants.RESOURCE_CHECKSUM;
+import static org.openecomp.sdc.onboarding.Constants.RESOURCE_ONLY;
+import static org.openecomp.sdc.onboarding.Constants.RESOURCE_WITH_TEST_ONLY;
+import static org.openecomp.sdc.onboarding.Constants.SHA1;
+import static org.openecomp.sdc.onboarding.Constants.SKIP_MAIN_SOURCE_COMPILE;
+import static org.openecomp.sdc.onboarding.Constants.SKIP_PMD;
import static org.openecomp.sdc.onboarding.Constants.SKIP_TEST_RUN;
+import static org.openecomp.sdc.onboarding.Constants.SKIP_TEST_SOURCE_COMPILE;
import static org.openecomp.sdc.onboarding.Constants.TEST;
+import static org.openecomp.sdc.onboarding.Constants.TEST_CHECKSUM;
+import static org.openecomp.sdc.onboarding.Constants.TEST_ONLY;
+import static org.openecomp.sdc.onboarding.Constants.TEST_RESOURCE_ONLY;
+import static org.openecomp.sdc.onboarding.Constants.TEST_SOURCE_CHECKSUM;
import static org.openecomp.sdc.onboarding.Constants.UNICORN;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
import org.apache.maven.artifact.Artifact;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MavenPluginManager;
import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
-@Mojo(name = "pre-compile-helper", threadSafe = true, defaultPhase = LifecyclePhase.GENERATE_SOURCES,
+
+@Mojo(name = "pre-compile-helper", threadSafe = true, defaultPhase = LifecyclePhase.GENERATE_RESOURCES,
requiresDependencyResolution = ResolutionScope.TEST)
public class PreCompileHelperMojo extends AbstractMojo {
- @Parameter(defaultValue = "${project}", readonly = true)
+ @Parameter(defaultValue = "${project}")
private MavenProject project;
@Parameter(defaultValue = "${project.artifact.groupId}:${project.artifact.artifactId}")
private String moduleCoordinates;
+ @Parameter(defaultValue = "${session}")
+ private MavenSession session;
@Parameter
private String excludePackaging;
@Parameter
private List<String> excludeDependencies;
@Parameter
- private File mainCompiledLocation;
- @Parameter
- private File testCompiledLocation;
- @Parameter
- private File inputSourceFilesList;
- @Parameter
- private File inputTestFilesList;
- @Parameter
private BuildState buildState;
+ @Parameter
+ private File mainSourceLocation;
+ @Parameter
+ private File testSourceLocation;
+ @Parameter
+ private File generatedSourceLocation;
+ @Component
+ private MavenPluginManager pluginManager;
+ @Parameter
+ private File mainResourceLocation;
+ @Parameter
+ private File testResourceLocation;
+ private Map<String, Object> resourceBuildData;
- public void execute() throws MojoExecutionException {
- if (!System.getProperties().containsKey(UNICORN)) {
- return;
- }
+ private static Map<String, String> checksumMap;
+
+ static {
+ checksumMap = readCurrentPMDState("pmd.dat");
+ }
+
+ public void execute() throws MojoExecutionException, MojoFailureException {
+
+ long mainChecksum = 0, testChecksum = 0, resourceChecksum = 0;
+ Optional<String> artifactPath;
+
if (project.getPackaging().equals(excludePackaging)) {
return;
}
+ init();
+ project.getProperties()
+ .setProperty(MAIN_CHECKSUM, String.valueOf(mainChecksum = getChecksum(mainSourceLocation, JAVA_EXT)));
+ project.getProperties()
+ .setProperty(TEST_CHECKSUM, String.valueOf(testChecksum = getChecksum(testSourceLocation, JAVA_EXT)));
+ String checksum = mainChecksum + COLON + testChecksum;
+ if (!checksum.equals(checksumMap.get(moduleCoordinates)) || isPMDMandatory(project.getArtifacts())) {
+ project.getProperties().setProperty(SKIP_PMD, Boolean.FALSE.toString());
+ buildState.recordPMDRun(moduleCoordinates);
+ }
+ project.getProperties().setProperty(EMPTY_JAR, "");
+ if (!System.getProperties().containsKey(UNICORN)) {
+ return;
+ }
+
+ project.getProperties().setProperty(RESOURCE_CHECKSUM,
+ String.valueOf(resourceChecksum = getChecksum(mainResourceLocation, ANY_EXT)));
+ byte[] sourceChecksum = calculateChecksum(mainChecksum, resourceChecksum).getBytes();
+ boolean instrumented = isCurrentModuleInstrumented();
+ artifactPath = getArtifactPathInLocalRepo(session.getLocalRepository().getUrl(), project, sourceChecksum);
+
+ boolean isFirstBuild = buildState.getBuildTime(moduleCoordinates) == 0 || !artifactPath.isPresent();
Map<String, Object> moduleBuildData = getCurrentModuleBuildData();
Map<String, Object> lastTimeModuleBuildData = buildState.readModuleBuildData();
+ resourceBuildData = getCurrentResourceBuildData();
+ Map<String, Object> lastTimeResourceBuildData = buildState.readResourceBuildData();
- boolean buildDataSameWithPreviousBuild = lastTimeModuleBuildData.get(MAIN) != null && moduleBuildData.get(MAIN)
- .equals(lastTimeModuleBuildData
- .get(MAIN));
- boolean isFirstBuild = buildState.getBuildTime(moduleCoordinates) == 0;
+ boolean buildDataSameWithPreviousBuild =
+ isBuildDataSameWithPreviousBuild(lastTimeModuleBuildData, moduleBuildData);
+ boolean resourceMainBuildDataSameWithPreviousBuild =
+ isResourceMainBuildDataSameWithPreviousBuild(lastTimeResourceBuildData);
- if (isCompileNeeded(HashMap.class.cast(moduleBuildData.get(MAIN)).keySet(), isFirstBuild,
- buildDataSameWithPreviousBuild)) {
- try {
- buildState.markModuleDirty(inputSourceFilesList);
- buildState.markModuleDirty(inputTestFilesList);
- project.getProperties().setProperty(SKIP_TEST_RUN, "false");
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
- }
+ boolean mainToBeCompiled = isCompileNeeded(HashMap.class.cast(moduleBuildData.get(MAIN)).keySet(), isFirstBuild,
+ buildDataSameWithPreviousBuild);
- if (!moduleBuildData.get(TEST).equals(lastTimeModuleBuildData.get(TEST))) {
- try {
- buildState.markModuleDirty(inputTestFilesList);
- project.getProperties().setProperty(SKIP_TEST_RUN, Boolean.FALSE.toString());
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
- }
+ boolean resourceDataSame = resourceBuildData.equals(lastTimeResourceBuildData);
- if (!moduleBuildData.equals(lastTimeModuleBuildData)) {
+ boolean testToBeCompiled =
+ lastTimeModuleBuildData == null || !moduleBuildData.get(TEST).equals(lastTimeModuleBuildData.get(TEST));
+ setMainBuildAttribute(mainToBeCompiled, testToBeCompiled);
+ generateSignature(sourceChecksum);
+ setTestBuild(resourceDataSame, resourceMainBuildDataSameWithPreviousBuild, testToBeCompiled, mainToBeCompiled);
+ setInstrumentedBuild(testToBeCompiled, mainToBeCompiled, instrumented);
+
+ if (!moduleBuildData.equals(lastTimeModuleBuildData) || isFirstBuild) {
buildState.addModuleBuildData(moduleCoordinates, moduleBuildData);
}
+ setResourceBuild(resourceMainBuildDataSameWithPreviousBuild, mainToBeCompiled, testToBeCompiled);
+ setJarFlags(mainToBeCompiled, instrumented, !resourceMainBuildDataSameWithPreviousBuild);
+ setInstallFlags(mainToBeCompiled, instrumented, project.getPackaging(),
+ !resourceMainBuildDataSameWithPreviousBuild);
- if (inputSourceFilesList.isFile() && inputSourceFilesList.length() == 0) {
- if (!inputSourceFilesList.delete()) {
- throw new MojoExecutionException(
- "****** Please remove 'target' directory manually under path " + project.getBasedir()
- .getAbsolutePath());
- }
+ if (!mainToBeCompiled && !instrumented && JAR.equals(project.getPackaging())
+ && resourceMainBuildDataSameWithPreviousBuild) {
+ project.getProperties().setProperty("artifactPathToCopy", artifactPath.orElse(null));
}
- if (inputTestFilesList.isFile() && inputTestFilesList.length() == 0) {
- if (!inputTestFilesList.delete()) {
- throw new MojoExecutionException(
- "****** Please remove 'target' directory manually under path " + project.getBasedir()
- .getAbsolutePath());
+ }
+
+ private void generateSignature(byte[] sourceChecksum) {
+ try {
+ Files.write(Paths.get(project.getBuild().getDirectory(), project.getBuild().getFinalName() + DOT + UNICORN),
+ sourceChecksum, StandardOpenOption.CREATE);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ private String calculateChecksum(long mainChecksum, long resourceChecksum) throws MojoExecutionException {
+ try {
+ return getSourceChecksum(mainChecksum + COLON + resourceChecksum, SHA1);
+ } catch (NoSuchAlgorithmException e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+ }
+
+ private boolean isResourceMainBuildDataSameWithPreviousBuild(Map<String, Object> lastTimeResourceBuildData) {
+ return lastTimeResourceBuildData != null && (lastTimeResourceBuildData.get(MAIN) != null && resourceBuildData
+ .get(MAIN)
+ .equals(lastTimeResourceBuildData
+ .get(MAIN)));
+ }
+
+ private boolean isBuildDataSameWithPreviousBuild(Map<String, Object> lastTimeModuleBuildData,
+ Map<String, Object> moduleBuildData) {
+ return lastTimeModuleBuildData != null && (lastTimeModuleBuildData.get(MAIN) != null && moduleBuildData
+ .get(MAIN)
+ .equals(lastTimeModuleBuildData
+ .get(MAIN)));
+ }
+
+ private void setInstrumentedBuild(boolean testToBeCompiled, boolean mainToBeCompiled, boolean instrumented) {
+ if (!testToBeCompiled && !mainToBeCompiled && instrumented) {
+ project.getProperties().setProperty(INSTRUMENT_ONLY, Boolean.TRUE.toString());
+ project.getProperties().remove(SKIP_MAIN_SOURCE_COMPILE);
+ project.getProperties().remove(SKIP_TEST_SOURCE_COMPILE);
+ }
+ if (testToBeCompiled && !mainToBeCompiled && instrumented) {
+ project.getProperties().setProperty(INSTRUMENT_WITH_TEST_ONLY, Boolean.TRUE.toString());
+ project.getProperties().remove(SKIP_MAIN_SOURCE_COMPILE);
+ }
+ if (instrumented) {
+ buildState.markTestsMandatoryModule(moduleCoordinates);
+ project.getProperties().setProperty(SKIP_TEST_RUN, Boolean.FALSE.toString());
+ }
+ }
+
+ private void setResourceBuild(boolean resourceMainBuildDataSameWithPreviousBuild, boolean mainToBeCompiled,
+ boolean testToBeCompiled) {
+ if (resourceMainBuildDataSameWithPreviousBuild) {
+ project.getProperties().setProperty("skipResourceCollection", Boolean.TRUE.toString());
+ } else {
+ project.getProperties().setProperty(RESOURCES_CHANGED, Boolean.TRUE.toString());
+ }
+ if (!resourceMainBuildDataSameWithPreviousBuild && !mainToBeCompiled) {
+ project.getProperties().remove(SKIP_MAIN_SOURCE_COMPILE);
+ if (!testToBeCompiled) {
+ project.getProperties().remove(SKIP_TEST_SOURCE_COMPILE);
+ project.getProperties().setProperty(RESOURCE_ONLY, Boolean.TRUE.toString());
+ } else {
+ project.getProperties().setProperty(RESOURCE_WITH_TEST_ONLY, Boolean.TRUE.toString());
}
}
}
+ private void setTestBuild(boolean resourceDataSame, boolean resourceMainBuildDataSameWithPreviousBuild,
+ boolean testToBeCompiled, boolean mainToBeCompiled) {
+ if (!resourceDataSame) {
+ buildState.addResourceBuildData(moduleCoordinates, resourceBuildData);
+ project.getProperties().setProperty(SKIP_TEST_RUN, Boolean.FALSE.toString());
+ if (resourceMainBuildDataSameWithPreviousBuild && !testToBeCompiled && !mainToBeCompiled) {
+ project.getProperties().setProperty(TEST_RESOURCE_ONLY, Boolean.TRUE.toString());
+ project.getProperties().remove(SKIP_MAIN_SOURCE_COMPILE);
+ project.getProperties().remove(SKIP_TEST_SOURCE_COMPILE);
+ }
+ }
+ }
+
+ private void setMainBuildAttribute(boolean mainToBeCompiled, boolean testToBeCompiled) {
+ if (!mainToBeCompiled) {
+ project.getProperties().setProperty(SKIP_MAIN_SOURCE_COMPILE, Boolean.TRUE.toString());
+ }
+ if (testToBeCompiled && !mainToBeCompiled) {
+ project.getProperties().setProperty(TEST_ONLY, Boolean.TRUE.toString());
+ project.getProperties().remove(SKIP_MAIN_SOURCE_COMPILE);
+ }
+
+ if (mainToBeCompiled || testToBeCompiled) {
+ project.getProperties().setProperty(SKIP_TEST_RUN, Boolean.FALSE.toString());
+ } else {
+ project.getProperties().setProperty(SKIP_TEST_SOURCE_COMPILE, Boolean.TRUE.toString());
+ }
+ }
+
+ private void setJarFlags(boolean compile, boolean instrumented, boolean resourceChanged) {
+ if (compile || instrumented || resourceChanged) {
+ project.getProperties().setProperty(EMPTY_JAR, "");
+ } else {
+ project.getProperties().setProperty(EMPTY_JAR, "**/*");
+ project.getProperties().setProperty("mvnDsc", "false");
+ }
+ }
+
+ private void setInstallFlags(boolean compile, boolean instrumented, String packaging, boolean resourceChanged) {
+ if (!compile && !instrumented && !resourceChanged && JAR.equals(packaging)) {
+ project.getProperties().setProperty("skipInstall", Boolean.TRUE.toString());
+ }
+ }
+
private boolean isCompileNeeded(Collection<String> dependencyCoordinates, boolean isFirstBuild,
- boolean buildDataSame) {
+ boolean buildDataSame) throws MojoFailureException {
return isFirstBuild || !buildDataSame || buildState.isCompileMust(moduleCoordinates, dependencyCoordinates);
}
+ private boolean isCurrentModuleInstrumented() {
+ try {
+ return scanModuleFor(LifecyclePhase.PROCESS_CLASSES.id(), LifecyclePhase.PROCESS_TEST_CLASSES.id(),
+ LifecyclePhase.COMPILE.id(), LifecyclePhase.TEST_COMPILE.id());
+ } catch (Exception e) {
+ return true;
+ }
+ }
+
+ boolean isCodeGenerator() {
+ try {
+ return scanModuleFor(LifecyclePhase.GENERATE_RESOURCES.id(), LifecyclePhase.GENERATE_SOURCES.id(),
+ LifecyclePhase.GENERATE_TEST_RESOURCES.id(), LifecyclePhase.GENERATE_TEST_SOURCES.id());
+ } catch (Exception e) {
+ return true;
+ }
+ }
+
private Map<String, Object> getCurrentModuleBuildData() {
Map<String, Object> moduleBuildData = new HashMap<>();
moduleBuildData.put(MAIN, new HashMap<String, String>());
moduleBuildData.put(TEST, new HashMap<String, String>());
+ HashMap.class.cast(moduleBuildData.get(MAIN))
+ .put(MAIN_SOURCE_CHECKSUM, project.getProperties().getProperty(MAIN_CHECKSUM));
+ HashMap.class.cast(moduleBuildData.get(TEST))
+ .put(TEST_SOURCE_CHECKSUM, project.getProperties().getProperty(TEST_CHECKSUM));
+ if (isCodeGenerator()) {
+ HashMap.class.cast(moduleBuildData.get(MAIN))
+ .put(GENERATED_SOURCE_CHECKSUM, getChecksum(generatedSourceLocation, JAVA_EXT));
+ }
if (project.getArtifacts() == null || project.getArtifacts().isEmpty()) {
return moduleBuildData;
}
for (Artifact dependency : project.getArtifacts()) {
+ String fileNme = dependency.getFile().getName();
if (excludeDependencies.contains(dependency.getScope())) {
HashMap.class.cast(moduleBuildData.get(TEST))
- .put(dependency.getGroupId() + ":" + dependency.getArtifactId(), dependency.getVersion());
+ .put(dependency.getGroupId() + COLON + dependency.getArtifactId(),
+ fileNme.endsWith(dependency.getVersion() + DOT + JAR) ? dependency.getVersion() :
+ fileNme);
continue;
}
HashMap.class.cast(moduleBuildData.get(MAIN))
- .put(dependency.getGroupId() + ":" + dependency.getArtifactId(), dependency.getVersion());
+ .put(dependency.getGroupId() + COLON + dependency.getArtifactId(),
+ fileNme.endsWith(dependency.getVersion() + DOT + JAR) ? dependency.getVersion() :
+ fileNme);
}
return moduleBuildData;
}
+
+ private static Map<String, String> readCurrentPMDState(String fileName) {
+ Optional<HashMap> val = readState(fileName, HashMap.class);
+ return val.orElseGet(HashMap::new);
+ }
+
+ private boolean isPMDMandatory(Set<Artifact> dependencies) {
+ for (Artifact artifact : dependencies) {
+ if (buildState.isPMDRun(artifact.getGroupId() + COLON + artifact.getArtifactId())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean scanModuleFor(String... types)
+ throws InvalidPluginDescriptorException, PluginResolutionException, MojoNotFoundException,
+ PluginDescriptorParsingException {
+ for (Plugin plugin : project.getBuildPlugins()) {
+ if (!(plugin.getGroupId().equals("org.apache.maven.plugins") && plugin.getArtifactId().startsWith("maven"))
+ && !plugin.getGroupId().startsWith("org.openecomp.sdc")) {
+ if (scanPlugin(plugin, types)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean scanPlugin(Plugin plugin, String... types)
+ throws InvalidPluginDescriptorException, PluginDescriptorParsingException, MojoNotFoundException,
+ PluginResolutionException {
+ for (PluginExecution pluginExecution : plugin.getExecutions()) {
+ if (pluginExecution.getPhase() != null) {
+ if (Arrays.asList(types).contains(pluginExecution.getPhase())) {
+ return true;
+ }
+ }
+ for (String goal : pluginExecution.getGoals()) {
+ MojoDescriptor md = pluginManager.getMojoDescriptor(plugin, goal, project.getRemotePluginRepositories(),
+ session.getRepositorySession());
+ if (Arrays.asList(types).contains(md.getPhase())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private Map<String, Object> getCurrentResourceBuildData() {
+ HashMap<String, Object> resourceBuildStateData = new HashMap<>();
+ resourceBuildStateData.put(MAIN, project.getProperties().getProperty(RESOURCE_CHECKSUM));
+ resourceBuildStateData.put(TEST, getChecksum(testResourceLocation, ANY_EXT));
+ resourceBuildStateData.put("dependency", getDependencies().hashCode());
+ return resourceBuildStateData;
+ }
+
+ private Map<String, String> getDependencies() {
+ Map<String, String> dependencies = new HashMap<>();
+ for (Artifact d : project.getArtifacts()) {
+ dependencies.put(d.getGroupId() + COLON + d.getArtifactId(), d.getVersion());
+ }
+ return dependencies;
+ }
+
+ private void init() {
+ if (mainSourceLocation == null) {
+ mainSourceLocation = Paths.get(project.getBuild().getSourceDirectory()).toFile();
+ }
+ if (testSourceLocation == null) {
+ testSourceLocation = Paths.get(project.getBuild().getTestSourceDirectory()).toFile();
+ }
+ if (mainResourceLocation == null) {
+ mainResourceLocation = Paths.get(project.getBuild().getResources().get(0).getDirectory()).toFile();
+ }
+ if (testResourceLocation == null) {
+ testResourceLocation = Paths.get(project.getBuild().getTestResources().get(0).getDirectory()).toFile();
+ }
+ }
}
diff --git a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PreTestCompileHelperMojo.java b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PreTestCompileHelperMojo.java
index e711cb0..a11d796 100644
--- a/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PreTestCompileHelperMojo.java
+++ b/openecomp-be/tools/compile-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/PreTestCompileHelperMojo.java
@@ -17,14 +17,13 @@
package org.openecomp.sdc.onboarding;
import static org.openecomp.sdc.onboarding.Constants.JACOCO_SKIP;
-import static org.openecomp.sdc.onboarding.Constants.SKIP_TEST_RUN;
import static org.openecomp.sdc.onboarding.Constants.RESOURCES_CHANGED;
+import static org.openecomp.sdc.onboarding.Constants.SKIP_TESTS;
+import static org.openecomp.sdc.onboarding.Constants.SKIP_TEST_RUN;
import static org.openecomp.sdc.onboarding.Constants.UNICORN;
-import java.io.File;
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.util.stream.Collectors;
+import java.util.List;
+import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
@@ -33,23 +32,20 @@
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
-@Mojo(name = "pre-test-compile-helper", threadSafe = true, defaultPhase = LifecyclePhase.GENERATE_TEST_RESOURCES,
+@Mojo(name = "pre-test-compile-helper", threadSafe = true, defaultPhase = LifecyclePhase.PROCESS_TEST_CLASSES,
requiresDependencyResolution = ResolutionScope.TEST)
public class PreTestCompileHelperMojo extends AbstractMojo {
@Parameter
- private File compiledFilesList;
- @Parameter
- private Long staleThreshold;
- @Parameter
- private File inputTestFilesList;
- @Parameter
private BuildState buildState;
@Parameter(defaultValue = "${project}", readonly = true)
private MavenProject project;
@Parameter(defaultValue = "${project.artifact.groupId}:${project.artifact.artifactId}")
private String moduleCoordinates;
+ @Parameter(defaultValue = "${project.buildPlugins}", readonly = true)
+ private List<Plugin> plugins;
@Parameter
private String excludePackaging;
@@ -61,25 +57,17 @@
if (project.getPackaging().equals(excludePackaging)) {
return;
}
- if (compiledFilesList.exists()
- && compiledFilesList.lastModified() > System.currentTimeMillis() - staleThreshold) {
- try {
- buildState.markModuleDirty(inputTestFilesList);
- project.getProperties().setProperty(SKIP_TEST_RUN, Boolean.FALSE.toString());
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
+ if (buildState.isTestExecutionMandatory()) {
+ project.getProperties().setProperty(SKIP_TEST_RUN, Boolean.FALSE.toString());
}
- boolean isTestMust = buildState.isTestMust(moduleCoordinates,
- project.getDependencies().stream().map(d -> d.getGroupId() + ":" + d.getArtifactId())
- .collect(Collectors.toList()));
+ boolean isTestMust = buildState.isTestMust(moduleCoordinates);
if (isTestMust) {
project.getProperties().setProperty(RESOURCES_CHANGED, Boolean.TRUE.toString());
if (!project.getProperties().containsKey(SKIP_TEST_RUN)) {
project.getProperties().setProperty(SKIP_TEST_RUN, Boolean.FALSE.toString());
}
}
- if (!project.getProperties().containsKey(SKIP_TEST_RUN)) {
+ if (!project.getProperties().containsKey(SKIP_TEST_RUN) || isTestSkippedExplicitly()) {
project.getProperties().setProperty(SKIP_TEST_RUN, Boolean.TRUE.toString());
}
if (System.getProperties().containsKey(JACOCO_SKIP) && Boolean.FALSE.equals(Boolean.valueOf(
@@ -87,4 +75,17 @@
project.getProperties().setProperty(SKIP_TEST_RUN, Boolean.FALSE.toString());
}
}
+
+
+ private boolean isTestSkippedExplicitly() {
+ for (Plugin p : plugins) {
+ if ("org.apache.maven.plugins:maven-surefire-plugin".equals(p.getKey())) {
+ Xpp3Dom dom = Xpp3Dom.class.cast(p.getConfiguration());
+ if (dom.getChild(SKIP_TESTS) != null) {
+ return Boolean.TRUE.equals(Boolean.valueOf(dom.getValue()));
+ }
+ }
+ }
+ return false;
+ }
}
diff --git a/openecomp-be/tools/pmd-helper-plugin/pom.xml b/openecomp-be/tools/pmd-helper-plugin/pom.xml
new file mode 100644
index 0000000..75ab1f8
--- /dev/null
+++ b/openecomp-be/tools/pmd-helper-plugin/pom.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.openecomp.sdc.onboarding</groupId>
+ <artifactId>pmd-helper-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+
+ <parent>
+ <artifactId>sdc-onboarding</artifactId>
+ <groupId>org.openecomp.sdc</groupId>
+ <version>1.2.0-SNAPSHOT</version>
+ <relativePath>../../../onboarding</relativePath>
+ </parent>
+ <properties>
+ <skipPMD>true</skipPMD>
+ <classes>classes/**/*.class</classes>
+ <mavenStatus>maven-status/**</mavenStatus>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>${maven-core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.plugin-tools</groupId>
+ <artifactId>maven-plugin-annotations</artifactId>
+ <version>${maven-plugin-annotations.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>${maven-plugin-plugin.version}</version>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
diff --git a/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/InitializationHelperMojo.java b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/InitializationHelperMojo.java
new file mode 100644
index 0000000..4102a1b
--- /dev/null
+++ b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/InitializationHelperMojo.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright © 2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on a "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.onboarding.pmd;
+
+import static org.openecomp.sdc.onboarding.pmd.PMDHelperUtils.getStateFile;
+import static org.openecomp.sdc.onboarding.pmd.PMDHelperUtils.readCurrentPMDState;
+import static org.openecomp.sdc.onboarding.pmd.PMDHelperUtils.readInputStream;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.List;
+import java.util.Map;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.project.MavenProject;
+
+@Mojo(name = "init-pmd-helper", threadSafe = true, defaultPhase = LifecyclePhase.PREPARE_PACKAGE,
+ requiresDependencyResolution = ResolutionScope.NONE)
+public class InitializationHelperMojo extends AbstractMojo {
+
+ private static final String SKIP_PMD = "skipPMD";
+
+ @Parameter(defaultValue = "${project}", readonly = true)
+ private MavenProject project;
+ @Parameter(defaultValue = "${project.artifact.groupId}:${project.artifact.artifactId}")
+ private String moduleCoordinates;
+ @Parameter
+ private File pmdTargetLocation;
+ @Parameter
+ private File pmdReportFile;
+ @Parameter
+ private String persistingModuleCoordinates;
+ @Parameter
+ private File pmdStateFile;
+ @Parameter
+ private String pmdCurrentStateFilePath;
+ @Parameter
+ private String excludePackaging;
+
+ static {
+ PMDState.setHistoricState(readCurrentPMDState("pmd.dat"));
+ }
+
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ if (project.getPackaging().equals(excludePackaging)) {
+ return;
+ }
+ if (moduleCoordinates.equals(persistingModuleCoordinates)) {
+ pmdStateFile.getParentFile().mkdirs();
+ try (OutputStream os = new FileOutputStream(pmdStateFile);
+ ObjectOutputStream oos = new ObjectOutputStream(os)) {
+ File f = getStateFile(pmdCurrentStateFilePath.substring(0, pmdCurrentStateFilePath.indexOf('/')),
+ project, pmdCurrentStateFilePath);
+ Map<String, List<Violation>> data = readCurrentPMDState(f);
+ if (PMDState.getHistoricState() != null) {
+ PMDState.getHistoricState().putAll(data);
+ oos.writeObject(PMDState.getHistoricState());
+ } else {
+ oos.writeObject(data);
+ }
+ if (Paths.get(f.getParentFile().getAbsolutePath(), "compileState.dat").toFile().exists()) {
+ Files.copy(Paths.get(f.getParentFile().getAbsolutePath(), "compileState.dat"),
+ Paths.get(pmdStateFile.getParentFile().getAbsolutePath(), "compile.dat"),
+ StandardCopyOption.REPLACE_EXISTING);
+ }
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return;
+ }
+ if (project.getProperties().containsKey(SKIP_PMD) && Boolean.TRUE.equals(Boolean.valueOf(
+ project.getProperties().getProperty(SKIP_PMD)))) {
+ return;
+ }
+ pmdTargetLocation.getParentFile().mkdirs();
+ try (InputStream is = this.getClass().getResourceAsStream("/pmd-empty.xml");
+ OutputStream os = new FileOutputStream(pmdTargetLocation)) {
+ String text = readInputStream(is);
+ os.write(text.getBytes());
+ } catch (IOException ioe) {
+ throw new UncheckedIOException(ioe);
+ }
+ }
+
+}
diff --git a/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/PMDHelperUtils.java b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/PMDHelperUtils.java
new file mode 100644
index 0000000..38dde12
--- /dev/null
+++ b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/PMDHelperUtils.java
@@ -0,0 +1,242 @@
+package org.openecomp.sdc.onboarding.pmd;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.StandardOpenOption;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.project.MavenProject;
+
+public class PMDHelperUtils {
+
+ private PMDHelperUtils() {
+ // default constructor. donot remove.
+ }
+
+ private static Map<String, String> pmdLink = new HashMap<>();
+
+ static {
+ pmdLink.put("one", "errorprone");
+ pmdLink.put("ign", "design");
+ pmdLink.put("ing", "multithreading");
+ pmdLink.put("nce", "performance");
+ pmdLink.put("ity", "security");
+ pmdLink.put("yle", "codestyle");
+ pmdLink.put("ces", "bestpractices");
+ }
+
+ static String readInputStream(InputStream is) {
+ try (Scanner s = new Scanner(is).useDelimiter("\\A")) {
+ return s.hasNext() ? s.next() : "";
+ }
+ }
+
+ static File getStateFile(String moduleCoordinate, MavenProject proj, String filePath) {
+ return new File(getTopParentProject(moduleCoordinate, proj).getBasedir(),
+ filePath.substring(filePath.indexOf('/') + 1));
+ }
+
+ private static MavenProject getTopParentProject(String moduleCoordinate, MavenProject proj) {
+ if (getModuleCoordinate(proj).equals(moduleCoordinate) || proj.getParent() == null) {
+ return proj;
+ } else {
+ return getTopParentProject(moduleCoordinate, proj.getParent());
+ }
+ }
+
+ private static String getModuleCoordinate(MavenProject project) {
+ return project.getGroupId() + ":" + project.getArtifactId();
+ }
+
+ private static <T> T readState(String fileName, Class<T> clazz) {
+ try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
+ ObjectInputStream ois = new ObjectInputStream(is)) {
+ return clazz.cast(ois.readObject());
+ } catch (Exception ioe) {
+ return null;
+ }
+ }
+
+ static <T> T readState(File file, Class<T> clazz) {
+ try (InputStream is = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(is)) {
+ return clazz.cast(ois.readObject());
+ } catch (Exception ioe) {
+ return null;
+ }
+ }
+
+ static boolean evaluateCodeQuality(Map<String, List<Violation>> stats, Map<String, List<Violation>> current,
+ File file, Log logger) {
+ boolean qualityCheckPassed = true;
+ Map<String, String> table = new HashMap<>();
+ Set<String> classes = current.keySet();
+ int counter = 0;
+ for (String clazz : classes) {
+ List<Violation> orgViolation = stats.get(clazz) == null ? new ArrayList<>() : stats.get(clazz);
+ List<Violation> currViolation = current.get(clazz) == null ? new ArrayList<>() : current.get(clazz);
+ if (diffViolation(orgViolation, currViolation) > 0) {
+ Map<String, Integer> lDetails = diffCategory(orgViolation, currViolation);
+ for (String cat : lDetails.keySet()) {
+ String lineNo = getLineNumbers(currViolation, cat);
+ table.put(++counter + clazz, cat + ":" + lDetails.get(cat) + ":" + lineNo);
+ }
+ }
+ }
+ if (!table.isEmpty()) {
+ qualityCheckPassed = false;
+ try {
+ Files.write(file.toPath(),
+ new Table(getTableHeaders(true), getContents(table, true)).drawTable().getBytes(),
+ StandardOpenOption.CREATE);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ logger.error(new Table(getTableHeaders(false), getContents(table, false)).drawTable());
+ }
+ return qualityCheckPassed;
+ }
+
+ private static ArrayList<String> getTableHeaders(boolean addLink) {
+ ArrayList<String> list = new ArrayList<>();
+ list.add("Class Name");
+ list.add("Rule Category");
+ list.add("Rule Name");
+ list.add("Fix");
+ list.add("Source Line No");
+ if (addLink) {
+ list.add("Help Link");
+ }
+ return list;
+ }
+
+ private static ArrayList<ArrayList<String>> getContents(Map<String, String> data, boolean addLink) {
+ ArrayList<ArrayList<String>> list = new ArrayList<>();
+ Pattern p = Pattern.compile("(.*):(.*):(.*):(.*)");
+ for (String s : data.keySet()) {
+ ArrayList<String> l = new ArrayList<>();
+ l.add(s.substring(s.indexOf("::") + 2));
+ Matcher m = p.matcher(data.get(s));
+ if (m.find()) {
+ l.add(m.group(1));
+ l.add(m.group(2));
+ l.add(m.group(3) + " at least");
+ l.add(m.group(4));
+ if (addLink) {
+ l.add("http://pmd.sourceforge.net/snapshot/pmd_rules_java_" + getLinkCategory(m.group(1)) + ".html#"
+ + m.group(2).toLowerCase());
+ }
+ }
+ list.add(l);
+ }
+ return list;
+ }
+
+ private static String getLinkCategory(String cat) {
+ for (String category : pmdLink.keySet()) {
+ if (cat.contains(category)) {
+ return pmdLink.get(category);
+ }
+ }
+ return "ERROR";
+ }
+
+ private static int diffViolation(List<Violation> org, List<Violation> curr) {
+ int diff = 0;
+ if (org == null || org.isEmpty()) {
+ if (curr != null && !curr.isEmpty()) {
+ diff = curr.size();
+ }
+ } else {
+ if (curr != null && !curr.isEmpty()) {
+ diff = curr.size() - org.size();
+ }
+ }
+ return diff;
+ }
+
+ private static Map<String, Integer> diffCategory(List<Violation> org, List<Violation> curr) {
+ Map<String, AtomicInteger> currData = new HashMap<>();
+ Map<String, AtomicInteger> orgData = new HashMap<>();
+ countViolations(curr, currData);
+ countViolations(org, orgData);
+ Map<String, Integer> val = new HashMap<>();
+ for (String cat : currData.keySet()) {
+ if (orgData.get(cat) == null) {
+ val.put(cat, currData.get(cat).intValue());
+ } else if (currData.get(cat).intValue() > orgData.get(cat).intValue()) {
+ val.put(cat, currData.get(cat).intValue() - orgData.get(cat).intValue());
+ }
+ }
+ return val;
+ }
+
+ private static void countViolations(List<Violation> violations, Map<String, AtomicInteger> store){
+ for (Violation v : violations) {
+ if (store.get(v.getCategory() + ":" + v.getRule()) == null) {
+ store.put(v.getCategory() + ":" + v.getRule(), new AtomicInteger(1));
+ } else {
+ store.get(v.getCategory() + ":" + v.getRule()).incrementAndGet();
+ }
+ }
+ }
+
+ private static void processOriginalViolations(List<Violation> org){
+
+ }
+ private static String getLineNumbers(List<Violation> vList, String category) {
+ String val = "";
+ boolean firstOver = false;
+ for (Violation v : vList) {
+ if (category.equals(v.getCategory() + ":" + v.getRule())) {
+ if (firstOver) {
+ val += ",";
+ }
+ val += v.getLine();
+ firstOver = true;
+ }
+ }
+ return val;
+ }
+
+ static Map<String, List<Violation>> readCurrentPMDState(String fileName) {
+ Map<String, List<Violation>> val = readState(fileName, HashMap.class);
+ return val == null ? new HashMap<>() : val;
+ }
+
+ static Map<String, List<Violation>> readCurrentPMDState(File file) {
+ Map<String, List<Violation>> val = readState(file, HashMap.class);
+ return val == null ? new HashMap<>() : val;
+ }
+
+ static void writeCurrentPMDState(File file, Map<String, List<Violation>> data) {
+ try (OutputStream os = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(os)) {
+ oos.writeObject(data);
+ } catch (IOException ioe) {
+ throw new UncheckedIOException(ioe);
+ }
+ }
+
+ static boolean isReportEmpty(File reportFile){
+ try {
+ return !reportFile.exists() || Files.readAllLines(reportFile.toPath()).size()<=1;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+}
diff --git a/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/PMDState.java b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/PMDState.java
new file mode 100644
index 0000000..2602fff
--- /dev/null
+++ b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/PMDState.java
@@ -0,0 +1,74 @@
+package org.openecomp.sdc.onboarding.pmd;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class PMDState {
+
+ private static Map<String, List<Violation>> data = new HashMap<>();
+ private static Map<String, List<Violation>> historicState = null;
+ private static Pattern p =
+ Pattern.compile("\"(.*)\",\"(.*)\",\"(.*)\",\"(.*)\",\"(.*)\",\"(.*)\",\"(.*)\",\"(.*)\"");
+
+ public static boolean addViolation(String line, String fileLocation) {
+ Matcher m = p.matcher(line);
+ if (m.find()) {
+ if (m.group(3).indexOf("generated-sources") != -1) {
+ return true;
+ }
+ String mainOrTest =
+ m.group(3).indexOf(File.separator + "test" + File.separator) == -1 ? "[MAIN] " : "[TEST] ";
+ List<Violation> list = data.get(fileLocation + "::" + mainOrTest + m.group(2) + "." + m.group(3).substring(
+ m.group(3).lastIndexOf(File.separatorChar) + 1));
+ if (list == null) {
+ list = new LinkedList<>();
+ data.put(fileLocation + "::" + mainOrTest + m.group(2) + "." + m.group(3).substring(
+ m.group(3).lastIndexOf(File.separatorChar) + 1), list);
+ }
+
+ list.add(new Violation(m.group(7), m.group(8), m.group(6), Integer.parseInt(m.group(4)),
+ Integer.parseInt(m.group(5))));
+ return true;
+ }
+ return false;
+ }
+
+ public static void reset(File mainFile, File testFile, String moduleCoordinates) throws IOException {
+ data.clear();
+ init(mainFile, moduleCoordinates, "[MAIN] ");
+ init(testFile, moduleCoordinates, "[TEST] ");
+ }
+
+ private static void init(File file, String moduleCoordinates, String maiOrTest) throws IOException {
+ if (file.exists()) {
+ List<String> coll = Files.readAllLines(file.toPath());
+ for (String line : coll) {
+ if (line.indexOf("$") == -1) {
+ data.put(moduleCoordinates + "::" + maiOrTest + line.substring(0, line.indexOf('.'))
+ .replace(File.separator, ".") + ".java",
+ new LinkedList<>());
+ }
+ }
+ }
+ }
+
+ public static Map<String, List<Violation>> getState() {
+ return data;
+ }
+
+ public static void setHistoricState(Map<String, List<Violation>> data) {
+ historicState = data;
+ }
+
+ public static Map<String, List<Violation>> getHistoricState() {
+ return historicState;
+ }
+
+}
diff --git a/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/Table.java b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/Table.java
new file mode 100644
index 0000000..68eafd0
--- /dev/null
+++ b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/Table.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright © 2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on a "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.onboarding.pmd;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Table {
+
+ private final int TABLEPADDING = 1;
+ private final char SEPERATOR_CHAR = '-';
+
+ private ArrayList<String> headers;
+ private ArrayList<ArrayList<String>> table;
+ private ArrayList<Integer> maxLength;
+
+ public Table(ArrayList<String> headersIn, ArrayList<ArrayList<String>> content) {
+ this.headers = headersIn;
+ this.maxLength = new ArrayList<Integer>();
+ for (int i = 0; i < headers.size(); i++) {
+ maxLength.add(headers.get(i).length());
+ }
+ this.table = content;
+ calcMaxLengthAll();
+ }
+
+ public String drawTable() {
+ StringBuilder sb = new StringBuilder();
+ StringBuilder sbRowSep = new StringBuilder();
+ StringBuffer padder = new StringBuffer();
+ String rowSeperator = "";
+
+ for (int i = 0; i < TABLEPADDING; i++) {
+ padder.append(" ");
+ }
+
+ for (int i = 0; i < maxLength.size(); i++) {
+ sbRowSep.append("|");
+ for (int j = 0; j < maxLength.get(i) + (TABLEPADDING * 2); j++) {
+ sbRowSep.append(SEPERATOR_CHAR);
+ }
+ }
+ sbRowSep.append("|");
+ rowSeperator = sbRowSep.toString();
+
+ sb.append(rowSeperator);
+ sb.append("\n");
+ sb.append("|");
+ for (int i = 0; i < headers.size(); i++) {
+ sb.append(padder);
+ sb.append(headers.get(i));
+ for (int k = 0; k < (maxLength.get(i) - headers.get(i).length()); k++) {
+ sb.append(" ");
+ }
+ sb.append(padder);
+ sb.append("|");
+ }
+ sb.append("\n");
+ sb.append(rowSeperator);
+ sb.append("\n");
+
+ for (int i = 0; i < table.size(); i++) {
+ ArrayList<String> tempRow = table.get(i);
+ sb.append("|");
+ for (int j = 0; j < tempRow.size(); j++) {
+ sb.append(padder);
+ sb.append(tempRow.get(j));
+ for (int k = 0; k < (maxLength.get(j) - tempRow.get(j).length()); k++) {
+ sb.append(" ");
+ }
+ sb.append(padder);
+ sb.append("|");
+ }
+ sb.append("\n");
+ sb.append(rowSeperator);
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+
+ private void calcMaxLengthAll() {
+ for (int i = 0; i < table.size(); i++) {
+ List<String> temp = table.get(i);
+ for (int j = 0; j < temp.size(); j++) {
+ if (temp.get(j).length() > maxLength.get(j)) {
+ maxLength.set(j, temp.get(j).length());
+ }
+ }
+ }
+ }
+
+}
+
diff --git a/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/VerifyHelperMojo.java b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/VerifyHelperMojo.java
new file mode 100644
index 0000000..87c9ca5
--- /dev/null
+++ b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/VerifyHelperMojo.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright © 2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on a "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.onboarding.pmd;
+
+import static org.openecomp.sdc.onboarding.pmd.PMDHelperUtils.getStateFile;
+import static org.openecomp.sdc.onboarding.pmd.PMDHelperUtils.readCurrentPMDState;
+import static org.openecomp.sdc.onboarding.pmd.PMDHelperUtils.writeCurrentPMDState;
+import static org.openecomp.sdc.onboarding.pmd.PMDHelperUtils.isReportEmpty;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.project.MavenProject;
+
+@Mojo(name = "post-verify-helper", threadSafe = true, defaultPhase = LifecyclePhase.VERIFY,
+ requiresDependencyResolution = ResolutionScope.NONE)
+public class VerifyHelperMojo extends AbstractMojo {
+
+ private static final String SKIP_PMD = "skipPMD";
+
+ @Parameter(defaultValue = "${project}", readonly = true)
+ private MavenProject project;
+ @Parameter(defaultValue = "${project.artifact.groupId}:${project.artifact.artifactId}")
+ private String moduleCoordinates;
+ @Parameter(defaultValue = "${session}")
+ private MavenSession session;
+ @Parameter
+ private File pmdTargetLocation;
+ @Parameter
+ private File pmdReportFile;
+ @Parameter
+ private File pmdStateFile;
+ @Parameter
+ private String pmdCurrentStateFilePath;
+ @Parameter
+ private String excludePackaging;
+ @Parameter
+ private Boolean validatePMDReport = Boolean.FALSE;
+ @Parameter
+ private String persistingModuleCoordinates;
+ @Parameter
+ private File pmdFailureReportLocation;
+ @Parameter
+ private File compiledFilesList;
+ @Parameter
+ private File compiledTestFilesList;
+
+ private static File pmdCurrentStateFile;
+
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ if (project.getPackaging().equals(excludePackaging)) {
+ return;
+ }
+ if (moduleCoordinates.equals(persistingModuleCoordinates)) {
+ if (pmdStateFile.exists()) {
+ pmdStateFile.delete();
+ }
+ }
+ if (pmdCurrentStateFile == null) {
+ pmdCurrentStateFile =
+ getStateFile(pmdCurrentStateFilePath.substring(0, pmdCurrentStateFilePath.indexOf('/')), project,
+ pmdCurrentStateFilePath);
+ pmdCurrentStateFile.getParentFile().mkdirs();
+ pmdReportFile.getParentFile().mkdirs();
+ }
+ if (PMDState.getHistoricState() != null && PMDState.getHistoricState().isEmpty()) {
+ getLog().error("PMD Check is skipped. problem while loading data.");
+ }
+ if (Boolean.FALSE.equals(Boolean.valueOf(project.getProperties().getProperty(SKIP_PMD))) && !isReportEmpty(pmdReportFile)) {
+ Map<String, List<Violation>> data = readCurrentPMDState(pmdCurrentStateFile);
+ Map<String, List<Violation>> cv = readCurrentModulePMDReport();
+ data.putAll(cv);
+ if (!PMDState.getHistoricState().isEmpty() && !PMDHelperUtils
+ .evaluateCodeQuality(PMDState.getHistoricState(), cv,
+ pmdFailureReportLocation, getLog())) {
+ if (validatePMDReport) {
+ throw new MojoFailureException(
+ "PMD Failures encountered. Build halted. For details refer " + pmdFailureReportLocation
+ .getAbsolutePath());
+ } else {
+ getLog().error(
+ "\u001B[31m\u001B[1m Code Quality concerns raised by Quality Management System. For details refer "
+ + pmdFailureReportLocation.getAbsolutePath()
+ + " and address them before committing this code in Version Control System. \u001B[0m");
+ }
+ }
+ Map<String, Object> checksumStore = HashMap.class.cast(data);
+ checksumStore.put(moduleCoordinates,
+ project.getProperties().getProperty("mainChecksum") + ":" + project.getProperties()
+ .getProperty("testChecksum"));
+ writeCurrentPMDState(pmdCurrentStateFile, data);
+ }
+ if (Boolean.FALSE.equals(Boolean.valueOf(project.getProperties().getProperty(SKIP_PMD)))) {
+ if (isReportEmpty(pmdReportFile)){
+ HashMap data = HashMap.class.cast(readCurrentPMDState(pmdCurrentStateFile));
+ data.put(moduleCoordinates,
+ project.getProperties().getProperty("mainChecksum") + ":" + project.getProperties()
+ .getProperty("testChecksum"));
+ writeCurrentPMDState(pmdCurrentStateFile, data);
+ }
+ pmdReportFile.delete();
+ }
+ if (pmdTargetLocation.exists()) {
+ pmdTargetLocation.delete();
+ }
+
+ }
+
+ private Map<String, List<Violation>> readCurrentModulePMDReport() {
+ try {
+ PMDState.reset(compiledFilesList, compiledTestFilesList, moduleCoordinates);
+ if (pmdReportFile.exists()) {
+ boolean isFirst = true;
+ for (String line : Files.lines(pmdReportFile.toPath()).collect(Collectors.toList())) {
+ if (isFirst) {
+ isFirst = false;
+ } else {
+ PMDState.addViolation(line, moduleCoordinates);
+ }
+ }
+ }
+ } catch (IOException ioe) {
+ throw new UncheckedIOException(ioe);
+ }
+ return PMDState.getState();
+ }
+
+}
diff --git a/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/Violation.java b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/Violation.java
new file mode 100644
index 0000000..4bfbee1
--- /dev/null
+++ b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/Violation.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on a "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.onboarding.pmd;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.jar.JarFile;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Violation implements Serializable {
+
+ private final String category;
+ private final String rule;
+ private final String description;
+ private final int priority;
+ private final int line;
+
+ public String getCategory() {
+ return category;
+ }
+
+ public String getRule() {
+ return rule;
+ }
+
+ public int getPriority() {
+ return priority;
+ }
+
+ public int getLine() {
+ return line;
+ }
+
+ public Violation(String category, String rule, String description, int priority, int line) {
+ this.category = category;
+ this.rule = rule;
+ this.description = description;
+ this.priority = priority;
+ this.line = line;
+ }
+
+ public String toString() {
+ return category + ":" + rule + ":" + getPriority() + description + ":" + line;
+ }
+}
diff --git a/openecomp-be/tools/pmd-helper-plugin/src/main/resources/pmd-empty.xml b/openecomp-be/tools/pmd-helper-plugin/src/main/resources/pmd-empty.xml
new file mode 100644
index 0000000..c23b533
--- /dev/null
+++ b/openecomp-be/tools/pmd-helper-plugin/src/main/resources/pmd-empty.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<pmd xmlns="http://pmd.sourceforge.net/report/2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://pmd.sourceforge.net/report/2.0.0 http://pmd.sourceforge.net/report_2_0_0.xsd"
+ version="6.0.1" timestamp="2018-04-29T23:06:21.384">
+</pmd>