📄 eventplugin.java
字号:
/*------------------------------------------------------------------------------ Name: EventPlugin.java Project: xmlBlaster.org Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file ------------------------------------------------------------------------------*/package org.xmlBlaster.engine;import gnu.regexp.RE;import gnu.regexp.REException;import java.util.Map;import java.util.Set;import java.util.TreeSet;import java.util.logging.Logger;import java.util.logging.LogRecord;import java.util.logging.Level;import javax.mail.internet.InternetAddress;import javax.management.NotificationBroadcasterSupport;import org.xmlBlaster.util.Global;import org.xmlBlaster.util.I_EventDispatcher;import org.xmlBlaster.util.I_Timeout;import org.xmlBlaster.util.MsgUnit;import org.xmlBlaster.util.ReplaceVariable;import org.xmlBlaster.util.SessionName;import org.xmlBlaster.util.StringPairTokenizer;import org.xmlBlaster.util.Timeout;import org.xmlBlaster.util.XmlBlasterException;import org.xmlBlaster.util.XmlBuffer;import org.xmlBlaster.util.context.ContextNode;import org.xmlBlaster.util.def.Constants;import org.xmlBlaster.util.def.ErrorCode;import org.xmlBlaster.util.dispatch.ConnectionStateEnum;import org.xmlBlaster.util.dispatch.DispatchManager;import org.xmlBlaster.util.dispatch.I_ConnectionStatusListener;import org.xmlBlaster.util.key.MsgKeyData;import org.xmlBlaster.util.log.I_LogListener;import org.xmlBlaster.util.log.XbNotifyHandler;import org.xmlBlaster.util.plugin.I_PluginConfig;import org.xmlBlaster.util.plugin.PluginInfo;import org.xmlBlaster.util.plugin.I_Plugin;import org.xmlBlaster.util.protocol.email.EmailData;import org.xmlBlaster.util.protocol.email.SmtpClient;import org.xmlBlaster.util.qos.ClientProperty;import org.xmlBlaster.util.qos.MsgQosData;import org.xmlBlaster.util.qos.TopicProperty;import org.xmlBlaster.util.qos.storage.HistoryQueueProperty;import org.xmlBlaster.util.queue.QueueEventHandler;import org.xmlBlaster.util.queue.QueuePluginManager;import org.xmlBlaster.util.queue.StorageEventHandler;import org.xmlBlaster.util.Timestamp;import org.xmlBlaster.authentication.ClientEvent;import org.xmlBlaster.authentication.I_ClientListener;import org.xmlBlaster.authentication.SessionInfo;import org.xmlBlaster.authentication.SubjectInfo;import org.xmlBlaster.client.key.PublishKey;import org.xmlBlaster.client.qos.PublishQos;import org.xmlBlaster.engine.msgstore.MapEventHandler;import org.xmlBlaster.engine.msgstore.StoragePluginManager;import org.xmlBlaster.engine.runlevel.I_RunlevelListener;import org.xmlBlaster.engine.runlevel.RunlevelManager;/** * Registers for events from the xmlBlaster core and forwards them as * configured. * <p> * This is useful for clients or administrators to be notified on certain core events. * </p> * <p> * This <tt>EventPlugin</tt> plugin is started with the run level manager as * configured in <code>xmlBlasterPlugins.xml</code>, for example: * </p> * * <pre> *<plugin id='EventPlugin' className='org.xmlBlaster.engine.EventPlugin'> * <action do='LOAD' onStartupRunlevel='7' sequence='11' * onFail='resource.configuration.pluginFailed'/> * <action do='STOP' onShutdownRunlevel='6' sequence='11'/> * * <attribute id='eventTypes'> * logging/severe/*, * logging/warning/*, * service/RunlevelManager/event/startupRunlevel8, * client/joe/session/1/event/connect * </attribute> * * <attribute id='destination.smtp'> * mail.smtp.from=xmlBlaster@localhost, * mail.smtp.to=demo@localhost, * mail.collectMillis=10000 * </attribute> * <attribute id='destination.jmx'/> *</plugin> * </pre> * * <p> * In the above example an email is send if any logging/severe/* (==log/error) or logging/warning/* occurs. * Further an event is emitted on xmlBlaster startup in run level 8 * and if a new client logs in. * Those events are send as JMX notifications as well. * Adding <code><attribute id='destination.publish'/></code> would send * the event as a xmlBlaster message as well, but take care to not send logging events * as such messages will most certainly loop (if they log something they will trigger another message and so forth)! * </p> * <p> * List of supported event sources, note that this plugin must be active on * a runlevel early enough depending on the event you want to capture: * </p> * <table border="1"> * <tr><td>logging/severe/*</td><td>Captures all errors logged</td></tr> * <tr><td>logging/warning/*</td><td>Captures all warnings logged</td></tr> * <tr><td>service/RunlevelManager/event/startupRunlevel9</td><td>Captures event when startup run level reaches 9 (RUNNING), any other runlevel is possible as well (note that this plugin must be active beforehand)</td></tr> * <tr><td>service/RunlevelManager/event/shutdownRunlevel8</td><td>Captures event when shutdown runlevel reaches 8 (RUNNING_RPE), any other run level is possible as well (note that this plugin must be active beforehand)</td></tr> * <tr><td>client/* /session/* /event/connect</td><td>Captures event on client login (all clients)</td></tr> * <tr><td>client/[subjectId]/session/[publicSessionId]/event/connect</td><td>Captures event on given client login, e.g. "client/joe/session/1/event/connect"</td></tr> * <tr><td>client/* /session/* /event/disconnect</td><td>Captures event on client logout (all clients)</td></tr> * <tr><td>client/[subjectId]/session/[publicSessionId]/event/disconnect</td><td>Captures event on given client logout, e.g. "client/joe/session/1/event/disconnect"</td></tr> * <tr><td>topic/* /event/subscribe</td><td>Captures if subscribe() is invoked (on all topics)</td></tr> * <tr><td>topic/[topicId]/event/subscribe</td><td>Captures if subscribe() on the specified topic is invoked</td></tr> * <tr><td>client/[subjectId]/session/[publicSessionId]/event/subscribe</td><td>Captures if the given client has invoked subscribe(), e.g. "client/joe/session/1/event/subscribe". The publicSessionId can be a wildcard "*".</td></tr> * <tr><td>topic/* /event/unSubscribe</td><td>Captures if unSubscribe() is invoked (on all topics)</td></tr> * <tr><td>topic/[topicId]/event/unSubscribe</td><td>Captures if unSubscribe() on the specified topic is invoked</td></tr> * <tr><td>client/[subjectId]/session/[publicSessionId]/event/unSubscribe</td><td>Captures if the given client has invoked unSubscribe(), e.g. "client/joe/session/1/event/unSubscribe". The publicSessionId can be a wildcard "*".</td></tr> * <tr><td>topic/* /event/alive</td><td>Captures if a topic is created (on all topics)</td></tr> * <tr><td>topic/hello/event/alive</td><td>Captures event if the topic 'hello' is created</td></tr> * <tr><td>topic/* /event/dead</td><td>Captures if a topic is destroyed (on all topics)</td></tr> * <tr><td>topic/hello/event/dead</td><td>Captures event if the topic 'hello' is destroyed</td></tr> * <tr><td>client/[subjectId]/session/[publicSessionId]/event/callbackState</td><td>Captures event if the client callback server goes to ALIVE or POLLING. Note that the status change to DEAD is currently not implemented (it is reported as POLLING). Wildcards are not supported.</td></tr> * <tr><td>heartbeat.360000</td><td>Sends a heartbeat notification every given milli seconds. Setting <code>heartbeat</code> defaults to one notification per day (86400000 millis).</td></tr> * </table> * <p> * List of supported event sinks: * </p> * <table border="1"> * <tr> * <td>destination.smtp</td> * <td>Sends an email about the occurred event. * Collects multiple events to one mail depending on configuration. * You need to configure at least the email address parameters * <code>mail.stmp.from</code> and <code>mail.smtp.to</code> and * activate the <code>SmtpClient</code> plugin in <code>xmlBlasterPlugins.xml</code>. * If you have a reasonable email provider you can configure it to * forward the mail as an SMS (mine offers this feature).</td> * </tr> * <tr> * <td>destination.publish</td> * <td>Publishes an xmlBlaster message which contains the occurred event, * currently all messages are published into a topic named '__sys__Event'</td> * </tr> * <tr> * <td>destination.jmx</td> * <td>Emits an JMX notification for the occurred event. * Open 'jconsole' and 'MBeans->org.xmlBlaster->node->xxx->service->EventPlugin[yyy]' * there choose the 'Notifications[0]' tabulator and click the 'Subscribe' button. * Now you receive the configured events.</td> * </tr> * </table> * * <p> * We access the xmlBlaster core directly to register the supported internal * events, hence this plugin works only if it is in the same virtual * machine (JVM) as the xmlBlaster server. * </p> * <p> * All events don't throw any exceptions as this plugin should have * no influence on the regular work-flow of xmlBlaster. * </p> * * @author <a href="mailto:xmlblast@marcelruff.info">Marcel Ruff</a> * @see <a * href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/admin.events.html">The * admin.events requirement</a> */public class EventPlugin extends NotificationBroadcasterSupport implements I_Plugin, EventPluginMBean, I_ClientListener, I_RunlevelListener, I_LogListener, I_SubscriptionListener, I_TopicListener, I_ConnectionStatusListener, I_RemotePropertiesListener, I_EventDispatcher, Comparable { private final static String ME = EventPlugin.class.getName(); private static Logger log = Logger.getLogger(EventPlugin.class.getName()); /** My JMX registration */ private Object mbeanHandle; private ContextNode contextNode; protected Global glob; protected I_PluginConfig pluginConfig; protected org.xmlBlaster.engine.ServerScope engineGlob; protected RequestBroker requestBroker; protected SessionInfo sessionInfo; protected boolean isActive; protected boolean isShutdown; protected String eventTypes; protected Set loggingSet; protected Set runlevelSet; protected Set clientSet; protected Set topicSet; protected Set pendingCallbackSessionInfoSet; protected Set callbackSessionStateSet; protected static int staticInstanceCounter; protected int instanceCounter; private String uniqueInstanceName; /** * Helper class to send emails */ class SmtpDestinationHelper { SmtpClient smtpClient; String to, from, subjectTemplate, cc, bcc, contentTemplate, contentSeparator; long collectIntervall = Constants.DAY_IN_MILLIS / 2; public SmtpDestinationHelper(SmtpClient smtpClient, String destination) throws XmlBlasterException { this.smtpClient = smtpClient; Map map = StringPairTokenizer.parseLineToProperties(destination); if (map.containsKey("mail.smtp.to")) this.to = (String) map.get("mail.smtp.to"); verifyInternetAddress(this.to); if (map.containsKey("mail.smtp.from")) this.from = (String) map.get("mail.smtp.from"); if (this.from == null) this.from = "xmlBlaster@localhost"; verifyInternetAddress(this.from); // Each line of characters MUST be no more than 998 characters, // and SHOULD be no more than 78 characters, excluding the CRLF if (map.containsKey("mail.subject")) this.subjectTemplate = (String) map.get("mail.subject"); else this.subjectTemplate = "[XmlBlaster event: $_{eventType}] $_{nodeId}"; //this.subjectTemplate = "[XmlBlaster generated email] $_{nodeId} $_{summary}"; if (map.containsKey("mail.content")) this.contentTemplate = (String) map.get("mail.content"); else this.contentTemplate = "eventType: $_{eventType}\ninstanceId: $_{instanceId}\n\nsummary: $_{summary}\ndescription: $_{description}\n\neventDate: $_{datetime}\nversionInfo: $_{versionInfo}\n\n--\nhttp://www.xmlblaster.org/xmlBlaster/doc/requirements/admin.events.html"; if (map.containsKey("mail.contentSeparator")) this.contentSeparator = (String) map.get("mail.contentSeparator"); else this.contentSeparator = "\n\n========== NEXT ============\n\n"; if (map.containsKey("mail.smtp.cc")) this.cc = (String) map.get("mail.smtp.cc"); if (this.cc != null && this.cc.trim().length() > 0) verifyInternetAddress(this.cc); if (map.containsKey("mail.smtp.bcc")) this.bcc = (String) map.get("mail.smtp.bcc"); if (this.bcc != null && this.bcc.trim().length() > 0) verifyInternetAddress(this.bcc); if (map.containsKey("mail.collectMillis")) { String tmp = (String) map.get("mail.collectMillis"); this.collectIntervall = Long.valueOf(tmp.trim()).longValue(); } if (this.collectIntervall < 0) this.collectIntervall = 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -