private String getActionFromOutputMessage(final OperationInfo operation) { MessageInfo outputMessage = operation.getOutput(); if (outputMessage != null && outputMessage.getExtensionAttributes() != null) { String outputAction = InternalContextUtils.getAction(outputMessage); if (!StringUtils.isEmpty(outputAction)) { return outputAction; } } return null; }
protected String getActionUri(Message message, boolean checkMessage) { BindingOperationInfo bop = message.getExchange().getBindingOperationInfo(); if (bop == null || Boolean.TRUE.equals(bop.getProperty("operation.is.synthetic"))) { return null; } OperationInfo op = bop.getOperationInfo(); if (op.isUnwrapped()) { op = ((UnwrappedOperationInfo) op).getWrappedOperation(); } String actionUri = null; if (checkMessage) { actionUri = (String) message.get(ContextUtils.ACTION); if (actionUri == null) { actionUri = (String) message.get(SoapBindingConstants.SOAP_ACTION); } } if (actionUri != null) { return actionUri; } String opNamespace = getActionBaseUri(op); boolean inbound = !ContextUtils.isOutbound(message); boolean requestor = ContextUtils.isRequestor(message); boolean inMsg = requestor ^ inbound; if (ContextUtils.isFault(message)) { String faultName = getFaultNameFromMessage(message); actionUri = getActionFromFaultMessage(op, faultName); } else if (inMsg) { String explicitAction = getActionFromInputMessage(op); if (StringUtils.isEmpty(explicitAction)) { SoapOperationInfo soi = InternalContextUtils.getSoapOperationInfo(bop); explicitAction = soi == null ? null : soi.getAction(); } if (!StringUtils.isEmpty(explicitAction)) { actionUri = explicitAction; } else if (null == op.getInputName()) { actionUri = addPath(opNamespace, op.getName().getLocalPart() + "Request"); } else { actionUri = addPath(opNamespace, op.getInputName()); } } else { String explicitAction = getActionFromOutputMessage(op); if (explicitAction != null) { actionUri = explicitAction; } else if (null == op.getOutputName()) { actionUri = addPath(opNamespace, op.getName().getLocalPart() + "Response"); } else { actionUri = addPath(opNamespace, op.getOutputName()); } } return actionUri; }
private String getActionFromInputMessage(final OperationInfo operation) { MessageInfo inputMessage = operation.getInput(); if (inputMessage.getExtensionAttributes() != null) { String inputAction = InternalContextUtils.getAction(inputMessage); if (!StringUtils.isEmpty(inputAction)) { return inputAction; } } return null; }
/** * Assemble the generic MAPs (for both requests and responses). * * @param message the current message * @return AddressingProperties containing the generic MAPs */ private AddressingProperties assembleGeneric(Message message) { AddressingProperties maps = getMAPs(message, true, true); // MessageID if (maps.getMessageID() == null) { String messageID = ContextUtils.generateUUID(); maps.setMessageID(ContextUtils.getAttributedURI(messageID)); } // Action if (ContextUtils.hasEmptyAction(maps)) { maps.setAction(InternalContextUtils.getAction(message)); if (ContextUtils.hasEmptyAction(maps) && ContextUtils.isOutbound(message)) { maps.setAction(ContextUtils.getAttributedURI(getActionUri(message, true))); } } return maps; }
private String getActionFromFaultMessage(final OperationInfo operation, final String faultName) { if (operation.getFaults() != null) { for (FaultInfo faultInfo : operation.getFaults()) { if (isSameFault(faultInfo, faultName)) { if (faultInfo.getExtensionAttributes() != null) { String faultAction = InternalContextUtils.getAction(faultInfo); if (!StringUtils.isEmpty(faultAction)) { return faultAction; } } return addPath( addPath( addPath(getActionBaseUri(operation), operation.getName().getLocalPart()), "Fault"), faultInfo.getFaultName().getLocalPart()); } } } return addPath( addPath(addPath(getActionBaseUri(operation), operation.getName().getLocalPart()), "Fault"), faultName); }
/** * Add MAPs which are specific to the requestor or responder role. * * @param maps the MAPs being assembled * @param message the current message * @param isRequestor true iff the current messaging role is that of requestor * @param isFault true if a fault is being mediated */ private void addRoleSpecific( AddressingProperties maps, Message message, boolean isRequestor, boolean isFault) { if (isRequestor) { Exchange exchange = message.getExchange(); // add request-specific MAPs boolean isOneway = exchange.isOneWay(); boolean isOutbound = ContextUtils.isOutbound(message); // To if (maps.getTo() == null) { Conduit conduit = null; if (isOutbound) { conduit = ContextUtils.getConduit(null, message); } String s = (String) message.get(Message.ENDPOINT_ADDRESS); EndpointReferenceType reference = conduit != null ? conduit.getTarget() : ContextUtils.getNoneEndpointReference(); if (conduit != null && !StringUtils.isEmpty(s) && !reference.getAddress().getValue().equals(s)) { EndpointReferenceType ref = new EndpointReferenceType(); AttributedURIType tp = new AttributedURIType(); tp.setValue(s); ref.setAddress(tp); ref.setMetadata(reference.getMetadata()); ref.setReferenceParameters(reference.getReferenceParameters()); ref.getOtherAttributes().putAll(reference.getOtherAttributes()); reference = ref; } maps.setTo(reference); } // ReplyTo, set if null in MAPs or if set to a generic address // (anonymous or none) that may not be appropriate for the // current invocation EndpointReferenceType replyTo = maps.getReplyTo(); if (ContextUtils.isGenericAddress(replyTo)) { replyTo = getReplyTo(message, replyTo); if (replyTo == null || (isOneway && (replyTo == null || replyTo.getAddress() == null || !Names.WSA_NONE_ADDRESS.equals(replyTo.getAddress().getValue())))) { AttributedURIType address = ContextUtils.getAttributedURI( isOneway ? Names.WSA_NONE_ADDRESS : Names.WSA_ANONYMOUS_ADDRESS); replyTo = ContextUtils.WSA_OBJECT_FACTORY.createEndpointReferenceType(); replyTo.setAddress(address); } maps.setReplyTo(replyTo); } // FaultTo if (maps.getFaultTo() == null) { maps.setFaultTo(maps.getReplyTo()); } else if (maps.getFaultTo().getAddress() == null) { maps.setFaultTo(null); } } else { // add response-specific MAPs AddressingProperties inMAPs = getMAPs(message, false, false); maps.exposeAs(inMAPs.getNamespaceURI()); // To taken from ReplyTo or FaultTo in incoming MAPs (depending // on the fault status of the response) if (isFault && inMAPs.getFaultTo() != null) { maps.setTo(inMAPs.getFaultTo()); } else if (maps.getTo() == null && inMAPs.getReplyTo() != null) { maps.setTo(inMAPs.getReplyTo()); } // RelatesTo taken from MessageID in incoming MAPs if (inMAPs.getMessageID() != null && !Boolean.TRUE.equals(message.get(Message.PARTIAL_RESPONSE_MESSAGE))) { String inMessageID = inMAPs.getMessageID().getValue(); maps.setRelatesTo(ContextUtils.getRelatesTo(inMessageID)); } else { maps.setRelatesTo(ContextUtils.getRelatesTo(Names.WSA_UNSPECIFIED_RELATIONSHIP)); } // fallback fault action if (isFault && maps.getAction() == null) { maps.setAction(ContextUtils.getAttributedURI(Names.WSA_DEFAULT_FAULT_ACTION)); } if (isFault && !ContextUtils.isGenericAddress(inMAPs.getFaultTo())) { Message m = message.getExchange().getInFaultMessage(); if (m == null) { m = message; } InternalContextUtils.rebaseResponse(inMAPs.getFaultTo(), inMAPs, m); Destination destination = InternalContextUtils.createDecoupledDestination(m.getExchange(), inMAPs.getFaultTo()); m.getExchange().setDestination(destination); } } }
/** * Mediate message flow. * * @param message the current message * @param isFault true if a fault is being mediated * @return true if processing should continue on dispatch path */ protected boolean mediate(Message message, boolean isFault) { boolean continueProcessing = true; if (ContextUtils.isOutbound(message)) { if (usingAddressing(message)) { // request/response MAPs must be aggregated aggregate(message, isFault); } AddressingProperties theMaps = ContextUtils.retrieveMAPs(message, false, ContextUtils.isOutbound(message)); if (null != theMaps) { if (ContextUtils.isRequestor(message)) { assertAddressing(message, theMaps.getReplyTo(), theMaps.getFaultTo()); } else { checkReplyTo(message, theMaps); } } } else if (!ContextUtils.isRequestor(message)) { // responder validates incoming MAPs AddressingProperties maps = getMAPs(message, false, false); // check responses if (maps != null) { checkAddressingResponses(maps.getReplyTo(), maps.getFaultTo()); assertAddressing(message, maps.getReplyTo(), maps.getFaultTo()); } boolean isOneway = message.getExchange().isOneWay(); if (null == maps && !addressingRequired) { return false; } continueProcessing = validateIncomingMAPs(maps, message); if (maps != null) { AddressingProperties theMaps = ContextUtils.retrieveMAPs(message, false, ContextUtils.isOutbound(message)); if (null != theMaps) { assertAddressing(message, theMaps.getReplyTo(), theMaps.getFaultTo()); } if (isOneway || !ContextUtils.isGenericAddress(maps.getReplyTo())) { InternalContextUtils.rebaseResponse(maps.getReplyTo(), maps, message); } if (!isOneway) { if (ContextUtils.isNoneAddress(maps.getReplyTo())) { LOG.warning("Detected NONE value in ReplyTo WSA header for request-respone MEP"); } else { // ensure the inbound MAPs are available in both the full & fault // response messages (used to determine relatesTo etc.) ContextUtils.propogateReceivedMAPs(maps, message.getExchange()); } } } if (continueProcessing) { // any faults thrown from here on can be correlated with this message message.put(FaultMode.class, FaultMode.LOGICAL_RUNTIME_FAULT); } else { // validation failure => dispatch is aborted, response MAPs // must be aggregated // isFault = true; // aggregate(message, isFault); if (isSOAP12(message)) { SoapFault soap12Fault = new SoapFault( ContextUtils.retrieveMAPFaultReason(message), Soap12.getInstance().getSender()); soap12Fault.setSubCode( new QName(Names.WSA_NAMESPACE_NAME, ContextUtils.retrieveMAPFaultName(message))); throw soap12Fault; } throw new SoapFault( ContextUtils.retrieveMAPFaultReason(message), new QName(Names.WSA_NAMESPACE_NAME, ContextUtils.retrieveMAPFaultName(message))); } } else { AddressingProperties theMaps = ContextUtils.retrieveMAPs(message, false, ContextUtils.isOutbound(message)); if (null != theMaps) { assertAddressing(message, theMaps.getReplyTo(), theMaps.getFaultTo()); } // If the wsa policy is enabled , but the client sets the // WSAddressingFeature.isAddressingRequired to false , we need to assert all WSA assertion to // true if (!ContextUtils.isOutbound(message) && ContextUtils.isRequestor(message) && getWSAddressingFeature(message) != null && !getWSAddressingFeature(message).isAddressingRequired()) { assertAddressing(message); } // CXF-3060 :If wsa policy is not enforced, AddressingProperties map is null and // AddressingFeature.isRequired, requestor checks inbound message and throw exception if (null == theMaps && !ContextUtils.isOutbound(message) && ContextUtils.isRequestor(message) && getWSAddressingFeature(message) != null && getWSAddressingFeature(message).isAddressingRequired()) { boolean missingWsaHeader = false; AssertionInfoMap aim = message.get(AssertionInfoMap.class); if (aim == null || aim.size() == 0) { missingWsaHeader = true; } if (aim != null && aim.size() > 0) { missingWsaHeader = true; QName[] types = new QName[] { MetadataConstants.ADDRESSING_ASSERTION_QNAME, MetadataConstants.USING_ADDRESSING_2004_QNAME, MetadataConstants.USING_ADDRESSING_2005_QNAME, MetadataConstants.USING_ADDRESSING_2006_QNAME }; for (QName type : types) { for (AssertionInfo assertInfo : aim.getAssertionInfo(type)) { if (assertInfo.isAsserted()) { missingWsaHeader = false; } } } } if (missingWsaHeader) { throw new SoapFault( "MISSING_ACTION_MESSAGE", BUNDLE, new QName(Names.WSA_NAMESPACE_NAME, Names.HEADER_REQUIRED_NAME)); } } if (MessageUtils.isPartialResponse(message) && message.getExchange().getOutMessage() != null) { // marked as a partial response, let's see if it really is MessageInfo min = message.get(MessageInfo.class); MessageInfo mout = message.getExchange().getOutMessage().get(MessageInfo.class); if (min != null && mout != null && min.getOperation() == mout.getOperation() && message.getContent(List.class) != null) { // the in and out messages are on the same operation // and we were able to get a response for it. message.remove(Message.PARTIAL_RESPONSE_MESSAGE); } } } return continueProcessing; }