Finished airline sample.
This commit is contained in:
@@ -267,43 +267,6 @@
|
||||
<artifactId>spring-mock</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- XML handling dependencies -->
|
||||
<dependency>
|
||||
<groupId>jdom</groupId>
|
||||
<artifactId>jdom</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jaxen</groupId>
|
||||
<artifactId>jaxen</artifactId>
|
||||
<scope>runtime</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>dom4j</groupId>
|
||||
<artifactId>dom4j</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>jdom</groupId>
|
||||
<artifactId>jdom</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>xerces</groupId>
|
||||
<artifactId>xmlParserAPIs</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>xerces</groupId>
|
||||
<artifactId>xercesImpl</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>xom</groupId>
|
||||
<artifactId>xom</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>xalan</groupId>
|
||||
<artifactId>xalan</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- JEE dependencies -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
@@ -335,7 +298,7 @@
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate</artifactId>
|
||||
<version>3.2.1.ga</version>
|
||||
<version>3.2.4.sp1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-dbcp</groupId>
|
||||
@@ -371,6 +334,11 @@
|
||||
<version>1.0</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>1.5.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security</artifactId>
|
||||
|
||||
@@ -21,6 +21,7 @@ import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
@@ -35,7 +36,7 @@ public class Flight implements Serializable {
|
||||
|
||||
@Id
|
||||
@Column(name = "ID")
|
||||
@GeneratedValue
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "NUMBER")
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.io.Serializable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Inheritance;
|
||||
import javax.persistence.InheritanceType;
|
||||
@@ -30,7 +31,7 @@ import javax.persistence.Table;
|
||||
public class Passenger implements Serializable {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "ID")
|
||||
private Long id;
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
@@ -38,7 +39,7 @@ import org.joda.time.LocalDate;
|
||||
public class Ticket implements Serializable {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "ISSUE_DATE")
|
||||
|
||||
@@ -17,8 +17,10 @@ package org.springframework.ws.samples.airline.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.acegisecurity.annotation.Secured;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.ws.samples.airline.domain.Flight;
|
||||
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
|
||||
import org.springframework.ws.samples.airline.domain.Passenger;
|
||||
@@ -30,6 +32,7 @@ import org.springframework.ws.samples.airline.domain.Ticket;
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public interface AirlineService {
|
||||
|
||||
/**
|
||||
@@ -69,6 +72,7 @@ public interface AirlineService {
|
||||
* @see org.springframework.ws.samples.airline.domain.Passenger
|
||||
* @see org.springframework.ws.samples.airline.domain.FrequentFlyer
|
||||
*/
|
||||
@Transactional(rollbackFor = {NoSuchFlightException.class, NoSeatAvailableException.class})
|
||||
Ticket bookFlight(String flightNumber, DateTime departureTime, List<Passenger> passengers)
|
||||
throws NoSuchFlightException, NoSeatAvailableException;
|
||||
|
||||
@@ -77,5 +81,6 @@ public interface AirlineService {
|
||||
*
|
||||
* @return the amount of frequent flyer miles
|
||||
*/
|
||||
@Secured({"ROLE_FREQUENT_FLYER"})
|
||||
int getFrequentFlyerMileage();
|
||||
}
|
||||
|
||||
@@ -17,12 +17,15 @@
|
||||
package org.springframework.ws.samples.airline.service;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.ws.soap.server.endpoint.annotation.FaultCode;
|
||||
import org.springframework.ws.soap.server.endpoint.annotation.SoapFault;
|
||||
|
||||
/**
|
||||
* Exception thrown when a specified flight cannot be found.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
@SoapFault(faultCode = FaultCode.CLIENT)
|
||||
public class NoSuchFlightException extends Exception {
|
||||
|
||||
private String flightNumber;
|
||||
|
||||
@@ -17,12 +17,10 @@ package org.springframework.ws.samples.airline.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.acegisecurity.annotation.Secured;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.samples.airline.dao.FlightDao;
|
||||
import org.springframework.ws.samples.airline.dao.TicketDao;
|
||||
@@ -61,7 +59,6 @@ public class AirlineServiceImpl implements AirlineService {
|
||||
this.frequentFlyerSecurityService = frequentFlyerSecurityService;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = {NoSuchFlightException.class, NoSeatAvailableException.class})
|
||||
public Ticket bookFlight(String flightNumber, DateTime departureTime, List<Passenger> passengers)
|
||||
throws NoSuchFlightException, NoSeatAvailableException {
|
||||
Assert.notEmpty(passengers, "No passengers given");
|
||||
@@ -96,7 +93,6 @@ public class AirlineServiceImpl implements AirlineService {
|
||||
return ticketDao.save(ticket);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Flight getFlight(Long id) throws NoSuchFlightException {
|
||||
Flight flight = flightDao.getFlight(id);
|
||||
if (flight != null) {
|
||||
@@ -107,7 +103,6 @@ public class AirlineServiceImpl implements AirlineService {
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<Flight> getFlights(String fromAirportCode,
|
||||
String toAirportCode,
|
||||
LocalDate departureDate,
|
||||
@@ -127,9 +122,10 @@ public class AirlineServiceImpl implements AirlineService {
|
||||
return flights;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
@Secured({"ROLE_FREQUENT_FLYER"})
|
||||
public int getFrequentFlyerMileage() {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Using " + frequentFlyerSecurityService + " for security");
|
||||
}
|
||||
FrequentFlyer frequentFlyer = frequentFlyerSecurityService.getCurrentlyAuthenticatedFrequentFlyer();
|
||||
return frequentFlyer != null ? frequentFlyer.getMiles() : 0;
|
||||
}
|
||||
|
||||
@@ -19,5 +19,13 @@ package org.springframework.ws.samples.airline.ws;
|
||||
/** @author Arjen Poutsma */
|
||||
public interface AirlineWebServiceConstants {
|
||||
|
||||
String BOOK_FLIGHT_REQUEST = "BookFlightRequest";
|
||||
|
||||
String GET_FLIGHTS_REQUEST = "GetFlightsRequest";
|
||||
|
||||
String GET_FREQUENT_FLYER_MILEAGE_RESPONSE = "GetFrequentFlyerMileageResponse";
|
||||
|
||||
String NAMESPACE = "http://www.springframework.org/spring-ws/samples/airline/schemas";
|
||||
|
||||
String GET_FREQUENT_FLYER_MILEAGE_REQUEST = "GetFrequentFlyerMileageRequest";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2006 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 org.springframework.ws.samples.airline.service.AirlineService;
|
||||
import org.springframework.ws.server.endpoint.AbstractDomPayloadEndpoint;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Endpoint that returns the amount of frequent flyer miles for the currently logged in user. Secured via a WS-Security
|
||||
* UsernameToken
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class GetFrequentFlyerMileageEndpoint extends AbstractDomPayloadEndpoint implements AirlineWebServiceConstants {
|
||||
|
||||
private final AirlineService airlineService;
|
||||
|
||||
public GetFrequentFlyerMileageEndpoint(AirlineService airlineService) {
|
||||
this.airlineService = airlineService;
|
||||
}
|
||||
|
||||
protected Element invokeInternal(Element ignored, Document responseDocument) throws Exception {
|
||||
int mileage = airlineService.getFrequentFlyerMileage();
|
||||
Element response = responseDocument.createElementNS(NAMESPACE, GET_FREQUENT_FLYER_MILEAGE_RESPONSE);
|
||||
response.setTextContent(Integer.toString(mileage));
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ public class MarshallingAirlineEndpoint implements AirlineWebServiceConstants {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(MarshallingAirlineEndpoint.class);
|
||||
|
||||
private AirlineService airlineService;
|
||||
private final AirlineService airlineService;
|
||||
|
||||
private ObjectFactory objectFactory = new ObjectFactory();
|
||||
|
||||
@@ -72,7 +72,7 @@ public class MarshallingAirlineEndpoint implements AirlineWebServiceConstants {
|
||||
*
|
||||
* @param request the JAXB2 representation of a <code><GetFlightsRequest></code>
|
||||
*/
|
||||
@PayloadRoot(localPart = "GetFlightsRequest", namespace = NAMESPACE)
|
||||
@PayloadRoot(localPart = GET_FLIGHTS_REQUEST, namespace = NAMESPACE)
|
||||
public GetFlightsResponse getFlights(GetFlightsRequest request) throws DatatypeConfigurationException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Received GetFlightsRequest '" + request.getFrom() + "' to '" + request.getTo() + "' on " +
|
||||
@@ -106,7 +106,7 @@ public class MarshallingAirlineEndpoint implements AirlineWebServiceConstants {
|
||||
* @param request the JAXB2 representation of a <code><BookFlightRequest></code>
|
||||
* @return the JAXB2 representation of a <code><BookFlightResponse></code>
|
||||
*/
|
||||
@PayloadRoot(localPart = "BookFlightRequest", namespace = NAMESPACE)
|
||||
@PayloadRoot(localPart = BOOK_FLIGHT_REQUEST, namespace = NAMESPACE)
|
||||
public JAXBElement<Ticket> bookFlight(BookFlightRequest request)
|
||||
throws NoSeatAvailableException, DatatypeConfigurationException, NoSuchFlightException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
@@ -143,18 +143,4 @@ public class MarshallingAirlineEndpoint implements AirlineWebServiceConstants {
|
||||
return SchemaConversionUtils.toSchemaType(domainTicket);
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint method uses marshalling to handle message with a <code><GetFrequentFlyerMileageRequest></code>
|
||||
* payload.
|
||||
*
|
||||
* @param ignored is ignored
|
||||
* @return the JAXB2 representation of a <code><GetFrequentFlyerMileageResponse></code>
|
||||
*/
|
||||
@PayloadRoot(localPart = "GetFrequentFlyerMileageRequest", namespace = NAMESPACE)
|
||||
public JAXBElement<Integer> getFrequentFlyerMileage(JAXBElement<String> ignored) {
|
||||
logger.debug("Received GetFrequentFlyerMileageRequest request");
|
||||
int result = airlineService.getFrequentFlyerMileage();
|
||||
return objectFactory.createGetFrequentFlyerMileageResponse(result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -63,11 +63,11 @@ public class XPathAirlineEndpoint implements AirlineWebServiceConstants {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(XPathAirlineEndpoint.class);
|
||||
|
||||
private AirlineService airlineService;
|
||||
private final AirlineService airlineService;
|
||||
|
||||
private ObjectFactory objectFactory = new ObjectFactory();
|
||||
|
||||
private Marshaller marshaller;
|
||||
private final Marshaller marshaller;
|
||||
|
||||
public XPathAirlineEndpoint(AirlineService airlineService, Marshaller marshaller) {
|
||||
Assert.notNull(airlineService, "airlineService must not be null");
|
||||
@@ -84,7 +84,7 @@ public class XPathAirlineEndpoint implements AirlineWebServiceConstants {
|
||||
* @param departureDateString the string representation of the departure date
|
||||
* @param serviceClassString the string representation of the service class
|
||||
*/
|
||||
@PayloadRoot(localPart = "GetFlightsRequest", namespace = NAMESPACE)
|
||||
@PayloadRoot(localPart = GET_FLIGHTS_REQUEST, namespace = NAMESPACE)
|
||||
public Source getFlights(@XPathParam("//tns:from")String from,
|
||||
@XPathParam("//tns:to")String to,
|
||||
@XPathParam("//tns:departureDate")String departureDateString,
|
||||
@@ -115,7 +115,7 @@ public class XPathAirlineEndpoint implements AirlineWebServiceConstants {
|
||||
* @param passengerNodes the passenger nodes
|
||||
* @param frequentFlyerNodes the frequent flyer nodes
|
||||
*/
|
||||
@PayloadRoot(localPart = "BookFlightRequest", namespace = NAMESPACE)
|
||||
@PayloadRoot(localPart = BOOK_FLIGHT_REQUEST, namespace = NAMESPACE)
|
||||
public Source bookFlight(@XPathParam("//tns:flightNumber")String flightNumber,
|
||||
@XPathParam("//tns:departureTime")String departureTimeString,
|
||||
@XPathParam("//tns:passengers/tns:passenger")NodeList passengerNodes,
|
||||
@@ -161,17 +161,5 @@ public class XPathAirlineEndpoint implements AirlineWebServiceConstants {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint method uses XPath to handle message with a <code><GetFrequentFlyerMileageRequest></code>
|
||||
* payload.
|
||||
*/
|
||||
@PayloadRoot(localPart = "GetFrequentFlyerMileageRequest", namespace = NAMESPACE)
|
||||
public Source getFrequentFlyerMileage() {
|
||||
logger.debug("Received GetFrequentFlyerMileageRequest request");
|
||||
int result = airlineService.getFrequentFlyerMileage();
|
||||
JAXBElement<Integer> response = objectFactory.createGetFrequentFlyerMileageResponse(result);
|
||||
return new MarshallingSource(marshaller, response);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
</description>
|
||||
</bean>
|
||||
|
||||
|
||||
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
<property name="jpaVendorAdapter">
|
||||
|
||||
@@ -1,42 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
|
||||
|
||||
<description>
|
||||
This application context contains the WS-Security and Acegi beans.
|
||||
</description>
|
||||
|
||||
<aop:config>
|
||||
<aop:pointcut id="getFrequentFlyerMileage"
|
||||
expression="execution(* org.springframework.ws.samples.airline.service.AirlineService+.*(..))"/>
|
||||
<aop:advisor advice-ref="methodSecurityInterceptor" pointcut-ref="getFrequentFlyerMileage"/>
|
||||
</aop:config>
|
||||
|
||||
<bean id="securityService"
|
||||
class="org.springframework.ws.samples.airline.security.AcegiFrequentFlyerSecurityService">
|
||||
<description>
|
||||
A transactional security service used to obtain Frequent Flyer information.
|
||||
A security service used to obtain Frequent Flyer information.
|
||||
</description>
|
||||
<property name="frequentFlyerDao" ref="frequentFlyerDao"/>
|
||||
<constructor-arg ref="frequentFlyerDao"/>
|
||||
</bean>
|
||||
|
||||
<!-- ===================== WS-SECURITY ============================== -->
|
||||
|
||||
<bean id="secureMapping" class="org.springframework.ws.soap.server.endpoint.mapping.SoapActionEndpointMapping">
|
||||
<description>
|
||||
This SOAP Action endpoint mapping is used for endpoints that are secured via WS-Security. It uses a
|
||||
securityInterceptor to validate incoming messages.
|
||||
</description>
|
||||
<property name="mappings">
|
||||
<props>
|
||||
<prop key="http://www.springframework.org/spring-ws/samples/airline/GetFrequentFlyerMileage">
|
||||
getFrequentFlyerMileageEndpoint
|
||||
</prop>
|
||||
</props>
|
||||
</property>
|
||||
<property name="interceptors">
|
||||
<list>
|
||||
<bean class="org.springframework.ws.soap.server.endpoint.interceptor.SoapEnvelopeLoggingInterceptor"/>
|
||||
<ref local="wsSecurityInterceptor"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
|
||||
<description>
|
||||
This interceptor validates incoming messages according to the policy defined in 'securityPolicy.xml'.
|
||||
@@ -53,6 +41,7 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
|
||||
<!-- ======================== ACEGI AUTHENTICATION ======================= -->
|
||||
|
||||
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
|
||||
@@ -76,7 +65,7 @@
|
||||
<ref local="authenticationManager"/>
|
||||
</property>
|
||||
<property name="accessDecisionManager">
|
||||
<bean class="org.acegisecurity.vote.UnanimousBased">
|
||||
<bean class="org.acegisecurity.vote.AffirmativeBased">
|
||||
<property name="decisionVoters">
|
||||
<bean class="org.acegisecurity.vote.RoleVoter"/>
|
||||
</property>
|
||||
|
||||
@@ -1,53 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><!--
|
||||
~ Copyright 2007 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.
|
||||
-->
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
|
||||
|
||||
<tx:annotation-driven/>
|
||||
|
||||
<bean id="airlineService" class="org.springframework.ws.samples.airline.service.impl.AirlineServiceImpl">
|
||||
<description>
|
||||
The Airline business service. It requires a flight DAO and ticket DAO to work. The
|
||||
frequentFlyerSecurityService property is not required, so we use a property to configure it.
|
||||
</description>
|
||||
<constructor-arg ref="flightDao"/>
|
||||
<constructor-arg ref="ticketDao"/>
|
||||
<property name="frequentFlyerSecurityService" ref="securityService"/>
|
||||
</bean>
|
||||
|
||||
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
|
||||
<description>
|
||||
The MessageFactory is used to create new SOAP messages from incoming requests. It is referenced to in
|
||||
airline-servlet.xml.
|
||||
</description>
|
||||
</bean>
|
||||
|
||||
<!--
|
||||
<bean id="airlineService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
|
||||
<property name="target" ref="airlineServiceTarget"/>
|
||||
<property name="transactionManager" ref="transactionManager"/>
|
||||
<property name="transactionAttributes">
|
||||
<props>
|
||||
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
|
||||
<prop key="book*">PROPAGATION_REQUIRED</prop>
|
||||
</props>
|
||||
</property>
|
||||
-->
|
||||
<!-- Remove the following line if you want to disable WS-Security and Acegi -->
|
||||
<!--
|
||||
<property name="postInterceptors" ref="methodSecurityInterceptor"/>
|
||||
</bean>
|
||||
-->
|
||||
</beans>
|
||||
@@ -10,9 +10,7 @@
|
||||
<param-value>
|
||||
classpath:org/springframework/ws/samples/airline/dao/jpa/applicationContext-jpa.xml
|
||||
classpath:org/springframework/ws/samples/airline/service/applicationContext.xml
|
||||
<!-- Remove the following line if you want to disable WS-Security and Acegi -->
|
||||
<!--classpath:org/springframework/ws/samples/airline/security/applicationContext-security.xml-->
|
||||
<!--classpath:org/springframework/ws/samples/airline/ws/applicationContext-ws.xml-->
|
||||
classpath:org/springframework/ws/samples/airline/security/applicationContext-security.xml
|
||||
</param-value>
|
||||
</context-param>
|
||||
<listener>
|
||||
|
||||
@@ -8,23 +8,36 @@
|
||||
<!-- ===================== ENDPOINTS ===================================== -->
|
||||
|
||||
<!--
|
||||
<bean id="marshallingEndpoint" class="org.springframework.ws.samples.airline.ws.MarshallingAirlineEndpoint">
|
||||
The marshallingEndpoint and xpathEndpoint handle the same messages. So, you can only use one of them at the
|
||||
same time. This is done for illustration purposes only, typically you would not create two endpoints which
|
||||
handle the same messages.
|
||||
-->
|
||||
|
||||
<bean id="marshallingEndpoint" class="org.springframework.ws.samples.airline.ws.MarshallingAirlineEndpoint">
|
||||
<description>
|
||||
This endpoint handles the Airline Web Service messages using JAXB2 marshalling.
|
||||
</description>
|
||||
<constructor-arg ref="airlineService"/>
|
||||
</bean>
|
||||
|
||||
<!--
|
||||
<bean id="xpathEndpoint" class="org.springframework.ws.samples.airline.ws.XPathAirlineEndpoint">
|
||||
<description>
|
||||
This endpoint handles the Airline Web Service messages using JAXB2 marshalling.
|
||||
This endpoint handles the Airline Web Service messages using XPath expressions and JAXB2 marshalling.
|
||||
</description>
|
||||
<constructor-arg ref="airlineService"/>
|
||||
<constructor-arg ref="marshaller"/>
|
||||
</bean>
|
||||
-->
|
||||
|
||||
<bean id="xpathEndpoint" class="org.springframework.ws.samples.airline.ws.XPathAirlineEndpoint">
|
||||
<bean id="getFrequentFlyerMileageEndpoint"
|
||||
class="org.springframework.ws.samples.airline.ws.GetFrequentFlyerMileageEndpoint">
|
||||
<description>
|
||||
This endpoint handles the Airline Web Service messages using XPath expressions and JAXB2 marshalling.
|
||||
This endpoint handles get frequent flyer mileage requests.
|
||||
</description>
|
||||
<constructor-arg ref="airlineService"/>
|
||||
<constructor-arg ref="marshaller"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
|
||||
<description>
|
||||
The JAXB 2 Marshaller is used by the endpoints.
|
||||
@@ -33,9 +46,14 @@
|
||||
<property name="contextPath" value="org.springframework.ws.samples.airline.schema"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<!-- ===================== ENDPOINT MAPPINGS ============================== -->
|
||||
|
||||
<!--
|
||||
The endpoint mappings map from a request to an endpoint. Because we only want the security interception to
|
||||
occur for the GetFrequentFlyerMileageEndpoint, we define two mappings: one with the securityInterceptor, and
|
||||
a general one without it.
|
||||
-->
|
||||
|
||||
<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
|
||||
<description>
|
||||
Detects @PayloadRoot annotations on @Endpoint bean methods. The MarshallingAirlineEndpoint
|
||||
@@ -52,10 +70,40 @@
|
||||
</bean>
|
||||
</list>
|
||||
</property>
|
||||
<property name="order" value="1"/>
|
||||
</bean>
|
||||
|
||||
<bean id="secureMapping" class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
|
||||
<description>
|
||||
This endpoint mapping is used for endpoints that are secured via WS-Security. It uses a
|
||||
securityInterceptor, defined in applicationContext-security.xml, to validate incoming messages.
|
||||
</description>
|
||||
<property name="mappings">
|
||||
<props>
|
||||
<prop key="{http://www.springframework.org/spring-ws/samples/airline/schemas}GetFrequentFlyerMileageRequest">
|
||||
getFrequentFlyerMileageEndpoint
|
||||
</prop>
|
||||
</props>
|
||||
</property>
|
||||
<property name="interceptors">
|
||||
<list>
|
||||
<bean class="org.springframework.ws.soap.server.endpoint.interceptor.SoapEnvelopeLoggingInterceptor"/>
|
||||
<ref bean="wsSecurityInterceptor"/>
|
||||
</list>
|
||||
</property>
|
||||
<property name="order" value="2"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<!-- ===================== ENDPOINT ADAPTERS ============================== -->
|
||||
|
||||
<!--
|
||||
Endpoint adapters adapt from the incoming message to a specific object or method signature. Because this
|
||||
example application uses three different endpoint programming models, we have to define three adapters. This
|
||||
is done for illustration purposes only, typically you would use one adapter, for instance the
|
||||
MarshallingMethodEndpointAdapter.
|
||||
-->
|
||||
|
||||
<bean class="org.springframework.ws.server.endpoint.adapter.MarshallingMethodEndpointAdapter">
|
||||
<description>
|
||||
This adapter allows for methods that need and returns marshalled objects. The MarshallingEndpoint
|
||||
@@ -75,25 +123,44 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.ws.server.endpoint.adapter.PayloadEndpointAdapter">
|
||||
<description>
|
||||
This adapter allows for endpoints which implement the PayloadEndpoint interface. The Get
|
||||
FrequentFlyerMileageEndpoint implements this interface.
|
||||
</description>
|
||||
</bean>
|
||||
|
||||
<!-- ===================== ENDPOINT EXCEPTION RESOLVER ===================== -->
|
||||
|
||||
<!--
|
||||
Endpoint exception resolvers can handle exceptions as they occur in the Web service. We have two sorts of
|
||||
exceptions we want to handle: the business logic exceptions NoSeatAvailableException and NoSuchFlightException,
|
||||
which both have a @SoapFault annotation, and other exceptions, which don't have the annotation. Therefore, we
|
||||
have two exception resolvers here.
|
||||
-->
|
||||
|
||||
<bean class="org.springframework.ws.soap.server.endpoint.SoapFaultAnnotationExceptionResolver">
|
||||
<description>
|
||||
This exception resolver maps exceptions with the @SoapFault annotation to SOAP Faults. The business logic
|
||||
exceptions NoSeatAvailableException and NoSuchFlightException have these.
|
||||
</description>
|
||||
<property name="order" value="1"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.ws.soap.server.endpoint.SoapFaultMappingExceptionResolver">
|
||||
<description>
|
||||
This exception resolver maps exceptions to SOAP Faults. The business logic exceptions
|
||||
NoSeatAvailableException and NoSuchFlightException are explictely mapped. Both
|
||||
UnmarshallingException andValidationFailureException are mapped to a SOAP Fault with a "Sender" fault code.
|
||||
This exception resolver maps other exceptions to SOAP Faults. Both UnmarshallingException and
|
||||
ValidationFailureException are mapped to a SOAP Fault with a "Client" fault code.
|
||||
All other exceptions are mapped to a "Server" error code, the default.
|
||||
</description>
|
||||
<property name="defaultFault" value="SERVER"/>
|
||||
<property name="exceptionMappings">
|
||||
<props>
|
||||
<prop key="org.springframework.ws.samples.airline.service.NoSuchFlightException">CLIENT</prop>
|
||||
<prop key="org.springframework.ws.samples.airline.service.NoSeatAvailableException">SERVER</prop>
|
||||
<prop key="org.springframework.oxm.UnmarshallingFailureException">CLIENT,Invalid request</prop>
|
||||
<prop key="org.springframework.oxm.ValidationFailureException">CLIENT,Invalid request</prop>
|
||||
</props>
|
||||
</property>
|
||||
<property name="order" value="2"/>
|
||||
</bean>
|
||||
|
||||
<!-- ===================== WSDL DEFINITION ============================== -->
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2007 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 javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import static org.easymock.EasyMock.*;
|
||||
import org.springframework.ws.samples.airline.service.AirlineService;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
public class GetFrequentFlyerMileageEndpointTest extends TestCase {
|
||||
|
||||
private GetFrequentFlyerMileageEndpoint endpoint;
|
||||
|
||||
private AirlineService airlineServiceMock;
|
||||
|
||||
private Document document;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
airlineServiceMock = createMock(AirlineService.class);
|
||||
endpoint = new GetFrequentFlyerMileageEndpoint(airlineServiceMock);
|
||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||
document = documentBuilder.newDocument();
|
||||
}
|
||||
|
||||
public void testGetFrequentFlyerMileage() throws Exception {
|
||||
expect(airlineServiceMock.getFrequentFlyerMileage()).andReturn(42);
|
||||
|
||||
replay(airlineServiceMock);
|
||||
|
||||
Element response = endpoint.invokeInternal(null, document);
|
||||
assertNotNull("Invalid response", response);
|
||||
|
||||
verify(airlineServiceMock);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -189,16 +189,4 @@ public class MarshallingAirlineEndpointTest extends TestCase {
|
||||
verify(airlineServiceMock);
|
||||
}
|
||||
|
||||
public void testGetFrequentFlyerMileage() throws Exception {
|
||||
JAXBElement<String> request = objectFactory.createGetFrequentFlyerMileageRequest(null);
|
||||
|
||||
expect(airlineServiceMock.getFrequentFlyerMileage()).andReturn(42);
|
||||
|
||||
replay(airlineServiceMock);
|
||||
|
||||
JAXBElement<Integer> response = endpoint.getFrequentFlyerMileage(request);
|
||||
assertEquals("Invalid amount of miles received", 42, response.getValue().intValue());
|
||||
|
||||
verify(airlineServiceMock);
|
||||
}
|
||||
}
|
||||
@@ -69,16 +69,5 @@ public class XPathAirlineEndpointTest extends TestCase {
|
||||
return domainFlight;
|
||||
}
|
||||
|
||||
public void testGetFrequentFlyerMileage() throws Exception {
|
||||
expect(airlineServiceMock.getFrequentFlyerMileage()).andReturn(42);
|
||||
|
||||
replay(airlineServiceMock);
|
||||
|
||||
Source response = endpoint.getFrequentFlyerMileage();
|
||||
assertNotNull("Invalid response", response);
|
||||
|
||||
verify(airlineServiceMock);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user