浏览代码

Refactored construction of HandlingEvent instance into a factory, which uses repositories for assembly.

peter_backlund 18 年前
父节点
当前提交
e335d1895b

+ 3
- 0
dddsample/src/main/java/se/citerus/dddsample/application/ws/HandlingEventServiceEndpoint.java 查看文件

@@ -19,4 +19,7 @@ public interface HandlingEventServiceEndpoint {
19 19
    */
20 20
   void register(String completionTime, String trackingId, String carrierMovementId, String unlocode, String eventType);
21 21
 
22
+  // TODO structured class that holds these fields, and/or a batching method that accepts a list of those
23
+  // TODO contract-first instead of code-first (?)
24
+  
22 25
 }

+ 48
- 31
dddsample/src/main/java/se/citerus/dddsample/application/ws/HandlingEventServiceEndpointImpl.java 查看文件

@@ -10,6 +10,7 @@ import org.springframework.transaction.support.TransactionTemplate;
10 10
 import se.citerus.dddsample.domain.model.cargo.TrackingId;
11 11
 import se.citerus.dddsample.domain.model.carrier.CarrierMovementId;
12 12
 import se.citerus.dddsample.domain.model.handling.HandlingEvent;
13
+import se.citerus.dddsample.domain.model.handling.HandlingEventFactory;
13 14
 import se.citerus.dddsample.domain.model.location.UnLocode;
14 15
 import se.citerus.dddsample.domain.service.HandlingEventService;
15 16
 import se.citerus.dddsample.domain.service.UnknownCarrierMovementIdException;
@@ -24,6 +25,7 @@ import java.util.Date;
24 25
 @WebService(endpointInterface = "se.citerus.dddsample.application.ws.HandlingEventServiceEndpoint")
25 26
 public class HandlingEventServiceEndpointImpl implements HandlingEventServiceEndpoint {
26 27
 
28
+  private HandlingEventFactory handlingEventFactory;
27 29
   private HandlingEventService handlingEventService;
28 30
   private TransactionTemplate transactionTemplate;
29 31
   private final Log logger = LogFactory.getLog(getClass());
@@ -41,27 +43,9 @@ public class HandlingEventServiceEndpointImpl implements HandlingEventServiceEnd
41 43
         cid = null;
42 44
       }
43 45
       final HandlingEvent.Type type = parseEventType(eventType);
44
-
45 46
       final UnLocode ul = new UnLocode(unlocode);
46 47
 
47
-      // Using programmatic demarcation here due to weaving conflicts
48
-      // between jax-ws and Spring transaction annotations
49
-      transactionTemplate.execute(new TransactionCallbackWithoutResult() {
50
-          protected void doInTransactionWithoutResult(TransactionStatus status) {
51
-              try {
52
-
53
-                  handlingEventService.register(date, tid, cid, ul, type);
54
-
55
-              } catch (UnknownCarrierMovementIdException e) {
56
-                  handleUnknownCarrierMovementId(e);
57
-              } catch (UnknownTrackingIdException e) {
58
-                  handleUnknownTrackingId(e);
59
-              } catch (UnknownLocationException e) {
60
-                  handleOtherError(e);
61
-              }
62
-          }
63
-      });
64
-
48
+      doRegister(date, tid, cid, type, ul);
65 49
     } catch (IllegalArgumentException iae) {
66 50
       handleIllegalArgument(iae);
67 51
     } catch (ParseException pe) {
@@ -73,6 +57,40 @@ public class HandlingEventServiceEndpointImpl implements HandlingEventServiceEnd
73 57
     }
74 58
   }
75 59
 
60
+  // TODO this entire step would be well suited to move to a consumer of asynchronous messages
61
+  private void doRegister(final Date date, final TrackingId tid, final CarrierMovementId cid, final HandlingEvent.Type type, final UnLocode ul) {
62
+    // Using programmatic demarcation here due to weaving conflicts
63
+    // between jax-ws and Spring transaction annotations
64
+    transactionTemplate.execute(new TransactionCallbackWithoutResult() {
65
+        protected void doInTransactionWithoutResult(TransactionStatus status) {
66
+            try {
67
+                HandlingEvent event = handlingEventFactory.createHandlingEvent(date, tid, cid, ul, type);
68
+                handlingEventService.register(event);
69
+            } catch (UnknownCarrierMovementIdException e) {
70
+                handleUnknownCarrierMovementId(e);
71
+            } catch (UnknownTrackingIdException e) {
72
+                handleUnknownTrackingId(e);
73
+            } catch (UnknownLocationException e) {
74
+                handleUnknownLocation(e);
75
+            }
76
+        }
77
+    });
78
+  }
79
+
80
+  private HandlingEvent.Type parseEventType(final String eventType) throws InvalidEventTypeException {
81
+    try {
82
+      return HandlingEvent.Type.valueOf(eventType);
83
+    } catch (IllegalArgumentException e) {
84
+      throw new InvalidEventTypeException(eventType);
85
+    }
86
+  }
87
+
88
+  private Date parseIso8601Date(final String completionTime) throws ParseException {
89
+    return new SimpleDateFormat(ISO_8601_FORMAT).parse(completionTime);
90
+  }
91
+
92
+  // Validation/translation errors
93
+
76 94
   private void handleIllegalArgument(IllegalArgumentException iae) {
77 95
     logger.error(iae, iae);
78 96
   }
@@ -89,27 +107,23 @@ public class HandlingEventServiceEndpointImpl implements HandlingEventServiceEnd
89 107
     logger.error("Invalid date format: " + completionTime + ", must be on ISO 8601 format: " + ISO_8601_FORMAT);
90 108
   }
91 109
 
92
-  private HandlingEvent.Type parseEventType(final String eventType) throws InvalidEventTypeException {
93
-    try {
94
-      return HandlingEvent.Type.valueOf(eventType);
95
-    } catch (IllegalArgumentException e) {
96
-      throw new InvalidEventTypeException(eventType);
97
-    }
110
+  // Domain errors, don't belong here really
111
+
112
+  private void handleUnknownLocation(UnknownLocationException e) {
113
+    logger.error(e, e);
98 114
   }
99 115
 
100 116
   private void handleUnknownCarrierMovementId(UnknownCarrierMovementIdException e) {
101
-    logger.info("Placing event in retry queue due to: " + e.getMessage());
117
+    logger.error(e, e);
102 118
   }
103 119
 
104 120
   private void handleUnknownTrackingId(Exception e) {
105
-    logger.info("Placing event in retry queue due to: " + e.getMessage());
121
+    logger.error(e, e);
106 122
   }
107 123
 
108
-  private Date parseIso8601Date(final String completionTime) throws ParseException {
109
-    return new SimpleDateFormat(ISO_8601_FORMAT).parse(completionTime);
110
-  }
124
+  // Setters
111 125
 
112
-  public void setHandlingEventService(final HandlingEventService handlingEventService) {
126
+  public void setHandlingEventService(HandlingEventService handlingEventService) {
113 127
     this.handlingEventService = handlingEventService;
114 128
   }
115 129
 
@@ -117,4 +131,7 @@ public class HandlingEventServiceEndpointImpl implements HandlingEventServiceEnd
117 131
       transactionTemplate = new TransactionTemplate(transactionManager);
118 132
   }
119 133
 
134
+  public void setHandlingEventFactory(HandlingEventFactory handlingEventFactory) {
135
+    this.handlingEventFactory = handlingEventFactory;
136
+  }
120 137
 }

+ 103
- 0
dddsample/src/main/java/se/citerus/dddsample/domain/model/handling/HandlingEventFactory.java 查看文件

@@ -0,0 +1,103 @@
1
+package se.citerus.dddsample.domain.model.handling;
2
+
3
+import org.apache.commons.lang.Validate;
4
+import se.citerus.dddsample.domain.model.cargo.Cargo;
5
+import se.citerus.dddsample.domain.model.cargo.CargoRepository;
6
+import se.citerus.dddsample.domain.model.cargo.TrackingId;
7
+import se.citerus.dddsample.domain.model.carrier.CarrierMovement;
8
+import se.citerus.dddsample.domain.model.carrier.CarrierMovementId;
9
+import se.citerus.dddsample.domain.model.carrier.CarrierMovementRepository;
10
+import se.citerus.dddsample.domain.model.location.Location;
11
+import se.citerus.dddsample.domain.model.location.LocationRepository;
12
+import se.citerus.dddsample.domain.model.location.UnLocode;
13
+import se.citerus.dddsample.domain.service.UnknownCarrierMovementIdException;
14
+import se.citerus.dddsample.domain.service.UnknownLocationException;
15
+import se.citerus.dddsample.domain.service.UnknownTrackingIdException;
16
+
17
+import java.util.Date;
18
+
19
+/**
20
+ * Creates handling events.
21
+ */
22
+public class HandlingEventFactory {
23
+
24
+  private CargoRepository cargoRepository;
25
+  private CarrierMovementRepository carrierMovementRepository;
26
+  private LocationRepository locationRepository;
27
+
28
+  /**
29
+   * @param completionTime    when the event was completed, for example finished loading
30
+   * @param trackingId        tracking id
31
+   * @param carrierMovementId carrier movement id, if applicable (may be null)
32
+   * @param unlocode          United Nations Location Code for the location of the event
33
+   * @param type              type of event
34
+   * @throws UnknownCarrierMovementIdException
35
+   *                                    if there's not carrier movement with this id
36
+   * @throws UnknownTrackingIdException if there's no cargo with this tracking id
37
+   * @throws UnknownLocationException   if there's no location with this UN Locode
38
+   * @return A handling event.
39
+   */
40
+  public HandlingEvent createHandlingEvent(Date completionTime, TrackingId trackingId, CarrierMovementId carrierMovementId, UnLocode unlocode, HandlingEvent.Type type)
41
+    throws UnknownTrackingIdException, UnknownCarrierMovementIdException, UnknownLocationException {
42
+
43
+    // Carrier movement may be null for certain event types
44
+    Validate.noNullElements(new Object[]{trackingId, unlocode, type});
45
+
46
+    final Cargo cargo = cargoRepository.find(trackingId);
47
+    if (cargo == null) throw new UnknownTrackingIdException(trackingId);
48
+
49
+    final CarrierMovement carrierMovement = findCarrierMovement(carrierMovementId);
50
+
51
+    final Location location = findLocation(unlocode);
52
+    if (location == null) throw new UnknownLocationException(unlocode);
53
+
54
+    final Date registrationTime = new Date();
55
+
56
+    if (carrierMovement == null) {
57
+      return new HandlingEvent(cargo, completionTime, registrationTime, type, location);   
58
+    } else {
59
+      return new HandlingEvent(cargo, completionTime, registrationTime, type, location, carrierMovement);
60
+    }
61
+  }
62
+
63
+  private CarrierMovement findCarrierMovement(final CarrierMovementId carrierMovementId)
64
+    throws UnknownCarrierMovementIdException {
65
+
66
+    if (carrierMovementId == null) {
67
+      return null;
68
+    }
69
+    final CarrierMovement carrierMovement = carrierMovementRepository.find(carrierMovementId);
70
+    if (carrierMovement == null) {
71
+      throw new UnknownCarrierMovementIdException(carrierMovementId);
72
+    }
73
+
74
+    return carrierMovement;
75
+  }
76
+
77
+  private Location findLocation(final UnLocode unlocode) throws UnknownLocationException {
78
+    if (unlocode == null) {
79
+      return Location.UNKNOWN;
80
+    }
81
+
82
+    final Location location = locationRepository.find(unlocode);
83
+    if (location == null) {
84
+      throw new UnknownLocationException(unlocode);
85
+    }
86
+
87
+    return location;
88
+  }
89
+
90
+  public void setCargoRepository(final CargoRepository cargoRepository) {
91
+    this.cargoRepository = cargoRepository;
92
+  }
93
+
94
+  public void setCarrierMovementRepository(final CarrierMovementRepository carrierMovementRepository) {
95
+    this.carrierMovementRepository = carrierMovementRepository;
96
+  }
97
+
98
+  public void setLocationRepository(final LocationRepository locationRepository) {
99
+    this.locationRepository = locationRepository;
100
+  }
101
+
102
+
103
+}

+ 5
- 16
dddsample/src/main/java/se/citerus/dddsample/domain/service/HandlingEventService.java 查看文件

@@ -1,11 +1,6 @@
1 1
 package se.citerus.dddsample.domain.service;
2 2
 
3
-import se.citerus.dddsample.domain.model.cargo.TrackingId;
4
-import se.citerus.dddsample.domain.model.carrier.CarrierMovementId;
5 3
 import se.citerus.dddsample.domain.model.handling.HandlingEvent;
6
-import se.citerus.dddsample.domain.model.location.UnLocode;
7
-
8
-import java.util.Date;
9 4
 
10 5
 
11 6
 /**
@@ -14,17 +9,11 @@ import java.util.Date;
14 9
 public interface HandlingEventService {
15 10
 
16 11
   /**
17
-   * @param completionTime    when the event was completed, for example finished loading
18
-   * @param trackingId        tracking id
19
-   * @param carrierMovementId carrier movement id, if applicable (may be null)
20
-   * @param unlocode          United Nations Location Code for the location of the event
21
-   * @param type              type of event
22
-   * @throws UnknownCarrierMovementIdException
23
-   *                                    if there's not carrier movement with this id
24
-   * @throws UnknownTrackingIdException if there's no cargo with this tracking id
25
-   * @throws UnknownLocationException   if there's no location with this UN Locode
12
+   * Registers a handling event in the system, and notifies interested
13
+   * parties that an event has been registered.
14
+   *
15
+   * @param event handling event to register
26 16
    */
27
-  void register(Date completionTime, TrackingId trackingId, CarrierMovementId carrierMovementId, UnLocode unlocode, HandlingEvent.Type type)
28
-  throws UnknownCarrierMovementIdException, UnknownTrackingIdException, UnknownLocationException;
17
+  void register(HandlingEvent event);
29 18
 
30 19
 }

+ 14
- 81
dddsample/src/main/java/se/citerus/dddsample/domain/service/impl/HandlingEventServiceImpl.java 查看文件

@@ -1,103 +1,36 @@
1 1
 package se.citerus.dddsample.domain.service.impl;
2 2
 
3
-import org.apache.commons.lang.Validate;
4
-import se.citerus.dddsample.domain.model.cargo.Cargo;
5
-import se.citerus.dddsample.domain.model.cargo.CargoRepository;
6
-import se.citerus.dddsample.domain.model.cargo.TrackingId;
7
-import se.citerus.dddsample.domain.model.carrier.CarrierMovement;
8
-import se.citerus.dddsample.domain.model.carrier.CarrierMovementId;
9
-import se.citerus.dddsample.domain.model.carrier.CarrierMovementRepository;
10 3
 import se.citerus.dddsample.domain.model.handling.HandlingEvent;
11 4
 import se.citerus.dddsample.domain.model.handling.HandlingEventRepository;
12
-import se.citerus.dddsample.domain.model.location.Location;
13
-import se.citerus.dddsample.domain.model.location.LocationRepository;
14
-import se.citerus.dddsample.domain.model.location.UnLocode;
15
-import se.citerus.dddsample.domain.service.*;
16
-
17
-import java.util.Date;
5
+import se.citerus.dddsample.domain.service.DomainEventNotifier;
6
+import se.citerus.dddsample.domain.service.HandlingEventService;
18 7
 
19 8
 public final class HandlingEventServiceImpl implements HandlingEventService {
20
-  private CargoRepository cargoRepository;
21
-  private CarrierMovementRepository carrierMovementRepository;
9
+
22 10
   private HandlingEventRepository handlingEventRepository;
23
-  private LocationRepository locationRepository;
24 11
   private DomainEventNotifier domainEventNotifier;
25 12
 
26
-  public void register(final Date completionTime, final TrackingId trackingId, final CarrierMovementId carrierMovementId,
27
-                       final UnLocode unlocode, final HandlingEvent.Type type)
28
-    throws UnknownCarrierMovementIdException, UnknownTrackingIdException, UnknownLocationException {
29
-
30
-    // Carrier movement may be null for certain event types
31
-    Validate.noNullElements(new Object[]{trackingId, unlocode, type});
32
-
33
-    Cargo cargo = cargoRepository.find(trackingId);
34
-    if (cargo == null) throw new UnknownTrackingIdException(trackingId);
35
-
36
-    final CarrierMovement carrierMovement = findCarrierMovement(carrierMovementId);
37
-    final Location location = findLocation(unlocode);
38
-    final Date registrationTime = new Date();
39
-
40
-    final HandlingEvent event = new HandlingEvent(cargo, completionTime, registrationTime, type, location, carrierMovement);
41
-
13
+  public void register(final HandlingEvent event) {
42 14
     /*
43
-      NOTE:
44
-        The cargo instance that's loaded and associated with the handling event is
45
-        in an inconsitent state, because the cargo delivery history's collection of
46
-        events does not contain the event created here. However, this is not a problem,
47
-        because cargo is in a different aggregate from handling event.
48
-
49
-        The rules of an aggregate dictate that all consistency rules within the aggregate
50
-        are enforced synchronously in the transaction, but consistency rules of other aggregates
51
-        are enforced by asynchronous updates, after the commit of this transaction.
52
-     */
15
+     NOTE:
16
+       The cargo instance that's loaded and associated with the handling event is
17
+       in an inconsitent state, because the cargo delivery history's collection of
18
+       events does not contain the event created here. However, this is not a problem,
19
+       because cargo is in a different aggregate from handling event.
20
+
21
+       The rules of an aggregate dictate that all consistency rules within the aggregate
22
+       are enforced synchronously in the transaction, but consistency rules of other aggregates
23
+       are enforced by asynchronous updates, after the commit of this transaction.
24
+    */
53 25
     handlingEventRepository.save(event);
54 26
 
55 27
     domainEventNotifier.cargoWasHandled(event);
56 28
   }
57 29
 
58
-  private CarrierMovement findCarrierMovement(final CarrierMovementId carrierMovementId)
59
-    throws UnknownCarrierMovementIdException {
60
-
61
-    if (carrierMovementId == null) {
62
-      return null;
63
-    }
64
-    final CarrierMovement carrierMovement = carrierMovementRepository.find(carrierMovementId);
65
-    if (carrierMovement == null) {
66
-      throw new UnknownCarrierMovementIdException(carrierMovementId);
67
-    }
68
-
69
-    return carrierMovement;
70
-  }
71
-
72
-  private Location findLocation(final UnLocode unlocode) throws UnknownLocationException {
73
-    if (unlocode == null) {
74
-      return Location.UNKNOWN;
75
-    }
76
-
77
-    final Location location = locationRepository.find(unlocode);
78
-    if (location == null) {
79
-      throw new UnknownLocationException(unlocode);
80
-    }
81
-
82
-    return location;
83
-  }
84
-
85
-  public void setCargoRepository(final CargoRepository cargoRepository) {
86
-    this.cargoRepository = cargoRepository;
87
-  }
88
-
89
-  public void setCarrierMovementRepository(final CarrierMovementRepository carrierMovementRepository) {
90
-    this.carrierMovementRepository = carrierMovementRepository;
91
-  }
92
-
93 30
   public void setHandlingEventRepository(final HandlingEventRepository handlingEventRepository) {
94 31
     this.handlingEventRepository = handlingEventRepository;
95 32
   }
96 33
 
97
-  public void setLocationRepository(final LocationRepository locationRepository) {
98
-    this.locationRepository = locationRepository;
99
-  }
100
-
101 34
   public void setDomainEventNotifier(DomainEventNotifier domainEventNotifier) {
102 35
     this.domainEventNotifier = domainEventNotifier;
103 36
   }

+ 9
- 3
dddsample/src/test/java/se/citerus/dddsample/application/ws/HandlinEventServiceEndpointTest.java 查看文件

@@ -6,6 +6,7 @@ import se.citerus.dddsample.application.service.InMemTransactionManager;
6 6
 import se.citerus.dddsample.domain.model.cargo.TrackingId;
7 7
 import se.citerus.dddsample.domain.model.carrier.CarrierMovementId;
8 8
 import se.citerus.dddsample.domain.model.handling.HandlingEvent;
9
+import se.citerus.dddsample.domain.model.handling.HandlingEventFactory;
9 10
 import se.citerus.dddsample.domain.model.location.UnLocode;
10 11
 import se.citerus.dddsample.domain.service.HandlingEventService;
11 12
 import se.citerus.dddsample.domain.service.UnknownCarrierMovementIdException;
@@ -18,9 +19,11 @@ public class HandlinEventServiceEndpointTest extends TestCase {
18 19
 
19 20
   private HandlingEventServiceEndpointImpl endpoint;
20 21
   private HandlingEventService handlingEventService;
22
+  private HandlingEventFactory handlingEventFactory;
21 23
   private SimpleDateFormat sdf;
22 24
 
23 25
   protected void setUp() throws Exception {
26
+    handlingEventFactory = new HandlingEventFactory();
24 27
     endpoint = new HandlingEventServiceEndpointImpl();
25 28
     handlingEventService = createMock(HandlingEventService.class);
26 29
     endpoint.setHandlingEventService(handlingEventService);
@@ -31,7 +34,8 @@ public class HandlinEventServiceEndpointTest extends TestCase {
31 34
   public void testRegisterValidEvent() throws Exception {
32 35
     Date date = new Date(100);
33 36
 
34
-    handlingEventService.register(date, new TrackingId("FOO"), new CarrierMovementId("CAR_456"), new UnLocode("CNHKG"), HandlingEvent.Type.LOAD);
37
+    final HandlingEvent event = handlingEventFactory.createHandlingEvent(date, new TrackingId("FOO"), new CarrierMovementId("CAR_456"), new UnLocode("CNHKG"), HandlingEvent.Type.LOAD);
38
+    handlingEventService.register(event);
35 39
     replay(handlingEventService);
36 40
 
37 41
     // Tested call
@@ -45,7 +49,8 @@ public class HandlinEventServiceEndpointTest extends TestCase {
45 49
     TrackingId trackingId = new TrackingId("NOTFOUND");
46 50
     UnLocode unlocode = new UnLocode("SESTO");
47 51
 
48
-    handlingEventService.register(date, trackingId, null, unlocode, HandlingEvent.Type.CLAIM);
52
+    final HandlingEvent event = handlingEventFactory.createHandlingEvent(date, trackingId, null, unlocode, HandlingEvent.Type.CLAIM);
53
+    handlingEventService.register(event);
49 54
     expectLastCall().andThrow(new UnknownTrackingIdException(trackingId));
50 55
     replay(handlingEventService);
51 56
 
@@ -59,7 +64,8 @@ public class HandlinEventServiceEndpointTest extends TestCase {
59 64
     TrackingId trackingId = new TrackingId("XYZ");
60 65
     CarrierMovementId carrierMovementId = new CarrierMovementId("NOTFOUND");
61 66
 
62
-    handlingEventService.register(date, trackingId, carrierMovementId, new UnLocode("AUMEL"), HandlingEvent.Type.UNLOAD);
67
+    final HandlingEvent event = handlingEventFactory.createHandlingEvent(date, trackingId, carrierMovementId, new UnLocode("AUMEL"), HandlingEvent.Type.UNLOAD);
68
+    handlingEventService.register(event);
63 69
     expectLastCall().andThrow(new UnknownCarrierMovementIdException(carrierMovementId));
64 70
     replay(handlingEventService);
65 71
 

+ 17
- 9
dddsample/src/test/java/se/citerus/dddsample/domain/service/HandlingEventServiceTest.java 查看文件

@@ -9,6 +9,7 @@ import se.citerus.dddsample.domain.model.carrier.CarrierMovementId;
9 9
 import se.citerus.dddsample.domain.model.carrier.CarrierMovementRepository;
10 10
 import se.citerus.dddsample.domain.model.carrier.SampleCarrierMovements;
11 11
 import se.citerus.dddsample.domain.model.handling.HandlingEvent;
12
+import se.citerus.dddsample.domain.model.handling.HandlingEventFactory;
12 13
 import se.citerus.dddsample.domain.model.handling.HandlingEventRepository;
13 14
 import se.citerus.dddsample.domain.model.location.LocationRepository;
14 15
 import static se.citerus.dddsample.domain.model.location.SampleLocations.*;
@@ -24,6 +25,7 @@ public class HandlingEventServiceTest extends TestCase {
24 25
   private CarrierMovementRepository carrierMovementRepository;
25 26
   private HandlingEventRepository handlingEventRepository;
26 27
   private LocationRepository locationRepository;
28
+  private HandlingEventFactory handlingEventFactory;
27 29
 
28 30
   private final Cargo cargoABC = new Cargo(new TrackingId("ABC"), HAMBURG, TOKYO);
29 31
 
@@ -36,11 +38,12 @@ public class HandlingEventServiceTest extends TestCase {
36 38
     handlingEventRepository = createMock(HandlingEventRepository.class);
37 39
     locationRepository = createMock(LocationRepository.class);
38 40
     domainEventNotifier = createMock(DomainEventNotifier.class);
41
+    handlingEventFactory = new HandlingEventFactory();
39 42
 
40
-    service.setCargoRepository(cargoRepository);
41
-    service.setCarrierMovementRepository(carrierMovementRepository);
43
+    handlingEventFactory.setCargoRepository(cargoRepository);
44
+    handlingEventFactory.setCarrierMovementRepository(carrierMovementRepository);
45
+    handlingEventFactory.setLocationRepository(locationRepository);
42 46
     service.setHandlingEventRepository(handlingEventRepository);
43
-    service.setLocationRepository(locationRepository);
44 47
     service.setDomainEventNotifier(domainEventNotifier);
45 48
   }
46 49
 
@@ -65,8 +68,9 @@ public class HandlingEventServiceTest extends TestCase {
65 68
     domainEventNotifier.cargoWasHandled(isA(HandlingEvent.class));
66 69
 
67 70
     replay(cargoRepository, carrierMovementRepository, handlingEventRepository, locationRepository, domainEventNotifier);
68
-    
69
-    service.register(date, trackingId, carrierMovementId, unLocode, HandlingEvent.Type.LOAD);
71
+
72
+    final HandlingEvent event = handlingEventFactory.createHandlingEvent(date, trackingId, carrierMovementId, unLocode, HandlingEvent.Type.LOAD);
73
+    service.register(event);
70 74
   }
71 75
 
72 76
   public void testRegisterEventWithoutCarrierMovement() throws Exception {
@@ -82,7 +86,8 @@ public class HandlingEventServiceTest extends TestCase {
82 86
 
83 87
     replay(cargoRepository, carrierMovementRepository, handlingEventRepository, locationRepository, domainEventNotifier);
84 88
 
85
-    service.register(date, trackingId, null, STOCKHOLM.unLocode(), HandlingEvent.Type.CLAIM);
89
+    final HandlingEvent event = handlingEventFactory.createHandlingEvent(date, trackingId, null, STOCKHOLM.unLocode(), HandlingEvent.Type.CLAIM);
90
+    service.register(event);
86 91
   }
87 92
   
88 93
 
@@ -100,7 +105,8 @@ public class HandlingEventServiceTest extends TestCase {
100 105
     replay(cargoRepository, carrierMovementRepository, handlingEventRepository, locationRepository, domainEventNotifier);
101 106
     
102 107
     try {
103
-      service.register(date, trackingId, carrierMovementId, MELBOURNE.unLocode(), HandlingEvent.Type.UNLOAD);
108
+      final HandlingEvent event = handlingEventFactory.createHandlingEvent(date, trackingId, carrierMovementId, MELBOURNE.unLocode(), HandlingEvent.Type.UNLOAD);
109
+      service.register(event);
104 110
       fail("Should not be able to register an event with non-existing carrier movement");
105 111
     } catch (UnknownCarrierMovementIdException expected) {}
106 112
   }
@@ -116,7 +122,8 @@ public class HandlingEventServiceTest extends TestCase {
116 122
     replay(cargoRepository, carrierMovementRepository, handlingEventRepository, locationRepository, domainEventNotifier);
117 123
     
118 124
     try {
119
-      service.register(date, trackingId, null, HONGKONG.unLocode(), HandlingEvent.Type.CLAIM);
125
+      final HandlingEvent event = handlingEventFactory.createHandlingEvent(date, trackingId, null, HONGKONG.unLocode(), HandlingEvent.Type.CLAIM);
126
+      service.register(event);
120 127
       fail("Should not be able to register an event with non-existing cargo");
121 128
     } catch (UnknownTrackingIdException expected) {}
122 129
   }
@@ -132,7 +139,8 @@ public class HandlingEventServiceTest extends TestCase {
132 139
     replay(cargoRepository, carrierMovementRepository, handlingEventRepository, locationRepository, domainEventNotifier);
133 140
     
134 141
     try {
135
-      service.register(date, trackingId, null, wayOff, HandlingEvent.Type.CLAIM);
142
+      final HandlingEvent event = handlingEventFactory.createHandlingEvent(date, trackingId, null, wayOff, HandlingEvent.Type.CLAIM);
143
+      service.register(event);
136 144
       fail("Should not be able to register an event with non-existing Location");
137 145
     } catch (UnknownLocationException expected) {}
138 146
   }