/** * Invoked by the Aggregate objects that are timed out, to signal timeout/completion of itself * * @param aggregate the timed out Aggregate that holds collected messages and properties */ public boolean completeAggregate(Aggregate aggregate) { boolean markedCompletedNow = false; boolean wasComplete = aggregate.isCompleted(); if (wasComplete) { return false; } if (log.isDebugEnabled()) { log.debug("Aggregation completed or timed out"); } // cancel the timer synchronized (this) { if (!aggregate.isCompleted()) { aggregate.cancel(); aggregate.setCompleted(true); markedCompletedNow = true; } } if (!markedCompletedNow) { return false; } MessageContext newSynCtx = getAggregatedMessage(aggregate); if (newSynCtx == null) { log.warn("An aggregation of messages timed out with no aggregated messages", null); return false; } else { // Get the aggregated message to the next mediator placed after the aggregate mediator // in the sequence if (newSynCtx.isContinuationEnabled()) { try { aggregate .getLastMessage() .setEnvelope(MessageHelper.cloneSOAPEnvelope(newSynCtx.getEnvelope())); } catch (AxisFault axisFault) { log.warn( "Error occurred while assigning aggregated message" + " back to the last received message context"); } } } aggregate.clear(); activeAggregates.remove(aggregate.getCorrelation()); if ((correlateExpression != null && !correlateExpression.toString().equals(aggregate.getCorrelation())) || correlateExpression == null) { if (onCompleteSequence != null) { ContinuationStackManager.addReliantContinuationState(newSynCtx, 0, getMediatorPosition()); boolean result = onCompleteSequence.mediate(newSynCtx); if (result) { ContinuationStackManager.removeReliantContinuationState(newSynCtx); } return result; } else if (onCompleteSequenceRef != null && newSynCtx.getSequence(onCompleteSequenceRef) != null) { ContinuationStackManager.updateSeqContinuationState(newSynCtx, getMediatorPosition()); return newSynCtx.getSequence(onCompleteSequenceRef).mediate(newSynCtx); } else { handleException( "Unable to find the sequence for the mediation " + "of the aggregated message", newSynCtx); } } return false; }
/** * Aggregate messages flowing through this mediator according to the correlation criteria and the * aggregation algorithm specified to it * * @param synCtx - MessageContext to be mediated and aggregated * @return boolean true if the complete condition for the particular aggregate is validated */ public boolean mediate(MessageContext synCtx) { if (synCtx.getEnvironment().isDebugEnabled()) { if (super.divertMediationRoute(synCtx)) { return true; } } SynapseLog synLog = getLog(synCtx); if (synLog.isTraceOrDebugEnabled()) { synLog.traceOrDebug("Start : Aggregate mediator"); if (synLog.isTraceTraceEnabled()) { synLog.traceTrace("Message : " + synCtx.getEnvelope()); } } try { Aggregate aggregate = null; String correlationIdName = (id != null ? EIPConstants.AGGREGATE_CORRELATION + "." + id : EIPConstants.AGGREGATE_CORRELATION); // if a correlateExpression is provided and there is a coresponding // element in the current message prepare to correlate the messages on that Object result = null; if (correlateExpression != null) { result = correlateExpression.evaluate(synCtx); if (result instanceof List) { if (((List) result).isEmpty()) { handleException( "Failed to evaluate correlate expression: " + correlateExpression.toString(), synCtx); } } } if (result != null) { while (aggregate == null) { synchronized (lock) { if (activeAggregates.containsKey(correlateExpression.toString())) { aggregate = activeAggregates.get(correlateExpression.toString()); if (aggregate != null) { if (!aggregate.getLock()) { aggregate = null; } } } else { if (synLog.isTraceOrDebugEnabled()) { synLog.traceOrDebug( "Creating new Aggregator - " + (completionTimeoutMillis > 0 ? "expires in : " + (completionTimeoutMillis / 1000) + "secs" : "without expiry time")); } Double minMsg = Double.parseDouble(minMessagesToComplete.evaluateValue(synCtx)); Double maxMsg = Double.parseDouble(maxMessagesToComplete.evaluateValue(synCtx)); aggregate = new Aggregate( synCtx.getEnvironment(), correlateExpression.toString(), completionTimeoutMillis, minMsg.intValue(), maxMsg.intValue(), this); if (completionTimeoutMillis > 0) { synCtx .getConfiguration() .getSynapseTimer() .schedule(aggregate, completionTimeoutMillis); } aggregate.getLock(); activeAggregates.put(correlateExpression.toString(), aggregate); } } } } else if (synCtx.getProperty(correlationIdName) != null) { // if the correlattion cannot be found using the correlateExpression then // try the default which is through the AGGREGATE_CORRELATION message property // which is the unique original message id of a split or iterate operation and // which thus can be used to uniquely group messages into aggregates Object o = synCtx.getProperty(correlationIdName); String correlation; if (o != null && o instanceof String) { correlation = (String) o; while (aggregate == null) { synchronized (lock) { if (activeAggregates.containsKey(correlation)) { aggregate = activeAggregates.get(correlation); if (aggregate != null) { if (!aggregate.getLock()) { aggregate = null; } } else { break; } } else { if (synLog.isTraceOrDebugEnabled()) { synLog.traceOrDebug( "Creating new Aggregator - " + (completionTimeoutMillis > 0 ? "expires in : " + (completionTimeoutMillis / 1000) + "secs" : "without expiry time")); } Double minMsg = -1.0; if (minMessagesToComplete != null) { minMsg = Double.parseDouble(minMessagesToComplete.evaluateValue(synCtx)); } Double maxMsg = -1.0; if (maxMessagesToComplete != null) { maxMsg = Double.parseDouble(maxMessagesToComplete.evaluateValue(synCtx)); } aggregate = new Aggregate( synCtx.getEnvironment(), correlation, completionTimeoutMillis, minMsg.intValue(), maxMsg.intValue(), this); if (completionTimeoutMillis > 0) { synchronized (aggregate) { if (!aggregate.isCompleted()) { synCtx .getConfiguration() .getSynapseTimer() .schedule(aggregate, completionTimeoutMillis); } } } aggregate.getLock(); activeAggregates.put(correlation, aggregate); } } } } else { synLog.traceOrDebug("Unable to find aggrgation correlation property"); return true; } } else { synLog.traceOrDebug("Unable to find aggrgation correlation XPath or property"); return true; } // if there is an aggregate continue on aggregation if (aggregate != null) { // this is a temporary fix synCtx.getEnvelope().build(); boolean collected = aggregate.addMessage(synCtx); if (synLog.isTraceOrDebugEnabled()) { if (collected) { synLog.traceOrDebug("Collected a message during aggregation"); if (synLog.isTraceTraceEnabled()) { synLog.traceTrace("Collected message : " + synCtx); } } } // check the completeness of the aggregate and if completed aggregate the messages // if not completed return false and block the message sequence till it completes if (aggregate.isComplete(synLog)) { synLog.traceOrDebug("Aggregation completed - invoking onComplete"); boolean onCompleteSeqResult = completeAggregate(aggregate); synLog.traceOrDebug("End : Aggregate mediator"); isAggregateComplete = onCompleteSeqResult; return onCompleteSeqResult; } else { aggregate.releaseLock(); } } else { // if the aggregation correlation cannot be found then continue the message on the // normal path by returning true synLog.traceOrDebug("Unable to find an aggregate for this message - skip"); return true; } } catch (JaxenException e) { handleException("Unable to execute the XPATH over the message", e, synCtx); } synLog.traceOrDebug("End : Aggregate mediator"); // When Aggregation is not completed return false to hold the flow return false; }