/*
* Copyright PMEase (c) 2005 - 2010,
* Date: Jan 12, 2010 1:13:27 AM
*
* All rights reserved.
*
* Revision: $Id$
*/
package com.pmease.quickbuild.monitor.notifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.pmease.quickbuild.monitor.gui.TrayMonitor;
import com.pmease.quickbuild.monitor.notifier.Notifier.NotificationType;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
public class NotificationHandler extends Thread {
private final Client client;
private final TrayMonitor monitor;
private static final Logger logger = LoggerFactory.getLogger(NotificationHandler.class);
private boolean paused = false;
private boolean shutdown = false;
private boolean connectionLost = false;
public NotificationHandler(TrayMonitor monitor) {
this.monitor = monitor;
this.setName("NotificationHandler");
this.setPriority(Thread.MIN_PRIORITY);
client = new Client();
}
public void shutdown() {
shutdown = true;
}
@Override
public void run() {
long lastUpdated = System.currentTimeMillis();
while (!shutdown) {
try {
synchronized (this) {
while (paused) {
try {
this.wait(300);
} catch (InterruptedException e) {
// ignore
}
}
}
while (System.currentTimeMillis() <= (lastUpdated + monitor.settings.getInterval() * 1000)) {
Thread.yield();
}
lastUpdated = System.currentTimeMillis();
Long lastNotifiedId = monitor.settings.getLastNotifiedId();
List<BuildFragment> builds = getBuilds(lastNotifiedId);
if (!builds.isEmpty()) {
lastNotifiedId = builds.get(builds.size()-1).getBuildId();
monitor.settings.setLastNotifiedId(lastNotifiedId);
monitor.history.add(builds);
monitor.windowManager.refreshHistoryDialog();
}
try {
for (BuildFragment build : builds) {
monitor.showBuildNotification(build);
Thread.sleep(1000);
}
Thread.sleep(monitor.settings.getInterval() * 1000);
} catch (InterruptedException e) {
//Ignore
}
} catch (Exception e) {
logger.error("Checking notifications failed!", e);
shutdown = true;
monitor.close();
}
}
}
public void pause() {
paused = true;
}
public void unpause() {
paused = false;
}
@SuppressWarnings("unchecked")
public List<BuildFragment> getBuilds(Long lastNotifiedBuildId) {
client.removeAllFilters();
client.addFilter(new HTTPBasicAuthFilter(monitor.settings.getUsername(), monitor.settings.getPassword()));
String response = null;
try {
WebResource resource = client.resource(monitor.settings.getRestUrl("notifications"));
if (lastNotifiedBuildId != null)
resource = resource.queryParam("last_notified_build_id", lastNotifiedBuildId.toString());
response = resource.get(String.class);
if (connectionLost == true) {
monitor.showMessage("Connection recovered!",
"The connection with server " + monitor.settings.getHost() + " is recovered now.",
NotificationType.SUCCESS);
connectionLost = false;
monitor.updateStatus();
}
} catch (Exception e) {
if (!connectionLost) {
logger.error("Connection failed!", e);
monitor.showError("Connection failed!",
"Connect to server " + monitor.settings.getHost() + " failed!\nMaybe server is down or your host url is not correctly configured.");
}
// monitor.setStatus(Status.CONNECTION_LOST);
connectionLost = true;
monitor.updateStatus();
return Collections.emptyList();
}
if (StringUtils.isEmpty(response)) {
return Collections.emptyList();
}
Document doc;
try {
doc = DocumentHelper.parseText(response);
} catch (DocumentException e) {
logger.error("Parse document failed!", e);
monitor.showError("Parse response failed!", "The response from server contains error and can't be parsed!");
return Collections.emptyList();
}
List<Element> elements = doc.getRootElement().elements();
List<BuildFragment> builds = new ArrayList<BuildFragment>();
for (Element element : elements) {
BuildFragment build = new BuildFragment();
build.fromRest(element);
String configurationId = element.elementText("configuration");
String configurationPath = getConfigurationPath(configurationId);
build.setConfigurationPath(configurationPath);
if (StringUtils.isEmpty(build.getTriggeredBy())) {
if (build.isScheduled()) {
build.setTriggeredBy("Unknown");
} else {
build.setTriggeredBy("Scheduler");
}
} else {
build.setTriggeredBy(getTriggeredBy(build.getTriggeredBy()));
}
builds.add(build);
}
return builds;
}
/*
@SuppressWarnings({ "unchecked" })
public void checkNotifications() {
Date now = new Date();
String response;
try {
client.addFilter(new HTTPBasicAuthFilter(monitor.setting.getUsername(), monitor.setting.getPassword()));
response = client.resource(monitor.setting.getRestUrl("notifications"))
.queryParam("from", new SimpleDateFormat(DATETIME_FORMAT).format(lastUpdateDate))
.queryParam("to", new SimpleDateFormat(DATETIME_FORMAT).format(now))
.get(String.class);
monitor.updateStatus(TrayMonitor.Status.OK);
} catch (Exception e) {
Throwable throwable = ExceptionUtils.getCause(e);
if (throwable instanceof ConnectException) {
monitor.showErrorNotification("Connection failed!",
"Connect to host " + monitor.setting.getHost()
+ " failed!\nPlease configure your host correctly in 'Preferences'.");
} else {
monitor.showErrorNotification("Retrieve Response Error!", e.getMessage());
}
monitor.updateStatus(TrayMonitor.Status.ERROR);
return;
}
Document doc;
try {
doc = DocumentHelper.parseText(response);
} catch (DocumentException e) {
monitor.showErrorNotification("Parse Response Error!", "Parse quickbuild notifications response failed!");
return;
}
List<Element> elements = doc.getRootElement().elements();
for (Element element : elements) {
final BuildWrapper build = new BuildWrapper(element);
String configurationId = element.elementText("configuration");
String configurationPath = getConfigurationPath(configurationId);
build.setConfigurationPath(configurationPath);
System.out.println(element.asXML());
monitor.showBuildNotification(build);
}
lastUpdateDate = now;
}
*/
private String getConfigurationPath(String id) {
return client.resource(monitor.settings.getRestUrl("configurations/" + id + "/path")).get(String.class);
}
private String getTriggeredBy(String id) {
return client.resource(monitor.settings.getRestUrl("users/" + id + "/display_name")).get(String.class);
}
public boolean isPaused() {
return paused;
}
public void setPaused(boolean paused) {
this.paused = paused;
}
public boolean isConnectionLost() {
return connectionLost;
}
public void setConnectionLost(boolean connectionLost) {
this.connectionLost = connectionLost;
}
}