use of org.apache.cxf.ws.rm.v200702.SequenceAcknowledgement in project cxf by apache.
the class Destination method acknowledge.
/**
* Acknowledges receipt of a message. If the message is the last in the
* sequence, sends an out-of-band SequenceAcknowledgement unless there a
* response will be sent to the acksTo address onto which the acknowldegment
* can be piggybacked.
*
* @param sequenceType the sequenceType object that includes identifier and
* message number (and possibly a lastMessage element) for the
* message to be acknowledged)
* @param replyToAddress the replyTo address of the message that carried
* this sequence information
* @throws SequenceFault if the sequence specified in
* <code>sequenceType</code> does not exist
*/
public void acknowledge(Message message) throws SequenceFault, RMException {
RMProperties rmps = RMContextUtils.retrieveRMProperties(message, false);
SequenceType sequenceType = rmps.getSequence();
if (null == sequenceType) {
return;
}
DestinationSequence seq = getSequence(sequenceType.getIdentifier());
if (null != seq) {
if (seq.applyDeliveryAssurance(sequenceType.getMessageNumber(), message)) {
if (PropertyUtils.isTrue(message.get(RMMessageConstants.DELIVERING_ROBUST_ONEWAY))) {
return;
}
seq.acknowledge(message);
if (null != rmps.getCloseSequence()) {
seq.setLastMessageNumber(sequenceType.getMessageNumber());
ackImmediately(seq, message);
}
} else {
try {
message.getInterceptorChain().abort();
if (seq.sendAcknowledgement()) {
ackImmediately(seq, message);
}
Exchange exchange = message.getExchange();
Conduit conduit = exchange.getDestination().getBackChannel(message);
if (conduit != null) {
// null if it knows it cannot send anything.
if (seq.sendAcknowledgement()) {
AddressingProperties maps = RMContextUtils.retrieveMAPs(message, false, false);
InternalContextUtils.rebaseResponse(null, maps, message);
} else {
Message response = createMessage(exchange);
response.setExchange(exchange);
response.remove(Message.CONTENT_TYPE);
conduit.prepare(response);
conduit.close(response);
}
}
} catch (IOException e) {
LOG.log(Level.SEVERE, e.getMessage());
throw new RMException(e);
}
}
} else {
ProtocolVariation protocol = RMContextUtils.getProtocolVariation(message);
RMConstants consts = protocol.getConstants();
SequenceFaultFactory sff = new SequenceFaultFactory(consts);
throw sff.createUnknownSequenceFault(sequenceType.getIdentifier());
}
}
use of org.apache.cxf.ws.rm.v200702.SequenceAcknowledgement in project cxf by apache.
the class RMCaptureOutInterceptor method handle.
protected void handle(Message msg) throws SequenceFault, RMException {
AddressingProperties maps = ContextUtils.retrieveMAPs(msg, false, true, false);
if (null == maps) {
LogUtils.log(LOG, Level.WARNING, "MAPS_RETRIEVAL_FAILURE_MSG");
return;
}
if (Boolean.TRUE.equals(msg.get(RMMessageConstants.RM_RETRANSMISSION))) {
return;
}
if (isRuntimeFault(msg)) {
LogUtils.log(LOG, Level.WARNING, "RUNTIME_FAULT_MSG");
// in case of a SequenceFault or other WS-RM related fault, set action appropriately.
// the received inbound maps is available to extract some values in case if needed.
Throwable cause = msg.getContent(Exception.class).getCause();
if (cause instanceof SequenceFault || cause instanceof RMException) {
maps.getAction().setValue(getAddressingNamespace(maps) + "/fault");
}
return;
}
Source source = getManager().getSource(msg);
RMConfiguration config = getManager().getEffectiveConfiguration(msg);
String wsaNamespace = config.getAddressingNamespace();
String rmNamespace = config.getRMNamespace();
ProtocolVariation protocol = ProtocolVariation.findVariant(rmNamespace, wsaNamespace);
RMContextUtils.setProtocolVariation(msg, protocol);
maps.exposeAs(wsaNamespace);
String action = null;
if (null != maps.getAction()) {
action = maps.getAction().getValue();
}
// make sure we use the appropriate namespace
maps.exposeAs(wsaNamespace);
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("Action: " + action);
}
boolean isApplicationMessage = !RMContextUtils.isRMProtocolMessage(action);
boolean isPartialResponse = MessageUtils.isPartialResponse(msg);
RMConstants constants = protocol.getConstants();
boolean isLastMessage = RM10Constants.CLOSE_SEQUENCE_ACTION.equals(action);
RMProperties rmpsOut = RMContextUtils.retrieveRMProperties(msg, true);
if (null == rmpsOut) {
rmpsOut = new RMProperties();
rmpsOut.exposeAs(protocol.getWSRMNamespace());
RMContextUtils.storeRMProperties(msg, rmpsOut, true);
}
// Activate process response for oneWay
if (msg.getExchange().isOneWay()) {
msg.getExchange().put(Message.PROCESS_ONEWAY_RESPONSE, true);
}
RMProperties rmpsIn = null;
Identifier inSeqId = null;
long inMessageNumber = 0;
if (isApplicationMessage) {
rmpsIn = RMContextUtils.retrieveRMProperties(msg, false);
if (null != rmpsIn && null != rmpsIn.getSequence()) {
inSeqId = rmpsIn.getSequence().getIdentifier();
inMessageNumber = rmpsIn.getSequence().getMessageNumber();
}
ContextUtils.storeDeferUncorrelatedMessageAbort(msg);
}
Map<?, ?> invocationContext = (Map<?, ?>) msg.get(Message.INVOCATION_CONTEXT);
if ((isApplicationMessage || (isLastMessage && invocationContext != null)) && !isPartialResponse) {
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("inbound sequence: " + (null == inSeqId ? "null" : inSeqId.getValue()));
}
// get the current sequence, requesting the creation of a new one if necessary
synchronized (source) {
SourceSequence seq = null;
if (isLastMessage) {
seq = (SourceSequence) invocationContext.get(SourceSequence.class.getName());
} else {
seq = getManager().getSequence(inSeqId, msg, maps);
}
assert null != seq;
// increase message number and store a sequence type object in
// context
seq.nextMessageNumber(inSeqId, inMessageNumber, isLastMessage);
if (Boolean.TRUE.equals(msg.getContextualProperty(RMManager.WSRM_LAST_MESSAGE_PROPERTY))) {
// mark the message as the last one
seq.setLastMessage(true);
}
rmpsOut.setSequence(seq);
if (seq.isLastMessage()) {
source.setCurrent(null);
}
}
} else if (!MessageUtils.isRequestor(msg) && constants.getCreateSequenceAction().equals(action)) {
maps.getAction().setValue(constants.getCreateSequenceResponseAction());
} else if (isPartialResponse && action == null && isResponseToAction(msg, constants.getSequenceAckAction())) {
Collection<SequenceAcknowledgement> acks = rmpsIn != null ? rmpsIn.getAcks() : null;
if (acks != null && acks.size() == 1) {
SourceSequence ss = source.getSequence(acks.iterator().next().getIdentifier());
if (ss != null && ss.allAcknowledged()) {
setAction(maps, constants.getTerminateSequenceAction());
setTerminateSequence(msg, ss.getIdentifier(), protocol);
msg.remove(Message.EMPTY_PARTIAL_RESPONSE_MESSAGE);
// removing this sequence now. See the comment in SourceSequence.setAcknowledged()
source.removeSequence(ss);
}
}
}
// capture message if retransmission possible
if (isApplicationMessage && !isPartialResponse) {
OutputStream os = msg.getContent(OutputStream.class);
// message until connection is setup
if (!(os instanceof WriteOnCloseOutputStream)) {
WriteOnCloseOutputStream cached = new WriteOnCloseOutputStream(os);
msg.setContent(OutputStream.class, cached);
os = cached;
}
getManager().initializeInterceptorChain(msg);
// doneCaptureMessage(msg);
captureMessage(msg);
} else if (isLastMessage) {
// got either the rm11 CS or the rm10 empty LM
RMStore store = getManager().getStore();
if (null != store) {
store.persistOutgoing(rmpsOut.getSourceSequence(), null);
}
}
}
use of org.apache.cxf.ws.rm.v200702.SequenceAcknowledgement in project cxf by apache.
the class RMInInterceptorTest method testProcessAcknowledgments.
@Test
public void testProcessAcknowledgments() throws RMException {
interceptor = new RMInInterceptor();
manager = control.createMock(RMManager.class);
Source source = control.createMock(Source.class);
rme = control.createMock(RMEndpoint.class);
EasyMock.expect(rme.getSource()).andReturn(source).anyTimes();
interceptor.setManager(manager);
SequenceAcknowledgement ack1 = control.createMock(SequenceAcknowledgement.class);
SequenceAcknowledgement ack2 = control.createMock(SequenceAcknowledgement.class);
Collection<SequenceAcknowledgement> acks = new ArrayList<>();
acks.add(ack1);
acks.add(ack2);
EasyMock.expect(rmps.getAcks()).andReturn(acks);
Identifier id1 = control.createMock(Identifier.class);
EasyMock.expect(ack1.getIdentifier()).andReturn(id1);
SourceSequence ss1 = control.createMock(SourceSequence.class);
EasyMock.expect(source.getSequence(id1)).andReturn(ss1);
ss1.setAcknowledged(ack1);
EasyMock.expectLastCall();
Identifier id2 = control.createMock(Identifier.class);
EasyMock.expect(ack2.getIdentifier()).andReturn(id2);
EasyMock.expect(source.getSequence(id2)).andReturn(null);
control.replay();
try {
interceptor.processAcknowledgments(rme, rmps, ProtocolVariation.RM10WSA200408);
fail("Expected SequenceFault not thrown");
} catch (SequenceFault sf) {
assertEquals(RM10Constants.UNKNOWN_SEQUENCE_FAULT_QNAME, sf.getFaultCode());
}
}
use of org.apache.cxf.ws.rm.v200702.SequenceAcknowledgement in project cxf by apache.
the class SourceSequenceTest method acknowledge.
protected void acknowledge(SourceSequence seq, int... messageNumbers) throws RMException {
SequenceAcknowledgement ack = factory.createSequenceAcknowledgement();
int i = 0;
while (i < messageNumbers.length) {
SequenceAcknowledgement.AcknowledgementRange r = factory.createSequenceAcknowledgementAcknowledgementRange();
Long l = new Long(messageNumbers[i]);
r.setLower(l);
i++;
while (i < messageNumbers.length && (messageNumbers[i] - messageNumbers[i - 1]) == 1) {
i++;
}
Long u = new Long(messageNumbers[i - 1]);
r.setUpper(u);
ack.getAcknowledgementRange().add(r);
}
seq.setAcknowledged(ack);
}
use of org.apache.cxf.ws.rm.v200702.SequenceAcknowledgement in project cxf by apache.
the class RMProperties method addAck.
public void addAck(DestinationSequence seq) {
if (null == acks) {
acks = new ArrayList<>();
}
SequenceAcknowledgement ack = seq.getAcknowledgment();
acks.add(ack);
seq.acknowledgmentSent();
}
Aggregations