Bläddra i källkod

Renamed DomainEventNotifer to SystemEvents and moved out to application layer.

Moved handling of rejected registration attempts into HandlingEventService, making the JMS consumer pure delegation.
peter_backlund 18 år sedan
förälder
incheckning
c44996ccef

+ 1
- 3
dddsample/src/main/java/se/citerus/dddsample/application/HandlingEventService.java Visa fil

@@ -1,7 +1,6 @@
1 1
 package se.citerus.dddsample.application;
2 2
 
3 3
 import se.citerus.dddsample.application.messaging.HandlingEventRegistrationAttempt;
4
-import se.citerus.dddsample.domain.model.handling.CannotCreateHandlingEventException;
5 4
 
6 5
 
7 6
 /**
@@ -14,8 +13,7 @@ public interface HandlingEventService {
14 13
    * parties that an event has been registered.
15 14
    *
16 15
    * @param attempt handling event registration attempt
17
-   * @throws se.citerus.dddsample.domain.model.handling.CannotCreateHandlingEventException
18 16
    */
19
-  void register(HandlingEventRegistrationAttempt attempt) throws CannotCreateHandlingEventException;
17
+  void register(HandlingEventRegistrationAttempt attempt);
20 18
 
21 19
 }

+ 32
- 0
dddsample/src/main/java/se/citerus/dddsample/application/SystemEvents.java Visa fil

@@ -0,0 +1,32 @@
1
+package se.citerus.dddsample.application;
2
+
3
+import se.citerus.dddsample.application.messaging.HandlingEventRegistrationAttempt;
4
+import se.citerus.dddsample.domain.model.cargo.Cargo;
5
+import se.citerus.dddsample.domain.model.handling.CannotCreateHandlingEventException;
6
+import se.citerus.dddsample.domain.model.handling.HandlingEvent;
7
+
8
+/**
9
+ * This interface provides a way to let other parts
10
+ * of the system know about events that have occurred.
11
+ * <p/>
12
+ * It may be implemented synchronously or asynchronously, using
13
+ * for example JMS.
14
+ */
15
+public interface SystemEvents {
16
+
17
+  /**
18
+   * A cargo has been handled.
19
+   *
20
+   * @param event handling event
21
+   */
22
+  void cargoWasHandled(HandlingEvent event);
23
+
24
+  void cargoWasMisdirected(Cargo cargo);
25
+
26
+  void cargoHasArrived(Cargo cargo);
27
+
28
+  void rejectHandlingEventRegistrationAttempt(HandlingEventRegistrationAttempt attempt, CannotCreateHandlingEventException problem);
29
+
30
+  //void scheduleWasChanged(Voyage voyage);
31
+
32
+}

+ 1
- 1
dddsample/src/main/java/se/citerus/dddsample/application/impl/BookingServiceImpl.java Visa fil

@@ -28,7 +28,7 @@ public final class BookingServiceImpl implements BookingService {
28 28
   }
29 29
 
30 30
   @Override
31
-  @Transactional(readOnly = false)
31
+  @Transactional
32 32
   public TrackingId bookNewCargo(final UnLocode originUnLocode, final UnLocode destinationUnLocode) {
33 33
     Validate.notNull(originUnLocode);
34 34
     Validate.notNull(destinationUnLocode);

+ 13
- 9
dddsample/src/main/java/se/citerus/dddsample/application/impl/HandlingEventServiceImpl.java Visa fil

@@ -2,22 +2,22 @@ package se.citerus.dddsample.application.impl;
2 2
 
3 3
 import org.springframework.transaction.annotation.Transactional;
4 4
 import se.citerus.dddsample.application.HandlingEventService;
5
+import se.citerus.dddsample.application.SystemEvents;
5 6
 import se.citerus.dddsample.application.messaging.HandlingEventRegistrationAttempt;
6 7
 import se.citerus.dddsample.domain.model.handling.CannotCreateHandlingEventException;
7 8
 import se.citerus.dddsample.domain.model.handling.HandlingEvent;
8 9
 import se.citerus.dddsample.domain.model.handling.HandlingEventFactory;
9 10
 import se.citerus.dddsample.domain.model.handling.HandlingEventRepository;
10
-import se.citerus.dddsample.domain.service.DomainEventNotifier;
11 11
 
12 12
 public final class HandlingEventServiceImpl implements HandlingEventService {
13 13
 
14 14
   private final HandlingEventRepository handlingEventRepository;
15
-  private final DomainEventNotifier domainEventNotifier;
15
+  private final SystemEvents systemEvents;
16 16
   private final HandlingEventFactory handlingEventFactory;
17 17
 
18
-  public HandlingEventServiceImpl(HandlingEventRepository handlingEventRepository, DomainEventNotifier domainEventNotifier, HandlingEventFactory handlingEventFactory) {
18
+  public HandlingEventServiceImpl(HandlingEventRepository handlingEventRepository, SystemEvents systemEvents, HandlingEventFactory handlingEventFactory) {
19 19
     this.handlingEventRepository = handlingEventRepository;
20
-    this.domainEventNotifier = domainEventNotifier;
20
+    this.systemEvents = systemEvents;
21 21
     this.handlingEventFactory = handlingEventFactory;
22 22
   }
23 23
 
@@ -33,11 +33,15 @@ public final class HandlingEventServiceImpl implements HandlingEventService {
33 33
      are enforced by asynchronous updates, after the commit of this transaction.
34 34
   */
35 35
   @Override
36
-  @Transactional(readOnly = false, rollbackFor = {CannotCreateHandlingEventException.class})
37
-  public void register(HandlingEventRegistrationAttempt attempt) throws CannotCreateHandlingEventException {
38
-    final HandlingEvent event = handlingEventFactory.createHandlingEvent(attempt.getDate(), attempt.getTrackingId(), attempt.getVoyageNumber(), attempt.getUnLocode(), attempt.getType());
39
-    handlingEventRepository.save(event);
40
-    domainEventNotifier.cargoWasHandled(event);
36
+  @Transactional
37
+  public void register(HandlingEventRegistrationAttempt attempt) {
38
+    try {
39
+      final HandlingEvent event = handlingEventFactory.createHandlingEvent(attempt.getDate(), attempt.getTrackingId(), attempt.getVoyageNumber(), attempt.getUnLocode(), attempt.getType());
40
+      handlingEventRepository.save(event);
41
+      systemEvents.cargoWasHandled(event);
42
+    } catch (CannotCreateHandlingEventException e) {
43
+      systemEvents.rejectHandlingEventRegistrationAttempt(attempt, e);
44
+    }
41 45
   }
42 46
 
43 47
 }

+ 7
- 7
dddsample/src/main/java/se/citerus/dddsample/application/impl/TrackingServiceImpl.java Visa fil

@@ -4,25 +4,25 @@ import org.apache.commons.lang.Validate;
4 4
 import org.apache.commons.logging.Log;
5 5
 import org.apache.commons.logging.LogFactory;
6 6
 import org.springframework.transaction.annotation.Transactional;
7
+import se.citerus.dddsample.application.SystemEvents;
7 8
 import se.citerus.dddsample.application.TrackingService;
8 9
 import se.citerus.dddsample.domain.model.cargo.Cargo;
9 10
 import se.citerus.dddsample.domain.model.cargo.CargoRepository;
10 11
 import se.citerus.dddsample.domain.model.cargo.TrackingId;
11
-import se.citerus.dddsample.domain.service.DomainEventNotifier;
12 12
 
13 13
 public class TrackingServiceImpl implements TrackingService {
14 14
 
15
-  private final DomainEventNotifier domainEventNotifier;
15
+  private final SystemEvents systemEvents;
16 16
   private final CargoRepository cargoRepository;
17 17
   private final Log logger = LogFactory.getLog(getClass());
18 18
 
19
-  public TrackingServiceImpl(DomainEventNotifier domainEventNotifier, CargoRepository cargoRepository) {
20
-    this.domainEventNotifier = domainEventNotifier;
19
+  public TrackingServiceImpl(SystemEvents systemEvents, CargoRepository cargoRepository) {
20
+    this.systemEvents = systemEvents;
21 21
     this.cargoRepository = cargoRepository;
22 22
   }
23 23
 
24 24
   @Override
25
-  @Transactional
25
+  @Transactional(readOnly = true)
26 26
   public void onCargoHandled(final TrackingId trackingId) {
27 27
     Validate.notNull(trackingId, "Tracking ID is required");
28 28
 
@@ -35,11 +35,11 @@ public class TrackingServiceImpl implements TrackingService {
35 35
     // TODO cargo delivery status update would happen here
36 36
 
37 37
     if (cargo.isMisdirected()) {
38
-      domainEventNotifier.cargoWasMisdirected(cargo);
38
+      systemEvents.cargoWasMisdirected(cargo);
39 39
     }
40 40
 
41 41
     if (cargo.isUnloadedAtDestination()) {
42
-      domainEventNotifier.cargoHasArrived(cargo);
42
+      systemEvents.cargoHasArrived(cargo);
43 43
     }
44 44
   }
45 45
 

+ 1
- 2
dddsample/src/main/java/se/citerus/dddsample/application/messaging/CargoHandledConsumer.java Visa fil

@@ -2,7 +2,6 @@ package se.citerus.dddsample.application.messaging;
2 2
 
3 3
 import org.apache.commons.logging.Log;
4 4
 import org.apache.commons.logging.LogFactory;
5
-import org.springframework.transaction.annotation.Transactional;
6 5
 import se.citerus.dddsample.application.TrackingService;
7 6
 import se.citerus.dddsample.domain.model.cargo.TrackingId;
8 7
 
@@ -19,7 +18,7 @@ public class CargoHandledConsumer implements MessageListener {
19 18
   private TrackingService trackingService;
20 19
   private final Log logger = LogFactory.getLog(getClass());
21 20
 
22
-  @Transactional(readOnly = true)  
21
+  @Override  
23 22
   public void onMessage(final Message message) {
24 23
     if (logger.isDebugEnabled()) {
25 24
       logger.debug("Received message " + message);

+ 8
- 25
dddsample/src/main/java/se/citerus/dddsample/application/messaging/HandlingEventRegistrationAttemptConsumer.java Visa fil

@@ -2,38 +2,28 @@ package se.citerus.dddsample.application.messaging;
2 2
 
3 3
 import org.apache.commons.logging.Log;
4 4
 import org.apache.commons.logging.LogFactory;
5
-import org.springframework.jms.core.JmsOperations;
6
-import org.springframework.jms.core.MessageCreator;
7 5
 import se.citerus.dddsample.application.HandlingEventService;
8
-import se.citerus.dddsample.domain.model.handling.CannotCreateHandlingEventException;
9 6
 
10
-import javax.jms.*;
7
+import javax.jms.Message;
8
+import javax.jms.MessageListener;
9
+import javax.jms.ObjectMessage;
11 10
 
12 11
 /**
12
+ * Consumes handling event registration attempt messages and delegates to
13
+ * proper registration.
14
+ * 
13 15
  */
14 16
 public class HandlingEventRegistrationAttemptConsumer implements MessageListener {
15 17
 
16 18
   private HandlingEventService handlingEventService;
17
-  private JmsOperations jmsOperations;
18
-  private Destination rejectedRegistrationAttemptsQueue;
19 19
   private static final Log logger = LogFactory.getLog(HandlingEventRegistrationAttemptConsumer.class);
20 20
 
21 21
   @Override
22 22
   public void onMessage(final Message message) {
23 23
     try {
24 24
       final ObjectMessage om = (ObjectMessage) message;
25
-      final HandlingEventRegistrationAttempt attempt = (HandlingEventRegistrationAttempt) om.getObject();
26
-      try {
27
-        handlingEventService.register(attempt);
28
-      } catch (CannotCreateHandlingEventException e) {
29
-        jmsOperations.send(rejectedRegistrationAttemptsQueue, new MessageCreator() {
30
-          public Message createMessage(Session session) throws JMSException {
31
-            
32
-            return session.createObjectMessage(attempt);
33
-          }
34
-        });
35
-      }
36
-    } catch (JMSException e) {
25
+      handlingEventService.register((HandlingEventRegistrationAttempt) om.getObject());
26
+    } catch (Exception e) {
37 27
       logger.error(e, e);
38 28
     }
39 29
   }
@@ -42,11 +32,4 @@ public class HandlingEventRegistrationAttemptConsumer implements MessageListener
42 32
     this.handlingEventService = handlingEventService;
43 33
   }
44 34
 
45
-  public void setJmsOperations(JmsOperations jmsOperations) {
46
-    this.jmsOperations = jmsOperations;
47
-  }
48
-
49
-  public void setRejectedRegistrationAttemptsQueue(Destination rejectedRegistrationAttemptsQueue) {
50
-    this.rejectedRegistrationAttemptsQueue = rejectedRegistrationAttemptsQueue;
51
-  }
52 35
 }

+ 83
- 0
dddsample/src/main/java/se/citerus/dddsample/application/messaging/JmsSystemEventsImpl.java Visa fil

@@ -0,0 +1,83 @@
1
+package se.citerus.dddsample.application.messaging;
2
+
3
+import org.springframework.jms.core.JmsOperations;
4
+import org.springframework.jms.core.MessageCreator;
5
+import se.citerus.dddsample.application.SystemEvents;
6
+import se.citerus.dddsample.domain.model.cargo.Cargo;
7
+import se.citerus.dddsample.domain.model.handling.CannotCreateHandlingEventException;
8
+import se.citerus.dddsample.domain.model.handling.HandlingEvent;
9
+
10
+import javax.jms.Destination;
11
+import javax.jms.JMSException;
12
+import javax.jms.Message;
13
+import javax.jms.Session;
14
+
15
+/**
16
+ * JMS based implementation.
17
+ */
18
+public final class JmsSystemEventsImpl implements SystemEvents {
19
+
20
+  private JmsOperations jmsOperations;
21
+  private Destination cargoHandledTopic;
22
+  private Destination misdirectedCargoTopic;
23
+  private Destination deliveredCargoTopic;
24
+  private Destination rejectedRegistrationAttemptsQueue;
25
+
26
+  @Override
27
+  public void cargoWasHandled(final HandlingEvent event) {
28
+    final Cargo cargo = event.cargo();
29
+    jmsOperations.send(cargoHandledTopic, new MessageCreator() {
30
+      public Message createMessage(final Session session) throws JMSException {
31
+        return session.createTextMessage(cargo.trackingId().idString());
32
+      }
33
+    });
34
+  }
35
+
36
+  @Override
37
+  public void cargoWasMisdirected(final Cargo cargo) {
38
+    jmsOperations.send(misdirectedCargoTopic, new MessageCreator() {
39
+      public Message createMessage(Session session) throws JMSException {
40
+        return session.createTextMessage(cargo.trackingId().idString());
41
+      }
42
+    });
43
+  }
44
+
45
+  @Override
46
+  public void cargoHasArrived(final Cargo cargo) {
47
+    jmsOperations.send(deliveredCargoTopic, new MessageCreator() {
48
+      public Message createMessage(Session session) throws JMSException {
49
+        return session.createTextMessage(cargo.trackingId().idString());
50
+      }
51
+    });
52
+  }
53
+
54
+  @Override
55
+  public void rejectHandlingEventRegistrationAttempt(final HandlingEventRegistrationAttempt attempt, CannotCreateHandlingEventException problem) {
56
+    // TODO include error message in JMS message
57
+    jmsOperations.send(rejectedRegistrationAttemptsQueue, new MessageCreator() {
58
+      public Message createMessage(Session session) throws JMSException {
59
+        return session.createObjectMessage(attempt);
60
+      }
61
+    });
62
+  }
63
+
64
+  public void setJmsOperations(final JmsOperations jmsOperations) {
65
+    this.jmsOperations = jmsOperations;
66
+  }
67
+
68
+  public void setCargoHandledTopic(final Destination cargoHandledTopic) {
69
+    this.cargoHandledTopic = cargoHandledTopic;
70
+  }
71
+
72
+  public void setMisdirectedCargoTopic(Destination misdirectedCargoTopic) {
73
+    this.misdirectedCargoTopic = misdirectedCargoTopic;
74
+  }
75
+
76
+  public void setDeliveredCargoTopic(Destination deliveredCargoTopic) {
77
+    this.deliveredCargoTopic = deliveredCargoTopic;
78
+  }
79
+
80
+  public void setRejectedRegistrationAttemptsQueue(Destination rejectedRegistrationAttemptsQueue) {
81
+    this.rejectedRegistrationAttemptsQueue = rejectedRegistrationAttemptsQueue;
82
+  }
83
+}

+ 3
- 2
dddsample/src/main/resources/context-messaging-jms.xml Visa fil

@@ -16,6 +16,7 @@
16 16
   <amq:topic id="misdirectedCargoTopic" name="MisdirectedCargoTopic"/>
17 17
   <amq:topic id="deliveredCargoTopic" name="DeliveredCargoTopic"/>
18 18
   <amq:queue id="handlingEventRegistrationAttemptQueue" name="HandlingEventRegistrationAttemptQueue"/>
19
+  <amq:queue id="rejectedRegistrationAttemptsQueue" name="RejectedRegistrationAttemptsQueue"/>
19 20
 
20 21
   <jms:listener-container connection-factory="jmsConnectionFactory">
21 22
     <jms:listener destination="cargoHandledTopic" ref="cargoHandledConsumer" />
@@ -30,11 +31,12 @@
30 31
     <property name="connectionFactory" ref="jmsConnectionFactory"/>
31 32
   </bean>
32 33
 
33
-  <bean id="domainEventNotifier" class="se.citerus.dddsample.application.messaging.JmsDomainEventNotifierImpl">
34
+  <bean id="systemEvents" class="se.citerus.dddsample.application.messaging.JmsSystemEventsImpl">
34 35
     <property name="jmsOperations" ref="jmsOperations"/>
35 36
     <property name="cargoHandledTopic" ref="cargoHandledTopic"/>
36 37
     <property name="misdirectedCargoTopic" ref="misdirectedCargoTopic"/>
37 38
     <property name="deliveredCargoTopic" ref="deliveredCargoTopic"/>
39
+    <property name="rejectedRegistrationAttemptsQueue" ref="rejectedRegistrationAttemptsQueue"/>
38 40
   </bean>
39 41
 
40 42
   <bean id="cargoHandledConsumer" class="se.citerus.dddsample.application.messaging.CargoHandledConsumer">
@@ -42,7 +44,6 @@
42 44
   </bean>
43 45
 
44 46
   <bean id="handlingEventRegistrationAttemptConsumer" class="se.citerus.dddsample.application.messaging.HandlingEventRegistrationAttemptConsumer">
45
-    <property name="handlingEventFactory" ref="handlingEventFactory"/>
46 47
     <property name="handlingEventService" ref="handlingEventService"/>
47 48
   </bean>
48 49
   

+ 3
- 4
dddsample/src/main/resources/context-service.xml Visa fil

@@ -15,12 +15,13 @@
15 15
 
16 16
   <bean id="trackingService" class="se.citerus.dddsample.application.impl.TrackingServiceImpl">
17 17
     <constructor-arg ref="cargoRepository"/>
18
-    <constructor-arg ref="domainEventNotifier"/>
18
+    <constructor-arg ref="systemEvents"/>
19 19
   </bean>
20 20
 
21 21
   <bean id="handlingEventService" class="se.citerus.dddsample.application.impl.HandlingEventServiceImpl">
22 22
     <constructor-arg ref="handlingEventRepository"/>
23
-    <constructor-arg ref="domainEventNotifier"/>
23
+    <constructor-arg ref="handlingEventFactory"/>
24
+    <constructor-arg ref="systemEvents"/>
24 25
   </bean>
25 26
 
26 27
   <bean id="handlingEventFactory" class="se.citerus.dddsample.domain.model.handling.HandlingEventFactory">
@@ -29,8 +30,6 @@
29 30
     <constructor-arg ref="locationRepository"/>
30 31
   </bean>
31 32
 
32
-  <!-- Aplication services below -->
33
-
34 33
   <tx:annotation-driven transaction-manager="transactionManager"/>
35 34
 
36 35
   <bean id="routingService" class="se.citerus.dddsample.application.routing.ExternalRoutingService">

+ 30
- 31
dddsample/src/test/java/se/citerus/dddsample/application/HandlingEventServiceTest.java Visa fil

@@ -10,17 +10,19 @@ import se.citerus.dddsample.domain.model.cargo.TrackingId;
10 10
 import se.citerus.dddsample.domain.model.carrier.SampleVoyages;
11 11
 import se.citerus.dddsample.domain.model.carrier.VoyageNumber;
12 12
 import se.citerus.dddsample.domain.model.carrier.VoyageRepository;
13
-import se.citerus.dddsample.domain.model.handling.*;
13
+import se.citerus.dddsample.domain.model.handling.CannotCreateHandlingEventException;
14
+import se.citerus.dddsample.domain.model.handling.HandlingEvent;
15
+import se.citerus.dddsample.domain.model.handling.HandlingEventFactory;
16
+import se.citerus.dddsample.domain.model.handling.HandlingEventRepository;
14 17
 import se.citerus.dddsample.domain.model.location.LocationRepository;
15 18
 import static se.citerus.dddsample.domain.model.location.SampleLocations.*;
16 19
 import se.citerus.dddsample.domain.model.location.UnLocode;
17
-import se.citerus.dddsample.domain.service.DomainEventNotifier;
18 20
 
19 21
 import java.util.Date;
20 22
 
21 23
 public class HandlingEventServiceTest extends TestCase {
22 24
   private HandlingEventServiceImpl service;
23
-  private DomainEventNotifier domainEventNotifier;
25
+  private SystemEvents systemEvents;
24 26
   private CargoRepository cargoRepository;
25 27
   private VoyageRepository voyageRepository;
26 28
   private HandlingEventRepository handlingEventRepository;
@@ -36,13 +38,13 @@ public class HandlingEventServiceTest extends TestCase {
36 38
     voyageRepository = createMock(VoyageRepository.class);
37 39
     handlingEventRepository = createMock(HandlingEventRepository.class);
38 40
     locationRepository = createMock(LocationRepository.class);
39
-    domainEventNotifier = createMock(DomainEventNotifier.class);
41
+    systemEvents = createMock(SystemEvents.class);
40 42
     handlingEventFactory = new HandlingEventFactory(cargoRepository, voyageRepository, locationRepository);
41
-    service = new HandlingEventServiceImpl(handlingEventRepository, domainEventNotifier, handlingEventFactory);
43
+    service = new HandlingEventServiceImpl(handlingEventRepository, systemEvents, handlingEventFactory);
42 44
   }
43 45
 
44 46
   protected void tearDown() throws Exception {
45
-    verify(cargoRepository, voyageRepository, handlingEventRepository, domainEventNotifier);
47
+    verify(cargoRepository, voyageRepository, handlingEventRepository, systemEvents);
46 48
   }
47 49
 
48 50
   public void testRegisterEvent() throws Exception {
@@ -57,9 +59,9 @@ public class HandlingEventServiceTest extends TestCase {
57 59
 
58 60
     // TODO: does not inspect the handling event instance in a sufficient way
59 61
     handlingEventRepository.save(isA(HandlingEvent.class));
60
-    domainEventNotifier.cargoWasHandled(isA(HandlingEvent.class));
62
+    systemEvents.cargoWasHandled(isA(HandlingEvent.class));
61 63
 
62
-    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, domainEventNotifier);
64
+    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, systemEvents);
63 65
 
64 66
     service.register(new HandlingEventRegistrationAttempt(
65 67
       new Date(), new Date(), trackingId, voyageNumber, HandlingEvent.Type.LOAD, unLocode
@@ -71,11 +73,11 @@ public class HandlingEventServiceTest extends TestCase {
71 73
     expect(cargoRepository.find(trackingId)).andReturn(cargoABC);
72 74
 
73 75
     handlingEventRepository.save(isA(HandlingEvent.class));
74
-    domainEventNotifier.cargoWasHandled(isA(HandlingEvent.class));
76
+    systemEvents.cargoWasHandled(isA(HandlingEvent.class));
75 77
 
76 78
     expect(locationRepository.find(STOCKHOLM.unLocode())).andReturn(STOCKHOLM);
77 79
 
78
-    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, domainEventNotifier);
80
+    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, systemEvents);
79 81
 
80 82
     service.register(new HandlingEventRegistrationAttempt(
81 83
       new Date(), new Date(), trackingId, null, HandlingEvent.Type.RECEIVE, STOCKHOLM.unLocode()
@@ -91,15 +93,14 @@ public class HandlingEventServiceTest extends TestCase {
91 93
     expect(cargoRepository.find(trackingId)).andReturn(new Cargo(trackingId, CHICAGO, STOCKHOLM));
92 94
 
93 95
     expect(locationRepository.find(MELBOURNE.unLocode())).andReturn(MELBOURNE);
96
+
97
+    systemEvents.rejectHandlingEventRegistrationAttempt(isA(HandlingEventRegistrationAttempt.class), isA(CannotCreateHandlingEventException.class));
98
+
99
+    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, systemEvents);
94 100
     
95
-    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, domainEventNotifier);
96
-    
97
-    try {
98
-      service.register(new HandlingEventRegistrationAttempt(
99
-        new Date(), new Date(), trackingId, voyageNumber, HandlingEvent.Type.UNLOAD, MELBOURNE.unLocode()
100
-      ));
101
-      fail("Should not be able to register an event with non-existing carrier movement");
102
-    } catch (UnknownVoyageException expected) {}
101
+    service.register(new HandlingEventRegistrationAttempt(
102
+      new Date(), new Date(), trackingId, voyageNumber, HandlingEvent.Type.UNLOAD, MELBOURNE.unLocode()
103
+    ));
103 104
   }
104 105
   
105 106
   public void testRegisterEventInvalidCargo() throws Exception {
@@ -107,15 +108,14 @@ public class HandlingEventServiceTest extends TestCase {
107 108
     expect(cargoRepository.find(trackingId)).andReturn(null);
108 109
 
109 110
     expect(locationRepository.find(HONGKONG.unLocode())).andReturn(HONGKONG);
111
+
112
+    systemEvents.rejectHandlingEventRegistrationAttempt(isA(HandlingEventRegistrationAttempt.class), isA(CannotCreateHandlingEventException.class));
113
+
114
+    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, systemEvents);
110 115
     
111
-    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, domainEventNotifier);
112
-    
113
-    try {
114 116
       service.register(new HandlingEventRegistrationAttempt(
115 117
         new Date(), new Date(), trackingId, new VoyageNumber("V001"), HandlingEvent.Type.CLAIM, HONGKONG.unLocode()
116 118
       ));
117
-      fail("Should not be able to register an event with non-existing cargo");
118
-    } catch (UnknownCargoException expected) {}
119 119
   }
120 120
   
121 121
   public void testRegisterEventInvalidLocation() throws Exception {
@@ -123,14 +123,13 @@ public class HandlingEventServiceTest extends TestCase {
123 123
     expect(cargoRepository.find(trackingId)).andReturn(cargoXYZ);
124 124
     UnLocode wayOff = new UnLocode("XXYYY");
125 125
     expect(locationRepository.find(wayOff)).andReturn(null);
126
+
127
+    systemEvents.rejectHandlingEventRegistrationAttempt(isA(HandlingEventRegistrationAttempt.class), isA(CannotCreateHandlingEventException.class));
128
+
129
+    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, systemEvents);
126 130
     
127
-    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, domainEventNotifier);
128
-    
129
-    try {
130
-      service.register(new HandlingEventRegistrationAttempt(
131
-        new Date(), new Date(), trackingId, null, HandlingEvent.Type.CLAIM, wayOff
132
-      ));
133
-      fail("Should not be able to register an event with non-existing Location");
134
-    } catch (UnknownLocationException expected) {}
131
+    service.register(new HandlingEventRegistrationAttempt(
132
+      new Date(), new Date(), trackingId, null, HandlingEvent.Type.CLAIM, wayOff
133
+    ));
135 134
   }
136 135
 }

+ 10
- 6
dddsample/src/test/java/se/citerus/dddsample/scenario/CargoHandlingScenarioTest.java Visa fil

@@ -2,6 +2,7 @@ package se.citerus.dddsample.scenario;
2 2
 
3 3
 import junit.framework.TestCase;
4 4
 import se.citerus.dddsample.application.HandlingEventService;
5
+import se.citerus.dddsample.application.SystemEvents;
5 6
 import se.citerus.dddsample.application.TrackingService;
6 7
 import se.citerus.dddsample.application.impl.HandlingEventServiceImpl;
7 8
 import se.citerus.dddsample.application.impl.TrackingServiceImpl;
@@ -17,7 +18,6 @@ import se.citerus.dddsample.domain.model.handling.HandlingEventRepository;
17 18
 import se.citerus.dddsample.domain.model.location.Location;
18 19
 import se.citerus.dddsample.domain.model.location.LocationRepository;
19 20
 import static se.citerus.dddsample.domain.model.location.SampleLocations.*;
20
-import se.citerus.dddsample.domain.service.DomainEventNotifier;
21 21
 import se.citerus.dddsample.domain.service.RoutingService;
22 22
 import se.citerus.dddsample.infrastructure.persistence.inmemory.LocationRepositoryInMem;
23 23
 import se.citerus.dddsample.infrastructure.persistence.inmemory.VoyageRepositoryInMem;
@@ -31,7 +31,7 @@ public class CargoHandlingScenarioTest extends TestCase {
31 31
 
32 32
   HandlingEventFactory handlingEventFactory;
33 33
 
34
-  DomainEventNotifier domainEventNotifier;
34
+  SystemEvents systemEvents;
35 35
 
36 36
   HandlingEventService handlingEventService;
37 37
   TrackingService trackingService;
@@ -140,13 +140,17 @@ public class CargoHandlingScenarioTest extends TestCase {
140 140
     };
141 141
 
142 142
     // Synchronous stub
143
-    domainEventNotifier = new DomainEventNotifier() {
143
+    systemEvents = new SystemEvents() {
144
+      @Override
144 145
       public void cargoWasHandled(HandlingEvent event) {
145 146
         trackingService.onCargoHandled(event.cargo().trackingId());
146 147
       }
148
+      @Override
147 149
       public void cargoWasMisdirected(Cargo cargo) {}
150
+      @Override
148 151
       public void cargoHasArrived(Cargo cargo) {}
149
-      public void rejectHandlingEventRegistrationAttempt(CannotCreateHandlingEventException e) {}
152
+      @Override
153
+      public void rejectHandlingEventRegistrationAttempt(HandlingEventRegistrationAttempt attempt, CannotCreateHandlingEventException problem) {}
150 154
     };
151 155
 
152 156
     // Stub
@@ -185,8 +189,8 @@ public class CargoHandlingScenarioTest extends TestCase {
185 189
     voyageRepository = new VoyageRepositoryInMem();
186 190
 
187 191
     // Domain services and factories that are implemented in the domain layer - not stubbed
188
-    trackingService = new TrackingServiceImpl(domainEventNotifier, cargoRepository);
192
+    trackingService = new TrackingServiceImpl(systemEvents, cargoRepository);
189 193
     handlingEventFactory = new HandlingEventFactory(cargoRepository, this.voyageRepository, this.locationRepository);
190
-    handlingEventService = new HandlingEventServiceImpl(handlingEventRepository, domainEventNotifier, handlingEventFactory);
194
+    handlingEventService = new HandlingEventServiceImpl(handlingEventRepository, systemEvents, handlingEventFactory);
191 195
   }
192 196
 }