use of org.mule.runtime.api.notification.RoutingNotification in project mule by mulesoft.
the class EventCorrelator method process.
public CoreEvent process(CoreEvent event) throws RoutingException {
// the correlationId of the event's message
final String groupId = event.getCorrelationId();
if (logger.isTraceEnabled()) {
try {
logger.trace(format("Received async reply message for correlationID: %s%n%s%n%s", groupId, truncate(StringMessageUtils.toString(event.getMessage().getPayload().getValue()), 200, false), event.getMessage().toString()));
} catch (Exception e) {
// ignore
}
}
// spinloop for the EventGroup lookup
while (true) {
try {
if (isGroupAlreadyProcessed(groupId)) {
if (logger.isDebugEnabled()) {
logger.debug("An event was received for an event group that has already been processed, " + "this is probably because the async-reply timed out. GroupCorrelation Id is: " + groupId + ". Dropping event");
}
// Fire a notification to say we received this message
notificationFirer.dispatch(new RoutingNotification(event.getMessage(), event.getContext().getOriginatingLocation().getComponentIdentifier().getIdentifier().getNamespace(), MISSED_AGGREGATION_GROUP_EVENT));
return null;
}
} catch (ObjectStoreException e) {
throw new RoutingException(timeoutMessageProcessor, e);
}
// check for an existing group first
EventGroup group;
try {
group = this.getEventGroup(groupId);
} catch (ObjectStoreException e) {
throw new RoutingException(timeoutMessageProcessor, e);
}
// does the group exist?
if (group == null) {
// ..apparently not, so create a new one & add it
try {
EventGroup eventGroup = callback.createEventGroup(event, groupId);
eventGroup.initEventsStore(correlatorStore);
group = this.addEventGroup(eventGroup);
} catch (ObjectStoreException e) {
throw new RoutingException(timeoutMessageProcessor, e);
}
}
// ensure that only one thread at a time evaluates this EventGroup
synchronized (groupsLock) {
if (logger.isDebugEnabled()) {
logger.debug("Adding event to aggregator group: " + groupId);
}
// add the incoming event to the group
try {
group.addEvent(event);
} catch (ObjectStoreException e) {
throw new RoutingException(timeoutMessageProcessor, e);
}
// check to see if the event group is ready to be aggregated
if (callback.shouldAggregateEvents(group)) {
// create the response event
CoreEvent returnEvent = null;
try {
returnEvent = callback.aggregateEvents(group);
} catch (RoutingException routingException) {
try {
this.removeEventGroup(group);
group.clear();
} catch (ObjectStoreException objectStoreException) {
throw new RoutingException(timeoutMessageProcessor, objectStoreException);
}
throw routingException;
}
// for this group once we aggregate
try {
this.removeEventGroup(group);
group.clear();
} catch (ObjectStoreException e) {
throw new RoutingException(timeoutMessageProcessor, e);
}
return returnEvent;
} else {
return null;
}
}
}
}
use of org.mule.runtime.api.notification.RoutingNotification in project mule by mulesoft.
the class EventCorrelator method handleGroupExpiry.
protected void handleGroupExpiry(EventGroup group) throws MuleException {
try {
removeEventGroup(group);
} catch (ObjectStoreException e) {
throw new DefaultMuleException(e);
}
if (isFailOnTimeout()) {
CoreEvent messageCollectionEvent = group.getMessageCollectionEvent();
notificationFirer.dispatch(new RoutingNotification(messageCollectionEvent.getMessage(), null, CORRELATION_TIMEOUT));
try {
group.clear();
} catch (ObjectStoreException e) {
logger.warn("Failed to clear group with id " + group.getGroupId() + " since underlying ObjectStore threw Exception:" + e.getMessage());
}
throw new CorrelationTimeoutException(correlationTimedOut(group.getGroupId()));
} else {
if (logger.isDebugEnabled()) {
logger.debug(MessageFormat.format("Aggregator expired, but ''failOnTimeOut'' is false. Forwarding {0} events out of {1} " + "total for group ID: {2}", group.size(), group.expectedSize().map(v -> v.toString()).orElse(NOT_SET), group.getGroupId()));
}
try {
if (!(group.getCreated() + DAYS.toMillis(1) < currentTimeMillis())) {
CoreEvent newEvent = CoreEvent.builder(callback.aggregateEvents(group)).build();
group.clear();
if (!correlatorStore.contains((String) group.getGroupId(), getExpiredAndDispatchedPartitionKey())) {
// returned?
if (timeoutMessageProcessor != null) {
processToApply(newEvent, timeoutMessageProcessor, false, empty());
} else {
throw new MessagingException(createStaticMessage(MessageFormat.format("Group {0} timed out, but no timeout message processor was " + "configured.", group.getGroupId())), newEvent);
}
correlatorStore.store((String) group.getGroupId(), group.getCreated(), getExpiredAndDispatchedPartitionKey());
} else {
logger.warn(MessageFormat.format("Discarding group {0}", group.getGroupId()));
}
}
} catch (MessagingException me) {
throw me;
} catch (Exception e) {
throw new MessagingException(group.getMessageCollectionEvent(), e);
}
}
}
use of org.mule.runtime.api.notification.RoutingNotification in project mule by mulesoft.
the class AbstractAsyncRequestReplyRequester method receiveAsyncReply.
private PrivilegedEvent receiveAsyncReply(CoreEvent event) throws MuleException {
String asyncReplyCorrelationId = getAsyncReplyCorrelationId(event);
System.out.println("receiveAsyncReply: " + asyncReplyCorrelationId);
Latch asyncReplyLatch = getLatch(asyncReplyCorrelationId);
// flag for catching the interrupted status of the Thread waiting for a
// result
boolean interruptedWhileWaiting = false;
boolean resultAvailable = false;
PrivilegedEvent result;
try {
if (logger.isDebugEnabled()) {
logger.debug("Waiting for async reply message with id: " + asyncReplyCorrelationId);
}
// how long should we wait for the lock?
if (timeout <= 0) {
asyncReplyLatch.await();
resultAvailable = true;
} else {
resultAvailable = asyncReplyLatch.await(timeout, MILLISECONDS);
}
if (!resultAvailable) {
asyncReplyLatch.await(1000, MILLISECONDS);
resultAvailable = asyncReplyLatch.getCount() == 0;
}
} catch (InterruptedException e) {
interruptedWhileWaiting = true;
} finally {
locks.remove(asyncReplyCorrelationId);
result = responseEvents.remove(asyncReplyCorrelationId);
if (interruptedWhileWaiting) {
Thread.currentThread().interrupt();
return null;
}
}
if (resultAvailable) {
if (result == null) {
// this should never happen, just using it as a safe guard for now
throw new IllegalStateException("Response MuleEvent is null");
}
// Copy event because the async-reply message was received by a different
// receiver thread (or the senders dispatcher thread in case of vm
// with queueEvents="false") and the current thread may need to mutate
// the even. See MULE-4370
setCurrentEvent(result);
return result;
} else {
addProcessed(new ProcessedEvents(asyncReplyCorrelationId, EndReason.FINISHED_BY_TIMEOUT));
if (failOnTimeout) {
notificationFirer.dispatch(new RoutingNotification(event.getMessage(), null, ASYNC_REPLY_TIMEOUT));
throw new ResponseTimeoutException(responseTimedOutWaitingForId((int) timeout, asyncReplyCorrelationId), null);
} else {
return null;
}
}
}
Aggregations