001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.systest.ws.addressing;
019:
020: import java.util.ArrayList;
021: import java.util.Iterator;
022: import java.util.List;
023: import java.util.Set;
024:
025: import javax.xml.bind.JAXBContext;
026: import javax.xml.bind.JAXBElement;
027: import javax.xml.bind.JAXBException;
028: import javax.xml.bind.Marshaller;
029: import javax.xml.namespace.QName;
030: import javax.xml.soap.SOAPException;
031:
032: import org.w3c.dom.Document;
033: import org.w3c.dom.Element;
034: import org.w3c.dom.NodeList;
035:
036: import org.apache.cxf.binding.soap.SoapMessage;
037: import org.apache.cxf.binding.soap.SoapVersion;
038: import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
039: import org.apache.cxf.headers.Header;
040: import org.apache.cxf.helpers.DOMUtils;
041: import org.apache.cxf.phase.Phase;
042: import org.apache.cxf.ws.addressing.AddressingProperties;
043: import org.apache.cxf.ws.addressing.AttributedURIType;
044: import org.apache.cxf.ws.addressing.ContextUtils;
045: import org.apache.cxf.ws.addressing.Names;
046: import org.apache.cxf.ws.addressing.soap.VersionTransformer;
047: import org.apache.cxf.ws.addressing.v200408.AttributedURI;
048:
049: import static org.apache.cxf.ws.addressing.JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES_INBOUND;
050: import static org.apache.cxf.ws.addressing.JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_OUTBOUND;
051:
052: /**
053: * Verifies presence of expected SOAP headers.
054: */
055: public class HeaderVerifier extends AbstractSoapInterceptor {
056: VerificationCache verificationCache;
057: String currentNamespaceURI;
058:
059: public HeaderVerifier() {
060: super (Phase.POST_PROTOCOL);
061: }
062:
063: public Set<QName> getUnderstoodHeaders() {
064: return Names.HEADERS;
065: }
066:
067: public void handleMessage(SoapMessage message) {
068: mediate(message);
069: }
070:
071: public void handleFault(SoapMessage message) {
072: mediate(message);
073: }
074:
075: private void mediate(SoapMessage message) {
076: boolean outgoingPartialResponse = isOutgoingPartialResponse(message);
077: if (outgoingPartialResponse) {
078: addPartialResponseHeader(message);
079: }
080: verify(message, outgoingPartialResponse);
081: }
082:
083: private void addPartialResponseHeader(SoapMessage message) {
084: try {
085: // add piggybacked wsa:From header to partial response
086: List<Header> header = message.getHeaders();
087: Document doc = DOMUtils.createDocument();
088: SoapVersion ver = message.getVersion();
089: Element hdr = doc.createElementNS(ver.getHeader()
090: .getNamespaceURI(), ver.getHeader().getLocalPart());
091: hdr.setPrefix(ver.getHeader().getPrefix());
092:
093: marshallFrom("urn:piggyback_responder", hdr,
094: getMarshaller());
095: NodeList nl = hdr.getChildNodes();
096: for (int i = 0; i < nl.getLength(); i++) {
097: Object obj = nl.item(i);
098: if (obj instanceof Element) {
099: Element elem = (Element) obj;
100: Header holder = new Header(new QName(elem
101: .getNamespaceURI(), elem.getLocalName()),
102: elem, null);
103: header.add(holder);
104: }
105: }
106:
107: } catch (Exception e) {
108: verificationCache.put("SOAP header addition failed: " + e);
109: e.printStackTrace();
110: }
111: }
112:
113: private void verify(SoapMessage message,
114: boolean outgoingPartialResponse) {
115: try {
116: List<String> wsaHeaders = new ArrayList<String>();
117: List<Header> headers = message.getHeaders();
118: if (headers != null) {
119: recordWSAHeaders(headers, wsaHeaders,
120: Names.WSA_NAMESPACE_NAME);
121: recordWSAHeaders(
122: headers,
123: wsaHeaders,
124: VersionTransformer.Names200408.WSA_NAMESPACE_NAME);
125: recordWSAHeaders(headers, wsaHeaders,
126: MAPTestBase.CUSTOMER_NAME.getNamespaceURI());
127: }
128: boolean partialResponse = isIncomingPartialResponse(message)
129: || outgoingPartialResponse;
130: verificationCache.put(MAPTest.verifyHeaders(wsaHeaders,
131: partialResponse, isRequestLeg(message)));
132: } catch (SOAPException se) {
133: verificationCache.put("SOAP header verification failed: "
134: + se);
135: }
136: }
137:
138: private void recordWSAHeaders(List<Header> headers,
139: List<String> wsaHeaders, String namespaceURI) {
140: Iterator<Header> iter = headers.iterator();
141: while (iter.hasNext()) {
142: Object obj = iter.next().getObject();
143: if (obj instanceof Element) {
144: Element hdr = (Element) obj;
145: if (namespaceURI.equals(hdr.getNamespaceURI())) {
146: if (namespaceURI.endsWith("addressing")) {
147: currentNamespaceURI = namespaceURI;
148: wsaHeaders.add(hdr.getLocalName());
149: } else if (MAPTestBase.CUSTOMER_NAME
150: .getNamespaceURI().equals(namespaceURI)) {
151: String headerText = hdr.getTextContent();
152: if (MAPTestBase.CUSTOMER_KEY.equals(headerText)) {
153: wsaHeaders.add(hdr.getLocalName());
154: }
155: }
156: }
157: }
158:
159: }
160: }
161:
162: private boolean isRequestLeg(SoapMessage message) {
163: return (ContextUtils.isRequestor(message) && ContextUtils
164: .isOutbound(message))
165: || (!ContextUtils.isRequestor(message) && !ContextUtils
166: .isOutbound(message));
167: }
168:
169: private boolean isOutgoingPartialResponse(SoapMessage message) {
170: AddressingProperties maps = (AddressingProperties) message
171: .get(SERVER_ADDRESSING_PROPERTIES_OUTBOUND);
172: return ContextUtils.isOutbound(message)
173: && !ContextUtils.isRequestor(message)
174: && maps != null
175: && Names.WSA_ANONYMOUS_ADDRESS.equals(maps.getTo()
176: .getValue());
177: }
178:
179: private boolean isIncomingPartialResponse(SoapMessage message)
180: throws SOAPException {
181: AddressingProperties maps = (AddressingProperties) message
182: .get(CLIENT_ADDRESSING_PROPERTIES_INBOUND);
183: return !ContextUtils.isOutbound(message)
184: && ContextUtils.isRequestor(message)
185: && maps != null
186: && Names.WSA_ANONYMOUS_ADDRESS.equals(maps.getTo()
187: .getValue());
188: }
189:
190: private Marshaller getMarshaller() throws JAXBException {
191: JAXBContext jaxbContext = VersionTransformer
192: .getExposedJAXBContext(currentNamespaceURI);
193: Marshaller marshaller = jaxbContext.createMarshaller();
194: marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
195: return marshaller;
196: }
197:
198: private void marshallFrom(String from, Element header,
199: Marshaller marshaller) throws JAXBException {
200: if (Names.WSA_NAMESPACE_NAME.equals(currentNamespaceURI)) {
201: String u = "urn:piggyback_responder";
202: AttributedURIType value = org.apache.cxf.ws.addressing.ContextUtils
203: .getAttributedURI(u);
204: marshaller.marshal(new JAXBElement<AttributedURIType>(
205: Names.WSA_FROM_QNAME, AttributedURIType.class,
206: value), header);
207: } else if (VersionTransformer.Names200408.WSA_NAMESPACE_NAME
208: .equals(currentNamespaceURI)) {
209: AttributedURI value = VersionTransformer.Names200408.WSA_OBJECT_FACTORY
210: .createAttributedURI();
211: value.setValue(from);
212: QName qname = new QName(
213: VersionTransformer.Names200408.WSA_NAMESPACE_NAME,
214: Names.WSA_FROM_NAME);
215: marshaller.marshal(new JAXBElement<AttributedURI>(qname,
216: AttributedURI.class, value), header);
217: }
218: }
219:
220: public void setVerificationCache(VerificationCache cache) {
221: verificationCache = cache;
222: }
223: }
|