Преглед на файлове

Added asynchronous event emission whenever a handling event is registered, so that interested parties can be notified if a cargo is misdirected (is unloaded, is late, has arrived, or whatever).

Two different implementations a available: JMS and a simple thread-based one.

Also, the cargo service track method now uses TrackingId in the signature, for consistency.
peter_backlund преди 18 години
родител
ревизия
4d94406f1e

+ 50
- 4
dddsample/pom.xml Целия файл

@@ -23,13 +23,13 @@
23 23
     <repository>
24 24
       <id>maven2-repository.dev.java.net</id>
25 25
       <name>Java.net Repository for Maven</name>
26
-      <url>http://download.java.net/maven/2/</url>
26
+      <url>http://download.java.net/maven/2</url>
27 27
       <layout>default</layout>
28 28
     </repository>
29 29
     <repository>
30 30
       <id>maven-repository.dev.java.net</id>
31 31
       <name>Java.net Repository for Maven 1</name>
32
-      <url>http://download.java.net/maven/1/</url>
32
+      <url>http://download.java.net/maven/1</url>
33 33
       <layout>legacy</layout>
34 34
     </repository>
35 35
   </repositories>
@@ -37,7 +37,7 @@
37 37
     <pluginRepository>
38 38
       <id>maven2-repository.dev.java.net</id>
39 39
       <name>Java.net Repository for Maven</name>
40
-      <url>http://download.java.net/maven/2/</url>
40
+      <url>http://download.java.net/maven/2</url>
41 41
     </pluginRepository>
42 42
   </pluginRepositories>
43 43
   <developers>
@@ -178,6 +178,11 @@
178 178
     </dependency>
179 179
     <dependency>
180 180
       <groupId>org.springframework</groupId>
181
+      <artifactId>spring-jms</artifactId>
182
+      <version>${spring.version}</version>
183
+    </dependency>
184
+    <dependency>
185
+      <groupId>org.springframework</groupId>
181 186
       <artifactId>spring-test</artifactId>
182 187
       <version>${spring.version}</version>
183 188
       <scope>test</scope>
@@ -216,6 +221,10 @@
216 221
           <groupId>avalon-framework</groupId>
217 222
           <artifactId>avalon-framework</artifactId>
218 223
         </exclusion>
224
+        <exclusion>
225
+          <groupId>logkit</groupId>
226
+          <artifactId>logkit</artifactId>
227
+        </exclusion>
219 228
       </exclusions>
220 229
     </dependency>
221 230
     <dependency>
@@ -251,6 +260,23 @@
251 260
       <scope>runtime</scope>
252 261
     </dependency>
253 262
     <dependency>
263
+      <groupId>org.apache.activemq</groupId>
264
+      <artifactId>activemq-core</artifactId>
265
+      <version>5.0.0</version>
266
+      <exclusions>
267
+        <!--
268
+          This is a snapshot dependency, with no published pom.
269
+          It does not appear to be needed either:
270
+          
271
+          http://mail-archives.apache.org/mod_mbox/activemq-commits/200610.mbox/%3C20061005025744.0C6591A981A@eris.apache.org%3E
272
+        -->
273
+        <exclusion>
274
+          <groupId>org.apache.activemq</groupId>
275
+          <artifactId>activeio-core</artifactId>
276
+        </exclusion>
277
+      </exclusions>
278
+    </dependency>
279
+    <dependency>
254 280
       <groupId>org.easymock</groupId>
255 281
       <artifactId>easymock</artifactId>
256 282
       <version>2.3</version>
@@ -259,7 +285,11 @@
259 285
 
260 286
     <!-- JAX-WS integration with Spring. Lots of broken pom files unfortunately,
261 287
       so we need a few excluded-and-overridden dependencies.
262
-      This problem will mostly go away when we move to Java 6. -->
288
+      This problem will mostly go away when we move to Java 6.
289
+
290
+      javax.activation is excluded because of class loading issues with Jetty:
291
+      http://jira.codehaus.org/browse/JETTY-420
292
+      -->
263 293
     <dependency>
264 294
       <groupId>org.jvnet.jax-ws-commons.spring</groupId>
265 295
       <artifactId>jaxws-spring</artifactId>
@@ -277,6 +307,10 @@
277 307
           <groupId>org.jvnet.staxex</groupId>
278 308
           <artifactId>stax-ex</artifactId>
279 309
         </exclusion>
310
+        <exclusion>
311
+          <groupId>javax.activation</groupId>
312
+          <artifactId>activation</artifactId>
313
+        </exclusion>
280 314
       </exclusions>
281 315
     </dependency>
282 316
     <dependency>
@@ -284,12 +318,24 @@
284 318
       <artifactId>stax-ex</artifactId>
285 319
       <version>1.2</version>
286 320
       <scope>runtime</scope>
321
+      <exclusions>
322
+        <exclusion>
323
+          <groupId>javax.activation</groupId>
324
+          <artifactId>activation</artifactId>
325
+        </exclusion>
326
+      </exclusions>
287 327
     </dependency>
288 328
     <dependency>
289 329
       <groupId>com.sun.xml.stream.buffer</groupId>
290 330
       <artifactId>streambuffer</artifactId>
291 331
       <version>0.7</version>
292 332
       <scope>runtime</scope>
333
+      <exclusions>
334
+        <exclusion>
335
+          <groupId>javax.activation</groupId>
336
+          <artifactId>activation</artifactId>
337
+        </exclusion>
338
+      </exclusions>
293 339
     </dependency>
294 340
     <dependency>
295 341
       <groupId>com.sun.xml.ws</groupId>

+ 8
- 1
dddsample/src/main/java/se/citerus/dddsample/service/CargoService.java Целия файл

@@ -1,5 +1,6 @@
1 1
 package se.citerus.dddsample.service;
2 2
 
3
+import se.citerus.dddsample.domain.TrackingId;
3 4
 import se.citerus.dddsample.service.dto.CargoWithHistoryDTO;
4 5
 
5 6
 /**
@@ -12,6 +13,12 @@ public interface CargoService {
12 13
    * @param trackingId tracking id
13 14
    * @return A cargo and its delivery history, or null if no cargo with given tracking id is found.
14 15
    */
15
-  CargoWithHistoryDTO track(String trackingId);
16
+  CargoWithHistoryDTO track(TrackingId trackingId);
16 17
 
18
+  /**
19
+   * Sends a notification to whom it may concern if a cargo is misrouted.  
20
+   *
21
+   * @param trackingId cargo tracking id
22
+   */
23
+  void notifyIfMisdirected(TrackingId trackingId);
17 24
 }

+ 15
- 3
dddsample/src/main/java/se/citerus/dddsample/service/CargoServiceImpl.java Целия файл

@@ -1,5 +1,7 @@
1 1
 package se.citerus.dddsample.service;
2 2
 
3
+import org.apache.commons.logging.Log;
4
+import org.apache.commons.logging.LogFactory;
3 5
 import org.springframework.transaction.annotation.Transactional;
4 6
 import se.citerus.dddsample.domain.*;
5 7
 import se.citerus.dddsample.repository.CargoRepository;
@@ -10,11 +12,11 @@ import java.util.List;
10 12
 
11 13
 public class CargoServiceImpl implements CargoService {
12 14
   private CargoRepository cargoRepository;
15
+  private static final Log logger = LogFactory.getLog(CargoServiceImpl.class);
13 16
 
14 17
   @Transactional(readOnly = true)
15
-  public CargoWithHistoryDTO track(String trackingId) {
16
-    final TrackingId tid = new TrackingId(trackingId);
17
-    final Cargo cargo = cargoRepository.find(tid);
18
+  public CargoWithHistoryDTO track(TrackingId trackingId) {
19
+    final Cargo cargo = cargoRepository.find(trackingId);
18 20
     if (cargo == null) {
19 21
       return null;
20 22
     }
@@ -49,6 +51,16 @@ public class CargoServiceImpl implements CargoService {
49 51
 
50 52
   }
51 53
 
54
+  @Transactional(readOnly = true)
55
+  public void notifyIfMisdirected(TrackingId trackingId) {
56
+    Cargo cargo = cargoRepository.find(trackingId);
57
+    if (cargo.isMisdirected()) {
58
+      // TODO: more elaborate notification than logging - mail, xmpp, other?
59
+      logger.info("Cargo " + trackingId + " has been misdirected. " +
60
+                  "Last event was " + cargo.deliveryHistory().lastEvent());
61
+    }
62
+  }
63
+
52 64
   public void setCargoRepository(CargoRepository cargoRepository) {
53 65
     this.cargoRepository = cargoRepository;
54 66
   }

+ 14
- 0
dddsample/src/main/java/se/citerus/dddsample/service/EventService.java Целия файл

@@ -0,0 +1,14 @@
1
+package se.citerus.dddsample.service;
2
+
3
+import se.citerus.dddsample.domain.HandlingEvent;
4
+
5
+/**
6
+ * Event service.
7
+ */
8
+public interface EventService {
9
+
10
+  /**
11
+   * @param event handling event
12
+   */
13
+  void fireHandlingEventRegistered(HandlingEvent event);
14
+}

+ 37
- 0
dddsample/src/main/java/se/citerus/dddsample/service/HandlingEventMessageDelegate.java Целия файл

@@ -0,0 +1,37 @@
1
+package se.citerus.dddsample.service;
2
+
3
+import org.apache.commons.logging.Log;
4
+import org.apache.commons.logging.LogFactory;
5
+import se.citerus.dddsample.domain.TrackingId;
6
+
7
+import javax.jms.JMSException;
8
+import javax.jms.Message;
9
+import javax.jms.MessageListener;
10
+
11
+/**
12
+ * Consumes JMS messages and delegates notification of misdirected
13
+ * cargo to the cargo service.
14
+ *
15
+ * This point of this is to decouple the cargo service from JMS,
16
+ * and to allow a thread-based messaging implementation to live in
17
+ * parallell. 
18
+ */
19
+public class HandlingEventMessageDelegate implements MessageListener {
20
+
21
+  CargoService cargoService;
22
+  private static final Log logger = LogFactory.getLog(HandlingEventMessageDelegate.class);
23
+
24
+  public void onMessage(Message message) {
25
+    logger.info("Received message " + message);
26
+    try {
27
+      String tidString = message.getStringProperty(TrackingId.class.getName());
28
+      cargoService.notifyIfMisdirected(new TrackingId(tidString));
29
+    } catch (JMSException e) {
30
+      logger.error(e, e);
31
+    }
32
+  }
33
+
34
+  public void setCargoService(CargoService cargoService) {
35
+    this.cargoService = cargoService;
36
+  }
37
+}

+ 10
- 3
dddsample/src/main/java/se/citerus/dddsample/service/HandlingEventServiceImpl.java Целия файл

@@ -15,6 +15,7 @@ public class HandlingEventServiceImpl implements HandlingEventService {
15 15
   private CarrierMovementRepository carrierMovementRepository;
16 16
   private HandlingEventRepository handlingEventRepository;
17 17
   private LocationRepository locationRepository;
18
+  private EventService eventService;
18 19
 
19 20
   @Transactional(readOnly = false)
20 21
   public void register(Date completionTime, TrackingId trackingId, CarrierMovementId carrierMovementId, UnLocode unlocode, HandlingEvent.Type type) throws UnknownCarrierMovementIdException, UnknownTrackingIdException, UnknownLocationException {
@@ -27,9 +28,8 @@ public class HandlingEventServiceImpl implements HandlingEventService {
27 28
     CarrierMovement carrierMovement = findCarrierMovement(carrierMovementId);
28 29
     Location location = findLocation(unlocode);
29 30
     Date registrationTime = new Date();
30
-    HandlingEvent event = new HandlingEvent(cargo, completionTime, registrationTime, type, location, carrierMovement);
31 31
 
32
-    handlingEventRepository.save(event);
32
+    HandlingEvent event = new HandlingEvent(cargo, completionTime, registrationTime, type, location, carrierMovement);
33 33
 
34 34
     /*
35 35
       NOTE:
@@ -41,6 +41,9 @@ public class HandlingEventServiceImpl implements HandlingEventService {
41 41
         are enforced synchronously in the transaction, but consistency rules of other aggregates
42 42
         are enforced by asynchronous updates, after the commit of this transaction.
43 43
      */
44
+    handlingEventRepository.save(event);
45
+
46
+    eventService.fireHandlingEventRegistered(event);
44 47
   }
45 48
 
46 49
   private CarrierMovement findCarrierMovement(CarrierMovementId carrierMovementId) throws UnknownCarrierMovementIdException {
@@ -72,7 +75,7 @@ public class HandlingEventServiceImpl implements HandlingEventService {
72 75
     this.cargoRepository = cargoRepository;
73 76
   }
74 77
 
75
-  public void setCarrierRepository(CarrierMovementRepository carrierMovementRepository) {
78
+  public void setCarrierMovementRepository(CarrierMovementRepository carrierMovementRepository) {
76 79
     this.carrierMovementRepository = carrierMovementRepository;
77 80
   }
78 81
 
@@ -83,4 +86,8 @@ public class HandlingEventServiceImpl implements HandlingEventService {
83 86
   public void setLocationRepository(LocationRepository locationRepository) {
84 87
     this.locationRepository = locationRepository;
85 88
   }
89
+
90
+  public void setEventService(EventService eventService) {
91
+    this.eventService = eventService;
92
+  }
86 93
 }

+ 36
- 0
dddsample/src/main/java/se/citerus/dddsample/service/JmsEventServiceImpl.java Целия файл

@@ -0,0 +1,36 @@
1
+package se.citerus.dddsample.service;
2
+
3
+import org.springframework.jms.core.JmsOperations;
4
+import org.springframework.jms.core.MessageCreator;
5
+import se.citerus.dddsample.domain.HandlingEvent;
6
+import se.citerus.dddsample.domain.TrackingId;
7
+
8
+import javax.jms.*;
9
+
10
+/**
11
+ * JMS based implementation.
12
+ */
13
+public class JmsEventServiceImpl implements EventService {
14
+  private JmsOperations jmsOperations;
15
+  private Destination destination;
16
+
17
+  public void fireHandlingEventRegistered(final HandlingEvent event) {
18
+    jmsOperations.send(destination, new MessageCreator() {
19
+
20
+      public Message createMessage(Session session) throws JMSException {
21
+        MapMessage message = session.createMapMessage();
22
+        message.setStringProperty(TrackingId.class.getName(), event.cargo().trackingId().idString());
23
+        return message;
24
+      }
25
+
26
+    });
27
+  }
28
+  
29
+  public void setJmsOperations(JmsOperations jmsOperations) {
30
+    this.jmsOperations = jmsOperations;
31
+  }
32
+
33
+  public void setDestination(Destination destination) {
34
+    this.destination = destination;
35
+  }
36
+}

+ 22
- 0
dddsample/src/main/java/se/citerus/dddsample/service/ThreadBasedEventServiceImpl.java Целия файл

@@ -0,0 +1,22 @@
1
+package se.citerus.dddsample.service;
2
+
3
+import se.citerus.dddsample.domain.HandlingEvent;
4
+
5
+/**
6
+ * Thread based implementation.
7
+ */
8
+public class ThreadBasedEventServiceImpl implements EventService {
9
+  private CargoService cargoService;
10
+
11
+  public void fireHandlingEventRegistered(final HandlingEvent event) {
12
+    new Thread(new Runnable() {
13
+      public void run() {
14
+        cargoService.notifyIfMisdirected(event.cargo().trackingId());
15
+      }
16
+    }).start();
17
+  }
18
+
19
+  public void setCargoService(CargoService cargoService) {
20
+    this.cargoService = cargoService;
21
+  }
22
+}

+ 3
- 1
dddsample/src/main/java/se/citerus/dddsample/web/CargoTrackingController.java Целия файл

@@ -3,6 +3,7 @@ package se.citerus.dddsample.web;
3 3
 import org.springframework.validation.BindException;
4 4
 import org.springframework.web.servlet.ModelAndView;
5 5
 import org.springframework.web.servlet.mvc.SimpleFormController;
6
+import se.citerus.dddsample.domain.TrackingId;
6 7
 import se.citerus.dddsample.service.CargoService;
7 8
 import se.citerus.dddsample.service.dto.CargoWithHistoryDTO;
8 9
 import se.citerus.dddsample.web.command.TrackCommand;
@@ -29,7 +30,8 @@ public class CargoTrackingController extends SimpleFormController {
29 30
   @Override
30 31
   protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception {
31 32
     final TrackCommand trackCommand = (TrackCommand) command;
32
-    final CargoWithHistoryDTO cargo = cargoService.track(trackCommand.getTrackingId());
33
+    final String tidStr = trackCommand.getTrackingId();
34
+    final CargoWithHistoryDTO cargo = cargoService.track(new TrackingId(tidStr));
33 35
 
34 36
     final Map<String, Object> model = new HashMap<String, Object>();
35 37
     if (cargo != null) {

+ 36
- 0
dddsample/src/main/resources/context-messaging.xml Целия файл

@@ -0,0 +1,36 @@
1
+<?xml version="1.0"?>
2
+
3
+<beans xmlns="http://www.springframework.org/schema/beans"
4
+       xmlns:jms="http://www.springframework.org/schema/jms"
5
+       xmlns:amq="http://activemq.org/config/1.0"
6
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
7
+       xsi:schemaLocation="
8
+        http://activemq.org/config/1.0 http://activemq.apache.org/schema/core/activemq-core-5.0.0.xsd
9
+        http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-2.5.xsd
10
+        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
11
+
12
+  <amq:broker useJmx="false" persistent="false">
13
+    <amq:transportConnectors>
14
+      <amq:transportConnector uri="tcp://localhost:0"/>
15
+    </amq:transportConnectors>
16
+  </amq:broker>
17
+
18
+  <amq:connectionFactory id="jmsConnectionFactory" brokerURL="vm://localhost"/>
19
+
20
+  <amq:topic id="handlingEventTopic" name="HandlingEventTopic" physicalName="HandlingEventTopic"/>
21
+
22
+  <bean id="handlingEventMessageDelegate" class="se.citerus.dddsample.service.HandlingEventMessageDelegate">
23
+    <property name="cargoService" ref="cargoService"/>
24
+  </bean>
25
+
26
+  <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
27
+    <property name="connectionFactory" ref="jmsConnectionFactory"/>
28
+    <property name="destination" ref="handlingEventTopic"/>
29
+    <property name="messageListener" ref="handlingEventMessageDelegate"/>
30
+  </bean>
31
+
32
+  <bean id="jmsOperations" class="org.springframework.jms.core.JmsTemplate">
33
+    <property name="connectionFactory" ref="jmsConnectionFactory"/>
34
+  </bean>
35
+
36
+</beans>

+ 13
- 1
dddsample/src/main/resources/context-service.xml Целия файл

@@ -20,8 +20,20 @@
20 20
   <bean id="handlingEventService" class="se.citerus.dddsample.service.HandlingEventServiceImpl">
21 21
     <property name="cargoRepository" ref="cargoRepository"/>
22 22
     <property name="handlingEventRepository" ref="handlingEventRepository"/>
23
-    <property name="carrierRepository" ref="carrierMovementRepository"/>
23
+    <property name="carrierMovementRepository" ref="carrierMovementRepository"/>
24 24
     <property name="locationRepository" ref="locationRepository"/>
25
+    <property name="eventService" ref="eventService"/>
25 26
   </bean>
26 27
 
28
+  <bean id="eventService" class="se.citerus.dddsample.service.JmsEventServiceImpl">
29
+    <property name="jmsOperations" ref="jmsOperations"/>
30
+    <property name="destination" ref="handlingEventTopic"/>
31
+  </bean>
32
+
33
+  <!--
34
+  <bean id="eventService" class="se.citerus.dddsample.service.ThreadBasedEventServiceImpl">
35
+    <property name="cargoService" ref="cargoService"/>
36
+  </bean>
37
+  -->
38
+
27 39
 </beans>

+ 2
- 2
dddsample/src/test/java/se/citerus/dddsample/service/CargoServiceTest.java Целия файл

@@ -99,7 +99,7 @@ public class CargoServiceTest extends AbstractDependencyInjectionSpringContextTe
99 99
 
100 100
 
101 101
     // Tested call
102
-    CargoWithHistoryDTO cargoDTO = cargoService.track("XYZ");
102
+    CargoWithHistoryDTO cargoDTO = cargoService.track(new TrackingId("XYZ"));
103 103
 
104 104
 
105 105
     assertEquals("XYZ", cargoDTO.getTrackingId());
@@ -137,7 +137,7 @@ public class CargoServiceTest extends AbstractDependencyInjectionSpringContextTe
137 137
     replay(cargoRepository);
138 138
 
139 139
     // Tested call
140
-    CargoWithHistoryDTO cargoDTO = cargoService.track("XYZ");
140
+    CargoWithHistoryDTO cargoDTO = cargoService.track(new TrackingId("XYZ"));
141 141
     
142 142
     assertNull(cargoDTO);
143 143
   }

+ 14
- 9
dddsample/src/test/java/se/citerus/dddsample/service/HandlingEventServiceTest.java Целия файл

@@ -12,6 +12,7 @@ import java.util.Date;
12 12
 
13 13
 public class HandlingEventServiceTest extends TestCase {
14 14
   private HandlingEventServiceImpl service;
15
+  private EventService eventService;
15 16
   private CargoRepository cargoRepository;
16 17
   private CarrierMovementRepository carrierMovementRepository;
17 18
   private HandlingEventRepository handlingEventRepository;
@@ -40,15 +41,17 @@ public class HandlingEventServiceTest extends TestCase {
40 41
     carrierMovementRepository = createMock(CarrierMovementRepository.class);
41 42
     handlingEventRepository = createMock(HandlingEventRepository.class);
42 43
     locationRepository = createMock(LocationRepository.class);
43
-    
44
+    eventService = createMock(EventService.class);
45
+
44 46
     service.setCargoRepository(cargoRepository);
45
-    service.setCarrierRepository(carrierMovementRepository);
47
+    service.setCarrierMovementRepository(carrierMovementRepository);
46 48
     service.setHandlingEventRepository(handlingEventRepository);
47 49
     service.setLocationRepository(locationRepository);
50
+    service.setEventService(eventService);
48 51
   }
49 52
 
50 53
   protected void tearDown() throws Exception {
51
-    verify(cargoRepository, carrierMovementRepository, handlingEventRepository);
54
+    verify(cargoRepository, carrierMovementRepository, handlingEventRepository, eventService);
52 55
   }
53 56
 
54 57
   public void testRegisterEvent() throws Exception {
@@ -65,8 +68,9 @@ public class HandlingEventServiceTest extends TestCase {
65 68
 
66 69
     // TODO: does not inspect the handling event instance in a sufficient way
67 70
     handlingEventRepository.save(isA(HandlingEvent.class));
71
+    eventService.fireHandlingEventRegistered(isA(HandlingEvent.class));
68 72
 
69
-    replay(cargoRepository, carrierMovementRepository, handlingEventRepository, locationRepository);
73
+    replay(cargoRepository, carrierMovementRepository, handlingEventRepository, locationRepository, eventService);
70 74
     
71 75
     service.register(date, trackingId, carrierMovementId, unLocode, HandlingEvent.Type.LOAD);
72 76
   }
@@ -78,10 +82,11 @@ public class HandlingEventServiceTest extends TestCase {
78 82
     expect(cargoRepository.find(trackingId)).andReturn(cargoABC);
79 83
 
80 84
     handlingEventRepository.save(isA(HandlingEvent.class));
81
-    
85
+    eventService.fireHandlingEventRegistered(isA(HandlingEvent.class));
86
+
82 87
     expect(locationRepository.find(stockholm.unLocode())).andReturn(stockholm);
83 88
 
84
-    replay(cargoRepository, carrierMovementRepository, handlingEventRepository, locationRepository);
89
+    replay(cargoRepository, carrierMovementRepository, handlingEventRepository, locationRepository, eventService);
85 90
 
86 91
     service.register(date, trackingId, null, stockholm.unLocode(), HandlingEvent.Type.CLAIM);
87 92
   }
@@ -98,7 +103,7 @@ public class HandlingEventServiceTest extends TestCase {
98 103
 
99 104
     expect(locationRepository.find(melbourne.unLocode())).andReturn(melbourne);
100 105
     
101
-    replay(cargoRepository, carrierMovementRepository, handlingEventRepository, locationRepository);
106
+    replay(cargoRepository, carrierMovementRepository, handlingEventRepository, locationRepository, eventService);
102 107
     
103 108
     try {
104 109
       service.register(date, trackingId, carrierMovementId, melbourne.unLocode(), HandlingEvent.Type.UNLOAD);
@@ -114,7 +119,7 @@ public class HandlingEventServiceTest extends TestCase {
114 119
 
115 120
     expect(locationRepository.find(hongkong.unLocode())).andReturn(hongkong);
116 121
     
117
-    replay(cargoRepository, carrierMovementRepository, handlingEventRepository, locationRepository);
122
+    replay(cargoRepository, carrierMovementRepository, handlingEventRepository, locationRepository, eventService);
118 123
     
119 124
     try {
120 125
       service.register(date, trackingId, null, hongkong.unLocode(), HandlingEvent.Type.CLAIM);
@@ -130,7 +135,7 @@ public class HandlingEventServiceTest extends TestCase {
130 135
     UnLocode wayOff = new UnLocode("XX", "YYY");
131 136
     expect(locationRepository.find(wayOff)).andReturn(null);
132 137
     
133
-    replay(cargoRepository, carrierMovementRepository, handlingEventRepository, locationRepository);
138
+    replay(cargoRepository, carrierMovementRepository, handlingEventRepository, locationRepository, eventService);
134 139
     
135 140
     try {
136 141
       service.register(date, trackingId, null, wayOff, HandlingEvent.Type.CLAIM);

+ 7
- 3
dddsample/src/test/java/se/citerus/dddsample/web/CargoTrackingControllerTest.java Целия файл

@@ -39,10 +39,10 @@ public class CargoTrackingControllerTest extends TestCase {
39 39
 
40 40
   private CargoService getCargoServiceMock() {
41 41
     return new CargoService() {
42
-      public CargoWithHistoryDTO track(String trackingId) {
42
+      public CargoWithHistoryDTO track(TrackingId trackingId) {
43 43
         final Location a5 = new Location(new UnLocode("AA","AAA"), "AAAAA");
44 44
         final Location b5 = new Location(new UnLocode("BB","BBB"), "BBBBB");
45
-        Cargo cargo = new Cargo(new TrackingId(trackingId), a5, b5);
45
+        Cargo cargo = new Cargo(trackingId, a5, b5);
46 46
         HandlingEvent event = new HandlingEvent(cargo, new Date(10L), new Date(20L), HandlingEvent.Type.RECEIVE, b5);
47 47
 //        cargo.handle(event);
48 48
 
@@ -61,14 +61,18 @@ public class CargoTrackingControllerTest extends TestCase {
61 61
           event.completionTime()));
62 62
         return cargoDTO;
63 63
       }
64
+
65
+      public void notifyIfMisdirected(TrackingId trackingId) {
66
+      }
64 67
     };
65 68
   }
66 69
   
67 70
   private CargoService getCargoServiceNullMock() {
68 71
     return new CargoService() {
69
-      public CargoWithHistoryDTO track(String trackingId) {
72
+      public CargoWithHistoryDTO track(TrackingId trackingId) {
70 73
         return null;
71 74
       }
75
+      public void notifyIfMisdirected(TrackingId trackingId) {}
72 76
     };
73 77
   }
74 78
 

+ 11
- 2
dddsample/src/test/resources/mock-context-persistence.xml Целия файл

@@ -20,7 +20,16 @@
20 20
     <constructor-arg value="se.citerus.dddsample.repository.CarrierMovementRepository"/>
21 21
   </bean>
22 22
 
23
-  <bean id="locationRepository" class="se.citerus.dddsample.repository.LocationRepositoryHibernate">
24
-    <property name="sessionFactory" ref="sessionFactory"/>
23
+  <bean id="locationRepository" class="org.easymock.EasyMock" factory-method="createMock">
24
+    <constructor-arg value="se.citerus.dddsample.repository.LocationRepository"/>
25 25
   </bean>
26
+
27
+  <bean id="jmsOperations" class="org.easymock.EasyMock" factory-method="createMock">
28
+    <constructor-arg value="org.springframework.jms.core.JmsOperations"/>
29
+  </bean>
30
+
31
+  <bean id="handlingEventTopic" class="org.easymock.EasyMock" factory-method="createMock">
32
+    <constructor-arg value="javax.jms.Destination"/>
33
+  </bean>
34
+  
26 35
 </beans>