diff --git a/samples/airline/server/pom.xml b/samples/airline/server/pom.xml index f1933e5a..b6c90e37 100644 --- a/samples/airline/server/pom.xml +++ b/samples/airline/server/pom.xml @@ -151,7 +151,6 @@ org.springframework spring-jdbc - runtime org.springframework diff --git a/samples/airline/server/src/main/java/org/springframework/ws/samples/airline/ws/AirlineEndpoint.java b/samples/airline/server/src/main/java/org/springframework/ws/samples/airline/ws/AirlineEndpoint.java new file mode 100644 index 00000000..22e7d5cf --- /dev/null +++ b/samples/airline/server/src/main/java/org/springframework/ws/samples/airline/ws/AirlineEndpoint.java @@ -0,0 +1,160 @@ +/* + * Copyright 2005-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ws.samples.airline.ws; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import javax.xml.bind.JAXBElement; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StringUtils; +import org.springframework.ws.samples.airline.domain.FrequentFlyer; +import org.springframework.ws.samples.airline.domain.Passenger; +import org.springframework.ws.samples.airline.domain.ServiceClass; +import org.springframework.ws.samples.airline.schema.BookFlightRequest; +import org.springframework.ws.samples.airline.schema.GetFlightsResponse; +import org.springframework.ws.samples.airline.schema.Name; +import org.springframework.ws.samples.airline.schema.ObjectFactory; +import org.springframework.ws.samples.airline.schema.Ticket; +import org.springframework.ws.samples.airline.schema.support.SchemaConversionUtils; +import org.springframework.ws.samples.airline.service.AirlineService; +import org.springframework.ws.samples.airline.service.NoSeatAvailableException; +import org.springframework.ws.samples.airline.service.NoSuchFlightException; +import org.springframework.ws.samples.airline.service.NoSuchFrequentFlyerException; +import org.springframework.ws.server.endpoint.annotation.Endpoint; +import org.springframework.ws.server.endpoint.annotation.Namespace; +import org.springframework.ws.server.endpoint.annotation.PayloadRoot; +import org.springframework.ws.server.endpoint.annotation.RequestPayload; +import org.springframework.ws.server.endpoint.annotation.ResponsePayload; +import org.springframework.ws.server.endpoint.annotation.XPathParam; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.joda.time.DateTime; +import org.joda.time.LocalDate; + +import static org.springframework.ws.samples.airline.ws.AirlineWebServiceConstants.*; + +/** + * Endpoint that handles the Airline Web Service messages using a combination of JAXB2 marshalling and XPath + * expressions. + * + * @author Arjen Poutsma + */ +@Endpoint +public class AirlineEndpoint { + + private static final Log logger = LogFactory.getLog(AirlineEndpoint.class); + + private final ObjectFactory objectFactory = new ObjectFactory(); + + private final AirlineService airlineService; + + @Autowired + public AirlineEndpoint(AirlineService airlineService) { + this.airlineService = airlineService; + } + + /** + * This endpoint method uses a combination of XPath expressions and marshalling to handle message with a + * <GetFlightsRequest> payload. + * + * @param from the from airport + * @param to the to airport + * @param departureDateString the string representation of the departure date + * @param serviceClassString the string representation of the service class + * @return the JAXB2 representation of a <GetFlightsResponse> + */ + @PayloadRoot(localPart = GET_FLIGHTS_REQUEST, namespace = MESSAGES_NAMESPACE) + @Namespace(prefix = "m", uri = MESSAGES_NAMESPACE) + @ResponsePayload + public GetFlightsResponse getFlights(@XPathParam("//m:from") String from, + @XPathParam("//m:to") String to, + @XPathParam("//m:departureDate") String departureDateString, + @XPathParam("//m:serviceClass") String serviceClassString) + throws DatatypeConfigurationException { + if (logger.isDebugEnabled()) { + logger.debug("Received GetFlightsRequest '" + from + "' to '" + to + "' on " + departureDateString); + } + LocalDate departureDate = new LocalDate(departureDateString); + ServiceClass serviceClass = null; + if (StringUtils.hasLength(serviceClassString)) { + serviceClass = ServiceClass.valueOf(serviceClassString.toUpperCase()); + } + List flights = + airlineService.getFlights(from, to, departureDate, serviceClass); + + GetFlightsResponse response = objectFactory.createGetFlightsResponse(); + for (org.springframework.ws.samples.airline.domain.Flight domainFlight : flights) { + response.getFlight().add(SchemaConversionUtils.toSchemaType(domainFlight)); + } + return response; + } + + /** + * This endpoint method uses marshalling to handle message with a <BookFlightRequest> payload. + * + * @param request the JAXB2 representation of a <BookFlightRequest> + * @return the JAXB2 representation of a <BookFlightResponse> + */ + @PayloadRoot(localPart = BOOK_FLIGHT_REQUEST, namespace = MESSAGES_NAMESPACE) + @ResponsePayload + public JAXBElement bookFlight(@RequestPayload BookFlightRequest request) + throws NoSeatAvailableException, DatatypeConfigurationException, NoSuchFlightException, + NoSuchFrequentFlyerException { + if (logger.isDebugEnabled()) { + logger.debug("Received BookingFlightRequest '" + request.getFlightNumber() + "' on '" + + request.getDepartureTime() + "' for " + request.getPassengers().getPassengerOrUsername()); + } + Ticket ticket = bookSchemaFlight(request.getFlightNumber(), request.getDepartureTime(), + request.getPassengers().getPassengerOrUsername()); + return objectFactory.createBookFlightResponse(ticket); + } + + /** + * Converts between the domain and schema types. + */ + private Ticket bookSchemaFlight(String flightNumber, + XMLGregorianCalendar xmlDepartureTime, + List passengerOrUsernameList) + throws NoSeatAvailableException, NoSuchFlightException, NoSuchFrequentFlyerException, + DatatypeConfigurationException { + DateTime departureTime = SchemaConversionUtils.toDateTime(xmlDepartureTime); + List passengers = new ArrayList(passengerOrUsernameList.size()); + for (Iterator iterator = passengerOrUsernameList.iterator(); iterator.hasNext();) { + Object passengerOrUsername = iterator.next(); + if (passengerOrUsername instanceof Name) { + Name passengerName = (Name) passengerOrUsername; + Passenger passenger = new Passenger(passengerName.getFirst(), passengerName.getLast()); + passengers.add(passenger); + } + else if (passengerOrUsername instanceof String) { + String frequentFlyerUsername = (String) passengerOrUsername; + FrequentFlyer frequentFlyer = new FrequentFlyer(frequentFlyerUsername); + passengers.add(frequentFlyer); + } + } + org.springframework.ws.samples.airline.domain.Ticket domainTicket = + airlineService.bookFlight(flightNumber, departureTime, passengers); + return SchemaConversionUtils.toSchemaType(domainTicket); + } + + +} diff --git a/samples/airline/server/src/main/resources/org/springframework/ws/samples/airline/ws/applicationContext-ws.xml b/samples/airline/server/src/main/resources/org/springframework/ws/samples/airline/ws/applicationContext-ws.xml index c1302ad9..6734945c 100644 --- a/samples/airline/server/src/main/resources/org/springframework/ws/samples/airline/ws/applicationContext-ws.xml +++ b/samples/airline/server/src/main/resources/org/springframework/ws/samples/airline/ws/applicationContext-ws.xml @@ -5,7 +5,9 @@ xmlns:sws="http://www.springframework.org/schema/web-services" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd - http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-1.5.xsd"> + http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd"> + + @@ -21,17 +23,21 @@ + + + + diff --git a/samples/airline/server/src/test/java/org/springframework/ws/samples/airline/dao/jpa/JpaFlightDaoTest.java b/samples/airline/server/src/test/java/org/springframework/ws/samples/airline/dao/jpa/JpaFlightDaoTest.java index 445d2143..3637cdf1 100644 --- a/samples/airline/server/src/test/java/org/springframework/ws/samples/airline/dao/jpa/JpaFlightDaoTest.java +++ b/samples/airline/server/src/test/java/org/springframework/ws/samples/airline/dao/jpa/JpaFlightDaoTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2007 the original author or authors. + * Copyright 2005-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,18 +17,31 @@ package org.springframework.ws.samples.airline.dao.jpa; import java.util.List; +import javax.sql.DataSource; -import org.joda.time.DateTime; -import org.joda.time.Interval; -import org.springframework.test.jpa.AbstractJpaTests; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.transaction.BeforeTransaction; +import org.springframework.transaction.annotation.Transactional; import org.springframework.ws.samples.airline.dao.FlightDao; import org.springframework.ws.samples.airline.domain.Airport; import org.springframework.ws.samples.airline.domain.Flight; import org.springframework.ws.samples.airline.domain.ServiceClass; -public class JpaFlightDaoTest extends AbstractJpaTests { +import org.joda.time.DateTime; +import org.joda.time.Interval; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; - private FlightDao flightDao; +import static org.junit.Assert.*; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("applicationContext-jpa.xml") +@Transactional +public class JpaFlightDaoTest { private DateTime departureTime; @@ -40,17 +53,18 @@ public class JpaFlightDaoTest extends AbstractJpaTests { private Airport toAirport; - public void setFlightDao(FlightDao flightDao) { - this.flightDao = flightDao; + @Autowired + private FlightDao flightDao; + + private JdbcTemplate jdbcTemplate; + + @Autowired + public void setDataSource(DataSource dataSource) { + jdbcTemplate = new JdbcTemplate(dataSource); } - @Override - protected String[] getConfigPaths() { - return new String[]{"applicationContext-jpa.xml"}; - } - - @Override - protected void onSetUpBeforeTransaction() throws Exception { + @BeforeTransaction + public void createTestData() { departureTime = new DateTime(2006, 1, 31, 10, 5, 0, 0); arrivalTime = new DateTime(2006, 1, 31, 12, 25, 0, 0); interval = departureTime.toLocalDate().toInterval(); @@ -58,13 +72,14 @@ public class JpaFlightDaoTest extends AbstractJpaTests { toAirport = new Airport("OSL", "Gardermoen", "Oslo"); } - @Override - protected void onSetUpInTransaction() throws Exception { + @Before + public void insertTestData() { jdbcTemplate.update("INSERT INTO AIRPORT(CODE, NAME, CITY) VALUES('RTM', 'Rotterdam Airport', 'Rotterdam')"); jdbcTemplate.update("INSERT INTO AIRPORT(CODE, NAME, CITY) VALUES('OSL', 'Gardermoen', 'Oslo')"); } - public void testGetFlightsInPeriod() throws Exception { + @Test + public void getFlightsInPeriod() throws Exception { jdbcTemplate .update("INSERT INTO FLIGHT(NUMBER, DEPARTURE_TIME, FROM_AIRPORT_CODE, ARRIVAL_TIME, TO_AIRPORT_CODE, SERVICE_CLASS, SEATS_AVAILABLE, MILES) " + "VALUES ('KL020','2006-01-31 10:05:00', 'RTM', '2006-01-31 12:25:00', 'OSL', 'BUSINESS', 90, 10)"); @@ -73,7 +88,8 @@ public class JpaFlightDaoTest extends AbstractJpaTests { assertEquals("Invalid amount of flights", 1, flights.size()); } - public void testGetFlightsOutOfPeriod() throws Exception { + @Test + public void getFlightsOutOfPeriod() throws Exception { jdbcTemplate .update("INSERT INTO FLIGHT(NUMBER, DEPARTURE_TIME, FROM_AIRPORT_CODE, ARRIVAL_TIME, TO_AIRPORT_CODE, SERVICE_CLASS, SEATS_AVAILABLE, MILES) " + "VALUES ('KL020','2006-01-31 10:05:00', 'RTM', '2006-01-31 12:25:00', 'OSL', 'BUSINESS', 90, 10)"); @@ -83,7 +99,8 @@ public class JpaFlightDaoTest extends AbstractJpaTests { assertEquals("Invalid amount of flights", 0, flights.size()); } - public void testGetFlightByNumberDepartureTime() throws Exception { + @Test + public void getFlightByNumberDepartureTime() throws Exception { jdbcTemplate .update("INSERT INTO FLIGHT(NUMBER, DEPARTURE_TIME, FROM_AIRPORT_CODE, ARRIVAL_TIME, TO_AIRPORT_CODE, SERVICE_CLASS, SEATS_AVAILABLE, MILES) " + "VALUES ('KL020','2006-01-31 10:05:00', 'RTM', '2006-01-31 12:25:00', 'OSL', 'BUSINESS', 90, 10)"); @@ -98,20 +115,8 @@ public class JpaFlightDaoTest extends AbstractJpaTests { assertEquals("Invalid flight service class", ServiceClass.BUSINESS, flight.getServiceClass()); } - public void testUpdate() throws Exception { - jdbcTemplate - .update("INSERT INTO FLIGHT(NUMBER, DEPARTURE_TIME, FROM_AIRPORT_CODE, ARRIVAL_TIME, TO_AIRPORT_CODE, SERVICE_CLASS, SEATS_AVAILABLE, MILES) " + - "VALUES ('KL020','2006-01-31 10:05:00', 'RTM', '2006-01-31 12:25:00', 'OSL', 'BUSINESS', 90, 10)"); - Flight flight = flightDao.getFlight("KL020", departureTime); - flight.setSeatsAvailable(0); - flightDao.update(flight); - sharedEntityManager.flush(); - int count = jdbcTemplate - .queryForInt("SELECT SEATS_AVAILABLE FROM FLIGHT WHERE ID = ?", new Object[]{flight.getId()}); - assertEquals("Flight not updated", 0, count); - } - - public void testNoSuchFlight() { + @Test + public void noSuchFlight() { Flight flight = flightDao.getFlight("INVALID", departureTime); assertNull("Flight returned", flight); } diff --git a/samples/airline/server/src/test/java/org/springframework/ws/samples/airline/dao/jpa/JpaFrequentFlyerDaoTest.java b/samples/airline/server/src/test/java/org/springframework/ws/samples/airline/dao/jpa/JpaFrequentFlyerDaoTest.java index d1c12c18..b6e20c57 100644 --- a/samples/airline/server/src/test/java/org/springframework/ws/samples/airline/dao/jpa/JpaFrequentFlyerDaoTest.java +++ b/samples/airline/server/src/test/java/org/springframework/ws/samples/airline/dao/jpa/JpaFrequentFlyerDaoTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2007 the original author or authors. + * Copyright 2005-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,25 +16,38 @@ package org.springframework.ws.samples.airline.dao.jpa; -import org.springframework.test.jpa.AbstractJpaTests; -import org.springframework.ws.samples.airline.dao.FrequentFlyerDao; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; import org.springframework.ws.samples.airline.domain.FrequentFlyer; -public class JpaFrequentFlyerDaoTest extends AbstractJpaTests { +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; - private FrequentFlyerDao frequentFlyerDao; +import static org.junit.Assert.*; - public void setFrequentFlyerDao(FrequentFlyerDao frequentFlyerDao) { - this.frequentFlyerDao = frequentFlyerDao; +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("applicationContext-jpa.xml") +@Transactional +public class JpaFrequentFlyerDaoTest { + + @Autowired + private JpaFrequentFlyerDao frequentFlyerDao; + + private JdbcTemplate jdbcTemplate; + + @Autowired + public void setDataSource(DataSource dataSource) { + jdbcTemplate = new JdbcTemplate(dataSource); } - @Override - protected String[] getConfigPaths() { - return new String[]{"applicationContext-jpa.xml"}; - } - - @Override - protected void onSetUpInTransaction() throws Exception { + @Before + public void insertTestData() { jdbcTemplate .update("INSERT INTO PASSENGER(ID, FIRST_NAME, LAST_NAME) " + "VALUES (42, 'Arjen', 'Poutsma')"); jdbcTemplate @@ -42,7 +55,8 @@ public class JpaFrequentFlyerDaoTest extends AbstractJpaTests { "VALUES (42, 'arjen', 'changeme', 0)"); } - public void testGetByUsername() throws Exception { + @Test + public void getByUsername() throws Exception { FrequentFlyer flyer = frequentFlyerDao.get("arjen"); assertNotNull("No frequent flyer returned", flyer); assertEquals("Invalid username", "arjen", flyer.getUsername()); @@ -51,7 +65,8 @@ public class JpaFrequentFlyerDaoTest extends AbstractJpaTests { assertEquals("Invalid last name", "Poutsma", flyer.getLastName()); } - public void testNoSuchUsername() { + @Test + public void noSuchUsername() { FrequentFlyer flyer = frequentFlyerDao.get("invalid"); assertNull("FrequentFlyer returned", flyer); } diff --git a/samples/airline/server/src/test/java/org/springframework/ws/samples/airline/dao/jpa/JpaTicketDaoTest.java b/samples/airline/server/src/test/java/org/springframework/ws/samples/airline/dao/jpa/JpaTicketDaoTest.java index 292070da..2e4a5f7c 100644 --- a/samples/airline/server/src/test/java/org/springframework/ws/samples/airline/dao/jpa/JpaTicketDaoTest.java +++ b/samples/airline/server/src/test/java/org/springframework/ws/samples/airline/dao/jpa/JpaTicketDaoTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2007 the original author or authors. + * Copyright 2005-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,28 +16,45 @@ package org.springframework.ws.samples.airline.dao.jpa; -import org.joda.time.LocalDate; -import org.springframework.test.jpa.AbstractJpaTests; -import org.springframework.ws.samples.airline.dao.TicketDao; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; import org.springframework.ws.samples.airline.domain.Flight; import org.springframework.ws.samples.airline.domain.Passenger; import org.springframework.ws.samples.airline.domain.Ticket; -public class JpaTicketDaoTest extends AbstractJpaTests { +import org.joda.time.LocalDate; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; - private TicketDao ticketDao; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; - public void setTicketDao(TicketDao ticketDao) { - this.ticketDao = ticketDao; +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("applicationContext-jpa.xml") +@Transactional +public class JpaTicketDaoTest { + + @Autowired + private JpaTicketDao ticketDao; + + @Autowired + private JpaFlightDao flightDao; + + private JdbcTemplate jdbcTemplate; + + @Autowired + public void setDataSource(DataSource dataSource) { + jdbcTemplate = new JdbcTemplate(dataSource); } - @Override - protected String[] getConfigPaths() { - return new String[]{"applicationContext-jpa.xml"}; - } - - @Override - protected void onSetUpInTransaction() throws Exception { + @Before + public void insertTestData() { jdbcTemplate.update("INSERT INTO AIRPORT(CODE, NAME, CITY) VALUES('RTM', 'Rotterdam Airport', 'Rotterdam')"); jdbcTemplate.update("INSERT INTO AIRPORT(CODE, NAME, CITY) VALUES('OSL', 'Gardermoen', 'Oslo')"); jdbcTemplate @@ -45,9 +62,10 @@ public class JpaTicketDaoTest extends AbstractJpaTests { "VALUES (42, 'KL020','2006-01-31 10:05:00', 'RTM', '2006-01-31 12:25:00', 'OSL', 'BUSINESS', 90, 10)"); } - public void testSave() throws Exception { + @Test + public void save() throws Exception { Passenger passenger = new Passenger("Arjen", "Poutsma"); - Flight flight = sharedEntityManager.find(Flight.class, 42L); + Flight flight = flightDao.getFlight(42L); Ticket ticket = new Ticket(); ticket.addPassenger(passenger); ticket.setFlight(flight); @@ -55,7 +73,6 @@ public class JpaTicketDaoTest extends AbstractJpaTests { int startTicketCount = jdbcTemplate.queryForInt("SELECT COUNT(0) FROM TICKET"); int startPassengerCount = jdbcTemplate.queryForInt("SELECT COUNT(0) FROM PASSENGER"); ticketDao.save(ticket); - sharedEntityManager.flush(); assertNotNull("No Id generated", ticket.getId()); int endTicketCount = jdbcTemplate.queryForInt("SELECT COUNT(0) FROM TICKET"); int endPassengerCount = jdbcTemplate.queryForInt("SELECT COUNT(0) FROM PASSENGER"); diff --git a/samples/airline/server/src/test/java/org/springframework/ws/samples/airline/ws/AirlineEndpointTest.java b/samples/airline/server/src/test/java/org/springframework/ws/samples/airline/ws/AirlineEndpointTest.java new file mode 100644 index 00000000..6a30f551 --- /dev/null +++ b/samples/airline/server/src/test/java/org/springframework/ws/samples/airline/ws/AirlineEndpointTest.java @@ -0,0 +1,192 @@ +/* + * Copyright 2005-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ws.samples.airline.ws; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import javax.xml.bind.JAXBElement; +import javax.xml.datatype.DatatypeConstants; +import javax.xml.datatype.DatatypeFactory; + +import org.springframework.ws.samples.airline.domain.Airport; +import org.springframework.ws.samples.airline.domain.FrequentFlyer; +import org.springframework.ws.samples.airline.domain.Passenger; +import org.springframework.ws.samples.airline.schema.BookFlightRequest; +import org.springframework.ws.samples.airline.schema.Flight; +import org.springframework.ws.samples.airline.schema.GetFlightsResponse; +import org.springframework.ws.samples.airline.schema.Name; +import org.springframework.ws.samples.airline.schema.ObjectFactory; +import org.springframework.ws.samples.airline.schema.ServiceClass; +import org.springframework.ws.samples.airline.schema.Ticket; +import org.springframework.ws.samples.airline.service.AirlineService; + +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.joda.time.LocalDate; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.easymock.EasyMock.*; + +public class AirlineEndpointTest { + + private AirlineEndpoint endpoint; + + private AirlineService airlineServiceMock; + + private DatatypeFactory datatypeFactory; + + private ObjectFactory objectFactory; + + @Before + public void setUp() throws Exception { + airlineServiceMock = createMock(AirlineService.class); + endpoint = new AirlineEndpoint(airlineServiceMock); + datatypeFactory = DatatypeFactory.newInstance(); + objectFactory = new ObjectFactory(); + } + + @Test + public void testGetFlights() throws Exception { + org.springframework.ws.samples.airline.domain.Flight domainFlight = createDomainFlight(); + + expect(airlineServiceMock.getFlights("ABC", "DEF", new LocalDate(2007, 6, 13), + org.springframework.ws.samples.airline.domain.ServiceClass.FIRST)) + .andReturn(Collections.singletonList(domainFlight)); + + replay(airlineServiceMock); + + GetFlightsResponse response = endpoint.getFlights("ABC", "DEF", "2007-06-13", "first"); + Assert.assertEquals("Invalid amount of flights received", 1, response.getFlight().size()); + Flight schemaFlight = response.getFlight().get(0); + verifySchemaFlight(schemaFlight); + + verify(airlineServiceMock); + } + + private void verifySchemaFlight(Flight schemaFlight) { + Assert.assertEquals("Invalid number", "ABC1234", schemaFlight.getNumber()); + Assert.assertEquals("Invalid departure time", + datatypeFactory.newXMLGregorianCalendar(2007, 6, 13, 12, 0, 0, 0, 0), schemaFlight.getDepartureTime()); + Assert.assertEquals("Invalid from code", "ABC", schemaFlight.getFrom().getCode()); + Assert.assertEquals("Invalid from name", "ABC Airport", schemaFlight.getFrom().getName()); + Assert.assertEquals("Invalid from city", "ABC City", schemaFlight.getFrom().getCity()); + Assert.assertEquals("Invalid arrival time", + datatypeFactory.newXMLGregorianCalendar(2007, 6, 13, 14, 0, 0, 0, 0), schemaFlight.getArrivalTime()); + Assert.assertEquals("Invalid to code", "DEF", schemaFlight.getTo().getCode()); + Assert.assertEquals("Invalid to name", "DEF Airport", schemaFlight.getTo().getName()); + Assert.assertEquals("Invalid to city", "DEF City", schemaFlight.getTo().getCity()); + Assert.assertEquals("Invalid service class", ServiceClass.FIRST, schemaFlight.getServiceClass()); + } + + private org.springframework.ws.samples.airline.domain.Flight createDomainFlight() { + org.springframework.ws.samples.airline.domain.Flight domainFlight = + new org.springframework.ws.samples.airline.domain.Flight(); + domainFlight.setNumber("ABC1234"); + domainFlight.setDepartureTime(new DateTime(2007, 6, 13, 12, 0, 0, 0, DateTimeZone.UTC)); + domainFlight.setFrom(new Airport("ABC", "ABC Airport", "ABC City")); + domainFlight.setArrivalTime(new DateTime(2007, 6, 13, 14, 0, 0, 0, DateTimeZone.UTC)); + domainFlight.setTo(new Airport("DEF", "DEF Airport", "DEF City")); + domainFlight.setServiceClass(org.springframework.ws.samples.airline.domain.ServiceClass.FIRST); + return domainFlight; + } + + @Test + public void testBookFlightPassenger() throws Exception { + BookFlightRequest request = objectFactory.createBookFlightRequest(); + request.setDepartureTime(datatypeFactory.newXMLGregorianCalendar(2007, 6, 13, 12, 0, 0, 0, 0)); + request.setFlightNumber("ABC1234"); + Name passengerName = new Name(); + passengerName.setFirst("John"); + passengerName.setLast("Doe"); + BookFlightRequest.Passengers passengers = new BookFlightRequest.Passengers(); + passengers.getPassengerOrUsername().add(passengerName); + request.setPassengers(passengers); + + Passenger domainPassenger = new Passenger("John", "Doe"); + + org.springframework.ws.samples.airline.domain.Ticket domainTicket = + new org.springframework.ws.samples.airline.domain.Ticket(42L); + domainTicket.setFlight(createDomainFlight()); + domainTicket.setIssueDate(new LocalDate(2007, 6, 13)); + domainTicket.setPassengers(Collections.singleton(domainPassenger)); + + expect(airlineServiceMock.bookFlight("ABC1234", new DateTime(2007, 6, 13, 12, 0, 0, 0, DateTimeZone.UTC), + Collections.singletonList(domainPassenger))).andReturn(domainTicket); + + replay(airlineServiceMock); + + JAXBElement response = endpoint.bookFlight(request); + Ticket schemaTicket = response.getValue(); + Assert.assertEquals("Invalid id", 42L, schemaTicket.getId()); + Assert.assertEquals("Invalid issue date", + datatypeFactory.newXMLGregorianCalendarDate(2007, 6, 13, DatatypeConstants.FIELD_UNDEFINED), + schemaTicket.getIssueDate()); + Assert.assertEquals("Invalid amount of passengers", 1, schemaTicket.getPassengers().getPassenger().size()); + Name schemaPassenger = schemaTicket.getPassengers().getPassenger().get(0); + Assert.assertEquals("Invalid passenger first name", "John", schemaPassenger.getFirst()); + Assert.assertEquals("Invalid passenger first name", "Doe", schemaPassenger.getLast()); + verifySchemaFlight(schemaTicket.getFlight()); + + verify(airlineServiceMock); + } + + @Test + public void testBookFlightFrequentFlyer() throws Exception { + BookFlightRequest request = objectFactory.createBookFlightRequest(); + request.setDepartureTime(datatypeFactory.newXMLGregorianCalendar(2007, 6, 13, 12, 0, 0, 0, 0)); + request.setFlightNumber("ABC1234"); + BookFlightRequest.Passengers passengers = new BookFlightRequest.Passengers(); + passengers.getPassengerOrUsername().add("john"); + request.setPassengers(passengers); + + FrequentFlyer domainFrequentFlyer = new FrequentFlyer("John", "Doe", "john", "changeme"); + Set domainPassengers = new HashSet(); + domainPassengers.add(domainFrequentFlyer); + + org.springframework.ws.samples.airline.domain.Ticket domainTicket = + new org.springframework.ws.samples.airline.domain.Ticket(42L); + domainTicket.setFlight(createDomainFlight()); + domainTicket.setIssueDate(new LocalDate(2007, 6, 13)); + domainTicket.setPassengers(domainPassengers); + + List domainPassengerList = new ArrayList(domainPassengers); + expect(airlineServiceMock.bookFlight("ABC1234", new DateTime(2007, 6, 13, 12, 0, 0, 0, DateTimeZone.UTC), + domainPassengerList)).andReturn(domainTicket); + + replay(airlineServiceMock); + + JAXBElement response = endpoint.bookFlight(request); + Ticket schemaTicket = response.getValue(); + Assert.assertEquals("Invalid id", 42L, schemaTicket.getId()); + Assert.assertEquals("Invalid issue date", + datatypeFactory.newXMLGregorianCalendarDate(2007, 6, 13, DatatypeConstants.FIELD_UNDEFINED), + schemaTicket.getIssueDate()); + Assert.assertEquals("Invalid amount of passengers", 1, schemaTicket.getPassengers().getPassenger().size()); + Name schemaPassenger = schemaTicket.getPassengers().getPassenger().get(0); + Assert.assertEquals("Invalid passenger first name", "John", schemaPassenger.getFirst()); + Assert.assertEquals("Invalid passenger first name", "Doe", schemaPassenger.getLast()); + verifySchemaFlight(schemaTicket.getFlight()); + + verify(airlineServiceMock); + } + +} \ No newline at end of file