incubator-blur-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cr...@apache.org
Subject [26/53] [partial] Initial commit of console v2. Sorry for the large commit
Date Mon, 17 Feb 2014 16:07:02 GMT
http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/exceptions/TableCollisionException.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/exceptions/TableCollisionException.java b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/exceptions/TableCollisionException.java
new file mode 100644
index 0000000..bfd98ce
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/exceptions/TableCollisionException.java
@@ -0,0 +1,24 @@
+package org.apache.blur.agent.exceptions;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@SuppressWarnings("serial")
+public class TableCollisionException extends CollisionException {
+	public TableCollisionException(int size, String table) {
+		super(size, "Table", table);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/exceptions/TableMissingException.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/exceptions/TableMissingException.java b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/exceptions/TableMissingException.java
new file mode 100644
index 0000000..53b30ff
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/exceptions/TableMissingException.java
@@ -0,0 +1,24 @@
+package org.apache.blur.agent.exceptions;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@SuppressWarnings("serial")
+public class TableMissingException extends MissingException {
+	public TableMissingException(String table) {
+		super("Table", table);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/exceptions/ZookeeperNameCollisionException.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/exceptions/ZookeeperNameCollisionException.java b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/exceptions/ZookeeperNameCollisionException.java
new file mode 100644
index 0000000..fa62f31
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/exceptions/ZookeeperNameCollisionException.java
@@ -0,0 +1,24 @@
+package org.apache.blur.agent.exceptions;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@SuppressWarnings("serial")
+public class ZookeeperNameCollisionException extends CollisionException {
+	public ZookeeperNameCollisionException(int size, String zookeeperName) {
+		super(size, "Zookeepers", zookeeperName);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/exceptions/ZookeeperNameMissingException.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/exceptions/ZookeeperNameMissingException.java b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/exceptions/ZookeeperNameMissingException.java
new file mode 100644
index 0000000..9922a64
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/exceptions/ZookeeperNameMissingException.java
@@ -0,0 +1,24 @@
+package org.apache.blur.agent.exceptions;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@SuppressWarnings("serial")
+public class ZookeeperNameMissingException extends MissingException {
+	public ZookeeperNameMissingException(String zookeeperName) {
+		super("Zookeeper", zookeeperName);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/monitor/ThreadController.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/monitor/ThreadController.java b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/monitor/ThreadController.java
new file mode 100644
index 0000000..004090e
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/monitor/ThreadController.java
@@ -0,0 +1,45 @@
+package org.apache.blur.agent.monitor;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+public class ThreadController {
+	private static Set<Thread> threads = new HashSet<Thread>();
+	public static boolean exitOnStop = true;
+
+	public static void registerThread(Thread thread) {
+		if (thread != null) {
+			threads.add(thread);
+		}
+	}
+
+	public static void stopAllThreads() {
+		Iterator<Thread> iterator = threads.iterator();
+		while (iterator.hasNext()) {
+			Thread next = iterator.next();
+			next.interrupt();
+			iterator.remove();
+		}
+
+		if (exitOnStop) {
+			System.exit(1);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/notifications/AgentMailerAuthenticator.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/notifications/AgentMailerAuthenticator.java b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/notifications/AgentMailerAuthenticator.java
new file mode 100644
index 0000000..d69e695
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/notifications/AgentMailerAuthenticator.java
@@ -0,0 +1,32 @@
+package org.apache.blur.agent.notifications;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import javax.mail.Authenticator;
+import javax.mail.PasswordAuthentication;
+
+public class AgentMailerAuthenticator extends Authenticator {
+	private final PasswordAuthentication authentication;
+
+	public AgentMailerAuthenticator(String username, String password) {
+		this.authentication = new PasswordAuthentication(username, password);
+	}
+
+	protected PasswordAuthentication getPasswordAuthentication() {
+		return this.authentication;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/notifications/Mailer.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/notifications/Mailer.java b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/notifications/Mailer.java
new file mode 100644
index 0000000..804ff58
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/notifications/Mailer.java
@@ -0,0 +1,94 @@
+package org.apache.blur.agent.notifications;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.AddressException;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class Mailer {
+	private static final Log log = LogFactory.getLog(Mailer.class);
+
+	private AgentMailerAuthenticator authenticator;
+	private String automatedSender;
+	private List<InternetAddress> recipients;
+	private Properties mailerProperties;
+	private boolean sendMail = false;
+
+	public Mailer(Properties props) {
+		if (props.containsKey("mail.enabled") && props.getProperty("mail.enabled").equals("true")) {
+			sendMail = true;
+			authenticator = new AgentMailerAuthenticator(props.getProperty("mail.sender.username"), props.getProperty("mail.sender.password"));
+			automatedSender = props.getProperty("mail.from.address", "DoNotReply");
+			setupRecipients(props.getProperty("mail.recipients", ""));			
+			
+			mailerProperties = new Properties();
+			mailerProperties.put("mail.transport.protocol", "smtp");
+			mailerProperties.put("mail.smtp.host", props.getProperty("mail.host", ""));
+			mailerProperties.put("mail.smtp.port", props.getProperty("mail.port", ""));
+			mailerProperties.put("mail.smtp.auth", "true");
+			mailerProperties.put("mail.smtp.starttls.enable", "true");
+		}
+	}
+
+	public void sendMessage(String subject, String messageBody) {
+		if (!sendMail) {
+			log.info("Mailer has been disabled.  No emails will be sent.");
+			return;
+		}
+		if (recipients.isEmpty()) {
+			log.warn("There were no recipients found to send mail to.  Skipping send mail.");
+			return;
+		}
+
+		Session session = Session.getInstance(this.mailerProperties, this.authenticator);
+		try {
+			MimeMessage message = new MimeMessage(session);
+			message.setFrom(new InternetAddress(this.automatedSender));
+			message.addRecipients(Message.RecipientType.TO, recipients.toArray(new InternetAddress[recipients.size()]));
+
+			message.setSubject(subject);
+			message.setContent(messageBody, "text/plain");
+
+			Transport.send(message);
+		} catch (MessagingException e) {
+			log.error("An error occured while sending a warning email.", e);
+		}
+	}
+	
+	private void setupRecipients(String recipientProp) {
+		recipients = new ArrayList<InternetAddress>();
+		for (String email : recipientProp.split("\\|")) {
+			try {
+				recipients.add(new InternetAddress(email));
+			} catch (AddressException e) {
+				log.warn("Invalid email address found.  Ignoring.", e);
+			}
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/notifications/Notifier.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/notifications/Notifier.java b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/notifications/Notifier.java
new file mode 100644
index 0000000..2c547fc
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/notifications/Notifier.java
@@ -0,0 +1,75 @@
+package org.apache.blur.agent.notifications;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class Notifier {
+	private static final Log log = LogFactory.getLog(Notifier.class);
+	private static final String SUBJECT = "Blur Console: {0} nodes may have gone offline!";
+	private static final String MESSAGE = "Blur Console has received notice that the following {0} nodes have recently gone offline.\n\n{1}";
+	private static Notifier notifier;
+	
+	private Mailer mailer;
+	
+	private Notifier(Properties props) {
+		mailer = new Mailer(props);
+	}
+	
+	public void notifyZookeeperOffline(String zookeeperName) {
+		sendNotification("Zookeeper", new ArrayList<String>(Arrays.asList(new String[]{zookeeperName})));
+	}
+
+	public void notifyControllerOffline(List<String> controllerNames) {
+		sendNotification("Controller", controllerNames);
+	}
+
+	public void notifyShardOffline(List<String> shardNames) {
+		sendNotification("Shard", shardNames);
+	}
+	
+	private void sendNotification(String nodeType, List<String> nodeNames) {
+		String subject = MessageFormat.format(SUBJECT, nodeType);
+		String message = MessageFormat.format(MESSAGE, nodeType, StringUtils.join(nodeNames, "\n"));
+		
+		mailer.sendMessage(subject, message);
+	}
+	
+	public static Notifier getNotifier(Properties props, boolean forceNew) {
+		if (notifier == null || forceNew) {
+			notifier = new Notifier(props);
+		}
+		return notifier;
+	}
+
+	public static Notifier getNotifier() {
+		if (notifier != null) {
+			return notifier;
+		}
+
+		log.warn("Notifier has not been configured yet.  No notifications will be sent.");
+		return new Notifier(new Properties());
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/types/Column.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/types/Column.java b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/types/Column.java
new file mode 100644
index 0000000..13bfd11
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/types/Column.java
@@ -0,0 +1,89 @@
+package org.apache.blur.agent.types;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+public class Column {
+	String name;
+	String analyzer;
+	boolean fullText;
+	boolean live;
+
+	public Column(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getAnalyzer() {
+		return analyzer;
+	}
+
+	public void setAnalyzer(String analyzer) {
+		this.analyzer = analyzer;
+	}
+
+	public boolean isLive() {
+		return live;
+	}
+
+	public void setLive(boolean live) {
+		this.live = live;
+	}
+
+	public boolean isFullText() {
+		return fullText;
+	}
+
+	public void setFullText(boolean fullText) {
+		this.fullText = fullText;
+	}
+
+	public boolean isSearchable() {
+		return !"stored".equalsIgnoreCase(this.analyzer);
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Column other = (Column) obj;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		return true;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/types/Family.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/types/Family.java b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/types/Family.java
new file mode 100644
index 0000000..799c04e
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/types/Family.java
@@ -0,0 +1,66 @@
+package org.apache.blur.agent.types;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.util.ArrayList;
+import java.util.List;
+
+public class Family {
+	String name;
+	List<Column> columns = new ArrayList<Column>();
+
+	public Family(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public List<Column> getColumns() {
+		return columns;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Family other = (Family) obj;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		return true;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/types/TimeHelper.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/types/TimeHelper.java b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/types/TimeHelper.java
new file mode 100644
index 0000000..b2bda82
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/main/java/org/apache/blur/agent/types/TimeHelper.java
@@ -0,0 +1,41 @@
+package org.apache.blur.agent.types;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+public class TimeHelper {
+	public static Calendar now() {
+		return getAdjustedTime(new Date().getTime());
+	}
+
+	public static Calendar getAdjustedTime(long time) {
+		Calendar cal = Calendar.getInstance();
+		TimeZone z = cal.getTimeZone();
+		cal.add(Calendar.MILLISECOND, -(z.getOffset(time)));
+		return cal;
+	}
+	
+	public static Calendar getTimeAgo(int timeAgoInMS){
+		Calendar timeAgo = Calendar.getInstance();
+		timeAgo.setTimeInMillis(now().getTimeInMillis());
+		timeAgo.add(Calendar.MILLISECOND, -timeAgoInMS);
+		return timeAgo;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/cleaners/AgentCleanerTest.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/cleaners/AgentCleanerTest.java b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/cleaners/AgentCleanerTest.java
new file mode 100644
index 0000000..dd2b191
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/cleaners/AgentCleanerTest.java
@@ -0,0 +1,93 @@
+package org.apache.blur.agent.cleaners;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.List;
+
+import org.apache.blur.agent.cleaners.AgentCleaners;
+import org.apache.blur.agent.connections.cleaners.CleanerDatabaseConnection;
+import org.apache.blur.agent.connections.cleaners.interfaces.CleanerDatabaseInterface;
+import org.apache.blur.agent.test.AgentBaseTestClass;
+import org.apache.blur.agent.types.TimeHelper;
+import org.junit.Test;
+
+
+public class AgentCleanerTest extends AgentBaseTestClass {
+	private static CleanerDatabaseInterface database = new CleanerDatabaseConnection(jdbc);
+
+	@Test
+	public void shouldCleanStatsAndQueries() {
+		List<String> activeCollectors = new ArrayList<String>();
+		activeCollectors.addAll(Arrays.asList("queries", "hdfs"));
+
+		makeOldData();
+
+		Thread testStatsCleaner = new Thread(new AgentCleaners(activeCollectors, database), "Test Agent Thread");
+		testStatsCleaner.start();
+		waitForThreadToSleep(testStatsCleaner, 250);
+
+		int hdfsCount = jdbc.queryForInt("select count(id) from hdfs_stats");
+		int queryCount = jdbc.queryForInt("select count(id) from blur_queries");
+		assertEquals(0, hdfsCount);
+		assertEquals(0, queryCount);
+	}
+
+	@Test
+	public void shouldOnlyCleanStats() {
+		List<String> activeCollectors = new ArrayList<String>();
+		activeCollectors.add("hdfs");
+
+		makeOldData();
+
+		Thread testStatsCleaner = new Thread(new AgentCleaners(activeCollectors, database), "Test Agent Thread");
+		testStatsCleaner.start();
+		waitForThreadToSleep(testStatsCleaner, 250);
+
+		int hdfsCount = jdbc.queryForInt("select count(id) from hdfs_stats");
+		int queryCount = jdbc.queryForInt("select count(id) from blur_queries");
+		assertEquals(0, hdfsCount);
+		assertEquals(1, queryCount);
+	}
+
+	@Test
+	public void shouldOnlyCleanQueries() {
+		List<String> activeCollectors = new ArrayList<String>();
+		activeCollectors.add("queries");
+
+		makeOldData();
+
+		Thread testStatsCleaner = new Thread(new AgentCleaners(activeCollectors, database), "Test Agent Thread");
+		testStatsCleaner.start();
+		waitForThreadToSleep(testStatsCleaner, 250);
+
+		int hdfsCount = jdbc.queryForInt("select count(id) from hdfs_stats");
+		int queryCount = jdbc.queryForInt("select count(id) from blur_queries");
+		assertEquals(1, hdfsCount);
+		assertEquals(0, queryCount);
+	}
+
+	private void makeOldData() {
+		Calendar overTwoWeeksAgo = TimeHelper.getTimeAgo(16 * 24 * 60 * 60 * 1000);
+		jdbc.update("insert into hdfs_stats (created_at) values (?)", overTwoWeeksAgo);
+		jdbc.update("insert into blur_queries (state, updated_at, created_at) values (?,?,?)", 0, overTwoWeeksAgo, overTwoWeeksAgo);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/cleaners/HdfsStatsCleanerTest.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/cleaners/HdfsStatsCleanerTest.java b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/cleaners/HdfsStatsCleanerTest.java
new file mode 100644
index 0000000..456550b
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/cleaners/HdfsStatsCleanerTest.java
@@ -0,0 +1,68 @@
+package org.apache.blur.agent.cleaners;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.util.Calendar;
+
+import org.apache.blur.agent.cleaners.HdfsStatsCleaner;
+import org.apache.blur.agent.connections.cleaners.CleanerDatabaseConnection;
+import org.apache.blur.agent.connections.cleaners.interfaces.CleanerDatabaseInterface;
+import org.apache.blur.agent.test.AgentBaseTestClass;
+import org.apache.blur.agent.types.TimeHelper;
+import org.junit.Test;
+
+
+public class HdfsStatsCleanerTest extends AgentBaseTestClass {
+	private static CleanerDatabaseInterface database = new CleanerDatabaseConnection(jdbc);
+
+	@Test
+	public void shouldDeleteOldStats() {
+		Calendar overTwoWeeksAgo = TimeHelper.getTimeAgo(16 * 24 * 60 * 60 * 1000);
+		jdbc.update("insert into hdfs_stats (created_at) values (?)", overTwoWeeksAgo);
+
+		Thread testStatsCleaner = new Thread(new HdfsStatsCleaner(database), "Hdfs Stats Cleaner Test Thread");
+		testStatsCleaner.start();
+		try {
+			testStatsCleaner.join();
+		} catch (InterruptedException e) {
+			fail("The test QueriesCleaner failed while waiting for it to finish!");
+		}
+
+		int updatedCount = jdbc.queryForInt("select count(id) from hdfs_stats");
+		assertEquals(0, updatedCount);
+	}
+	
+	@Test
+	public void shouldNotDeleteYoungStats() {
+		Calendar underTwoWeeksAgo = TimeHelper.getTimeAgo(8 * 24 * 60 * 60 * 1000);
+		jdbc.update("insert into hdfs_stats (created_at) values (?)", underTwoWeeksAgo);
+
+		Thread testStatsCleaner = new Thread(new HdfsStatsCleaner(database), "Hdfs Stats Cleaner Test Thread");
+		testStatsCleaner.start();
+		try {
+			testStatsCleaner.join();
+		} catch (InterruptedException e) {
+			fail("The test QueriesCleaner failed while waiting for it to finish!");
+		}
+
+		int updatedCount = jdbc.queryForInt("select count(id) from hdfs_stats");
+		assertEquals(1, updatedCount);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/cleaners/QueryCleanerTest.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/cleaners/QueryCleanerTest.java b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/cleaners/QueryCleanerTest.java
new file mode 100644
index 0000000..8d3eb57
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/cleaners/QueryCleanerTest.java
@@ -0,0 +1,121 @@
+package org.apache.blur.agent.cleaners;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.util.Calendar;
+
+import org.apache.blur.agent.cleaners.QueriesCleaner;
+import org.apache.blur.agent.connections.cleaners.CleanerDatabaseConnection;
+import org.apache.blur.agent.connections.cleaners.interfaces.CleanerDatabaseInterface;
+import org.apache.blur.agent.test.AgentBaseTestClass;
+import org.apache.blur.agent.types.TimeHelper;
+import org.junit.Test;
+
+
+public class QueryCleanerTest extends AgentBaseTestClass {
+	private static CleanerDatabaseInterface database = new CleanerDatabaseConnection(jdbc);
+
+	@Test
+	public void shouldExpireOldRunningQueries() {
+		Calendar timeOfQuery = TimeHelper.getTimeAgo(3 * 60 * 1000);
+		jdbc.update("insert into blur_queries (state, updated_at, created_at) values (?,?,?)", 0, timeOfQuery, timeOfQuery);
+
+		Thread testQueryCleaner = new Thread(new QueriesCleaner(database), "Query Test Thread");
+		testQueryCleaner.start();
+		try {
+			testQueryCleaner.join();
+		} catch (InterruptedException e) {
+			fail("The test QueriesCleaner failed while waiting for it to finish!");
+		}
+
+		int state = jdbc.queryForInt("select state from blur_queries limit 0, 1");
+		assertEquals(1, state);
+	}
+	
+	@Test
+	public void shouldNotExpireNewlyRunningQueries() {		
+		Calendar timeOfQuery = TimeHelper.getTimeAgo(1 * 60 * 1000);
+		jdbc.update("insert into blur_queries (state, updated_at, created_at) values (?,?,?)", 0, timeOfQuery, timeOfQuery);
+
+		Thread testQueryCleaner = new Thread(new QueriesCleaner(database), "Query Test Thread");
+		testQueryCleaner.start();
+		try {
+			testQueryCleaner.join();
+		} catch (InterruptedException e) {
+			fail("The test QueriesCleaner failed while waiting for it to finish!");
+		}
+
+		int state = jdbc.queryForInt("select state from blur_queries limit 0, 1");
+		assertEquals(0, state);
+	}
+	
+	@Test
+	public void shouldNotExpireExpiredRunningQueries() {		
+		Calendar timeOfQuery = TimeHelper.getTimeAgo(1 * 60 * 1000);
+		// a more recent time, for testing to see if a query is updated after it is created
+		Calendar timeOfUpdate = TimeHelper.getTimeAgo(1 * 30 * 1000);
+		jdbc.update("insert into blur_queries (state, updated_at, created_at) values (?,?,?)", 1, timeOfQuery, timeOfQuery);
+
+		Thread testQueryCleaner = new Thread(new QueriesCleaner(database), "Query Test Thread");
+		testQueryCleaner.start();
+		try {
+			testQueryCleaner.join();
+		} catch (InterruptedException e) {
+			fail("The test QueriesCleaner failed while waiting for it to finish!");
+		}
+
+		int updatedCount = jdbc.queryForInt("select count(id) from blur_queries where updated_at > ?", timeOfUpdate);
+		assertEquals(0, updatedCount);
+	}
+	
+	@Test
+	public void shouldDeleteOldQueries() {		
+		Calendar timeOfQuery = TimeHelper.getTimeAgo(3 * 60 * 60 * 1000);
+		jdbc.update("insert into blur_queries (state, updated_at, created_at) values (?,?,?)", 1, timeOfQuery, timeOfQuery);
+
+		Thread testQueryCleaner = new Thread(new QueriesCleaner(database), "Query Test Thread");
+		testQueryCleaner.start();
+		try {
+			testQueryCleaner.join();
+		} catch (InterruptedException e) {
+			fail("The test QueriesCleaner failed while waiting for it to finish!");
+		}
+
+		int updatedCount = jdbc.queryForInt("select count(id) from blur_queries");
+		assertEquals(0, updatedCount);
+	}
+	
+	@Test
+	public void shouldNotDeleteYoungQueries() {		
+		Calendar timeOfQuery = TimeHelper.getTimeAgo(1 * 60 * 60 * 1000);
+		jdbc.update("insert into blur_queries (state, updated_at, created_at) values (?,?,?)", 1, timeOfQuery, timeOfQuery);
+
+		Thread testQueryCleaner = new Thread(new QueriesCleaner(database), "Query Test Thread");
+		testQueryCleaner.start();
+		try {
+			testQueryCleaner.join();
+		} catch (InterruptedException e) {
+			fail("The test QueriesCleaner failed while waiting for it to finish!");
+		}
+
+		int updatedCount = jdbc.queryForInt("select count(id) from blur_queries");
+		assertEquals(1, updatedCount);
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/collectors/blur/query/QueryCollectorTest.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/collectors/blur/query/QueryCollectorTest.java b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/collectors/blur/query/QueryCollectorTest.java
new file mode 100644
index 0000000..580e411
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/collectors/blur/query/QueryCollectorTest.java
@@ -0,0 +1,71 @@
+package org.apache.blur.agent.collectors.blur.query;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+
+import org.apache.blur.MiniCluster;
+import org.apache.blur.agent.connections.blur.BlurDatabaseConnection;
+import org.apache.blur.agent.test.BlurAgentBaseTestClass;
+import org.apache.blur.thirdparty.thrift_0_9_0.TException;
+import org.apache.blur.thrift.BlurClient;
+import org.apache.blur.thrift.generated.Blur.Iface;
+import org.apache.blur.thrift.generated.BlurException;
+import org.apache.blur.thrift.generated.BlurQuery;
+import org.apache.blur.thrift.generated.Query;
+import org.apache.blur.thrift.generated.ScoreType;
+import org.apache.blur.thrift.generated.TableDescriptor;
+import org.junit.Test;
+
+
+public class QueryCollectorTest extends BlurAgentBaseTestClass {
+	private static BlurDatabaseConnection database = new BlurDatabaseConnection(jdbc);
+
+	@Test
+	public void shouldAddQueriesToDB() throws BlurException, TException, IOException {
+		Iface blurConnection = BlurClient.getClient(MiniCluster.getControllerConnectionStr());
+
+
+		TableDescriptor td = new TableDescriptor(); 
+		td.setTableUri(MiniCluster.getFileSystemUri() + "/blur-tables/test");
+		td.setName("test");
+		td.setShardCount(1);
+
+		blurConnection.createTable(td);
+		
+		BlurQuery query = new BlurQuery();
+		query.setQuery(new Query("test.col:*", true, ScoreType.SUPER, null, null));
+		query.setUuid("12345");
+		blurConnection.query("test", query);
+		
+		System.out.println(jdbc.queryForList("select * from blur_queries"));
+		
+		Thread testQueryCollector = new Thread(new QueryCollector(BlurClient.getClient(MiniCluster.getControllerConnectionStr()), "test",
+				1, database), "Query Test Thread");
+		testQueryCollector.start();
+		try {
+			testQueryCollector.join();
+		} catch (InterruptedException e) {
+			fail("The test QueryCollector failed while waiting for it to finish!");
+		}
+		int query_count = jdbc.queryForInt("select count(id) from blur_queries");
+		assertEquals(1, query_count);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/collectors/hdfs/HdfsCollectorTest.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/collectors/hdfs/HdfsCollectorTest.java b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/collectors/hdfs/HdfsCollectorTest.java
new file mode 100644
index 0000000..db5ddca
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/collectors/hdfs/HdfsCollectorTest.java
@@ -0,0 +1,84 @@
+package org.apache.blur.agent.collectors.hdfs;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.blur.MiniCluster;
+import org.apache.blur.agent.collectors.hdfs.HdfsCollector;
+import org.apache.blur.agent.connections.hdfs.HdfsDatabaseConnection;
+import org.apache.blur.agent.connections.hdfs.interfaces.HdfsDatabaseInterface;
+import org.apache.blur.agent.exceptions.HdfsThreadException;
+import org.apache.blur.agent.test.BlurAgentBaseTestClass;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class HdfsCollectorTest extends BlurAgentBaseTestClass {
+	private static HdfsDatabaseInterface database = new HdfsDatabaseConnection(jdbc);
+	private static URI hdfsUri;
+
+	@Before
+	public void setup() throws IOException {
+		hdfsUri = MiniCluster.getFileSystemUri();
+	}
+
+	@Test
+	public void shouldCreateHdfs() throws HdfsThreadException {
+		List<String> activeCollectors = new ArrayList<String>();
+
+		Thread testHdfsCollector = new Thread(new HdfsCollector("TestHDFS", hdfsUri.toString(), "hdfs://localhost:55314", null,
+				activeCollectors, database), "Hdfs Test Thread");
+		testHdfsCollector.start();
+		waitForThreadToSleep(testHdfsCollector, 250);
+
+		int hdfsCount = jdbc.queryForInt("select count(id) from hdfs");
+		assertEquals(1, hdfsCount);
+	}
+
+	@Test
+	public void shouldCollectStatsWhenActive() throws HdfsThreadException {
+		List<String> activeCollectors = new ArrayList<String>();
+		activeCollectors.add("hdfs");
+
+		Thread testHdfsCollector = new Thread(new HdfsCollector("TestHDFS", hdfsUri.toString(), "hdfs://localhost:55314", null,
+				activeCollectors, database), "Hdfs Test Thread");
+		testHdfsCollector.start();
+		waitForThreadToSleep(testHdfsCollector, 250);
+
+		int statsCount = jdbc.queryForInt("select count(id) from hdfs_stats");
+		assertEquals(1, statsCount);
+	}
+
+	@Test
+	public void shouldNotCollectStatsWithoutActive() throws HdfsThreadException {
+		List<String> activeCollectors = new ArrayList<String>();
+
+		Thread testHdfsCollector = new Thread(new HdfsCollector("TestHDFS", hdfsUri.toString(), "hdfs://localhost:55314", null,
+				activeCollectors, database), "Hdfs Test Thread");
+		testHdfsCollector.start();
+		waitForThreadToSleep(testHdfsCollector, 250);
+
+		int statsCount = jdbc.queryForInt("select count(id) from hdfs_stats");
+		assertEquals(0, statsCount);
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/collectors/hdfs/HdfsStatCollectorTest.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/collectors/hdfs/HdfsStatCollectorTest.java b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/collectors/hdfs/HdfsStatCollectorTest.java
new file mode 100644
index 0000000..1ebf493
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/collectors/hdfs/HdfsStatCollectorTest.java
@@ -0,0 +1,70 @@
+package org.apache.blur.agent.collectors.hdfs;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.net.URI;
+
+import org.apache.blur.MiniCluster;
+import org.apache.blur.agent.connections.hdfs.HdfsDatabaseConnection;
+import org.apache.blur.agent.connections.hdfs.interfaces.HdfsDatabaseInterface;
+import org.apache.blur.agent.test.BlurAgentBaseTestClass;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class HdfsStatCollectorTest extends BlurAgentBaseTestClass {
+	private static HdfsDatabaseInterface database = new HdfsDatabaseConnection(jdbc);
+	private static URI hdfsUri;
+
+	@Before
+	public void setup() throws IOException {
+		hdfsUri = MiniCluster.getFileSystemUri();
+	}
+
+	@Test
+	public void shouldNotInsertStatsWithoutParent() {
+		Thread testHdfsStatsCollector = new Thread(new HdfsStatsCollector("Test HDFS", hdfsUri, null, database), "HdfsStat Test Thread");
+		testHdfsStatsCollector.start();
+		try {
+			testHdfsStatsCollector.join();
+		} catch (InterruptedException e) {
+			fail("The test HdfsStatCollector failed while waiting for it to finish!");
+		}
+
+		int statsCount = jdbc.queryForInt("select count(id) from hdfs_stats");
+		assertEquals(0, statsCount);
+	}
+	
+	@Test
+	public void shouldInsertStats() {
+		jdbc.update("insert into hdfs (name) values (?)", "TestHdfs");
+		Thread testHdfsStatsCollector = new Thread(new HdfsStatsCollector("TestHdfs", hdfsUri, null, database), "HdfsStat Test Thread");
+		testHdfsStatsCollector.start();
+		try {
+			testHdfsStatsCollector.join();
+		} catch (InterruptedException e) {
+			fail("The test HdfsStatCollector failed while waiting for it to finish!");
+		}
+
+		int statsCount = jdbc.queryForInt("select count(id) from hdfs_stats");
+		assertEquals(1, statsCount);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/notifications/MailerTest.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/notifications/MailerTest.java b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/notifications/MailerTest.java
new file mode 100644
index 0000000..0270b88
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/notifications/MailerTest.java
@@ -0,0 +1,275 @@
+package org.apache.blur.agent.notifications;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.Properties;
+
+import javax.mail.MessagingException;
+
+import org.apache.blur.agent.notifications.Mailer;
+import org.junit.Test;
+import org.springframework.util.ReflectionUtils;
+import org.subethamail.wiser.Wiser;
+
+
+public class MailerTest {
+
+	@Test
+	public void testSingletons() {
+		// getter no props
+		Mailer mailer = new Mailer(new Properties());
+		assertFieldEquals("Send mail should be false", mailer, "sendMail", false);
+		assertFieldEquals("Recipients shouldn't have been set because sendMail is false.", mailer, "recipients", null);
+		assertFieldEquals("Sender should be null", mailer, "automatedSender", null);
+
+		// getter with props
+		Properties props = new Properties();
+		props.setProperty("mail.enabled", "true");
+		props.setProperty("mail.host", "localhost");
+		props.setProperty("mail.port", "25");
+		props.setProperty("mail.sender.username", "crohr");
+		props.setProperty("mail.from.address", "crohr");
+		props.setProperty("mail.sender.password", "password");
+		props.setProperty("mail.recipients", "crohr@nearinfinity.com|bmarcur@nearinfinity.com");
+		mailer = new Mailer(props);
+		assertFieldEquals("Send mail should be true", mailer, "sendMail", true);
+		assertCollectionFieldEquals("There should be 2 valid recipients", mailer, "recipients", 2);
+		assertFieldEquals("Sender should be crohr", mailer, "automatedSender", "crohr");
+	}
+
+	@Test
+	public void testMailerSetupInvalidAddress() {
+		Properties props = new Properties();
+		props.setProperty("mail.enabled", "true");
+		props.setProperty("mail.host", "localhost");
+		props.setProperty("mail.port", "25");
+		props.setProperty("mail.sender.username", "crohr");
+		props.setProperty("mail.from.address", "crohr");
+		props.setProperty("mail.sender.password", "password");
+		props.setProperty("mail.recipients", "test@nearinfinity com");
+		Mailer mailer = new Mailer(props);
+
+		assertCollectionFieldEquals("There should be no valid recipients", mailer, "recipients", 0);
+		assertFieldEquals("Sender should be crohr", mailer, "automatedSender", "crohr");
+	}
+
+	@Test
+	public void testMailerSetupWithUniqueDomain() {
+		Properties props = new Properties();
+		props.setProperty("mail.enabled", "true");
+		props.setProperty("mail.host", "localhost");
+		props.setProperty("mail.port", "25");
+		props.setProperty("mail.sender.username", "crohr");
+		props.setProperty("mail.from.address", "crohr");
+		props.setProperty("mail.sender.password", "password");
+		props.setProperty("mail.recipients", "crohr@abc");
+		Mailer mailer = new Mailer(props);
+
+		assertCollectionFieldEquals("There should be 1 valid recipient", mailer, "recipients", 1);
+		assertFieldEquals("Sender should be crohr", mailer, "automatedSender", "crohr");
+	}
+	
+	@Test
+	public void testSendMessageMailerDisabled() {
+		Wiser server = new Wiser(2500);
+		server.start();
+		
+		Properties props = new Properties();
+		props.setProperty("mail.enabled", "false");
+		Mailer mailer = new Mailer(props);
+		mailer.sendMessage("Test Message Subject", "Test Message Body");
+		
+		server.stop();
+		assertTrue(server.getMessages().size() == 0);
+	}
+	
+	@Test
+	public void testSendMessageNoRecipients() {
+		Wiser server = new Wiser(2500);
+		server.start();
+		
+		Properties props = new Properties();
+		props.setProperty("mail.enabled", "true");
+		props.setProperty("mail.host", "localhost");
+		props.setProperty("mail.port", "25");
+		props.setProperty("mail.sender.username", "crohr");
+		props.setProperty("mail.from.address", "crohr");
+		props.setProperty("mail.sender.password", "password");
+		Mailer mailer = new Mailer(props);
+		mailer.sendMessage("Test Message Subject", "Test Message Body");
+		
+		server.stop();
+		assertTrue(server.getMessages().size() == 0);
+	}
+	
+	@Test
+	public void testSendMessage() throws MessagingException {
+		Wiser server = new Wiser(2500);
+		server.start();
+		
+		Properties props = new Properties();
+		props.setProperty("mail.enabled", "true");
+		props.setProperty("mail.host", "localhost");
+		props.setProperty("mail.port", "2500");
+		props.setProperty("mail.sender.username", "crohr");
+		props.setProperty("mail.from.address", "crohr");
+		props.setProperty("mail.sender.password", "password");
+		props.setProperty("mail.recipients", "crohr@nearinfinity.com|bmarcur@nearinfinity.com");
+		Mailer mailer = new Mailer(props);
+		mailer.sendMessage("Test Message Subject", "Test Message Body");
+		
+		server.stop();
+		assertTrue(server.getMessages().size() == 2);
+		assertEquals("Test Message Subject", server.getMessages().get(0).getMimeMessage().getSubject());
+	}
+
+//	@Test
+//	public void testSendZookeeperNotice() throws MessagingException, IOException {
+//		Wiser server = new Wiser(2500);
+//		server.start();
+//
+//		setupActiveMailer("crohr@nearinfinity.com").notifyZookeeperOffline("ZK1");
+//
+//		server.stop();
+//
+//		assertProperMessageSent("Zookeeper", "ZK1", server);
+//	}
+//	
+//	@Test
+//	public void testSendControllersNoticeSingleNode() throws MessagingException, IOException {
+//		Wiser server = new Wiser(2500);
+//		server.start();
+//
+//		List<String> names = new ArrayList<String>();
+//		names.add("C1");
+//		
+//		setupActiveMailer("crohr@nearinfinity.com").notifyControllerOffline(names);
+//
+//		server.stop();
+//
+//		assertProperMessageSent("Controllers", "C1", server);
+//	}
+//	
+//	@Test
+//	public void testSendControllersNoticeMultiNode() throws MessagingException, IOException {
+//		Wiser server = new Wiser(2500);
+//		server.start();
+//
+//		List<String> names = new ArrayList<String>();
+//		names.add("C1");
+//		names.add("C2");
+//		
+//		setupActiveMailer("crohr@nearinfinity.com").notifyControllerOffline(names);
+//
+//		server.stop();
+//
+//		assertProperMultiMessageSent("Controllers", names, server);
+//	}
+//	
+//	@Test
+//	public void testSendShardsNoticeSingleNode() throws MessagingException, IOException {
+//		Wiser server = new Wiser(2500);
+//		server.start();
+//
+//		List<String> names = new ArrayList<String>();
+//		names.add("S1");
+//		
+//		setupActiveMailer("crohr@nearinfinity.com").notifyShardOffline(names);
+//
+//		server.stop();
+//
+//		assertProperMessageSent("Shards", "S1", server);
+//	}
+//	
+//	@Test
+//	public void testSendShardsNoticeMultiNode() throws MessagingException, IOException {
+//		Wiser server = new Wiser(2500);
+//		server.start();
+//
+//		List<String> names = new ArrayList<String>();
+//		names.add("S1");
+//		names.add("S2");
+//		
+//		setupActiveMailer("crohr@nearinfinity.com").notifyShardOffline(names);
+//
+//		server.stop();
+//
+//		assertProperMultiMessageSent("Shards", names, server);
+//	}
+//
+//	@Test
+//	public void testNoMessageSentWithNoRecipients() {
+//		Wiser server = new Wiser(2500);
+//		server.start();
+//
+//		List<String> names = new ArrayList<String>();
+//		names.add("S1");
+//		setupActiveMailer("").notifyShardOffline(names);
+//
+//		server.stop();
+//
+//		assertTrue(server.getMessages().size() == 0);
+//	}
+
+//	private Mailer setupActiveMailer(String recipients) {
+//		Properties props = new Properties();
+//		props.setProperty("mail.host", "localhost");
+//		props.setProperty("mail.port", "2500");
+//		props.setProperty("mail.sender.username", "crohr");
+//		props.setProperty("mail.sender.password", "password");
+//		props.setProperty("mail.recipients", recipients);
+//		return new Mailer(props);
+//	}
+//
+//	private void assertProperMessageSent(String type, String name, Wiser server) throws MessagingException, IOException {
+//		assertTrue(server.getMessages().size() == 1);
+//		Iterator<WiserMessage> emailIter = server.getMessages().iterator();
+//		WiserMessage email = (WiserMessage) emailIter.next();
+//		assertTrue(email.getMimeMessage().getSubject().equals("Blur Console: " + type + " [" + name + "] may have gone offline!"));
+//		assertEquals("Blur Console has received notice that " + type + " [" + name
+//				+ "] has recently gone offline, if this was expected please ignore this email.",
+//				StringUtils.trim((String) email.getMimeMessage().getContent()));
+//	}
+//	
+//	private void assertProperMultiMessageSent(String type, List<String> names, Wiser server) throws MessagingException, IOException {
+//		assertTrue(server.getMessages().size() == 1);
+//		Iterator<WiserMessage> emailIter = server.getMessages().iterator();
+//		WiserMessage email = (WiserMessage) emailIter.next();
+//		assertTrue(email.getMimeMessage().getSubject().equals("Blur Console: Multiple " + type + " may have gone offline!"));
+//		assertEquals("Blur Console has received notice that " + type + " [" + StringUtils.join(names, "','")
+//				+ "] have recently gone offline, if this was expected please ignore this email.",
+//				StringUtils.trim((String) email.getMimeMessage().getContent()));
+//	}
+
+	private void assertFieldEquals(String message, Object object, String fieldName, Object value) {
+		Field field = ReflectionUtils.findField(object.getClass(), fieldName);
+		ReflectionUtils.makeAccessible(field);
+		assertEquals(message, value, ReflectionUtils.getField(field, object));
+	}
+
+	@SuppressWarnings("unchecked")
+	private void assertCollectionFieldEquals(String message, Object object, String fieldName, int expectedCollectionSize) {
+		Field field = ReflectionUtils.findField(object.getClass(), fieldName);
+		ReflectionUtils.makeAccessible(field);
+		assertEquals(message, expectedCollectionSize, ((Collection<Object>) ReflectionUtils.getField(field, object)).size());
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/notifications/NotifierTest.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/notifications/NotifierTest.java b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/notifications/NotifierTest.java
new file mode 100644
index 0000000..697ee06
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/notifications/NotifierTest.java
@@ -0,0 +1,21 @@
+package org.apache.blur.agent.notifications;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+public class NotifierTest {
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/notifications/XMPPEmbeddedServer.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/notifications/XMPPEmbeddedServer.java b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/notifications/XMPPEmbeddedServer.java
new file mode 100644
index 0000000..f8a6b17
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/notifications/XMPPEmbeddedServer.java
@@ -0,0 +1,111 @@
+package org.apache.blur.agent.notifications;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class XMPPEmbeddedServer implements Runnable {
+	private static final Log log = LogFactory.getLog(XMPPEmbeddedServer.class);
+	private static Thread serverThread;
+	private static XMPPEmbeddedServer server;
+	private ServerSocket socket;
+	
+	public static void startServer(int port) {
+		server = new XMPPEmbeddedServer(port);
+		serverThread = new Thread(server);
+		serverThread.start();
+	}
+	
+	public static void stopServer() {
+		server.closeServer();
+		serverThread.interrupt();
+	}
+	
+	public static List<Object> getMessages() {
+		return new ArrayList<Object>();
+	}
+	
+	private XMPPEmbeddedServer(int port) {
+		try {
+			log.info("Starting IM Server *:" + port);
+			socket = new ServerSocket(port);
+			log.info("IM Server started *:" + port);
+		} catch (IOException e) {
+			log.error("Error creating IM server:" + e.getMessage());
+			stopServer();
+		}
+	}
+
+	@Override
+	public void run() {
+		if (socket == null) {
+			log.info("IM Server has not been configured.");
+		} else {
+			while(true) {
+				if (socket != null) {
+					try {
+						Socket accept = socket.accept();
+						System.out.println("got a connection");
+						
+						PrintWriter out = new PrintWriter(accept.getOutputStream(), true);
+						out.println("<stream id='xxxx' from='192.168.0.12:5222' xmlns='jabber:client'/>");
+						
+						BufferedReader in = new BufferedReader(new InputStreamReader(accept.getInputStream()));
+						
+						String inputLine;
+						while ((inputLine = in.readLine()) != null) { 
+							System.out.println(inputLine);
+						}
+						
+//						out = new PrintWriter(accept.getOutputStream(), true);
+//						out.println("<iq type='result' id='reg2'/>");
+						
+						
+						
+					} catch (IOException e) {
+//						e.printStackTrace();
+					}
+				}
+			}
+		}
+	}
+	
+	public void closeServer() {
+		if (socket != null) {
+			try {
+				log.info("Shutting down IM server");
+				socket.close();
+				log.info("IM server has been shut down");
+			} catch (IOException e) {
+				log.error("There was a problem trying to close IM server: " + e.getMessage());
+			}
+			socket = null;
+		}
+	}
+	
+	
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/test/AgentBaseTestClass.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/test/AgentBaseTestClass.java b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/test/AgentBaseTestClass.java
new file mode 100644
index 0000000..74c897f
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/test/AgentBaseTestClass.java
@@ -0,0 +1,62 @@
+package org.apache.blur.agent.test;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.blur.agent.connections.JdbcConnection;
+import org.junit.After;
+import org.junit.BeforeClass;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+
+public abstract class AgentBaseTestClass {
+	protected static JdbcTemplate jdbc;
+
+	@BeforeClass
+	public static void setupDatabaseConnection() {
+		Properties props = new Properties();
+		props.setProperty("store.url", "jdbc:mysql://localhost/blurtools-test");
+		props.setProperty("store.user", "root");
+		props.setProperty("store.password", "");
+		jdbc = JdbcConnection.createDBConnection(props);
+	}
+
+	@After
+	public void tearDownDatabase() {
+		List<String> tables = jdbc.queryForList("select TABLE_NAME from information_schema.tables where table_schema = 'blurtools-test'",
+				String.class);
+
+		for (String table : tables) {
+			if (!"schema_migrations".equalsIgnoreCase(table)) {
+				jdbc.execute("truncate table " + table);
+			}
+		}
+	}
+	
+	protected void waitForThreadToSleep(Thread tiredThread, int catchupTime){
+		while(tiredThread.getState() != Thread.State.TIMED_WAITING){
+			// Wait until the thread goes to sleep
+		}
+		try {
+			Thread.sleep(catchupTime);
+			tiredThread.interrupt();
+		} catch (InterruptedException e) {}
+		return;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/test/BlurAgentBaseTestClass.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/test/BlurAgentBaseTestClass.java b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/test/BlurAgentBaseTestClass.java
new file mode 100644
index 0000000..9106a1c
--- /dev/null
+++ b/contrib/blur-console-v1/blur-agent/src/test/java/org/apache/blur/agent/test/BlurAgentBaseTestClass.java
@@ -0,0 +1,39 @@
+package org.apache.blur.agent.test;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import org.apache.blur.MiniCluster;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public abstract class BlurAgentBaseTestClass extends AgentBaseTestClass {
+	@BeforeClass
+	public static void startBlur() {
+		MiniCluster.startDfs("./tmp");
+		MiniCluster.startZooKeeper("./tmp");
+		MiniCluster.startControllers(1);
+		MiniCluster.startShards(1);
+	}
+
+	@AfterClass
+	public static void stopBlur() {
+		MiniCluster.stopShards();
+		MiniCluster.stopControllers();
+		MiniCluster.shutdownZooKeeper();
+		MiniCluster.shutdownDfs();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/build.sh
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/build.sh b/contrib/blur-console-v1/build.sh
new file mode 100755
index 0000000..aecb2c2
--- /dev/null
+++ b/contrib/blur-console-v1/build.sh
@@ -0,0 +1,149 @@
+#!/bin/bash
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version=$1
+
+# Setup build directory
+if [ ! -e "build" ]; then
+  echo "Creating build directory"
+  mkdir "build"
+fi
+
+# Clean build directory
+echo "Cleaning build directory"
+rm -r build/*
+
+##########################
+# Prep Rails app         #
+##########################
+echo "Assembling Rails app"
+cd blur-admin
+bundle install
+
+echo "Compiling assets"
+bundle exec rake RAILS_ENV=production js:routes
+bundle exec rake RAILS_ENV=production assets:clean
+bundle exec rake RAILS_ENV=production assets:precompile
+
+cd ../build
+GUI_DIR=gui
+mkdir $GUI_DIR
+
+echo "Copying Rails files"
+cp ../blur-admin/Rakefile ../blur-admin/config.ru $GUI_DIR
+
+echo "Copying app"
+cp -r ../blur-admin/app $GUI_DIR
+
+echo "Copying config"
+cp -r ../blur-admin/config $GUI_DIR
+rm $GUI_DIR/config/environments/development.rb
+rm $GUI_DIR/config/environments/test.rb
+
+echo "Copying db"
+cp -r ../blur-admin/db $GUI_DIR
+
+echo "Copying lib"
+cp -r ../blur-admin/lib $GUI_DIR
+rm -r $GUI_DIR/lib/pounder
+rm -r $GUI_DIR/lib/tasks/*.rake
+
+echo "Copying public"
+cp -r ../blur-admin/public $GUI_DIR
+
+echo "Copying script"
+cp -r ../blur-admin/script $GUI_DIR
+
+mkdir $GUI_DIR/tmp
+touch $GUI_DIR/tmp/placeholder.txt
+
+echo "Copying vendor"
+cp -r ../blur-admin/vendor $GUI_DIR
+
+echo "Copy production files"
+cp ../etc/default/Gemfile $GUI_DIR/
+cp ../etc/default/database.yml $GUI_DIR/config/
+
+echo "Vendor gems"
+cd $GUI_DIR
+bundle install
+bundle package
+
+find . -name .DS_Store | xargs rm
+
+echo "Compressing and zipping rails dir"
+cd ..
+mv $GUI_DIR "$GUI_DIR-$version"
+tar -cvzf "$GUI_DIR-$version.tar.gz" "$GUI_DIR-$version"
+
+#################################
+# Prep Agent                    #
+#################################
+
+echo "Build agent jar"
+cd ../blur-agent
+mvn clean package -DskipTests
+cd ../build
+
+mkdir agent
+
+echo "Create bin dir"
+mkdir agent/bin
+cp ../etc/*.sh agent/bin
+chmod 775 agent/bin/*.sh
+
+echo "Create conf dir"
+mkdir agent/conf
+cp ../etc/agent.config.sample agent/conf
+cp ../etc/log4j.properties agent/conf 
+
+echo "Create lib dir"
+mkdir agent/lib
+cp ../blur-agent/target/blur-agent-*.jar agent/lib/agent.jar
+cp ../blur-agent/target/lib/*.jar agent/lib
+rm agent/lib/ant*.jar
+rm agent/lib/commons-cli*.jar
+rm agent/lib/commons-el*.jar
+rm agent/lib/commons-httpclient*.jar
+rm agent/lib/commons-net*.jar
+rm agent/lib/core*.jar
+rm agent/lib/hamcrest*.jar
+rm agent/lib/hsqldb*.jar
+rm agent/lib/jasper*.jar
+rm agent/lib/jets3t*.jar
+rm agent/lib/jetty*.jar
+rm agent/lib/jsp-api*.jar
+rm agent/lib/junit*.jar
+rm agent/lib/mysql-connector-java*.jar
+rm agent/lib/oro*.jar
+rm agent/lib/servlet-api*.jar
+rm agent/lib/xmlenc*.jar
+
+echo "Compressing and zipping agent dir"
+mv agent "agent-$version"
+tar -cvzf "agent-$version.tar.gz" "agent-$version"
+
+#################################
+# Final packaging               #
+#################################
+
+cp ../etc/INSTALL .
+cp ../etc/install.sh .
+cp ../etc/VERSION .
+tar -cvzf "blur-tools-$version.tar.gz" "$GUI_DIR-$version.tar.gz" "agent-$version.tar.gz" INSTALL VERSION
+
+echo "Build complete"

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/etc/INSTALL
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/etc/INSTALL b/contrib/blur-console-v1/etc/INSTALL
new file mode 100644
index 0000000..baee13d
--- /dev/null
+++ b/contrib/blur-console-v1/etc/INSTALL
@@ -0,0 +1,52 @@
+This document is intended to aid in the installation of the Blur Console
+application pieces.  Please contact support@nearinfinity.com if you have
+any problems installing the tool.
+
+System Requirements
+========================================================================
+Required:
+	* Ruby 1.9.3+ (with bundler gem)
+	* Java 6+
+	* Mysql 5.5+
+	* mysql jdbc connector (http://www.mysql.com/products/connector/)
+
+Recommended:
+	* Apache webserver
+	* Phusion Passenger
+	
+Installing the Rails application
+========================================================================
+1. Extract the blur-console-version.tar.gz
+2. Copy the rails directory into the appropriate folder for your webserver
+3. Change your directory to the rails directory
+		cd rails
+4. Create a tmp and log directory
+5. Install the dependent libraries
+		bundle install --local
+6. Update configuration files for your environment
+		a. Setup your mysql connection information in config/database.yml
+7. If this is a new install create the database
+		bundle exec rake RAILS_ENV=production db:create
+8. Update the database with any changes
+		bundle exec rake RAILS_ENV=production db:migrate
+9. Load any initial data
+		bundle exec rake RAILS_ENV=production db:seed
+10. Configure your webserver to point to the rails directory according to 
+   the server documentation
+11. Open your browser to the url you specified in your server configuration
+	 (i.e. https://mydomain.com/)
+
+Note: Currently the initial data that is loaded is a default admin user.  The
+username is admin and the password is password.  This should be changed immediately.
+
+Installing the Agent application
+===============================================================================
+1. Extract the agent-version.tar.gz
+2. Copy the agent directory to the location you want it to reside.
+3. Place the mysql jdbc connector jar into the agent/lib folder.
+4. Create log directory
+5. Update configuration files for your environment
+		a. Copy agent/conf/agent.config.sample to agent/conf/blur-agent.config
+		b. Update agent/conf/blur-agent.config to specify the information about your install and cluster(s).
+6. Start the agent by running agent/bin/start-agent.sh
+		To stop the agent run agent/bin/stop-agent.sh

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/etc/VERSION
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/etc/VERSION b/contrib/blur-console-v1/etc/VERSION
new file mode 100644
index 0000000..35eb04b
--- /dev/null
+++ b/contrib/blur-console-v1/etc/VERSION
@@ -0,0 +1,18 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#  http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+1.4.2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/etc/agent.config.sample
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/etc/agent.config.sample b/contrib/blur-console-v1/etc/agent.config.sample
new file mode 100644
index 0000000..032fbb1
--- /dev/null
+++ b/contrib/blur-console-v1/etc/agent.config.sample
@@ -0,0 +1,63 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#  http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+
+# Mysql connection information
+#store.url=
+#store.user=
+#store.password=
+
+# ZooKeeper Instances (instances separated by | )
+#zk.instances=some-zk
+
+#zk.some-zk.url=
+
+# Active Collectors
+active.collectors=hdfs|queries|tables
+
+# HDFS Collector properties (instances separated by | )
+#hdfs.instances=some-hdfs
+
+#hdfs.some-hdfs.thrift.url=
+#hdfs.some-hdfs.url=
+#hdfs.some-hdfs.login.user=SOMEUSER (optional)
+
+# Blur properties (instances separated by | )
+#blur.instances=some-blur
+
+#blur.some-blur.url=
+
+# Email Properties
+# mail.enabled=true
+# mail.host=smtp.DOMAIN.com
+# mail.port=1337
+
+# mail.sender.username=SENDER@gmail.com
+# mail.sender.password=PASSWORD
+
+# mail.from.address=DoNotReply
+# mail.recipients=ADMINS@gmail.com|OTHERADMINS@gmail.com
+
+# IM Properties
+# messenger.enabled=true
+# messenger.host=google.com
+# messenger.port=5222
+
+# messenger.user=SENDER@gmail.com
+# messenger.password=password
+
+# messenger.recipients=ADMINS@gmail.com|OTHERADMINS@gmail.com

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/etc/agent.sh
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/etc/agent.sh b/contrib/blur-console-v1/etc/agent.sh
new file mode 100644
index 0000000..223208e
--- /dev/null
+++ b/contrib/blur-console-v1/etc/agent.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#  http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+
+bin=`dirname $0`
+bin=`cd "$bin"; pwd`
+
+export BLUR_AGENT_HOME="$bin"/..
+export BLUR_AGENT_HOME_LIB=$BLUR_AGENT_HOME/lib
+
+for f in $BLUR_AGENT_HOME_LIB/*.jar; do
+  BLUR_AGENT_CLASSPATH="$BLUR_AGENT_CLASSPATH:$f"
+done
+
+cd $BLUR_AGENT_HOME/bin
+
+$JAVA_HOME/bin/java -cp $BLUR_AGENT_CLASSPATH com.nearinfinity.agent.Agent $1

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/etc/default/Gemfile
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/etc/default/Gemfile b/contrib/blur-console-v1/etc/default/Gemfile
new file mode 100644
index 0000000..7d225a9
--- /dev/null
+++ b/contrib/blur-console-v1/etc/default/Gemfile
@@ -0,0 +1,40 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#  http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+
+source 'https://rubygems.org'
+
+gem 'rails', '3.2.2'
+
+gem 'mysql2'
+gem 'jquery-rails'
+gem 'thrift_client'
+gem 'authlogic'
+gem 'cancan', '2.0.0.alpha', :path => 'vendor/gems/cancan'
+gem 'twitter_bootstrap_form_for'
+gem 'bootstrap-sass'
+gem 'js-routes'
+gem 'haml-rails'
+gem 'sass-rails',   '~> 3.2.3'
+gem 'ejs'
+
+# Gems used only for assets and not required
+# in production environments by default.
+group :assets do
+  gem 'coffee-rails', '~> 3.2.1'
+  gem 'uglifier', '>= 1.0.3'
+end

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/etc/default/database.yml
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/etc/default/database.yml b/contrib/blur-console-v1/etc/default/database.yml
new file mode 100644
index 0000000..a27136f
--- /dev/null
+++ b/contrib/blur-console-v1/etc/default/database.yml
@@ -0,0 +1,26 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#  http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+
+production:
+  adapter: mysql2
+  encoding: utf8
+  database: blurtools
+  host: localhost
+  pool: 5
+  username: root
+  password: 

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/etc/log4j.properties
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/etc/log4j.properties b/contrib/blur-console-v1/etc/log4j.properties
new file mode 100644
index 0000000..fcc3e01
--- /dev/null
+++ b/contrib/blur-console-v1/etc/log4j.properties
@@ -0,0 +1,26 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#  http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+
+# Root logger option
+log4j.rootLogger=WARN, file
+# Direct log messages to a log file
+log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.file.File=../log/agent.log
+log4j.appender.file.DatePattern='.'yyyy-MM-dd
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/11a2529a/contrib/blur-console-v1/etc/start-agent.sh
----------------------------------------------------------------------
diff --git a/contrib/blur-console-v1/etc/start-agent.sh b/contrib/blur-console-v1/etc/start-agent.sh
new file mode 100644
index 0000000..c6b06d0
--- /dev/null
+++ b/contrib/blur-console-v1/etc/start-agent.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#  http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+
+bin=`dirname "$0"`
+bin=`cd "$bin"; pwd`
+
+nohup $bin/agent.sh $1 &


Mime
View raw message