Added source for asterix installer and event execution framework as modules under the asterix source tree
git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_stabilization_installer@1202 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-events/pom.xml b/asterix-events/pom.xml
new file mode 100644
index 0000000..a9aeaa5
--- /dev/null
+++ b/asterix-events/pom.xml
@@ -0,0 +1,156 @@
+<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/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>asterix</artifactId>
+ <groupId>edu.uci.ics.asterix</groupId>
+ <version>0.0.4-SNAPSHOT</version>
+ </parent>
+ <groupId>edu.uci.ics.asterix</groupId>
+ <artifactId>asterix-events</artifactId>
+ <version>0.0.4-SNAPSHOT</version>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.jvnet.jaxb2.maven2</groupId>
+ <artifactId>maven-jaxb2-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>event</id>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ <configuration>
+ <args>
+ <arg>-Xsetters</arg>
+ <arg>-Xvalue-constructor</arg>
+ </args>
+ <plugins>
+ <plugin>
+ <groupId>org.jvnet.jaxb2_commons</groupId>
+ <artifactId>jaxb2-basics</artifactId>
+ <version>0.6.2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.jvnet.jaxb2_commons</groupId>
+ <artifactId>jaxb2-value-constructor</artifactId>
+ <version>3.0</version>
+ </plugin>
+ </plugins>
+ <schemaDirectory>src/main/resources/schema</schemaDirectory>
+ <schemaIncludes>
+ <include>event.xsd</include>
+ </schemaIncludes>
+ <generatePackage>edu.uci.ics.asterix.event.schema.event</generatePackage>
+ <generateDirectory>${project.build.directory}/generated-sources/event</generateDirectory>
+ </configuration>
+ </execution>
+ <execution>
+ <id>pattern</id>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ <configuration>
+ <args>
+ <arg>-Xsetters</arg>
+ <arg>-Xvalue-constructor</arg>
+ </args>
+ <plugins>
+ <plugin>
+ <groupId>org.jvnet.jaxb2_commons</groupId>
+ <artifactId>jaxb2-basics</artifactId>
+ <version>0.6.2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.jvnet.jaxb2_commons</groupId>
+ <artifactId>jaxb2-value-constructor</artifactId>
+ <version>3.0</version>
+ </plugin>
+ </plugins>
+ <schemaDirectory>src/main/resources/schema</schemaDirectory>
+ <schemaIncludes>
+ <include>pattern.xsd</include>
+ </schemaIncludes>
+ <generatePackage>edu.uci.ics.asterix.event.schema.pattern</generatePackage>
+ <generateDirectory>${project.build.directory}/generated-sources/pattern</generateDirectory>
+ </configuration>
+ </execution>
+ <execution>
+ <id>cluster</id>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ <configuration>
+ <args>
+ <arg>-Xsetters</arg>
+ <arg>-Xvalue-constructor</arg>
+ </args>
+ <plugins>
+ <plugin>
+ <groupId>org.jvnet.jaxb2_commons</groupId>
+ <artifactId>jaxb2-basics</artifactId>
+ <version>0.6.2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.jvnet.jaxb2_commons</groupId>
+ <artifactId>jaxb2-value-constructor</artifactId>
+ <version>3.0</version>
+ </plugin>
+ </plugins>
+ <schemaDirectory>src/main/resources/schema</schemaDirectory>
+ <schemaIncludes>
+ <include>cluster.xsd</include>
+ </schemaIncludes>
+ <generatePackage>edu.uci.ics.asterix.event.schema.cluster</generatePackage>
+ <generateDirectory>${project.build.directory}/generated-sources/cluster</generateDirectory>
+ <bindingDirectory>src/main/resources/schema</bindingDirectory>
+ <bindingIncludes>
+ <bindingInclude>jaxb-bindings.xjb</bindingInclude>
+ </bindingIncludes>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>args4j</groupId>
+ <artifactId>args4j</artifactId>
+ <version>2.0.12</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jvnet.jaxb2_commons</groupId>
+ <artifactId>jaxb2-value-constructor</artifactId>
+ <version>3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>1.4</version>
+ </dependency>
+ </dependencies>
+</project>
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..379d811
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/driver/EventDriver.java
@@ -0,0 +1,183 @@
+/*
+ * 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 java.util.logging.Logger;
+
+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);
+
+ private static final Logger LOGGER = Logger.getLogger(EventDriver.class.getName());
+
+ private static String homeDir;
+ private static Events events;
+ private static Map<String, String> env = new HashMap<String, String>();
+ private static String scriptDirSuffix;
+
+ public static String getHomeDir() {
+ return homeDir;
+ }
+
+ public static void setHomeDir(String homeDir) {
+ EventDriver.homeDir = homeDir;
+ }
+
+ public static Events getEvents() {
+ return events;
+ }
+
+ public static void setEvents(Events events) {
+ EventDriver.events = 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 void initializeEvents(String path) throws IOException {
+ try {
+ File eventsFile = new File(path);
+ JAXBContext ctx = JAXBContext.newInstance(Events.class);
+ Unmarshaller unmarshaller = ctx.createUnmarshaller();
+ events = (Events) unmarshaller.unmarshal(eventsFile);
+ } catch (JAXBException e) {
+ e.printStackTrace();
+ }
+ }
+
+ 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 {
+ homeDir = System.getenv("EVENT_HOME");
+ if (homeDir == null) {
+ throw new IllegalStateException("EVENT_HOME is not set");
+ }
+ initializeEvents(homeDir + "/" + EventUtil.EVENTS_DIR + "/" + "events.xml");
+ }
+
+ public static EventrixClient getClient(Cluster cluster, boolean dryRun) throws Exception {
+ return new EventrixClient(cluster, dryRun, new DefaultOutputHandler());
+ }
+
+ public static EventrixClient getClient(Cluster cluster, boolean dryRun, IOutputHandler outputHandler)
+ throws Exception {
+ return new EventrixClient(cluster, dryRun, outputHandler);
+ }
+
+ public static void main(String[] args) throws Exception {
+ 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(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.setIp("127.0.0.1");
+ for (Node node : cluster.getNode()) {
+ args.add(node.getIp());
+ }
+ EventUtil.executeLocalScript(clientNode, homeDir + "/" + "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.setIp("127.0.0.1");
+ for (Node node : cluster.getNode()) {
+ args.add(node.getIp());
+ }
+ EventUtil.executeLocalScript(clientNode, homeDir + "/" + "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..869edd7
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventExecutor.java
@@ -0,0 +1,77 @@
+/*
+ * 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.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.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) throws IOException {
+ List<String> pargs = new ArrayList<String>();
+ pargs.add("/bin/bash");
+ pargs.add(EventDriver.getHomeDir() + File.separator + "events.pkg" + File.separator + EXECUTE_SCRIPT);
+ StringBuffer argBuffer = new StringBuffer();
+ StringBuffer envBuffer = new StringBuffer(IP_LOCATION + "=" + node.getIp());
+ if (!node.getId().equals(EventDriver.CLIENT_NODE_ID)) {
+ envBuffer.append(" " + EventDriver.getStringifiedEnv(cluster));
+ pargs.add(cluster.getUsername() == null ? System.getProperty("user.name") : cluster.getUsername());
+ }
+ if (args != null && args.size() > 0) {
+ for (String arg : args) {
+ argBuffer.append(arg + " ");
+ }
+ }
+ ProcessBuilder pb = new ProcessBuilder(pargs);
+ pb.environment().putAll(EventDriver.getEnvironment());
+ pb.environment().put(IP_LOCATION, node.getIp());
+ 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());
+ }
+ }
+ }
+}
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..aac2604
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventTask.java
@@ -0,0 +1,155 @@
+/*
+ * 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 java.util.logging.Level;
+import java.util.logging.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.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 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 scheduler;
+ private List<Node> candidateLocations;
+ private boolean dynamicLocation = false;
+ private boolean reuseLocation = false;
+ private State state;
+
+ static {
+ logger.setLevel(Level.WARNING);
+ }
+
+ public EventTask(Pattern pattern, EventrixClient client) {
+ this.pattern = pattern;
+ this.scheduler = 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, scheduler.getCluster());
+ }
+ String scriptsDir;
+ if (location.getId().equals(EventDriver.CLIENT_NODE_ID)) {
+ scriptsDir = EventDriver.getHomeDir() + File.separator + "events.pkg";
+ } else {
+ scriptsDir = client.getCluster().getWorkingDir().getDir() + File.separator + "events.pkg";
+ }
+ taskScript = scriptsDir + File.separator + EventUtil.getEvent(pattern).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();
+ scheduler.notifyCompletion(new EventTaskReport(this));
+ } else {
+ if (dynamicLocation) {
+ location = EventUtil.getEventLocation(pattern, candidateLocations, scheduler.getCluster());
+ if (!reuseLocation) {
+ candidateLocations.remove(location);
+ }
+ }
+
+ logger.info(EventUtil.dateFormat.format(new Date()) + " " + "EVENT "
+ + pattern.getEvent().getType().toUpperCase() + " at " + location.getId().toUpperCase());
+ try {
+ if (!scheduler.isDryRun()) {
+ new EventExecutor().executeEvent(location, taskScript, taskArgs, EventUtil.getEvent(pattern)
+ .isDaemon(), scheduler.getCluster(), pattern, scheduler.getErrorHandler());
+ }
+ occurrenceCount++;
+ if (occurrenceCount >= maxOccurs) {
+ timer.cancel();
+ scheduler.notifyCompletion(new EventTaskReport(this));
+ }
+ } catch (IOException ioe) {
+ timer.cancel();
+ scheduler.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..80bc0da
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventUtil.java
@@ -0,0 +1,238 @@
+/*
+ * 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.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+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.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";
+ 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 final DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+
+ private static final Logger logger = Logger.getLogger(EventDriver.class.getName());
+
+ 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) {
+ for (Event event : EventDriver.getEvents().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())) {
+ return new Node(cluster.getMasterNode().getId(), cluster.getMasterNode().getIp(), null, null, null);
+ }
+
+ 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.getHomeDir() + "/" + EXECUTE_SCRIPT);
+ StringBuffer argBuffer = new StringBuffer();
+ String env = EventDriver.getStringifiedEnv(cluster) + " " + IP_LOCATION + "=" + node.getIp();
+ 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.getIp());
+ 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.getIp());
+ 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..3792eb8
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventrixClient.java
@@ -0,0 +1,177 @@
+/*
+ * 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.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Logger;
+
+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.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;
+
+ public EventrixClient(Cluster cluster, boolean dryRun, IOutputHandler outputHandler) throws Exception {
+ this.cluster = cluster;
+ this.dryRun = dryRun;
+ this.outputHandler = outputHandler;
+ if (!dryRun) {
+ initializeCluster();
+ }
+ }
+
+ 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 void notifyCompletion(EventTaskReport report) {
+
+ if (report.isSuccess()) {
+ pendingTasks.decrementAndGet();
+ if (listener != null) {
+ 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) {
+ }
+ }
+ }
+ }
+
+ public void notifyFailure(EventTaskReport report) {
+
+ }
+
+ private void waitForCompletion() throws Exception {
+ while (true) {
+ EventTaskReport report = msgInbox.take();
+ if (report.isSuccess()) {
+ if (pendingTasks.get() == 0) {
+ break;
+ }
+ } else {
+ throw new RuntimeException(report.getException().getMessage());
+ }
+ }
+ }
+
+ private void initializeCluster() throws Exception {
+ Patterns patterns = initPattern();
+ submit(patterns);
+ }
+
+ private Patterns initPattern() {
+ Nodeid nodeid = new Nodeid(new Value(null, EventDriver.CLIENT_NODE.getId()));
+ List<Pattern> patternList = new ArrayList<Pattern>();
+ String workingDir = cluster.getWorkingDir().getDir();
+ File eventsPkg = new File(EventDriver.getHomeDir() + File.separator + "events.pkg.tar");
+ if (!eventsPkg.exists()) {
+ throw new IllegalStateException(" Events package does not exist (" + eventsPkg.getAbsolutePath() + ")");
+ }
+
+ String username = cluster.getUsername() == null ? System.getProperty("user.name") : cluster.getUsername();
+ patternList.add(getFileTransferPattern(username, eventsPkg.getAbsolutePath(), nodeid, cluster.getMasterNode()
+ .getIp(), workingDir, true));
+
+ if (!cluster.getWorkingDir().isNFS()) {
+ for (Node node : cluster.getNode()) {
+ patternList.add(getFileTransferPattern(username, eventsPkg.getAbsolutePath(), nodeid, node.getIp(),
+ workingDir, true));
+ }
+ }
+ Patterns patterns = new Patterns(patternList);
+ return patterns;
+ }
+
+ private Pattern getFileTransferPattern(String username, String src, Nodeid srcNode, String destNodeIp,
+ String destDir, boolean unpack) {
+ String pargs = username + " " + src + " " + destNodeIp + " " + destDir + " " + "unpack";
+ Event event = new Event("file_transfer", srcNode, pargs);
+ return new Pattern(null, 1, null, event);
+ }
+
+ public IOutputHandler getErrorHandler() {
+ return outputHandler;
+ }
+}
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/ConfigParser.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/xml/ConfigParser.java
new file mode 100644
index 0000000..b399226
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/xml/ConfigParser.java
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+import java.io.File;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+public class ConfigParser {
+
+ private static final String JAXB_PKG = "edu.uci.ics.asterix.event.trigger";
+
+ public static void main(String [] args){
+ try {
+ String path = "config/event_pattern1.xml";
+ JAXBContext ctx = JAXBContext.newInstance(JAXB_PKG);
+ Unmarshaller unmarshaller = ctx.createUnmarshaller();
+ Object o = unmarshaller.unmarshal(new File(path));
+ } catch (JAXBException e) {
+ e.printStackTrace();
+ }
+
+ }
+}
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/schema/cluster.xsd b/asterix-events/src/main/resources/schema/cluster.xsd
new file mode 100644
index 0000000..e5c6511
--- /dev/null
+++ b/asterix-events/src/main/resources/schema/cluster.xsd
@@ -0,0 +1,87 @@
+<?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="ram" type="xs:string"/>
+<xs:element name="logdir" type="xs:string"/>
+<xs:element name="id" type="xs:string"/>
+<xs:element name="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="java_home" type="xs:string"/>
+<xs:element name="username" type="xs:string"/>
+
+<!-- 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:ip"/>
+ <xs:element ref="cl:cluster-ip"/>
+ <xs:element ref="cl:ram" minOccurs="0"/>
+ <xs:element ref="cl:logdir" 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:ip"/>
+ <xs:element ref="cl:ram" minOccurs="0"/>
+ <xs:element ref="cl:logdir" minOccurs="0"/>
+ <xs:element ref="cl:store" 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:ram" minOccurs="0"/>
+ <xs:element ref="cl:java_home" minOccurs="1"/>
+ <xs:element ref="cl:logdir" minOccurs="0"/>
+ <xs:element ref="cl:store" minOccurs="0"/>
+ <xs:element ref="cl:workingDir"/>
+ <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..114a12a
--- /dev/null
+++ b/asterix-events/src/main/resources/scripts/execute.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+val=0
+line=""
+for x in $@
+do
+ if [[ $val == 0 ]]
+ then
+ line="$x="
+ val=1
+ else
+ msg="$line$x"
+ echo $line >> envr
+ val=0
+ fi
+done
+cat ./envr
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
diff --git a/asterix-installer/pom.xml b/asterix-installer/pom.xml
new file mode 100644
index 0000000..98ca7a2
--- /dev/null
+++ b/asterix-installer/pom.xml
@@ -0,0 +1,133 @@
+<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/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>asterix</artifactId>
+ <groupId>edu.uci.ics.asterix</groupId>
+ <version>0.0.4-SNAPSHOT</version>
+ </parent>
+ <groupId>edu.uci.ics.asterix</groupId>
+ <artifactId>asterix-installer</artifactId>
+ <version>0.0.4-SNAPSHOT</version>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.jvnet.jaxb2.maven2</groupId>
+ <artifactId>maven-jaxb2-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>configuration</id>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ <configuration>
+ <schemaDirectory>src/main/resources/schema</schemaDirectory>
+ <schemaIncludes>
+ <include>managix-conf.xsd</include>
+ </schemaIncludes>
+ <generatePackage>edu.uci.ics.asterix.installer.schema.conf</generatePackage>
+ <generateDirectory>${project.build.directory}/generated-sources/configuration</generateDirectory>
+ </configuration>
+ </execution>
+ <execution>
+ <id>cluster</id>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ <configuration>
+ <schemaDirectory>src/main/resources/schema</schemaDirectory>
+ <schemaIncludes>
+ <include>cluster.xsd</include>
+ </schemaIncludes>
+ <generatePackage>edu.uci.ics.asterix.installer.schema.cluster</generatePackage>
+ <generateDirectory>${project.build.directory}/generated-sources/cluster</generateDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>args4j</groupId>
+ <artifactId>args4j</artifactId>
+ <version>2.0.12</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.zookeeper</groupId>
+ <artifactId>zookeeper</artifactId>
+ <version>3.4.4</version>
+ <exclusions>
+ <exclusion>
+ <groupId>com.sun.jmx</groupId>
+ <artifactId>jmxri</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.sun.jdmk</groupId>
+ <artifactId>jmxtools</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>1.4</version>
+ </dependency>
+ <dependency>
+ <groupId>edu.uci.ics.asterix</groupId>
+ <artifactId>asterix-events</artifactId>
+ <version>0.0.4-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>edu.uci.ics.hyracks</groupId>
+ <artifactId>hyracks-server</artifactId>
+ <version>0.2.3-SNAPSHOT</version>
+ <type>zip</type>
+ <classifier>binary-assembly</classifier>
+ </dependency>
+ <dependency>
+ <groupId>edu.uci.ics.hyracks</groupId>
+ <artifactId>hyracks-cli</artifactId>
+ <version>0.2.3-SNAPSHOT</version>
+ <type>zip</type>
+ <classifier>binary-assembly</classifier>
+ </dependency>
+ <dependency>
+ <groupId>edu.uci.ics.asterix</groupId>
+ <artifactId>asterix-app</artifactId>
+ <version>0.0.4-SNAPSHOT</version>
+ <type>zip</type>
+ <classifier>binary-assembly</classifier>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/AbstractCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/AbstractCommand.java
new file mode 100644
index 0000000..ed2e2ff
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/AbstractCommand.java
@@ -0,0 +1,39 @@
+/*
+ * 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.installer.command;
+
+import java.util.logging.Logger;
+
+import org.kohsuke.args4j.CmdLineParser;
+
+public abstract class AbstractCommand implements ICommand {
+
+ protected static final Logger LOGGER = Logger.getLogger(AbstractCommand.class.getName());
+
+ protected CommandConfig config;
+
+ public void execute(String[] args) throws Exception {
+ String[] cmdArgs = new String[args.length - 1];
+ System.arraycopy(args, 1, cmdArgs, 0, cmdArgs.length);
+ config = getCommandConfig();
+ CmdLineParser parser = new CmdLineParser(config);
+ parser.parseArgument(cmdArgs);
+ execCommand();
+ }
+
+ abstract protected void execCommand() throws Exception;
+
+ abstract protected CommandConfig getCommandConfig();
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/AlterCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/AlterCommand.java
new file mode 100644
index 0000000..6dee399
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/AlterCommand.java
@@ -0,0 +1,61 @@
+/*
+ * 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.installer.command;
+
+import java.util.Date;
+import java.util.Properties;
+
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.installer.driver.ManagixUtil;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.service.ILookupService;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class AlterCommand extends AbstractCommand {
+
+ @Override
+ protected void execCommand() throws Exception {
+ String instanceName = ((AlterConfig) config).name;
+ ManagixUtil.validateAsterixInstanceExists(instanceName, State.INACTIVE);
+ ILookupService lookupService = ServiceProvider.INSTANCE.getLookupService();
+ AsterixInstance instance = lookupService.getAsterixInstance(instanceName);
+
+ Properties asterixConfProp = ManagixUtil.getAsterixConfiguration(((AlterConfig) config).confPath);
+ instance.setConfiguration(asterixConfProp);
+ instance.setModifiedTimestamp(new Date());
+ lookupService.updateAsterixInstance(instance);
+ }
+
+ @Override
+ protected CommandConfig getCommandConfig() {
+ return new AlterConfig();
+ }
+
+}
+
+class AlterConfig implements CommandConfig {
+
+ @Option(name = "-h", required = false, usage = "Help")
+ public boolean help = false;
+
+ @Option(name = "-n", required = false, usage = "Name of Asterix Instance")
+ public String name;
+
+ @Option(name = "-conf", required = false, usage = "Path to instance configuration")
+ public String confPath;
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/BackupCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/BackupCommand.java
new file mode 100644
index 0000000..9a0f7c7
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/BackupCommand.java
@@ -0,0 +1,67 @@
+/*
+ * 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.installer.command;
+
+import java.util.Date;
+import java.util.List;
+
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.event.driver.EventDriver;
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.ManagixUtil;
+import edu.uci.ics.asterix.installer.error.OutputHandler;
+import edu.uci.ics.asterix.installer.events.PatternCreator;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.BackupInfo;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class BackupCommand extends AbstractCommand {
+
+ @Override
+ protected void execCommand() throws Exception {
+ String asterixInstanceName = ((BackupConfig) config).name;
+ AsterixInstance instance = ManagixUtil.validateAsterixInstanceExists(asterixInstanceName, State.INACTIVE);
+ List<BackupInfo> backupInfo = instance.getBackupInfo();
+ PatternCreator pc = new PatternCreator();
+ Patterns patterns = pc.getBackUpAsterixPattern(instance, ((BackupConfig) config).localPath);
+ EventDriver.getClient(instance.getCluster(), false, OutputHandler.INSTANCE).submit(patterns);
+ int backupId = backupInfo.size();
+ BackupInfo binfo = new BackupInfo(backupId, new Date());
+ backupInfo.add(binfo);
+ System.out.println(asterixInstanceName + " backed up " + binfo);
+ ServiceProvider.INSTANCE.getLookupService().updateAsterixInstance(instance);
+ }
+
+ @Override
+ protected CommandConfig getCommandConfig() {
+ return new BackupConfig();
+ }
+
+}
+
+class BackupConfig implements CommandConfig {
+
+ @Option(name = "-h", required = false, usage = "Help")
+ public boolean help = false;
+
+ @Option(name = "-n", required = true, usage = "Name of the Asterix instance")
+ public String name;
+
+ @Option(name = "-local", required = false, usage = "Path on the local file system for backup")
+ public String localPath;
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandConfig.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandConfig.java
new file mode 100644
index 0000000..c0dd480
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandConfig.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.installer.command;
+
+public interface CommandConfig {
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandHandler.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandHandler.java
new file mode 100644
index 0000000..179412f
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandHandler.java
@@ -0,0 +1,52 @@
+/*
+ * 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.installer.command;
+
+import edu.uci.ics.asterix.installer.command.ICommand.CommandType;
+
+public class CommandHandler {
+
+ public void processCommand(String args[]) throws Exception {
+ CommandType cmdType = CommandType.valueOf(args[0].toUpperCase());
+ ICommand cmd = null;
+ switch (cmdType) {
+ case CREATE:
+ cmd = new CreateCommand();
+ break;
+ case ALTER:
+ cmd = new AlterCommand();
+ break;
+ case DELETE:
+ cmd = new DeleteCommand();
+ break;
+ case DESCRIBE:
+ cmd = new DescribeCommand();
+ break;
+ case BACKUP:
+ cmd = new BackupCommand();
+ break;
+ case RESTORE:
+ cmd = new RestoreCommand();
+ break;
+ case START:
+ cmd = new StartCommand();
+ break;
+ case STOP:
+ cmd = new StopCommand();
+ break;
+ }
+ cmd.execute(args);
+ }
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CreateCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CreateCommand.java
new file mode 100644
index 0000000..341baa8
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CreateCommand.java
@@ -0,0 +1,107 @@
+/*
+ * 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.installer.command;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+
+import org.kohsuke.args4j.Option;
+
+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.Env;
+import edu.uci.ics.asterix.event.schema.cluster.Property;
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.ManagixDriver;
+import edu.uci.ics.asterix.installer.driver.ManagixUtil;
+import edu.uci.ics.asterix.installer.error.OutputHandler;
+import edu.uci.ics.asterix.installer.error.VerificationUtil;
+import edu.uci.ics.asterix.installer.events.PatternCreator;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixRuntimeState;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class CreateCommand extends AbstractCommand {
+
+ private String asterixInstanceName;
+ private Cluster cluster;
+
+ @Override
+ protected void execCommand() throws Exception {
+ asterixInstanceName = ((CreateConfig) config).name;
+ ManagixUtil.validateAsterixInstanceNotExists(asterixInstanceName);
+ CreateConfig createConfig = (CreateConfig) config;
+ JAXBContext ctx = JAXBContext.newInstance(Cluster.class);
+ Unmarshaller unmarshaller = ctx.createUnmarshaller();
+ cluster = (Cluster) unmarshaller.unmarshal(new File(createConfig.clusterPath));
+ AsterixInstance asterixInstance = ManagixUtil.createAsterixInstance(asterixInstanceName, cluster,
+ ((CreateConfig) config).asterixConf);
+ ManagixUtil.createAsterixZip(asterixInstance, true);
+ List<Property> clusterProperties = new ArrayList<Property>();
+ clusterProperties.add(new Property("HYRACKS_HOME", cluster.getWorkingDir().getDir() + File.separator
+ + "hyracks"));
+ clusterProperties.add(new Property("JAVA_OPTS", "-Xmx" + cluster.getRam()));
+ clusterProperties.add(new Property("CLUSTER_NET_IP", cluster.getMasterNode().getClusterIp()));
+ clusterProperties.add(new Property("CLIENT_NET_IP", cluster.getMasterNode().getIp()));
+ clusterProperties.add(new Property("LOG_DIR", cluster.getLogdir()));
+ clusterProperties.add(new Property("JAVA_HOME", cluster.getJavaHome()));
+ cluster.setEnv(new Env(clusterProperties));
+
+ PatternCreator pc = new PatternCreator();
+ Patterns patterns = pc.getStartAsterixPattern(asterixInstanceName, cluster);
+ EventDriver.getClient(cluster, false, OutputHandler.INSTANCE).submit(patterns);
+
+ AsterixRuntimeState runtimeState = VerificationUtil.getAsterixRuntimeState(asterixInstance);
+ VerificationUtil.updateInstanceWithRuntimeDescription(asterixInstance, runtimeState, true);
+ ServiceProvider.INSTANCE.getLookupService().writeAsterixInstance(asterixInstance);
+ System.out.println(asterixInstance.getDescription(false));
+ ManagixUtil.deleteDirectory(ManagixDriver.getManagixHome() + File.separator + ManagixDriver.ASTERIX_DIR
+ + File.separator + asterixInstanceName);
+
+ }
+
+ @Override
+ protected CommandConfig getCommandConfig() {
+ return new CreateConfig();
+ }
+
+ public Cluster getCluster() {
+ return cluster;
+ }
+
+ public String getAsterixInstanceName() {
+ return asterixInstanceName;
+ }
+}
+
+class CreateConfig implements CommandConfig {
+
+ @Option(name = "-h", required = false, usage = "Help")
+ public boolean help = false;
+
+ @Option(name = "-n", required = true, usage = "Name of Asterix Instance")
+ public String name;
+
+ @Option(name = "-c", required = true, usage = "Path to cluster configuration")
+ public String clusterPath;
+
+ @Option(name = "-a", required = true, usage = "Path to cluster configuration")
+ public String asterixConf;
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/DeleteCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/DeleteCommand.java
new file mode 100644
index 0000000..3286575
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/DeleteCommand.java
@@ -0,0 +1,58 @@
+/*
+ * 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.installer.command;
+
+import java.util.logging.Level;
+
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.event.driver.EventDriver;
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.ManagixUtil;
+import edu.uci.ics.asterix.installer.error.OutputHandler;
+import edu.uci.ics.asterix.installer.events.PatternCreator;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class DeleteCommand extends AbstractCommand {
+
+ @Override
+ protected void execCommand() throws Exception {
+ String asterixInstanceName = ((DeleteConfig) config).name;
+ AsterixInstance instance = ManagixUtil.validateAsterixInstanceExists(asterixInstanceName, State.INACTIVE);
+ PatternCreator pc = new PatternCreator();
+ Patterns patterns = pc.createDeleteInstancePattern(instance);
+ EventDriver.getClient(instance.getCluster(), false, OutputHandler.INSTANCE).submit(patterns);
+ ServiceProvider.INSTANCE.getLookupService().removeAsterixInstance(asterixInstanceName);
+ LOGGER.log(Level.INFO, " Asterix instance: " + asterixInstanceName + " deleted");
+ }
+
+ @Override
+ protected CommandConfig getCommandConfig() {
+ return new DeleteConfig();
+ }
+
+}
+
+class DeleteConfig implements CommandConfig {
+
+ @Option(name = "-h", required = false, usage = "Help")
+ public boolean help = false;
+
+ @Option(name = "-n", required = false, usage = "Name of Asterix Instance")
+ public String name;
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/DescribeCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/DescribeCommand.java
new file mode 100644
index 0000000..c2713a3
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/DescribeCommand.java
@@ -0,0 +1,86 @@
+/*
+ * 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.installer.command;
+
+import java.util.List;
+
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.installer.driver.ManagixUtil;
+import edu.uci.ics.asterix.installer.error.ManagixException;
+import edu.uci.ics.asterix.installer.error.VerificationUtil;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixRuntimeState;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class DescribeCommand extends AbstractCommand {
+
+ @Override
+ protected void execCommand() throws Exception {
+ String asterixInstanceName = ((DescribeConfig) config).name;
+ boolean adminView = ((DescribeConfig) config).admin;
+ if (asterixInstanceName != null) {
+ ManagixUtil
+ .validateAsterixInstanceExists(asterixInstanceName, State.INACTIVE, State.ACTIVE, State.UNUSABLE);
+ AsterixInstance instance = ServiceProvider.INSTANCE.getLookupService().getAsterixInstance(
+ asterixInstanceName);
+ if (instance != null) {
+ AsterixRuntimeState state = VerificationUtil.getAsterixRuntimeState(instance);
+ boolean expectedRunning = instance.getState().equals(State.UNUSABLE) ? instance.getPreviousState()
+ .equals(State.ACTIVE) : !instance.getState().equals(State.INACTIVE);
+ VerificationUtil.updateInstanceWithRuntimeDescription(instance, state, expectedRunning);
+ ServiceProvider.INSTANCE.getLookupService().updateAsterixInstance(instance);
+ System.out.println(instance.getDescription(adminView));
+ } else {
+ throw new ManagixException("Asterix instance by the name " + asterixInstanceName + " does not exist.");
+ }
+ } else {
+ List<AsterixInstance> asterixInstances = ServiceProvider.INSTANCE.getLookupService().getAsterixInstances();
+ if (asterixInstances.size() > 0) {
+ for (AsterixInstance instance : asterixInstances) {
+ AsterixRuntimeState state = VerificationUtil.getAsterixRuntimeState(instance);
+ boolean expectedRunning = instance.getState().equals(State.UNUSABLE) ? instance.getPreviousState()
+ .equals(State.ACTIVE) : !instance.getState().equals(State.INACTIVE);
+ VerificationUtil.updateInstanceWithRuntimeDescription(instance, state, expectedRunning);
+ ServiceProvider.INSTANCE.getLookupService().updateAsterixInstance(instance);
+ System.out.println(instance.getDescription(adminView));
+ }
+ } else {
+ LOGGER.info("No Asterix instances found!");
+ }
+
+ }
+ }
+
+ @Override
+ protected CommandConfig getCommandConfig() {
+ return new DescribeConfig();
+ }
+
+}
+
+class DescribeConfig implements CommandConfig {
+
+ @Option(name = "-h", required = false, usage = "Help")
+ public boolean help = false;
+
+ @Option(name = "-n", required = false, usage = "Name of Asterix Instance")
+ public String name;
+
+ @Option(name = "-admin", required = false, usage = "Detailed description")
+ public boolean admin;
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ICommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ICommand.java
new file mode 100644
index 0000000..2822337
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ICommand.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.installer.command;
+
+public interface ICommand {
+
+ public enum CommandType {
+ CREATE, DELETE, START, STOP, BACKUP, RESTORE, DESCRIBE, ALTER
+ }
+
+ public void execute(String args[]) throws Exception;
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/RestoreCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/RestoreCommand.java
new file mode 100644
index 0000000..141fc03
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/RestoreCommand.java
@@ -0,0 +1,60 @@
+/*
+ * 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.installer.command;
+
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.event.driver.EventDriver;
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.ManagixUtil;
+import edu.uci.ics.asterix.installer.error.OutputHandler;
+import edu.uci.ics.asterix.installer.events.PatternCreator;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+
+public class RestoreCommand extends AbstractCommand {
+
+ @Override
+ protected void execCommand() throws Exception {
+ String asterixInstanceName = ((RestoreConfig) config).name;
+ AsterixInstance instance = ManagixUtil.validateAsterixInstanceExists(asterixInstanceName, State.INACTIVE);
+ int backupId = ((RestoreConfig) config).backupId;
+ if (instance.getBackupInfo().size() <= backupId || backupId < 0) {
+ throw new IllegalStateException("Invalid backup id");
+ }
+ PatternCreator pc = new PatternCreator();
+ Patterns patterns = pc.getRestoreAsterixPattern(instance, backupId);
+ EventDriver.getClient(instance.getCluster(), false, OutputHandler.INSTANCE).submit(patterns);
+ }
+
+ @Override
+ protected CommandConfig getCommandConfig() {
+ return new RestoreConfig();
+ }
+
+}
+
+class RestoreConfig implements CommandConfig {
+
+ @Option(name = "-h", required = false, usage = "Help")
+ public boolean help = false;
+
+ @Option(name = "-n", required = true, usage = "Name of the Asterix instance")
+ public String name;
+
+ @Option(name = "-b", required = true, usage = "Id corresponding to the backed up version")
+ public int backupId;
+
+}
\ No newline at end of file
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StartCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StartCommand.java
new file mode 100644
index 0000000..3aabb75
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StartCommand.java
@@ -0,0 +1,69 @@
+/*
+ * 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.installer.command;
+
+import java.io.File;
+
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.event.driver.EventDriver;
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.ManagixDriver;
+import edu.uci.ics.asterix.installer.driver.ManagixUtil;
+import edu.uci.ics.asterix.installer.error.OutputHandler;
+import edu.uci.ics.asterix.installer.error.VerificationUtil;
+import edu.uci.ics.asterix.installer.events.PatternCreator;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixRuntimeState;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class StartCommand extends AbstractCommand {
+
+ @Override
+ protected void execCommand() throws Exception {
+ String asterixInstanceName = ((StartConfig) config).name;
+ AsterixInstance instance = ManagixUtil.validateAsterixInstanceExists(asterixInstanceName, State.INACTIVE);
+ ManagixUtil.createAsterixZip(instance, false);
+ PatternCreator pc = new PatternCreator();
+ Patterns patterns = pc.getStartAsterixPattern(asterixInstanceName, instance.getCluster());
+ EventDriver.getClient(instance.getCluster(), false, OutputHandler.INSTANCE).submit(patterns);
+ ManagixUtil.deleteDirectory(ManagixDriver.getManagixHome() + File.separator + ManagixDriver.ASTERIX_DIR
+ + File.separator + asterixInstanceName);
+ AsterixRuntimeState runtimeState = VerificationUtil.getAsterixRuntimeState(instance);
+ VerificationUtil.updateInstanceWithRuntimeDescription(instance, runtimeState, true);
+ System.out.println(instance.getDescription(false));
+ ServiceProvider.INSTANCE.getLookupService().updateAsterixInstance(instance);
+ }
+
+ @Override
+ protected CommandConfig getCommandConfig() {
+ return new StartConfig();
+ }
+
+}
+
+class StartConfig implements CommandConfig {
+
+ @Option(name = "-h", required = false, usage = "Help")
+ public boolean help = false;
+
+ @Option(name = "-n", required = false, usage = "Name of Asterix Instance")
+ public String name;
+
+ @Option(name = "-conf", required = false, usage = "Path to instance configuration")
+ public String confPath;
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StopCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StopCommand.java
new file mode 100644
index 0000000..441b63c
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StopCommand.java
@@ -0,0 +1,79 @@
+/*
+ * 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.installer.command;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.event.driver.EventDriver;
+import edu.uci.ics.asterix.event.management.EventrixClient;
+import edu.uci.ics.asterix.event.schema.cluster.Node;
+import edu.uci.ics.asterix.event.schema.pattern.Pattern;
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.ManagixUtil;
+import edu.uci.ics.asterix.installer.error.OutputHandler;
+import edu.uci.ics.asterix.installer.events.PatternCreator;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class StopCommand extends AbstractCommand {
+
+ @Override
+ protected void execCommand() throws Exception {
+ String asterixInstanceName = ((StopConfig) config).name;
+ AsterixInstance asterixInstance = ManagixUtil.validateAsterixInstanceExists(asterixInstanceName, State.ACTIVE,
+ State.UNUSABLE);
+ PatternCreator pc = new PatternCreator();
+ List<Pattern> patternsToExecute = new ArrayList<Pattern>();
+ patternsToExecute.add(pc.createCCStopPattern(asterixInstance.getCluster().getMasterNode().getId()));
+
+ for (Node node : asterixInstance.getCluster().getNode()) {
+ patternsToExecute.add(pc.createNCStopPattern(node.getId(), asterixInstanceName + "_" + node.getId()));
+ }
+ EventrixClient client = EventDriver.getClient(asterixInstance.getCluster(), false, OutputHandler.INSTANCE);
+ try {
+ client.submit(new Patterns(patternsToExecute));
+ } catch (Exception e) {
+ // processes are already dead
+ }
+ asterixInstance.setState(State.INACTIVE);
+ asterixInstance.setStateChangeTimestamp(new Date());
+ ServiceProvider.INSTANCE.getLookupService().updateAsterixInstance(asterixInstance);
+ }
+
+ @Override
+ protected CommandConfig getCommandConfig() {
+ return new StopConfig();
+ }
+
+ public String getAsterixInstanceName() {
+ return ((StopConfig) config).name;
+ }
+
+}
+
+class StopConfig implements CommandConfig {
+
+ @Option(name = "-h", required = false, usage = "Help")
+ public boolean help = false;
+
+ @Option(name = "-n", required = true, usage = "Name of Asterix Instance")
+ public String name;
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/ManagixConfig.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/ManagixConfig.java
new file mode 100644
index 0000000..f955caf
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/ManagixConfig.java
@@ -0,0 +1,25 @@
+/*
+ * 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.installer.driver;
+
+import java.util.Set;
+
+class ManagixConfig {
+
+ public String asterixHome;
+ public String hyracksHome;
+ public String hdfsUrl;
+ public Set<String> zookeeperNodes;
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/ManagixDriver.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/ManagixDriver.java
new file mode 100644
index 0000000..c79ac61
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/ManagixDriver.java
@@ -0,0 +1,156 @@
+/*
+ * 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.installer.driver;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+
+import edu.uci.ics.asterix.event.driver.EventDriver;
+import edu.uci.ics.asterix.event.schema.event.Events;
+import edu.uci.ics.asterix.installer.command.CommandHandler;
+import edu.uci.ics.asterix.installer.schema.conf.Configuration;
+import edu.uci.ics.asterix.installer.service.ILookupService;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+@SuppressWarnings("restriction")
+public class ManagixDriver {
+
+ public static final String MANAGIX_INTERNAL_DIR = ".managix";
+ public static final String ASTERIX_DIR = "asterix";
+ public static final String EVENTS_DIR = "events";
+
+ private static final Logger LOGGER = Logger.getLogger(ManagixDriver.class.getName());
+ private static final String ENV_MANAGIX_HOME = "MANAGIX_HOME";
+ private static final String MANAGIX_CONF_XML = "conf" + File.separator + "managix-conf.xml";
+ private static final String MANAGIX_EVENTS_XML = MANAGIX_INTERNAL_DIR + File.separator + EVENTS_DIR
+ + File.separator + "events.pkg" + File.separator + "events.xml";
+
+ private static Configuration conf;
+ private static String managixHome;
+ private static String hyracksServerZip;
+ private static String hyracksClientZip;
+ private static String asterixZip;
+
+ public static String getHyrackServerZip() {
+ return hyracksServerZip;
+ }
+
+ public static String getHyracksClientZip() {
+ return hyracksClientZip;
+ }
+
+ public static String getAsterixZip() {
+ return asterixZip;
+ }
+
+ public static String getHyracksClientHome() {
+ return ASTERIX_DIR + File.separator + "hyracks-cli";
+ }
+
+ public static Configuration getConfiguration() {
+ return conf;
+ }
+
+ private static void initConfig() throws Exception {
+ managixHome = System.getenv(ENV_MANAGIX_HOME);
+ File configFile = new File(managixHome + File.separator + MANAGIX_CONF_XML);
+ JAXBContext configCtx = JAXBContext.newInstance(Configuration.class);
+ Unmarshaller unmarshaller = configCtx.createUnmarshaller();
+ conf = (Configuration) unmarshaller.unmarshal(configFile);
+
+ File managixEventFile = new File(managixHome + File.separator + MANAGIX_EVENTS_XML);
+ JAXBContext eventCtx = JAXBContext.newInstance(Events.class);
+ unmarshaller = eventCtx.createUnmarshaller();
+ Events events = (Events) unmarshaller.unmarshal(managixEventFile);
+ EventDriver.setHomeDir(managixHome + File.separator + MANAGIX_INTERNAL_DIR + File.separator + EVENTS_DIR);
+ EventDriver.setEvents(events);
+
+ hyracksServerZip = initBinary("hyracks-server");
+ hyracksClientZip = initBinary("hyracks-cli");
+ ManagixUtil.unzip(hyracksClientZip, getHyracksClientHome());
+ asterixZip = initBinary("asterix-app");
+
+ ILookupService lookupService = ServiceProvider.INSTANCE.getLookupService();
+ if (!lookupService.isRunning(conf)) {
+ lookupService.startService(conf);
+ }
+ }
+
+ private static String initBinary(final String fileNamePattern) {
+ String asterixDir = ManagixDriver.getAsterixDir();
+ File file = new File(asterixDir);
+ File[] zipFiles = file.listFiles(new FileFilter() {
+ public boolean accept(File arg0) {
+ return arg0.getAbsolutePath().contains(fileNamePattern) && arg0.isFile();
+ }
+ });
+ if (zipFiles.length == 0) {
+ String msg = " Binary not found at " + asterixDir;
+ LOGGER.log(Level.SEVERE, msg);
+ throw new IllegalStateException(msg);
+ }
+ if (zipFiles.length > 1) {
+ String msg = " Multiple binaries found at " + asterixDir;
+ LOGGER.log(Level.SEVERE, msg);
+ throw new IllegalStateException(msg);
+ }
+
+ return zipFiles[0].getAbsolutePath();
+ }
+
+ public static String getManagixHome() {
+ return managixHome;
+ }
+
+ public static String getAsterixDir() {
+ return managixHome + File.separator + ASTERIX_DIR;
+ }
+
+ public static void main(String args[]) {
+ try {
+ if (args.length != 0) {
+ initConfig();
+ CommandHandler cmdHandler = new CommandHandler();
+ cmdHandler.processCommand(args);
+ } else {
+ printUsage();
+ }
+ } catch (IllegalArgumentException iae) {
+ LOGGER.log(Level.SEVERE, "Unknown command");
+ printUsage();
+ } catch (Exception e) {
+ LOGGER.log(Level.SEVERE, e.getMessage());
+ }
+ }
+
+ private static void printUsage() {
+ StringBuffer buffer = new StringBuffer("managix <command> <args>" + "\n");
+ buffer.append("Commands" + "\n");
+ buffer.append("create " + ":" + " Creates a new asterix instance" + "\n");
+ buffer.append("delete " + ":" + " Deletes an asterix instance" + "\n");
+ buffer.append("start " + ":" + " Starts an asterix instance" + "\n");
+ buffer.append("stop " + ":" + " Stops an asterix instance that is in ACTIVE state" + "\n");
+ buffer.append("backup " + ":" + " Creates a back up for an existing asterix instance" + "\n");
+ buffer.append("restore " + ":" + " Restores an asterix instance" + "\n");
+ buffer.append("alter " + ":" + " Alters the configuration for an existing asterix instance" + "\n");
+ buffer.append("describe " + ":" + " Describes an existing asterix instance" + "\n");
+ LOGGER.log(Level.INFO, buffer.toString());
+ }
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/ManagixUtil.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/ManagixUtil.java
new file mode 100644
index 0000000..85dcf1e
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/ManagixUtil.java
@@ -0,0 +1,300 @@
+/*
+ * 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.installer.driver;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+import java.util.Random;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+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.installer.error.ManagixException;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class ManagixUtil {
+
+ public static AsterixInstance createAsterixInstance(String asterixInstanceName, Cluster cluster, String asterixConf)
+ throws FileNotFoundException, IOException {
+ Properties asterixConfProp = getAsterixConfiguration(asterixConf);
+ Node metadataNode = getMetadataNode(cluster);
+ String asterixZipName = ManagixDriver.getAsterixZip().substring(
+ ManagixDriver.getAsterixZip().lastIndexOf(File.separator) + 1);
+ String asterixVersion = asterixZipName.substring("asterix-app-".length(),
+ asterixZipName.indexOf("-binary-assembly"));
+ String hyracksZipName = ManagixDriver.getHyrackServerZip().substring(
+ ManagixDriver.getHyrackServerZip().lastIndexOf(File.separator) + 1);
+ String hyracksVersion = hyracksZipName.substring("hyracks-server-".length(),
+ hyracksZipName.indexOf("-binary-assembly"));
+ AsterixInstance instance = new AsterixInstance(asterixInstanceName, cluster, asterixConfProp,
+ metadataNode.getId(), asterixVersion, hyracksVersion);
+ return instance;
+ }
+
+ public static void createAsterixZip(AsterixInstance asterixInstance, boolean newDeployment) throws IOException {
+ writeAsterixConfigurationFile(asterixInstance, newDeployment);
+ String asterixInstanceDir = ManagixDriver.getAsterixDir() + File.separator + asterixInstance.getName();
+ unzip(ManagixDriver.getAsterixZip(), asterixInstanceDir);
+ File sourceJar = new File(asterixInstanceDir + File.separator + "lib" + File.separator + "asterix-app-"
+ + asterixInstance.getAsterixVersion() + ".jar");
+ String origFile = "test.properties";
+ File replacementFile = new File(asterixInstanceDir + File.separator + "test.properties");
+ replaceInJar(sourceJar, origFile, replacementFile);
+ new File(asterixInstanceDir + File.separator + "test.properties").delete();
+ String asterixZipName = ManagixDriver.getAsterixZip().substring(
+ ManagixDriver.getAsterixZip().lastIndexOf(File.separator) + 1);
+ zipDir(new File(asterixInstanceDir), new File(asterixInstanceDir + File.separator + asterixZipName));
+
+ }
+
+ private static Node getMetadataNode(Cluster cluster) {
+ Random random = new Random();
+ int nNodes = cluster.getNode().size();
+ return cluster.getNode().get(random.nextInt(nNodes));
+ }
+
+ private static void writeAsterixConfigurationFile(AsterixInstance asterixInstance, boolean newData)
+ throws IOException {
+ String asterixInstanceName = asterixInstance.getName();
+ Cluster cluster = asterixInstance.getCluster();
+ String metadataNodeId = asterixInstance.getMetadataNodeId();
+
+ StringBuffer conf = new StringBuffer();
+ conf.append("MetadataNode=" + asterixInstanceName + "_" + metadataNodeId + "\n");
+ conf.append("NewUniverse=" + newData + "\n");
+
+ for (Node node : cluster.getNode()) {
+ StringBuffer nodeDataStore = new StringBuffer();
+ if (node.getStore() != null) {
+ String[] nodeStores = node.getStore().split(",");
+ for (String ns : nodeStores) {
+ nodeDataStore.append(ns + File.separator + asterixInstanceName + File.separator);
+ nodeDataStore.append(",");
+ }
+ nodeDataStore.deleteCharAt(nodeDataStore.length() - 1);
+ } else {
+ if (cluster.getStore() != null) {
+ String[] nodeStores = cluster.getStore().split(",");
+ for (String ns : nodeStores) {
+ nodeDataStore.append(ns + File.separator + node.getId() + File.separator + asterixInstanceName
+ + File.separator);
+ nodeDataStore.append(",");
+ }
+ nodeDataStore.deleteCharAt(nodeDataStore.length() - 1);
+ }
+ }
+ if (nodeDataStore.length() == 0) {
+ throw new IllegalStateException(" Store not defined for node " + node.getId());
+ }
+ conf.append(asterixInstanceName + "_" + node.getId() + ".stores" + "=" + nodeDataStore
+ + "\n");
+
+ }
+ Properties asterixConfProp = asterixInstance.getConfiguration();
+ String outpuDir = asterixConfProp.getProperty("output_dir");
+ conf.append("OutputDir=" + outpuDir);
+ File asterixConfDir = new File(ManagixDriver.getAsterixDir() + File.separator + asterixInstanceName);
+ asterixConfDir.mkdirs();
+ dumpToFile(ManagixDriver.getAsterixDir() + File.separator + asterixInstanceName + File.separator
+ + "test.properties", conf.toString());
+ }
+
+ public static Properties getAsterixConfiguration(String asterixConf) throws FileNotFoundException, IOException {
+ Properties prop = new Properties();
+ prop.load(new FileInputStream(asterixConf));
+ return prop;
+ }
+
+ public static void unzip(String sourceFile, String destDir) throws IOException {
+ BufferedOutputStream dest = null;
+ FileInputStream fis = new FileInputStream(sourceFile);
+ ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
+ ZipEntry entry = null;
+
+ int BUFFER_SIZE = 4096;
+ while ((entry = zis.getNextEntry()) != null) {
+ String dst = destDir + File.separator + entry.getName();
+ if (entry.isDirectory()) {
+ createDir(destDir, entry);
+ continue;
+ }
+ int count;
+ byte data[] = new byte[BUFFER_SIZE];
+
+ //write the file to the disk
+ FileOutputStream fos = new FileOutputStream(dst);
+ dest = new BufferedOutputStream(fos, BUFFER_SIZE);
+ while ((count = zis.read(data, 0, BUFFER_SIZE)) != -1) {
+ dest.write(data, 0, count);
+ }
+ //close the output streams
+ dest.flush();
+ dest.close();
+ }
+
+ zis.close();
+ }
+
+ public static void zipDir(File sourceDir, File destFile) throws IOException {
+ FileOutputStream fos = new FileOutputStream(destFile);
+ ZipOutputStream zos = new ZipOutputStream(fos);
+ zipDir(sourceDir, destFile, zos);
+ zos.close();
+ }
+
+ private static void zipDir(File sourceDir, final File destFile, ZipOutputStream zos) throws IOException {
+ File[] dirList = sourceDir.listFiles(new FileFilter() {
+ public boolean accept(File f) {
+ return !f.getName().endsWith(destFile.getName());
+ }
+ });
+ for (int i = 0; i < dirList.length; i++) {
+ File f = dirList[i];
+ if (f.isDirectory()) {
+ zipDir(f, destFile, zos);
+ } else {
+ int bytesIn = 0;
+ byte[] readBuffer = new byte[2156];
+ FileInputStream fis = new FileInputStream(f);
+ ZipEntry entry = new ZipEntry(sourceDir.getName() + File.separator + f.getName());
+ zos.putNextEntry(entry);
+ while ((bytesIn = fis.read(readBuffer)) != -1) {
+ zos.write(readBuffer, 0, bytesIn);
+ }
+ fis.close();
+ }
+ }
+ }
+
+ private static void replaceInJar(File sourceJar, String origFile, File replacementFile) throws IOException {
+ File destJar = new File(sourceJar.getAbsolutePath() + ".modified");
+ InputStream jarIs = null;
+ FileInputStream fis = new FileInputStream(replacementFile);
+ JarFile sourceJarFile = new JarFile(sourceJar);
+ Enumeration<JarEntry> entries = sourceJarFile.entries();
+ JarOutputStream jos = new JarOutputStream(new FileOutputStream(destJar));
+ byte[] buffer = new byte[2048];
+ int read;
+ while (entries.hasMoreElements()) {
+ JarEntry entry = (JarEntry) entries.nextElement();
+ String name = entry.getName();
+ if (name.equals(origFile)) {
+ continue;
+ }
+ jarIs = sourceJarFile.getInputStream(entry);
+ jos.putNextEntry(entry);
+ while ((read = jarIs.read(buffer)) != -1) {
+ jos.write(buffer, 0, read);
+ }
+ }
+ JarEntry entry = new JarEntry(origFile);
+ jos.putNextEntry(entry);
+ while ((read = fis.read(buffer)) != -1) {
+ jos.write(buffer, 0, read);
+ }
+ fis.close();
+ jos.close();
+ jarIs.close();
+ sourceJar.delete();
+ destJar.renameTo(sourceJar);
+ sourceJar.setExecutable(true);
+ }
+
+ public static void dumpToFile(String dest, String content) throws IOException {
+ FileWriter writer = new FileWriter(dest);
+ writer.write(content);
+ writer.close();
+ }
+
+ private static void createDir(String destDirectory, ZipEntry entry) {
+ String name = entry.getName();
+ int index = name.lastIndexOf(File.separator);
+ String dirSequence = name.substring(0, index);
+ File newDirs = new File(destDirectory + File.separator + dirSequence);
+ newDirs.mkdirs();
+ }
+
+ public static AsterixInstance validateAsterixInstanceExists(String name, State... permissibleStates)
+ throws Exception {
+ AsterixInstance instance = ServiceProvider.INSTANCE.getLookupService().getAsterixInstance(name);
+ if (instance == null) {
+ throw new ManagixException(" Asterix instance by name " + name + " does not exist.");
+ }
+ boolean valid = false;
+ for (State state : permissibleStates) {
+ if (state.equals(instance.getState())) {
+ valid = true;
+ break;
+ }
+ }
+ if (!valid) {
+ throw new ManagixException(" Asterix instance by the name " + name + " is in " + instance.getState()
+ + " state ");
+ }
+ return instance;
+ }
+
+ public static void validateAsterixInstanceNotExists(String name) throws Exception {
+ AsterixInstance instance = ServiceProvider.INSTANCE.getLookupService().getAsterixInstance(name);
+ if (instance != null) {
+ throw new ManagixException(" Asterix instance by name " + name + " already exists.");
+ }
+ }
+
+ public static void deleteDirectory(String path) throws IOException {
+ Runtime.getRuntime().exec("rm -rf " + path);
+ }
+
+ public static String executeLocalScript(String path, List<String> args) throws Exception {
+ List<String> pargs = new ArrayList<String>();
+ pargs.add("/bin/bash");
+ pargs.add(path);
+ if (args != null) {
+ pargs.addAll(args);
+ }
+ ProcessBuilder pb = new ProcessBuilder(pargs);
+ pb.environment().putAll(EventDriver.getEnvironment());
+ pb.environment().put("IP_LOCATION", EventDriver.CLIENT_NODE.getIp());
+ Process p = pb.start();
+ BufferedInputStream bis = new BufferedInputStream(p.getInputStream());
+ StringWriter writer = new StringWriter();
+ IOUtils.copy(bis, writer, "UTF-8");
+ return writer.toString();
+ }
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/ManagixException.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/ManagixException.java
new file mode 100644
index 0000000..e13a2f4
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/ManagixException.java
@@ -0,0 +1,25 @@
+/*
+ * 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.installer.error;
+
+public class ManagixException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public ManagixException(String message) {
+ super(message);
+ }
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/OutputHandler.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/OutputHandler.java
new file mode 100644
index 0000000..c5ad2a4
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/OutputHandler.java
@@ -0,0 +1,92 @@
+/*
+ * 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.installer.error;
+
+import edu.uci.ics.asterix.event.management.IOutputHandler;
+import edu.uci.ics.asterix.event.management.OutputAnalysis;
+import edu.uci.ics.asterix.event.schema.pattern.Event;
+import edu.uci.ics.asterix.installer.model.EventList.EventType;
+
+public class OutputHandler implements IOutputHandler {
+
+ public static IOutputHandler INSTANCE = new OutputHandler();
+
+ private OutputHandler() {
+
+ }
+
+ public OutputAnalysis reportEventOutput(Event event, String output) {
+
+ EventType eventType = EventType.valueOf(event.getType().toUpperCase());
+ boolean ignore = true;
+ String trimmedOutput = output.trim();
+ StringBuffer errorMessage = new StringBuffer();
+ switch (eventType) {
+ case FILE_TRANSFER:
+ if (trimmedOutput.length() > 0) {
+ if (!output.contains("Permission denied") || output.contains("does not exist")
+ || output.contains("File exist")) {
+ ignore = true;
+ } else {
+ ignore = false;
+ }
+ }
+ break;
+
+ case BACKUP:
+ if (trimmedOutput.length() > 0) {
+ if (trimmedOutput.contains("AccessControlException")) {
+ errorMessage.append("Insufficient permissions on HDFS back up directory");
+ ignore = false;
+ }
+ if (output.contains("does not exist") || output.contains("File exist")) {
+ ignore = true;
+ } else {
+ ignore = false;
+ }
+ }
+ break;
+
+ case RESTORE:
+ if (trimmedOutput.length() > 0) {
+ if (trimmedOutput.contains("AccessControlException")) {
+ errorMessage.append("Insufficient permissions on HDFS back up directory");
+ ignore = false;
+ }
+ if (output.contains("does not exist") || output.contains("File exist")) {
+ ignore = true;
+ } else {
+ ignore = false;
+ }
+ }
+ break;
+
+ case ASTERIX_DEPLOY:
+ if (trimmedOutput.length() > 0) {
+ if (trimmedOutput.contains("Exception")) {
+ ignore = false;
+ errorMessage.append("Error in deploying Asterix: " + output);
+ errorMessage.append("\nStop the instance to initiate a cleanup");
+ }
+ }
+ }
+ if (ignore) {
+ return new OutputAnalysis(true, null);
+ } else {
+ return new OutputAnalysis(false, errorMessage.toString());
+ }
+ }
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/VerificationUtil.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/VerificationUtil.java
new file mode 100644
index 0000000..f4634a5
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/VerificationUtil.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.installer.error;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.event.schema.cluster.Cluster;
+import edu.uci.ics.asterix.event.schema.cluster.Node;
+import edu.uci.ics.asterix.installer.driver.ManagixDriver;
+import edu.uci.ics.asterix.installer.driver.ManagixUtil;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixRuntimeState;
+import edu.uci.ics.asterix.installer.model.ProcessInfo;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+
+public class VerificationUtil {
+
+ private static final String VERIFY_SCRIPT_PATH = ManagixDriver.getManagixHome() + File.separator
+ + ManagixDriver.MANAGIX_INTERNAL_DIR + File.separator + "scripts" + File.separator + "verify.sh";
+
+ public static AsterixRuntimeState getAsterixRuntimeState(AsterixInstance instance) throws Exception {
+
+ Cluster cluster = instance.getCluster();
+ List<String> args = new ArrayList<String>();
+ args.add(instance.getName());
+ args.add(instance.getCluster().getMasterNode().getIp());
+ for (Node node : cluster.getNode()) {
+ args.add(node.getIp());
+ args.add(instance.getName() + "_" + node.getId());
+ }
+
+ String output = ManagixUtil.executeLocalScript(VERIFY_SCRIPT_PATH, args);
+ boolean ccRunning = true;
+ List<String> failedNCs = new ArrayList<String>();
+ String[] infoFields;
+ ProcessInfo pInfo;
+ List<ProcessInfo> processes = new ArrayList<ProcessInfo>();
+
+ for (String line : output.split("\n")) {
+ infoFields = line.split(":");
+ try {
+ int pid = Integer.parseInt(infoFields[3]);
+ pInfo = new ProcessInfo(infoFields[0], infoFields[1], pid);
+ processes.add(pInfo);
+ } catch (Exception e) {
+ if (infoFields[0].equalsIgnoreCase("CC")) {
+ ccRunning = false;
+ } else {
+ failedNCs.add(infoFields[1]);
+ }
+ }
+ }
+ return new AsterixRuntimeState(processes, failedNCs, ccRunning);
+ }
+
+ public static void updateInstanceWithRuntimeDescription(AsterixInstance instance, AsterixRuntimeState state,
+ boolean expectedRunning) {
+ StringBuffer summary = new StringBuffer();
+ if (expectedRunning) {
+ if (!state.isCcRunning()) {
+ summary.append("Cluster Controller not running at " + instance.getCluster().getMasterNode().getIp()
+ + "\n");
+ instance.setState(State.UNUSABLE);
+ }
+ if (state.getFailedNCs() != null && !state.getFailedNCs().isEmpty()) {
+ summary.append("Node Controller not running at the following nodes" + "\n");
+ for (String failedNC : state.getFailedNCs()) {
+ summary.append(failedNC + "\n");
+ }
+ instance.setState(State.UNUSABLE);
+ }
+ if (!(instance.getState().equals(State.UNUSABLE))) {
+ instance.setState(State.ACTIVE);
+ }
+ } else {
+ if (state.getProcesses() != null && state.getProcesses().size() > 0) {
+ summary.append("Following process still running " + "\n");
+ for (ProcessInfo pInfo : state.getProcesses()) {
+ summary.append(pInfo + "\n");
+ }
+ instance.setState(State.UNUSABLE);
+ } else {
+ instance.setState(State.INACTIVE);
+ }
+ }
+ state.setSummary(summary.toString());
+ instance.setAsterixRuntimeStates(state);
+ }
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/events/PatternCreator.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/events/PatternCreator.java
new file mode 100644
index 0000000..8fe00ab
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/events/PatternCreator.java
@@ -0,0 +1,279 @@
+/*
+ * 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.installer.events;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+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.MasterNode;
+import edu.uci.ics.asterix.event.schema.cluster.Node;
+import edu.uci.ics.asterix.event.schema.pattern.Delay;
+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;
+import edu.uci.ics.asterix.installer.command.StopCommand;
+import edu.uci.ics.asterix.installer.driver.ManagixDriver;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.service.ILookupService;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class PatternCreator {
+
+ private static final Logger LOGGER = Logger.getLogger(PatternCreator.class.getName());
+ private ILookupService lookupService = ServiceProvider.INSTANCE.getLookupService();
+ private static int CC_DEBUG_PORT = 8800;
+ private static int NC_DEBUG_PORT = 8701;
+
+ private void addInitialDelay(Pattern p, int delay, String unit) {
+ Delay d = new Delay(new Value(null, "" + delay), unit);
+ p.setDelay(d);
+ }
+
+ public Patterns getStartAsterixPattern(String asterixInstanceName, Cluster cluster) throws Exception {
+ String ccLocationId = cluster.getMasterNode().getId();
+ String ccLocationIp = cluster.getMasterNode().getIp();
+
+ String destDir = cluster.getWorkingDir().getDir() + File.separator + "hyracks";
+ List<Pattern> ps = new ArrayList<Pattern>();
+
+ Pattern createCC = createCCStartPattern(ccLocationId);
+ addInitialDelay(createCC, 2, "sec");
+ ps.add(createCC);
+
+ Pattern copyHyracks = createCopyHyracksPattern(cluster, ccLocationIp, destDir);
+ ps.add(copyHyracks);
+
+ boolean copyHyracksToNC = !cluster.getWorkingDir().isNFS();
+ for (Node node : cluster.getNode()) {
+ if (copyHyracksToNC) {
+ Pattern copyHyracksForNC = createCopyHyracksPattern(cluster, node.getIp(), destDir);
+ ps.add(copyHyracksForNC);
+ }
+ Pattern createNC = createNCStartPattern(cluster.getMasterNode().getIp(), node.getId(), asterixInstanceName
+ + "_" + node.getId());
+ addInitialDelay(createNC, 3, "sec");
+ ps.add(createNC);
+ }
+
+ Pattern asterixDeploy = createAsterixDeployPattern(asterixInstanceName, cluster);
+ addInitialDelay(asterixDeploy, 4, "sec");
+ ps.add(asterixDeploy);
+
+ Patterns patterns = new Patterns(ps);
+ patterns.getPattern().addAll(createHadoopLibraryTransferPattern(cluster).getPattern());
+ return patterns;
+ }
+
+ public Patterns getStopCommandPattern(StopCommand stopCommand) throws Exception {
+ List<Pattern> ps = new ArrayList<Pattern>();
+ AsterixInstance asterixInstance = lookupService.getAsterixInstance(stopCommand.getAsterixInstanceName());
+ Cluster cluster = asterixInstance.getCluster();
+
+ String ccLocation = cluster.getMasterNode().getId();
+ Pattern createCC = createCCStopPattern(ccLocation);
+ addInitialDelay(createCC, 5, "sec");
+ ps.add(createCC);
+
+ String asterixInstanceName = stopCommand.getAsterixInstanceName();
+ int nodeControllerIndex = 1;
+ for (Node node : cluster.getNode()) {
+ Pattern createNC = createNCStopPattern(node.getId(), asterixInstanceName + "_" + nodeControllerIndex);
+ ps.add(createNC);
+ nodeControllerIndex++;
+ }
+
+ Patterns patterns = new Patterns(ps);
+ return patterns;
+ }
+
+ public Patterns getBackUpAsterixPattern(AsterixInstance instance, String backupPath) throws Exception {
+ Cluster cluster = instance.getCluster();
+ String clusterStore = instance.getCluster().getStore();
+ String hdfsUrl = ManagixDriver.getConfiguration().getBackup().getHdfs().getUrl();
+ String hadoopVersion = ManagixDriver.getConfiguration().getBackup().getHdfs().getVersion();
+ String hdfsBackupDir = ManagixDriver.getConfiguration().getBackup().getHdfs().getBackupDir();
+ String workingDir = cluster.getWorkingDir().getDir();
+ String backupId = "" + instance.getBackupInfo().size();
+ String nodeStore;
+ String pargs;
+ List<Pattern> patternList = new ArrayList<Pattern>();
+ for (Node node : cluster.getNode()) {
+ Nodeid nodeid = new Nodeid(new Value(null, node.getId()));
+ nodeStore = node.getStore() == null ? clusterStore : node.getStore();
+ pargs = workingDir + " " + instance.getName() + " " + nodeStore + " " + backupId + " " + hdfsUrl + " "
+ + hadoopVersion + " " + hdfsBackupDir + " " + node.getId();
+ Event event = new Event("backup", nodeid, pargs);
+ patternList.add(new Pattern(null, 1, null, event));
+ }
+ return new Patterns(patternList);
+ }
+
+ public Patterns getRestoreAsterixPattern(AsterixInstance instance, int backupId) throws Exception {
+ Cluster cluster = instance.getCluster();
+ String clusterStore = instance.getCluster().getStore();
+ String hdfsUrl = ManagixDriver.getConfiguration().getBackup().getHdfs().getUrl();
+ String hadoopVersion = ManagixDriver.getConfiguration().getBackup().getHdfs().getVersion();
+ String hdfsBackupDir = ManagixDriver.getConfiguration().getBackup().getHdfs().getBackupDir();
+ String workingDir = cluster.getWorkingDir().getDir();
+ String nodeStore;
+ String pargs;
+ List<Pattern> patternList = new ArrayList<Pattern>();
+ for (Node node : cluster.getNode()) {
+ Nodeid nodeid = new Nodeid(new Value(null, node.getId()));
+ nodeStore = node.getStore() == null ? clusterStore : node.getStore();
+ pargs = workingDir + " " + instance.getName() + " " + nodeStore + " " + backupId + " " + hdfsUrl + " "
+ + hadoopVersion + " " + hdfsBackupDir + " " + node.getId();
+ Event event = new Event("restore", nodeid, pargs);
+ patternList.add(new Pattern(null, 1, null, event));
+ }
+ return new Patterns(patternList);
+ }
+
+ public Patterns createHadoopLibraryTransferPattern(Cluster cluster) throws Exception {
+ List<Pattern> patternList = new ArrayList<Pattern>();
+ String workingDir = cluster.getWorkingDir().getDir();
+ String hadoopVersion = ManagixDriver.getConfiguration().getBackup().getHdfs().getVersion();
+ File hadoopTar = new File(ManagixDriver.getManagixHome() + File.separator + ManagixDriver.MANAGIX_INTERNAL_DIR
+ + File.separator + "hadoop" + File.separator + "hadoop-" + hadoopVersion + ".tar");
+ if (!hadoopTar.exists()) {
+ throw new IllegalStateException("Hadoop version :" + hadoopVersion + " not supported");
+ }
+
+ Nodeid nodeid = new Nodeid(new Value(null, EventDriver.CLIENT_NODE.getId()));
+ String username = cluster.getUsername() != null ? cluster.getUsername() : System.getProperty("user.name");
+ String pargs = username + " " + hadoopTar.getAbsolutePath() + " " + cluster.getMasterNode().getIp() + " "
+ + workingDir + " " + "unpack";
+ Event event = new Event("file_transfer", nodeid, pargs);
+ Pattern p = new Pattern(null, 1, null, event);
+ addInitialDelay(p, 2, "sec");
+ patternList.add(p);
+
+ boolean copyToNC = !cluster.getWorkingDir().isNFS();
+ if (copyToNC) {
+ for (Node node : cluster.getNode()) {
+ nodeid = new Nodeid(new Value(null, node.getId()));
+ pargs = cluster.getUsername() + " " + hadoopTar.getAbsolutePath() + " " + node.getIp() + " "
+ + workingDir + " " + "unpack";
+ event = new Event("file_transfer", nodeid, pargs);
+ p = new Pattern(null, 1, null, event);
+ addInitialDelay(p, 2, "sec");
+ patternList.add(p);
+ }
+ }
+ Patterns patterns = new Patterns(patternList);
+ return patterns;
+ }
+
+ public Patterns createDeleteInstancePattern(AsterixInstance instance) throws Exception {
+ List<Pattern> patternList = new ArrayList<Pattern>();
+ patternList.addAll(createRemoveAsterixStoragePattern(instance).getPattern());
+ if (instance.getBackupInfo() != null && instance.getBackupInfo().size() > 0) {
+ patternList.addAll(createRemoveHDFSBackupPattern(instance).getPattern());
+ }
+ Patterns patterns = new Patterns(patternList);
+ return patterns;
+ }
+
+ private Patterns createRemoveHDFSBackupPattern(AsterixInstance instance) throws Exception {
+ List<Pattern> patternList = new ArrayList<Pattern>();
+ Cluster cluster = instance.getCluster();
+ String hdfsUrl = ManagixDriver.getConfiguration().getBackup().getHdfs().getUrl();
+ String hadoopVersion = ManagixDriver.getConfiguration().getBackup().getHdfs().getVersion();
+ String hdfsBackupDir = ManagixDriver.getConfiguration().getBackup().getHdfs().getBackupDir();
+ String workingDir = cluster.getWorkingDir().getDir();
+ Node launchingNode = cluster.getNode().get(0);
+ Nodeid nodeid = new Nodeid(new Value(null, launchingNode.getId()));
+ String pathToDelete = hdfsBackupDir + File.separator + instance.getName();
+ String pargs = workingDir + " " + hadoopVersion + " " + hdfsUrl + " " + pathToDelete;
+ Event event = new Event("hdfs_delete", nodeid, pargs);
+ patternList.add(new Pattern(null, 1, null, event));
+ Patterns patterns = new Patterns(patternList);
+ return patterns;
+ }
+
+ private Patterns createRemoveAsterixStoragePattern(AsterixInstance instance) throws Exception {
+ List<Pattern> patternList = new ArrayList<Pattern>();
+ Cluster cluster = instance.getCluster();
+ String clusterStore = cluster.getStore();
+ String nodeStore;
+ String pargs;
+
+ for (Node node : cluster.getNode()) {
+ Nodeid nodeid = new Nodeid(new Value(null, node.getId()));
+ nodeStore = node.getStore() == null ? clusterStore + File.separator + node.getId() : node.getStore();
+ String[] nodeStores = nodeStore.split(",");
+ for (String ns : nodeStores) {
+ pargs = ns + File.separator + node.getId() + instance.getName();
+ Event event = new Event("file_delete", nodeid, pargs);
+ patternList.add(new Pattern(null, 1, null, event));
+ }
+ }
+ Patterns patterns = new Patterns(patternList);
+ return patterns;
+ }
+
+ private Pattern createCopyHyracksPattern(Cluster cluster, String destinationIp, String destDir) {
+ Nodeid nodeid = new Nodeid(new Value(null, EventDriver.CLIENT_NODE.getId()));
+ String username = cluster.getUsername() != null ? cluster.getUsername() : System.getProperty("user.name");
+ String pargs = username + " " + ManagixDriver.getHyrackServerZip() + " " + destinationIp + " " + destDir + " "
+ + "unpack";
+ Event event = new Event("file_transfer", nodeid, pargs);
+ return new Pattern(null, 1, null, event);
+ }
+
+ private Pattern createCCStartPattern(String hostId) {
+ Nodeid nodeid = new Nodeid(new Value(null, hostId));
+ Event event = new Event("cc_start", nodeid, "" + CC_DEBUG_PORT);
+ CC_DEBUG_PORT++;
+ return new Pattern(null, 1, null, event);
+ }
+
+ public Pattern createCCStopPattern(String hostId) {
+ Nodeid nodeid = new Nodeid(new Value(null, hostId));
+ Event event = new Event("cc_failure", nodeid, null);
+ return new Pattern(null, 1, null, event);
+ }
+
+ public Pattern createNCStartPattern(String ccHost, String hostId, String nodeControllerId) {
+ Nodeid nodeid = new Nodeid(new Value(null, hostId));
+ Event event = new Event("node_join", nodeid, ccHost + " " + nodeControllerId + " " + NC_DEBUG_PORT);
+ NC_DEBUG_PORT++;
+ return new Pattern(null, 1, null, event);
+ }
+
+ public Pattern createNCStopPattern(String hostId, String nodeControllerId) {
+ Nodeid nodeid = new Nodeid(new Value(null, hostId));
+ Event event = new Event("node_failure", nodeid, nodeControllerId);
+ return new Pattern(null, 1, null, event);
+ }
+
+ private Pattern createAsterixDeployPattern(String asterixInstanceName, Cluster cluster) {
+ Nodeid nodeid = new Nodeid(new Value(null, EventDriver.CLIENT_NODE.getId()));
+ String asterixZipName = ManagixDriver.getAsterixZip().substring(
+ ManagixDriver.getAsterixZip().lastIndexOf(File.separator) + 1);
+ String asterixInstanceZip = ManagixDriver.getAsterixDir() + File.separator + asterixInstanceName
+ + File.separator + asterixZipName;
+ Event event = new Event("asterix_deploy", nodeid, ManagixDriver.getManagixHome() + " " + asterixInstanceZip
+ + " " + cluster.getMasterNode().getIp());
+ return new Pattern(null, 1, null, event);
+ }
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/AsterixInstance.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/AsterixInstance.java
new file mode 100644
index 0000000..d1a6485
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/AsterixInstance.java
@@ -0,0 +1,195 @@
+/*
+ * 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.installer.model;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Properties;
+
+import edu.uci.ics.asterix.event.schema.cluster.Cluster;
+import edu.uci.ics.asterix.event.schema.cluster.Node;
+
+public class AsterixInstance implements Serializable {
+
+ private static final long serialVersionUID = 2874439550187520449L;
+
+ public enum State {
+ ACTIVE,
+ INACTIVE,
+ UNUSABLE
+ }
+
+ private final Cluster cluster;
+ private final String name;
+ private final Date createdTimestamp;
+ private Date stateChangeTimestamp;
+ private Date modifiedTimestamp;
+ private Properties configuration;
+ private State state;
+ private final String metadataNodeId;
+ private final String asterixVersion;
+ private final String hyracksVersion;
+ private final List<BackupInfo> backupInfo;
+ private final String webInterfaceUrl;
+ private AsterixRuntimeState runtimeState;
+ private State previousState;
+
+ public AsterixInstance(String name, Cluster cluster, Properties configuration, String metadataNodeId,
+ String asterixVersion, String hyracksVersion) {
+ this.name = name;
+ this.cluster = cluster;
+ this.configuration = configuration;
+ this.metadataNodeId = metadataNodeId;
+ this.state = State.ACTIVE;
+ this.previousState = State.UNUSABLE;
+ this.asterixVersion = asterixVersion;
+ this.hyracksVersion = hyracksVersion;
+ this.createdTimestamp = new Date();
+ this.backupInfo = new ArrayList<BackupInfo>();
+ this.webInterfaceUrl = "http://" + cluster.getMasterNode().getIp() + ":" + 19001;
+ }
+
+ public Date getModifiedTimestamp() {
+ return stateChangeTimestamp;
+ }
+
+ public Properties getConfiguration() {
+ return configuration;
+ }
+
+ public void setConfiguration(Properties properties) {
+ this.configuration = properties;
+ }
+
+ public State getState() {
+ return state;
+ }
+
+ public void setState(State state) {
+ this.previousState = this.state;
+ this.state = state;
+ }
+
+ public Cluster getCluster() {
+ return cluster;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Date getCreatedTimestamp() {
+ return createdTimestamp;
+ }
+
+ public Date getStateChangeTimestamp() {
+ return stateChangeTimestamp;
+ }
+
+ public void setStateChangeTimestamp(Date stateChangeTimestamp) {
+ this.stateChangeTimestamp = stateChangeTimestamp;
+ }
+
+ public void setModifiedTimestamp(Date modifiedTimestamp) {
+ this.modifiedTimestamp = modifiedTimestamp;
+ }
+
+ public String getMetadataNodeId() {
+ return metadataNodeId;
+ }
+
+ public String getAsterixVersion() {
+ return asterixVersion;
+ }
+
+ public String getHyracksVersion() {
+ return hyracksVersion;
+ }
+
+ public String getDescription(boolean detailed) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("Name:" + name + "\n");
+ buffer.append("Created:" + createdTimestamp + "\n");
+ buffer.append("Web-Url:" + webInterfaceUrl + "\n");
+ buffer.append("State:" + state);
+ if (!state.equals(State.UNUSABLE) && stateChangeTimestamp != null) {
+ buffer.append(" (" + stateChangeTimestamp + ")" + "\n");
+ } else {
+ buffer.append("\n");
+ }
+ if (modifiedTimestamp != null) {
+ buffer.append("Last modified timestamp:" + modifiedTimestamp + "\n");
+ }
+
+ if (runtimeState.getSummary() != null && runtimeState.getSummary().length() > 0) {
+ buffer.append("\nWARNING!:" + runtimeState.getSummary() + "\n");
+ }
+ if (detailed) {
+ addDetailedInformation(buffer);
+ }
+ buffer.append("\n");
+ return buffer.toString();
+ }
+
+ public List<BackupInfo> getBackupInfo() {
+ return backupInfo;
+ }
+
+ public String getWebInterfaceUrl() {
+ return webInterfaceUrl;
+ }
+
+ public AsterixRuntimeState getAsterixRuntimeState() {
+ return runtimeState;
+ }
+
+ public void setAsterixRuntimeStates(AsterixRuntimeState runtimeState) {
+ this.runtimeState = runtimeState;
+ }
+
+ private void addDetailedInformation(StringBuffer buffer) {
+ buffer.append("Master node:" + cluster.getMasterNode().getId() + ":" + cluster.getMasterNode().getIp() + "\n");
+ for (Node node : cluster.getNode()) {
+ buffer.append(node.getId() + ":" + node.getIp() + "\n");
+ }
+
+ buffer.append("\n");
+ if (backupInfo != null && backupInfo.size() > 0) {
+ for (BackupInfo info : backupInfo) {
+ buffer.append("Backup:" + info.getId() + " created at " + info.getDate() + "\n");
+ }
+ }
+ buffer.append("\n");
+ buffer.append("Asterix version:" + asterixVersion + "\n");
+ buffer.append("Hyracks version:" + hyracksVersion + "\n");
+ buffer.append("Asterix Configuration" + "\n");
+ for (Entry<Object, Object> entry : configuration.entrySet()) {
+ buffer.append(entry.getKey() + " = " + entry.getValue() + "\n");
+ }
+ buffer.append("Metadata Node:" + metadataNodeId + "\n");
+ buffer.append("Processes" + "\n");
+ for (ProcessInfo pInfo : runtimeState.getProcesses()) {
+ buffer.append(pInfo + "\n");
+ }
+
+ }
+
+ public State getPreviousState() {
+ return previousState;
+ }
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/AsterixRuntimeState.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/AsterixRuntimeState.java
new file mode 100644
index 0000000..207c570
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/AsterixRuntimeState.java
@@ -0,0 +1,53 @@
+/*
+ * 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.installer.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+public class AsterixRuntimeState implements Serializable {
+
+ private final List<ProcessInfo> processes;
+ private final List<String> failedNCs;
+ private final boolean ccRunning;
+ private String summary;
+
+ public AsterixRuntimeState(List<ProcessInfo> processes, List<String> failedNCs, boolean ccRunning) {
+ this.processes = processes;
+ this.failedNCs = failedNCs;
+ this.ccRunning = ccRunning;
+ }
+
+ public List<ProcessInfo> getProcesses() {
+ return processes;
+ }
+
+ public List<String> getFailedNCs() {
+ return failedNCs;
+ }
+
+ public boolean isCcRunning() {
+ return ccRunning;
+ }
+
+ public void setSummary(String summary) {
+ this.summary = summary;
+ }
+
+ public String getSummary() {
+ return summary;
+ }
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/BackupInfo.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/BackupInfo.java
new file mode 100644
index 0000000..a5d2b36
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/BackupInfo.java
@@ -0,0 +1,43 @@
+/*
+ * 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.installer.model;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class BackupInfo implements Serializable {
+
+ private final int id;
+ private final Date date;
+
+ public BackupInfo(int id, Date date) {
+ this.id = id;
+ this.date = date;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ @Override
+ public String toString() {
+ return id + "_" + date;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/EventList.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/EventList.java
new file mode 100644
index 0000000..8d1486d
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/EventList.java
@@ -0,0 +1,29 @@
+/*
+ * 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.installer.model;
+
+public class EventList {
+
+ public enum EventType {
+ NODE_JOIN,
+ NODE_FAILURE,
+ CC_START,
+ CC_FAILURE,
+ ASTERIX_DEPLOY,
+ BACKUP,
+ RESTORE,
+ FILE_TRANSFER
+ }
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/ProcessInfo.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/ProcessInfo.java
new file mode 100644
index 0000000..2880671
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/ProcessInfo.java
@@ -0,0 +1,48 @@
+/*
+ * 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.installer.model;
+
+import java.io.Serializable;
+
+public class ProcessInfo implements Serializable {
+
+ private static final long serialVersionUID = 304186774065853730L;
+ private final String processName;
+ private final String host;
+ private final int processId;
+
+ public ProcessInfo(String processName, String host, int processId) {
+ this.processName = processName;
+ this.host = host;
+ this.processId = processId;
+ }
+
+ public String getProcessName() {
+ return processName;
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public int getProcessId() {
+ return processId;
+ }
+
+ public String toString() {
+ return processName + " at " + host + " [ " + processId + " ] ";
+ }
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ILookupService.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ILookupService.java
new file mode 100644
index 0000000..f258e66
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ILookupService.java
@@ -0,0 +1,39 @@
+/*
+ * 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.installer.service;
+
+import java.util.List;
+
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.schema.conf.Configuration;
+
+public interface ILookupService {
+
+ public void writeAsterixInstance(AsterixInstance asterixInstance) throws Exception;
+
+ public AsterixInstance getAsterixInstance(String name) throws Exception;
+
+ public boolean isRunning(Configuration conf) throws Exception;
+
+ public void startService(Configuration conf) throws Exception;
+
+ public boolean exists(String name) throws Exception;
+
+ public void removeAsterixInstance(String name) throws Exception;
+
+ public List<AsterixInstance> getAsterixInstances() throws Exception;
+
+ public void updateAsterixInstance(AsterixInstance updatedInstance) throws Exception;
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ServiceProvider.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ServiceProvider.java
new file mode 100644
index 0000000..1a9e9e6
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ServiceProvider.java
@@ -0,0 +1,30 @@
+/*
+ * 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.installer.service;
+
+public class ServiceProvider {
+
+ public static ServiceProvider INSTANCE = new ServiceProvider();
+ private static ILookupService lookupService = new ZooKeeperService();
+
+ private ServiceProvider() {
+
+ }
+
+ public ILookupService getLookupService() {
+ return lookupService;
+ }
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ZooKeeperService.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ZooKeeperService.java
new file mode 100644
index 0000000..ec6bd61
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ZooKeeperService.java
@@ -0,0 +1,221 @@
+/*
+ * 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.installer.service;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.Stat;
+
+import edu.uci.ics.asterix.installer.driver.ManagixDriver;
+import edu.uci.ics.asterix.installer.driver.ManagixUtil;
+import edu.uci.ics.asterix.installer.error.ManagixException;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.schema.conf.Configuration;
+
+public class ZooKeeperService implements ILookupService {
+
+ private static final Logger LOGGER = Logger.getLogger(ZooKeeperService.class.getName());
+
+ private static final int ZOOKEEPER_LEADER_CONN_PORT = 2222;
+ private static final int ZOOKEEPER_LEADER_ELEC_PORT = 2223;
+ private static final int ZOOKEEPER_SESSION_TIME_OUT = 40 * 1000; //milliseconds
+ private static final String ZOOKEEPER_HOME = ManagixDriver.getManagixHome() + File.separator
+ + ManagixDriver.MANAGIX_INTERNAL_DIR + File.separator + "zookeeper";
+ private static final String ZOO_KEEPER_CONFIG = ZOOKEEPER_HOME + File.separator + "zk.pkg" + File.separator
+ + "zk.cfg";
+
+ private boolean isRunning = false;
+ private ZooKeeper zk;
+ private String zkConnectionString;
+ private static final String ASTERIX_INSTANCE_BASE_PATH = "/asterix";
+ private static final int DEFAULT_NODE_VERSION = -1;
+ private LinkedBlockingQueue<String> msgQ = new LinkedBlockingQueue<String>();
+ private ZooKeeperWatcher watcher = new ZooKeeperWatcher(msgQ);
+
+ public boolean isRunning(Configuration conf) throws Exception {
+ LOGGER.setLevel(Level.WARNING);
+ List<String> servers = conf.getZookeeper().getServers().getServer();
+ int clientPort = conf.getZookeeper().getClientPort().intValue();
+ StringBuffer connectionString = new StringBuffer();
+ for (String serverAddress : servers) {
+ connectionString.append(serverAddress);
+ connectionString.append(":");
+ connectionString.append(clientPort);
+ connectionString.append(",");
+ }
+ if (connectionString.length() > 0) {
+ connectionString.deleteCharAt(connectionString.length() - 1);
+ }
+ zkConnectionString = connectionString.toString();
+
+ zk = new ZooKeeper(zkConnectionString, ZOOKEEPER_SESSION_TIME_OUT, watcher);
+ try {
+ zk.exists("/dummy", watcher);
+ if (LOGGER.isLoggable(Level.INFO)) {
+ LOGGER.info("ZooKeeper running at " + connectionString);
+ }
+ createRootIfNotExist();
+ isRunning = true;
+ } catch (KeeperException ke) {
+ isRunning = false;
+ }
+ return isRunning;
+ }
+
+ public void startService(Configuration conf) throws Exception {
+ LOGGER.info("Starting ZooKeeper at " + zkConnectionString);
+ ZookeeperUtil.writeConfiguration(ZOO_KEEPER_CONFIG, conf, ZOOKEEPER_LEADER_CONN_PORT,
+ ZOOKEEPER_LEADER_ELEC_PORT);
+ String initScript = ZOOKEEPER_HOME + File.separator + "zk.init";
+ StringBuffer cmdBuffer = new StringBuffer();
+ cmdBuffer.append(initScript + " ");
+ cmdBuffer.append(conf.getZookeeper().getHomeDir() + " ");
+ List<String> zkServers = conf.getZookeeper().getServers().getServer();
+ for (String zkServer : zkServers) {
+ cmdBuffer.append(zkServer + " ");
+ }
+ Runtime.getRuntime().exec(cmdBuffer.toString());
+ zk = new ZooKeeper(zkConnectionString, ZOOKEEPER_SESSION_TIME_OUT, watcher);
+ msgQ.take();
+ createRootIfNotExist();
+ }
+
+ public void writeAsterixInstance(AsterixInstance asterixInstance) throws Exception {
+ String instanceBasePath = ASTERIX_INSTANCE_BASE_PATH + File.separator + asterixInstance.getName();
+ ByteArrayOutputStream b = new ByteArrayOutputStream();
+ ObjectOutputStream o = new ObjectOutputStream(b);
+ o.writeObject(asterixInstance);
+ zk.create(instanceBasePath, b.toByteArray(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ }
+
+ private void createRootIfNotExist() throws Exception {
+ try {
+ Stat stat = zk.exists(ASTERIX_INSTANCE_BASE_PATH, false);
+ if (stat == null) {
+ zk.create(ASTERIX_INSTANCE_BASE_PATH, "root".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ }
+ } catch (Exception e) {
+ createRootIfNotExist();
+ }
+ }
+
+ public AsterixInstance getAsterixInstance(String name) throws Exception {
+ String path = ASTERIX_INSTANCE_BASE_PATH + File.separator + name;
+ Stat stat = zk.exists(ASTERIX_INSTANCE_BASE_PATH + File.separator + name, false);
+ if (stat == null) {
+ return null;
+ }
+ byte[] asterixInstanceBytes = zk.getData(path, false, new Stat());
+ return readAsterixInstanceObject(asterixInstanceBytes);
+ }
+
+ public boolean exists(String asterixInstanceName) throws Exception {
+ return zk.exists(ASTERIX_INSTANCE_BASE_PATH + File.separator + asterixInstanceName, false) != null;
+ }
+
+ public void removeAsterixInstance(String name) throws Exception {
+ if (!exists(name)) {
+ throw new ManagixException(" Asterix instance by name " + name + " does not exists.");
+ }
+ zk.delete(ASTERIX_INSTANCE_BASE_PATH + File.separator + name, DEFAULT_NODE_VERSION);
+ }
+
+ public List<AsterixInstance> getAsterixInstances() throws Exception {
+ List<String> instanceNames = zk.getChildren(ASTERIX_INSTANCE_BASE_PATH, false);
+ List<AsterixInstance> asterixInstances = new ArrayList<AsterixInstance>();
+ String path;
+ for (String instanceName : instanceNames) {
+ path = ASTERIX_INSTANCE_BASE_PATH + File.separator + instanceName;
+ byte[] asterixInstanceBytes = zk.getData(path, false, new Stat());
+ asterixInstances.add(readAsterixInstanceObject(asterixInstanceBytes));
+ }
+ return asterixInstances;
+ }
+
+ private AsterixInstance readAsterixInstanceObject(byte[] asterixInstanceBytes) throws IOException,
+ ClassNotFoundException {
+ ByteArrayInputStream b = new ByteArrayInputStream(asterixInstanceBytes);
+ ObjectInputStream ois = new ObjectInputStream(b);
+ return (AsterixInstance) ois.readObject();
+ }
+
+ public void updateAsterixInstance(AsterixInstance updatedInstance) throws Exception {
+ removeAsterixInstance(updatedInstance.getName());
+ writeAsterixInstance(updatedInstance);
+ }
+
+}
+
+class ZooKeeperWatcher implements Watcher {
+
+ private boolean isRunning = true;
+ private LinkedBlockingQueue<String> msgQ;
+
+ public ZooKeeperWatcher(LinkedBlockingQueue<String> msgQ) {
+ this.msgQ = msgQ;
+ }
+
+ public void process(WatchedEvent wEvent) {
+ switch (wEvent.getState()) {
+ case SyncConnected:
+ msgQ.add("connected");
+ break;
+ }
+ }
+
+ public boolean isRunning() {
+ return isRunning;
+ }
+
+}
+
+class ZookeeperUtil {
+
+ public static void writeConfiguration(String zooKeeperConfigPath, Configuration conf, int leaderConnPort,
+ int leaderElecPort) throws IOException {
+
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("tickTime=1000" + "\n");
+ buffer.append("dataDir=" + conf.getZookeeper().getHomeDir() + File.separator + "data" + "\n");
+ buffer.append("clientPort=" + conf.getZookeeper().getClientPort().intValue() + "\n");
+ buffer.append("initLimit=" + 2 + "\n");
+ buffer.append("syncLimit=" + 2 + "\n");
+
+ List<String> servers = conf.getZookeeper().getServers().getServer();
+ int serverId = 1;
+ for (String server : servers) {
+ buffer.append("server" + "." + serverId + "=" + server + ":" + leaderConnPort + ":" + leaderElecPort + "\n");
+ serverId++;
+ }
+ ManagixUtil.dumpToFile(zooKeeperConfigPath, buffer.toString());
+ }
+
+}
diff --git a/asterix-installer/src/main/resources/schema/managix-conf.xsd b/asterix-installer/src/main/resources/schema/managix-conf.xsd
new file mode 100644
index 0000000..b53c089
--- /dev/null
+++ b/asterix-installer/src/main/resources/schema/managix-conf.xsd
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mg="managix" targetNamespace="managix" elementFormDefault="qualified">
+
+<!-- definition of simple types -->
+<xs:element name="asterix_home" type="xs:string"/>
+<xs:element name="hyracks_home" type="xs:string"/>
+<xs:element name="hdfsurl" type="xs:string"/>
+<xs:element name="server" type="xs:string"/>
+<xs:element name="clientPort" type="xs:integer"/>
+<xs:element name="homeDir" type="xs:string"/>
+<xs:element name="version" type="xs:string"/>
+<xs:element name="url" type="xs:string"/>
+<xs:element name="backupDir" type="xs:string"/>
+
+<!-- definition of complex elements -->
+<xs:element name="hdfs">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="mg:version"/>
+ <xs:element ref="mg:url"/>
+ <xs:element ref="mg:backupDir"/>
+ </xs:sequence>
+ </xs:complexType>
+</xs:element>
+
+<xs:element name="backup">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="mg:hdfs"/>
+ </xs:sequence>
+ </xs:complexType>
+</xs:element>
+
+<xs:element name="zookeeper">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="mg:homeDir"/>
+ <xs:element ref="mg:clientPort"/>
+ <xs:element ref="mg:servers"/>
+ </xs:sequence>
+ </xs:complexType>
+</xs:element>
+
+<xs:element name="servers">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="mg:server" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+</xs:element>
+
+<xs:element name="configuration">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="mg:backup" minOccurs="0"/>
+ <xs:element ref="mg:asterix_home" minOccurs="0"/>
+ <xs:element ref="mg:hyracks_home" minOccurs="0"/>
+ <xs:element ref="mg:hdfsurl" minOccurs="0"/>
+ <xs:element ref="mg:zookeeper"/>
+ </xs:sequence>
+ </xs:complexType>
+</xs:element>
+
+</xs:schema>
diff --git a/pom.xml b/pom.xml
index fadaa0b..ef66149 100644
--- a/pom.xml
+++ b/pom.xml
@@ -82,6 +82,8 @@
<module>asterix-hyracks-glue</module>
<module>asterix-external-data</module>
<module>asterix-metadata</module>
+ <module>asterix-installer</module>
+ <module>asterix-events</module>
<module>asterix-dist</module>
<module>asterix-test-framework</module>
</modules>