/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.runtime.core.context.notification; import static org.mule.runtime.core.api.context.notification.EnrichedNotificationInfo.createInfo; import org.mule.runtime.api.component.location.ComponentLocation; import org.mule.runtime.core.api.MuleContext; import org.mule.runtime.core.api.Event; import org.mule.runtime.core.api.construct.FlowConstruct; import org.mule.runtime.core.api.context.notification.EnrichedNotificationInfo; import org.mule.runtime.core.api.context.notification.ServerNotification; import org.mule.runtime.core.api.context.notification.ServerNotificationHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; /** * Simple class to fire notifications of a specified type over a {@link ServerNotificationHandler}. * * When the notification is to be sent on the context of the processing of a {@link Event} (meaning, the method used to fire the * notification takes a {@link Event} argument), then this instance will delegate into a {@link ServerNotificationHandler} that * corresponds to the {@link MuleContext} of that event. When the notification does not relate to a particular {@link Event} (for * example, connection/reconnection/disconnection events), then a {@link #defaultNotificationHandler} will be used */ public class NotificationHelper { private static final Logger logger = LoggerFactory.getLogger(NotificationHelper.class); private final Class<? extends ServerNotification> notificationClass; private final boolean dynamicNotifications; private final ServerNotificationHandler defaultNotificationHandler; private final LoadingCache<MuleContext, ServerNotificationHandler> serverNotificationHandlers = CacheBuilder.newBuilder().build(new CacheLoader<MuleContext, ServerNotificationHandler>() { @Override public ServerNotificationHandler load(MuleContext muleContext) throws Exception { return adaptNotificationHandler(muleContext.getNotificationManager()); } }); /** * Creates a new {@link NotificationHelper} that emits instances of {@code notificationClass} class. * * @param defaultNotificationHandler The {@link ServerNotificationHandler} to be used on notifications which don't relate to a * {@link Event} * @param notificationClass The {@link Class} of the notifications to be fired by this helper * @param dynamicNotifications If {@code true}, notifications will be fired directly to a {@link ServerNotificationHandler} * responsible to decide to emit it or not. If {@code false} the notification will be checked to be enable or not at * creation time */ public NotificationHelper(ServerNotificationHandler defaultNotificationHandler, Class<? extends ServerNotification> notificationClass, boolean dynamicNotifications) { this.notificationClass = notificationClass; this.dynamicNotifications = dynamicNotifications; this.defaultNotificationHandler = adaptNotificationHandler(defaultNotificationHandler); } /** * Checks if the {@link #defaultNotificationHandler} is enabled to fire instances of {@link #notificationClass}. Use this method * when planning to fire a notification that is not related to a {@link Event} (connect/disconnect/etc). Otherwise, use * {@link #isNotificationEnabled(Event)} instead * * @return {@code true} if {@link #defaultNotificationHandler} is enabled for {@link #notificationClass} */ public boolean isNotificationEnabled() { return defaultNotificationHandler.isNotificationEnabled(notificationClass); } /** * Checks if the {@link ServerNotificationHandler} associated to the given {@code event} is enabled to fire instances of * {@link #notificationClass} * * @param muleContext the Mule node. * @return {@code true} if there is a {@link ServerNotificationHandler} enabled for {@link #notificationClass} */ public boolean isNotificationEnabled(MuleContext muleContext) { return getNotificationHandler(muleContext).isNotificationEnabled(notificationClass); } /** * Fires a {@link ConnectorMessageNotification} for the given arguments using the {@link ServerNotificationHandler} associated * to the given {@code event} and based on a {@link ComponentLocation}. * * @param source * @param event a {@link org.mule.runtime.core.api.Event} * @param flowConstruct the {@link org.mule.runtime.core.api.construct.FlowConstruct} that generated the notification * @param action the action code for the notification */ public void fireNotification(Object source, Event event, FlowConstruct flowConstruct, int action) { ServerNotificationHandler serverNotificationHandler = getNotificationHandler(flowConstruct.getMuleContext()); try { if (serverNotificationHandler.isNotificationEnabled(notificationClass)) { serverNotificationHandler .fireNotification(new ConnectorMessageNotification(createInfo(event, null, source), flowConstruct, action)); } } catch (Exception e) { logger.warn("Could not fire notification. Action: " + action, e); } } /** * Fires the given {@code notification} using the {@link #defaultNotificationHandler}. Use this method when the * {@code notification} is not related to any {@link Event} (for example, connect/disconnect/etc). Otherwise, use * {@link #fireNotification(ServerNotification, Event)} instead * * @param notification a {@link ServerNotification} */ public void fireNotification(ServerNotification notification) { defaultNotificationHandler.fireNotification(notification); } /** * Fires the given {@code notification} using the {@link ServerNotificationHandler} that corresponds to the given {@code event} * * @param notification a {@link ServerNotification} * @param muleContext the Mule node. */ public void fireNotification(ServerNotification notification, MuleContext muleContext) { getNotificationHandler(muleContext).fireNotification(notification); } private ServerNotificationHandler adaptNotificationHandler(ServerNotificationHandler serverNotificationHandler) { return dynamicNotifications ? serverNotificationHandler : new OptimisedNotificationHandler(serverNotificationHandler, notificationClass); } private ServerNotificationHandler getNotificationHandler(MuleContext muleContext) { return serverNotificationHandlers.getUnchecked(muleContext); } }