|
|
@@ -1,22 +1,23 @@
|
|
1
|
1
|
package se.citerus.dddsample.tracking.core.domain.scenario;
|
|
2
|
2
|
|
|
|
3
|
+import org.junit.Test;
|
|
|
4
|
+import se.citerus.dddsample.tracking.core.domain.model.cargo.*;
|
|
|
5
|
+import se.citerus.dddsample.tracking.core.domain.service.RoutingService;
|
|
|
6
|
+import se.citerus.dddsample.tracking.core.infrastructure.persistence.inmemory.TrackingIdFactoryInMem;
|
|
|
7
|
+
|
|
|
8
|
+import java.util.Date;
|
|
|
9
|
+import java.util.List;
|
|
|
10
|
+
|
|
|
11
|
+import static java.util.Arrays.asList;
|
|
3
|
12
|
import static org.hamcrest.core.Is.is;
|
|
4
|
13
|
import static org.junit.Assert.*;
|
|
5
|
|
-import org.junit.Test;
|
|
6
|
14
|
import static se.citerus.dddsample.tracking.core.application.util.DateTestUtil.toDate;
|
|
7
|
|
-import se.citerus.dddsample.tracking.core.domain.model.cargo.*;
|
|
8
|
15
|
import static se.citerus.dddsample.tracking.core.domain.model.cargo.RoutingStatus.*;
|
|
9
|
16
|
import static se.citerus.dddsample.tracking.core.domain.model.cargo.TransportStatus.*;
|
|
10
|
17
|
import static se.citerus.dddsample.tracking.core.domain.model.location.SampleLocations.*;
|
|
11
|
18
|
import static se.citerus.dddsample.tracking.core.domain.model.shared.HandlingActivity.*;
|
|
12
|
19
|
import static se.citerus.dddsample.tracking.core.domain.model.voyage.SampleVoyages.*;
|
|
13
|
20
|
import static se.citerus.dddsample.tracking.core.domain.model.voyage.Voyage.NONE;
|
|
14
|
|
-import se.citerus.dddsample.tracking.core.domain.service.RoutingService;
|
|
15
|
|
-import se.citerus.dddsample.tracking.core.infrastructure.persistence.inmemory.TrackingIdFactoryInMem;
|
|
16
|
|
-
|
|
17
|
|
-import static java.util.Arrays.asList;
|
|
18
|
|
-import java.util.Date;
|
|
19
|
|
-import java.util.List;
|
|
20
|
21
|
|
|
21
|
22
|
public class CargoLifecycle {
|
|
22
|
23
|
|
|
|
@@ -125,11 +126,8 @@ public class CargoLifecycle {
|
|
125
|
126
|
assertNull(cargo.estimatedTimeOfArrival());
|
|
126
|
127
|
assertNull(cargo.nextExpectedActivity());
|
|
127
|
128
|
|
|
128
|
|
-
|
|
129
|
|
-
|
|
130
|
129
|
// Route: Hongkong - Long Beach - New York - Stockholm
|
|
131
|
|
- List<Itinerary> itineraries =
|
|
132
|
|
- routingService.fetchRoutesForSpecification(cargo.routeSpecification());
|
|
|
130
|
+ List<Itinerary> itineraries = routingService.fetchRoutesForSpecification(cargo.routeSpecification());
|
|
133
|
131
|
Itinerary itinerary = selectAppropriateRoute(itineraries);
|
|
134
|
132
|
cargo.assignToRoute(itinerary);
|
|
135
|
133
|
|
|
|
@@ -139,38 +137,12 @@ public class CargoLifecycle {
|
|
139
|
137
|
assertThat(cargo.nextExpectedActivity(), is(receiveIn(HONGKONG)));
|
|
140
|
138
|
assertNotNull(cargo.estimatedTimeOfArrival());
|
|
141
|
139
|
|
|
142
|
|
-
|
|
143
|
|
-
|
|
144
|
|
-
|
|
145
|
|
-
|
|
146
|
|
-
|
|
147
|
|
-
|
|
148
|
|
-
|
|
149
|
|
-
|
|
150
|
|
-
|
|
151
|
|
-
|
|
152
|
140
|
// Received
|
|
153
|
141
|
cargo.handled(receiveIn(HONGKONG));
|
|
154
|
142
|
|
|
155
|
143
|
assertThat(cargo.transportStatus(), is(IN_PORT));
|
|
156
|
144
|
assertThat(cargo.lastKnownLocation(), is(HONGKONG));
|
|
157
|
145
|
|
|
158
|
|
-
|
|
159
|
|
-
|
|
160
|
|
-
|
|
161
|
|
-
|
|
162
|
|
-
|
|
163
|
|
-
|
|
164
|
|
-
|
|
165
|
|
-
|
|
166
|
|
-
|
|
167
|
|
-
|
|
168
|
|
-
|
|
169
|
|
-
|
|
170
|
|
-
|
|
171
|
|
-
|
|
172
|
|
-
|
|
173
|
|
-
|
|
174
|
146
|
// Loaded
|
|
175
|
147
|
cargo.handled(loadOnto(pacific1).in(HONGKONG));
|
|
176
|
148
|
|
|
|
@@ -180,117 +152,38 @@ public class CargoLifecycle {
|
|
180
|
152
|
assertThat(cargo.nextExpectedActivity(), is(unloadOff(pacific1).in(LONGBEACH)));
|
|
181
|
153
|
assertFalse(cargo.isMisdirected());
|
|
182
|
154
|
|
|
183
|
|
-
|
|
184
|
|
-
|
|
185
|
|
-
|
|
186
|
|
-
|
|
187
|
|
-
|
|
188
|
|
-
|
|
189
|
|
-
|
|
190
|
|
-
|
|
191
|
|
-
|
|
192
|
|
-
|
|
193
|
|
-
|
|
194
|
|
-
|
|
195
|
|
-
|
|
196
|
|
- // Unloaded
|
|
197
|
|
- cargo.handled(unloadOff(pacific1).in(LONGBEACH));
|
|
198
|
|
-
|
|
199
|
|
- assertThat(cargo.currentVoyage(), is(NONE));
|
|
200
|
|
- assertThat(cargo.lastKnownLocation(), is(LONGBEACH));
|
|
201
|
|
- assertThat(cargo.transportStatus(), is(IN_PORT));
|
|
202
|
|
- assertFalse(cargo.isMisdirected());
|
|
203
|
|
- assertThat(cargo.nextExpectedActivity(), is(loadOnto(continental1).in(LONGBEACH)));
|
|
204
|
|
-
|
|
205
|
|
-
|
|
206
|
|
-
|
|
207
|
|
-
|
|
208
|
|
-
|
|
209
|
|
-
|
|
210
|
|
-
|
|
211
|
|
-
|
|
212
|
|
-
|
|
213
|
|
-
|
|
214
|
|
-
|
|
215
|
|
-
|
|
216
|
|
-
|
|
217
|
|
-
|
|
218
|
|
-
|
|
219
|
|
- // Unloaded in Rotterdam, wasn't supposed to happen
|
|
220
|
|
- cargo.handled(unloadOff(pacific2).in(ROTTERDAM));
|
|
|
155
|
+ // Unloaded in Seattle, wasn't supposed to happen
|
|
|
156
|
+ cargo.handled(unloadOff(pacific1).in(SEATTLE));
|
|
221
|
157
|
|
|
222
|
158
|
// Misdirected
|
|
223
|
159
|
assertTrue(cargo.isMisdirected());
|
|
224
|
|
- assertThat(cargo.lastKnownLocation(), is(ROTTERDAM));
|
|
|
160
|
+ assertThat(cargo.lastKnownLocation(), is(SEATTLE));
|
|
225
|
161
|
assertThat(cargo.transportStatus(), is(IN_PORT));
|
|
226
|
|
-
|
|
227
|
|
-
|
|
228
|
|
-
|
|
229
|
|
-
|
|
230
|
|
-
|
|
231
|
|
-
|
|
232
|
|
-
|
|
233
|
|
-
|
|
234
|
|
-
|
|
235
|
|
-
|
|
236
|
|
-
|
|
237
|
|
-
|
|
|
162
|
+ assertNull(cargo.nextExpectedActivity());
|
|
|
163
|
+ assertNull(cargo.estimatedTimeOfArrival());
|
|
238
|
164
|
|
|
239
|
165
|
// Reroute: specify new route
|
|
240
|
|
- RouteSpecification currentRouteSpec = cargo.routeSpecification();
|
|
241
|
|
- RouteSpecification newRouteSpec =
|
|
242
|
|
- currentRouteSpec.withOrigin(cargo.lastKnownLocation());
|
|
243
|
|
- cargo.specifyNewRoute(newRouteSpec);
|
|
244
|
|
-
|
|
245
|
|
- assertThat(cargo.routingStatus(), is(MISROUTED));
|
|
246
|
|
-
|
|
247
|
|
-
|
|
248
|
|
-
|
|
249
|
|
-
|
|
250
|
|
-
|
|
251
|
|
-
|
|
252
|
|
-
|
|
253
|
|
-
|
|
254
|
|
-
|
|
255
|
166
|
|
|
256
|
167
|
// Assign to new route
|
|
257
|
|
- List<Itinerary> available = routingService.fetchRoutesForSpecification(newRouteSpec);
|
|
|
168
|
+ List<Itinerary> available = routingService.fetchRoutesForSpecification(
|
|
|
169
|
+ cargo.routeSpecification().withOrigin(cargo.earliestReroutingLocation())
|
|
|
170
|
+ );
|
|
|
171
|
+
|
|
258
|
172
|
Itinerary newItinerary = selectAppropriateRoute(available);
|
|
259
|
|
- cargo.assignToRoute(newItinerary);
|
|
|
173
|
+ Itinerary mergedItinerary = cargo.itineraryMergedWith(newItinerary);
|
|
|
174
|
+ cargo.assignToRoute(mergedItinerary);
|
|
260
|
175
|
|
|
|
176
|
+ assertFalse(cargo.isMisdirected());
|
|
261
|
177
|
assertThat(cargo.routingStatus(), is(ROUTED));
|
|
262
|
|
- assertThat(cargo.nextExpectedActivity(), is(loadOnto(atlantic1).in(ROTTERDAM)));
|
|
263
|
|
-
|
|
264
|
|
-
|
|
265
|
|
-
|
|
266
|
|
-
|
|
267
|
|
-
|
|
268
|
|
-
|
|
269
|
|
-
|
|
270
|
|
-
|
|
271
|
|
-
|
|
272
|
|
-
|
|
273
|
|
-
|
|
|
178
|
+ assertThat(cargo.nextExpectedActivity(), is(loadOnto(continental3).in(SEATTLE)));
|
|
274
|
179
|
|
|
275
|
180
|
// Loaded, back on track
|
|
276
|
|
- cargo.handled(loadOnto(atlantic1).in(ROTTERDAM));
|
|
|
181
|
+ cargo.handled(loadOnto(continental3).in(SEATTLE));
|
|
277
|
182
|
assertFalse(cargo.isMisdirected());
|
|
278
|
|
- assertThat(cargo.lastKnownLocation(), is(ROTTERDAM));
|
|
|
183
|
+ assertThat(cargo.lastKnownLocation(), is(SEATTLE));
|
|
279
|
184
|
assertThat(cargo.transportStatus(), is(ONBOARD_CARRIER));
|
|
280
|
185
|
|
|
281
|
|
-
|
|
282
|
|
-
|
|
283
|
|
-
|
|
284
|
|
-
|
|
285
|
|
-
|
|
286
|
|
-
|
|
287
|
|
-
|
|
288
|
|
-
|
|
289
|
|
-
|
|
290
|
|
-
|
|
291
|
|
-
|
|
292
|
|
-
|
|
293
|
|
-
|
|
|
186
|
+ // Etc
|
|
294
|
187
|
}
|
|
295
|
188
|
|
|
296
|
189
|
@Test
|
|
|
@@ -344,7 +237,6 @@ public class CargoLifecycle {
|
|
344
|
237
|
|
|
345
|
238
|
// Customer wants cargo to go to Rotterdam instead of Stockholm
|
|
346
|
239
|
RouteSpecification toRotterdam = cargo.routeSpecification().
|
|
347
|
|
- withOrigin(cargo.lastKnownLocation()).
|
|
348
|
240
|
withDestination(ROTTERDAM);
|
|
349
|
241
|
|
|
350
|
242
|
cargo.specifyNewRoute(toRotterdam);
|
|
|
@@ -358,7 +250,9 @@ public class CargoLifecycle {
|
|
358
|
250
|
// Assign to new route
|
|
359
|
251
|
List<Itinerary> available = routingService.fetchRoutesForSpecification(cargo.routeSpecification());
|
|
360
|
252
|
Itinerary newItinerary = selectAppropriateRoute(available);
|
|
361
|
|
- cargo.assignToRoute(newItinerary);
|
|
|
253
|
+ Itinerary mergedItinerary = cargo.itineraryMergedWith(newItinerary);
|
|
|
254
|
+
|
|
|
255
|
+ cargo.assignToRoute(mergedItinerary);
|
|
362
|
256
|
|
|
363
|
257
|
assertThat(cargo.routingStatus(), is(ROUTED));
|
|
364
|
258
|
assertThat(cargo.nextExpectedActivity(), is(loadOnto(continental2).in(LONGBEACH)));
|
|
|
@@ -407,8 +301,8 @@ public class CargoLifecycle {
|
|
407
|
301
|
);
|
|
408
|
302
|
|
|
409
|
303
|
private static final Itinerary itinerary2 = new Itinerary(
|
|
410
|
|
- Leg.deriveLeg(atlantic1, ROTTERDAM, HAMBURG),
|
|
411
|
|
- Leg.deriveLeg(atlantic2, HAMBURG, STOCKHOLM)
|
|
|
304
|
+ Leg.deriveLeg(continental3, SEATTLE, NEWYORK),
|
|
|
305
|
+ Leg.deriveLeg(atlantic2, NEWYORK, STOCKHOLM)
|
|
412
|
306
|
);
|
|
413
|
307
|
|
|
414
|
308
|
private static final Itinerary itinerary3 = new Itinerary(
|
|
|
@@ -417,13 +311,13 @@ public class CargoLifecycle {
|
|
417
|
311
|
);
|
|
418
|
312
|
|
|
419
|
313
|
public List<Itinerary> fetchRoutesForSpecification(RouteSpecification routeSpecification) {
|
|
420
|
|
- if (routeSpecification.origin().sameAs(HONGKONG)) {
|
|
|
314
|
+ if (routeSpecification.origin().sameAs(HONGKONG) && routeSpecification.destination().sameAs(STOCKHOLM)) {
|
|
421
|
315
|
// Hongkong - Long Beach - New York - Stockholm, initial routing
|
|
422
|
316
|
return asList(itinerary1);
|
|
423
|
|
- } else if (routeSpecification.origin().sameAs(ROTTERDAM)) {
|
|
|
317
|
+ } else if (routeSpecification.origin().sameAs(SEATTLE) && routeSpecification.destination().sameAs(STOCKHOLM)) {
|
|
424
|
318
|
// Rotterdam - Hamburg - Stockholm, rerouting misdirected cargo from Rotterdam
|
|
425
|
319
|
return asList(itinerary2);
|
|
426
|
|
- } else if (routeSpecification.origin().sameAs(LONGBEACH)) {
|
|
|
320
|
+ } else if (routeSpecification.origin().sameAs(HONGKONG) && routeSpecification.destination().sameAs(ROTTERDAM)) {
|
|
427
|
321
|
// Customer requested change of destination
|
|
428
|
322
|
return asList(itinerary3);
|
|
429
|
323
|
} else {
|