diff --git a/libraries-testing/pom.xml b/libraries-testing/pom.xml index 5a5cb99238..8052680ea5 100644 --- a/libraries-testing/pom.xml +++ b/libraries-testing/pom.xml @@ -1,7 +1,7 @@ + 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"> 4.0.0 libraries-testing libraries-testing @@ -158,6 +158,13 @@ test + + com.tngtech.archunit + archunit-junit5 + ${archunit.version} + test + + @@ -193,7 +200,7 @@ 1.5.7.1 - 1.9.9 + 1.9.9 1.9.0 1.9.0 1.9.27 @@ -210,6 +217,7 @@ 1.8 1.8 3.8.1 + 0.14.1 diff --git a/libraries-testing/src/main/java/com/baeldung/archunit/smurfs/persistence/SmurfsRepository.java b/libraries-testing/src/main/java/com/baeldung/archunit/smurfs/persistence/SmurfsRepository.java new file mode 100644 index 0000000000..5d90d0f288 --- /dev/null +++ b/libraries-testing/src/main/java/com/baeldung/archunit/smurfs/persistence/SmurfsRepository.java @@ -0,0 +1,38 @@ +package com.baeldung.archunit.smurfs.persistence; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.TreeMap; + +import com.baeldung.archunit.smurfs.persistence.domain.Smurf; + +import static java.util.stream.Collectors.toList; + +public class SmurfsRepository { + + private static Map smurfs = Collections.synchronizedMap(new TreeMap<>()); + + static { + // Just a few here. A full list can be found + // at https://smurfs.fandom.com/wiki/List_of_Smurf_characters + smurfs.put("Papa", new Smurf("Papa", true, true)); + smurfs.put("Actor", new Smurf("Actor", true, true)); + smurfs.put("Alchemist", new Smurf("Alchemist", true, true)); + smurfs.put("Archeologist", new Smurf("Archeologist", true, true)); + smurfs.put("Architect", new Smurf("Architect", true, true)); + smurfs.put("Baby", new Smurf("Baby", true, true)); + smurfs.put("Baker", new Smurf("Baker", true, true)); + smurfs.put("Baker", new Smurf("Baker", true, true)); + } + + public List findAll() { + return Collections.unmodifiableList(smurfs.values().stream().collect(toList())); + } + + public Optional findByName(String name) { + return Optional.of(smurfs.get(name)); + } + +} diff --git a/libraries-testing/src/main/java/com/baeldung/archunit/smurfs/persistence/domain/Smurf.java b/libraries-testing/src/main/java/com/baeldung/archunit/smurfs/persistence/domain/Smurf.java new file mode 100644 index 0000000000..255a024cdc --- /dev/null +++ b/libraries-testing/src/main/java/com/baeldung/archunit/smurfs/persistence/domain/Smurf.java @@ -0,0 +1,39 @@ +package com.baeldung.archunit.smurfs.persistence.domain; + +public class Smurf { + private String name; + private boolean comic; + private boolean cartoon; + + public Smurf() {} + + public Smurf(String name, boolean comic, boolean cartoon) { + this.name = name; + this.comic = comic; + this.cartoon = cartoon; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isComic() { + return comic; + } + + public void setCommic(boolean comic) { + this.comic = comic; + } + + public boolean isCartoon() { + return cartoon; + } + + public void setCartoon(boolean cartoon) { + this.cartoon = cartoon; + } +} diff --git a/libraries-testing/src/main/java/com/baeldung/archunit/smurfs/presentation/SmurfsController.java b/libraries-testing/src/main/java/com/baeldung/archunit/smurfs/presentation/SmurfsController.java new file mode 100644 index 0000000000..7e31980d89 --- /dev/null +++ b/libraries-testing/src/main/java/com/baeldung/archunit/smurfs/presentation/SmurfsController.java @@ -0,0 +1,27 @@ +package com.baeldung.archunit.smurfs.presentation; + +import java.util.List; + +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.archunit.smurfs.service.SmurfsService; +import com.baeldung.archunit.smurfs.service.dto.SmurfDTO; + +@RequestMapping(value = "/smurfs", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) +@RestController +public class SmurfsController { + + private SmurfsService smurfs; + + public SmurfsController(SmurfsService smurfs) { + this.smurfs = smurfs; + } + + @GetMapping + public List getSmurfs() { + return smurfs.findAll(); + } +} diff --git a/libraries-testing/src/main/java/com/baeldung/archunit/smurfs/service/SmurfsService.java b/libraries-testing/src/main/java/com/baeldung/archunit/smurfs/service/SmurfsService.java new file mode 100644 index 0000000000..4034b33b39 --- /dev/null +++ b/libraries-testing/src/main/java/com/baeldung/archunit/smurfs/service/SmurfsService.java @@ -0,0 +1,35 @@ + +package com.baeldung.archunit.smurfs.service; + +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.stereotype.Component; + +import com.baeldung.archunit.smurfs.persistence.SmurfsRepository; +import com.baeldung.archunit.smurfs.persistence.domain.Smurf; +import com.baeldung.archunit.smurfs.service.dto.SmurfDTO; + +@Component +public class SmurfsService { + + private SmurfsRepository repository; + + public SmurfsService(SmurfsRepository repository) { + this.repository = repository; + } + + public List findAll() { + + return repository.findAll() + .stream() + .map(SmurfsService::toDTO) + .collect(Collectors.toList()); + } + + + public static SmurfDTO toDTO(Smurf smurf) { + return new SmurfDTO(smurf.getName(),smurf.isComic(), smurf.isCartoon()); + } + +} diff --git a/libraries-testing/src/main/java/com/baeldung/archunit/smurfs/service/dto/SmurfDTO.java b/libraries-testing/src/main/java/com/baeldung/archunit/smurfs/service/dto/SmurfDTO.java new file mode 100644 index 0000000000..523c639c41 --- /dev/null +++ b/libraries-testing/src/main/java/com/baeldung/archunit/smurfs/service/dto/SmurfDTO.java @@ -0,0 +1,41 @@ + +package com.baeldung.archunit.smurfs.service.dto; + +public class SmurfDTO { + private String name; + private boolean comic; + private boolean cartoon; + + public SmurfDTO() {} + + public SmurfDTO(String name, boolean comic, boolean cartoon) { + this.name = name; + this.comic = comic; + this.cartoon = cartoon; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isComic() { + return comic; + } + + public void setCommic(boolean comic) { + this.comic = comic; + } + + public boolean isCartoon() { + return cartoon; + } + + public void setCartoon(boolean cartoon) { + this.cartoon = cartoon; + } + +} diff --git a/libraries-testing/src/test/java/com/baeldung/archunit/smurfs/SmurfsArchUnitTest.java b/libraries-testing/src/test/java/com/baeldung/archunit/smurfs/SmurfsArchUnitTest.java new file mode 100644 index 0000000000..9724c2bcae --- /dev/null +++ b/libraries-testing/src/test/java/com/baeldung/archunit/smurfs/SmurfsArchUnitTest.java @@ -0,0 +1,76 @@ +package com.baeldung.archunit.smurfs; + + +import com.tngtech.archunit.core.domain.JavaClasses; +import com.tngtech.archunit.core.importer.ClassFileImporter; +import com.tngtech.archunit.lang.ArchRule; +import com.tngtech.archunit.library.Architectures.LayeredArchitecture; + +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes; +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; +import static com.tngtech.archunit.library.Architectures.layeredArchitecture; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class SmurfsArchUnitTest { + + @Test + public void givenPresentationLayerClasses_thenWrongCheckFails() { + JavaClasses jc = new ClassFileImporter().importPackages("com.baeldung.archunit.smurfs"); + + ArchRule r1 = classes() + .that() + .resideInAPackage("..presentation..") + .should().onlyDependOnClassesThat() + .resideInAPackage("..service.."); + + assertThrows(AssertionError.class, ()-> r1.check(jc)) ; + } + + + @Test + public void givenPresentationLayerClasses_thenCheckWithFrameworkDependenciesSuccess() { + JavaClasses jc = new ClassFileImporter().importPackages("com.baeldung.archunit.smurfs"); + + ArchRule r1 = classes() + .that() + .resideInAPackage("..presentation..") + .should().onlyDependOnClassesThat() + .resideInAnyPackage("..service..", "java..", "javax..", "org.springframework.."); + + r1.check(jc); + } + + @Test + public void givenPresentationLayerClasses_thenNoPersistenceLayerAccess() { + JavaClasses jc = new ClassFileImporter().importPackages("com.baeldung.archunit.smurfs"); + + ArchRule r1 = noClasses() + .that() + .resideInAPackage("..presentation..") + .should().dependOnClassesThat() + .resideInAPackage("..persistence.."); + + r1.check(jc); + } + + @Test + public void givenApplicationClasses_thenNoLayerViolationsShouldExist() { + + JavaClasses jc = new ClassFileImporter().importPackages("com.baeldung.archunit.smurfs"); + + LayeredArchitecture arch = layeredArchitecture() + // Define layers + .layer("Presentation").definedBy("..presentation..") + .layer("Service").definedBy("..service..") + .layer("Persistence").definedBy("..persistence..") + // Add constraints + .whereLayer("Presentation").mayNotBeAccessedByAnyLayer() + .whereLayer("Service").mayOnlyBeAccessedByLayers("Presentation") + .whereLayer("Persistence").mayOnlyBeAccessedByLayers("Service"); + + arch.check(jc); + } +}