浏览代码

Added CargoService.registerNew, which assigns a tracking id to a cargo and stores it.

Reorganized JSP views slightly.
peter_backlund 18 年前
父节点
当前提交
da0b6a059c
共有 20 个文件被更改,包括 116 次插入41 次删除
  1. 5
    0
      dddsample/src/main/java/se/citerus/dddsample/repository/CargoRepository.java
  2. 10
    0
      dddsample/src/main/java/se/citerus/dddsample/repository/CargoRepositoryHibernate.java
  3. 5
    0
      dddsample/src/main/java/se/citerus/dddsample/repository/CargoRepositoryInMem.java
  4. 12
    2
      dddsample/src/main/java/se/citerus/dddsample/service/CargoService.java
  5. 20
    5
      dddsample/src/main/java/se/citerus/dddsample/service/CargoServiceImpl.java
  6. 2
    2
      dddsample/src/main/java/se/citerus/dddsample/service/RoutingService.java
  7. 19
    6
      dddsample/src/main/java/se/citerus/dddsample/service/RoutingServiceImpl.java
  8. 2
    2
      dddsample/src/main/java/se/citerus/dddsample/service/dto/CargoTrackingDTO.java
  9. 3
    3
      dddsample/src/main/java/se/citerus/dddsample/web/CargoTrackingController.java
  10. 1
    0
      dddsample/src/main/resources/context-service.xml
  11. 1
    1
      dddsample/src/main/resources/context-web.xml
  12. 2
    2
      dddsample/src/main/webapp/WEB-INF/dispatch-servlet.xml
  13. 0
    0
      dddsample/src/main/webapp/WEB-INF/jsp/cargo/track.jsp
  14. 0
    0
      dddsample/src/main/webapp/WEB-INF/jsp/error/dataAccessFailure.jsp
  15. 1
    1
      dddsample/src/main/webapp/index.jsp
  16. 1
    1
      dddsample/src/test/java/se/citerus/dddsample/domain/SampleLocations.java
  17. 5
    4
      dddsample/src/test/java/se/citerus/dddsample/service/CargoServiceTest.java
  18. 1
    1
      dddsample/src/test/java/se/citerus/dddsample/service/RoutingScenarioTest.java
  19. 11
    5
      dddsample/src/test/java/se/citerus/dddsample/service/RoutingServiceTest.java
  20. 15
    6
      dddsample/src/test/java/se/citerus/dddsample/web/CargoTrackingControllerTest.java

+ 5
- 0
dddsample/src/main/java/se/citerus/dddsample/repository/CargoRepository.java 查看文件

4
 import se.citerus.dddsample.domain.TrackingId;
4
 import se.citerus.dddsample.domain.TrackingId;
5
 
5
 
6
 public interface CargoRepository {
6
 public interface CargoRepository {
7
+
7
   Cargo find(TrackingId trackingId);
8
   Cargo find(TrackingId trackingId);
9
+
8
   void save(Cargo cargo);
10
   void save(Cargo cargo);
11
+
12
+  TrackingId nextTrackingId();
13
+
9
 }
14
 }

+ 10
- 0
dddsample/src/main/java/se/citerus/dddsample/repository/CargoRepositoryHibernate.java 查看文件

4
 import se.citerus.dddsample.domain.Cargo;
4
 import se.citerus.dddsample.domain.Cargo;
5
 import se.citerus.dddsample.domain.TrackingId;
5
 import se.citerus.dddsample.domain.TrackingId;
6
 
6
 
7
+import java.util.UUID;
8
+
7
 /**
9
 /**
8
  * Hibernate implementation of CargoRepository.
10
  * Hibernate implementation of CargoRepository.
9
  */
11
  */
34
     getSession().saveOrUpdate(cargo);
36
     getSession().saveOrUpdate(cargo);
35
   }
37
   }
36
 
38
 
39
+  public TrackingId nextTrackingId() {
40
+    // TODO:
41
+    // Could be an opportunity to maybe illustrate how to handle pessimistic locking
42
+    // and aggregate boundaries, and maybe problems with a distributed application
43
+    // sharing a database. For now it's simply random though.
44
+    return new TrackingId(UUID.randomUUID().toString());
45
+  }
46
+
37
   public void setHandlingEventRepository(HandlingEventRepository handlingEventRepository) {
47
   public void setHandlingEventRepository(HandlingEventRepository handlingEventRepository) {
38
     this.handlingEventRepository = handlingEventRepository;
48
     this.handlingEventRepository = handlingEventRepository;
39
   }
49
   }

+ 5
- 0
dddsample/src/main/java/se/citerus/dddsample/repository/CargoRepositoryInMem.java 查看文件

6
 
6
 
7
 import java.util.HashMap;
7
 import java.util.HashMap;
8
 import java.util.Map;
8
 import java.util.Map;
9
+import java.util.UUID;
9
 
10
 
10
 /**
11
 /**
11
  * CargoRepositoryInMem implement the CargoRepository interface but is a test
12
  * CargoRepositoryInMem implement the CargoRepository interface but is a test
37
     //No need to save anything with InMem
38
     //No need to save anything with InMem
38
   }
39
   }
39
 
40
 
41
+  public TrackingId nextTrackingId() {
42
+    return new TrackingId(UUID.randomUUID().toString());
43
+  }
44
+
40
   /**
45
   /**
41
    * 
46
    * 
42
    * @throws Exception
47
    * @throws Exception

+ 12
- 2
dddsample/src/main/java/se/citerus/dddsample/service/CargoService.java 查看文件

1
 package se.citerus.dddsample.service;
1
 package se.citerus.dddsample.service;
2
 
2
 
3
+import se.citerus.dddsample.domain.Location;
3
 import se.citerus.dddsample.domain.TrackingId;
4
 import se.citerus.dddsample.domain.TrackingId;
4
-import se.citerus.dddsample.service.dto.CargoWithHistoryDTO;
5
+import se.citerus.dddsample.service.dto.CargoTrackingDTO;
5
 
6
 
6
 /**
7
 /**
7
  * Cargo service.
8
  * Cargo service.
10
 public interface CargoService {
11
 public interface CargoService {
11
 
12
 
12
   /**
13
   /**
14
+   * Registers a new cargo in the tracking system, not yet routed.
15
+   *
16
+   * @param origin cargo origin
17
+   * @param destination cargo destination
18
+   * @return Cargo tracking id
19
+   */
20
+  TrackingId registerNew(Location origin, Location destination);
21
+
22
+  /**
13
    * @param trackingId tracking id
23
    * @param trackingId tracking id
14
    * @return A cargo and its delivery history, or null if no cargo with given tracking id is found.
24
    * @return A cargo and its delivery history, or null if no cargo with given tracking id is found.
15
    */
25
    */
16
-  CargoWithHistoryDTO track(TrackingId trackingId);
26
+  CargoTrackingDTO track(TrackingId trackingId);
17
 
27
 
18
   /**
28
   /**
19
    * Send relevant notifications to interested parties,
29
    * Send relevant notifications to interested parties,

+ 20
- 5
dddsample/src/main/java/se/citerus/dddsample/service/CargoServiceImpl.java 查看文件

1
 package se.citerus.dddsample.service;
1
 package se.citerus.dddsample.service;
2
 
2
 
3
+import org.apache.commons.lang.Validate;
3
 import org.apache.commons.logging.Log;
4
 import org.apache.commons.logging.Log;
4
 import org.apache.commons.logging.LogFactory;
5
 import org.apache.commons.logging.LogFactory;
5
 import org.springframework.transaction.annotation.Transactional;
6
 import org.springframework.transaction.annotation.Transactional;
6
 import se.citerus.dddsample.domain.*;
7
 import se.citerus.dddsample.domain.*;
7
 import se.citerus.dddsample.repository.CargoRepository;
8
 import se.citerus.dddsample.repository.CargoRepository;
8
-import se.citerus.dddsample.service.dto.CargoWithHistoryDTO;
9
+import se.citerus.dddsample.service.dto.CargoTrackingDTO;
9
 import se.citerus.dddsample.service.dto.HandlingEventDTO;
10
 import se.citerus.dddsample.service.dto.HandlingEventDTO;
10
 
11
 
11
 import java.util.List;
12
 import java.util.List;
12
 
13
 
13
 public class CargoServiceImpl implements CargoService {
14
 public class CargoServiceImpl implements CargoService {
15
+
14
   private CargoRepository cargoRepository;
16
   private CargoRepository cargoRepository;
15
   private static final Log logger = LogFactory.getLog(CargoServiceImpl.class);
17
   private static final Log logger = LogFactory.getLog(CargoServiceImpl.class);
16
 
18
 
19
+  @Transactional(readOnly = false)
20
+  public TrackingId registerNew(Location origin, Location destination) {
21
+    Validate.notNull(origin);
22
+    Validate.notNull(destination);
23
+
24
+    TrackingId trackingId = cargoRepository.nextTrackingId();
25
+    Cargo cargo = new Cargo(trackingId, origin, destination);
26
+    cargoRepository.save(cargo);
27
+
28
+    logger.info("Registered new cargo with tracking id " + trackingId.idString());
29
+    
30
+    return trackingId;
31
+  }
32
+
17
   @Transactional(readOnly = true)
33
   @Transactional(readOnly = true)
18
-  public CargoWithHistoryDTO track(TrackingId trackingId) {
34
+  public CargoTrackingDTO track(TrackingId trackingId) {
19
     final Cargo cargo = cargoRepository.find(trackingId);
35
     final Cargo cargo = cargoRepository.find(trackingId);
20
     if (cargo == null) {
36
     if (cargo == null) {
21
       return null;
37
       return null;
23
 
39
 
24
     DeliveryHistory deliveryHistory = cargo.deliveryHistory();
40
     DeliveryHistory deliveryHistory = cargo.deliveryHistory();
25
 
41
 
26
-    //CargoWithHistoryDTO
27
-
28
     Location currentLocation = deliveryHistory.currentLocation();
42
     Location currentLocation = deliveryHistory.currentLocation();
29
     CarrierMovement currentCarrierMovement = deliveryHistory.currentCarrierMovement();
43
     CarrierMovement currentCarrierMovement = deliveryHistory.currentCarrierMovement();
30
-    final CargoWithHistoryDTO dto = new CargoWithHistoryDTO(
44
+    final CargoTrackingDTO dto = new CargoTrackingDTO(
31
       cargo.trackingId().idString(),
45
       cargo.trackingId().idString(),
32
       cargo.origin().toString(),
46
       cargo.origin().toString(),
33
       cargo.finalDestination().toString(),
47
       cargo.finalDestination().toString(),
53
 
67
 
54
   }
68
   }
55
 
69
 
70
+  // TODO: move this to another class?
56
   @Transactional(readOnly = true)
71
   @Transactional(readOnly = true)
57
   public void notify(TrackingId trackingId) {
72
   public void notify(TrackingId trackingId) {
58
     Cargo cargo = cargoRepository.find(trackingId);
73
     Cargo cargo = cargoRepository.find(trackingId);

+ 2
- 2
dddsample/src/main/java/se/citerus/dddsample/service/RoutingService.java 查看文件

1
 package se.citerus.dddsample.service;
1
 package se.citerus.dddsample.service;
2
 
2
 
3
-import se.citerus.dddsample.domain.Cargo;
4
 import se.citerus.dddsample.domain.Itinerary;
3
 import se.citerus.dddsample.domain.Itinerary;
5
 import se.citerus.dddsample.domain.Specification;
4
 import se.citerus.dddsample.domain.Specification;
5
+import se.citerus.dddsample.domain.TrackingId;
6
 
6
 
7
 import java.util.Set;
7
 import java.util.Set;
8
 
8
 
11
  */
11
  */
12
 public interface RoutingService {
12
 public interface RoutingService {
13
 
13
 
14
-  Set<Itinerary> calculatePossibleRoutes(Cargo cargo, Specification specification);
14
+  Set<Itinerary> calculatePossibleRoutes(TrackingId trackingId, Specification specification);
15
 
15
 
16
 }
16
 }

+ 19
- 6
dddsample/src/main/java/se/citerus/dddsample/service/RoutingServiceImpl.java 查看文件

2
 
2
 
3
 import org.springframework.transaction.annotation.Transactional;
3
 import org.springframework.transaction.annotation.Transactional;
4
 import se.citerus.dddsample.domain.*;
4
 import se.citerus.dddsample.domain.*;
5
+import se.citerus.dddsample.repository.CargoRepository;
5
 import se.citerus.dddsample.repository.LocationRepository;
6
 import se.citerus.dddsample.repository.LocationRepository;
6
 
7
 
7
 import java.util.*;
8
 import java.util.*;
14
 public class RoutingServiceImpl implements RoutingService {
15
 public class RoutingServiceImpl implements RoutingService {
15
 
16
 
16
   LocationRepository locationRepository;
17
   LocationRepository locationRepository;
18
+  CargoRepository cargoRepository;
17
 
19
 
18
   @Transactional(readOnly = true)
20
   @Transactional(readOnly = true)
19
-  public Set<Itinerary> calculatePossibleRoutes(Cargo cargo, Specification specification) {
21
+  public Set<Itinerary> calculatePossibleRoutes(TrackingId trackingId, Specification specification) {
22
+    Cargo cargo = cargoRepository.find(trackingId);
23
+    if (cargo == null) {
24
+      return Collections.emptySet();
25
+    }
20
     List<Location> allLocations = locationRepository.findAll();
26
     List<Location> allLocations = locationRepository.findAll();
21
 
27
 
22
     allLocations.remove(cargo.origin());
28
     allLocations.remove(cargo.origin());
30
       Collections.shuffle(allLocations);
36
       Collections.shuffle(allLocations);
31
       List<Leg> legs = new ArrayList<Leg>(allLocations.size() - 1);
37
       List<Leg> legs = new ArrayList<Leg>(allLocations.size() - 1);
32
 
38
 
33
-      legs.add(new Leg(new CarrierMovementId("CM000"), cargo.origin(), allLocations.get(0)));
39
+      Location firstLegTo = allLocations.get(0);
40
+      legs.add(new Leg(new CarrierMovementId("CM000"), cargo.origin(), firstLegTo));
41
+
34
       for (int j = 0; j < allLocations.size() - 1 ; j++) {
42
       for (int j = 0; j < allLocations.size() - 1 ; j++) {
35
-        legs.add(new Leg(new CarrierMovementId("CM00" + j), 
43
+        legs.add(new Leg(
44
+          new CarrierMovementId("CM00" + j),
36
           allLocations.get(j), allLocations.get(j + 1)));
45
           allLocations.get(j), allLocations.get(j + 1)));
37
       }
46
       }
38
-      legs.add(new Leg(new CarrierMovementId("CM999"), allLocations.get(allLocations.size() - 1), cargo.finalDestination()));
39
 
47
 
40
-      Itinerary itinerary = new Itinerary(legs);
48
+      Location lastLegFrom = allLocations.get(allLocations.size() - 1);
49
+      legs.add(new Leg(new CarrierMovementId("CM999"), lastLegFrom, cargo.finalDestination()));
41
 
50
 
42
-      candidates.add(itinerary);
51
+      candidates.add(new Itinerary(legs));
43
     }
52
     }
44
 
53
 
45
     return candidates;
54
     return candidates;
49
     this.locationRepository = locationRepository;
58
     this.locationRepository = locationRepository;
50
   }
59
   }
51
 
60
 
61
+  public void setCargoRepository(CargoRepository cargoRepository) {
62
+    this.cargoRepository = cargoRepository;
63
+  }
64
+
52
 }
65
 }

dddsample/src/main/java/se/citerus/dddsample/service/dto/CargoWithHistoryDTO.java → dddsample/src/main/java/se/citerus/dddsample/service/dto/CargoTrackingDTO.java 查看文件

11
  * DTO for a cargo and its delivery history.
11
  * DTO for a cargo and its delivery history.
12
  *
12
  *
13
  */
13
  */
14
-public class CargoWithHistoryDTO implements Serializable {
14
+public class CargoTrackingDTO implements Serializable {
15
 
15
 
16
   String trackingId;
16
   String trackingId;
17
   String origin;
17
   String origin;
22
   StatusCode statusCode;
22
   StatusCode statusCode;
23
   boolean misdirected;
23
   boolean misdirected;
24
 
24
 
25
-  public CargoWithHistoryDTO(String trackingId, String origin, String finalDestination,
25
+  public CargoTrackingDTO(String trackingId, String origin, String finalDestination,
26
                              StatusCode statusCode, String currentLocationId, String carrierMovementId,
26
                              StatusCode statusCode, String currentLocationId, String carrierMovementId,
27
                              boolean isMisdirected) {
27
                              boolean isMisdirected) {
28
     this.trackingId = trackingId;
28
     this.trackingId = trackingId;

+ 3
- 3
dddsample/src/main/java/se/citerus/dddsample/web/CargoTrackingController.java 查看文件

5
 import org.springframework.web.servlet.mvc.SimpleFormController;
5
 import org.springframework.web.servlet.mvc.SimpleFormController;
6
 import se.citerus.dddsample.domain.TrackingId;
6
 import se.citerus.dddsample.domain.TrackingId;
7
 import se.citerus.dddsample.service.CargoService;
7
 import se.citerus.dddsample.service.CargoService;
8
-import se.citerus.dddsample.service.dto.CargoWithHistoryDTO;
8
+import se.citerus.dddsample.service.dto.CargoTrackingDTO;
9
 import se.citerus.dddsample.web.command.TrackCommand;
9
 import se.citerus.dddsample.web.command.TrackCommand;
10
 
10
 
11
 import javax.servlet.http.HttpServletRequest;
11
 import javax.servlet.http.HttpServletRequest;
31
   protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception {
31
   protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception {
32
     final TrackCommand trackCommand = (TrackCommand) command;
32
     final TrackCommand trackCommand = (TrackCommand) command;
33
     final String tidStr = trackCommand.getTrackingId();
33
     final String tidStr = trackCommand.getTrackingId();
34
-    final CargoWithHistoryDTO cargo = cargoService.track(new TrackingId(tidStr));
34
+    final CargoTrackingDTO cargo = cargoService.track(new TrackingId(tidStr));
35
 
35
 
36
-    final Map<String, Object> model = new HashMap<String, Object>();
36
+    final Map<String, CargoTrackingDTO> model = new HashMap<String, CargoTrackingDTO>();
37
     if (cargo != null) {
37
     if (cargo != null) {
38
       model.put("cargo", cargo);
38
       model.put("cargo", cargo);
39
     } else {
39
     } else {

+ 1
- 0
dddsample/src/main/resources/context-service.xml 查看文件

32
 
32
 
33
   <bean id="routingService" class="se.citerus.dddsample.service.RoutingServiceImpl">
33
   <bean id="routingService" class="se.citerus.dddsample.service.RoutingServiceImpl">
34
     <property name="locationRepository" ref="locationRepository"/>
34
     <property name="locationRepository" ref="locationRepository"/>
35
+    <property name="cargoRepository" ref="cargoRepository"/>
35
   </bean>
36
   </bean>
36
 
37
 
37
   <!--
38
   <!--

+ 1
- 1
dddsample/src/main/resources/context-web.xml 查看文件

21
   <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
21
   <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
22
     <property name="exceptionMappings">
22
     <property name="exceptionMappings">
23
       <props>
23
       <props>
24
-        <prop key="org.springframework.dao.DataAccessException">dataAccessFailure</prop>
24
+        <prop key="org.springframework.dao.DataAccessException">error/dataAccessFailure</prop>
25
       </props>
25
       </props>
26
     </property>
26
     </property>
27
   </bean>
27
   </bean>

+ 2
- 2
dddsample/src/main/webapp/WEB-INF/dispatch-servlet.xml 查看文件

3
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
4
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
5
 
5
 
6
-  <bean name="/start.html" class="se.citerus.dddsample.web.CargoTrackingController">
6
+  <bean name="/cargo/track.html" class="se.citerus.dddsample.web.CargoTrackingController">
7
     <property name="sessionForm" value="true"/>
7
     <property name="sessionForm" value="true"/>
8
     <property name="commandName" value="trackCommand"/>
8
     <property name="commandName" value="trackCommand"/>
9
-    <property name="formView" value="start"/>
9
+    <property name="formView" value="cargo/track"/>
10
     <property name="successView" value="start"/>
10
     <property name="successView" value="start"/>
11
     <property name="cargoService" ref="cargoService"/>
11
     <property name="cargoService" ref="cargoService"/>
12
     <property name="validator" ref="trackCommandValidator"/>
12
     <property name="validator" ref="trackCommandValidator"/>

dddsample/src/main/webapp/WEB-INF/jsp/start.jsp → dddsample/src/main/webapp/WEB-INF/jsp/cargo/track.jsp 查看文件


dddsample/src/main/webapp/WEB-INF/jsp/dataAccessFailure.jsp → dddsample/src/main/webapp/WEB-INF/jsp/error/dataAccessFailure.jsp 查看文件


+ 1
- 1
dddsample/src/main/webapp/index.jsp 查看文件

1
 <%
1
 <%
2
-  response.sendRedirect("start.html");
2
+  response.sendRedirect("cargo/track.html");
3
 %>
3
 %>

+ 1
- 1
dddsample/src/test/java/se/citerus/dddsample/domain/SampleLocations.java 查看文件

13
   public static final Location HONGKONG = new Location(new UnLocode("CN", "HKG"), "Hongkong");
13
   public static final Location HONGKONG = new Location(new UnLocode("CN", "HKG"), "Hongkong");
14
   public static final Location MELBOURNE = new Location(new UnLocode("AU","MEL"), "Melbourne");
14
   public static final Location MELBOURNE = new Location(new UnLocode("AU","MEL"), "Melbourne");
15
   public static final Location STOCKHOLM = new Location(new UnLocode("SE","STO"), "Stockholm");
15
   public static final Location STOCKHOLM = new Location(new UnLocode("SE","STO"), "Stockholm");
16
-  public static final Location HELSINKI = new Location(new UnLocode("Fi","HEL"), "Helsinki");
16
+  public static final Location HELSINKI = new Location(new UnLocode("FI","HEL"), "Helsinki");
17
   public static final Location CHICAGO = new Location(new UnLocode("US", "CHI"), "Chicago");
17
   public static final Location CHICAGO = new Location(new UnLocode("US", "CHI"), "Chicago");
18
   public static final Location TOKYO = new Location(new UnLocode("JN","TKO"), "Tokyo");
18
   public static final Location TOKYO = new Location(new UnLocode("JN","TKO"), "Tokyo");
19
   public static final Location HAMBURG = new Location(new UnLocode("DE", "HAM"), "Hamburg");
19
   public static final Location HAMBURG = new Location(new UnLocode("DE", "HAM"), "Hamburg");

+ 5
- 4
dddsample/src/test/java/se/citerus/dddsample/service/CargoServiceTest.java 查看文件

10
 import org.springframework.transaction.TransactionStatus;
10
 import org.springframework.transaction.TransactionStatus;
11
 import org.springframework.transaction.interceptor.TransactionAspectSupport;
11
 import org.springframework.transaction.interceptor.TransactionAspectSupport;
12
 import se.citerus.dddsample.domain.*;
12
 import se.citerus.dddsample.domain.*;
13
-import static se.citerus.dddsample.domain.SampleLocations.*;
13
+import static se.citerus.dddsample.domain.SampleLocations.CHICAGO;
14
+import static se.citerus.dddsample.domain.SampleLocations.STOCKHOLM;
14
 import se.citerus.dddsample.repository.CargoRepository;
15
 import se.citerus.dddsample.repository.CargoRepository;
15
 import se.citerus.dddsample.repository.HandlingEventRepository;
16
 import se.citerus.dddsample.repository.HandlingEventRepository;
16
-import se.citerus.dddsample.service.dto.CargoWithHistoryDTO;
17
+import se.citerus.dddsample.service.dto.CargoTrackingDTO;
17
 import se.citerus.dddsample.service.dto.HandlingEventDTO;
18
 import se.citerus.dddsample.service.dto.HandlingEventDTO;
18
 
19
 
19
 import java.sql.Connection;
20
 import java.sql.Connection;
97
 
98
 
98
 
99
 
99
     // Tested call
100
     // Tested call
100
-    CargoWithHistoryDTO cargoDTO = cargoService.track(new TrackingId("XYZ"));
101
+    CargoTrackingDTO cargoDTO = cargoService.track(new TrackingId("XYZ"));
101
 
102
 
102
 
103
 
103
     assertEquals("XYZ", cargoDTO.getTrackingId());
104
     assertEquals("XYZ", cargoDTO.getTrackingId());
135
     replay(cargoRepository);
136
     replay(cargoRepository);
136
 
137
 
137
     // Tested call
138
     // Tested call
138
-    CargoWithHistoryDTO cargoDTO = cargoService.track(new TrackingId("XYZ"));
139
+    CargoTrackingDTO cargoDTO = cargoService.track(new TrackingId("XYZ"));
139
     
140
     
140
     assertNull(cargoDTO);
141
     assertNull(cargoDTO);
141
   }
142
   }

+ 1
- 1
dddsample/src/test/java/se/citerus/dddsample/service/RoutingScenarioTest.java 查看文件

24
       satisfy the given specification (must arrive in three days, must not
24
       satisfy the given specification (must arrive in three days, must not
25
       cost more than $10,000 etc).
25
       cost more than $10,000 etc).
26
      */
26
      */
27
-    Set<Itinerary> itineraryCandidates = routingService.calculatePossibleRoutes(cargo, specification);
27
+    Set<Itinerary> itineraryCandidates = routingService.calculatePossibleRoutes(trackingId, specification);
28
 
28
 
29
     /*
29
     /*
30
       Someone, or something, selects the most appropriate itinerary and
30
       Someone, or something, selects the most appropriate itinerary and

+ 11
- 5
dddsample/src/test/java/se/citerus/dddsample/service/RoutingServiceTest.java 查看文件

5
 import se.citerus.dddsample.domain.*;
5
 import se.citerus.dddsample.domain.*;
6
 import static se.citerus.dddsample.domain.SampleLocations.HELSINKI;
6
 import static se.citerus.dddsample.domain.SampleLocations.HELSINKI;
7
 import static se.citerus.dddsample.domain.SampleLocations.HONGKONG;
7
 import static se.citerus.dddsample.domain.SampleLocations.HONGKONG;
8
+import se.citerus.dddsample.repository.CargoRepository;
8
 import se.citerus.dddsample.repository.LocationRepository;
9
 import se.citerus.dddsample.repository.LocationRepository;
9
 
10
 
10
 import java.util.List;
11
 import java.util.List;
14
 
15
 
15
   RoutingServiceImpl routingService;
16
   RoutingServiceImpl routingService;
16
   LocationRepository locationRepository;
17
   LocationRepository locationRepository;
18
+  CargoRepository cargoRepository;
17
 
19
 
18
   protected void setUp() throws Exception {
20
   protected void setUp() throws Exception {
19
     routingService = new RoutingServiceImpl();
21
     routingService = new RoutingServiceImpl();
20
     locationRepository = createMock(LocationRepository.class);
22
     locationRepository = createMock(LocationRepository.class);
21
     routingService.setLocationRepository(locationRepository);
23
     routingService.setLocationRepository(locationRepository);
24
+    cargoRepository = createMock(CargoRepository.class);
25
+    routingService.setCargoRepository(cargoRepository);
22
   }
26
   }
23
 
27
 
24
   public void testCalculatePossibleRoutes() {
28
   public void testCalculatePossibleRoutes() {
29
+    TrackingId trackingId = new TrackingId("ABC");
30
+    Cargo cargo = new Cargo(trackingId, HONGKONG, HELSINKI);
31
+
25
     expect(locationRepository.findAll()).andStubReturn(SampleLocations.getAll());
32
     expect(locationRepository.findAll()).andStubReturn(SampleLocations.getAll());
26
-    replay(locationRepository);
33
+    expect(cargoRepository.find(isA(TrackingId.class))).andReturn(cargo);
34
+    replay(locationRepository, cargoRepository);
27
 
35
 
28
-    Cargo cargo = new Cargo(new TrackingId("ABC"), HONGKONG, HELSINKI);
29
-    Set<Itinerary> candidates = routingService.calculatePossibleRoutes(cargo, null);
36
+    Set<Itinerary> candidates = routingService.calculatePossibleRoutes(trackingId, null);
30
     assertNotNull(candidates);
37
     assertNotNull(candidates);
31
     
38
     
32
     for (Itinerary itinerary : candidates) {
39
     for (Itinerary itinerary : candidates) {
48
       }
55
       }
49
     }
56
     }
50
 
57
 
51
-
52
-    verify(locationRepository);
58
+    verify(locationRepository, cargoRepository);
53
   }
59
   }
54
 
60
 
55
 }
61
 }

+ 15
- 6
dddsample/src/test/java/se/citerus/dddsample/web/CargoTrackingControllerTest.java 查看文件

10
 import org.springframework.validation.FieldError;
10
 import org.springframework.validation.FieldError;
11
 import org.springframework.web.servlet.ModelAndView;
11
 import org.springframework.web.servlet.ModelAndView;
12
 import se.citerus.dddsample.domain.*;
12
 import se.citerus.dddsample.domain.*;
13
-import static se.citerus.dddsample.domain.SampleLocations.*;
13
+import static se.citerus.dddsample.domain.SampleLocations.HONGKONG;
14
+import static se.citerus.dddsample.domain.SampleLocations.TOKYO;
14
 import se.citerus.dddsample.service.CargoService;
15
 import se.citerus.dddsample.service.CargoService;
15
-import se.citerus.dddsample.service.dto.CargoWithHistoryDTO;
16
+import se.citerus.dddsample.service.dto.CargoTrackingDTO;
16
 import se.citerus.dddsample.service.dto.HandlingEventDTO;
17
 import se.citerus.dddsample.service.dto.HandlingEventDTO;
17
 import se.citerus.dddsample.web.command.TrackCommand;
18
 import se.citerus.dddsample.web.command.TrackCommand;
18
 
19
 
40
 
41
 
41
   private CargoService getCargoServiceMock() {
42
   private CargoService getCargoServiceMock() {
42
     return new CargoService() {
43
     return new CargoService() {
43
-      public CargoWithHistoryDTO track(TrackingId trackingId) {
44
+      public TrackingId registerNew(Location origin, Location destination) {
45
+        return null;
46
+      }
47
+
48
+      public CargoTrackingDTO track(TrackingId trackingId) {
44
         Cargo cargo = new Cargo(trackingId, HONGKONG, TOKYO);
49
         Cargo cargo = new Cargo(trackingId, HONGKONG, TOKYO);
45
         HandlingEvent event = new HandlingEvent(cargo, new Date(10L), new Date(20L), HandlingEvent.Type.RECEIVE, HONGKONG, null);
50
         HandlingEvent event = new HandlingEvent(cargo, new Date(10L), new Date(20L), HandlingEvent.Type.RECEIVE, HONGKONG, null);
46
 
51
 
47
         // TODO: use DTO assemblers
52
         // TODO: use DTO assemblers
48
-        CargoWithHistoryDTO cargoDTO = new CargoWithHistoryDTO(
53
+        CargoTrackingDTO cargoDTO = new CargoTrackingDTO(
49
                 cargo.trackingId().idString(),
54
                 cargo.trackingId().idString(),
50
                 cargo.origin().unLocode().idString(),
55
                 cargo.origin().unLocode().idString(),
51
                 cargo.finalDestination().unLocode().idString(),
56
                 cargo.finalDestination().unLocode().idString(),
69
   
74
   
70
   private CargoService getCargoServiceNullMock() {
75
   private CargoService getCargoServiceNullMock() {
71
     return new CargoService() {
76
     return new CargoService() {
72
-      public CargoWithHistoryDTO track(TrackingId trackingId) {
77
+      public TrackingId registerNew(Location origin, Location destination) {
78
+        return null;
79
+      }
80
+
81
+      public CargoTrackingDTO track(TrackingId trackingId) {
73
         return null;
82
         return null;
74
       }
83
       }
75
       public void notify(TrackingId trackingId) {}
84
       public void notify(TrackingId trackingId) {}
97
     assertEquals("test-form", mav.getViewName());
106
     assertEquals("test-form", mav.getViewName());
98
     // Errors, command are two standard map attributes, the third should be the cargo object
107
     // Errors, command are two standard map attributes, the third should be the cargo object
99
     assertEquals(3, mav.getModel().size());
108
     assertEquals(3, mav.getModel().size());
100
-    CargoWithHistoryDTO cargo = (CargoWithHistoryDTO) mav.getModel().get("cargo");
109
+    CargoTrackingDTO cargo = (CargoTrackingDTO) mav.getModel().get("cargo");
101
     assertEquals("AAAAA", cargo.getCurrentLocationId());
110
     assertEquals("AAAAA", cargo.getCurrentLocationId());
102
   }
111
   }
103
 
112