Explorar el Código

Reporting application with a bounded context partialy implemented (server side REST API on top of separate data store)

peter_backlund hace 17 años
padre
commit
7290519096
Se han modificado 18 ficheros con 718 adiciones y 12 borrados
  1. 45
    4
      dddsample/external/reporting/pom.xml
  2. 140
    0
      dddsample/external/reporting/src/main/java/com.reporting/CargoReport.java
  3. 25
    0
      dddsample/external/reporting/src/main/java/com.reporting/CargoReportRowMapper.java
  4. 10
    0
      dddsample/external/reporting/src/main/java/com.reporting/Constants.java
  5. 0
    4
      dddsample/external/reporting/src/main/java/com.reporting/DeliveryReport.java
  6. 20
    0
      dddsample/external/reporting/src/main/java/com.reporting/HandlingRowMapper.java
  7. 87
    3
      dddsample/external/reporting/src/main/java/com.reporting/ReportingService.java
  8. 59
    0
      dddsample/external/reporting/src/main/java/com.reporting/VoyageReport.java
  9. 20
    0
      dddsample/external/reporting/src/main/java/com.reporting/VoyageReportRowMapper.java
  10. 23
    0
      dddsample/external/reporting/src/main/resources/context-cxf.xml
  11. 29
    0
      dddsample/external/reporting/src/main/resources/context.xml
  12. 29
    0
      dddsample/external/reporting/src/main/resources/schema.sql
  13. 15
    1
      dddsample/external/reporting/src/main/webapp/WEB-INF/web.xml
  14. 42
    0
      dddsample/external/reporting/src/test/java/com/reporting/Fixture.java
  15. 71
    0
      dddsample/external/reporting/src/test/java/com/reporting/ReportServiceTest.java
  16. 23
    0
      dddsample/external/reporting/src/test/resources/context-cxf.xml
  17. 13
    0
      dddsample/external/reporting/src/test/resources/context-test-setup.xml
  18. 67
    0
      dddsample/external/reporting/src/test/resources/testdata.sql

+ 45
- 4
dddsample/external/reporting/pom.xml Ver fichero

@@ -1,3 +1,4 @@
1
+
1 2
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2 3
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3 4
   <modelVersion>4.0.0</modelVersion>
@@ -11,8 +12,48 @@
11 12
   <packaging>war</packaging>
12 13
   <name>External: Reporting context</name>
13 14
   <version>${project.parent.version}</version>
14
-  <description>DESC</description>
15
-  <build>
16
-    <defaultGoal>package</defaultGoal>
17
-  </build>
15
+  <description>Reporting context</description>
16
+  <dependencies>
17
+    <dependency>
18
+      <groupId>org.springframework</groupId>
19
+      <artifactId>spring</artifactId>
20
+    </dependency>
21
+    <dependency>
22
+      <groupId>org.springframework</groupId>
23
+      <artifactId>spring-test</artifactId>
24
+    </dependency>
25
+    <dependency>
26
+      <groupId>commons-dbcp</groupId>
27
+      <artifactId>commons-dbcp</artifactId>  
28
+    </dependency>
29
+    <dependency>
30
+      <groupId>org.apache.activemq</groupId>
31
+      <artifactId>activemq-core</artifactId>
32
+    </dependency>
33
+    <dependency>
34
+      <groupId>org.apache.cxf</groupId>
35
+      <artifactId>cxf-rt-transports-http</artifactId>
36
+    </dependency>
37
+    <dependency>
38
+      <groupId>org.apache.cxf</groupId>
39
+      <artifactId>cxf-rt-transports-http-jetty</artifactId>
40
+      <version>2.2.2</version>
41
+    </dependency>
42
+    <dependency>
43
+      <groupId>org.apache.cxf</groupId>
44
+      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
45
+    </dependency>
46
+    <dependency>
47
+      <groupId>javax.ws.rs</groupId>
48
+      <artifactId>jsr311-api</artifactId>
49
+    </dependency>
50
+    <dependency>
51
+      <groupId>hsqldb</groupId>
52
+      <artifactId>hsqldb</artifactId>
53
+    </dependency>
54
+    <dependency>
55
+      <groupId>cglib</groupId>
56
+      <artifactId>cglib-nodep</artifactId>
57
+    </dependency>
58
+  </dependencies>
18 59
 </project>

+ 140
- 0
dddsample/external/reporting/src/main/java/com.reporting/CargoReport.java Ver fichero

@@ -0,0 +1,140 @@
1
+package com.reporting;
2
+
3
+import javax.xml.bind.annotation.XmlRootElement;
4
+import java.util.Date;
5
+import java.util.List;
6
+
7
+@XmlRootElement(name = "cargo")
8
+public class CargoReport {
9
+
10
+  String trackingId;
11
+  String receivedIn;
12
+  String finalDestination;
13
+  String arrivalDeadline;
14
+  String eta;
15
+  String currentStatus;
16
+  String currentVoyage;
17
+  String currentLocation;
18
+  String lastUpdatedOn;
19
+  List<Handling> handlings;
20
+
21
+  public String getTrackingId() {
22
+    return trackingId;
23
+  }
24
+
25
+  public void setTrackingId(String trackingId) {
26
+    this.trackingId = trackingId;
27
+  }
28
+
29
+  public String getReceivedIn() {
30
+    return receivedIn;
31
+  }
32
+
33
+  public void setReceivedIn(String receivedIn) {
34
+    this.receivedIn = receivedIn;
35
+  }
36
+
37
+  public String getFinalDestination() {
38
+    return finalDestination;
39
+  }
40
+
41
+  public void setFinalDestination(String finalDestination) {
42
+    this.finalDestination = finalDestination;
43
+  }
44
+
45
+  public String getArrivalDeadline() {
46
+    return arrivalDeadline;
47
+  }
48
+
49
+  public void setArrivalDeadline(String arrivalDeadline) {
50
+    this.arrivalDeadline = arrivalDeadline;
51
+  }
52
+
53
+  public String getEta() {
54
+    return eta;
55
+  }
56
+
57
+  public void setEta(String eta) {
58
+    this.eta = eta;
59
+  }
60
+
61
+  public String getCurrentStatus() {
62
+    return currentStatus;
63
+  }
64
+
65
+  public void setCurrentStatus(String currentStatus) {
66
+    this.currentStatus = currentStatus;
67
+  }
68
+
69
+  public String getCurrentVoyage() {
70
+    return currentVoyage;
71
+  }
72
+
73
+  public void setCurrentVoyage(String currentVoyage) {
74
+    this.currentVoyage = currentVoyage;
75
+  }
76
+
77
+  public String getCurrentLocation() {
78
+    return currentLocation;
79
+  }
80
+
81
+  public void setCurrentLocation(String currentLocation) {
82
+    this.currentLocation = currentLocation;
83
+  }
84
+
85
+  public List<Handling> getHandlings() {
86
+    return handlings;
87
+  }
88
+
89
+  public void setHandlings(List<Handling> handlings) {
90
+    this.handlings = handlings;
91
+  }
92
+
93
+  public String getLastUpdatedOn() {
94
+    return lastUpdatedOn;
95
+  }
96
+
97
+  public void setLastUpdatedOn(String lastUpdatedOn) {
98
+    this.lastUpdatedOn = lastUpdatedOn;
99
+  }
100
+
101
+  public static class Handling {
102
+    String type;
103
+    String location;
104
+    String voyage;
105
+    Date completedOn;
106
+
107
+    public String getType() {
108
+      return type;
109
+    }
110
+
111
+    public void setType(String type) {
112
+      this.type = type;
113
+    }
114
+
115
+    public String getLocation() {
116
+      return location;
117
+    }
118
+
119
+    public void setLocation(String location) {
120
+      this.location = location;
121
+    }
122
+
123
+    public String getVoyage() {
124
+      return voyage;
125
+    }
126
+
127
+    public void setVoyage(String voyage) {
128
+      this.voyage = voyage;
129
+    }
130
+
131
+    public Date getCompletedOn() {
132
+      return completedOn;
133
+    }
134
+
135
+    public void setCompletedOn(Date completedOn) {
136
+      this.completedOn = completedOn;
137
+    }
138
+  }
139
+
140
+}

+ 25
- 0
dddsample/external/reporting/src/main/java/com.reporting/CargoReportRowMapper.java Ver fichero

@@ -0,0 +1,25 @@
1
+package com.reporting;
2
+
3
+import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
4
+
5
+import java.sql.ResultSet;
6
+import java.sql.SQLException;
7
+
8
+class CargoReportRowMapper implements ParameterizedRowMapper<CargoReport> {
9
+
10
+  @Override
11
+  public CargoReport mapRow(ResultSet rs, int rowNum) throws SQLException {
12
+    CargoReport cargoReport = new CargoReport();
13
+    cargoReport.setTrackingId(rs.getString("cargo_tracking_id"));
14
+    cargoReport.setArrivalDeadline(Constants.US_DATETIME.format(rs.getTimestamp("arrival_deadline")));
15
+    cargoReport.setCurrentLocation(rs.getString("current_location"));
16
+    cargoReport.setCurrentStatus(rs.getString("current_status"));
17
+    cargoReport.setCurrentVoyage(rs.getString("current_voyage_number"));
18
+    cargoReport.setEta(Constants.US_DATETIME.format(rs.getTimestamp("eta")));
19
+    cargoReport.setFinalDestination(rs.getString("destination"));
20
+    cargoReport.setLastUpdatedOn(Constants.US_DATETIME.format(rs.getTimestamp("last_updated_on")));
21
+    cargoReport.setReceivedIn(rs.getString("received_in"));
22
+    return cargoReport;
23
+  }
24
+
25
+}

+ 10
- 0
dddsample/external/reporting/src/main/java/com.reporting/Constants.java Ver fichero

@@ -0,0 +1,10 @@
1
+package com.reporting;
2
+
3
+import java.text.DateFormat;
4
+import java.util.Locale;
5
+
6
+public interface Constants {
7
+
8
+  DateFormat US_DATETIME = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.US);
9
+
10
+}

+ 0
- 4
dddsample/external/reporting/src/main/java/com.reporting/DeliveryReport.java Ver fichero

@@ -1,4 +0,0 @@
1
-package com.reporting;
2
-
3
-public class DeliveryReport {
4
-}

+ 20
- 0
dddsample/external/reporting/src/main/java/com.reporting/HandlingRowMapper.java Ver fichero

@@ -0,0 +1,20 @@
1
+package com.reporting;
2
+
3
+import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
4
+
5
+import java.sql.ResultSet;
6
+import java.sql.SQLException;
7
+
8
+class HandlingRowMapper implements ParameterizedRowMapper<CargoReport.Handling> {
9
+
10
+  @Override
11
+  public CargoReport.Handling mapRow(ResultSet rs, int rowNum) throws SQLException {
12
+    CargoReport.Handling handling = new CargoReport.Handling();
13
+    handling.setCompletedOn(rs.getDate("completed_on"));
14
+    handling.setLocation(rs.getString("location"));
15
+    handling.setType(rs.getString("type"));
16
+    handling.setVoyage(rs.getString("voyage_number"));
17
+    return handling;
18
+  }
19
+
20
+}

+ 87
- 3
dddsample/external/reporting/src/main/java/com.reporting/ReportingService.java Ver fichero

@@ -1,9 +1,93 @@
1 1
 package com.reporting;
2 2
 
3
-public interface ReportingService {
3
+import org.springframework.jdbc.core.JdbcTemplate;
4
+import org.springframework.jdbc.core.RowCallbackHandler;
5
+import org.springframework.transaction.annotation.Transactional;
6
+import org.springframework.dao.EmptyResultDataAccessException;
4 7
 
5
-  DeliveryReport getDeliveryReport(int start, int offset);
8
+import javax.sql.DataSource;
9
+import javax.ws.rs.GET;
10
+import javax.ws.rs.Path;
11
+import javax.ws.rs.PathParam;
12
+import javax.ws.rs.Produces;
13
+import javax.ws.rs.core.Response;
14
+import javax.ws.rs.core.Context;
15
+import java.util.List;
16
+import java.util.ArrayList;
17
+import java.sql.ResultSet;
18
+import java.sql.SQLException;
6 19
 
7
-  VoyageReport getVoyageReport();
20
+@Produces("application/json")
21
+@Path("/report")
22
+public class ReportingService {
8 23
 
24
+  private JdbcTemplate jdbc;
25
+  private HandlingRowMapper handlingRowMapper;
26
+  private CargoReportRowMapper cargoReportRowMapper;
27
+  private VoyageReportRowMapper rowMapper;
28
+
29
+  public ReportingService(DataSource dataSource) {
30
+    this.jdbc = new JdbcTemplate(dataSource);
31
+    this.handlingRowMapper = new HandlingRowMapper();
32
+    this.cargoReportRowMapper = new CargoReportRowMapper();
33
+    this.rowMapper = new VoyageReportRowMapper();
34
+  }
35
+
36
+  @GET
37
+  @Path("/cargo/{trackingId}")
38
+  @Transactional
39
+  public CargoReport getCargoReport(@PathParam("trackingId") String trackingId, @Context Response.ResponseBuilder response) {
40
+    CargoReport cargoReport = loadCargoReport(trackingId);
41
+    if (cargoReport == null) return null;
42
+
43
+    cargoReport.setHandlings(loadHandlings(trackingId));
44
+    //response.lastModified(cargoReport.getLastUpdatedOn());
45
+    return cargoReport;
46
+  }
47
+
48
+  @GET
49
+  @Path("/voyage/{voyageNumber}")
50
+  @Transactional
51
+  public VoyageReport getVoyageReport(@PathParam("voyageNumber") String voyageNumber, @Context Response.ResponseBuilder response) {
52
+    VoyageReport voyageReport = loadVoyageReport(voyageNumber);
53
+    if (voyageReport == null) return null;
54
+
55
+    //response.lastModified(voyageReport.getLastUpdatedOn());
56
+    return voyageReport;
57
+  }
58
+
59
+  // --- Private methods ---
60
+
61
+  private CargoReport loadCargoReport(String trackingId) {
62
+    try {
63
+      return (CargoReport) jdbc.queryForObject("select * from cargo where cargo_tracking_id = ?", new String[] {trackingId}, cargoReportRowMapper);
64
+    } catch (EmptyResultDataAccessException e) {
65
+      return null;
66
+    }
67
+  }
68
+
69
+  private List<CargoReport.Handling> loadHandlings(String trackingId) {
70
+    final List<CargoReport.Handling> handlings = new ArrayList<CargoReport.Handling>();
71
+    RowCallbackHandler handler = new RowCallbackHandler() {
72
+      @Override
73
+      public void processRow(ResultSet rs) throws SQLException {
74
+        handlings.add(handlingRowMapper.mapRow(rs, rs.getRow()));
75
+      }
76
+    };
77
+    String[] args = {trackingId};
78
+    String sql = "select * from handling where cargo_tracking_id = ?";
79
+    jdbc.query(sql, args, handler);
80
+    return handlings;
81
+  }
82
+
83
+  private VoyageReport loadVoyageReport(String voyageNumber) {
84
+    String[] args = {voyageNumber};
85
+    String sql = "select * from voyage where voyage_number = ?";
86
+    return (VoyageReport) jdbc.queryForObject(sql, args, rowMapper);
87
+  }
88
+
89
+  ReportingService() {
90
+    // Needed by CGLIB
91
+  }
92
+  
9 93
 }

+ 59
- 0
dddsample/external/reporting/src/main/java/com.reporting/VoyageReport.java Ver fichero

@@ -1,4 +1,63 @@
1 1
 package com.reporting;
2 2
 
3
+import javax.xml.bind.annotation.XmlRootElement;
4
+import java.util.Date;
5
+
6
+@XmlRootElement(name = "voyage")
3 7
 public class VoyageReport {
8
+
9
+  private Date lastUpdatedOn;
10
+  private String voyageNumber;
11
+  private String nextStop;
12
+  private Date etaNextStop;
13
+  private String currentStatus;
14
+  private int delayedByMinutes;
15
+
16
+  public Date getLastUpdatedOn() {
17
+    return lastUpdatedOn;
18
+  }
19
+
20
+  public void setLastUpdatedOn(Date lastUpdatedOn) {
21
+    this.lastUpdatedOn = lastUpdatedOn;
22
+  }
23
+
24
+  public String getVoyageNumber() {
25
+    return voyageNumber;
26
+  }
27
+
28
+  public void setVoyageNumber(String voyageNumber) {
29
+    this.voyageNumber = voyageNumber;
30
+  }
31
+
32
+  public String getNextStop() {
33
+    return nextStop;
34
+  }
35
+
36
+  public void setNextStop(String nextStop) {
37
+    this.nextStop = nextStop;
38
+  }
39
+
40
+  public Date getEtaNextStop() {
41
+    return etaNextStop;
42
+  }
43
+
44
+  public void setEtaNextStop(Date etaNextStop) {
45
+    this.etaNextStop = etaNextStop;
46
+  }
47
+
48
+  public String getCurrentStatus() {
49
+    return currentStatus;
50
+  }
51
+
52
+  public void setCurrentStatus(String currentStatus) {
53
+    this.currentStatus = currentStatus;
54
+  }
55
+
56
+  public int getDelayedByMinutes() {
57
+    return delayedByMinutes;
58
+  }
59
+
60
+  public void setDelayedByMinutes(int delayedByMinutes) {
61
+    this.delayedByMinutes = delayedByMinutes;
62
+  }
4 63
 }

+ 20
- 0
dddsample/external/reporting/src/main/java/com.reporting/VoyageReportRowMapper.java Ver fichero

@@ -0,0 +1,20 @@
1
+package com.reporting;
2
+
3
+import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
4
+
5
+import java.sql.ResultSet;
6
+import java.sql.SQLException;
7
+
8
+class VoyageReportRowMapper implements ParameterizedRowMapper<VoyageReport> {
9
+  @Override
10
+  public VoyageReport mapRow(ResultSet rs, int rowNum) throws SQLException {
11
+    VoyageReport voyageReport = new VoyageReport();
12
+    voyageReport.setVoyageNumber(rs.getString("voyage_number"));
13
+    voyageReport.setCurrentStatus(rs.getString("current_status"));
14
+    voyageReport.setDelayedByMinutes(rs.getInt("delayed_by_min"));
15
+    voyageReport.setEtaNextStop(rs.getDate("eta_next_stop"));
16
+    voyageReport.setLastUpdatedOn(rs.getDate("last_updated_on"));
17
+    voyageReport.setNextStop(rs.getString("next_stop"));
18
+    return voyageReport;
19
+  }
20
+}

+ 23
- 0
dddsample/external/reporting/src/main/resources/context-cxf.xml Ver fichero

@@ -0,0 +1,23 @@
1
+<?xml version="1.0"?>
2
+
3
+<beans xmlns="http://www.springframework.org/schema/beans"
4
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5
+       xmlns:jaxrs="http://cxf.apache.org/jaxrs"
6
+       xmlns:tx="http://www.springframework.org/schema/tx"
7
+       xsi:schemaLocation="
8
+        http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
9
+        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
10
+        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
11
+
12
+  <import resource="classpath:META-INF/cxf/cxf.xml"/>
13
+  <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
14
+  <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml"/>
15
+  <import resource="classpath:META-INF/cxf/cxf-extension-http.xml" />
16
+
17
+  <jaxrs:server address="/">
18
+    <jaxrs:serviceBeans>
19
+      <ref bean="reportingService"/>
20
+    </jaxrs:serviceBeans>
21
+  </jaxrs:server>
22
+
23
+</beans>

+ 29
- 0
dddsample/external/reporting/src/main/resources/context.xml Ver fichero

@@ -0,0 +1,29 @@
1
+<?xml version="1.0"?>
2
+
3
+<beans xmlns="http://www.springframework.org/schema/beans"
4
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5
+       xmlns:jaxrs="http://cxf.apache.org/jaxrs"
6
+       xmlns:tx="http://www.springframework.org/schema/tx"
7
+       xsi:schemaLocation="
8
+        http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
9
+        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
10
+        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
11
+
12
+  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
13
+    <property name="dataSource" ref="dataSource"/>
14
+  </bean>
15
+
16
+  <tx:annotation-driven transaction-manager="transactionManager"/>
17
+
18
+  <bean id="reportingService" class="com.reporting.ReportingService">
19
+    <constructor-arg ref="dataSource"/>
20
+  </bean>
21
+
22
+  <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
23
+    <property name="url" value="jdbc:hsqldb:mem:reporting"/>
24
+    <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
25
+    <property name="username" value="sa"/>
26
+    <property name="password" value=""/>
27
+  </bean>
28
+
29
+</beans>

+ 29
- 0
dddsample/external/reporting/src/main/resources/schema.sql Ver fichero

@@ -0,0 +1,29 @@
1
+create table cargo (
2
+  cargo_tracking_id varchar not null primary key,
3
+  received_in varchar,
4
+  destination varchar,
5
+  arrival_deadline timestamp,
6
+  eta timestamp,
7
+  current_status varchar,
8
+  current_voyage_number varchar,
9
+  current_location varchar,
10
+  last_updated_on timestamp
11
+)
12
+
13
+create table handling (
14
+  cargo_tracking_id varchar not null,
15
+  type varchar,
16
+  location varchar,
17
+  voyage_number varchar,
18
+  completed_on timestamp,
19
+  foreign key (cargo_tracking_id) references cargo(cargo_tracking_id)
20
+)
21
+
22
+create table voyage (
23
+  voyage_number varchar not null primary key,
24
+  next_stop varchar,
25
+  eta_next_stop timestamp,
26
+  current_status varchar not null,
27
+  delayed_by_min int not null,
28
+  last_updated_on timestamp
29
+)

+ 15
- 1
dddsample/external/reporting/src/main/webapp/WEB-INF/web.xml Ver fichero

@@ -21,7 +21,21 @@
21 21
 
22 22
   <context-param>
23 23
     <param-name>contextConfigLocation</param-name>
24
-    <param-value>classpath:applicationContext.xml</param-value>
24
+    <param-value>
25
+      classpath:context.xml
26
+      classpath:context-cxf.xml
27
+    </param-value>
25 28
   </context-param>
26 29
 
30
+  <servlet>
31
+    <servlet-name>cxf</servlet-name>
32
+    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
33
+    <load-on-startup>1</load-on-startup>
34
+  </servlet>
35
+
36
+  <servlet-mapping>
37
+    <servlet-name>cxf</servlet-name>
38
+    <url-pattern>/*</url-pattern>
39
+  </servlet-mapping>
40
+
27 41
 </web-app>

+ 42
- 0
dddsample/external/reporting/src/test/java/com/reporting/Fixture.java Ver fichero

@@ -0,0 +1,42 @@
1
+/**
2
+ * Purpose
3
+ * @author peter
4
+ * @created 2009-okt-03
5
+ * $Id$
6
+ */
7
+package com.reporting;
8
+
9
+import org.apache.commons.io.IOUtils;
10
+import org.springframework.context.ApplicationEvent;
11
+import org.springframework.context.ApplicationListener;
12
+import org.springframework.context.event.ContextRefreshedEvent;
13
+import org.springframework.core.io.Resource;
14
+import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
15
+
16
+import javax.sql.DataSource;
17
+import java.io.IOException;
18
+
19
+public class Fixture implements ApplicationListener {
20
+
21
+  private SimpleJdbcTemplate jdbc;
22
+  private Resource schema;
23
+  private Resource testdata;
24
+
25
+  public Fixture(DataSource dataSource, Resource schema, Resource testdata) {
26
+    this.jdbc = new SimpleJdbcTemplate(dataSource);
27
+    this.testdata = testdata;
28
+    this.schema = schema;
29
+  }
30
+
31
+  @Override
32
+  public void onApplicationEvent(ApplicationEvent event) {
33
+    if (event instanceof ContextRefreshedEvent) {
34
+      try {
35
+        jdbc.update(IOUtils.toString(schema.getInputStream()));
36
+        jdbc.update(IOUtils.toString(testdata.getInputStream()));
37
+      } catch (IOException e) {
38
+        throw new RuntimeException(e);
39
+      }
40
+    }
41
+  }
42
+}

+ 71
- 0
dddsample/external/reporting/src/test/java/com/reporting/ReportServiceTest.java Ver fichero

@@ -0,0 +1,71 @@
1
+package com.reporting;
2
+
3
+import org.apache.commons.io.IOUtils;
4
+import org.codehaus.jettison.json.JSONObject;
5
+import org.codehaus.jettison.json.JSONException;
6
+import org.codehaus.jettison.json.JSONArray;
7
+import static org.junit.Assert.assertEquals;
8
+import static org.junit.Assert.*;
9
+import org.junit.Test;
10
+import org.junit.Assert;
11
+import org.junit.runner.RunWith;
12
+import org.springframework.test.context.ContextConfiguration;
13
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
14
+
15
+import java.net.URL;
16
+import java.net.URLConnection;
17
+import java.io.IOException;
18
+
19
+@RunWith(SpringJUnit4ClassRunner.class)
20
+@ContextConfiguration(locations={"/context.xml", "/context-cxf.xml", "/context-test-setup.xml"})
21
+public class ReportServiceTest {
22
+
23
+  @Test
24
+  public void deliveryReport() throws Exception {
25
+    JSONObject json = readJSON("/report/cargo/ABC");
26
+    JSONObject cargo = json.getJSONObject("cargo");
27
+    
28
+    assertEquals("ABC", cargo.get("trackingId"));
29
+    assertEquals("Hongkong", cargo.get("receivedIn"));
30
+    assertEquals("Stockholm", cargo.get("finalDestination"));
31
+    assertEquals("6/15/09 12:00 PM", cargo.get("arrivalDeadline"));
32
+    assertEquals("6/12/09 6:30 PM", cargo.get("eta"));
33
+    assertEquals("Onboard voyage", cargo.get("currentStatus"));
34
+    assertEquals("V0100", cargo.get("currentVoyage"));
35
+    assertEquals("Tokyo", cargo.get("currentLocation"));
36
+    assertEquals("6/8/09 2:23 PM", cargo.get("lastUpdatedOn"));
37
+
38
+    JSONArray handlings = cargo.getJSONArray("handlings");
39
+    assertEquals(4, handlings.length());
40
+
41
+    verifyHandling(handlings.getJSONObject(0), "Receive", "Hongkong", null);
42
+    verifyHandling(handlings.getJSONObject(1), "Load", "Hongkong", "V0100");
43
+    verifyHandling(handlings.getJSONObject(2), "Unload", "Long Beach", "V0100");
44
+    verifyHandling(handlings.getJSONObject(3), "Load", "Long Beach", "V0200");
45
+  }
46
+
47
+  private void verifyHandling(JSONObject handling, String type, String location, String voyage) throws JSONException {
48
+    assertEquals(type, handling.get("type"));
49
+    assertEquals(location, handling.get("location"));
50
+    if (voyage == null) {
51
+      assertFalse(handling.has("voyage"));
52
+    } else {
53
+      assertEquals(voyage, handling.get("voyage"));
54
+    }
55
+  }
56
+
57
+  @Test
58
+  public void voyageReport() throws Exception {
59
+    JSONObject json = readJSON("/report/voyage/V0200");
60
+    JSONObject voyage = json.getJSONObject("voyage");
61
+
62
+    assertEquals("V0200", voyage.get("voyageNumber"));
63
+  }
64
+
65
+  private JSONObject readJSON(String path) throws IOException, JSONException {
66
+    URLConnection urlConnection = new URL("http://localhost:14000" + path).openConnection();
67
+    String jsonString = IOUtils.toString(urlConnection.getInputStream());
68
+    return new JSONObject(jsonString);
69
+  }
70
+
71
+}

+ 23
- 0
dddsample/external/reporting/src/test/resources/context-cxf.xml Ver fichero

@@ -0,0 +1,23 @@
1
+<?xml version="1.0"?>
2
+
3
+<beans xmlns="http://www.springframework.org/schema/beans"
4
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5
+       xmlns:jaxrs="http://cxf.apache.org/jaxrs"
6
+       xmlns:tx="http://www.springframework.org/schema/tx"
7
+       xsi:schemaLocation="
8
+        http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
9
+        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
10
+        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
11
+
12
+  <import resource="classpath:META-INF/cxf/cxf.xml"/>
13
+  <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
14
+  <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml"/>
15
+  <import resource="classpath:META-INF/cxf/cxf-extension-http-jetty.xml" />
16
+
17
+  <jaxrs:server address="http://localhost:14000" id="jaxRsService">
18
+    <jaxrs:serviceBeans>
19
+      <ref bean="reportingService"/>
20
+    </jaxrs:serviceBeans>
21
+  </jaxrs:server>
22
+
23
+</beans>

+ 13
- 0
dddsample/external/reporting/src/test/resources/context-test-setup.xml Ver fichero

@@ -0,0 +1,13 @@
1
+<?xml version="1.0"?>
2
+
3
+<beans xmlns="http://www.springframework.org/schema/beans"
4
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
6
+
7
+  <bean class="com.reporting.Fixture">
8
+    <constructor-arg ref="dataSource"/>
9
+    <constructor-arg value="classpath:schema.sql"/>
10
+    <constructor-arg value="classpath:testdata.sql"/>
11
+  </bean>
12
+
13
+</beans>

+ 67
- 0
dddsample/external/reporting/src/test/resources/testdata.sql Ver fichero

@@ -0,0 +1,67 @@
1
+insert into cargo (
2
+  cargo_tracking_id,
3
+  received_in,
4
+  destination,
5
+  arrival_deadline,
6
+  eta,
7
+  current_status,
8
+  current_voyage_number,
9
+  current_location,
10
+  last_updated_on
11
+) values (
12
+  'ABC',
13
+  'Hongkong',
14
+  'Stockholm',
15
+  '2009-06-15 12:00:00.000',
16
+  '2009-06-12 18:30:00.000',
17
+  'Onboard voyage',
18
+  'V0100',
19
+  'Tokyo',
20
+  '2009-06-08 14:23:12.123'
21
+);
22
+
23
+insert into handling (cargo_tracking_id, type,location,voyage_number,completed_on)
24
+values ('ABC','Receive','Hongkong',  null,   '2009-05-30 07:32:00.000');
25
+
26
+insert into handling (cargo_tracking_id, type,location,voyage_number,completed_on)
27
+values ('ABC','Load',   'Hongkong',  'V0100','2009-05-31 13:37:00.000');
28
+
29
+insert into handling (cargo_tracking_id, type,location,voyage_number,completed_on)
30
+values ('ABC','Unload', 'Long Beach','V0100','2009-06-04 19:01:00.000');
31
+
32
+insert into handling (cargo_tracking_id, type,location,voyage_number,completed_on)
33
+values ('ABC','Load',   'Long Beach','V0200','2009-06-06 22:50:00.000');
34
+
35
+insert into voyage (
36
+  voyage_number,
37
+  next_stop,
38
+  eta_next_stop,
39
+  current_status,
40
+  delayed_by_min,
41
+  last_updated_on
42
+)
43
+values (
44
+  'V0100',
45
+  'Honolulu',
46
+  '',
47
+  'In port',
48
+  '300',
49
+  ''
50
+);
51
+
52
+insert into voyage (
53
+  voyage_number,
54
+  next_stop,
55
+  eta_next_stop,
56
+  current_status,
57
+  delayed_by_min,
58
+  last_updated_on
59
+)
60
+values (
61
+  'V0200',
62
+  'Seattle',
63
+  '',
64
+  'In transit',
65
+  '0',
66
+  ''
67
+);