1 package se.citerus.dddsample.application.util;
2
3 import org.hibernate.SessionFactory;
4 import org.hibernate.classic.Session;
5 import org.springframework.beans.factory.BeanFactoryUtils;
6 import org.springframework.jdbc.core.JdbcTemplate;
7 import org.springframework.transaction.PlatformTransactionManager;
8 import org.springframework.transaction.TransactionStatus;
9 import org.springframework.transaction.support.TransactionCallbackWithoutResult;
10 import org.springframework.transaction.support.TransactionTemplate;
11 import org.springframework.web.context.WebApplicationContext;
12 import org.springframework.web.context.support.WebApplicationContextUtils;
13 import static se.citerus.dddsample.application.util.DateTestUtil.toDate;
14 import se.citerus.dddsample.domain.model.cargo.*;
15 import se.citerus.dddsample.domain.model.handling.*;
16 import se.citerus.dddsample.domain.model.location.Location;
17 import se.citerus.dddsample.domain.model.location.LocationRepository;
18 import se.citerus.dddsample.domain.model.location.SampleLocations;
19 import static se.citerus.dddsample.domain.model.location.SampleLocations.*;
20 import static se.citerus.dddsample.domain.model.voyage.SampleVoyages.*;
21 import se.citerus.dddsample.domain.model.voyage.VoyageRepository;
22
23 import javax.servlet.ServletContextEvent;
24 import javax.servlet.ServletContextListener;
25 import javax.sql.DataSource;
26 import java.sql.Timestamp;
27 import java.text.ParseException;
28 import java.text.SimpleDateFormat;
29 import static java.util.Arrays.asList;
30 import java.util.Date;
31
32
33
34
35 public class SampleDataGenerator implements ServletContextListener {
36
37 private static final Timestamp base;
38 static {
39 try {
40 Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2008-01-01");
41 base = new Timestamp(date.getTime() - 1000L * 60 * 60 * 24 * 100);
42 } catch (ParseException e) {
43 throw new RuntimeException(e);
44 }
45 }
46
47 private static void loadHandlingEventData(JdbcTemplate jdbcTemplate) {
48 String handlingEventSql =
49 "insert into HandlingEvent (completionTime, registrationTime, type, location_id, voyage_id, cargo_id) " +
50 "values (?, ?, ?, ?, ?, ?)";
51
52 Object[][] handlingEventArgs = {
53
54 {ts(0), ts((0)), "RECEIVE", 1, null, 1},
55 {ts((4)), ts((5)), "LOAD", 1, 1, 1},
56 {ts((14)), ts((14)), "UNLOAD", 5, 1, 1},
57 {ts((15)), ts((15)), "LOAD", 5, 1, 1},
58 {ts((30)), ts((30)), "UNLOAD", 6, 1, 1},
59 {ts((33)), ts((33)), "LOAD", 6, 1, 1},
60 {ts((34)), ts((34)), "UNLOAD", 3, 1, 1},
61 {ts((60)), ts((60)), "LOAD", 3, 1, 1},
62 {ts((70)), ts((71)), "UNLOAD", 4, 1, 1},
63 {ts((75)), ts((75)), "LOAD", 4, 1, 1},
64 {ts((88)), ts((88)), "UNLOAD", 2, 1, 1},
65 {ts((100)), ts((102)), "CLAIM", 2, null, 1},
66
67
68 {ts((200)), ts((201)), "RECEIVE", 2, null, 3},
69 {ts((202)), ts((202)), "LOAD", 2, 2, 3},
70 {ts((208)), ts((208)), "UNLOAD", 7, 2, 3},
71 {ts((212)), ts((212)), "LOAD", 7, 2, 3},
72 {ts((230)), ts((230)), "UNLOAD", 6, 2, 3},
73 {ts((235)), ts((235)), "LOAD", 6, 2, 3},
74
75
76 {ts((20)), ts((21)), "CLAIM", 2, null, 2},
77
78
79 {ts((0)), ts((1)), "RECEIVE", 2, null, 4},
80 {ts((10)), ts((11)), "LOAD", 2, 2, 4},
81 {ts((20)), ts((21)), "UNLOAD", 7, 2, 4},
82
83
84 {ts(100), ts(160), "RECEIVE", 3, null, 5},
85 {ts(150), ts(110), "LOAD", 3, 3, 5},
86
87
88 {ts(200), ts(220), "RECEIVE", 6, null, 6},
89 {ts(300), ts(330), "LOAD", 6, 3, 6},
90 {ts(400), ts(440), "UNLOAD", 5, 3, 6}
91 };
92 executeUpdate(jdbcTemplate, handlingEventSql, handlingEventArgs);
93 }
94
95 private static void loadCarrierMovementData(JdbcTemplate jdbcTemplate) {
96 String voyageSql =
97 "insert into Voyage (id, voyage_number) values (?, ?)";
98 Object[][] voyageArgs = {
99 {1,"0101"},
100 {2,"0202"},
101 {3,"0303"}
102 };
103 executeUpdate(jdbcTemplate, voyageSql, voyageArgs);
104
105 String carrierMovementSql =
106 "insert into CarrierMovement (id, voyage_id, departure_location_id, arrival_location_id, departure_time, arrival_time, cm_index) " +
107 "values (?,?,?,?,?,?,?)";
108
109 Object[][] carrierMovementArgs = {
110
111 {1,1,1,5,ts(1),ts(2),0},
112 {2,1,5,6,ts(1),ts(2),1},
113 {3,1,6,3,ts(1),ts(2),2},
114 {4,1,3,4,ts(1),ts(2),3},
115 {5,1,4,2,ts(1),ts(2),4},
116
117
118 {7,2,2,7,ts(1),ts(2),0},
119 {8,2,7,6,ts(1),ts(2),1},
120 {9,2,6,1,ts(1),ts(2),2},
121 {6,2,1,5,ts(1),ts(2),3},
122
123
124 {10,3,3,2,ts(1),ts(2),0},
125 {11,3,2,5,ts(1),ts(2),1},
126 {12,3,6,1,ts(1),ts(2),2},
127 {13,3,1,7,ts(1),ts(2),3},
128 {14,3,7,4,ts(1),ts(2),4}
129 };
130 executeUpdate(jdbcTemplate, carrierMovementSql, carrierMovementArgs);
131 }
132
133 private static void loadCargoData(JdbcTemplate jdbcTemplate) {
134 String cargoSql =
135 "insert into Cargo (id, tracking_id, origin_id, spec_origin_id, spec_destination_id, spec_arrival_deadline, transport_status, current_voyage_id, last_known_location_id, is_misdirected, routing_status, calculated_at, unloaded_at_dest) " +
136 "values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
137
138 Object[][] cargoArgs = {
139 {1, "XYZ", 1, 1, 2, ts(10), "IN_PORT", null, 1, false, "ROUTED", ts(100), false},
140 {2, "ABC", 1, 1, 5, ts(20), "IN_PORT", null, 1, false, "ROUTED", ts(100), false},
141 {3, "ZYX", 2, 2, 1, ts(30), "IN_PORT", null, 1, false, "NOT_ROUTED", ts(100), false},
142 {4, "CBA", 5, 5, 1, ts(40), "IN_PORT", null, 1, false, "MISROUTED", ts(100), false},
143 {5, "FGH", 1, 3, 5, ts(50), "IN_PORT", null, 1, false, "ROUTED", ts(100), false},
144 {6, "JKL", 6, 6, 4, ts(60), "IN_PORT", null, 1, true, "ROUTED", ts(100), false}
145 };
146 executeUpdate(jdbcTemplate, cargoSql, cargoArgs);
147 }
148
149 private static void loadLocationData(JdbcTemplate jdbcTemplate) {
150 String locationSql =
151 "insert into Location (id, unlocode, name) " +
152 "values (?, ?, ?)";
153
154 Object[][] locationArgs = {
155 {1, "SESTO", "Stockholm"},
156 {2, "AUMEL", "Melbourne"},
157 {3, "CNHKG", "Hongkong"},
158 {4, "JPTOK", "Tokyo"},
159 {5, "FIHEL", "Helsinki"},
160 {6, "DEHAM", "Hamburg"},
161 {7, "USCHI", "Chicago"}
162 };
163 executeUpdate(jdbcTemplate, locationSql, locationArgs);
164 }
165
166 private static void loadItineraryData(JdbcTemplate jdbcTemplate) {
167 String legSql =
168 "insert into Leg (id, cargo_id, voyage_id, load_location_id, unload_location_id, load_time, unload_time, leg_index) " +
169 "values (?,?,?,?,?,?,?,?)";
170
171 Object [][] legArgs = {
172
173 {1,5,1,3,2,ts(1),ts(2),0},
174 {2,5,1,2,1,ts(3),ts(4),1},
175 {3,5,1,1,5,ts(4),ts(5),2},
176
177 {4,6,2,6,1,ts(1),ts(2),0},
178 {5,6,2,1,7,ts(3),ts(4),1},
179 {6,6,2,7,4,ts(5),ts(6),2}
180 };
181 executeUpdate(jdbcTemplate, legSql, legArgs);
182 }
183
184 public void contextInitialized(ServletContextEvent event) {
185 WebApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(event.getServletContext());
186 DataSource dataSource = (DataSource) BeanFactoryUtils.beanOfType(context, DataSource.class);
187 PlatformTransactionManager transactionManager = (PlatformTransactionManager) BeanFactoryUtils.beanOfType(context, PlatformTransactionManager.class);
188 TransactionTemplate tt = new TransactionTemplate(transactionManager);
189
190
191
192 SessionFactory sf = (SessionFactory) BeanFactoryUtils.beanOfType(context, SessionFactory.class);
193 HandlingEventFactory handlingEventFactory = new HandlingEventFactory(
194 getBean(context, CargoRepository.class),
195 getBean(context, VoyageRepository.class),
196 getBean(context, LocationRepository.class));
197 loadHibernateData(tt, sf, handlingEventFactory, getBean(context, HandlingEventRepository.class));
198 }
199
200 private <T> T getBean(WebApplicationContext context, Class<T> cls) {
201 return (T) BeanFactoryUtils.beanOfType(context, cls);
202 }
203
204 public static void loadHibernateData(TransactionTemplate tt, final SessionFactory sf, final HandlingEventFactory handlingEventFactory, final HandlingEventRepository handlingEventRepository) {
205 System.out.println("*** Loading Hibernate data ***");
206 tt.execute(new TransactionCallbackWithoutResult() {
207 @Override
208 protected void doInTransactionWithoutResult(TransactionStatus status) {
209 Session session = sf.getCurrentSession();
210
211 for (Location location : SampleLocations.getAll()) {
212 session.save(location);
213 }
214
215 session.save(HONGKONG_TO_NEW_YORK);
216 session.save(NEW_YORK_TO_DALLAS);
217 session.save(DALLAS_TO_HELSINKI);
218 session.save(HELSINKI_TO_HONGKONG);
219 session.save(DALLAS_TO_HELSINKI_ALT);
220
221 RouteSpecification routeSpecification = new RouteSpecification(HONGKONG, HELSINKI, toDate("2009-03-15"));
222 TrackingId trackingId = new TrackingId("ABC123");
223 Cargo abc123 = new Cargo(trackingId, routeSpecification);
224
225 Itinerary itinerary = new Itinerary(asList(
226 new Leg(HONGKONG_TO_NEW_YORK, HONGKONG, NEWYORK, toDate("2009-03-02"), toDate("2009-03-05")),
227 new Leg(NEW_YORK_TO_DALLAS, NEWYORK, DALLAS, toDate("2009-03-06"), toDate("2009-03-08")),
228 new Leg(DALLAS_TO_HELSINKI, DALLAS, HELSINKI, toDate("2009-03-09"), toDate("2009-03-12"))
229 ));
230 abc123.assignToRoute(itinerary);
231
232 session.save(abc123);
233
234 try {
235 HandlingEvent event1 = handlingEventFactory.createHandlingEvent(
236 new Date(), toDate("2009-03-01"), trackingId, null, HONGKONG.unLocode(), HandlingEvent.Type.RECEIVE
237 );
238 session.save(event1);
239
240 HandlingEvent event2 = handlingEventFactory.createHandlingEvent(
241 new Date(), toDate("2009-03-02"), trackingId, HONGKONG_TO_NEW_YORK.voyageNumber(), HONGKONG.unLocode(), HandlingEvent.Type.LOAD
242 );
243 session.save(event2);
244
245 HandlingEvent event3 = handlingEventFactory.createHandlingEvent(
246 new Date(), toDate("2009-03-05"), trackingId, HONGKONG_TO_NEW_YORK.voyageNumber(), NEWYORK.unLocode(), HandlingEvent.Type.UNLOAD
247 );
248 session.save(event3);
249 } catch (CannotCreateHandlingEventException e) {
250 throw new RuntimeException(e);
251 }
252
253 HandlingHistory handlingHistory = handlingEventRepository.lookupHandlingHistoryOfCargo(trackingId);
254 abc123.deriveDeliveryProgress(handlingHistory);
255
256 session.update(abc123);
257
258
259
260 RouteSpecification routeSpecification1 = new RouteSpecification(HANGZOU, STOCKHOLM, toDate("2009-03-18"));
261 TrackingId trackingId1 = new TrackingId("JKL567");
262 Cargo jkl567 = new Cargo(trackingId1, routeSpecification1);
263
264 Itinerary itinerary1 = new Itinerary(asList(
265 new Leg(HONGKONG_TO_NEW_YORK, HANGZOU, NEWYORK, toDate("2009-03-03"), toDate("2009-03-05")),
266 new Leg(NEW_YORK_TO_DALLAS, NEWYORK, DALLAS, toDate("2009-03-06"), toDate("2009-03-08")),
267 new Leg(DALLAS_TO_HELSINKI, DALLAS, STOCKHOLM, toDate("2009-03-09"), toDate("2009-03-11"))
268 ));
269 jkl567.assignToRoute(itinerary1);
270
271 session.save(jkl567);
272
273 try {
274 HandlingEvent event1 = handlingEventFactory.createHandlingEvent(
275 new Date(), toDate("2009-03-01"), trackingId1, null, HANGZOU.unLocode(), HandlingEvent.Type.RECEIVE
276 );
277 session.save(event1);
278
279 HandlingEvent event2 = handlingEventFactory.createHandlingEvent(
280 new Date(), toDate("2009-03-03"), trackingId1, HONGKONG_TO_NEW_YORK.voyageNumber(), HANGZOU.unLocode(), HandlingEvent.Type.LOAD
281 );
282 session.save(event2);
283
284 HandlingEvent event3 = handlingEventFactory.createHandlingEvent(
285 new Date(), toDate("2009-03-05"), trackingId1, HONGKONG_TO_NEW_YORK.voyageNumber(), NEWYORK.unLocode(), HandlingEvent.Type.UNLOAD
286 );
287 session.save(event3);
288
289 HandlingEvent event4 = handlingEventFactory.createHandlingEvent(
290 new Date(), toDate("2009-03-06"), trackingId1, HONGKONG_TO_NEW_YORK.voyageNumber(), NEWYORK.unLocode(), HandlingEvent.Type.LOAD
291 );
292 session.save(event4);
293
294 } catch (CannotCreateHandlingEventException e) {
295 throw new RuntimeException(e);
296 }
297
298 HandlingHistory handlingHistory1 = handlingEventRepository.lookupHandlingHistoryOfCargo(trackingId1);
299 jkl567.deriveDeliveryProgress(handlingHistory1);
300
301 session.update(jkl567);
302 }
303 });
304 }
305
306 public void contextDestroyed(ServletContextEvent event) {}
307
308 public static void loadSampleData(final JdbcTemplate jdbcTemplate, TransactionTemplate transactionTemplate) {
309 transactionTemplate.execute(new TransactionCallbackWithoutResult() {
310 protected void doInTransactionWithoutResult(TransactionStatus status) {
311 loadLocationData(jdbcTemplate);
312 loadCarrierMovementData(jdbcTemplate);
313 loadCargoData(jdbcTemplate);
314 loadItineraryData(jdbcTemplate);
315 loadHandlingEventData(jdbcTemplate);
316 }
317 });
318 }
319
320 private static void executeUpdate(JdbcTemplate jdbcTemplate, String sql, Object[][] args) {
321 for (Object[] arg : args) {
322 jdbcTemplate.update(sql, arg);
323 }
324 }
325
326 private static Timestamp ts(int hours) {
327 return new Timestamp(base.getTime() + 1000L * 60 * 60 * hours);
328 }
329
330 public static Date offset(int hours) {
331 return new Date(ts(hours).getTime());
332 }
333 }