diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 87e800988..ce35b12b0 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -14,10 +14,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: - java-version: '11' + java-version: '17' distribution: 'temurin' cache: maven server-id: github # Value of the distributionManagement/repository/id field of the pom.xml diff --git a/pom.xml b/pom.xml index 8687c84bc..6c618f410 100644 --- a/pom.xml +++ b/pom.xml @@ -8,8 +8,8 @@ org.springframework.boot spring-boot-starter-parent - 2.0.9.RELEASE - + 3.3.4 + This application shows a few key concepts of @@ -78,7 +78,7 @@ - 11 + 17 5.9.1 @@ -124,22 +124,12 @@ commons-io commons-io - 2.11.0 + 2.17.0 org.hsqldb hsqldb - - javax.servlet - javax.servlet-api - provided - 4.0.1 - - - javax.validation - validation-api - org.apache.activemq activemq-spring @@ -148,26 +138,26 @@ org.apache.activemq activemq-broker + + - org.apache.xbean - xbean-spring - 4.23 + org.projectlombok + lombok - - jakarta.xml.bind - jakarta.xml.bind-api - 2.3.3 + + + + org.springframework.boot + spring-boot-starter-actuator - - com.sun.xml.bind - jaxb-impl - 2.3.3 - runtime + + io.micrometer + micrometer-tracing-bridge-brave - - org.javassist - javassist - 3.30.2-GA + + net.ttddyy.observation + datasource-micrometer-spring-boot + 1.0.5 @@ -192,25 +182,21 @@ org.junit.jupiter junit-jupiter - 5.10.2 test org.mockito mockito-core - 5.3.1 test org.mockito mockito-junit-jupiter - 5.3.1 test net.bytebuddy byte-buddy - 1.14.4 org.assertj @@ -226,11 +212,12 @@ org.seleniumhq.selenium htmlunit-driver - - - - - + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.5.0 + diff --git a/src/main/java/com/pathfinder/internal/GraphTraversalServiceImpl.java b/src/main/java/com/pathfinder/internal/GraphTraversalServiceImpl.java index 4c0964f3b..dbdc866a7 100644 --- a/src/main/java/com/pathfinder/internal/GraphTraversalServiceImpl.java +++ b/src/main/java/com/pathfinder/internal/GraphTraversalServiceImpl.java @@ -3,6 +3,7 @@ import com.pathfinder.api.GraphTraversalService; import com.pathfinder.api.TransitEdge; import com.pathfinder.api.TransitPath; + import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.*; diff --git a/src/main/java/se/citerus/dddsample/application/util/DateUtils.java b/src/main/java/se/citerus/dddsample/application/util/DateUtils.java index 728dd8083..0ec4e5e26 100644 --- a/src/main/java/se/citerus/dddsample/application/util/DateUtils.java +++ b/src/main/java/se/citerus/dddsample/application/util/DateUtils.java @@ -1,7 +1,5 @@ package se.citerus.dddsample.application.util; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.time.Instant; import java.time.format.DateTimeParseException; diff --git a/src/main/java/se/citerus/dddsample/config/DDDSampleApplicationContext.java b/src/main/java/se/citerus/dddsample/config/DDDSampleApplicationContext.java index 6be5d650a..c676ea92d 100644 --- a/src/main/java/se/citerus/dddsample/config/DDDSampleApplicationContext.java +++ b/src/main/java/se/citerus/dddsample/config/DDDSampleApplicationContext.java @@ -1,6 +1,7 @@ package se.citerus.dddsample.config; import com.pathfinder.api.GraphTraversalService; +import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -25,35 +26,28 @@ import se.citerus.dddsample.infrastructure.sampledata.SampleDataGenerator; import se.citerus.dddsample.interfaces.InterfacesApplicationContext; -import javax.persistence.EntityManager; @Configuration @Import({InterfacesApplicationContext.class, InfrastructureMessagingJmsConfig.class}) public class DDDSampleApplicationContext { @Autowired - CargoRepository cargoRepository; + private CargoRepository cargoRepository; @Autowired - LocationRepository locationRepository; + private VoyageRepository voyageRepository; @Autowired - VoyageRepository voyageRepository; + private LocationRepository locationRepository; @Autowired - GraphTraversalService graphTraversalService; + private HandlingEventRepository handlingEventRepository; @Autowired - RoutingService routingService; + private GraphTraversalService graphTraversalService; @Autowired - HandlingEventFactory handlingEventFactory; - - @Autowired - HandlingEventRepository handlingEventRepository; - - @Autowired - ApplicationEvents applicationEvents; + private ApplicationEvents applicationEvents; @Bean public CargoFactory cargoFactory() { @@ -61,7 +55,7 @@ public CargoFactory cargoFactory() { } @Bean - public BookingService bookingService(CargoFactory cargoFactory) { + public BookingService bookingService(CargoFactory cargoFactory,RoutingService routingService) { return new BookingServiceImpl(cargoRepository, locationRepository, routingService, cargoFactory); } @@ -71,7 +65,7 @@ public CargoInspectionService cargoInspectionService() { } @Bean - public HandlingEventService handlingEventService() { + public HandlingEventService handlingEventService(HandlingEventFactory handlingEventFactory) { return new HandlingEventServiceImpl(handlingEventRepository, applicationEvents, handlingEventFactory); } @@ -86,16 +80,15 @@ public RoutingService routingService() { } @Bean - public SampleDataGenerator sampleDataGenerator(CargoRepository cargoRepository, VoyageRepository voyageRepository, - LocationRepository locationRepository, HandlingEventRepository handlingEventRepository, - PlatformTransactionManager platformTransactionManager, EntityManager entityManager) { - SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(cargoRepository, voyageRepository, locationRepository, handlingEventRepository, platformTransactionManager); - try { - sampleDataGenerator.generate(); // TODO investigate if this can be called with initMethod in the annotation - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - return sampleDataGenerator; + public SampleDataGenerator sampleDataGenerator(CargoRepository cargoRepository, + VoyageRepository voyageRepository, + LocationRepository locationRepository, + HandlingEventRepository handlingEventRepository, + PlatformTransactionManager platformTransactionManager) { + return new SampleDataGenerator(cargoRepository, + voyageRepository, + locationRepository, + handlingEventRepository, + platformTransactionManager); } } diff --git a/src/main/java/se/citerus/dddsample/domain/model/cargo/Cargo.java b/src/main/java/se/citerus/dddsample/domain/model/cargo/Cargo.java index c6be2ed7c..9b119b3f9 100644 --- a/src/main/java/se/citerus/dddsample/domain/model/cargo/Cargo.java +++ b/src/main/java/se/citerus/dddsample/domain/model/cargo/Cargo.java @@ -1,11 +1,14 @@ package se.citerus.dddsample.domain.model.cargo; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.Setter; import org.apache.commons.lang3.Validate; import se.citerus.dddsample.domain.model.handling.HandlingHistory; import se.citerus.dddsample.domain.model.location.Location; -import se.citerus.dddsample.domain.shared.Entity; +import se.citerus.dddsample.domain.shared.DomainEntity; -import javax.persistence.*; import java.util.List; /** @@ -44,9 +47,11 @@ * in port etc), are captured in this aggregate. * */ -@javax.persistence.Entity(name = "Cargo") +@Entity(name = "Cargo") @Table(name = "Cargo") -public class Cargo implements Entity { +@Setter(AccessLevel.PROTECTED) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Cargo implements DomainEntity { @Id @GeneratedValue(strategy = GenerationType.AUTO) @@ -217,8 +222,6 @@ public String toString() { return trackingId; } - Cargo() { - // Needed by Hibernate - } + } diff --git a/src/main/java/se/citerus/dddsample/domain/model/cargo/Delivery.java b/src/main/java/se/citerus/dddsample/domain/model/cargo/Delivery.java index b60c10068..b24b05be2 100644 --- a/src/main/java/se/citerus/dddsample/domain/model/cargo/Delivery.java +++ b/src/main/java/se/citerus/dddsample/domain/model/cargo/Delivery.java @@ -1,5 +1,8 @@ package se.citerus.dddsample.domain.model.cargo; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; @@ -9,7 +12,6 @@ import se.citerus.dddsample.domain.model.voyage.Voyage; import se.citerus.dddsample.domain.shared.ValueObject; -import javax.persistence.*; import java.time.Instant; import java.util.Iterator; import java.util.Objects; @@ -23,6 +25,7 @@ * */ @Embeddable +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Delivery implements ValueObject { @Column @@ -354,7 +357,4 @@ public int hashCode() { toHashCode(); } - Delivery() { - // Needed by Hibernate - } } diff --git a/src/main/java/se/citerus/dddsample/domain/model/cargo/HandlingActivity.java b/src/main/java/se/citerus/dddsample/domain/model/cargo/HandlingActivity.java index 2c431514a..2d868f851 100644 --- a/src/main/java/se/citerus/dddsample/domain/model/cargo/HandlingActivity.java +++ b/src/main/java/se/citerus/dddsample/domain/model/cargo/HandlingActivity.java @@ -1,5 +1,8 @@ package se.citerus.dddsample.domain.model.cargo; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; @@ -8,8 +11,6 @@ import se.citerus.dddsample.domain.model.voyage.Voyage; import se.citerus.dddsample.domain.shared.ValueObject; -import javax.persistence.*; - /** * A handling activity represents how and where a cargo can be handled, * and can be used to express predictions about what is expected to @@ -17,6 +18,7 @@ * */ @Embeddable +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class HandlingActivity implements ValueObject { // TODO make HandlingActivity a part of HandlingEvent too? There is some overlap. @@ -92,8 +94,4 @@ public boolean equals(final Object obj) { return sameValueAs(other); } - HandlingActivity() { - // Needed by Hibernate - } - } diff --git a/src/main/java/se/citerus/dddsample/domain/model/cargo/Leg.java b/src/main/java/se/citerus/dddsample/domain/model/cargo/Leg.java index 8593064f1..b0d0bb411 100644 --- a/src/main/java/se/citerus/dddsample/domain/model/cargo/Leg.java +++ b/src/main/java/se/citerus/dddsample/domain/model/cargo/Leg.java @@ -1,5 +1,8 @@ package se.citerus.dddsample.domain.model.cargo; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; @@ -7,7 +10,6 @@ import se.citerus.dddsample.domain.model.voyage.Voyage; import se.citerus.dddsample.domain.shared.ValueObject; -import javax.persistence.*; import java.time.Instant; /** @@ -15,6 +17,7 @@ */ @Entity(name = "Leg") @Table(name = "Leg") +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Leg implements ValueObject { @Id @@ -101,7 +104,4 @@ public int hashCode() { toHashCode(); } - Leg() { - // Needed by Hibernate - } } diff --git a/src/main/java/se/citerus/dddsample/domain/model/cargo/RouteSpecification.java b/src/main/java/se/citerus/dddsample/domain/model/cargo/RouteSpecification.java index aff067eac..8df45e710 100644 --- a/src/main/java/se/citerus/dddsample/domain/model/cargo/RouteSpecification.java +++ b/src/main/java/se/citerus/dddsample/domain/model/cargo/RouteSpecification.java @@ -1,5 +1,11 @@ package se.citerus.dddsample.domain.model.cargo; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; @@ -7,10 +13,6 @@ import se.citerus.dddsample.domain.shared.AbstractSpecification; import se.citerus.dddsample.domain.shared.ValueObject; -import javax.persistence.Column; -import javax.persistence.Embeddable; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; import java.time.Instant; /** @@ -19,6 +21,7 @@ * */ @Embeddable +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class RouteSpecification extends AbstractSpecification implements ValueObject { @ManyToOne() @@ -105,8 +108,4 @@ public int hashCode() { toHashCode(); } - RouteSpecification() { - // Needed by Hibernate - } - } diff --git a/src/main/java/se/citerus/dddsample/domain/model/handling/HandlingEvent.java b/src/main/java/se/citerus/dddsample/domain/model/handling/HandlingEvent.java index d20f4369f..32af72bff 100644 --- a/src/main/java/se/citerus/dddsample/domain/model/handling/HandlingEvent.java +++ b/src/main/java/se/citerus/dddsample/domain/model/handling/HandlingEvent.java @@ -1,5 +1,8 @@ package se.citerus.dddsample.domain.model.handling; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; @@ -9,7 +12,6 @@ import se.citerus.dddsample.domain.shared.DomainEvent; import se.citerus.dddsample.domain.shared.ValueObject; -import javax.persistence.*; import java.time.Instant; import java.util.Objects; @@ -31,6 +33,7 @@ */ @Entity(name = "HandlingEvent") @Table(name = "HandlingEvent") +@NoArgsConstructor(access = AccessLevel.PROTECTED) public final class HandlingEvent implements DomainEvent { @Id @@ -237,7 +240,5 @@ public String toString() { return builder.toString(); } - HandlingEvent() { - // Needed by Hibernate - } + } diff --git a/src/main/java/se/citerus/dddsample/domain/model/handling/HandlingHistory.java b/src/main/java/se/citerus/dddsample/domain/model/handling/HandlingHistory.java index 43c95d6d2..8794c58bc 100644 --- a/src/main/java/se/citerus/dddsample/domain/model/handling/HandlingHistory.java +++ b/src/main/java/se/citerus/dddsample/domain/model/handling/HandlingHistory.java @@ -31,7 +31,7 @@ public List distinctEventsByCompletionTime() { final List ordered = new ArrayList<>( new HashSet<>(handlingEvents) ); - sort(ordered, BY_COMPLETION_TIME_COMPARATOR); + ordered.sort(BY_COMPLETION_TIME_COMPARATOR); return Collections.unmodifiableList(ordered); } diff --git a/src/main/java/se/citerus/dddsample/domain/model/location/Location.java b/src/main/java/se/citerus/dddsample/domain/model/location/Location.java index 7acce8a0c..bd8ec3a3b 100644 --- a/src/main/java/se/citerus/dddsample/domain/model/location/Location.java +++ b/src/main/java/se/citerus/dddsample/domain/model/location/Location.java @@ -1,9 +1,11 @@ package se.citerus.dddsample.domain.model.location; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.Setter; import org.apache.commons.lang3.Validate; -import se.citerus.dddsample.domain.shared.Entity; - -import javax.persistence.*; +import se.citerus.dddsample.domain.shared.DomainEntity; /** * A location is our model is stops on a journey, such as cargo @@ -11,9 +13,11 @@ * It is uniquely identified by a UN Locode. * */ -@javax.persistence.Entity(name = "Location") +@Entity(name = "Location") @Table(name = "Location") -public final class Location implements Entity { +@Setter(AccessLevel.PROTECTED) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public final class Location implements DomainEntity { @Id @GeneratedValue(strategy = GenerationType.AUTO) @@ -79,11 +83,10 @@ public boolean equals(final Object object) { if (this == object) { return true; } - if (!(object instanceof Location)) { + if (!(object instanceof Location other)) { return false; } - Location other = (Location) object; - return sameIdentityAs(other); + return sameIdentityAs(other); } @Override @@ -104,11 +107,4 @@ public String toString() { return name + " [" + unlocode + "]"; } - Location() { - // Needed by Hibernate - } - - public void setId(long id) { - this.id = id; - } } diff --git a/src/main/java/se/citerus/dddsample/domain/model/voyage/CarrierMovement.java b/src/main/java/se/citerus/dddsample/domain/model/voyage/CarrierMovement.java index 686f02eb5..bb941ce09 100644 --- a/src/main/java/se/citerus/dddsample/domain/model/voyage/CarrierMovement.java +++ b/src/main/java/se/citerus/dddsample/domain/model/voyage/CarrierMovement.java @@ -1,12 +1,12 @@ package se.citerus.dddsample.domain.model.voyage; +import jakarta.persistence.*; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import se.citerus.dddsample.domain.model.location.Location; import se.citerus.dddsample.domain.shared.ValueObject; -import javax.persistence.*; import java.time.Instant; diff --git a/src/main/java/se/citerus/dddsample/domain/model/voyage/Voyage.java b/src/main/java/se/citerus/dddsample/domain/model/voyage/Voyage.java index e94512ef4..5bd63531b 100644 --- a/src/main/java/se/citerus/dddsample/domain/model/voyage/Voyage.java +++ b/src/main/java/se/citerus/dddsample/domain/model/voyage/Voyage.java @@ -1,10 +1,13 @@ package se.citerus.dddsample.domain.model.voyage; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.Setter; import org.apache.commons.lang3.Validate; import se.citerus.dddsample.domain.model.location.Location; -import se.citerus.dddsample.domain.shared.Entity; +import se.citerus.dddsample.domain.shared.DomainEntity; -import javax.persistence.*; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -12,9 +15,11 @@ /** * A Voyage. */ -@javax.persistence.Entity(name = "Voyage") +@Entity(name = "Voyage") @Table(name = "Voyage") -public class Voyage implements Entity { +@Setter(AccessLevel.PROTECTED) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Voyage implements DomainEntity { @Id @GeneratedValue(strategy = GenerationType.AUTO) @@ -28,11 +33,10 @@ public class Voyage implements Entity { public List carrierMovements; // Null object pattern - public static final Voyage NONE = new Voyage( - new VoyageNumber(""), Schedule.EMPTY - ); + @Transient + public static final Voyage NONE = new Voyage(new VoyageNumber(""), Schedule.EMPTY); - public Voyage(final VoyageNumber voyageNumber, final Schedule schedule) { + public Voyage(final VoyageNumber voyageNumber, final Schedule schedule) { Validate.notNull(voyageNumber, "Voyage number is required"); Validate.notNull(schedule, "Schedule is required"); @@ -80,13 +84,10 @@ public String toString() { return "Voyage " + voyageNumber; } - Voyage() { - // Needed by Hibernate - } /** * Builder pattern is used for incremental construction - * of a Voyage aggregate. This serves as an aggregate factory. + * of a Voyage aggregate. This serves as an aggregate factory. */ public static final class Builder { diff --git a/src/main/java/se/citerus/dddsample/domain/shared/Entity.java b/src/main/java/se/citerus/dddsample/domain/shared/DomainEntity.java similarity index 90% rename from src/main/java/se/citerus/dddsample/domain/shared/Entity.java rename to src/main/java/se/citerus/dddsample/domain/shared/DomainEntity.java index a137dae31..63827ba9a 100644 --- a/src/main/java/se/citerus/dddsample/domain/shared/Entity.java +++ b/src/main/java/se/citerus/dddsample/domain/shared/DomainEntity.java @@ -4,7 +4,7 @@ * An entity, as explained in the DDD book. * */ -public interface Entity { +public interface DomainEntity { /** * Entities compare by identity, not by attributes. diff --git a/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/CargoHandledConsumer.java b/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/CargoHandledConsumer.java index 2123059a2..dd02a5741 100644 --- a/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/CargoHandledConsumer.java +++ b/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/CargoHandledConsumer.java @@ -1,13 +1,13 @@ package se.citerus.dddsample.infrastructure.messaging.jms; +import jakarta.jms.Message; +import jakarta.jms.MessageListener; +import jakarta.jms.TextMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import se.citerus.dddsample.application.CargoInspectionService; import se.citerus.dddsample.domain.model.cargo.TrackingId; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.TextMessage; import java.lang.invoke.MethodHandles; /** diff --git a/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/HandlingEventRegistrationAttemptConsumer.java b/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/HandlingEventRegistrationAttemptConsumer.java index e5cf01f33..31ef40351 100644 --- a/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/HandlingEventRegistrationAttemptConsumer.java +++ b/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/HandlingEventRegistrationAttemptConsumer.java @@ -1,19 +1,19 @@ package se.citerus.dddsample.infrastructure.messaging.jms; +import jakarta.jms.Message; +import jakarta.jms.MessageListener; +import jakarta.jms.ObjectMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import se.citerus.dddsample.application.HandlingEventService; import se.citerus.dddsample.interfaces.handling.HandlingEventRegistrationAttempt; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.ObjectMessage; import java.lang.invoke.MethodHandles; /** * Consumes handling event registration attempt messages and delegates to * proper registration. - * + * */ public class HandlingEventRegistrationAttemptConsumer implements MessageListener { diff --git a/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/InfrastructureMessagingJmsConfig.java b/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/InfrastructureMessagingJmsConfig.java index 03c22b392..f9fcc6b6d 100644 --- a/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/InfrastructureMessagingJmsConfig.java +++ b/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/InfrastructureMessagingJmsConfig.java @@ -1,5 +1,6 @@ package se.citerus.dddsample.infrastructure.messaging.jms; +import jakarta.jms.*; import org.apache.activemq.ActiveMQConnection; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.command.ActiveMQDestination; @@ -15,7 +16,6 @@ import se.citerus.dddsample.application.CargoInspectionService; import se.citerus.dddsample.application.HandlingEventService; -import javax.jms.*; import java.util.List; @EnableJms @@ -60,11 +60,6 @@ public MessageConsumer rejectedRegistrationAttemptsConsumer(Session session, @Qu return consumer; } - @Bean - public HandlingEventRegistrationAttemptConsumer handlingEventRegistrationAttemptConsumer(HandlingEventService handlingEventService) { - return new HandlingEventRegistrationAttemptConsumer(handlingEventService); - } - @Bean("cargoHandledQueue") public Destination cargoHandledQueue() throws Exception { return createQueue("CargoHandledQueue"); @@ -119,7 +114,7 @@ public Connection connection(ConnectionFactory connectionFactory) throws JMSExce @Bean public Session session(Connection connection) throws JMSException { - return ((ActiveMQConnection) connection).createSession(false, Session.AUTO_ACKNOWLEDGE); + return connection.createSession(false, Session.AUTO_ACKNOWLEDGE); } @Bean diff --git a/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/JmsApplicationEventsImpl.java b/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/JmsApplicationEventsImpl.java index 727b2ea8e..85480a496 100644 --- a/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/JmsApplicationEventsImpl.java +++ b/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/JmsApplicationEventsImpl.java @@ -1,5 +1,6 @@ package se.citerus.dddsample.infrastructure.messaging.jms; +import jakarta.jms.Destination; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.jms.core.JmsOperations; @@ -8,7 +9,6 @@ import se.citerus.dddsample.domain.model.handling.HandlingEvent; import se.citerus.dddsample.interfaces.handling.HandlingEventRegistrationAttempt; -import javax.jms.Destination; import java.lang.invoke.MethodHandles; /** diff --git a/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/SimpleLoggingConsumer.java b/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/SimpleLoggingConsumer.java index e7504122f..30f9d1a66 100644 --- a/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/SimpleLoggingConsumer.java +++ b/src/main/java/se/citerus/dddsample/infrastructure/messaging/jms/SimpleLoggingConsumer.java @@ -1,10 +1,10 @@ package se.citerus.dddsample.infrastructure.messaging.jms; +import jakarta.jms.Message; +import jakarta.jms.MessageListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.jms.Message; -import javax.jms.MessageListener; import java.lang.invoke.MethodHandles; public class SimpleLoggingConsumer implements MessageListener { diff --git a/src/main/java/se/citerus/dddsample/infrastructure/persistence/jpa/HandlingEventRepositoryJPA.java b/src/main/java/se/citerus/dddsample/infrastructure/persistence/jpa/HandlingEventRepositoryJPA.java index 9d0b17f0a..b4827ce69 100644 --- a/src/main/java/se/citerus/dddsample/infrastructure/persistence/jpa/HandlingEventRepositoryJPA.java +++ b/src/main/java/se/citerus/dddsample/infrastructure/persistence/jpa/HandlingEventRepositoryJPA.java @@ -23,7 +23,7 @@ default HandlingHistory lookupHandlingHistoryOfCargo(final TrackingId trackingId return new HandlingHistory(getHandlingHistoryOfCargo(trackingId.idString())); } - @Query("select he from HandlingEvent he where he.cargo.trackingId = :trackingId and he.location != NULL") + @Query("select he from HandlingEvent he where he.cargo.trackingId = :trackingId and he.location is not NULL") List getHandlingHistoryOfCargo(String trackingId); } diff --git a/src/main/java/se/citerus/dddsample/infrastructure/routing/ExternalRoutingService.java b/src/main/java/se/citerus/dddsample/infrastructure/routing/ExternalRoutingService.java index 84555473d..4af9c6718 100644 --- a/src/main/java/se/citerus/dddsample/infrastructure/routing/ExternalRoutingService.java +++ b/src/main/java/se/citerus/dddsample/infrastructure/routing/ExternalRoutingService.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.Properties; import java.util.stream.Collectors; -import java.util.stream.Collectors; /** * Our end of the routing service. This is basically a data model diff --git a/src/main/java/se/citerus/dddsample/infrastructure/sampledata/SampleDataGenerator.java b/src/main/java/se/citerus/dddsample/infrastructure/sampledata/SampleDataGenerator.java index 9d005af48..375d79e9b 100644 --- a/src/main/java/se/citerus/dddsample/infrastructure/sampledata/SampleDataGenerator.java +++ b/src/main/java/se/citerus/dddsample/infrastructure/sampledata/SampleDataGenerator.java @@ -1,6 +1,8 @@ package se.citerus.dddsample.infrastructure.sampledata; -import org.springframework.lang.NonNull; +import jakarta.annotation.PostConstruct; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; @@ -12,15 +14,12 @@ import se.citerus.dddsample.domain.model.voyage.VoyageRepository; import java.sql.Timestamp; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDate; import java.time.ZoneOffset; import java.time.format.DateTimeParseException; import java.util.List; -import static java.util.Objects.requireNonNull; import static se.citerus.dddsample.application.util.DateUtils.toDate; import static se.citerus.dddsample.infrastructure.sampledata.SampleLocations.*; import static se.citerus.dddsample.infrastructure.sampledata.SampleVoyages.*; @@ -28,7 +27,8 @@ /** * Provides sample data. */ -public class SampleDataGenerator { +@Slf4j +public class SampleDataGenerator { private static final Timestamp base = getBaseTimeStamp(); @@ -43,15 +43,16 @@ public SampleDataGenerator(@NonNull CargoRepository cargoRepository, @NonNull LocationRepository locationRepository, @NonNull HandlingEventRepository handlingEventRepository, @NonNull PlatformTransactionManager transactionManager) { - // TODO can the requireNonNull calls be replaced by annotations? - this.cargoRepository = requireNonNull(cargoRepository); - this.voyageRepository = requireNonNull(voyageRepository); - this.locationRepository = requireNonNull(locationRepository); - this.handlingEventRepository = requireNonNull(handlingEventRepository); - this.transactionManager = requireNonNull(transactionManager); + this.cargoRepository =cargoRepository; + this.voyageRepository = voyageRepository; + this.locationRepository = locationRepository; + this.handlingEventRepository = handlingEventRepository; + this.transactionManager = transactionManager; } - public void generate() { + + @PostConstruct + protected void generate() { TransactionTemplate tt = new TransactionTemplate(transactionManager); HandlingEventFactory handlingEventFactory = new HandlingEventFactory( @@ -62,7 +63,7 @@ public void generate() { } public void loadHibernateData(TransactionTemplate tt, final HandlingEventFactory handlingEventFactory) { - System.out.println("*** Loading Hibernate data ***"); + log.info("*** Loading Hibernate data ***"); tt.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { diff --git a/src/main/java/se/citerus/dddsample/infrastructure/sampledata/SampleVoyages.java b/src/main/java/se/citerus/dddsample/infrastructure/sampledata/SampleVoyages.java index f2b0b3ee5..296d497de 100644 --- a/src/main/java/se/citerus/dddsample/infrastructure/sampledata/SampleVoyages.java +++ b/src/main/java/se/citerus/dddsample/infrastructure/sampledata/SampleVoyages.java @@ -8,7 +8,10 @@ import java.lang.reflect.Field; import java.time.Instant; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import static se.citerus.dddsample.application.util.DateUtils.toDate; import static se.citerus.dddsample.infrastructure.sampledata.SampleLocations.*; diff --git a/src/main/java/se/citerus/dddsample/interfaces/InterfacesApplicationContext.java b/src/main/java/se/citerus/dddsample/interfaces/InterfacesApplicationContext.java index 4cda84149..1f0661bf7 100644 --- a/src/main/java/se/citerus/dddsample/interfaces/InterfacesApplicationContext.java +++ b/src/main/java/se/citerus/dddsample/interfaces/InterfacesApplicationContext.java @@ -1,5 +1,6 @@ package se.citerus.dddsample.interfaces; +import jakarta.persistence.EntityManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -28,7 +29,6 @@ import se.citerus.dddsample.interfaces.tracking.TrackCommandValidator; import se.citerus.dddsample.interfaces.tracking.ws.CargoTrackingRestService; -import javax.persistence.EntityManager; import java.io.File; import java.lang.invoke.MethodHandles; import java.util.Locale; @@ -61,8 +61,14 @@ public FixedLocaleResolver localeResolver() { } @Bean - public CargoTrackingController cargoTrackingController(MessageSource messageSource, CargoRepository cargoRepository, HandlingEventRepository handlingEventRepository) { - return new CargoTrackingController(cargoRepository, handlingEventRepository, messageSource); + public CargoTrackingController cargoTrackingController(MessageSource messageSource, + CargoRepository cargoRepository, + HandlingEventRepository handlingEventRepository, + TrackCommandValidator TrackCommandValidator) { + return new CargoTrackingController(cargoRepository, + handlingEventRepository, + messageSource, + TrackCommandValidator); } @Bean @@ -106,10 +112,10 @@ public ThreadPoolTaskScheduler myScheduler(@Nullable UploadDirectoryScanner scan return null; } ThreadPoolTaskScheduler threadPoolTaskScheduler - = new ThreadPoolTaskScheduler(); + = new ThreadPoolTaskScheduler(); threadPoolTaskScheduler.setPoolSize(10); threadPoolTaskScheduler.setThreadNamePrefix( - "ThreadPoolTaskScheduler"); + "ThreadPoolTaskScheduler"); threadPoolTaskScheduler.initialize(); threadPoolTaskScheduler.scheduleAtFixedRate(scanner, 5000); return threadPoolTaskScheduler; diff --git a/src/main/java/se/citerus/dddsample/interfaces/booking/facade/BookingServiceFacade.java b/src/main/java/se/citerus/dddsample/interfaces/booking/facade/BookingServiceFacade.java index 86b140c42..3783ce1e0 100644 --- a/src/main/java/se/citerus/dddsample/interfaces/booking/facade/BookingServiceFacade.java +++ b/src/main/java/se/citerus/dddsample/interfaces/booking/facade/BookingServiceFacade.java @@ -1,13 +1,13 @@ package se.citerus.dddsample.interfaces.booking.facade; -import java.rmi.RemoteException; -import java.time.Instant; -import java.util.List; - import se.citerus.dddsample.interfaces.booking.facade.dto.CargoRoutingDTO; import se.citerus.dddsample.interfaces.booking.facade.dto.LocationDTO; import se.citerus.dddsample.interfaces.booking.facade.dto.RouteCandidateDTO; +import java.rmi.RemoteException; +import java.time.Instant; +import java.util.List; + /** * This facade shields the domain layer - model, services, repositories - * from concerns about such things as the user interface. diff --git a/src/main/java/se/citerus/dddsample/interfaces/booking/web/CargoAdminController.java b/src/main/java/se/citerus/dddsample/interfaces/booking/web/CargoAdminController.java index 11e7b6454..c3387d468 100644 --- a/src/main/java/se/citerus/dddsample/interfaces/booking/web/CargoAdminController.java +++ b/src/main/java/se/citerus/dddsample/interfaces/booking/web/CargoAdminController.java @@ -1,5 +1,8 @@ package se.citerus.dddsample.interfaces.booking.web; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.propertyeditors.CustomDateEditor; import org.springframework.stereotype.Controller; import org.springframework.web.bind.ServletRequestDataBinder; @@ -12,8 +15,6 @@ import se.citerus.dddsample.interfaces.booking.facade.dto.LocationDTO; import se.citerus.dddsample.interfaces.booking.facade.dto.RouteCandidateDTO; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDate; @@ -39,7 +40,8 @@ @RequestMapping("/admin") public final class CargoAdminController { - private final BookingServiceFacade bookingServiceFacade; + @Autowired + private BookingServiceFacade bookingServiceFacade; public CargoAdminController(BookingServiceFacade bookingServiceFacade) { this.bookingServiceFacade = bookingServiceFacade; diff --git a/src/main/java/se/citerus/dddsample/interfaces/handling/HandlingEventRegistrationAttempt.java b/src/main/java/se/citerus/dddsample/interfaces/handling/HandlingEventRegistrationAttempt.java index ffaa4b7c3..56e47a589 100644 --- a/src/main/java/se/citerus/dddsample/interfaces/handling/HandlingEventRegistrationAttempt.java +++ b/src/main/java/se/citerus/dddsample/interfaces/handling/HandlingEventRegistrationAttempt.java @@ -1,5 +1,7 @@ package se.citerus.dddsample.interfaces.handling; +import lombok.Getter; +import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import se.citerus.dddsample.domain.model.cargo.TrackingId; @@ -13,60 +15,23 @@ /** * This is a simple transfer object for passing incoming handling event * registration attempts to proper the registration procedure. - * - * It is used as a message queue element. - * + *

+ * It is used as a message queue element. */ +@Getter +@RequiredArgsConstructor public final class HandlingEventRegistrationAttempt implements Serializable { - private final Instant registrationTime; - private final Instant completionTime; - private final TrackingId trackingId; - private final VoyageNumber voyageNumber; - private final HandlingEvent.Type type; - private final UnLocode unLocode; + private final Instant registrationTime; + private final Instant completionTime; + private final TrackingId trackingId; + private final VoyageNumber voyageNumber; + private final HandlingEvent.Type type; + private final UnLocode unLocode; - public HandlingEventRegistrationAttempt(final Instant registrationDate, - final Instant completionDate, - final TrackingId trackingId, - final VoyageNumber voyageNumber, - final HandlingEvent.Type type, - final UnLocode unLocode) { - this.registrationTime = registrationDate; - this.completionTime = completionDate; - this.trackingId = trackingId; - this.voyageNumber = voyageNumber; - this.type = type; - this.unLocode = unLocode; - } + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); + } - public Instant getCompletionTime() { - return completionTime; - } - - public TrackingId getTrackingId() { - return trackingId; - } - - public VoyageNumber getVoyageNumber() { - return voyageNumber; - } - - public HandlingEvent.Type getType() { - return type; - } - - public UnLocode getUnLocode() { - return unLocode; - } - - public Instant getRegistrationTime() { - return registrationTime; - } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); - } - } diff --git a/src/main/java/se/citerus/dddsample/interfaces/handling/HandlingReportParser.java b/src/main/java/se/citerus/dddsample/interfaces/handling/HandlingReportParser.java index 4d822d0fe..fca5187e4 100644 --- a/src/main/java/se/citerus/dddsample/interfaces/handling/HandlingReportParser.java +++ b/src/main/java/se/citerus/dddsample/interfaces/handling/HandlingReportParser.java @@ -7,11 +7,13 @@ import se.citerus.dddsample.domain.model.voyage.VoyageNumber; import se.citerus.dddsample.interfaces.handling.ws.HandlingReport; -import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.*; import java.time.format.DateTimeParseException; -import java.util.*; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.Optional; import static java.util.Collections.emptyList; import static java.util.stream.Collectors.toList; diff --git a/src/main/java/se/citerus/dddsample/interfaces/handling/file/UploadDirectoryScanner.java b/src/main/java/se/citerus/dddsample/interfaces/handling/file/UploadDirectoryScanner.java index b1f15d9c2..adc80e0d1 100644 --- a/src/main/java/se/citerus/dddsample/interfaces/handling/file/UploadDirectoryScanner.java +++ b/src/main/java/se/citerus/dddsample/interfaces/handling/file/UploadDirectoryScanner.java @@ -17,7 +17,10 @@ import java.nio.file.Files; import java.nio.file.StandardOpenOption; import java.time.Instant; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.TimerTask; import static se.citerus.dddsample.interfaces.handling.HandlingReportParser.*; diff --git a/src/main/java/se/citerus/dddsample/interfaces/handling/ws/HandlingReportServiceImpl.java b/src/main/java/se/citerus/dddsample/interfaces/handling/ws/HandlingReportServiceImpl.java index 025b3ea37..21a27ef1f 100644 --- a/src/main/java/se/citerus/dddsample/interfaces/handling/ws/HandlingReportServiceImpl.java +++ b/src/main/java/se/citerus/dddsample/interfaces/handling/ws/HandlingReportServiceImpl.java @@ -1,5 +1,6 @@ package se.citerus.dddsample.interfaces.handling.ws; +import jakarta.validation.Valid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.ResponseEntity; @@ -9,7 +10,6 @@ import se.citerus.dddsample.application.ApplicationEvents; import se.citerus.dddsample.interfaces.handling.HandlingEventRegistrationAttempt; -import javax.validation.Valid; import java.lang.invoke.MethodHandles; import java.util.List; diff --git a/src/main/java/se/citerus/dddsample/interfaces/tracking/CargoTrackingController.java b/src/main/java/se/citerus/dddsample/interfaces/tracking/CargoTrackingController.java index 4b051909d..3879e9115 100644 --- a/src/main/java/se/citerus/dddsample/interfaces/tracking/CargoTrackingController.java +++ b/src/main/java/se/citerus/dddsample/interfaces/tracking/CargoTrackingController.java @@ -1,5 +1,8 @@ package se.citerus.dddsample.interfaces.tracking; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; @@ -12,7 +15,6 @@ import se.citerus.dddsample.domain.model.handling.HandlingEvent; import se.citerus.dddsample.domain.model.handling.HandlingEventRepository; -import javax.servlet.http.HttpServletRequest; import java.util.List; import java.util.Locale; import java.util.Map; @@ -28,35 +30,32 @@ * helps us shield the domain model classes. *

* - * @eee se.citerus.dddsample.application.web.CargoTrackingViewAdapter + * @see CargoTrackingViewAdapter * @see se.citerus.dddsample.interfaces.booking.web.CargoAdminController */ @Controller @RequestMapping("/track") +@RequiredArgsConstructor public final class CargoTrackingController { - private CargoRepository cargoRepository; - private HandlingEventRepository handlingEventRepository; - private MessageSource messageSource; - - public CargoTrackingController(CargoRepository cargoRepository, HandlingEventRepository handlingEventRepository, MessageSource messageSource) { - this.cargoRepository = cargoRepository; - this.handlingEventRepository = handlingEventRepository; - this.messageSource = messageSource; - } + private final CargoRepository cargoRepository; + private final HandlingEventRepository handlingEventRepository; + private final MessageSource messageSource; + private final TrackCommandValidator trackCommandValidator; @RequestMapping(method = RequestMethod.GET) - public String get(final Map model) { - model.put("trackCommand", new TrackCommand()); // TODO why is this method adding a TrackCommand without id? + public String index(final Map model) { + // using the empty command to support the thymeleaf form `

` + model.put("trackCommand", new TrackCommand()); return "track"; } @RequestMapping(method = RequestMethod.POST) - protected String onSubmit(final HttpServletRequest request, - final TrackCommand command, - final Map model, - final BindingResult bindingResult) { - new TrackCommandValidator().validate(command, bindingResult); + private String onSubmit(final HttpServletRequest request, + final TrackCommand command, + final Map model, + final BindingResult bindingResult) { + trackCommandValidator.validate(command, bindingResult); final TrackingId trackingId = new TrackingId(command.getTrackingId()); final Cargo cargo = cargoRepository.find(trackingId); diff --git a/src/main/java/se/citerus/dddsample/interfaces/tracking/CargoTrackingViewAdapter.java b/src/main/java/se/citerus/dddsample/interfaces/tracking/CargoTrackingViewAdapter.java index 439c776da..04ff20a57 100644 --- a/src/main/java/se/citerus/dddsample/interfaces/tracking/CargoTrackingViewAdapter.java +++ b/src/main/java/se/citerus/dddsample/interfaces/tracking/CargoTrackingViewAdapter.java @@ -8,9 +8,7 @@ import se.citerus.dddsample.domain.model.location.Location; import se.citerus.dddsample.domain.model.voyage.Voyage; -import java.text.SimpleDateFormat; import java.time.Instant; -import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.*; diff --git a/src/main/java/se/citerus/dddsample/interfaces/tracking/TrackCommandValidator.java b/src/main/java/se/citerus/dddsample/interfaces/tracking/TrackCommandValidator.java index 2f6fbd07a..8f8d39ebd 100644 --- a/src/main/java/se/citerus/dddsample/interfaces/tracking/TrackCommandValidator.java +++ b/src/main/java/se/citerus/dddsample/interfaces/tracking/TrackCommandValidator.java @@ -1,5 +1,6 @@ package se.citerus.dddsample.interfaces.tracking; +import org.springframework.lang.NonNull; import org.springframework.validation.Errors; import org.springframework.validation.ValidationUtils; import org.springframework.validation.Validator; @@ -9,11 +10,11 @@ */ public final class TrackCommandValidator implements Validator { - public boolean supports(final Class clazz) { + public boolean supports(@NonNull final Class clazz) { return TrackCommand.class.isAssignableFrom(clazz); } - public void validate(final Object object, final Errors errors) { + public void validate(@NonNull final Object object,@NonNull final Errors errors) { ValidationUtils.rejectIfEmptyOrWhitespace(errors, "trackingId", "error.required", "Required"); } diff --git a/src/main/java/se/citerus/dddsample/interfaces/tracking/ws/CargoTrackingDTOConverter.java b/src/main/java/se/citerus/dddsample/interfaces/tracking/ws/CargoTrackingDTOConverter.java index 5d5063157..a102883d4 100644 --- a/src/main/java/se/citerus/dddsample/interfaces/tracking/ws/CargoTrackingDTOConverter.java +++ b/src/main/java/se/citerus/dddsample/interfaces/tracking/ws/CargoTrackingDTOConverter.java @@ -6,7 +6,6 @@ import se.citerus.dddsample.domain.model.cargo.HandlingActivity; import se.citerus.dddsample.domain.model.handling.HandlingEvent; -import java.text.SimpleDateFormat; import java.time.Instant; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; diff --git a/src/main/java/se/citerus/dddsample/interfaces/tracking/ws/CargoTrackingRestService.java b/src/main/java/se/citerus/dddsample/interfaces/tracking/ws/CargoTrackingRestService.java index 3e7d1012c..e75d4baf2 100644 --- a/src/main/java/se/citerus/dddsample/interfaces/tracking/ws/CargoTrackingRestService.java +++ b/src/main/java/se/citerus/dddsample/interfaces/tracking/ws/CargoTrackingRestService.java @@ -1,6 +1,6 @@ package se.citerus.dddsample.interfaces.tracking.ws; -import javassist.NotFoundException; +import jakarta.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.MessageSource; @@ -16,7 +16,6 @@ import se.citerus.dddsample.domain.model.handling.HandlingEvent; import se.citerus.dddsample.domain.model.handling.HandlingEventRepository; -import javax.servlet.http.HttpServletRequest; import java.lang.invoke.MethodHandles; import java.net.URI; import java.util.List; @@ -46,15 +45,13 @@ public ResponseEntity trackCargo(final HttpServletRequest requ TrackingId trkId = new TrackingId(trackingId); Cargo cargo = cargoRepository.find(trkId); if (cargo == null) { - throw new NotFoundException("No cargo found for trackingId"); + URI uri = new UriTemplate(request.getContextPath() + "/api/track/{trackingId}").expand(trackingId); + return ResponseEntity.notFound().location(uri).build(); } final List handlingEvents = handlingEventRepository.lookupHandlingHistoryOfCargo(trkId) .distinctEventsByCompletionTime(); return ResponseEntity.ok(CargoTrackingDTOConverter.convert(cargo, handlingEvents, messageSource, locale)); - } catch (NotFoundException e) { - URI uri = new UriTemplate(request.getContextPath() + "/api/track/{trackingId}").expand(trackingId); - return ResponseEntity.notFound().location(uri).build(); - } catch (Exception e) { + } catch (Exception e) { log.error("Unexpected error in trackCargo endpoint", e); return ResponseEntity.status(500).build(); } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index bbce666d4..2b55daa0e 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,13 +2,9 @@ server: servlet: context-path: /dddsample -cxf: - path: /ws - logging: level: - org.hibernate.SQL: info - net.sf.ehcache.config.ConfigurationFactory: error + jdbc: debug uploadDirectory: /tmp/upload parseFailureDirectory: /tmp/failed @@ -17,8 +13,15 @@ brokerUrl: "vm://localhost?broker.persistent=false&broker.useJmx=false" spring: dataSource: - db_name: dddsample - driver_class: org.hsqldb.jdbcDriver url: jdbc:hsqldb:mem:dddsample username: sa - password: "" \ No newline at end of file + password: "" + +jdbc: + datasource-proxy: + enabled: true + query: + logger-name: jdbc + enable-logging: true + multiline: false + include-parameter-values: true diff --git a/src/test/java/se/citerus/dddsample/acceptance/AbstractAcceptanceTest.java b/src/test/java/se/citerus/dddsample/acceptance/AbstractAcceptanceTest.java index 894425cc6..da7a91e47 100644 --- a/src/test/java/se/citerus/dddsample/acceptance/AbstractAcceptanceTest.java +++ b/src/test/java/se/citerus/dddsample/acceptance/AbstractAcceptanceTest.java @@ -6,7 +6,7 @@ import org.openqa.selenium.WebDriver; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDriverBuilder; import org.springframework.web.context.WebApplicationContext; diff --git a/src/test/java/se/citerus/dddsample/infrastructure/persistence/jpa/CargoRepositoryTest.java b/src/test/java/se/citerus/dddsample/infrastructure/persistence/jpa/CargoRepositoryTest.java index 214d40e61..f01c37128 100644 --- a/src/test/java/se/citerus/dddsample/infrastructure/persistence/jpa/CargoRepositoryTest.java +++ b/src/test/java/se/citerus/dddsample/infrastructure/persistence/jpa/CargoRepositoryTest.java @@ -1,5 +1,6 @@ package se.citerus.dddsample.infrastructure.persistence.jpa; +import jakarta.persistence.EntityManager; import org.assertj.core.groups.Tuple; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -19,11 +20,7 @@ import se.citerus.dddsample.domain.model.voyage.VoyageNumber; import se.citerus.dddsample.domain.model.voyage.VoyageRepository; -import javax.persistence.EntityManager; -import java.math.BigInteger; import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.List; @@ -80,11 +77,11 @@ public void testFindByCargoId() { List legs = cargo.itinerary().legs(); assertThat(legs).hasSize(3) - .extracting("voyage.voyageNumber", "loadLocation", "unloadLocation") - .containsExactly( - Tuple.tuple(null, HONGKONG, NEWYORK), - Tuple.tuple("0200T", NEWYORK, DALLAS), - Tuple.tuple("0300A", DALLAS, HELSINKI)); + .extracting("voyage.voyageNumber", "loadLocation", "unloadLocation") + .containsExactly( + Tuple.tuple(null, HONGKONG, NEWYORK), + Tuple.tuple("0200T", NEWYORK, DALLAS), + Tuple.tuple("0300A", DALLAS, HELSINKI)); } private void assertHandlingEvent(Cargo cargo, HandlingEvent event, HandlingEvent.Type expectedEventType, @@ -94,8 +91,8 @@ private void assertHandlingEvent(Cargo cargo, HandlingEvent event, HandlingEvent assertThat(event.completionTime()).isEqualTo(expectedCompletionTime); DateTimeFormatter formatter = DateTimeFormatter - .ofPattern("yyyy-MM-dd hh:mm") - .withZone(ZoneOffset.UTC); + .ofPattern("yyyy-MM-dd hh:mm") + .withZone(ZoneOffset.UTC); assertThat(formatter.format(event.registrationTime())).isEqualTo(formatter.format(expectedRegistrationTime)); assertThat(event.voyage().voyageNumber()).isEqualTo(voyage); @@ -119,17 +116,17 @@ public void testSave() { Voyage voyage = voyageRepository.find(NEW_YORK_TO_DALLAS.voyageNumber()); assertThat(voyage).isNotNull(); cargo.assignToRoute(new Itinerary(List.of( - new Leg( - voyage, - locationRepository.find(STOCKHOLM.unLocode()), - locationRepository.find(MELBOURNE.unLocode()), - Instant.now(), Instant.now()) + new Leg( + voyage, + locationRepository.find(STOCKHOLM.unLocode()), + locationRepository.find(MELBOURNE.unLocode()), + Instant.now(), Instant.now()) ))); flush(); Cargo result = entityManager.createQuery( - String.format("from Cargo c where c.trackingId = '%s'", trackingId.idString()), Cargo.class).getSingleResult(); + String.format("from Cargo c where c.trackingId = '%s'", trackingId.idString()), Cargo.class).getSingleResult(); assertThat(result.trackingId().idString()).isEqualTo("AAA"); assertThat(result.routeSpecification.origin.id).isEqualTo(origin.id); assertThat(result.routeSpecification.destination.id).isEqualTo(destination.id); @@ -181,7 +178,7 @@ private void flush() { entityManager.flush(); } - private int countLegsForCargo(long cargoId) { - return ((BigInteger) entityManager.createNativeQuery(String.format("select count(*) from Leg l where l.cargo_id = %d", cargoId)).getSingleResult()).intValue(); + private long countLegsForCargo(long cargoId) { + return (long) entityManager.createNativeQuery(String.format("select count(*) from Leg l where l.cargo_id = %d", cargoId)).getSingleResult(); } } \ No newline at end of file diff --git a/src/test/java/se/citerus/dddsample/infrastructure/persistence/jpa/HandlingEventRepositoryTest.java b/src/test/java/se/citerus/dddsample/infrastructure/persistence/jpa/HandlingEventRepositoryTest.java index d45ca0b13..40782cb2f 100644 --- a/src/test/java/se/citerus/dddsample/infrastructure/persistence/jpa/HandlingEventRepositoryTest.java +++ b/src/test/java/se/citerus/dddsample/infrastructure/persistence/jpa/HandlingEventRepositoryTest.java @@ -1,5 +1,6 @@ package se.citerus.dddsample.infrastructure.persistence.jpa; +import jakarta.persistence.EntityManager; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -17,7 +18,6 @@ import se.citerus.dddsample.domain.model.location.LocationRepository; import se.citerus.dddsample.domain.model.location.UnLocode; -import javax.persistence.EntityManager; import java.time.Instant; import java.util.List; diff --git a/src/test/java/se/citerus/dddsample/interfaces/handling/HandlingReportIntegrationTest.java b/src/test/java/se/citerus/dddsample/interfaces/handling/HandlingReportIntegrationTest.java index 18de6eca8..47174f762 100644 --- a/src/test/java/se/citerus/dddsample/interfaces/handling/HandlingReportIntegrationTest.java +++ b/src/test/java/se/citerus/dddsample/interfaces/handling/HandlingReportIntegrationTest.java @@ -7,7 +7,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.MediaType; import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; @@ -62,7 +62,7 @@ void shouldReturn201ResponseWhenHandlingReportIsSubmitted() throws Exception { .body(body); ResponseEntity response = restTemplate.exchange(request, String.class); - assertThat(response.getStatusCodeValue()).isEqualTo(201); + assertThat(response.getStatusCode().value()).isEqualTo(201); Thread.sleep(1000); // TODO replace with Awaitility diff --git a/src/test/java/se/citerus/dddsample/interfaces/handling/HandlingReportParserTest.java b/src/test/java/se/citerus/dddsample/interfaces/handling/HandlingReportParserTest.java index 415fdc0c8..ef7187657 100644 --- a/src/test/java/se/citerus/dddsample/interfaces/handling/HandlingReportParserTest.java +++ b/src/test/java/se/citerus/dddsample/interfaces/handling/HandlingReportParserTest.java @@ -45,7 +45,7 @@ public void shouldThrowErrorOnParsingInvalidUnloCode(String input) { @ValueSource(strings = {"SESTO"}) public void shouldReturnUnloCodeOnParsingValidUnloCode(String input) { UnLocode result = HandlingReportParser.parseUnLocode(input); - assertThat(result).isNotNull().extracting("unlocode").contains(input); + assertThat(result).isNotNull().extracting("unlocode").asString().contains(input); } @ParameterizedTest @@ -68,7 +68,7 @@ public void shouldThrowErrorOnParsingEmptyTrackingId(String input) { @ValueSource(strings = {"ABC123"}) public void shouldReturnTrackingIdOnParsingValidTrackingId(String input) { TrackingId result = HandlingReportParser.parseTrackingId(input); - assertThat(result).isNotNull().extracting("id").contains(input); + assertThat(result).isNotNull().extracting("id").asString().contains(input); } @ParameterizedTest @@ -89,7 +89,7 @@ public void shouldReturnNullOnParsingEmptyVoyageNumber(String input) { @ValueSource(strings = {"0101"}) public void shouldReturnVoyageNumberOnParsingValidVoyageNumber(String input) { VoyageNumber result = HandlingReportParser.parseVoyageNumber(input); - assertThat(result).isNotNull().extracting("number").contains(input); + assertThat(result).isNotNull().extracting("number").asString().contains(input); } @ParameterizedTest diff --git a/src/test/java/se/citerus/dddsample/interfaces/tracking/CargoTrackingControllerTest.java b/src/test/java/se/citerus/dddsample/interfaces/tracking/CargoTrackingControllerTest.java index db2a70547..7c3c7876c 100644 --- a/src/test/java/se/citerus/dddsample/interfaces/tracking/CargoTrackingControllerTest.java +++ b/src/test/java/se/citerus/dddsample/interfaces/tracking/CargoTrackingControllerTest.java @@ -42,8 +42,9 @@ public void setup() throws Exception { cargoRepository.init(); CargoTrackingController controller = new CargoTrackingController(cargoRepository, - new HandlingEventRepositoryInMem(), - new FakeMessageSource()); + new HandlingEventRepositoryInMem(), + new FakeMessageSource(), + new TrackCommandValidator()); InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/jsp/"); diff --git a/src/test/java/se/citerus/dddsample/interfaces/tracking/ws/CargoTrackingRestServiceIntegrationTest.java b/src/test/java/se/citerus/dddsample/interfaces/tracking/ws/CargoTrackingRestServiceIntegrationTest.java index c4f1a199f..82e19d61d 100644 --- a/src/test/java/se/citerus/dddsample/interfaces/tracking/ws/CargoTrackingRestServiceIntegrationTest.java +++ b/src/test/java/se/citerus/dddsample/interfaces/tracking/ws/CargoTrackingRestServiceIntegrationTest.java @@ -4,7 +4,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -46,9 +46,9 @@ void shouldReturn200ResponseAndJsonWhenRequestingCargoWithIdABC123() throws Exce ResponseEntity response = restTemplate.exchange(request, String.class); - assertThat(response.getStatusCodeValue()).isEqualTo(200); + assertThat(response.getStatusCode().value()).isEqualTo(200); String expected = StreamUtils.copyToString(getClass().getResourceAsStream("/sampleCargoTrackingResponse.json"), StandardCharsets.UTF_8); - assertThat(response.getHeaders().get("Content-Type")).containsExactly("application/json;charset=UTF-8"); + assertThat(response.getHeaders().get("Content-Type")).containsExactly("application/json"); assertThat(response.getBody()).isEqualTo(expected); } diff --git a/src/test/resources/config/application.yml b/src/test/resources/config/application.yml index a4e804ab2..da8970494 100644 --- a/src/test/resources/config/application.yml +++ b/src/test/resources/config/application.yml @@ -1,3 +1,8 @@ spring: dataSource: - url: jdbc:hsqldb:mem:dddsample_test \ No newline at end of file + url: jdbc:hsqldb:mem:dddsample_test + main: + allow-bean-definition-overriding: true +server: + error: + include-message: always \ No newline at end of file diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties deleted file mode 100644 index 9d89009b5..000000000 --- a/src/test/resources/log4j.properties +++ /dev/null @@ -1,15 +0,0 @@ -log4j.rootLogger=info, stdout - -log4j.appender.stdout=org.apache.log4j.ConsoleAppender -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n - -log4j.logger.net.sf.ehcache.config.ConfigurationFactory=error - -log4j.logger.se.citerus.dddsample=debug -log4j.logger.org.hibernate.SQL=debug -#log4j.logger.org.hibernate.tool.hbm2ddl.SchemaExport=debug - -#log4j.logger.org.springframework.orm=debug -#log4j.logger.org.springframework.transaction=debug -#TODO move this config to spring boot config