Skip to content

Commit

Permalink
Some improvements to handling SOAP Actions
Browse files Browse the repository at this point in the history
git-svn-id: https://svn.apache.org/repos/asf/cxf/trunk@1368559 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
coheigea committed Aug 2, 2012
1 parent 92831c6 commit 9c70abe
Show file tree
Hide file tree
Showing 10 changed files with 759 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,11 @@ public void handleMessage(Message message) {
} else {
p = findMessagePart(exchange, operations, elName, client, paramNum, message);
}

if (p == null) {
throw new Fault(new org.apache.cxf.common.i18n.Message("NO_PART_FOUND", LOG, elName),
Fault.FAULT_CODE_CLIENT);
}


//Make sure the elName found on the wire is actually OK for
//the purpose we need it
validatePart(p, elName, si);

o = dr.read(p, xmlReader);
if (Boolean.TRUE.equals(si.getProperty("soap.force.doclit.bare"))
&& parameters.isEmpty()) {
Expand All @@ -223,6 +222,44 @@ public void handleMessage(Message message) {
}
}

private void validatePart(MessagePartInfo p, QName elName, ServiceInfo si) {
if (p == null) {
throw new Fault(new org.apache.cxf.common.i18n.Message("NO_PART_FOUND", LOG, elName),
Fault.FAULT_CODE_CLIENT);

}

Boolean synth = Boolean.FALSE;
if (p.getMessageInfo() != null && p.getMessageInfo().getOperation() != null) {
OperationInfo op = p.getMessageInfo().getOperation();
Boolean b = (Boolean)op.getProperty("operation.is.synthetic");
if (b != null) {
synth = b;
}
}
if (si != null && Boolean.TRUE.equals(si.getProperty("soap.force.doclit.bare"))) {
// something like a Provider service or similar that is forcing a
// doc/lit/bare on an endpoint that may not really be doc/lit/bare.
// we need to just let these through per spec so the endpoint
// can process it
synth = true;
}
if (p.isElement()) {
if (p.getConcreteName() != null
&& !elName.equals(p.getConcreteName())
&& !Boolean.TRUE.equals(synth)) {
throw new Fault("UNEXPECTED_ELEMENT", LOG, null, elName,
p.getConcreteName());
}
} else {
if (!(elName.equals(p.getName()) || elName.equals(p.getConcreteName()))
&& !Boolean.TRUE.equals(synth)) {
throw new Fault("UNEXPECTED_ELEMENT", LOG, null, elName,
p.getConcreteName());
}
}
}

private void getPara(DepthXMLStreamReader xmlReader,
DataReader<XMLStreamReader> dr,
MessageContentsList parameters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ COULD_NOT_FIND_SEICLASS=Could not find the class: {0}
EXCEPTION_WHILE_WRITING_FAULT = Exception occurred while writing fault.
EXCEPTION_WHILE_CREATING_EXCEPTION = Exception occurred while creating exception: {0}
UNEXPECTED_WRAPPER_ELEMENT = Unexpected wrapper element {0} found. Expected {1}.
UNEXPECTED_ELEMENT = Unexpected element {0} found. Expected {1}.

Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ INVALID_11_VERSION=A SOAP 1.2 message is not valid when sent to a SOAP 1.1 only
NO_NAMESPACE=No namespace on "{0}" element.
BP_2211_RPCLIT_CANNOT_BE_NULL=Cannot write part {0}. RPC/Literal parts cannot be null. (WS-I BP R2211)
UNKNOWN_RPC_LIT_PART=Found element {0} but could not find matching RPC/Literal part
SOAP_ACTION_MISMATCH=The given SOAPAction {0} does not match an operation.
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import org.apache.cxf.binding.soap.Soap11;
import org.apache.cxf.binding.soap.Soap12;
import org.apache.cxf.binding.soap.SoapBindingConstants;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.model.SoapOperationInfo;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.helpers.CastUtils;
Expand All @@ -40,6 +42,8 @@

public class SoapActionInInterceptor extends AbstractSoapInterceptor {

private static final Logger LOG = LogUtils.getL7dLogger(SoapActionInInterceptor.class);

public SoapActionInInterceptor() {
super(Phase.READ);
addAfter(ReadHeadersInterceptor.class.getName());
Expand Down Expand Up @@ -91,6 +95,10 @@ public static String getSoapAction(Message m) {
}

public void handleMessage(SoapMessage message) throws Fault {
if (isRequestor(message)) {
return;
}

String action = getSoapAction(message);
if (!StringUtils.isEmpty(action)) {
getAndSetOperation(message, action);
Expand All @@ -108,24 +116,54 @@ private void getAndSetOperation(SoapMessage message, String action) {

BindingOperationInfo bindingOp = null;

Collection<BindingOperationInfo> bops = ep.getBinding().getBindingInfo().getOperations();
if (bops == null) {
Collection<BindingOperationInfo> bops = ep.getEndpointInfo()
.getBinding().getOperations();
if (bops != null) {
for (BindingOperationInfo boi : bops) {
SoapOperationInfo soi = boi.getExtensor(SoapOperationInfo.class);
if (soi != null && action.equals(soi.getAction())) {
if (bindingOp != null) {
//more than one op with the same action, will need to parse normally
return;
}
bindingOp = boi;
}
}
}

if (bindingOp == null) {
//we didn't match the an operation, we'll try again later to make
//sure the incoming message did end up matching an operation.
//This could occur in some cases like WS-RM and WS-SecConv that will
//intercept the message with a new endpoint/operation
message.getInterceptorChain().add(new SoapActionInAttemptTwoInterceptor());
return;
}
for (BindingOperationInfo boi : bops) {

ex.put(BindingOperationInfo.class, bindingOp);
ex.put(OperationInfo.class, bindingOp.getOperationInfo());
}

public static class SoapActionInAttemptTwoInterceptor extends AbstractSoapInterceptor {
public SoapActionInAttemptTwoInterceptor() {
super(Phase.PRE_LOGICAL);
}
public void handleMessage(SoapMessage message) throws Fault {
BindingOperationInfo boi = message.getExchange().getBindingOperationInfo();
if (boi == null) {
return;
}
String action = getSoapAction(message);
if (StringUtils.isEmpty(action)) {
return;
}
SoapOperationInfo soi = boi.getExtensor(SoapOperationInfo.class);
if (soi != null && action.equals(soi.getAction())) {
if (bindingOp != null) {
//more than one op with the same action, will need to parse normally
return;
}
bindingOp = boi;
if (soi == null || action.equals(soi.getAction())) {
return;
}
}
if (bindingOp != null) {
ex.put(BindingOperationInfo.class, bindingOp);
ex.put(OperationInfo.class, bindingOp.getOperationInfo());
throw new Fault("SOAP_ACTION_MISMATCH", LOG, null, action);
}
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.cxf.systest.soap;

import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

import org.apache.hello_world_soap_action.WrappedGreeter;

@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter",
serviceName = "WrappedSOAPService")
@SOAPBinding(style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.ENCODED)
public class RPCEncodedSoapActionGreeterImpl implements WrappedGreeter {

public String sayHiRequestWrapped(String in) {
return "sayHi";
}

public String sayHiRequest2Wrapped(String in) {
return "sayHi2";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.cxf.systest.soap;

import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

import org.apache.hello_world_soap_action.WrappedGreeter;

@WebService(endpointInterface = "org.apache.hello_world_soap_action.WrappedGreeter",
serviceName = "WrappedSOAPService")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class RPCLitSoapActionGreeterImpl implements WrappedGreeter {

public String sayHiRequestWrapped(String in) {
return "sayHi";
}

public String sayHiRequest2Wrapped(String in) {
return "sayHi2";
}

}
Loading

0 comments on commit 9c70abe

Please sign in to comment.