You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by sa...@apache.org on 2012/11/19 18:05:12 UTC
svn commit: r1411310 - in
/airavata/trunk/modules/ws-messenger/message-monitor: ./ src/ src/main/
src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/airavata/ src/main/java/org/apache/airavata/ws/
src/main/java/org/apa...
Author: samindaw
Date: Mon Nov 19 17:05:10 2012
New Revision: 1411310
URL: http://svn.apache.org/viewvc?rev=1411310&view=rev
Log:
adding monitoring module
Added:
airavata/trunk/modules/ws-messenger/message-monitor/
airavata/trunk/modules/ws-messenger/message-monitor/pom.xml
airavata/trunk/modules/ws-messenger/message-monitor/src/
airavata/trunk/modules/ws-messenger/message-monitor/src/main/
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/EventFilter.java
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/Monitor.java
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorConfiguration.java
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorEvent.java
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorEventData.java
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorEventListener.java
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorException.java
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorUtil.java
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/WsmgClient.java
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/event/
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/event/Event.java
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/event/EventListener.java
airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/event/EventProducer.java
Added: airavata/trunk/modules/ws-messenger/message-monitor/pom.xml
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/ws-messenger/message-monitor/pom.xml?rev=1411310&view=auto
==============================================================================
--- airavata/trunk/modules/ws-messenger/message-monitor/pom.xml (added)
+++ airavata/trunk/modules/ws-messenger/message-monitor/pom.xml Mon Nov 19 17:05:10 2012
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under
+ the Apache License, Version 2.0 (theà "License"); you may not use this file except in compliance with the License. You may
+ obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to
+ in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+ ANY ~ KIND, either express or implied. See the License for the specific language governing permissions and limitations under
+ the License. -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <parent>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-ws-messenger</artifactId>
+ <version>0.6-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>airavata-message-monitor</artifactId>
+ <name>Airavata WS Monitor</name>
+ <url>http://airavata.apache.org/</url>
+ <packaging>jar</packaging>
+
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-workflow-model-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-messenger-commons</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-registry-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-common-utils</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>edu.berkeley</groupId>
+ <artifactId>yfilter</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>wsdl4j</groupId>
+ <artifactId>wsdl4j</artifactId>
+ <version>1.5.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transport-http</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transport-local</artifactId>
+ </dependency>
+
+ <!-- Logging -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-messenger-client</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ </dependencies>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ </properties>
+</project>
Added: airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/EventFilter.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/EventFilter.java?rev=1411310&view=auto
==============================================================================
--- airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/EventFilter.java (added)
+++ airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/EventFilter.java Mon Nov 19 17:05:10 2012
@@ -0,0 +1,27 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.ws.monitor;
+
+public interface EventFilter {
+
+ public boolean isAcceptable(MonitorEvent event);
+}
\ No newline at end of file
Added: airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/Monitor.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/Monitor.java?rev=1411310&view=auto
==============================================================================
--- airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/Monitor.java (added)
+++ airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/Monitor.java Mon Nov 19 17:05:10 2012
@@ -0,0 +1,246 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.ws.monitor;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.airavata.common.utils.XMLUtil;
+import org.apache.airavata.workflow.model.exceptions.WorkflowException;
+import org.apache.airavata.ws.monitor.event.Event;
+import org.apache.airavata.ws.monitor.event.EventProducer;
+import org.apache.airavata.ws.monitor.event.Event.Type;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xmlpull.infoset.XmlElement;
+
+public class Monitor extends EventProducer {
+
+ protected static final Logger logger = LoggerFactory.getLogger(Monitor.class);
+
+ protected MonitorConfiguration configuration;
+
+ protected static final String DEFAULT_MODEL_KEY = "_DEFAULT_MODEL_KEY";
+
+ protected Map<String, MonitorEventData> eventDataMap = new HashMap<String, MonitorEventData>();
+
+ protected WsmgClient wsmgClient;
+
+ protected boolean print;
+
+ protected long timeout = 20000L;
+
+ protected boolean status = false;
+
+ /**
+ * Constructs a Monitor.
+ *
+ * @param configuration
+ */
+ public Monitor(MonitorConfiguration configuration) {
+ this.configuration = configuration;
+ // The first one is special and it is for the main event panel display
+ // and
+ // it does not have and filters
+ this.eventDataMap.put(DEFAULT_MODEL_KEY, new MonitorEventData());
+
+
+ }
+
+ /**
+ * @return The configuration
+ */
+ public MonitorConfiguration getConfiguration() {
+ return this.configuration;
+ }
+
+ /**
+ * @return The event data;
+ */
+ public MonitorEventData getEventData() {
+ // send the first one cos that is the default one
+ return this.eventDataMap.get(DEFAULT_MODEL_KEY);
+ }
+
+ /**
+ * @return The event data;
+ */
+ public MonitorEventData getEventData(String nodeID) {
+ // send the first one cos that is the default one
+ return this.eventDataMap.get(nodeID);
+ }
+
+ /**
+ * @throws MonitorException
+ */
+ public synchronized void start() throws MonitorException {
+ // Stop the previous monitoring if any.
+ asynchronousStop();
+
+ subscribe();
+
+ if (null != this.configuration.getInteractiveNodeIDs()) {
+ List<String> interactiveNodeIDs = this.configuration.getInteractiveNodeIDs();
+ // now add models for this as well
+ for (String string : interactiveNodeIDs) {
+
+ final String nodeID = string;
+ // for each wsnode there is one data model which
+ this.eventDataMap.put(nodeID, new MonitorEventData(new EventFilter() {
+ /**
+ * @see org.apache.airavata.ws.monitor.EventFilter#isAcceptable(org.apache.airavata.ws.monitor.MonitorEvent)
+ */
+ public boolean isAcceptable(MonitorEvent event) {
+ return event != null && event.getNodeID() != null && event.getNodeID().equals(nodeID);
+ }
+ }));
+ }
+
+ }
+ }
+
+ public void startMonitoring(){
+ final Monitor m=this;
+ new Thread(){
+ @Override
+ public void run() {
+ try {
+ m.start();
+ } catch (MonitorException e) {
+ e.printStackTrace();
+ }
+ }
+ }.start();
+ }
+
+ /**
+ * Stops monitoring.
+ */
+ public synchronized void asynchronousStop() {
+ if (this.wsmgClient != null) {
+ // To make thread safe.
+ final WsmgClient client = this.wsmgClient;
+ this.wsmgClient = null;
+
+ // Users don't need to know the end of unsubscription.
+ new Thread() {
+ @Override
+ public void run() {
+ try {
+ unsubscribe(client);
+ } catch (WorkflowException e) {
+ // Ignore the error in unsubscription.
+ logger.error(e.getMessage(), e);
+ }
+ }
+ }.start();
+ }
+ }
+
+ /**
+ * Stops monitoring without using a thread.
+ *
+ * @throws MonitorException
+ */
+ public synchronized void stop() throws MonitorException {
+ if (this.wsmgClient != null) {
+ unsubscribe(this.wsmgClient);
+ this.wsmgClient = null;
+ }
+ }
+
+ /**
+ * Resets the graph and clear the monitoring table. Remove all the extra tablemodels available
+ */
+ public void reset() {
+ Set<String> keys = this.eventDataMap.keySet();
+ LinkedList<String> keysToBeRemoved = new LinkedList<String>();
+ // Remove everthing leaving only the last one
+ for (String key : keys) {
+ MonitorEventData monitorEventData = this.eventDataMap.get(key);
+ monitorEventData.removeAllEvents();
+ if (!key.equals(DEFAULT_MODEL_KEY)) {
+ keysToBeRemoved.add(key);
+ }
+ }
+ for (String key : keysToBeRemoved) {
+ this.eventDataMap.remove(key);
+ }
+
+ }
+
+ /**
+ * @param event
+ */
+ public synchronized void handleNotification(XmlElement event) {
+ Set<String> keys = this.eventDataMap.keySet();
+ // Remove everthing leaving only the last one
+ if(print){
+ System.out.println(XMLUtil.xmlElementToString(event));
+ }
+ for (String key : keys) {
+ this.eventDataMap.get(key).addEvent(event);
+ }
+ }
+
+ private void subscribe() throws MonitorException {
+ this.wsmgClient = new WsmgClient(this);
+ this.wsmgClient.setTimeout(this.getTimeout());
+ //Users can set the timeout and interval for the subscription using wsmg setter methods, here we use the default values
+ this.wsmgClient.subscribe();
+ this.status = true;
+
+ // Enable/disable some menu items and show the monitor panel.
+ sendSafeEvent(new Event(Type.MONITOR_STARTED));
+ }
+
+ private void unsubscribe(WsmgClient client) throws MonitorException {
+ // Enable/disable some menu items.
+ sendSafeEvent(new Event(Type.MONITOR_STOPED));
+
+ client.unsubscribe();
+ this.status = false;
+ }
+
+ public void setPrint(boolean print) {
+ this.print = print;
+ }
+
+ public long getTimeout() {
+ return timeout;
+ }
+
+ public void setTimeout(long timeout) {
+ this.timeout = timeout;
+ }
+
+ public boolean isStatus() {
+ return status;
+ }
+
+ public void setStatus(boolean status) {
+ this.status = status;
+ }
+}
\ No newline at end of file
Added: airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorConfiguration.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorConfiguration.java?rev=1411310&view=auto
==============================================================================
--- airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorConfiguration.java (added)
+++ airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorConfiguration.java Mon Nov 19 17:05:10 2012
@@ -0,0 +1,191 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.ws.monitor;
+
+import java.net.URI;
+import java.util.List;
+
+import org.apache.airavata.ws.monitor.event.Event;
+import org.apache.airavata.ws.monitor.event.EventProducer;
+import org.apache.airavata.ws.monitor.event.Event.Type;
+import org.apache.airavata.common.utils.StringUtil;
+
+public class MonitorConfiguration extends EventProducer implements Cloneable{
+
+ // private static final Logger logger = LoggerFactory.getLogger();
+
+ private URI brokerURL;
+
+ private String topic;
+
+ private boolean pullMode;
+
+ private URI messageBoxURL;
+
+ private List<String> interactiveNodeIDs = null;
+
+ /**
+ * Constructs a NotificationConfiguration.
+ *
+ * @param brokerURL
+ * @param topic
+ * @param pullMode
+ * @param messageBoxURL
+ */
+ public MonitorConfiguration(URI brokerURL, String topic, boolean pullMode, URI messageBoxURL) {
+ set(brokerURL, topic, pullMode, messageBoxURL);
+ }
+
+ /**
+ * @param brokerURL
+ * @param topic
+ * @param pullMode
+ * @param messageBoxURL
+ */
+ public void set(URI brokerURL, String topic, boolean pullMode, URI messageBoxURL) {
+ this.brokerURL = brokerURL;
+ this.topic = topic;
+ this.pullMode = pullMode;
+ this.messageBoxURL = messageBoxURL;
+ sendSafeEvent(new Event(Type.MONITOR_CONFIGURATION_CHANGED));
+ }
+
+ /**
+ * @param brokerURL
+ * The brokerLocation to set.
+ */
+ public void setBrokerURL(URI brokerURL) {
+ this.brokerURL = brokerURL;
+ sendSafeEvent(new Event(Type.MONITOR_CONFIGURATION_CHANGED));
+ }
+
+ /**
+ * Returns the URL of the notification broker.
+ *
+ * @return The URL of the notification broker
+ */
+ public URI getBrokerURL() {
+ return this.brokerURL;
+ }
+
+ /**
+ * @param topic
+ * The topic to set
+ */
+ public void setTopic(String topic) {
+ this.topic = StringUtil.trimAndNullify(topic);
+ sendSafeEvent(new Event(Type.MONITOR_CONFIGURATION_CHANGED));
+ }
+
+ /**
+ * @return The userId.
+ */
+ public String getTopic() {
+ return this.topic;
+ }
+
+ /**
+ * Returns the messageBoxUrl.
+ *
+ * @return The messageBoxUrl
+ */
+ public URI getMessageBoxURL() {
+ return this.messageBoxURL;
+ }
+
+ /**
+ * Sets messageBoxUrl.
+ *
+ * @param messageBoxURL
+ * The messageBoxUrl to set.
+ */
+ public void setMessageBoxURL(URI messageBoxURL) {
+ this.messageBoxURL = messageBoxURL;
+ sendSafeEvent(new Event(Type.MONITOR_CONFIGURATION_CHANGED));
+ }
+
+ /**
+ * Returns the pullMode.
+ *
+ * @return The pullMode
+ */
+ public boolean isPullMode() {
+ return this.pullMode;
+ }
+
+ /**
+ * Sets pullMode.
+ *
+ * @param pullMode
+ * The pullMode to set.
+ */
+ public void setPullMode(boolean pullMode) {
+ this.pullMode = pullMode;
+ sendSafeEvent(new Event(Type.MONITOR_CONFIGURATION_CHANGED));
+ }
+
+ /**
+ * @return true if the configuration is valid; false otherwise.
+ */
+ public boolean isValid() {
+ if (this.brokerURL == null) {
+ return false;
+ }
+ if (this.topic == null || this.topic.length() == 0) {
+ return false;
+ }
+ if (this.pullMode == true) {
+ if (this.messageBoxURL == null) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @see java.lang.Object#clone()
+ */
+ @Override
+ public MonitorConfiguration clone() {
+ return new MonitorConfiguration(this.brokerURL, this.topic, this.pullMode, this.messageBoxURL);
+ }
+
+ /**
+ * Returns the interactiveNodeIDs.
+ *
+ * @return The interactiveNodeIDs
+ */
+ public List<String> getInteractiveNodeIDs() {
+ return this.interactiveNodeIDs;
+ }
+
+ /**
+ * Sets interactiveNodeIDs.
+ *
+ * @param interactiveNodeIDs
+ * The interactiveNodeIDs to set.
+ */
+ public void setInteractiveNodeIDs(List<String> interactiveNodeIDs) {
+ this.interactiveNodeIDs = interactiveNodeIDs;
+ }
+
+}
\ No newline at end of file
Added: airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorEvent.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorEvent.java?rev=1411310&view=auto
==============================================================================
--- airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorEvent.java (added)
+++ airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorEvent.java Mon Nov 19 17:05:10 2012
@@ -0,0 +1,174 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.ws.monitor;
+
+import java.net.URI;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.airavata.ws.monitor.MonitorUtil.EventType;
+import org.xmlpull.infoset.XmlElement;
+
+public class MonitorEvent {
+
+ private String timeText;
+
+ private Date timestamp;
+
+ private String idText;
+
+ private String statusText;
+
+ private String message;
+
+ private XmlElement event;
+
+ private EventType type;
+
+ private URI workflowID;
+
+ private String nodeID;
+
+ private String experimentID;
+
+ /**
+ * Constructs a MonitorEvent.
+ *
+ * @param event
+ */
+ public MonitorEvent(XmlElement event) {
+ this.event = event;
+ parse();
+ }
+
+ /**
+ * Returns the event.
+ *
+ * @return The event
+ */
+ public XmlElement getEvent() {
+ return this.event;
+ }
+
+ /**
+ * Returns the idText.
+ *
+ * @return The idText
+ */
+ public String getIDText() {
+ return this.idText;
+ }
+
+ /**
+ * Returns the message.
+ *
+ * @return The message
+ */
+ public String getMessage() {
+ return this.message;
+ }
+
+ /**
+ * Returns the statusText.
+ *
+ * @return The statusText
+ */
+ public String getStatusText() {
+ return this.statusText;
+ }
+
+ /**
+ * Returns the timeText.
+ *
+ * @return The timeText
+ */
+ public String getTimeText() {
+ return this.timeText;
+ }
+
+ /**
+ * Returns the type.
+ *
+ * @return The type
+ */
+ public EventType getType() {
+ return this.type;
+ }
+
+ /**
+ * Returns the workflowID.
+ *
+ * @return The workflowID
+ */
+ public URI getWorkflowID() {
+ return this.workflowID;
+ }
+
+ /**
+ * Returns the nodeID.
+ *
+ * @return The nodeID
+ */
+ public String getNodeID() {
+ return this.nodeID;
+ }
+
+ private void parse() {
+ this.type = MonitorUtil.getType(this.event);
+ this.workflowID = MonitorUtil.getWorkflowID(this.event);
+ this.nodeID = MonitorUtil.getNodeID(this.event);
+ this.experimentID = MonitorUtil.getExperiementID(this.event);
+ timestamp = MonitorUtil.getTimestamp(this.event);
+
+ if (timestamp != null) {
+ SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss.S MM/dd/yy ");
+ this.timeText = format.format(timestamp);
+ } else {
+ this.timeText = "";
+ }
+
+ this.idText = this.nodeID;
+
+ this.statusText = MonitorUtil.getStatus(this.event);
+
+ this.message = MonitorUtil.getMessage(this.event);
+ if (this.type == MonitorUtil.EventType.PUBLISH_URL) {
+ String location = MonitorUtil.getLocation(this.event);
+ // should be looked into
+ // String url = PREFIX + location + SUFFIX;
+ String url = location;
+ this.message = "<html>" + this.message + ": " + "<a href=\"" + url + "\">" + url + " </a></html>";
+ }
+ }
+
+ public Date getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(Date timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public String getExperimentID() {
+ return experimentID;
+ }
+}
\ No newline at end of file
Added: airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorEventData.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorEventData.java?rev=1411310&view=auto
==============================================================================
--- airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorEventData.java (added)
+++ airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorEventData.java Mon Nov 19 17:05:10 2012
@@ -0,0 +1,451 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.ws.monitor;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.swing.BoundedRangeModel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.TableModel;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xmlpull.infoset.XmlElement;
+
+public class MonitorEventData implements TableModel, BoundedRangeModel {
+
+ /**
+ * Column
+ */
+ public static enum Column {
+ /**
+ * TIME
+ */
+ TIME("Time"),
+ /**
+ * ID
+ */
+ ID("Component"),
+ /**
+ * STATUS
+ */
+ STATUS("Status"),
+ /**
+ * MESSAGE
+ */
+ MESSAGE("Message");
+
+ private String name;
+
+ private Column(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @return The name.
+ */
+ public String getName() {
+ return this.name;
+ }
+ }
+
+ private static final Logger logger = LoggerFactory.getLogger(MonitorEventData.class);
+
+ private List<TableModelListener> tableModelListeners;
+
+ private List<ChangeListener> sliderModelListeners;
+
+ private List<MonitorEvent> events;
+
+ private int sliderValue;
+
+ private boolean sliderAdjusting;
+
+ private ChangeEvent tableModelChangeEvent;
+
+ private EventFilter filter;
+
+ private List<MonitorEventListener> monitorEventListerners;
+
+ /**
+ *
+ * Constructs a MonitorEventData.
+ *
+ */
+ public MonitorEventData() {
+ this(null);
+ }
+
+ /**
+ * Constructs a NotificationTableModel.
+ */
+ public MonitorEventData(EventFilter filter) {
+ this.filter = filter;
+ this.tableModelListeners = new LinkedList<TableModelListener>();
+ this.sliderModelListeners = new LinkedList<ChangeListener>();
+ this.tableModelChangeEvent = new ChangeEvent(this); // We only need one.
+ this.events = new ArrayList<MonitorEvent>();
+ }
+
+ /**
+ * @param message
+ */
+ public void addEvent(XmlElement message) {
+ MonitorEvent event = new MonitorEvent(message);
+ // no need the check for not null because second clause is evaluated only if
+ // not null
+ if (this.filter == null || this.filter.isAcceptable(event)) {
+ boolean sliderMax = (this.sliderValue == this.events.size());
+
+ this.events.add(event);
+
+ if (sliderMax) {
+ // Move the slider to the max
+ this.sliderValue = this.events.size();
+
+ // The new event shows up on the table only when the slider is
+ // max.
+ TableModelEvent tableEvent = new TableModelEvent(this, this.sliderValue - 1, this.sliderValue,
+ TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT);
+ fireTableChanged(tableEvent);
+ }
+
+ // The muxmum of the slider changed regardless whether we move the
+ // slider or not.
+ fireSliderChanged();
+ for (MonitorEventListener listener : getMonitorEventListerners()) {
+ try {
+ listener.notify(this, event);
+ } catch (Exception e) {
+ //just in case
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ }
+
+ /**
+ * @return All events.
+ */
+ public List<MonitorEvent> getEvents() {
+ return this.events;
+ }
+
+ /**
+ * Returns a notification at a specified row.
+ *
+ * @param index
+ * The specified row.
+ * @return The notification at the specified row
+ */
+ public MonitorEvent getEvent(int index) {
+ return this.events.get(index);
+ }
+
+ /**
+ * @return The number of events.
+ */
+ public int getEventSize() {
+ return this.events.size();
+ }
+
+ /**
+ * Clears the notifications.
+ */
+ public void removeAllEvents() {
+ int size = this.events.size();
+ this.events.clear();
+
+ this.sliderValue = 0;
+
+ TableModelEvent event = new TableModelEvent(this, 0, Math.max(0, size - 1), TableModelEvent.ALL_COLUMNS,
+ TableModelEvent.DELETE);
+ fireTableChanged(event);
+
+ // The muxmum of the slider changed.
+ fireSliderChanged();
+ }
+
+ // methods implementing TableModel interface.
+
+ /**
+ * @see javax.swing.table.TableModel#getRowCount()
+ */
+ public int getRowCount() {
+ // Only show the events up to the slider value.
+ return this.sliderValue;
+ }
+
+ /**
+ * @see javax.swing.table.TableModel#getColumnCount()
+ */
+ public int getColumnCount() {
+ return Column.values().length;
+ }
+
+ /**
+ * @see javax.swing.table.TableModel#getColumnName(int)
+ */
+ public String getColumnName(int columnIndex) {
+ Column[] columns = Column.values();
+ if (columnIndex < 0 || columnIndex >= columns.length) {
+ // Should not happen.
+ throw new IllegalArgumentException("columnIndex has be be between 0 to " + columns.length);
+ }
+ return columns[columnIndex].getName();
+ }
+
+ /**
+ * @see javax.swing.table.TableModel#getColumnClass(int)
+ */
+ public Class<?> getColumnClass(int columnIndex) {
+ return String.class;
+ }
+
+ /**
+ * @see javax.swing.table.TableModel#isCellEditable(int, int)
+ */
+ public boolean isCellEditable(int rowIndex, int columnIndex) {
+ return false;
+ }
+
+ /**
+ * @see javax.swing.table.TableModel#getValueAt(int, int)
+ */
+ public Object getValueAt(int rowIndex, int columnIndex) {
+ String value;
+ try {
+ MonitorEvent event = this.events.get(rowIndex);
+ value = getTextAt(event, columnIndex);
+ } catch (RuntimeException e) {
+ // This should not happen, but if it happens it blocks the UI.
+ // That's why catching it.
+ logger.error(e.getMessage(), e);
+ value = "Error";
+ }
+ return value;
+ }
+
+ /**
+ * @see javax.swing.table.TableModel#setValueAt(java.lang.Object, int, int)
+ */
+ public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @see javax.swing.table.TableModel#addTableModelListener(javax.swing.event.TableModelListener)
+ */
+ public void addTableModelListener(TableModelListener listener) {
+ this.tableModelListeners.add(listener);
+ }
+
+ /**
+ * @see javax.swing.table.TableModel#removeTableModelListener(javax.swing.event.TableModelListener)
+ */
+ public void removeTableModelListener(TableModelListener listener) {
+ this.tableModelListeners.remove(listener);
+ }
+
+ // methods implementing BoundedRangeModel interface.
+
+ /**
+ * @see javax.swing.BoundedRangeModel#getExtent()
+ */
+ public int getExtent() {
+ return 0;
+ }
+
+ /**
+ * @see javax.swing.BoundedRangeModel#setExtent(int)
+ */
+ public void setExtent(int newExtent) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @see javax.swing.BoundedRangeModel#getMaximum()
+ */
+ public int getMaximum() {
+ return getEventSize();
+ }
+
+ /**
+ * @see javax.swing.BoundedRangeModel#setMaximum(int)
+ */
+ public void setMaximum(int newMaximum) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @see javax.swing.BoundedRangeModel#getMinimum()
+ */
+ public int getMinimum() {
+ return 0;
+ }
+
+ /**
+ * @see javax.swing.BoundedRangeModel#setMinimum(int)
+ */
+ public void setMinimum(int newMinimum) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @see javax.swing.BoundedRangeModel#getValue()
+ */
+ public int getValue() {
+ return this.sliderValue;
+ }
+
+ /**
+ * @see javax.swing.BoundedRangeModel#setValue(int)
+ */
+ public void setValue(int newValue) {
+ if (this.sliderValue == newValue) {
+ return;
+ }
+
+ // Correct the value to be withing the range.
+ if (newValue < 0) {
+ newValue = 0;
+ }
+ if (newValue > this.events.size()) {
+ newValue = this.events.size();
+ }
+
+ int oldRowCount = this.sliderValue;
+ this.sliderValue = newValue;
+
+ TableModelEvent event;
+ if (oldRowCount < this.sliderValue) {
+ event = new TableModelEvent(this, oldRowCount, this.sliderValue, TableModelEvent.ALL_COLUMNS,
+ TableModelEvent.INSERT);
+ } else {
+ event = new TableModelEvent(this, this.sliderValue, oldRowCount, TableModelEvent.ALL_COLUMNS,
+ TableModelEvent.DELETE);
+ }
+ fireTableChanged(event);
+ fireSliderChanged();
+ }
+
+ /**
+ * @see javax.swing.BoundedRangeModel#getValueIsAdjusting()
+ */
+ public boolean getValueIsAdjusting() {
+ return this.sliderAdjusting;
+ }
+
+ /**
+ * @see javax.swing.BoundedRangeModel#setValueIsAdjusting(boolean)
+ */
+ public void setValueIsAdjusting(boolean adjusting) {
+ this.sliderAdjusting = adjusting;
+ fireSliderChanged();
+ }
+
+ /**
+ * @see javax.swing.BoundedRangeModel#setRangeProperties(int, int, int, int, boolean)
+ */
+ public void setRangeProperties(int value, int extent, int min, int max, boolean adjusting) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @see javax.swing.BoundedRangeModel#addChangeListener(javax.swing.event.ChangeListener)
+ */
+ public void addChangeListener(ChangeListener listener) {
+ this.sliderModelListeners.add(listener);
+ }
+
+ /**
+ * @see javax.swing.BoundedRangeModel#removeChangeListener(javax.swing.event.ChangeListener)
+ */
+ public void removeChangeListener(ChangeListener listener) {
+ this.sliderModelListeners.remove(listener);
+ }
+
+ private String getTextAt(MonitorEvent event, int columnIndex) {
+ Column[] columns = Column.values();
+ if (columnIndex < 0 || columnIndex >= columns.length) {
+ // Should not happen.
+ throw new IllegalArgumentException("columnIndex has be be between 0 to " + columns.length);
+ }
+ Column column = columns[columnIndex];
+ String value;
+ switch (column) {
+ case TIME:
+ value = event.getTimeText();
+ break;
+ case ID:
+ value = event.getIDText();
+ break;
+ case STATUS:
+ value = event.getStatusText();
+ break;
+ case MESSAGE:
+ value = event.getMessage();
+ break;
+ default:
+ // Should not happen.
+ throw new IllegalArgumentException("columnIndex has be be between 0 to " + columns.length);
+ }
+ return value;
+ }
+
+ private void fireTableChanged(TableModelEvent event) {
+ for (TableModelListener listener : this.tableModelListeners) {
+ listener.tableChanged(event);
+ }
+ }
+
+ private void fireSliderChanged() {
+ for (ChangeListener listener : this.sliderModelListeners) {
+ listener.stateChanged(this.tableModelChangeEvent);
+ }
+ }
+ private List<MonitorEventListener> getMonitorEventListerners() {
+ if (monitorEventListerners==null){
+ monitorEventListerners=new ArrayList<MonitorEventListener>();
+ }
+ return monitorEventListerners;
+ }
+
+ public void registerEventListener(MonitorEventListener listener){
+ if (listener!=null) {
+ getMonitorEventListerners().add(listener);
+ }
+ }
+
+ public void unregisterEventListener(MonitorEventListener listener){
+ if (getMonitorEventListerners().contains(listener)) {
+ getMonitorEventListerners().remove(listener);
+ }
+ }
+}
\ No newline at end of file
Added: airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorEventListener.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorEventListener.java?rev=1411310&view=auto
==============================================================================
--- airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorEventListener.java (added)
+++ airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorEventListener.java Mon Nov 19 17:05:10 2012
@@ -0,0 +1,26 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.ws.monitor;
+
+public interface MonitorEventListener {
+ public void notify(MonitorEventData eventData, MonitorEvent event);
+}
Added: airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorException.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorException.java?rev=1411310&view=auto
==============================================================================
--- airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorException.java (added)
+++ airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorException.java Mon Nov 19 17:05:10 2012
@@ -0,0 +1,62 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.ws.monitor;
+
+import org.apache.airavata.workflow.model.exceptions.WorkflowException;
+
+public class MonitorException extends WorkflowException {
+
+ /**
+ * Constructs a MonitorException.
+ */
+ public MonitorException() {
+ super();
+ }
+
+ /**
+ * Constructs a MonitorException.
+ *
+ * @param message
+ */
+ public MonitorException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a MonitorException.
+ *
+ * @param cause
+ */
+ public MonitorException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructs a MonitorException.
+ *
+ * @param message
+ * @param cause
+ */
+ public MonitorException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
Added: airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorUtil.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorUtil.java?rev=1411310&view=auto
==============================================================================
--- airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorUtil.java (added)
+++ airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/MonitorUtil.java Mon Nov 19 17:05:10 2012
@@ -0,0 +1,627 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.ws.monitor;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Date;
+
+import org.apache.airavata.common.utils.XMLUtil;
+import org.apache.airavata.workflow.model.exceptions.WorkflowRuntimeException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xmlpull.infoset.XmlElement;
+import org.xmlpull.infoset.XmlNamespace;
+
+import atomixmiser.DcDate;
+
+/**
+ * Manipulate XML Events
+ */
+public class MonitorUtil {
+
+ private static final Logger logger = LoggerFactory.getLogger(MonitorUtil.class);
+
+ /**
+ * Workflow tracking namespace
+ */
+ public static final XmlNamespace WOR_NS = XMLUtil.BUILDER.newNamespace("wor",
+ "http://airavata.apache.org/schemas/workflow_tracking_types");
+
+ /**
+ * XBaya events namespace
+ */
+ public static final XmlNamespace XBAYA_EVENTS_NS = XMLUtil.BUILDER.newNamespace("xbaya",
+ "http://www.extreme.indiana.edu/xgws/xbaya/ns/2006/");
+
+ /**
+ * gotResult
+ */
+ public static final String GOT_RESULT_EVENT_TAG = "receivedResult";
+
+ /**
+ * description
+ */
+ public static final String DESCRIPTION_TAG = "description";
+
+ /**
+ * timestamp
+ */
+ public static final String TIMESTAMP_TAG = "timestamp";
+
+ /**
+ * request
+ *
+ * In invokingService
+ */
+ public static final String REQUEST = "request";
+
+ /**
+ * result
+ *
+ * In sendingResult
+ */
+ public static final String RESULT = "result";
+
+ /**
+ * body
+ *
+ * In sendingResult
+ */
+ public static final String BODY = "body";
+
+ /**
+ * experimentID
+ * In Notification Message
+ */
+ public static final String WORKFLOW_EXPERIMENT_ID = "experimentID";
+ /**
+ * workflowID
+ *
+ * workflow instance ID.
+ */
+ private static final String WORKFLOW_ID_ATTRIBUTE = "workflowID";
+
+ /**
+ * serviceID
+ *
+ * In workflowInitialized notification, this is the worklfow instance ID.
+ */
+ private static final String SERVICE_ID_ATTRIBUTE = "serviceID";
+
+ /**
+ * workflowNodeID
+ *
+ * Node ID.
+ */
+ private static final String WORKFLOW_NODE_ID_ATTRIBUTE = "workflowNodeID";
+
+ /**
+ * receiver
+ *
+ * Extract a node ID from here when a notification is sent by a workflow when the workflow is sending a message to a
+ * service.
+ */
+ private static final String RECEIVER_TAG = "receiver";
+
+ /**
+ * responder
+ *
+ * Extract a node ID from here when a notification is sent by a workflow when the workflow is receiving a message
+ * from a service.
+ */
+ private static final String RESPONDER_TAG = "responder";
+
+ /**
+ * notificationSource
+ *
+ * Extract a node ID from here when a service sends notification.
+ */
+ private static final String NOTIFICATION_SOURCE_TAG = "notificationSource";
+
+ // Followings are specific to some event types.
+
+ /**
+ * location
+ *
+ * In publishURL
+ */
+ private static final String LOCATION_TAG = "location";
+
+ /**
+ * retryStatusCount
+ *
+ * In computationDuration
+ */
+ private static final String RETRY_STATUS_COUNT_TAG = "retryStatusCount";
+
+ /**
+ * mappedResource
+ *
+ * In resourceMapping
+ */
+ private static final String MAPPED_RESOURCE_TAG = "mappedResource";
+
+ /**
+ * dataProduct
+ *
+ * In a couple of data-related notifications.
+ */
+ private static final String DATA_PRODUCT_TAG = "dataProduct";
+
+ /**
+ * durationInMillis
+ *
+ * In computationDuration
+ */
+ @SuppressWarnings("unused")
+ private static final String DURATION_IN_MILLS_TAG = "durationInMillis";
+
+ /**
+ * Type of the notification event.
+ */
+ public enum EventType {
+ /**
+ * unknown
+ */
+ UNKNOWN("unknown"),
+
+ // Notification from a workflow
+
+ /**
+ * workflowInitialized
+ */
+ WORKFLOW_INITIALIZED("workflowInitialized"),
+
+ /**
+ * workflowInvoked
+ */
+ WORKFLOW_INVOKED("workflowInvoked"),
+
+ /**
+ * workflowTerminated
+ */
+ WORKFLOW_TERMINATED("workflowTerminated"),
+
+ /**
+ * invokingService
+ */
+ INVOKING_SERVICE("invokingService"),
+
+ /**
+ * invokingServiceSucceeded
+ */
+ INVOKING_SERVICE_SUCCEEDED("invokingServiceSucceeded"),
+
+ /**
+ * invokingServiceFailed
+ */
+ INVOKING_SERVICE_FAILED("invokingServiceFailed"),
+
+ /**
+ * receivedResult
+ */
+ RECEIVED_RESULT("receivedResult"),
+
+ /**
+ * receivedFault
+ */
+ RECEIVED_FAULT("receivedFault"),
+
+ // Notification from a service
+
+ /**
+ * serviceInvoked
+ */
+ SERVICE_INVOKED("serviceInvoked"),
+
+ /**
+ * sendingResult
+ */
+ SENDING_RESULT("sendingResult"),
+
+ /**
+ * sendingResponseFailed
+ */
+ SENDING_RESPONSE_FAILED("sendingResponseFailed"),
+
+ /**
+ * sendingFault
+ */
+ SENDING_FAULT("sendingFault"),
+
+ // Other types of notification from a service.
+ /**
+ * logInfo
+ */
+ LOG_INFO("logInfo"),
+
+ /**
+ * logException
+ */
+ LOG_EXCEPTION("logException"),
+
+ /**
+ * logWarning
+ */
+ LOG_WARNING("logWarning"),
+
+ /**
+ * logDebug
+ */
+ LOG_DEBUG("logDebug"),
+
+ /**
+ * dataConsumed
+ */
+ DATA_CONSUMED("dataConsumed"),
+
+ /**
+ * dataProduced
+ */
+ DATA_PRODUCED("dataProduced"),
+
+ /**
+ * dataReceiveDuration
+ */
+ DATA_RECEIVE_DURATION("dataReceiveDuration"),
+
+ /**
+ * applicationAudit
+ */
+ APPLICATION_AUDIT("applicationAudit"),
+
+ /**
+ * computationDuration
+ */
+ COMPUTATION_DURATION("computationDuration"),
+
+ /**
+ * publishURL
+ */
+ PUBLISH_URL("publishURL"),
+
+ /**
+ * resourceMapping
+ */
+ RESOURCE_MAPPING("resourceMapping");
+
+ String name;
+
+ EventType(String name) {
+ this.name = name;
+ }
+ }
+
+ /**
+ * @param event
+ * @return The type of the event.
+ */
+ public static EventType getType(XmlElement event) {
+ if (event == null) {
+ throw new IllegalArgumentException("null");
+ }
+ XmlNamespace ns = event.getNamespace();
+ String name = event.getName();
+ if (XBAYA_EVENTS_NS.equals(ns)) {
+ if (GOT_RESULT_EVENT_TAG.equals(name)) {
+ return EventType.WORKFLOW_TERMINATED;
+ } else {
+ return EventType.UNKNOWN;
+ }
+ } else if (WOR_NS.equals(ns)) {
+ for (EventType type : EventType.values()) {
+ if (type.name.equals(name)) {
+ return type;
+ }
+ }
+ }
+ return EventType.UNKNOWN;
+ }
+
+ /**
+ * @param event
+ * @return The timestamp.
+ */
+ public static Date getTimestamp(XmlElement event) {
+ if (event == null) {
+ throw new IllegalArgumentException("null");
+ }
+ XmlElement timestampEl = event.element(WOR_NS, TIMESTAMP_TAG);
+ if (timestampEl == null)
+ return null;
+ String timestamp = timestampEl.requiredText();
+ DcDate date = DcDate.create(timestamp);
+ return new Date(date.getTimeInMillis());
+ }
+
+ /**
+ * @param event
+ * @return The node ID if the message contains it; "", otherwise
+ */
+ public static String getNodeID(XmlElement event) {
+ if (event == null) {
+ throw new IllegalArgumentException("null");
+ }
+ XmlElement idElement = getIDElement(event);
+ String nodeID = null;
+ if (idElement != null) {
+ nodeID = idElement.attributeValue(WOR_NS, WORKFLOW_NODE_ID_ATTRIBUTE);
+ }
+ if(nodeID == null){
+ nodeID = event.element(NOTIFICATION_SOURCE_TAG).attributeValue(WOR_NS, WORKFLOW_NODE_ID_ATTRIBUTE);
+ }
+ if (nodeID == null) {
+ nodeID = "";
+ }
+ return nodeID;
+ }
+
+ /**
+ * @param event
+ * @return The node ID if the message contains it; "", otherwise
+ */
+ public static String getExperiementID(XmlElement event) {
+ if (event == null) {
+ throw new IllegalArgumentException("null");
+ }
+ XmlElement idElement = event.element(WOR_NS,NOTIFICATION_SOURCE_TAG);
+ String nodeID = null;
+ if (idElement != null) {
+ nodeID = idElement.attributeValue(WOR_NS, WORKFLOW_EXPERIMENT_ID);
+ }if(nodeID == null){
+ nodeID = event.element(NOTIFICATION_SOURCE_TAG).attributeValue(WOR_NS, WORKFLOW_EXPERIMENT_ID);
+ }
+ if (nodeID == null) {
+ nodeID = "";
+ }
+ return nodeID;
+ }
+
+ /**
+ * @param event
+ * @return The workflow instance ID. null if there is no workflow instance ID.
+ */
+ public static URI getWorkflowID(XmlElement event) {
+ if (event == null) {
+ throw new IllegalArgumentException("null");
+ }
+ EventType type = getType(event);
+ XmlElement idElement = getIDElement(event);
+ if (idElement == null) {
+ return null;
+ }
+
+ String workflowID;
+ switch (type) {
+ case WORKFLOW_INITIALIZED:
+ case WORKFLOW_TERMINATED:
+ // Special cases
+ workflowID = idElement.attributeValue(WOR_NS, SERVICE_ID_ATTRIBUTE);
+ break;
+ default:
+ // Default
+ workflowID = idElement.attributeValue(WOR_NS, WORKFLOW_ID_ATTRIBUTE);
+ break;
+ }
+ if (workflowID == null || workflowID.length() == 0) {
+ return null;
+ }
+ try {
+ return new URI(workflowID);
+ } catch (URISyntaxException e) {
+ logger.error(e.getMessage(), e);
+ return null;
+ }
+ }
+
+ /**
+ * @param event
+ * @return The type of the event to display
+ */
+ public static String getStatus(XmlElement event) {
+ if (event == null) {
+ throw new IllegalArgumentException("null");
+ }
+ EventType type = getType(event);
+ String status;
+ switch (type) {
+ case LOG_INFO:
+ status = "INFO";
+ break;
+ case LOG_EXCEPTION:
+ status = "EXCEPTION";
+ break;
+ case LOG_WARNING:
+ status = "WARNING";
+ break;
+ case LOG_DEBUG:
+ status = "DEBUG";
+ break;
+ default:
+ status = event.getName();
+ }
+ return status;
+ }
+
+ /**
+ * @param event
+ * @return The message to display.
+ */
+ public static String getMessage(XmlElement event) {
+ if (event == null) {
+ throw new IllegalArgumentException("null");
+ }
+ String description = null;
+ XmlElement descElement = event.element(WOR_NS, DESCRIPTION_TAG);
+ if (descElement != null) {
+ description = descElement.requiredText();
+ }
+
+ if (description == null || description.length() == 0) {
+ // It might be a data-related notification
+ XmlElement dataProduct = event.element(WOR_NS, DATA_PRODUCT_TAG);
+ if (dataProduct != null) {
+ descElement = dataProduct.element(WOR_NS, DESCRIPTION_TAG);
+ if (descElement != null) {
+ description = descElement.requiredText();
+ }
+ }
+ }
+
+ if (description == null) {
+ description = "";
+ }
+ return description;
+ }
+
+ /**
+ * @param event
+ * @return The location.
+ */
+ public static String getLocation(XmlElement event) {
+ if (event == null) {
+ throw new IllegalArgumentException("null");
+ }
+ XmlElement locationEl = event.element(WOR_NS, LOCATION_TAG);
+ if (locationEl != null) {
+ String location = locationEl.requiredText();
+ return location;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Gets the mapped resource from the event.
+ *
+ * @param event
+ * The event, the type of which has to be resourceMapping.
+ * @return The resource
+ */
+ public static String getMappedResource(XmlElement event) {
+ if (event == null) {
+ throw new IllegalArgumentException("null");
+ }
+ EventType type = getType(event);
+ if (type != EventType.RESOURCE_MAPPING) {
+ throw new IllegalArgumentException("Event must have resourceMapping type instead of " + type);
+ }
+ XmlElement mappedResource = event.element(MAPPED_RESOURCE_TAG);
+ String resource = mappedResource.requiredText();
+ return resource;
+ }
+
+ /**
+ * Gets the retry count from the event.
+ *
+ * @param event
+ * The event, the type of which has to be resourceMapping.
+ * @return The resource
+ */
+ public static String getRetryCount(XmlElement event) {
+ if (event == null) {
+ throw new IllegalArgumentException("null");
+ }
+ EventType type = getType(event);
+ if (type != EventType.RESOURCE_MAPPING) {
+ throw new IllegalArgumentException("Event must have resourceMapping type instead of " + type);
+ }
+ XmlElement retryCountElement = event.element(RETRY_STATUS_COUNT_TAG);
+ String retryCount = retryCountElement.requiredText();
+ return retryCount;
+ }
+
+ /**
+ * Gets the workflow instance ID.
+ *
+ * @param event
+ * The event, the type of which has to be workflowInitialized.
+ * @return The workflowInstanceID
+ */
+ public static URI getWorkflowInstanceID(XmlElement event) {
+ EventType type = getType(event);
+ if (!(type == EventType.WORKFLOW_INITIALIZED || type == EventType.WORKFLOW_TERMINATED)) {
+ throw new IllegalArgumentException(
+ "Event must be an workflowInitialized type or an workflowTerminated type instead of " + type);
+ }
+ XmlElement notificationSource = event.element(WOR_NS, NOTIFICATION_SOURCE_TAG);
+ if (notificationSource == null) {
+ throw new WorkflowRuntimeException("The notification should have " + NOTIFICATION_SOURCE_TAG + " element.");
+ }
+ String workflowInstanceID = notificationSource.attributeValue(WOR_NS, SERVICE_ID_ATTRIBUTE);
+ if (workflowInstanceID == null) {
+ throw new WorkflowRuntimeException("The notification should have " + SERVICE_ID_ATTRIBUTE + " attribute.");
+ }
+ try {
+ return new URI(workflowInstanceID);
+ } catch (URISyntaxException e) {
+ throw new WorkflowRuntimeException(e);
+ }
+ }
+
+ /**
+ * @param event
+ * @return The element that has workflow ID, node ID, etc.
+ */
+ private static XmlElement getIDElement(XmlElement event) {
+ EventType type = getType(event);
+ switch (type) {
+ // The following three don't include node ID, but includes workflow ID.
+ case WORKFLOW_INITIALIZED:
+ case WORKFLOW_INVOKED:
+ case WORKFLOW_TERMINATED:
+ // The followings include both workflow ID and node ID.
+ // TODO they might be used by a workflow too.
+ case SERVICE_INVOKED:
+ case SENDING_RESULT:
+ case SENDING_FAULT:
+ case SENDING_RESPONSE_FAILED: // TODO make sure
+ // The followings are used only in services.
+ case LOG_INFO:
+ case LOG_WARNING:
+ case LOG_EXCEPTION:
+ case LOG_DEBUG:
+ case DATA_CONSUMED:
+ case DATA_PRODUCED:
+ case DATA_RECEIVE_DURATION:
+ case APPLICATION_AUDIT:
+ case COMPUTATION_DURATION:
+ case RESOURCE_MAPPING:
+ case PUBLISH_URL:
+ case INVOKING_SERVICE:
+ return event.element(RECEIVER_TAG);
+ case INVOKING_SERVICE_SUCCEEDED: // TODO make sure
+ case INVOKING_SERVICE_FAILED: // TODO make sure
+ return event.element(RECEIVER_TAG);
+ case RECEIVED_RESULT:
+ case RECEIVED_FAULT:
+ return event.element(RESPONDER_TAG);
+ case UNKNOWN:
+ // Most of unknown types are from service.
+ return event.element(NOTIFICATION_SOURCE_TAG);
+ default:
+ // Most of unknown types are from service.
+ return event.element(NOTIFICATION_SOURCE_TAG);
+ }
+ }
+}
\ No newline at end of file
Added: airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/WsmgClient.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/WsmgClient.java?rev=1411310&view=auto
==============================================================================
--- airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/WsmgClient.java (added)
+++ airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/WsmgClient.java Mon Nov 19 17:05:10 2012
@@ -0,0 +1,165 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.ws.monitor;
+
+import java.io.IOException;
+import java.net.URI;
+
+import org.apache.airavata.common.utils.XMLUtil;
+import org.apache.airavata.wsmg.client.ConsumerNotificationHandler;
+import org.apache.airavata.wsmg.client.MsgBrokerClientException;
+import org.apache.airavata.wsmg.client.NotificationHandler;
+import org.apache.airavata.wsmg.client.WseMsgBrokerClient;
+import org.apache.airavata.wsmg.client.msgbox.MessagePuller;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axis2.addressing.EndpointReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xmlpull.infoset.XmlElement;
+
+public class WsmgClient implements ConsumerNotificationHandler, NotificationHandler {
+
+ private static final Logger logger = LoggerFactory.getLogger(WsmgClient.class);
+
+ private Monitor monitor;
+
+ private URI brokerURL;
+
+ private String topic;
+
+ private boolean pullMode;
+
+ private URI messageBoxURL;
+
+ private WseMsgBrokerClient wseClient;
+
+ private String subscriptionID;
+
+ private MessagePuller messagePuller;
+
+ private long timeout = 20000L;
+
+ private long interval = 1000L;
+ /**
+ * Constructs a WsmgClient.
+ *
+ * @param monitor
+ */
+ public WsmgClient(Monitor monitor) {
+ this.monitor = monitor;
+
+ MonitorConfiguration configuration = monitor.getConfiguration();
+ // We need to copy these because the configuration might change.
+ this.brokerURL = configuration.getBrokerURL();
+ this.topic = configuration.getTopic();
+ this.pullMode = configuration.isPullMode();
+ this.messageBoxURL = configuration.getMessageBoxURL();
+
+ this.wseClient = new WseMsgBrokerClient();
+ this.wseClient.init(this.brokerURL.toString());
+ }
+
+ /**
+ * Subscribes to the notification.
+ *
+ * @throws MonitorException
+ */
+ public synchronized void subscribe() throws MonitorException {
+ try {
+ if (this.pullMode) {
+ EndpointReference messageBoxEPR = this.wseClient.createPullMsgBox(this.messageBoxURL.toString(),getTimeout());
+ this.subscriptionID = this.wseClient.subscribe(messageBoxEPR.getAddress(), this.topic, null);
+ this.messagePuller = this.wseClient.startPullingEventsFromMsgBox(messageBoxEPR, this, getInterval(), getTimeout());
+ } else {
+ String[] endpoints = this.wseClient.startConsumerService(2222, this);
+ this.subscriptionID = this.wseClient.subscribe(endpoints[0], this.topic, null);
+ }
+ } catch (IOException e) {
+ throw new MonitorException("Failed to subscribe.", e);
+ } catch (RuntimeException e) {
+ throw new MonitorException("Failed to subscribe.", e);
+ }
+ }
+
+ /**
+ * Unsubscribes from the notification.
+ *
+ * @throws MonitorException
+ */
+ public synchronized void unsubscribe() throws MonitorException {
+ // This method needs to be synchronized along with subscribe() because
+ // unsubscribe() might be called while subscribe() is being executed.
+ if (this.subscriptionID == null) {
+ throw new IllegalStateException();
+ }
+ try {
+ if (this.pullMode) {
+ this.messagePuller.stopPulling();
+ } else {
+ this.wseClient.shutdownConsumerService();
+ }
+ this.wseClient.unSubscribe(this.subscriptionID);
+ } catch (MsgBrokerClientException e) {
+ throw new MonitorException("Failed to unsubscribe.", e);
+ }
+
+ }
+
+ /**
+ * @see org.apache.airavata.wsmg.client.NotificationHandler#handleNotification(java.lang.String)
+ */
+ public void handleNotification(SOAPEnvelope message) {
+ String soapBody = message.getBody().toString();
+ this.handleNotification(soapBody);
+ }
+
+ /**
+ *
+ * @param message
+ */
+ public void handleNotification(String message) {
+ try {
+ XmlElement event = XMLUtil.stringToXmlElement(message);
+ this.monitor.handleNotification(event);
+ } catch (Exception e) {
+ // Just log them because they can be unrelated messages sent to
+ // this topic by accident.
+ logger.warn("Could not parse received notification: " + message, e);
+ }
+ }
+
+ public long getTimeout() {
+ return timeout;
+ }
+
+ public void setTimeout(long timeout) {
+ this.timeout = timeout;
+ }
+
+ public long getInterval() {
+ return interval;
+ }
+
+ public void setInterval(long interval) {
+ this.interval = interval;
+ }
+}
\ No newline at end of file
Added: airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/event/Event.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/event/Event.java?rev=1411310&view=auto
==============================================================================
--- airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/event/Event.java (added)
+++ airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/event/Event.java Mon Nov 19 17:05:10 2012
@@ -0,0 +1,84 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.ws.monitor.event;
+
+public class Event {
+
+ /**
+ */
+ public enum Type {
+ /**
+ * GPEL_CONFIGURATION_CHANGED
+ */
+ GPEL_CONFIGURATION_CHANGED,
+ /**
+ * GPEL_CONNECTED
+ */
+ GPEL_ENGINE_CONNECTED,
+ /**
+ * GPEL_ENGINE_DISCONNECTED
+ */
+ GPEL_ENGINE_DISCONNECTED,
+
+ /**
+ * MONITOR_CONFIGURATION_CHANGED
+ */
+ MONITOR_CONFIGURATION_CHANGED,
+ /**
+ * MONITOR_STARTED
+ */
+ MONITOR_STARTED,
+ /**
+ * MONITOR_STOPED
+ */
+ MONITOR_STOPED,
+
+ /**
+ * KARMA_STARTED
+ */
+ KARMA_STARTED,
+
+ /**
+ * MYLEAD_CONFIGURATION_CHANGED
+ */
+ MYLEAD_CONFIGURATION_CHANGED,
+ }
+
+ private Type type;
+
+ /**
+ * Constructs a Event.
+ *
+ * @param type
+ */
+ public Event(Type type) {
+ this.type = type;
+ }
+
+ /**
+ * @return The type of the event
+ */
+ public Type getType() {
+ return this.type;
+ }
+
+}
\ No newline at end of file
Added: airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/event/EventListener.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/event/EventListener.java?rev=1411310&view=auto
==============================================================================
--- airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/event/EventListener.java (added)
+++ airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/event/EventListener.java Mon Nov 19 17:05:10 2012
@@ -0,0 +1,35 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.ws.monitor.event;
+
+import org.apache.airavata.workflow.model.exceptions.WorkflowException;
+
+public interface EventListener {
+
+ /**
+ * Called when an event is received.
+ *
+ * @param event
+ * @throws WorkflowException
+ */
+ public void eventReceived(Event event) throws WorkflowException;
+}
\ No newline at end of file
Added: airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/event/EventProducer.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/event/EventProducer.java?rev=1411310&view=auto
==============================================================================
--- airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/event/EventProducer.java (added)
+++ airavata/trunk/modules/ws-messenger/message-monitor/src/main/java/org/apache/airavata/ws/monitor/event/EventProducer.java Mon Nov 19 17:05:10 2012
@@ -0,0 +1,105 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.ws.monitor.event;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.airavata.workflow.model.exceptions.WorkflowException;
+import org.apache.airavata.workflow.model.exceptions.WorkflowRuntimeException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class EventProducer {
+
+ private static final Logger logger = LoggerFactory.getLogger(EventProducer.class);
+
+ private List<EventListener> listeners = new LinkedList<EventListener>();
+
+ /**
+ * @param listener
+ */
+ public void addEventListener(EventListener listener) {
+ this.listeners.add(listener);
+ }
+
+ /**
+ * @param listener
+ */
+ public void removeEventListener(EventListener listener) {
+ this.listeners.remove(listener);
+ }
+
+ /**
+ * @param event
+ */
+ public void sendSafeEvent(Event event) {
+ Throwable exception = null;
+ for (EventListener listener : this.listeners) {
+ try {
+ listener.eventReceived(event);
+ } catch (Throwable e) {
+ logger.error(e.getMessage(), e);
+ // Just remember the first one.
+ if (exception == null) {
+ exception = e;
+ }
+ }
+ }
+ if (exception != null) {
+ if (exception instanceof RuntimeException) {
+ throw (RuntimeException) exception;
+ } else {
+ throw new WorkflowRuntimeException(exception);
+ }
+ }
+ }
+
+ /**
+ * Sends an event.
+ *
+ * @param event
+ * @throws WorkflowException
+ */
+ public void sendEvent(Event event) throws WorkflowException {
+ Throwable exception = null;
+ for (EventListener listener : this.listeners) {
+ try {
+ listener.eventReceived(event);
+ } catch (Throwable e) {
+ logger.error(e.getMessage(), e);
+ // Just remember the first one.
+ if (exception == null) {
+ exception = e;
+ }
+ }
+ }
+ if (exception != null) {
+ if (exception instanceof WorkflowException) {
+ throw (WorkflowException) exception;
+ } else {
+ throw new WorkflowException(exception);
+ }
+ }
+ }
+
+}
\ No newline at end of file