aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruno Sakoto <bruno.sakoto@bell.ca>2021-05-12 08:37:16 -0400
committerBruno Sakoto <bruno.sakoto@bell.ca>2021-05-17 11:11:37 -0400
commit25050c117a6e69946de4f70503afa74cdef78aa7 (patch)
treeb3d6e11fba894ed91af7357daf3b1a60b91321c7
parent2d88ad8115c4f618275490e58c584f9b0c01c477 (diff)
Add automatic architecture verification
Introduce verification for dependencies and layers. Issue-ID: CPS-381 Signed-off-by: Bruno Sakoto <bruno.sakoto@bell.ca> Change-Id: I948439ee5bcba2d41ccba3028d62a728babc83da
-rwxr-xr-xpom.xml47
-rw-r--r--src/test/java/org/onap/cps/temporal/architecture/DependencyArchitectureTest.java42
-rw-r--r--src/test/java/org/onap/cps/temporal/architecture/LayeredArchitectureTest.java73
3 files changed, 148 insertions, 14 deletions
diff --git a/pom.xml b/pom.xml
index 9488873..c38b565 100755
--- a/pom.xml
+++ b/pom.xml
@@ -37,21 +37,34 @@
<properties>
<app>org.onap.cps.temporal.Application</app>
- <cps.checkstyle.version>1.0.1</cps.checkstyle.version>
- <cps.spotbugs.version>1.0.1</cps.spotbugs.version>
<docker.repository.pull>nexus3.onap.org:10001/</docker.repository.pull>
<docker.repository.push>nexus3.onap.org:10003/</docker.repository.push>
<image.base>${docker.repository.pull}onap/integration-java11:8.0.0</image.base>
<image.name>${docker.repository.push}onap/cps-temporal</image.name>
- <hibernate-types.version>2.10.0</hibernate-types.version>
<java.version>11</java.version>
- <jib-maven-plugin.version>3.0.0</jib-maven-plugin.version>
<maven.build.timestamp.format>yyyyMMdd'T'HHmmss'Z'</maven.build.timestamp.format>
<minimum-coverage>0.8</minimum-coverage>
+ <!-- Application dependencies versions -->
+ <spring-boot-dependencies.version>2.3.8.RELEASE</spring-boot-dependencies.version>
+ <hibernate-types.version>2.10.0</hibernate-types.version>
+ <liquibase-core.version>4.3.2</liquibase-core.version>
+ <!-- Tests dependencies versions -->
+ <spock-bom.version>2.0-M4-groovy-3.0</spock-bom.version>
+ <groovy.version>3.0.7</groovy.version>
+ <junit-jupiter.version>1.15.2</junit-jupiter.version>
+ <testcontainers-postgresql.version>1.15.2</testcontainers-postgresql.version>
+ <archunit-junit5.version>0.18.0</archunit-junit5.version>
+ <!-- Plugins and plugins dependencies versions -->
+ <spring-boot-maven-plugin.version>2.3.3.RELEASE</spring-boot-maven-plugin.version>
+ <gmavenplus-plugin.version>1.12.1</gmavenplus-plugin.version>
+ <jib-maven-plugin.version>3.0.0</jib-maven-plugin.version>
<oparent.version>3.2.0</oparent.version>
+ <cps.checkstyle.version>1.0.1</cps.checkstyle.version>
+ <cps.spotbugs.version>1.0.1</cps.spotbugs.version>
<spotbugs-maven-plugin.version>4.1.3</spotbugs-maven-plugin.version>
- <spotbugs.slf4j.version>1.8.0-beta4</spotbugs.slf4j.version>
<spotbugs.version>4.2.0</spotbugs.version>
+ <spotbugs.slf4j.version>1.8.0-beta4</spotbugs.slf4j.version>
+ <bug-pattern.version>1.5.0</bug-pattern.version>
</properties>
<dependencyManagement>
@@ -59,14 +72,14 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
- <version>2.3.8.RELEASE</version>
+ <version>${spring-boot-dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-bom</artifactId>
- <version>2.0-M4-groovy-3.0</version>
+ <version>${spock-bom.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -94,7 +107,7 @@
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
- <version>4.3.2</version>
+ <version>${liquibase-core.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
@@ -114,7 +127,7 @@
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
- <version>3.0.7</version>
+ <version>${groovy.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -140,13 +153,19 @@
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
- <version>1.15.2</version>
+ <version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
- <version>1.15.2</version>
+ <version>${testcontainers-postgresql.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.tngtech.archunit</groupId>
+ <artifactId>archunit-junit5</artifactId>
+ <version>${archunit-junit5.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
@@ -156,14 +175,14 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
- <version>2.3.3.RELEASE</version>
+ <version>${spring-boot-maven-plugin.version}</version>
</plugin>
<plugin>
<!-- The gmavenplus plugin is used to compile Groovy code. To learn more about this plugin,
visit https://github.com/groovy/GMavenPlus/wiki -->
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
- <version>1.12.1</version>
+ <version>${gmavenplus-plugin.version}</version>
<executions>
<execution>
<goals>
@@ -275,7 +294,7 @@
<plugin>
<groupId>jp.skypencil.findbugs.slf4j</groupId>
<artifactId>bug-pattern</artifactId>
- <version>1.5.0</version>
+ <version>${bug-pattern.version}</version>
</plugin>
</plugins>
<!--
diff --git a/src/test/java/org/onap/cps/temporal/architecture/DependencyArchitectureTest.java b/src/test/java/org/onap/cps/temporal/architecture/DependencyArchitectureTest.java
new file mode 100644
index 0000000..8e4cfd5
--- /dev/null
+++ b/src/test/java/org/onap/cps/temporal/architecture/DependencyArchitectureTest.java
@@ -0,0 +1,42 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (c) 2021 Bell Canada.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.temporal.architecture;
+
+import static com.tngtech.archunit.library.DependencyRules.NO_CLASSES_SHOULD_DEPEND_UPPER_PACKAGES;
+import static com.tngtech.archunit.library.dependencies.SlicesRuleDefinition.slices;
+
+import com.tngtech.archunit.core.importer.ImportOption;
+import com.tngtech.archunit.junit.AnalyzeClasses;
+import com.tngtech.archunit.junit.ArchTest;
+import com.tngtech.archunit.lang.ArchRule;
+
+/**
+ * Test class responsible for dependencies validations.
+ */
+@AnalyzeClasses(packages = "org.onap.cps.temporal", importOptions = { ImportOption.DoNotIncludeTests.class })
+public class DependencyArchitectureTest {
+
+ @ArchTest
+ static final ArchRule noCyclesRule =
+ slices().matching("org.onap.cps.temporal.(**)..").should().beFreeOfCycles();
+
+ @ArchTest
+ static final ArchRule noUpperPackageDependencyRule = NO_CLASSES_SHOULD_DEPEND_UPPER_PACKAGES;
+
+}
diff --git a/src/test/java/org/onap/cps/temporal/architecture/LayeredArchitectureTest.java b/src/test/java/org/onap/cps/temporal/architecture/LayeredArchitectureTest.java
new file mode 100644
index 0000000..d47e8a5
--- /dev/null
+++ b/src/test/java/org/onap/cps/temporal/architecture/LayeredArchitectureTest.java
@@ -0,0 +1,73 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (c) 2021 Bell Canada.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.temporal.architecture;
+
+import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
+import static com.tngtech.archunit.library.Architectures.layeredArchitecture;
+
+import com.tngtech.archunit.core.importer.ImportOption;
+import com.tngtech.archunit.junit.AnalyzeClasses;
+import com.tngtech.archunit.junit.ArchTest;
+import com.tngtech.archunit.lang.ArchRule;
+
+/**
+ * Test class responsible for layered architecture.
+ */
+@AnalyzeClasses(packages = "org.onap.cps.temporal", importOptions = { ImportOption.DoNotIncludeTests.class })
+public class LayeredArchitectureTest {
+
+ private static final String CONTROLLER_PACKAGE = "org.onap.cps.temporal.controller..";
+ private static final String SERVICE_PACKAGE = "org.onap.cps.temporal.service..";
+ private static final String REPOSITORY_PACKAGE = "org.onap.cps.temporal.repository..";
+
+ // 'access' catches only violations by real accesses,
+ // i.e. accessing a field, calling a method; compare 'dependOn' further down
+
+ @ArchTest
+ public static final ArchRule layeredArchitectureRule =
+ layeredArchitecture()
+ .layer("Controller").definedBy(CONTROLLER_PACKAGE)
+ .layer("Service").definedBy(SERVICE_PACKAGE)
+ .layer("Repository").definedBy(REPOSITORY_PACKAGE)
+ .whereLayer("Controller").mayNotBeAccessedByAnyLayer()
+ .whereLayer("Service").mayOnlyBeAccessedByLayers("Controller")
+ .whereLayer("Repository").mayOnlyBeAccessedByLayers("Service");
+
+ // 'dependOn' catches a wider variety of violations,
+ // e.g. having fields of type, having method parameters of type, extending type ...
+
+ @ArchTest
+ static final ArchRule controllerDependencyRule =
+ classes().that().resideInAPackage(CONTROLLER_PACKAGE)
+ .should().onlyHaveDependentClassesThat()
+ .resideInAPackage(CONTROLLER_PACKAGE);
+
+ @ArchTest
+ static final ArchRule serviceDependencyRule =
+ classes().that().resideInAPackage(SERVICE_PACKAGE)
+ .should().onlyHaveDependentClassesThat()
+ .resideInAnyPackage(CONTROLLER_PACKAGE, SERVICE_PACKAGE);
+
+ @ArchTest
+ static final ArchRule repositoryDependencyRule =
+ classes().that().resideInAPackage(REPOSITORY_PACKAGE)
+ .should().onlyHaveDependentClassesThat()
+ .resideInAnyPackage(SERVICE_PACKAGE, REPOSITORY_PACKAGE);
+
+} \ No newline at end of file