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

Implemented storage of cargo details and handlings in reporting context

peter_backlund преди 16 години
родител
ревизия
11fcd8cfea

+ 17
- 9
dddsample/external/reporting/src/main/java/com/reporting/ReportingService.java Целия файл

1
 package com.reporting;
1
 package com.reporting;
2
 
2
 
3
-import static com.reporting.Constants.US_DATETIME;
4
 import com.reporting.db.ReportDAO;
3
 import com.reporting.db.ReportDAO;
5
 import com.reporting.reports.CargoReport;
4
 import com.reporting.reports.CargoReport;
6
 import com.reporting.reports.VoyageReport;
5
 import com.reporting.reports.VoyageReport;
6
+import org.apache.commons.logging.Log;
7
+import org.apache.commons.logging.LogFactory;
8
+import org.springframework.transaction.annotation.Transactional;
7
 import se.citerus.dddsample.reporting.api.CargoDetails;
9
 import se.citerus.dddsample.reporting.api.CargoDetails;
8
 import se.citerus.dddsample.reporting.api.Handling;
10
 import se.citerus.dddsample.reporting.api.Handling;
9
 
11
 
10
 import javax.ws.rs.*;
12
 import javax.ws.rs.*;
11
 import javax.ws.rs.core.Response;
13
 import javax.ws.rs.core.Response;
14
+import java.text.ParseException;
15
+
16
+import static com.reporting.Constants.US_DATETIME;
12
 import static javax.ws.rs.core.Response.ok;
17
 import static javax.ws.rs.core.Response.ok;
13
 import static javax.ws.rs.core.Response.status;
18
 import static javax.ws.rs.core.Response.status;
14
-import java.text.ParseException;
15
 
19
 
16
 @Produces({"application/json", "application/pdf"})
20
 @Produces({"application/json", "application/pdf"})
17
-@Consumes("application/json")
21
+@Consumes({"application/json", "application/xml"})
18
 @Path("/")
22
 @Path("/")
19
 public class ReportingService {
23
 public class ReportingService {
20
 
24
 
21
   private ReportDAO reportDAO;
25
   private ReportDAO reportDAO;
26
+  private static final Log LOG = LogFactory.getLog(ReportingService.class);
22
 
27
 
23
   public ReportingService(ReportDAO reportDAO) {
28
   public ReportingService(ReportDAO reportDAO) {
24
     this.reportDAO = reportDAO;
29
     this.reportDAO = reportDAO;
50
 
55
 
51
   @PUT
56
   @PUT
52
   @Path("/cargo")
57
   @Path("/cargo")
53
-  public void reportCargoDetails(CargoDetails cargoDetails) {
54
-    // TODO
55
-    System.out.println("Received " + cargoDetails);
58
+  @Transactional
59
+  public void reportCargo(CargoDetails cargoDetails) {
60
+    reportDAO.storeCargoDetals(cargoDetails);
61
+    LOG.info("Stored cargo: " + cargoDetails);
56
   }
62
   }
57
 
63
 
58
-  @PUT
64
+  @POST
59
   @Path("/cargo/{trackingId}/handled")
65
   @Path("/cargo/{trackingId}/handled")
66
+  @Transactional
60
   public void reportHandling(@PathParam("trackingId") String trackingId, Handling handling) {
67
   public void reportHandling(@PathParam("trackingId") String trackingId, Handling handling) {
61
-    // TODO
62
-    System.out.println("Received " + trackingId + " : " + handling);
68
+    reportDAO.storeHandling(trackingId, handling);
69
+    LOG.info("Stored handling of cargo " + trackingId + ": " + handling);
63
   }
70
   }
64
 
71
 
72
+  @SuppressWarnings({"UnusedDeclaration"})
65
   ReportingService() {
73
   ReportingService() {
66
     // Needed by CGLIB
74
     // Needed by CGLIB
67
   }
75
   }

+ 70
- 10
dddsample/external/reporting/src/main/java/com/reporting/db/ReportDAO.java Целия файл

3
 import com.reporting.reports.CargoReport;
3
 import com.reporting.reports.CargoReport;
4
 import com.reporting.reports.VoyageReport;
4
 import com.reporting.reports.VoyageReport;
5
 import org.springframework.dao.EmptyResultDataAccessException;
5
 import org.springframework.dao.EmptyResultDataAccessException;
6
-import org.springframework.jdbc.core.JdbcTemplate;
7
 import org.springframework.jdbc.core.RowCallbackHandler;
6
 import org.springframework.jdbc.core.RowCallbackHandler;
8
-import org.springframework.transaction.annotation.Transactional;
7
+import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
8
+import se.citerus.dddsample.reporting.api.CargoDetails;
9
 import se.citerus.dddsample.reporting.api.Handling;
9
 import se.citerus.dddsample.reporting.api.Handling;
10
 import se.citerus.dddsample.reporting.api.OnboardCargo;
10
 import se.citerus.dddsample.reporting.api.OnboardCargo;
11
 
11
 
17
 
17
 
18
 public class ReportDAO {
18
 public class ReportDAO {
19
   
19
   
20
-  private JdbcTemplate jdbc;
20
+  private SimpleJdbcTemplate jdbc;
21
   private HandlingRowMapper handlingRowMapper;
21
   private HandlingRowMapper handlingRowMapper;
22
   private CargoReportRowMapper cargoReportRowMapper;
22
   private CargoReportRowMapper cargoReportRowMapper;
23
   private VoyageReportRowMapper rowMapper;
23
   private VoyageReportRowMapper rowMapper;
24
   private VoyageCargoRowMapper voyageCargoRowMapper;
24
   private VoyageCargoRowMapper voyageCargoRowMapper;
25
 
25
 
26
   public ReportDAO(DataSource dataSource) {
26
   public ReportDAO(DataSource dataSource) {
27
-    this.jdbc = new JdbcTemplate(dataSource);
27
+    this.jdbc = new SimpleJdbcTemplate(dataSource);
28
     this.handlingRowMapper = new HandlingRowMapper();
28
     this.handlingRowMapper = new HandlingRowMapper();
29
     this.cargoReportRowMapper = new CargoReportRowMapper();
29
     this.cargoReportRowMapper = new CargoReportRowMapper();
30
     this.rowMapper = new VoyageReportRowMapper();
30
     this.rowMapper = new VoyageReportRowMapper();
31
     this.voyageCargoRowMapper = new VoyageCargoRowMapper();
31
     this.voyageCargoRowMapper = new VoyageCargoRowMapper();
32
   }
32
   }
33
 
33
 
34
-  @Transactional(readOnly = true)
35
   public CargoReport loadCargoReport(String trackingId) {
34
   public CargoReport loadCargoReport(String trackingId) {
36
     try {
35
     try {
37
       String[] args = {trackingId};
36
       String[] args = {trackingId};
38
       String sql = "select * from cargo where cargo_tracking_id = ?";
37
       String sql = "select * from cargo where cargo_tracking_id = ?";
39
-      CargoReport cargoReport = (CargoReport) jdbc.queryForObject(sql, args, cargoReportRowMapper);
38
+      CargoReport cargoReport = (CargoReport) jdbc.getJdbcOperations().queryForObject(sql, args, cargoReportRowMapper);
40
       cargoReport.setHandlings(loadHandlings(trackingId));
39
       cargoReport.setHandlings(loadHandlings(trackingId));
41
       return cargoReport;
40
       return cargoReport;
42
     } catch (EmptyResultDataAccessException e) {
41
     } catch (EmptyResultDataAccessException e) {
44
     }
43
     }
45
   }
44
   }
46
 
45
 
47
-  @Transactional(readOnly = true)
48
   public VoyageReport loadVoyageReport(String voyageNumber) {
46
   public VoyageReport loadVoyageReport(String voyageNumber) {
49
     String[] args = {voyageNumber};
47
     String[] args = {voyageNumber};
50
     String sql = "select * from voyage where voyage_number = ?";
48
     String sql = "select * from voyage where voyage_number = ?";
51
     try {
49
     try {
52
-      VoyageReport voyageReport = (VoyageReport) jdbc.queryForObject(sql, args, rowMapper);
50
+      VoyageReport voyageReport = (VoyageReport) jdbc.getJdbcOperations().queryForObject(sql, args, rowMapper);
53
       voyageReport.setOnboardCargos(loadOnboardCargos(voyageNumber));
51
       voyageReport.setOnboardCargos(loadOnboardCargos(voyageNumber));
54
       return voyageReport;
52
       return voyageReport;
55
     } catch (EmptyResultDataAccessException e) {
53
     } catch (EmptyResultDataAccessException e) {
57
     }
55
     }
58
   }
56
   }
59
 
57
 
58
+  public void storeCargoDetals(CargoDetails cargoDetails) {
59
+    int count = jdbc.queryForInt("select count(*) from cargo where cargo_tracking_id = ?", cargoDetails.getTrackingId());
60
+
61
+    String sql;
62
+    Object[] params;
63
+    if (count > 0) {
64
+      sql =
65
+        "update cargo set " +
66
+          "received_in = ?," +
67
+          "destination = ?," +
68
+          "arrival_deadline = ?," +
69
+          "eta = ?," +
70
+          "current_status = ?," +
71
+          "current_voyage_number = ?," +
72
+          "current_location = ?," +
73
+          "last_updated_on = ? " +
74
+        "where cargo_tracking_id = ?";
75
+      params = new Object[] {
76
+        cargoDetails.getReceivedIn(),
77
+        cargoDetails.getFinalDestination(),
78
+        cargoDetails.getArrivalDeadline(),
79
+        cargoDetails.getEta(),
80
+        cargoDetails.getCurrentStatus(),
81
+        cargoDetails.getCurrentVoyage(),
82
+        cargoDetails.getCurrentLocation(),
83
+        cargoDetails.getLastUpdatedOn(),
84
+        cargoDetails.getTrackingId()
85
+      };
86
+    } else {
87
+      sql =
88
+        "insert into cargo (" +
89
+          "cargo_tracking_id," +
90
+          "received_in," +
91
+          "destination," +
92
+          "arrival_deadline," +
93
+          "eta," +
94
+          "current_status," +
95
+          "current_voyage_number," +
96
+          "current_location," +
97
+          "last_updated_on) " +
98
+        "values (?,?,?,?,?,?,?,?,?)";
99
+      params = new Object[] {
100
+        cargoDetails.getTrackingId(),
101
+        cargoDetails.getReceivedIn(),
102
+        cargoDetails.getFinalDestination(),
103
+        cargoDetails.getArrivalDeadline(),
104
+        cargoDetails.getEta(),
105
+        cargoDetails.getCurrentStatus(),
106
+        cargoDetails.getCurrentVoyage(),
107
+        cargoDetails.getCurrentLocation(),
108
+        cargoDetails.getLastUpdatedOn()
109
+      };
110
+    }
111
+
112
+    jdbc.update(sql, params);
113
+  }
114
+
115
+  public void storeHandling(String trackingId, Handling handling) {
116
+    String sql = "insert into handling (cargo_tracking_id,type,location,voyage_number,completed_on) values (?,?,?,?,?)";
117
+    jdbc.update(sql, trackingId, handling.getType(), handling.getLocation(), handling.getVoyage(), handling.getCompletedOn());  
118
+  }
119
+
60
   private List<Handling> loadHandlings(String trackingId) {
120
   private List<Handling> loadHandlings(String trackingId) {
61
     final List<Handling> handlings = new ArrayList<Handling>();
121
     final List<Handling> handlings = new ArrayList<Handling>();
62
     RowCallbackHandler handler = new RowCallbackHandler() {
122
     RowCallbackHandler handler = new RowCallbackHandler() {
67
     };
127
     };
68
     String[] args = {trackingId};
128
     String[] args = {trackingId};
69
     String sql = "select * from handling where cargo_tracking_id = ?";
129
     String sql = "select * from handling where cargo_tracking_id = ?";
70
-    jdbc.query(sql, args, handler);
130
+    jdbc.getJdbcOperations().query(sql, args, handler);
71
     return handlings;
131
     return handlings;
72
   }
132
   }
73
 
133
 
75
     final List<OnboardCargo> onboardCargos = new ArrayList<OnboardCargo>();
135
     final List<OnboardCargo> onboardCargos = new ArrayList<OnboardCargo>();
76
     String[] args = {voyageNumber};
136
     String[] args = {voyageNumber};
77
     String sql = "select cargo_tracking_id, destination from cargo where current_voyage_number = ?";
137
     String sql = "select cargo_tracking_id, destination from cargo where current_voyage_number = ?";
78
-    jdbc.query(sql, args, new RowCallbackHandler() {
138
+    jdbc.getJdbcOperations().query(sql, args, new RowCallbackHandler() {
79
       @Override
139
       @Override
80
       public void processRow(ResultSet rs) throws SQLException {
140
       public void processRow(ResultSet rs) throws SQLException {
81
         onboardCargos.add(voyageCargoRowMapper.mapRow(rs, rs.getRow()));
141
         onboardCargos.add(voyageCargoRowMapper.mapRow(rs, rs.getRow()));

+ 4
- 0
dddsample/external/reporting/src/main/webapp/index.jsp Целия файл

41
             }
41
             }
42
 
42
 
43
             $('#result').append('<p>Updated on: ' + cargo.lastUpdatedOn + '</p>');
43
             $('#result').append('<p>Updated on: ' + cargo.lastUpdatedOn + '</p>');
44
+
45
+            for (var handling in json.cargoReport.handlings) {
46
+              $('#result').append('<p>' + handling['location'] + '</p>');
47
+            }
44
           },
48
           },
45
           error: function(response) {
49
           error: function(response) {
46
             if (response.status == 404) {
50
             if (response.status == 404) {

+ 100
- 5
dddsample/external/reporting/src/test/java/com/reporting/ReportServiceTest.java Целия файл

1
 package com.reporting;
1
 package com.reporting;
2
 
2
 
3
+import com.reporting.db.ReportDAO;
4
+import com.reporting.reports.CargoReport;
3
 import org.apache.commons.io.IOUtils;
5
 import org.apache.commons.io.IOUtils;
4
 import org.codehaus.jettison.json.JSONArray;
6
 import org.codehaus.jettison.json.JSONArray;
5
 import org.codehaus.jettison.json.JSONException;
7
 import org.codehaus.jettison.json.JSONException;
6
 import org.codehaus.jettison.json.JSONObject;
8
 import org.codehaus.jettison.json.JSONObject;
7
-import static org.junit.Assert.*;
8
 import org.junit.Test;
9
 import org.junit.Test;
9
 import org.junit.runner.RunWith;
10
 import org.junit.runner.RunWith;
11
+import org.springframework.beans.factory.annotation.Autowired;
10
 import org.springframework.test.context.ContextConfiguration;
12
 import org.springframework.test.context.ContextConfiguration;
11
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
13
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
14
+import se.citerus.dddsample.reporting.api.Handling;
12
 
15
 
16
+import javax.xml.stream.XMLOutputFactory;
17
+import javax.xml.stream.XMLStreamException;
18
+import javax.xml.stream.XMLStreamWriter;
13
 import java.io.FileNotFoundException;
19
 import java.io.FileNotFoundException;
14
 import java.io.IOException;
20
 import java.io.IOException;
21
+import java.net.HttpURLConnection;
15
 import java.net.URL;
22
 import java.net.URL;
16
 import java.net.URLConnection;
23
 import java.net.URLConnection;
24
+import java.util.List;
25
+
26
+import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
27
+import static org.junit.Assert.*;
17
 
28
 
18
 @RunWith(SpringJUnit4ClassRunner.class)
29
 @RunWith(SpringJUnit4ClassRunner.class)
19
 @ContextConfiguration(locations={"/context.xml", "/context-cxf.xml", "/context-test-setup.xml"})
30
 @ContextConfiguration(locations={"/context.xml", "/context-cxf.xml", "/context-test-setup.xml"})
20
 public class ReportServiceTest {
31
 public class ReportServiceTest {
21
 
32
 
33
+  @Autowired
34
+  ReportDAO reportDAO;
35
+  private XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();
36
+
22
   @Test
37
   @Test
23
   public void cargoReport() throws Exception {
38
   public void cargoReport() throws Exception {
24
     JSONObject json = readJSON("/cargo/ABC.json");
39
     JSONObject json = readJSON("/cargo/ABC.json");
102
     assertTrue(pdf.length() > 0);
117
     assertTrue(pdf.length() > 0);
103
   }
118
   }
104
 
119
 
120
+  @Test
121
+  public void reportCargo() throws Exception {
122
+    HttpURLConnection con = openXMLPutConnection("/cargo");
123
+    XMLStreamWriter writer = xmlOutputFactory.createXMLStreamWriter(con.getOutputStream());
124
+    writer.writeStartDocument();
125
+    writer.writeStartElement("cargoDetails");
126
+
127
+    addElement(writer, "trackingId", "FGH456");
128
+    addElement(writer, "receivedIn", "HONGKONG");
129
+    addElement(writer, "finalDestination", "HELSINKI");
130
+    addElement(writer, "arrivalDeadline", "2010-05-15");
131
+    addElement(writer, "eta", "2010-05-04 14:30");
132
+    addElement(writer, "currentStatus", "ONBOARD_CARRIER");
133
+    addElement(writer, "currentVoyage", "S0134");
134
+    addElement(writer, "currentLocation", "");
135
+    addElement(writer, "lastUpdatedOn", "2010-05-01 12:20");
136
+
137
+    writer.writeEndElement();
138
+    writer.writeEndDocument();
139
+
140
+    writer.flush();
141
+    writer.close();
142
+    
143
+    assertEquals(HTTP_NO_CONTENT, con.getResponseCode());
144
+
145
+    CargoReport cargoReport = reportDAO.loadCargoReport("FGH456");
146
+    assertNotNull(cargoReport);
147
+  }
148
+
149
+  @Test
150
+  public void reportHandling() throws Exception {
151
+    HttpURLConnection con = openXMLPostConnection("/cargo/ABC/handled");
152
+    XMLStreamWriter writer = xmlOutputFactory.createXMLStreamWriter(con.getOutputStream());
153
+    writer.writeStartDocument();
154
+    writer.writeStartElement("handling");
155
+
156
+    addElement(writer, "type", "Unload");
157
+    addElement(writer, "location", "New York");
158
+    addElement(writer, "voyage", "V0200");
159
+    addElement(writer, "completedOn", "2009-06-09 12:10");
160
+
161
+    writer.writeEndElement();
162
+    writer.writeEndDocument();
163
+
164
+    writer.flush();
165
+    writer.close();
166
+
167
+    assertEquals(HTTP_NO_CONTENT, con.getResponseCode());
168
+
169
+    CargoReport cargoReport = reportDAO.loadCargoReport("ABC");
170
+    List<Handling> handlings = cargoReport.getHandlings();
171
+    assertEquals(5, handlings.size());
172
+    assertEquals("Unload", handlings.get(4).getType());
173
+  }
174
+
175
+  private HttpURLConnection openXMLPostConnection(String path) throws IOException {
176
+    return openWithMethod(path, "POST");
177
+  }
178
+
179
+  private HttpURLConnection openXMLPutConnection(String path) throws IOException {
180
+    return openWithMethod(path, "PUT");
181
+  }
182
+
183
+  private HttpURLConnection openWithMethod(String path, String method) throws IOException {
184
+    HttpURLConnection con = open(path);
185
+    con.setDoOutput(true);
186
+    con.setRequestMethod(method);
187
+    con.setRequestProperty("Content-type", "application/xml");
188
+    return con;
189
+  }
190
+
191
+  private void addElement(XMLStreamWriter writer, String elementName, String content) throws XMLStreamException {
192
+    writer.writeStartElement(elementName);
193
+    writer.writeCharacters(content);
194
+    writer.writeEndElement();
195
+  }
196
+
105
   private void verifyHandling(JSONObject handling, String type, String location, String voyage) throws JSONException {
197
   private void verifyHandling(JSONObject handling, String type, String location, String voyage) throws JSONException {
106
     assertEquals(type, handling.get("type"));
198
     assertEquals(type, handling.get("type"));
107
     assertEquals(location, handling.get("location"));
199
     assertEquals(location, handling.get("location"));
113
   }
205
   }
114
 
206
 
115
   private JSONObject readJSON(String path) throws IOException, JSONException {
207
   private JSONObject readJSON(String path) throws IOException, JSONException {
116
-    URL url = new URL("http://localhost:14000" + path);
117
-    URLConnection urlConnection = url.openConnection();
208
+    URLConnection urlConnection = open(path);
118
     String jsonString = IOUtils.toString(urlConnection.getInputStream());
209
     String jsonString = IOUtils.toString(urlConnection.getInputStream());
119
     return new JSONObject(jsonString);
210
     return new JSONObject(jsonString);
120
   }
211
   }
121
 
212
 
122
   private String readPDF(String path) throws IOException {
213
   private String readPDF(String path) throws IOException {
123
-    URL url = new URL("http://localhost:14000" + path);
124
-    URLConnection urlConnection = url.openConnection();
214
+    URLConnection urlConnection = open(path);
125
     return IOUtils.toString(urlConnection.getInputStream());
215
     return IOUtils.toString(urlConnection.getInputStream());
126
   }
216
   }
127
 
217
 
218
+  private HttpURLConnection open(String path) throws IOException {
219
+    URL url = new URL("http://localhost:14000" + path);
220
+    return (HttpURLConnection) url.openConnection();
221
+  }
222
+
128
 }
223
 }