diff options
author | Gautam Shah <gautams@amdocs.com> | 2018-05-27 13:32:07 +0530 |
---|---|---|
committer | GAUTAMS <gautams@amdocs.com> | 2018-05-28 23:34:45 +0530 |
commit | b145c0825c0bd163a0a2643aeee4c8b283e35ada (patch) | |
tree | e322d65c1fba0abfeb4e4a615c0868ddc23e6f72 /openecomp-be | |
parent | bd6665a88439c0c6459c32fdbe1f979b33a9068c (diff) |
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>
Diffstat (limited to 'openecomp-be')
31 files changed, 2529 insertions, 395 deletions
diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/pom.xml b/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/pom.xml index f2913ff522..43d0855824 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/pom.xml +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/pom.xml @@ -205,7 +205,6 @@ <artifactId>maven-war-plugin</artifactId> <version>${mvn.war.version}</version> <configuration> - <attachClasses>true</attachClasses> <webResources> <resource> <!-- this is relative to the pom.xml directory --> diff --git a/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/pom.xml b/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/pom.xml index 84696e4ae3..28842ce6b6 100644 --- a/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/pom.xml +++ b/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/pom.xml @@ -94,6 +94,7 @@ <parallel>classes</parallel> <threadCount>1</threadCount> <forkCount>${fork.count}</forkCount> + <forkMode>${fork.mode}</forkMode> <printSummary>false</printSummary> <redirectTestOutputToFile>true</redirectTestOutputToFile> <rerunFailingTestsCount>1</rerunFailingTestsCount> @@ -104,6 +105,7 @@ <logback.configurationFile>src/test/resources/logback-test.xml</logback.configurationFile> </systemPropertyVariables> <useSystemClassLoader>${useSystemClassLoader}</useSystemClassLoader> + <skip>${skipTestRun}</skip> </configuration> </plugin> </plugins> diff --git a/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/pom.xml b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/pom.xml index 2eb7df7474..0b2cb5f2a8 100644 --- a/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/pom.xml +++ b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/pom.xml @@ -86,13 +86,6 @@ <artifactId>openecomp-sdc-validation-core</artifactId> <version>${project.version}</version> </dependency> - <dependency> - <groupId>org.openecomp.sdc</groupId> - <artifactId>openecomp-sdc-validation-sdk</artifactId> - <version>${project.version}</version> - <type>test-jar</type> - <scope>test</scope> - </dependency> </dependencies> </project> diff --git a/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/test/java/org/openecomp/sdc/validation/util/ValidationTestUtil.java b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/test/java/org/openecomp/sdc/validation/util/ValidationTestUtil.java new file mode 100644 index 0000000000..41fbf45c64 --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/test/java/org/openecomp/sdc/validation/util/ValidationTestUtil.java @@ -0,0 +1,189 @@ +/* + * Copyright © 2016-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 an "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.validation.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.io.IOUtils; +import org.openecomp.core.utilities.file.FileUtils; +import org.openecomp.core.utilities.json.JsonUtil; +import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder; +import org.openecomp.core.validation.types.GlobalValidationContext; +import org.openecomp.core.validation.types.MessageContainer; +import org.openecomp.sdc.heat.datatypes.manifest.FileData; +import org.openecomp.sdc.heat.datatypes.manifest.ManifestContent; +import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate; +import org.openecomp.sdc.heat.datatypes.model.Resource; +import org.openecomp.sdc.heat.services.HeatStructureUtil; +import org.openecomp.sdc.heat.services.manifest.ManifestUtil; +import org.openecomp.sdc.validation.ResourceValidator; +import org.openecomp.sdc.validation.ValidationContext; +import org.openecomp.sdc.validation.Validator; +import org.openecomp.sdc.validation.base.ResourceBaseValidator; +import org.testng.Assert; + +/** + * @author TALIO + * @since 26 Feb 2017 + */ +public class ValidationTestUtil { + + private ValidationTestUtil(){} + + public static GlobalValidationContext createGlobalContextFromPath(String path) { + GlobalValidationContext globalValidationContext = new GlobalValidationContext(); + Map<String, byte[]> contentMap = getContentMapByPath(path); + if (contentMap == null) { + return null; + } + contentMap.forEach(globalValidationContext::addFileContext); + + return globalValidationContext; + } + + private static Map<String, byte[]> getContentMapByPath(String path) { + Map<String, byte[]> contentMap = new HashMap<>(); + URL url = ValidationTestUtil.class.getResource(path); + File pathFile = new File(url.getFile()); + File[] files; + if (pathFile.isDirectory()) { + files = pathFile.listFiles(); + } else { + files = new File[]{pathFile}; + } + + if (files == null || files.length == 0) { + return null; + } + + for (File file : files) { + + try (FileInputStream fis = new FileInputStream(file)) { + contentMap.put(file.getName(), FileUtils.toByteArray(fis)); + } catch (IOException e) { + throw new RuntimeException("Failed to read file: " + file, e); + } + + } + return contentMap; + } + + public static Map<String, MessageContainer> testValidator(Validator validator, String path) { + + GlobalValidationContext globalValidationContext = createGlobalContextFromPath(path); + validator.validate(globalValidationContext); + + assert globalValidationContext != null; + return globalValidationContext.getContextMessageContainers(); + + + } + + public static Map<String, MessageContainer> testValidator(ResourceBaseValidator baseValidator, + ResourceValidator resourceValidator, + String resourceTypeToValidate, String path) { + + GlobalValidationContext globalContext = Objects.requireNonNull( + createGlobalContextFromPath(path), "Global validation context cannot be null"); + + ManifestContent manifestContent = ValidationUtil.validateManifest(globalContext); + Map<String, FileData.Type> fileTypeMap = ManifestUtil.getFileTypeMap(manifestContent); + Map<String, FileData> fileEnvMap = ManifestUtil.getFileAndItsEnv(manifestContent); + + validateFiles(baseValidator, resourceValidator, globalContext, fileEnvMap, fileTypeMap, + resourceTypeToValidate); + + return globalContext.getContextMessageContainers(); + } + + private static void validateFiles(ResourceBaseValidator baseValidator, + ResourceValidator resourceValidator, + GlobalValidationContext globalContext, + Map<String, FileData> fileEnvMap, + Map<String, FileData.Type> fileTypeMap, + String resourceTypeToValidate) { + + Collection<String> files = globalContext.getFiles(); + for(String fileName : files){ + if(FileData.isHeatFile(fileTypeMap.get(fileName))) { + HeatOrchestrationTemplate heatOrchestrationTemplate = + ValidationUtil.checkHeatOrchestrationPreCondition(fileName, globalContext); + + if (Objects.isNull(heatOrchestrationTemplate)) { + continue; + } + + ValidationContext validationContext = baseValidator.createValidationContext(fileName, + fileEnvMap.get(fileName) == null ? null : fileEnvMap.get(fileName).getFile(), + heatOrchestrationTemplate, globalContext); + + validateResources(fileName, resourceValidator, resourceTypeToValidate, validationContext, + globalContext); + } + } + } + + private static void validateResources(String fileName, ResourceValidator resourceValidator, + String resourceTypeToValidate, ValidationContext validationContext, + GlobalValidationContext globalValidationContext){ + + HeatOrchestrationTemplate heatOrchestrationTemplate = + ValidationUtil.checkHeatOrchestrationPreCondition(fileName, globalValidationContext); + + Map<String, Resource> resourcesMap = + Objects.requireNonNull(heatOrchestrationTemplate, "Orchestration template cannot be null").getResources(); + + if(MapUtils.isEmpty(resourcesMap)){ + return; + } + + resourcesMap.entrySet() + .stream() + .filter(resourceEntry -> isResourceNeedToBeTested(resourceEntry.getValue().getType(), resourceTypeToValidate)) + .forEach(resourceEntry -> + resourceValidator.validate + (fileName, resourceEntry, globalValidationContext, validationContext)); + } + + private static boolean isResourceNeedToBeTested(String currResource, String resourceToTest){ + if(Objects.isNull(resourceToTest)){ + return HeatStructureUtil.isNestedResource(currResource); + } + + return currResource.equals(resourceToTest); + } + + public static void validateErrorMessage(String actualMessage, String expected, String... params) { + + Assert.assertEquals(actualMessage.replace("\n", "").replace("\r", ""), + ErrorMessagesFormatBuilder.getErrorWithParameters(expected, params).replace("\n", "") + .replace("\r", "")); + } + + public static Map<String, Object> getResourceMap(String configFileName) throws IOException { + URL mockResource = ValidationTestUtil.class.getResource(configFileName); + String json = IOUtils.toString(mockResource.openStream(), "UTF-8"); + return JsonUtil.json2Object(json, Map.class); + } +} diff --git a/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-sdk/pom.xml b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-sdk/pom.xml index 180e3184fc..ad49dac2f6 100644 --- a/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-sdk/pom.xml +++ b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-sdk/pom.xml @@ -42,22 +42,5 @@ </dependency> </dependencies> - <build> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-jar-plugin</artifactId> - <version>${mvn.jar.version}</version> - <executions> - <execution> - <goals> - <goal>test-jar</goal> - </goals> - </execution> - </executions> - </plugin> - </plugins> - </build> - </project> diff --git a/openecomp-be/pom.xml b/openecomp-be/pom.xml index 786ef92d38..22c23d4b57 100644 --- a/openecomp-be/pom.xml +++ b/openecomp-be/pom.xml @@ -49,65 +49,215 @@ <artifactId>maven-compiler-plugin</artifactId> <version>${mvn.compiler.version}</version> <inherited>true</inherited> + <executions> + <execution> + <id>default-compile</id> + <configuration> + <skipMain>${skipMainSourceCompile}</skipMain> + </configuration> + </execution> + <execution> + <id>default-testCompile</id> + <configuration> + <skip>${skipTestSourceCompile}</skip> + </configuration> + </execution> + </executions> <configuration> <source>${java.source}</source> <target>${java.target}</target> - <excludes> - <exclude>**/package-info.java</exclude> - </excludes> + </configuration> + </plugin> + <plugin> + <groupId>org.openecomp.sdc.onboarding</groupId> + <artifactId>artifact-copy-plugin</artifactId> + <version>${project.version}</version> + <executions> + <execution> + <goals> + <goal>init-artifact-helper</goal> + <goal>copy-helper</goal> + <goal>calibrate-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>pre-clean</phase> + <configuration> + <artifactId>build-data-helper</artifactId> + </configuration> + </execution> + <execution> + <id>id2</id> + <goals> + <goal>get</goal> + </goals> + <phase>pre-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> <plugin> <groupId>org.openecomp.sdc.onboarding</groupId> <artifactId>compile-helper-plugin</artifactId> <version>${project.version}</version> + <dependencies> + <dependency> + <groupId>org.openecomp.sdc</groupId> + <artifactId>build-data-helper</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.sdc.onboarding</groupId> + <artifactId>pmd-helper-plugin</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> <executions> <execution> <goals> + <goal>init-helper</goal> <goal>pre-compile-helper</goal> - <goal>pre-test-compile-helper</goal> <goal>post-compile-helper</goal> + <goal>pre-test-compile-helper</goal> <goal>post-test-run-helper</goal> - <goal>init-helper</goal> </goals> </execution> </executions> <configuration> <excludePackaging>pom</excludePackaging> <excludeDependencies>test,runtime</excludeDependencies> - <staleThreshold>10000</staleThreshold> - <mainSourceLocation>${basedir}/src/main/java</mainSourceLocation> - <testSourceLocation>${basedir}/src/test/java</testSourceLocation> - <mainResourceLocation>${basedir}/src/main/resources</mainResourceLocation> - <testResourceLocation>${basedir}/src/test/resources</testResourceLocation> - <mainCompiledLocation>${project.build.directory}/classes</mainCompiledLocation> - <testCompiledLocation>${project.build.directory}/test-classes</testCompiledLocation> - <compiledFilesList> - ${project.build.directory}/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst - </compiledFilesList> - <inputSourceFilesList> - ${project.build.directory}/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst - </inputSourceFilesList> - <inputTestFilesList> - ${project.build.directory}/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst - </inputTestFilesList> - <compiledTestFilesList> - ${project.build.directory}/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst - </compiledTestFilesList> + <generatedSourceLocation>${project.build.directory}/generated-sources</generatedSourceLocation> <buildState> - <moduleBuildDataFile>${project.build.directory}/build-data/ModuleDependencies.dat - </moduleBuildDataFile> - <resourceBuildDataFile>${project.build.directory}/build-data/ResourceDependencies.dat - </resourceBuildDataFile> <project>${project}</project> - <buildStateFilePath>org.openecomp.sdc:sdc-onboarding/target/build-data/BuildState.dat - </buildStateFilePath> - <resourceStateFilePath>org.openecomp.sdc:sdc-onboarding/target/build-data/ResourceState.dat - </resourceStateFilePath> + <compileStateFilePath>org.openecomp.sdc:sdc-onboarding/target/build-data/compileState.dat</compileStateFilePath> </buildState> </configuration> </plugin> <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-pmd-plugin</artifactId> + <version>${maven.pmd.plugin.version}</version> + <dependencies> + <dependency> + <groupId>org.openecomp.sdc</groupId> + <artifactId>build-tools</artifactId> + <version>${build.tools.version}</version> + </dependency> + <dependency> + <groupId>net.sourceforge.pmd</groupId> + <artifactId>pmd-core</artifactId> + <version>${pmd.core.version}</version> + </dependency> + <dependency> + <groupId>net.sourceforge.pmd</groupId> + <artifactId>pmd-java</artifactId> + <version>${pmd.java.version}</version> + </dependency> + </dependencies> + <configuration> + <skip>${skipPMD}</skip> + <showPmdLog>false</showPmdLog> + <analysisCache>false</analysisCache> + <analysisCacheLocation>${project.build.directory}/pmd/pmd.cache</analysisCacheLocation> + <failOnViolation>false</failOnViolation> + <printFailingErrors>false</printFailingErrors> + <format>csv</format> + <targetDirectory>${project.build.directory}/pmd</targetDirectory> + <includeTests>true</includeTests> + <linkXRef>false</linkXRef> + <aggregate>false</aggregate> + <rulesets> + <ruleset>/category/java/bestpractices.xml</ruleset> + <ruleset>/category/java/codestyle.xml</ruleset> + <ruleset>/category/java/design.xml</ruleset> + <ruleset>/category/java/errorprone.xml</ruleset> + <ruleset>/category/java/multithreading.xml</ruleset> + <ruleset>/category/java/performance.xml</ruleset> + <ruleset>/category/java/security.xml</ruleset> + </rulesets> + </configuration> + <executions> + <execution> + <goals> + <goal>check</goal> + </goals> + <phase>integration-test</phase> + </execution> + </executions> + </plugin> + <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> + <pmdFailureReportLocation>${project.build.directory}/pmd.txt</pmdFailureReportLocation> + <pmdReportFile>${project.build.directory}/pmd/pmd.csv</pmdReportFile> + <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> + <compiledFilesList>${project.build.directory}/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst</compiledFilesList> + <compiledTestFilesList>${project.build.directory}/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst</compiledTestFilesList> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <version>${mvn.jar.version}</version> + <configuration> + <archive> + <addMavenDescriptor>${mvnDsc}</addMavenDescriptor> + </archive> + <excludes> + <exclude>${emptyJAR}</exclude> + </excludes> + </configuration> + </plugin> + <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>license-maven-plugin</artifactId> <version>${mvn.license.version}</version> 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 0000000000..03301a719e --- /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 0000000000..e7ad5dacb1 --- /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 0000000000..4838608835 --- /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 0000000000..20b1a7c940 --- /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 0000000000..067517504c --- /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 0000000000..a5f55c3f59 --- /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 0000000000..94121b5ddc --- /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 3891558b66..73513f6b17 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 0000000000..42f3166ad6 --- /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 888622f959..17ff7c9500 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.FileOutputStream; 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); + void init() { + artifacts.clear(); + for (Artifact artifact : project.getArtifacts()) { + if (artifact.isSnapshot() && JAR.equals(artifact.getType())) { + artifacts.put(artifact.getGroupId() + ":" + artifact.getArtifactId(), artifact); + } + } + compileStateFile = + getCompileStateFile(compileStateFilePath.substring(0, compileStateFilePath.indexOf('/')), project); + } + 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 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())); - } - } catch (Exception e) { - store.clear(); - } - return file; + + static void recordPMDRun(String moduleCoordinates) { + pmdExecutedInRun.add(moduleCoordinates); } - private void writeFullBuildState() throws IOException { - writeState(buildStateFile, fullBuildData); + static boolean isPMDRun(String moduleCoordintes) { + return pmdExecutedInRun.contains(moduleCoordintes); } - private void writeFullResourceBuildState() throws IOException { - writeState(resourceStateFile, fullResourceBuildData); + private void writeCompileState() throws IOException { + writeState(compileStateFile, compileDataStore); } private void writeState(File file, Map store) throws IOException { @@ -90,20 +100,18 @@ public class BuildState { } } - private File getBuildStateFile(String moduleCoordinate, MavenProject proj) { - return getStateFile(moduleCoordinate, proj, buildStateFilePath); - } - private File getResourceStateFile(String moduleCoordinate, MavenProject proj) { - return getStateFile(moduleCoordinate, proj, resourceStateFilePath); + private File getCompileStateFile(String moduleCoordinate, MavenProject proj) { + return getStateFile(moduleCoordinate, proj, compileStateFilePath); } + 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 @@ public class BuildState { } 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 @@ public class BuildState { } 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 @@ public class BuildState { } 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 @@ public class BuildState { } 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 @@ public class BuildState { 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 96abc47882..c639c6d790 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 @@ package org.openecomp.sdc.onboarding; 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 cbf6f69c8a..8b0ff0eba2 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.Parameter; 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 9ab373509e..04e0ca8e23 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.Parameter; 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,88 +45,14 @@ public class PostCompileHelperMojo extends AbstractMojo { @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)) { @@ -143,93 +61,40 @@ public class PostCompileHelperMojo extends AbstractMojo { 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); - 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()); + 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); } - 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(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(SKIP_TEST_RUN)) { - if (compiledTestFilesList.exists() - && compiledTestFilesList.lastModified() > System.currentTimeMillis() - staleThreshold) { - project.getProperties().setProperty(SKIP_TEST_RUN, Boolean.FALSE.toString()); - } + 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); } - } - - 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()); - } + 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); } - } - - 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); + 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); } - 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()); - } + if (!project.getProperties().containsKey(SKIP_MAIN_SOURCE_COMPILE)) { + buildState.addModuleBuildTime(moduleCoordinates, System.currentTimeMillis()); + project.getProperties().setProperty(SKIP_PMD, Boolean.FALSE.toString()); } - 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()); + if (!project.getProperties().containsKey(SKIP_TEST_SOURCE_COMPILE)) { + project.getProperties().setProperty(SKIP_PMD, Boolean.FALSE.toString()); } - return dependencies; + buildState.saveModuleBuildData(moduleCoordinates); } } 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 0000000000..36e5f8ac32 --- /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 5b326f3ddf..c2816dbfbf 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 @@ public class PostTestRunHelperMojo extends AbstractMojo { 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 faa3167e37..854ef7fa97 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; + private BuildState buildState; @Parameter - private File testCompiledLocation; + private File mainSourceLocation; @Parameter - private File inputSourceFilesList; + private File testSourceLocation; @Parameter - private File inputTestFilesList; + private File generatedSourceLocation; + @Component + private MavenPluginManager pluginManager; @Parameter - private BuildState buildState; + private File mainResourceLocation; + @Parameter + private File testResourceLocation; + private Map<String, Object> resourceBuildData; - public void execute() throws MojoExecutionException { - if (!System.getProperties().containsKey(UNICORN)) { + 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; } - if (project.getPackaging().equals(excludePackaging)) { + 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; - - 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 buildDataSameWithPreviousBuild = + isBuildDataSameWithPreviousBuild(lastTimeModuleBuildData, moduleBuildData); + boolean resourceMainBuildDataSameWithPreviousBuild = + isResourceMainBuildDataSameWithPreviousBuild(lastTimeResourceBuildData); + + boolean mainToBeCompiled = isCompileNeeded(HashMap.class.cast(moduleBuildData.get(MAIN)).keySet(), isFirstBuild, + buildDataSameWithPreviousBuild); + + boolean resourceDataSame = resourceBuildData.equals(lastTimeResourceBuildData); + + 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 (!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); - } + if (!mainToBeCompiled && !instrumented && JAR.equals(project.getPackaging()) + && resourceMainBuildDataSameWithPreviousBuild) { + project.getProperties().setProperty("artifactPathToCopy", artifactPath.orElse(null)); } + } - if (!moduleBuildData.equals(lastTimeModuleBuildData)) { - buildState.addModuleBuildData(moduleCoordinates, moduleBuildData); + 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()); + } + } - if (inputSourceFilesList.isFile() && inputSourceFilesList.length() == 0) { - if (!inputSourceFilesList.delete()) { - throw new MojoExecutionException( - "****** Please remove 'target' directory manually under path " + project.getBasedir() - .getAbsolutePath()); + 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()); } } - if (inputTestFilesList.isFile() && inputTestFilesList.length() == 0) { - if (!inputTestFilesList.delete()) { - throw new MojoExecutionException( - "****** Please remove 'target' directory manually under path " + project.getBasedir() - .getAbsolutePath()); + } + + 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 e711cb0ae7..a11d796464 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.Mojo; 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 @@ public class PreTestCompileHelperMojo extends AbstractMojo { 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 @@ public class PreTestCompileHelperMojo extends AbstractMojo { 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 0000000000..75ab1f89c8 --- /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 0000000000..4102a1b382 --- /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 0000000000..38dde12454 --- /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 0000000000..2602fff2c6 --- /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 0000000000..68eafd0117 --- /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 0000000000..87c9ca5f1f --- /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 0000000000..4bfbee18b9 --- /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 0000000000..c23b533c81 --- /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> |