Merged asterix_lsm_stabilization upto r1547

git-svn-id: https://asterixdb.googlecode.com/svn/trunk/asterix@1622 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-events/src/main/assembly/binary-assembly.xml b/asterix-events/src/main/assembly/binary-assembly.xml
new file mode 100644
index 0000000..29ebbdd
--- /dev/null
+++ b/asterix-events/src/main/assembly/binary-assembly.xml
@@ -0,0 +1,27 @@
+<assembly>
+  <id>bin</id>
+  <formats>
+    <format>tar.gz</format>
+    <format>tar.bz2</format>
+    <format>zip</format>
+  </formats>
+  <fileSets>
+    <fileSet>
+      <directory>src/main/resources/events</directory>
+      <outputDirectory>events</outputDirectory>
+      <includes></includes>
+    </fileSet>
+    <fileSet>
+      <directory>src/main/resources/scripts</directory>
+      <outputDirectory>scripts</outputDirectory>
+      <includes></includes>
+    </fileSet>
+    <fileSet>
+      <directory>target</directory>
+      <outputDirectory>target</outputDirectory>
+      <includes>
+        <include>*.jar</include>
+      </includes>
+    </fileSet>
+  </fileSets>
+</assembly>
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/api/ClusterInfo.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/api/ClusterInfo.java
new file mode 100644
index 0000000..630f9b3
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/api/ClusterInfo.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.event.api;
+
+import java.util.List;
+
+public class ClusterInfo {
+
+	List<NodeInfo> nodes;
+
+	public ClusterInfo(List<NodeInfo> nodes) {
+		this.nodes = nodes;
+	}
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/api/NodeInfo.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/api/NodeInfo.java
new file mode 100644
index 0000000..835e0dc
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/api/NodeInfo.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.event.api;
+
+public class NodeInfo {
+
+	private final String id;
+	private final String ip;
+
+	public NodeInfo(String id, String ip) {
+		this.id = id;
+		this.ip = ip;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public String getIp() {
+		return ip;
+	}
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/driver/EventConfig.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/driver/EventConfig.java
new file mode 100644
index 0000000..9d0138b
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/driver/EventConfig.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.event.driver;
+
+import org.kohsuke.args4j.Option;
+
+public class EventConfig {
+
+	@Option(name = "-h", required = false, usage = "Help")
+	public boolean help = false;
+
+	@Option(name = "-d", required = false, usage = "Show the execution on a timeline")
+	public boolean dryRun = false;
+
+	@Option(name = "-s", required = false, usage = "Seed for randomization")
+	public int seed = -1;
+
+	@Option(name = "-c", required = true, usage = "Path to cluster configuration (REQUIRED)")
+	public String clusterPath;
+
+	@Option(name = "-p", required = true, usage = "Path to pattern configuration (REQUIRED)")
+	public String patternPath;
+
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/driver/EventDriver.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/driver/EventDriver.java
new file mode 100644
index 0000000..66c0102
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/driver/EventDriver.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.event.driver;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import org.kohsuke.args4j.CmdLineParser;
+
+import edu.uci.ics.asterix.event.management.DefaultOutputHandler;
+import edu.uci.ics.asterix.event.management.EventUtil;
+import edu.uci.ics.asterix.event.management.EventrixClient;
+import edu.uci.ics.asterix.event.management.IOutputHandler;
+import edu.uci.ics.asterix.event.management.Randomizer;
+import edu.uci.ics.asterix.event.schema.cluster.Cluster;
+import edu.uci.ics.asterix.event.schema.cluster.Node;
+import edu.uci.ics.asterix.event.schema.cluster.Property;
+import edu.uci.ics.asterix.event.schema.event.Events;
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+
+public class EventDriver {
+
+    public static final String CLIENT_NODE_ID = "client_node";
+    public static final Node CLIENT_NODE = new Node(CLIENT_NODE_ID, "127.0.0.1", null, null, null, null, null, null);
+
+    private static String eventsDir;
+    private static Events events;
+    private static Map<String, String> env = new HashMap<String, String>();
+    private static String scriptDirSuffix;
+
+    public static String getEventsDir() {
+        return eventsDir;
+    }
+
+    public static Events getEvents() {
+        return events;
+    }
+
+    public static Map<String, String> getEnvironment() {
+        return env;
+    }
+
+    public static String getStringifiedEnv(Cluster cluster) {
+        StringBuffer buffer = new StringBuffer();
+        for (Property p : cluster.getEnv().getProperty()) {
+            buffer.append(p.getKey() + "=" + p.getValue() + " ");
+        }
+        return buffer.toString();
+    }
+
+    public static Cluster initializeCluster(String path) throws JAXBException, IOException {
+        File file = new File(path);
+        JAXBContext ctx = JAXBContext.newInstance(Cluster.class);
+        Unmarshaller unmarshaller = ctx.createUnmarshaller();
+        Cluster cluster = (Cluster) unmarshaller.unmarshal(file);
+        for (Property p : cluster.getEnv().getProperty()) {
+            env.put(p.getKey(), p.getValue());
+        }
+        return cluster;
+    }
+
+    public static Patterns initializePatterns(String path) throws JAXBException, IOException {
+        File file = new File(path);
+        JAXBContext ctx = JAXBContext.newInstance(Patterns.class);
+        Unmarshaller unmarshaller = ctx.createUnmarshaller();
+        return (Patterns) unmarshaller.unmarshal(file);
+    }
+
+    private static void initialize(EventConfig eventConfig) throws IOException, JAXBException {
+
+    }
+
+    public static EventrixClient getClient(String eventsDir, Cluster cluster, boolean dryRun) throws Exception {
+        return new EventrixClient(eventsDir, cluster, dryRun, new DefaultOutputHandler());
+    }
+
+    public static EventrixClient getClient(String eventsDir, Cluster cluster, boolean dryRun,
+            IOutputHandler outputHandler) throws Exception {
+        return new EventrixClient(eventsDir, cluster, dryRun, outputHandler);
+    }
+
+    public static void main(String[] args) throws Exception {
+        String eventsHome = System.getenv("EVENT_HOME");
+        if (eventsHome == null) {
+            throw new IllegalStateException("EVENT_HOME is not set");
+        }
+        eventsDir = eventsHome + File.separator + EventUtil.EVENTS_DIR;
+        EventConfig eventConfig = new EventConfig();
+        CmdLineParser parser = new CmdLineParser(eventConfig);
+        try {
+            parser.parseArgument(args);
+            if (eventConfig.help) {
+                parser.printUsage(System.out);
+            }
+            if (eventConfig.seed > 0) {
+                Randomizer.getInstance(eventConfig.seed);
+            }
+            Cluster cluster = initializeCluster(eventConfig.clusterPath);
+            Patterns patterns = initializePatterns(eventConfig.patternPath);
+            initialize(eventConfig);
+
+            if (!eventConfig.dryRun) {
+                prepare(cluster);
+            }
+            EventrixClient client = new EventrixClient(eventsDir, cluster, eventConfig.dryRun,
+                    new DefaultOutputHandler());
+            client.submit(patterns);
+            if (!eventConfig.dryRun) {
+                cleanup(cluster);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            parser.printUsage(System.err);
+        }
+    }
+
+    private static void prepare(Cluster cluster) throws IOException, InterruptedException {
+
+        scriptDirSuffix = "" + System.nanoTime();
+        List<String> args = new ArrayList<String>();
+        args.add(scriptDirSuffix);
+        Node clientNode = new Node();
+        clientNode.setId("client");
+        clientNode.setClusterIp("127.0.0.1");
+        for (Node node : cluster.getNode()) {
+            args.add(node.getClusterIp());
+        }
+        EventUtil.executeLocalScript(clientNode, eventsDir + "/" + "events" + "/" + "prepare.sh", args);
+    }
+
+    private static void cleanup(Cluster cluster) throws IOException, InterruptedException {
+        List<String> args = new ArrayList<String>();
+        args.add(scriptDirSuffix);
+        Node clientNode = new Node();
+        clientNode.setId("client");
+        clientNode.setClusterIp("127.0.0.1");
+        for (Node node : cluster.getNode()) {
+            args.add(node.getClusterIp());
+        }
+        EventUtil.executeLocalScript(clientNode, eventsDir + "/" + "events" + "/" + "cleanup.sh", args);
+    }
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/DefaultOutputHandler.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/DefaultOutputHandler.java
new file mode 100644
index 0000000..e8f06a0
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/DefaultOutputHandler.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.event.management;
+
+import edu.uci.ics.asterix.event.schema.pattern.Event;
+
+public class DefaultOutputHandler implements IOutputHandler {
+
+    @Override
+    public OutputAnalysis reportEventOutput(Event event, String output) {
+        return new OutputAnalysis(true, null);
+    }
+
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/ErrorHandler.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/ErrorHandler.java
new file mode 100644
index 0000000..a6c038b
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/ErrorHandler.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.event.management;
+
+public class ErrorHandler {
+
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventExecutor.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventExecutor.java
new file mode 100644
index 0000000..6d89c88
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventExecutor.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.event.management;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.io.IOUtils;
+
+import edu.uci.ics.asterix.event.driver.EventDriver;
+import edu.uci.ics.asterix.event.schema.cluster.Cluster;
+import edu.uci.ics.asterix.event.schema.cluster.Node;
+import edu.uci.ics.asterix.event.schema.cluster.Property;
+import edu.uci.ics.asterix.event.schema.pattern.Pattern;
+
+public class EventExecutor {
+
+    public static final String EVENTS_DIR = "events";
+    private static final String EXECUTE_SCRIPT = "execute.sh";
+    private static final String IP_LOCATION = "IP_LOCATION";
+    private static final String CLUSTER_ENV = "ENV";
+    private static final String SCRIPT = "SCRIPT";
+    private static final String ARGS = "ARGS";
+    private static final String DAEMON = "DAEMON";
+
+    public void executeEvent(Node node, String script, List<String> args, boolean isDaemon, Cluster cluster,
+            Pattern pattern, IOutputHandler outputHandler, EventrixClient client) throws IOException {
+        List<String> pargs = new ArrayList<String>();
+        pargs.add("/bin/bash");
+        pargs.add(client.getEventsDir() + File.separator + "scripts" + File.separator + EXECUTE_SCRIPT);
+        StringBuffer envBuffer = new StringBuffer(IP_LOCATION + "=" + node.getClusterIp() + " ");
+        if (!node.getId().equals(EventDriver.CLIENT_NODE_ID) && cluster.getEnv() != null) {
+            for (Property p : cluster.getEnv().getProperty()) {
+                if (p.getKey().equals("JAVA_HOME")) {
+                    String val = node.getJavaHome() == null ? p.getValue() : node.getJavaHome();
+                    envBuffer.append(p.getKey() + "=" + val + " ");
+                } else if (p.getKey().equals("JAVA_OPTS")) {
+                    StringBuilder builder = new StringBuilder();
+                    builder.append("\"");
+                    String javaOpts = (node.getJavaOpts() == null ? cluster.getJavaOpts() : node.getJavaOpts());
+                    if (javaOpts != null) {
+                        builder.append(javaOpts);
+                    }
+                    if (cluster.isDebugEnabled() != null && cluster.isDebugEnabled().booleanValue()) {
+                        BigInteger debugPort = node.getDebug() == null ? cluster.getDebug() : node.getDebug();
+                        if (debugPort != null) {
+                            builder.append("-Xdebug -Xrunjdwp:transport=dt_socket,address=" + debugPort.intValue()
+                                    + "," + "server=y,suspend=n");
+                        }
+                    }
+                    builder.append("\"");
+                    envBuffer.append(p.getKey() + "=" + builder + " ");
+                } else {
+                    envBuffer.append(p.getKey() + "=" + p.getValue() + " ");
+                }
+
+            }
+            pargs.add(cluster.getUsername() == null ? System.getProperty("user.name") : cluster.getUsername());
+        }
+
+        StringBuffer argBuffer = new StringBuffer();
+        if (args != null && args.size() > 0) {
+            for (String arg : args) {
+                argBuffer.append(arg + " ");
+            }
+        }
+
+        ProcessBuilder pb = new ProcessBuilder(pargs);
+        pb.environment().put(IP_LOCATION, node.getClusterIp());
+        pb.environment().put(CLUSTER_ENV, envBuffer.toString());
+        pb.environment().put(SCRIPT, script);
+        pb.environment().put(ARGS, argBuffer.toString());
+        pb.environment().put(DAEMON, isDaemon ? "true" : "false");
+
+        Process p = pb.start();
+        if (!isDaemon) {
+            BufferedInputStream bis = new BufferedInputStream(p.getInputStream());
+            StringWriter writer = new StringWriter();
+            IOUtils.copy(bis, writer, "UTF-8");
+            String result = writer.getBuffer().toString();
+            OutputAnalysis analysis = outputHandler.reportEventOutput(pattern.getEvent(), result);
+            if (!analysis.isExpected()) {
+                throw new IOException(analysis.getErrorMessage() + result);
+            }
+        }
+    }
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventTask.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventTask.java
new file mode 100644
index 0000000..2586adf
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventTask.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.event.management;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+import org.apache.log4j.Logger;
+
+import edu.uci.ics.asterix.event.driver.EventDriver;
+import edu.uci.ics.asterix.event.schema.cluster.Node;
+import edu.uci.ics.asterix.event.schema.event.Event;
+import edu.uci.ics.asterix.event.schema.pattern.Pattern;
+import edu.uci.ics.asterix.event.schema.pattern.Period;
+
+public class EventTask extends TimerTask {
+
+	public static enum State {
+		INITIALIZED, IN_PROGRESS, COMPLETED, FAILED
+	}
+
+	private static final Logger logger = Logger.getLogger(EventTask.class
+			.getName());
+
+	private Pattern pattern;
+	private Event event;
+	private long interval = 0;
+	private long initialDelay = 0;
+	private int maxOccurs = Integer.MAX_VALUE;
+	private int occurrenceCount = 0;
+	private Timer timer;
+	private String taskScript;
+	private Node location;
+	private List<String> taskArgs;
+	private EventrixClient client;
+	private List<Node> candidateLocations;
+	private boolean dynamicLocation = false;
+	private boolean reuseLocation = false;
+	private State state;
+
+	
+
+	public EventTask(Pattern pattern, EventrixClient client) {
+		this.pattern = pattern;
+		this.client = client;
+		Period period = pattern.getPeriod();
+		if (period != null && period.getAbsvalue() != null) {
+			this.interval = EventUtil.parseTimeInterval(period.getAbsvalue(),
+					period.getUnit());
+		}
+		if (pattern.getDelay() != null) {
+			this.initialDelay = EventUtil.parseTimeInterval(new ValueType(
+					pattern.getDelay().getValue()), pattern.getDelay()
+					.getUnit());
+		}
+		if (pattern.getMaxOccurs() != null) {
+			this.maxOccurs = pattern.getMaxOccurs();
+		}
+		this.timer = new Timer();
+		taskArgs = EventUtil.getEventArgs(pattern);
+		candidateLocations = EventUtil.getCandidateLocations(pattern,
+				client.getCluster());
+		if (pattern.getEvent().getNodeid().getValue().getRandom() != null
+				&& period != null && maxOccurs > 1) {
+			dynamicLocation = true;
+			reuseLocation = pattern.getEvent().getNodeid().getValue()
+					.getRandom().getRange().isReuse();
+		} else {
+			location = EventUtil.getEventLocation(pattern, candidateLocations,
+					client.getCluster());
+		}
+		String scriptsDir;
+		if (location.getId().equals(EventDriver.CLIENT_NODE_ID)) {
+			scriptsDir = client.getEventsDir() + File.separator + "events";
+		} else {
+			scriptsDir = client.getCluster().getWorkingDir().getDir()
+					+ File.separator + "eventrix" + File.separator + "events";
+		}
+		event = EventUtil.getEvent(pattern, client.getEvents());
+		taskScript = scriptsDir + File.separator + event.getScript();
+		state = State.INITIALIZED;
+	}
+
+	public void start() {
+		if (interval > 0) {
+			timer.schedule(this, initialDelay, interval);
+		} else {
+			timer.schedule(this, initialDelay);
+		}
+	}
+
+	@Override
+	public void run() {
+		if (candidateLocations.size() == 0) {
+			timer.cancel();
+			client.notifyCompletion(new EventTaskReport(this));
+		} else {
+			if (dynamicLocation) {
+				location = EventUtil.getEventLocation(pattern,
+						candidateLocations, client.getCluster());
+				if (!reuseLocation) {
+					candidateLocations.remove(location);
+				}
+			}
+
+			logger.debug(EventUtil.dateFormat.format(new Date()) + " "
+					+ "EVENT " + pattern.getEvent().getType().toUpperCase()
+					+ " at " + location.getId().toUpperCase());
+			try {
+				if (!client.isDryRun()) {
+					new EventExecutor().executeEvent(location, taskScript,
+							taskArgs, event.isDaemon(), client.getCluster(),
+							pattern, client.getErrorHandler(), client);
+				}
+				occurrenceCount++;
+				if (occurrenceCount >= maxOccurs) {
+					timer.cancel();
+					client.notifyCompletion(new EventTaskReport(this));
+				}
+			} catch (IOException ioe) {
+				timer.cancel();
+				client.notifyCompletion(new EventTaskReport(this, false, ioe));
+			}
+		}
+
+	}
+
+	public Node getLocation() {
+		return location;
+	}
+
+	public long getInterval() {
+		return interval;
+	}
+
+	public long getInitialDelay() {
+		return initialDelay;
+	}
+
+	public Pattern getPattern() {
+		return pattern;
+	}
+
+	public State getState() {
+		return state;
+	}
+
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventTaskReport.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventTaskReport.java
new file mode 100644
index 0000000..7ad3682
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventTaskReport.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.event.management;
+
+import java.io.Serializable;
+
+public class EventTaskReport implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+    private final EventTask task;
+    private final boolean success;
+    private final Exception e;
+
+    public EventTaskReport(EventTask task, boolean success, Exception e) {
+        this.task = task;
+        this.success = success;
+        this.e = e;
+    }
+
+    public EventTaskReport(EventTask task) {
+        this.task = task;
+        this.success = true;
+        this.e = null;
+    }
+
+    public Exception getException() {
+        return e;
+    }
+
+    public EventTask getTask() {
+        return task;
+    }
+
+    public boolean isSuccess() {
+        return success;
+    }
+
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventUtil.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventUtil.java
new file mode 100644
index 0000000..e6c58eb
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventUtil.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.event.management;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.event.driver.EventDriver;
+import edu.uci.ics.asterix.event.management.ValueType.Type;
+import edu.uci.ics.asterix.event.schema.cluster.Cluster;
+import edu.uci.ics.asterix.event.schema.cluster.Node;
+import edu.uci.ics.asterix.event.schema.event.Event;
+import edu.uci.ics.asterix.event.schema.event.Events;
+import edu.uci.ics.asterix.event.schema.pattern.Pattern;
+
+public class EventUtil {
+
+	public static final String EVENTS_DIR = "events";
+	public static final String CLUSTER_CONF = "config/cluster.xml";
+	public static final String PATTERN_CONF = "config/pattern.xml";
+	public static final DateFormat dateFormat = new SimpleDateFormat(
+			"yyyy/MM/dd HH:mm:ss");
+
+	private static final String IP_LOCATION = "IP_LOCATION";
+	private static final String CLUSTER_ENV = "ENV";
+	private static final String SCRIPT = "SCRIPT";
+	private static final String ARGS = "ARGS";
+	private static final String EXECUTE_SCRIPT = "events/execute.sh";
+
+	public static long parseTimeInterval(ValueType v, String unit)
+			throws IllegalArgumentException {
+		int val = 0;
+		switch (v.getType()) {
+		case ABS:
+			val = Integer.parseInt(v.getAbsoluteValue());
+			break;
+		case RANDOM_MIN_MAX:
+			val = Randomizer.getInstance().getRandomInt(v.getMin(), v.getMax());
+			break;
+		case RANDOM_RANGE:
+			String[] values = v.getRangeSet();
+			val = Integer.parseInt(values[Randomizer.getInstance()
+					.getRandomInt(0, values.length - 1)]);
+			break;
+		}
+		return computeInterval(val, unit);
+	}
+
+	public static long parseTimeInterval(String v, String unit)
+			throws IllegalArgumentException {
+		int value = Integer.parseInt(v);
+		return computeInterval(value, unit);
+	}
+
+	private static long computeInterval(int val, String unit) {
+		int vmult = 1;
+		if ("hr".equalsIgnoreCase(unit)) {
+			vmult = 3600 * 1000;
+		} else if ("min".equalsIgnoreCase(unit)) {
+			vmult = 60 * 1000;
+		} else if ("sec".equalsIgnoreCase(unit)) {
+			vmult = 1000;
+		} else
+			throw new IllegalArgumentException(
+					" invalid unit value specified for frequency (hr,min,sec)");
+		return val * vmult;
+
+	}
+
+	public static Event getEvent(Pattern pattern, Events events) {
+		for (Event event : events.getEvent()) {
+			if (event.getType().equals(pattern.getEvent().getType())) {
+				return event;
+			}
+		}
+		throw new IllegalArgumentException(" Unknown event type"
+				+ pattern.getEvent().getType());
+	}
+
+	public static Node getEventLocation(Pattern pattern,
+			List<Node> candidateLocations, Cluster cluster) {
+		ValueType value = new ValueType(pattern.getEvent().getNodeid()
+				.getValue());
+		Node location = null;
+		Type vtype = value.getType();
+
+		switch (vtype) {
+		case ABS:
+			location = getNodeFromId(value.getAbsoluteValue(), cluster);
+			break;
+		case RANDOM_RANGE:
+			int nodeIndex = Randomizer.getInstance().getRandomInt(0,
+					candidateLocations.size() - 1);
+			location = candidateLocations.get(nodeIndex);
+			break;
+		case RANDOM_MIN_MAX:
+			throw new IllegalStateException(
+					" Canont configure a min max value range for location");
+		}
+		return location;
+
+	}
+
+	public static List<Node> getCandidateLocations(Pattern pattern,
+			Cluster cluster) {
+		ValueType value = new ValueType(pattern.getEvent().getNodeid()
+				.getValue());
+		List<Node> candidateList = new ArrayList<Node>();
+		switch (value.getType()) {
+		case ABS:
+			candidateList.add(getNodeFromId(value.getAbsoluteValue(), cluster));
+			break;
+		case RANDOM_RANGE:
+			boolean anyOption = false;
+			String[] values = value.getRangeSet();
+			for (String v : values) {
+				if (v.equalsIgnoreCase("ANY")) {
+					anyOption = true;
+				}
+			}
+			if (anyOption) {
+				for (Node node : cluster.getNode()) {
+					candidateList.add(node);
+				}
+			} else {
+				boolean found = false;
+				for (String v : values) {
+					for (Node node : cluster.getNode()) {
+						if (node.getId().equals(v)) {
+							candidateList.add(node);
+							found = true;
+							break;
+						}
+					}
+					if (!found) {
+						throw new IllegalStateException("Unknonw nodeId : " + v);
+					}
+					found = false;
+				}
+
+			}
+			String[] excluded = value.getRangeExcluded();
+			if (excluded != null && excluded.length > 0) {
+				List<Node> markedForRemoval = new ArrayList<Node>();
+				for (String exclusion : excluded) {
+					for (Node node : candidateList) {
+						if (node.getId().equals(exclusion)) {
+							markedForRemoval.add(node);
+						}
+					}
+				}
+				candidateList.removeAll(markedForRemoval);
+			}
+			break;
+		case RANDOM_MIN_MAX:
+			throw new IllegalStateException(
+					" Invalid value configured for location");
+		}
+		return candidateList;
+	}
+
+	private static Node getNodeFromId(String nodeid, Cluster cluster) {
+		if (nodeid.equals(EventDriver.CLIENT_NODE.getId())) {
+			return EventDriver.CLIENT_NODE;
+		}
+
+		if (nodeid.equals(cluster.getMasterNode().getId())) {
+			String javaOpts = cluster.getMasterNode().getJavaOpts() == null ? cluster
+					.getJavaOpts() : cluster.getMasterNode().getJavaOpts();
+			String logDir = cluster.getMasterNode().getLogdir() == null ? cluster
+					.getLogdir() : cluster.getMasterNode().getLogdir();
+			String javaHome = cluster.getMasterNode().getJavaHome() == null ? cluster
+					.getJavaHome() : cluster.getMasterNode().getJavaHome();
+			BigInteger debug = cluster.getMasterNode().getDebug();
+			return new Node(cluster.getMasterNode().getId(), cluster
+					.getMasterNode().getClusterIp(), javaHome, javaOpts,
+					logDir, null, null, debug);
+		}
+
+		List<Node> nodeList = cluster.getNode();
+		for (Node node : nodeList) {
+			if (node.getId().equals(nodeid)) {
+				return node;
+			}
+		}
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(EventDriver.CLIENT_NODE.getId() + ",");
+		buffer.append(cluster.getMasterNode().getId() + ",");
+		for (Node v : cluster.getNode()) {
+			buffer.append(v.getId() + ",");
+		}
+		buffer.deleteCharAt(buffer.length() - 1);
+		throw new IllegalArgumentException("Unknown node id :" + nodeid
+				+ " valid ids:" + buffer);
+	}
+
+	public static void executeEventScript(Node node, String script,
+			List<String> args, Cluster cluster) throws IOException,
+			InterruptedException {
+		List<String> pargs = new ArrayList<String>();
+		pargs.add("/bin/bash");
+		pargs.add(EventDriver.getEventsDir() + "/" + EXECUTE_SCRIPT);
+		StringBuffer argBuffer = new StringBuffer();
+		String env = EventDriver.getStringifiedEnv(cluster) + " " + IP_LOCATION
+				+ "=" + node.getClusterIp();
+		if (args != null) {
+			for (String arg : args) {
+				argBuffer.append(arg + " ");
+			}
+		}
+		ProcessBuilder pb = new ProcessBuilder(pargs);
+		pb.environment().putAll(EventDriver.getEnvironment());
+		pb.environment().put(IP_LOCATION, node.getClusterIp());
+		pb.environment().put(CLUSTER_ENV, env);
+		pb.environment().put(SCRIPT, script);
+		pb.environment().put(ARGS, argBuffer.toString());
+		pb.start();
+	}
+
+	public static void executeLocalScript(Node node, String script,
+			List<String> args) throws IOException, InterruptedException {
+		List<String> pargs = new ArrayList<String>();
+		pargs.add("/bin/bash");
+		pargs.add(script);
+		if (args != null) {
+			pargs.addAll(args);
+		}
+		ProcessBuilder pb = new ProcessBuilder(pargs);
+		pb.environment().putAll(EventDriver.getEnvironment());
+		pb.environment().put(IP_LOCATION, node.getClusterIp());
+		pb.start();
+	}
+
+	public static List<String> getEventArgs(Pattern pattern) {
+		List<String> pargs = new ArrayList<String>();
+		if (pattern.getEvent().getPargs() == null) {
+			return pargs;
+		}
+		String[] args = pattern.getEvent().getPargs().split(" ");
+		for (String arg : args) {
+			pargs.add(arg.trim());
+		}
+		return pargs;
+	}
+
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventrixClient.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventrixClient.java
new file mode 100644
index 0000000..6f4336d
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventrixClient.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.event.management;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Logger;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import edu.uci.ics.asterix.event.driver.EventDriver;
+import edu.uci.ics.asterix.event.schema.cluster.Cluster;
+import edu.uci.ics.asterix.event.schema.cluster.Node;
+import edu.uci.ics.asterix.event.schema.event.Events;
+import edu.uci.ics.asterix.event.schema.pattern.Event;
+import edu.uci.ics.asterix.event.schema.pattern.Nodeid;
+import edu.uci.ics.asterix.event.schema.pattern.Pattern;
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.event.schema.pattern.Value;
+
+public class EventrixClient {
+
+    private static final Logger LOGGER = Logger.getLogger(EventrixClient.class.getName());
+
+    private EventTask[] tasks;
+    private boolean dryRun = false;
+    private LinkedBlockingQueue<EventTaskReport> msgInbox = new LinkedBlockingQueue<EventTaskReport>();
+    private AtomicInteger pendingTasks = new AtomicInteger(0);
+    private final Cluster cluster;
+    private IPatternListener listener;
+    private IOutputHandler outputHandler;
+    private Events events;
+    private String eventsDir;
+
+    public EventrixClient(String eventsDir, Cluster cluster, boolean dryRun, IOutputHandler outputHandler)
+            throws Exception {
+        this.eventsDir = eventsDir;
+        this.events = initializeEvents();
+        this.cluster = cluster;
+        this.dryRun = dryRun;
+        this.outputHandler = outputHandler;
+        if (!dryRun) {
+            initializeCluster(eventsDir);
+        }
+    }
+
+    public void submit(Patterns patterns) throws Exception {
+        initTasks(patterns);
+        try {
+            waitForCompletion();
+        } catch (InterruptedException ie) {
+            LOGGER.info("Interrupted exception :" + ie);
+        } catch (Exception e) {
+            throw e;
+        }
+
+    }
+
+    public void submit(Patterns patterns, IPatternListener listener) throws Exception {
+        this.listener = listener;
+        initTasks(patterns);
+    }
+
+    private void initTasks(Patterns patterns) {
+        tasks = new EventTask[patterns.getPattern().size()];
+        pendingTasks.set(tasks.length);
+        int index = 0;
+        for (Pattern pattern : patterns.getPattern()) {
+            tasks[index] = new EventTask(pattern, this);
+            tasks[index].start();
+            index++;
+        }
+    }
+
+    public Cluster getCluster() {
+        return cluster;
+    }
+
+    public boolean isDryRun() {
+        return dryRun;
+    }
+
+    public Events getEvents() {
+        return events;
+    }
+
+    public String getEventsDir() {
+        return eventsDir;
+    }
+
+    public synchronized void notifyCompletion(EventTaskReport report) {
+
+        if (report.isSuccess()) {
+            if (listener != null) {
+                pendingTasks.decrementAndGet();
+                listener.eventCompleted(report);
+                if (pendingTasks.get() == 0) {
+                    listener.jobCompleted();
+                }
+            } else {
+                try {
+                    msgInbox.put(report);
+                } catch (InterruptedException e) {
+                }
+            }
+        } else {
+            for (EventTask t : tasks) {
+                if (t.getState() == EventTask.State.INITIALIZED || t.getState() == EventTask.State.IN_PROGRESS) {
+                    t.cancel();
+                }
+            }
+            if (listener != null) {
+                listener.jobFailed(report);
+            } else {
+                try {
+                    msgInbox.put(report);
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+    }
+
+    private void waitForCompletion() throws Exception {
+        while (true) {
+            EventTaskReport report = msgInbox.take();
+            if (report.isSuccess()) {
+                if (pendingTasks.decrementAndGet() == 0) {
+                    break;
+                }
+            } else {
+                throw new RuntimeException(report.getException().getMessage());
+            }
+        }
+    }
+
+    private void initializeCluster(String eventsDir) throws Exception {
+        Patterns patterns = initPattern(eventsDir);
+        submit(patterns);
+    }
+
+	private Patterns initPattern(String eventsDir) {
+		Nodeid nodeid = new Nodeid(new Value(null,
+				EventDriver.CLIENT_NODE.getId()));
+		List<Pattern> patternList = new ArrayList<Pattern>();
+		String workingDir = cluster.getWorkingDir().getDir();
+		String username = cluster.getUsername() == null ? System
+				.getProperty("user.name") : cluster.getUsername();
+		patternList.add(getDirectoryTransferPattern(username, eventsDir,
+				nodeid, cluster.getMasterNode().getClusterIp(), workingDir));
+
+		if (!cluster.getWorkingDir().isNFS()) {
+			for (Node node : cluster.getNode()) {
+				patternList.add(getDirectoryTransferPattern(username,
+						eventsDir, nodeid, node.getClusterIp(), workingDir));
+			}
+		}
+		Patterns patterns = new Patterns(patternList);
+		return patterns;
+	}
+
+    private Pattern getDirectoryTransferPattern(String username, String src, Nodeid srcNode, String destNodeIp,
+            String destDir) {
+        String pargs = username + " " + src + " " + destNodeIp + " " + destDir;
+        Event event = new Event("directory_transfer", srcNode, pargs);
+        return new Pattern(null, 1, null, event);
+    }
+
+    public IOutputHandler getErrorHandler() {
+        return outputHandler;
+    }
+
+    private Events initializeEvents() throws JAXBException, FileNotFoundException {
+        File file = new File(eventsDir + File.separator + "events" + File.separator + "events.xml");
+        JAXBContext eventCtx = JAXBContext.newInstance(Events.class);
+        Unmarshaller unmarshaller = eventCtx.createUnmarshaller();
+        events = (Events) unmarshaller.unmarshal(file);
+        return events;
+    }
+
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/IOutputHandler.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/IOutputHandler.java
new file mode 100644
index 0000000..c7929cb
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/IOutputHandler.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.event.management;
+
+import edu.uci.ics.asterix.event.schema.pattern.Event;
+
+public interface IOutputHandler {
+
+    public OutputAnalysis reportEventOutput(Event event, String output);
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/IPatternListener.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/IPatternListener.java
new file mode 100644
index 0000000..06a56cf
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/IPatternListener.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.event.management;
+
+public interface IPatternListener {
+
+    public void eventCompleted(EventTaskReport report);
+
+    public void jobCompleted();
+
+    public void jobFailed(EventTaskReport report);
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/OutputAnalysis.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/OutputAnalysis.java
new file mode 100644
index 0000000..2845ede
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/OutputAnalysis.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.event.management;
+
+public class OutputAnalysis {
+
+    private final boolean expected;
+    private final String errorMessage;
+
+    public OutputAnalysis(boolean expected, String errorMessage) {
+        this.expected = expected;
+        this.errorMessage = errorMessage;
+    }
+
+    public boolean isExpected() {
+        return expected;
+    }
+
+    public String getErrorMessage() {
+        return errorMessage;
+    }
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/Randomizer.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/Randomizer.java
new file mode 100644
index 0000000..e59e154
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/Randomizer.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.event.management;
+
+import java.util.Random;
+import java.util.logging.Logger;
+
+public class Randomizer {
+
+	private static final Logger LOGGER = Logger.getLogger(Randomizer.class
+			.getName());
+	private static Randomizer INSTANCE;
+	private final Random random;
+	private final int seed;
+
+	public static Randomizer getInstance(int seed) {
+		if (INSTANCE == null) {
+			INSTANCE = new Randomizer(seed);
+		}
+		return INSTANCE;
+	}
+
+	public static Randomizer getInstance() {
+		if (INSTANCE == null) {
+			INSTANCE = new Randomizer();
+		}
+		return INSTANCE;
+	}
+
+	private Randomizer() {
+		Random rm = new Random();
+		seed = rm.nextInt(10000);
+		random = new Random(seed);
+		LOGGER.info("SEED:" + seed);
+	}
+
+	private Randomizer(int seed) {
+		this.seed = seed;
+		random = new Random(seed);
+		LOGGER.info("SEED:" + seed);
+	}
+
+	public Random getRandom() {
+		return random;
+	}
+
+	public int getSeed() {
+		return seed;
+	}
+
+	public int getRandomInt(int min, int max) {
+		return min + random.nextInt(max - min + 1);
+	}
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/ValueType.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/ValueType.java
new file mode 100644
index 0000000..8aa5cc5
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/ValueType.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.event.management;
+
+import edu.uci.ics.asterix.event.schema.pattern.Value;
+
+public class ValueType {
+
+	public static enum Type {
+		ABS, RANDOM_RANGE, RANDOM_MIN_MAX
+	}
+
+	private Value value;
+	private Type type;
+
+	public ValueType(Value value) {
+		this.value = value;
+		if (value.getAbsvalue() != null) {
+			type = Type.ABS;
+		} else if (value.getRandom() != null) {
+			if (value.getRandom().getMinmax() != null) {
+				type = Type.RANDOM_MIN_MAX;
+			} else if (value.getRandom().getRange() != null) {
+				type = Type.RANDOM_RANGE;
+			} else {
+				throw new IllegalStateException("Incorrect value type");
+			}
+		}
+	}
+
+	public int getMin() {
+		switch (type) {
+		case RANDOM_MIN_MAX:
+			return Integer.parseInt(value.getRandom().getMinmax().getMin());
+		default:
+			throw new IllegalStateException("");
+		}
+	}
+
+	public int getMax() {
+		switch (type) {
+		case RANDOM_MIN_MAX:
+			return Integer.parseInt(value.getRandom().getMinmax().getMax());
+		default:
+			throw new IllegalStateException("");
+		}
+	}
+
+	public String[] getRangeSet() {
+		switch (type) {
+		case RANDOM_RANGE:
+			return value.getRandom().getRange().getSet().split(" ");
+		default:
+			throw new IllegalStateException("");
+		}
+	}
+
+	public String[] getRangeExcluded() {
+		switch (type) {
+		case RANDOM_RANGE:
+			String exl = value.getRandom().getRange().getExclude();
+			return exl != null ? exl.split(" ") : null;
+		default:
+			throw new IllegalStateException("");
+		}
+	}
+
+	public String getAbsoluteValue() {
+		switch (type) {
+		case ABS:
+			return value.getAbsvalue();
+		default:
+			throw new IllegalStateException("");
+		}
+	}
+
+	public Type getType() {
+		return type;
+	}
+
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/xml/PatternParser.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/xml/PatternParser.java
new file mode 100644
index 0000000..426279c
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/xml/PatternParser.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.event.xml;
+
+public class PatternParser {
+
+	public static void parsePattern(String path){
+		
+	}
+}
+
diff --git a/asterix-events/src/main/resources/events/backup/backup.sh b/asterix-events/src/main/resources/events/backup/backup.sh
new file mode 100755
index 0000000..556ca39
--- /dev/null
+++ b/asterix-events/src/main/resources/events/backup/backup.sh
@@ -0,0 +1,72 @@
+WORKING_DIR=$1
+ASTERIX_INSTANCE_NAME=$2
+ASTERIX_IODEVICES=$3
+NODE_STORE=$4
+ASTERIX_ROOT_METADATA_DIR=$5
+TXN_LOG_DIR_NAME=$6
+BACKUP_ID=$7
+BACKUP_DIR=$8
+BACKUP_TYPE=$9
+NODE_ID=${10}
+
+nodeIODevices=$(echo $ASTERIX_IODEVICES | tr "," "\n")
+
+if [ $BACKUP_TYPE == "hdfs" ];
+then
+  HDFS_URL=${11}
+  HADOOP_VERSION=${12}
+  export HADOOP_HOME=$WORKING_DIR/hadoop-$HADOOP_VERSION
+  index=1
+  for nodeIODevice in $nodeIODevices
+  do
+    STORE_DIR=$nodeIODevice/$NODE_STORE
+    TXN_LOG_DIR=$nodeIODevice/$TXN_LOG_DIR_NAME
+    NODE_BACKUP_DIR=$BACKUP_DIR/$ASTERIX_INSTANCE_NAME/$BACKUP_ID/$NODE_ID/
+   
+    # make the destination directory 
+    $HADOOP_HOME/bin/hadoop fs -mkdir $STORE_DIR $HDFS_URL/$NODE_BACKUP_DIR
+
+    # copy store directory
+    $HADOOP_HOME/bin/hadoop fs -copyFromLocal $STORE_DIR $HDFS_URL/$NODE_BACKUP_DIR/
+
+    # copy asterix root metadata directory and log directory from the primary(first) iodevice
+    if [ $index -eq 1 ];
+    then
+      # copy asterix root metadata directory
+      $HADOOP_HOME/bin/hadoop fs -copyFromLocal $nodeIODevice/$ASTERIX_ROOT_METADATA_DIR $HDFS_URL/$NODE_BACKUP_DIR/
+
+      # copy log directory 
+      $HADOOP_HOME/bin/hadoop fs -copyFromLocal $TXN_LOG_DIR $HDFS_URL/$NODE_BACKUP_DIR/
+    fi
+
+    index=`expr $index + 1`
+  done
+else 
+  index=1
+  for nodeIODevice in $nodeIODevices
+  do
+    STORE_DIR=$nodeIODevice/$NODE_STORE
+    TXN_LOG_DIR=$nodeIODevice/$TXN_LOG_DIR_NAME
+    NODE_BACKUP_DIR=$BACKUP_DIR/$ASTERIX_INSTANCE_NAME/$BACKUP_ID/$NODE_ID
+
+    # create the backup directory, if it does not exists
+    if [ ! -d $NODE_BACKUP_DIR ];
+    then
+      mkdir -p $NODE_BACKUP_DIR
+    fi
+
+    # copy store directory
+    cp -r $STORE_DIR $NODE_BACKUP_DIR/
+
+    # copy asterix root metadata directory and log directory from the primary(first) iodevice
+    if [ $index -eq 1 ];
+    then
+      cp -r $nodeIODevice/$ASTERIX_ROOT_METADATA_DIR  $NODE_BACKUP_DIR/
+
+      # copy log directory
+      cp -r $TXN_LOG_DIR $NODE_BACKUP_DIR/
+    fi
+
+    index=`expr $index + 1`
+  done
+fi
diff --git a/asterix-events/src/main/resources/events/cc_failure/cc_failure.sh b/asterix-events/src/main/resources/events/cc_failure/cc_failure.sh
new file mode 100755
index 0000000..aa722e5
--- /dev/null
+++ b/asterix-events/src/main/resources/events/cc_failure/cc_failure.sh
@@ -0,0 +1,6 @@
+#kill -9 `ps -ef  | grep hyracks | grep -v grep | cut -d "/" -f1 | tr -s " " | cut -d " " -f2`
+CC_PARENT_ID_INFO=`ps -ef  | grep asterix | grep cc_start | grep -v ssh`
+CC_PARENT_ID=`echo $CC_PARENT_ID_INFO | tr -s " " | cut -d " " -f2`
+CC_ID_INFO=`ps -ef | grep asterix | grep $CC_PARENT_ID | grep -v bash`
+CC_ID=`echo $CC_ID_INFO |  tr -s " " | cut -d " " -f2`
+kill -9 $CC_ID
diff --git a/asterix-events/src/main/resources/events/cc_start/cc_start.sh b/asterix-events/src/main/resources/events/cc_start/cc_start.sh
new file mode 100755
index 0000000..37645bc
--- /dev/null
+++ b/asterix-events/src/main/resources/events/cc_start/cc_start.sh
@@ -0,0 +1,5 @@
+if [ ! -d $LOG_DIR ]; 
+then 
+  mkdir -p $LOG_DIR
+fi
+$ASTERIX_HOME/bin/asterixcc -client-net-ip-address $CLIENT_NET_IP -client-net-port 1098 -cluster-net-ip-address $CLUSTER_NET_IP -cluster-net-port 1099 -http-port 8888  &> $LOG_DIR/cc.log
diff --git a/asterix-events/src/main/resources/events/events.xml b/asterix-events/src/main/resources/events/events.xml
new file mode 100644
index 0000000..f85e3ea
--- /dev/null
+++ b/asterix-events/src/main/resources/events/events.xml
@@ -0,0 +1,106 @@
+<events xmlns="events">
+  <event>
+    <type>node_join</type>
+    <script>node_join/nc_join.sh</script>
+    <description>Creates a NodeController process at a specified location.</description>
+    <args>location_of_cc location(hostname/ip_address) node_controller_id</args>
+    <daemon>true</daemon>
+  </event>
+  <event>
+    <type>node_failure</type>
+    <script>node_failure/nc_failure.sh</script>
+    <description>Kills a NodeController process at a specified location.</description>
+    <args>node_controller_id</args>
+    <daemon>false</daemon>
+  </event>
+  <event>
+    <type>cc_start</type>
+    <script>cc_start/cc_start.sh</script>
+    <description>Starts a  ClusterController process at a specified location.</description>
+    <args></args>
+    <daemon>true</daemon>
+  </event>
+  <event>
+    <type>cc_failure</type>
+    <script>cc_failure/cc_failure.sh</script>
+    <description>Kills the Cluster Controller process running at a specified location.</description>
+    <args></args>
+    <daemon>false</daemon>
+  </event>
+  <event>
+    <type>node_restart</type>
+    <script>node_restart/nc_restart.sh</script>
+    <description>Shuts and restarts a NodeControllerProcess after a specified time interval, at a specified location</description>
+    <args>address of cc, node controller id and sleep interval(seconds)</args>
+    <daemon>true</daemon>
+  </event>
+  <event>
+    <type>asterix_deploy</type>
+    <script>asterix_deploy/asterix_deploy.sh</script>
+    <description>Deploys Asterix application on a cluster running hyracks</description>
+    <args>IP address of the node running the hyracks cluster controller</args>
+    <daemon>false</daemon>
+  </event>
+  <event>
+    <type>zookeeper_start</type>
+    <script>zookeeper/start.sh</script>
+    <description>Launches ZooKeeper server process</description>
+    <args>IP address of the ZooKeeper server</args>
+    <daemon>true</daemon>
+  </event>
+  <event>
+    <type>zookeeper_stop</type>
+    <script>zookeeper/stop.sh</script>
+    <description>Terminates ZooKeeper server process</description>
+    <args>IP address of the ZooKeeper server</args>
+    <daemon>false</daemon>
+  </event>
+  <event>
+    <type>file_transfer</type>
+    <script>file/transfer.sh</script>
+    <description>Copies a file on the local file system to a remote node</description>
+    <args>local_source_path destination_node destination_path</args>
+    <daemon>false</daemon>
+  </event>
+  <event>
+    <type>directory_transfer</type>
+    <script>file/dir_transfer.sh</script>
+    <description>Copies a directory (and its contents) on the local file system to a remote node</description>
+    <args>local_source_path destination_node destination_path</args>
+    <daemon>false</daemon>
+  </event>
+  <event>
+    <type>file_delete</type>
+    <script>file/delete.sh</script>
+    <description>Deletes a file on the local file system to a remote node</description>
+    <args>local_source_path destination_node destination_path</args>
+    <daemon>false</daemon>
+  </event>
+  <event>
+    <type>backup</type>
+    <script>backup/backup.sh</script>
+    <description>Takes a backup of an Asterix instance</description>
+    <args>Asterix_data_dir HDFSurl</args>
+    <daemon>false</daemon>
+  </event>
+  <event>
+    <type>restore</type>
+    <script>restore/restore.sh</script>
+    <description>Restores an Asterix instance from a back up</description>
+    <args>Asterix_data_dir HDFSurl</args>
+    <daemon>false</daemon>
+  </event>
+  <event>
+    <type>hdfs_delete</type>
+    <script>hdfs/delete.sh</script>
+    <description>Deletes an HDFS path</description>
+    <args>WorkingDir HadoopVersion HDFSUrl Path_to_Delete</args>
+    <daemon>false</daemon>
+  </event>
+  <event>
+    <type>node_info</type>
+    <script>node_info/node_info.sh</script>
+    <description>Retrieved environment information for a node</description>
+    <daemon>false</daemon>
+  </event>
+</events>
diff --git a/asterix-events/src/main/resources/events/file/delete.sh b/asterix-events/src/main/resources/events/file/delete.sh
new file mode 100755
index 0000000..d5ac3ff
--- /dev/null
+++ b/asterix-events/src/main/resources/events/file/delete.sh
@@ -0,0 +1,3 @@
+PATH_TO_DELETE=$1
+echo "rm -rf $PATH_TO_DELETE" >> ~/backup.log
+rm -rf $PATH_TO_DELETE
diff --git a/asterix-events/src/main/resources/events/file/dir_transfer.sh b/asterix-events/src/main/resources/events/file/dir_transfer.sh
new file mode 100755
index 0000000..af7da70
--- /dev/null
+++ b/asterix-events/src/main/resources/events/file/dir_transfer.sh
@@ -0,0 +1,7 @@
+USERNAME=$1
+DIR_TO_TRANSFER=$2
+DEST_HOST=$3
+DEST_DIR=$4
+ssh -l $USERNAME $DEST_HOST "mkdir -p $DEST_DIR"
+echo "scp -r $DIR_TO_TRANSFER $USERNAME@$DEST_HOST:$DEST_DIR/" 
+scp -r $DIR_TO_TRANSFER $USERNAME@$DEST_HOST:$DEST_DIR/
diff --git a/asterix-events/src/main/resources/events/file/transfer.sh b/asterix-events/src/main/resources/events/file/transfer.sh
new file mode 100755
index 0000000..fbd4554
--- /dev/null
+++ b/asterix-events/src/main/resources/events/file/transfer.sh
@@ -0,0 +1,24 @@
+USERNAME=$1
+FILE_TO_TRANSFER=$2
+DEST_HOST=$3
+DEST_DIR=$4
+POST_ACTION=$5
+ssh -l $USERNAME $DEST_HOST "mkdir -p $DEST_DIR"
+echo "scp $FILE_TO_TRANSFER $USERNAME@$DEST_HOST:$DEST_DIR/" 
+scp $FILE_TO_TRANSFER $USERNAME@$DEST_HOST:$DEST_DIR/
+if [ $POST_ACTION == "unpack" ]
+ then 
+ filename=`echo ${FILE_TO_TRANSFER##*/}`
+ fileType=`echo ${FILE_TO_TRANSFER##*.}`
+ if [ $fileType == "tar" ]
+ then 
+   echo "ssh -l $USERNAME $DEST_HOST cd $DEST_DIR && tar xf $filename"
+   ssh -l $USERNAME $DEST_HOST "cd $DEST_DIR && tar xf $filename"
+ else if [ $fileType == "zip" ]
+   then
+     echo "ssh -l $USERNAME $DEST_HOST unzip -o -q -d $DEST_DIR $DEST_DIR/$filename"
+     ssh -l $USERNAME $DEST_HOST "unzip -o -q -d $DEST_DIR $DEST_DIR/$filename"
+     ssh -l $USERNAME $DEST_HOST "chmod -R 755  $DEST_DIR"
+   fi 
+ fi
+fi
diff --git a/asterix-events/src/main/resources/events/hdfs/delete.sh b/asterix-events/src/main/resources/events/hdfs/delete.sh
new file mode 100755
index 0000000..6ff54ee
--- /dev/null
+++ b/asterix-events/src/main/resources/events/hdfs/delete.sh
@@ -0,0 +1,7 @@
+WORKING_DIR=$1
+HADOOP_VERSION=$2
+HDFS_URL=$3
+HDFS_PATH=$4
+export HADOOP_HOME=$WORKING_DIR/hadoop-$HADOOP_VERSION
+echo "$HADOOP_HOME/bin/hadoop fs -rmr $HDFS_URL/$HDFS_PATH"
+$HADOOP_HOME/bin/hadoop fs -rmr $HDFS_URL/$HDFS_PATH
diff --git a/asterix-events/src/main/resources/events/node_failure/nc_failure.sh b/asterix-events/src/main/resources/events/node_failure/nc_failure.sh
new file mode 100755
index 0000000..c562bf2
--- /dev/null
+++ b/asterix-events/src/main/resources/events/node_failure/nc_failure.sh
@@ -0,0 +1,15 @@
+NC_ID=$1
+
+INFO=`ps -ef | grep nc_join | grep -v grep | grep -v ssh| grep $NC_ID | head -n 1`
+PARENT_ID=`echo  $INFO | cut -d " "  -f2`
+PID_INFO=`ps -ef |  grep asterix | grep -v grep | grep -v nc_join |  grep $PARENT_ID`
+PID=`echo $PID_INFO | cut -d " " -f2`
+kill -15 $PID
+
+cmd_output=$(jps|grep $PID)
+while [ ${#cmd_output} -ne 0 ]
+do
+  sleep 1
+  kill -15 $PID
+  cmd_output=$(jps|grep $PID)
+done
diff --git a/asterix-events/src/main/resources/events/node_info/node_info.sh b/asterix-events/src/main/resources/events/node_info/node_info.sh
new file mode 100755
index 0000000..2179d5a
--- /dev/null
+++ b/asterix-events/src/main/resources/events/node_info/node_info.sh
@@ -0,0 +1,2 @@
+JAVA_VERSION=`java -version 2>&1 |awk 'NR==1{ gsub(/"/,""); print $3 }'`
+echo "java_version=$JAVA_VERSION" 1>&2
diff --git a/asterix-events/src/main/resources/events/node_join/nc_join.sh b/asterix-events/src/main/resources/events/node_join/nc_join.sh
new file mode 100755
index 0000000..6b5280b
--- /dev/null
+++ b/asterix-events/src/main/resources/events/node_join/nc_join.sh
@@ -0,0 +1,8 @@
+CC_HOST=$1
+NC_ID=$2
+IO_DEVICES=$3
+if [ ! -d $LOG_DIR ]; 
+then 
+  mkdir -p $LOG_DIR
+fi
+$ASTERIX_HOME/bin/asterixnc -node-id $NC_ID -cc-host $CC_HOST -cc-port 1099 -cluster-net-ip-address $IP_LOCATION  -data-ip-address $IP_LOCATION -iodevices $IO_DEVICES -result-ip-address $IP_LOCATION &> $LOG_DIR/${NC_ID}.log
diff --git a/asterix-events/src/main/resources/events/node_restart/nc_restart.sh b/asterix-events/src/main/resources/events/node_restart/nc_restart.sh
new file mode 100755
index 0000000..961ce8d
--- /dev/null
+++ b/asterix-events/src/main/resources/events/node_restart/nc_restart.sh
@@ -0,0 +1,21 @@
+CC_HOST=$1
+NC_ID=$2
+SLEEP_TIME=$3
+
+if [ $NC_ID == 'ANY' ]
+then
+  NC_ID="." 
+  PARENT_ID=`ps -ej | tr -s " " | grep nc_join | grep -v grep | grep -v ssh |  cut -d " " -f2 | head -n 1` 
+  PARENT_PROCESS_ENTRY=`ps -ef | grep $PARENT_ID | grep -v grep   | head -n 1`
+  NC_ID=`echo ${PARENT_PROCESS_ENTRY##* }`
+  echo "NCid is $NC_ID" >> ~/try.txt
+else 
+  PARENT_ID=`ps -ej | tr -s " " | grep nc_join | grep -v grep | grep -v ssh | grep $NC_ID | cut -d " " -f2 | head -n 1` 
+fi 
+
+PID=`ps -ej | tr -s " " | grep hyracks | grep -v grep | grep -v nc_join |  grep $PARENT_ID | cut -d " " -f2 | head -n 1`
+kill -9 $PID
+
+sleep $3
+
+$HYRACKS_HOME/hyracks-server/target/hyracks-server-0.2.2-SNAPSHOT-binary-assembly/bin/hyracksnc -node-id $NC_ID -cc-host $CC_HOST -cc-port 1099 -cluster-net-ip-address $IP_LOCATION  -data-ip-address $IP_LOCATION
diff --git a/asterix-events/src/main/resources/events/restore/restore.sh b/asterix-events/src/main/resources/events/restore/restore.sh
new file mode 100755
index 0000000..6396eec
--- /dev/null
+++ b/asterix-events/src/main/resources/events/restore/restore.sh
@@ -0,0 +1,75 @@
+WORKING_DIR=$1
+ASTERIX_INSTANCE_NAME=$2
+ASTERIX_IODEVICES=$3
+NODE_STORE=$4
+ASTERIX_ROOT_METADATA_DIR=$5
+TXN_LOG_DIR_NAME=$6
+BACKUP_ID=$7
+BACKUP_DIR=$8
+BACKUP_TYPE=$9
+NODE_ID=${10}
+HDFS_URL=${11}
+HADOOP_VERSION=${12}
+HADOOP_HOME=$WORKING_DIR/hadoop-$HADOOP_VERSION
+
+iodevices=$(echo $ASTERIX_IODEVICES | tr "," "\n")
+
+index=1
+for iodevice in $iodevices
+do
+  NODE_BACKUP_DIR=$BACKUP_DIR/$ASTERIX_INSTANCE_NAME/$BACKUP_ID/$NODE_ID
+
+  # remove the existing store directory
+  STORE_DIR=$iodevice/$NODE_STORE
+
+  # if STORE_DIR ends with a /, remove it
+  if [ ${STORE_DIR:${#STORE_DIR}-1} == "/" ];
+  then
+    STORE_DIR=${STORE_DIR:0:${#STORE_DIR}-1}
+  fi
+
+  DEST_STORE_DIR=${STORE_DIR%/*}
+  SOURCE_STORE_DIR=${NODE_STORE##*/}
+  rm -rf $DEST_STORE_DIR/$SOURCE_STORE_DIR
+
+  # remove the existing log directory
+  DEST_LOG_DIR=$iodevice/$TXN_LOG_DIR_NAME/
+  rm -rf $DEST_LOG_DIR
+
+  # remove the existing asterix metadata directory
+  rm -rf $iodevice/$ASTERIX_ROOT_METADATA_DIR
+
+  if [ $BACKUP_TYPE == "hdfs" ];
+  then
+      # RESTORE FROM HDFS BACKUP
+
+      # copy store directory
+      $HADOOP_HOME/bin/hadoop fs -copyToLocal $HDFS_URL/$NODE_BACKUP_DIR/$SOURCE_STORE_DIR  $DEST_STORE_DIR/ 
+
+      # copy asterix metadata root directory and txn log directory
+      if [ $index -eq 1 ];
+      then
+        $HADOOP_HOME/bin/hadoop fs -copyToLocal $HDFS_URL/$NODE_BACKUP_DIR/$ASTERIX_ROOT_METADATA_DIR $iodevice/
+
+        # copy transaction logs directory
+        $HADOOP_HOME/bin/hadoop fs -copyToLocal $HDFS_URL/$NODE_BACKUP_DIR/$TXN_LOG_DIR_NAME $iodevice/
+      fi
+
+  else
+
+      # RESTORE FROM LOCAL BACKUP
+      # copy store directory
+      cp  -r $NODE_BACKUP_DIR/$SOURCE_STORE_DIR  $DEST_STORE_DIR/ 
+
+      # copy asterix metadata root directory and txn log directory
+      if [ $index -eq 1 ];
+      then
+        cp -r $NODE_BACKUP_DIR/$ASTERIX_ROOT_METADATA_DIR $iodevice/
+
+        # copy transaction logs directory
+        cp -r $NODE_BACKUP_DIR/$TXN_LOG_DIR_NAME $iodevice/
+      fi
+
+  fi
+  index=`expr $index + 1`
+done
diff --git a/asterix-events/src/main/resources/schema/cluster.xsd b/asterix-events/src/main/resources/schema/cluster.xsd
new file mode 100644
index 0000000..0e1adce
--- /dev/null
+++ b/asterix-events/src/main/resources/schema/cluster.xsd
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:cl="cluster" targetNamespace="cluster" elementFormDefault="qualified">
+
+<!-- definition of simple types --> 
+<xs:element name="name" type="xs:string"/>
+<xs:element name="java_opts" type="xs:string"/>
+<xs:element name="logdir" type="xs:string"/>
+<xs:element name="id" type="xs:string"/>
+<xs:element name="client-ip" type="xs:string"/>
+<xs:element name="cluster-ip" type="xs:string"/>
+<xs:element name="key" type="xs:string"/>
+<xs:element name="value" type="xs:string"/>
+<xs:element name="dir" type="xs:string"/>
+<xs:element name="NFS" type="xs:boolean"/>
+<xs:element name="store" type="xs:string"/>
+<xs:element name="iodevices" type="xs:string"/>
+<xs:element name="java_home" type="xs:string"/>
+<xs:element name="username" type="xs:string"/>
+<xs:element name="debug" type="xs:integer"/>
+<xs:element name="debugEnabled" type="xs:boolean"/>
+
+<!-- definition of complex elements -->
+<xs:element name="workingDir">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="cl:dir"/>
+      <xs:element ref="cl:NFS"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="master-node">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="cl:id"/>
+      <xs:element ref="cl:client-ip"/>
+      <xs:element ref="cl:cluster-ip"/>
+      <xs:element ref="cl:java_home" minOccurs="0"/>
+      <xs:element ref="cl:java_opts" minOccurs="0"/>
+      <xs:element ref="cl:logdir" minOccurs="0"/>
+      <xs:element ref="cl:debug" minOccurs="0"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="property">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="cl:key"/>
+      <xs:element ref="cl:value"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="env">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="cl:property" minOccurs="0" maxOccurs="unbounded"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="node">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="cl:id"/>
+      <xs:element ref="cl:cluster-ip"/>
+      <xs:element ref="cl:java_home" minOccurs="0"/>
+      <xs:element ref="cl:java_opts" minOccurs="0"/>
+      <xs:element ref="cl:logdir" minOccurs="0"/>
+      <xs:element ref="cl:store" minOccurs="0"/>
+      <xs:element ref="cl:iodevices" minOccurs="0"/>
+      <xs:element ref="cl:debug" minOccurs="0"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="cluster">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="cl:name"/>
+      <xs:element ref="cl:username"/>
+      <xs:element ref="cl:env" minOccurs="0"/>
+      <xs:element ref="cl:java_home" minOccurs="0"/>
+      <xs:element ref="cl:java_opts" minOccurs="0"/>
+      <xs:element ref="cl:logdir" minOccurs="0"/>
+      <xs:element ref="cl:store" minOccurs="0"/>
+      <xs:element ref="cl:iodevices" minOccurs="0"/>
+      <xs:element ref="cl:workingDir"/>
+      <xs:element ref="cl:debugEnabled" minOccurs="0"/>
+      <xs:element ref="cl:debug" minOccurs="0"/>
+      <xs:element ref="cl:master-node"/>
+      <xs:element ref="cl:node" maxOccurs="unbounded"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+</xs:schema>     
diff --git a/asterix-events/src/main/resources/schema/event.xsd b/asterix-events/src/main/resources/schema/event.xsd
new file mode 100644
index 0000000..a233c18
--- /dev/null
+++ b/asterix-events/src/main/resources/schema/event.xsd
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:es="events" targetNamespace="events" elementFormDefault="qualified">
+
+<!-- definition of simple types --> 
+<xs:element name="script" type="xs:string"/>
+<xs:element name="type" type="xs:string"/>
+<xs:element name="description" type="xs:string"/>
+<xs:element name="args" type="xs:string"/>
+<xs:element name="daemon" type="xs:boolean"/>
+
+<!-- definition of complex elements -->
+
+<xs:element name="event">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="es:type"/>
+      <xs:element ref="es:script"/>
+      <xs:element ref="es:description"/>
+      <xs:element ref="es:args"/>
+      <xs:element ref="es:daemon"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="events">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="es:event" maxOccurs="unbounded"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+ 
+</xs:schema>     
diff --git a/asterix-events/src/main/resources/schema/jaxb-bindings.xjb b/asterix-events/src/main/resources/schema/jaxb-bindings.xjb
new file mode 100644
index 0000000..b5982e0
--- /dev/null
+++ b/asterix-events/src/main/resources/schema/jaxb-bindings.xjb
@@ -0,0 +1,9 @@
+<jxb:bindings version="1.0"
+xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
+xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+<jxb:globalBindings>
+  <jxb:serializable uid="1"/>
+</jxb:globalBindings>
+
+</jxb:bindings>
diff --git a/asterix-events/src/main/resources/schema/pattern.xsd b/asterix-events/src/main/resources/schema/pattern.xsd
new file mode 100644
index 0000000..4eee880
--- /dev/null
+++ b/asterix-events/src/main/resources/schema/pattern.xsd
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:eg="patterns" targetNamespace="patterns">
+
+
+<!-- definition of simple types --> 
+<xs:element name="maxOccurs" type = "xs:int"/> 
+<xs:element name="pargs" type="xs:string"/>
+<xs:element name="absvalue" type="xs:string"/>
+<xs:element name="unit" type="xs:string"/>
+<xs:element name="type" type="xs:string"/>
+<xs:element name="min" type="xs:string"/>
+<xs:element name="max" type="xs:string"/>
+<xs:element name="abs" type="xs:string"/>
+<xs:element name="set" type="xs:string"/>
+<xs:element name="exclude" type="xs:string"/>
+<xs:element name="reuse" type="xs:boolean"/>
+<!-- definition of attributes -->
+
+<!-- definition of complex elements -->
+
+<xs:element name="range">
+  <xs:complexType>
+    <xs:sequence>
+     <xs:element ref="eg:set"/>
+     <xs:element ref="eg:exclude" minOccurs="0"/>
+     <xs:element ref="eg:reuse" minOccurs="0"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="minmax">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="eg:min"/>
+      <xs:element ref="eg:max"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+
+<xs:element name="random">
+  <xs:complexType>
+    <xs:sequence>
+       <xs:element ref="eg:minmax" minOccurs="0"/>
+       <xs:element ref="eg:range" minOccurs="0"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="value">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="eg:random" minOccurs="0"/>
+      <xs:element ref="eg:absvalue" minOccurs="0"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="nodeid">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="eg:value"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="period">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="eg:absvalue"/>
+      <xs:element ref="eg:unit"/>
+    </xs:sequence>   
+  </xs:complexType>
+</xs:element>    
+
+<xs:element name="delay">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="eg:value"/>
+      <xs:element ref="eg:unit"/>
+    </xs:sequence>   
+  </xs:complexType>
+</xs:element>    
+
+<xs:element name="event">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="eg:type"/>
+      <xs:element ref="eg:nodeid"/>
+      <xs:element ref="eg:pargs"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+ 
+<xs:element name="pattern">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="eg:delay"/>
+      <xs:element ref="eg:maxOccurs" maxOccurs="1" minOccurs="0"/>
+      <xs:element ref="eg:period"/>
+      <xs:element ref="eg:event"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="patterns">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="eg:pattern" maxOccurs="unbounded"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+</xs:schema>     
diff --git a/asterix-events/src/main/resources/scripts/execute.sh b/asterix-events/src/main/resources/scripts/execute.sh
new file mode 100755
index 0000000..30f6c2f
--- /dev/null
+++ b/asterix-events/src/main/resources/scripts/execute.sh
@@ -0,0 +1,27 @@
+USERNAME=$1
+if [ ! -d $MANAGIX_HOME/logs ];
+then
+   mkdir -p $MANAGIX_HOME/logs
+fi
+LOGDIR=$MANAGIX_HOME/logs
+if [ $DAEMON == "false" ]; then 
+  if [ -z $USERNAME ]
+  then
+    cmd_output=$(ssh $IP_LOCATION "$ENV $SCRIPT $ARGS" 2>&1 >/dev/null) 
+    echo "ssh $IP_LOCATION $ENV $SCRIPT $ARGS" >> $LOGDIR/execute.log
+    echo "$cmd_output"
+  else
+    echo "ssh -l $USERNAME $IP_LOCATION $ENV $SCRIPT $ARGS" >> $LOGDIR/execute.log
+    cmd_output=$(ssh -l $USERNAME $IP_LOCATION "$ENV $SCRIPT $ARGS" 2>&1 >/dev/null) 
+    echo "$cmd_output"
+  fi  
+else 
+  if [ -z $USERNAME ];
+  then
+     echo "ssh $IP_LOCATION $ENV $SCRIPT $ARGS &" >> $LOGDIR/execute.log
+     ssh $IP_LOCATION "$ENV $SCRIPT $ARGS" &
+  else
+     echo "ssh -l $USERNAME $IP_LOCATION $ENV $SCRIPT $ARGS &" >> $LOGDIR/execute.log
+     ssh -l $USERNAME $IP_LOCATION "$ENV $SCRIPT $ARGS" &
+  fi   
+fi
diff --git a/asterix-events/src/main/resources/scripts/prepare.sh b/asterix-events/src/main/resources/scripts/prepare.sh
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/asterix-events/src/main/resources/scripts/prepare.sh