All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.jexxa.jexxatest.architecture.PortsAndAdapters Maven / Gradle / Ivy

There is a newer version: 8.1.4
Show newest version
package io.jexxa.jexxatest.architecture;


import com.tngtech.archunit.core.importer.ImportOption;
import com.tngtech.archunit.library.Architectures;
import io.jexxa.addend.applicationcore.Aggregate;
import io.jexxa.addend.applicationcore.Repository;

import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
import static com.tngtech.archunit.library.Architectures.onionArchitecture;

/**
 * These tests validate the access direction of an onion architecture which is as follows:
 *
 * @startuml
 *
 * package "DrivingAdapter " #DDDDDD {
 *    [DrivingAdapter] #Implementation
 *  }
 * package ApplicationCore  #DDDDDD {
 *   [ApplicationService] #lightgreen
 *   [DomainService]      #lightgreen
 *   [Domain]             #lightgreen
 * }
 * package "DrivenAdapter "  #DDDDDD {
 *     [DrivenAdapter] #Implementation
 *  }
 * [DrivingAdapter] -r--> [ApplicationService] : uses
 * [DrivingAdapter] -r--> [DomainService] : uses
 * [ApplicationService] -down-> [DomainService] : uses
 * [ApplicationService] -down-> [Domain] : uses
 * [DomainService] -r-> [Domain] : uses
 * [DrivenAdapter] .u..> [Domain]
 * [DrivenAdapter] .u..> [DomainService] : implements
 *
 * @enduml
 * ....
 */
public class PortsAndAdapters extends ProjectContent {

    private final Architectures.OnionArchitecture onionArchitecture;
    @SuppressWarnings("unused")
    PortsAndAdapters(Class project)
    {
        this(project, ImportOption.Predefined.DO_NOT_INCLUDE_TESTS);
    }

    protected PortsAndAdapters(Class project, ImportOption importOption)
    {
        super(project, importOption);
        this.onionArchitecture = onionArchitecture()
                .domainModels(project().getPackage().getName() + ".domain..")
                .domainServices(project().getPackage().getName() +".domainservice..")
                .applicationServices(project().getPackage().getName() + ".applicationservice..");

        this.onionArchitecture.allowEmptyShould(true);
    }

    public PortsAndAdapters addDrivenAdapterPackage(String drivenAdapterPackage)
    {
        onionArchitecture.adapter("drivenAdapter." + drivenAdapterPackage, project().getPackageName() + "." + "infrastructure.drivenadapter." + drivenAdapterPackage + "..");
        return this;
    }

    public PortsAndAdapters addDrivingAdapterPackage(String drivingAdapterPackage)
    {
        onionArchitecture.adapter("drivingAdapter." + drivingAdapterPackage, project().getPackageName() + ".infrastructure.drivingadapter." + drivingAdapterPackage + "..");
        return this;
    }

    @Override
    public void validate()
    {
        validatePortsAndAdapters();
        validateDrivingAdapterAccess();
    }

    private void validatePortsAndAdapters()
    {
        onionArchitecture.check(importedClasses());
    }

    private void validateDrivingAdapterAccess()
    {
        //Don't access a repository or aggregate directly from a driving adapter
        var drivingAdapter = noClasses().that()
                .resideInAnyPackage(project().getPackageName() + ".infrastructure.drivingadapter..").should()
                .dependOnClassesThat().areAnnotatedWith(Aggregate.class).orShould()
                .dependOnClassesThat().areAnnotatedWith(Repository.class)
                .allowEmptyShould(true);
        drivingAdapter.check(importedClasses());
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy