@Test public void createSoap12Fault() { SoapBinding sb = control.createMock(SoapBinding.class); EasyMock.expect(sb.getSoapVersion()).andReturn(Soap12.getInstance()); setupJMSFault(true, SoapJMSConstants.getMismatchedSoapActionQName(), null); control.replay(); SoapFaultFactory factory = new SoapFaultFactory(sb); SoapFault fault = (SoapFault) factory.createFault(jmsFault); assertEquals("reason", fault.getReason()); assertEquals(Soap12.getInstance().getSender(), fault.getFaultCode()); assertEquals(SoapJMSConstants.getMismatchedSoapActionQName(), fault.getSubCode()); assertNull(fault.getDetail()); assertNull(fault.getCause()); control.verify(); }
private boolean isSOAP12(Message message) { if (message.getExchange().getBinding() instanceof SoapBinding) { SoapBinding binding = (SoapBinding) message.getExchange().getBinding(); if (binding.getSoapVersion() == Soap12.getInstance()) { return true; } } return false; }
/** * 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; }
/** * Asserts all Addressing assertions for the current message, regardless their nested Policies. * * @param message the current message */ private void assertAddressing( Message message, EndpointReferenceType replyTo, EndpointReferenceType faultTo) { AssertionInfoMap aim = message.get(AssertionInfoMap.class); if (null == aim) { return; } if (faultTo == null) { faultTo = replyTo; } boolean anonReply = ContextUtils.isGenericAddress(replyTo); boolean anonFault = ContextUtils.isGenericAddress(faultTo); boolean onlyAnonymous = anonReply && anonFault; boolean hasAnonymous = anonReply || anonFault; 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) { assertAssertion(aim, type); if (type.equals(MetadataConstants.ADDRESSING_ASSERTION_QNAME)) { if (onlyAnonymous) { assertAssertion(aim, MetadataConstants.ANON_RESPONSES_ASSERTION_QNAME); } else if (!hasAnonymous) { assertAssertion(aim, MetadataConstants.NON_ANON_RESPONSES_ASSERTION_QNAME); } } else if (type.equals(MetadataConstants.ADDRESSING_ASSERTION_QNAME_0705)) { if (onlyAnonymous) { assertAssertion(aim, MetadataConstants.ANON_RESPONSES_ASSERTION_QNAME_0705); } else if (!hasAnonymous) { assertAssertion(aim, MetadataConstants.NON_ANON_RESPONSES_ASSERTION_QNAME_0705); } } } if (!MessageUtils.isRequestor(message) && !MessageUtils.isOutbound(message)) { // need to throw an appropriate fault for these Collection<AssertionInfo> aicNonAnon = aim.getAssertionInfo(MetadataConstants.NON_ANON_RESPONSES_ASSERTION_QNAME); Collection<AssertionInfo> aicNonAnon2 = aim.getAssertionInfo(MetadataConstants.NON_ANON_RESPONSES_ASSERTION_QNAME_0705); Collection<AssertionInfo> aicAnon = aim.getAssertionInfo(MetadataConstants.ANON_RESPONSES_ASSERTION_QNAME); Collection<AssertionInfo> aicAnon2 = aim.getAssertionInfo(MetadataConstants.ANON_RESPONSES_ASSERTION_QNAME_0705); boolean hasAnon = (aicAnon != null && !aicAnon.isEmpty()) || (aicAnon2 != null && !aicAnon2.isEmpty()); boolean hasNonAnon = (aicNonAnon != null && !aicNonAnon.isEmpty()) || (aicNonAnon2 != null && !aicNonAnon2.isEmpty()); if (hasAnonymous && hasNonAnon && !hasAnon) { message.put(FaultMode.class, FaultMode.UNCHECKED_APPLICATION_FAULT); if (isSOAP12(message)) { SoapFault soap12Fault = new SoapFault( "Found anonymous address but non-anonymous required", Soap12.getInstance().getSender()); soap12Fault.addSubCode( new QName(Names.WSA_NAMESPACE_NAME, "OnlyNonAnonymousAddressSupported")); throw soap12Fault; } throw new SoapFault( "Found anonymous address but non-anonymous required", new QName(Names.WSA_NAMESPACE_NAME, "OnlyNonAnonymousAddressSupported")); } else if (!onlyAnonymous && !hasNonAnon && hasAnon) { message.put(FaultMode.class, FaultMode.UNCHECKED_APPLICATION_FAULT); if (isSOAP12(message)) { SoapFault soap12Fault = new SoapFault( "Found non-anonymous address but only anonymous supported", Soap12.getInstance().getSender()); soap12Fault.addSubCode( new QName(Names.WSA_NAMESPACE_NAME, "OnlyAnonymousAddressSupported")); throw soap12Fault; } throw new SoapFault( "Found non-anonymous address but only anonymous supported", new QName(Names.WSA_NAMESPACE_NAME, "OnlyAnonymousAddressSupported")); } } }