/**
* Copyright (C) 2008 Progress Software, Inc. All rights reserved.
* http://fusesource.com
*
* The software in this package is published under the terms of the AGPL license
* a copy of which has been included with this distribution in the license.txt file.
*/
package org.fusesource.cloudmix.agent.dir;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.fusesource.cloudmix.agent.AgentPoller;
import org.fusesource.cloudmix.agent.Bundle;
import org.fusesource.cloudmix.agent.Feature;
import org.fusesource.cloudmix.agent.InstallerAgent;
import org.fusesource.cloudmix.agent.RestGridClient;
import org.fusesource.cloudmix.agent.security.SecurityUtils;
import org.fusesource.cloudmix.common.dto.Constants;
import org.fusesource.cloudmix.common.util.FileUtils;
public class DirectoryInstallerAgent extends InstallerAgent {
private static final Log LOGGER = LogFactory.getLog(DirectoryInstallerAgent.class);
private static final String BUNDLE_FILE_KEY = DirectoryInstallerAgent.class.getName() + ".file";
private String installDir;
private String tmpSuffix;
public DirectoryInstallerAgent() {
// Complete.
}
public static void main(String[] args) {
try {
String controllerUrl = "http://localhost:8181/";
String directory = "target/provisioning";
String profile = Constants.WILDCARD_PROFILE_NAME;
if (args.length > 0) {
String arg0 = args[0];
if (arg0.startsWith("?") || arg0.startsWith("-")) {
System.out.println("Usage: DirectoryInstallerAgent [controllerURL] [provisionDirectory]");
return;
} else {
controllerUrl = arg0;
}
if (args.length > 1) {
directory = args[1];
}
}
LOGGER.info("Connecting to Cloudmix controller at: " + controllerUrl);
File rootDirectory = new File(directory);
File workDirectory = new File(rootDirectory, "work");
File installDirectory = new File(rootDirectory, "install");
workDirectory.mkdirs();
installDirectory.mkdirs();
LOGGER.info("Using rootDirectory: " + rootDirectory);
DirectoryInstallerAgent agent = new DirectoryInstallerAgent();
agent.setClient(new RestGridClient(controllerUrl));
agent.setInstallDirectory(installDirectory.toString());
agent.setWorkDirectory(workDirectory);
agent.setProfile(profile);
agent.init();
AgentPoller poller = new AgentPoller(agent);
poller.start();
} catch (Exception e) {
LOGGER.error("Caught: " + e, e);
}
}
public void setInstallDirectory(String path) {
LOGGER.info("install directory: " + path);
installDir = path;
}
public String getInstallDirectory() {
return installDir;
}
public void setTempSuffix(String s) {
this.tmpSuffix = s;
}
public String getTempSuffix() {
return tmpSuffix;
}
/**
* should be careful when using this: do not use hard coded value as the ID should be somewhat guaranteed
* to be unique. Can be used when reloading the agent settings after a restart
*
* @param anId
*/
public void setAgentId(String anId) {
agentId = anId;
}
@Override
public boolean validateAgent() {
if (installDir == null) {
LOGGER.warn("No install directory set; ignoring provisioning change");
return false;
}
return true;
}
@Override
protected boolean installBundle(Feature feature, Bundle bundle) {
LOGGER.info("Installing bundle " + bundle + " for feature " + feature);
String filename = getFilename(bundle);
if (filename == null) {
LOGGER.warn("Cannot get filename for bundle " + bundle);
return false;
}
String tmpFilename = getTempFilename(filename);
File tmpPath = new File(installDir, tmpFilename);
LOGGER.debug("Tmp Path: " + tmpPath);
File path = new File(installDir, filename);
FileOutputStream os = null;
InputStream is = null;
try {
String uri = bundle.getUri();
if (uri == null || "".equals(uri)) {
throw new RuntimeException("Feature "
+ feature
+ " contains a bundle with null or empty URI");
}
URL url = new URL(uri);
os = new FileOutputStream(tmpPath);
if (os == null) {
throw new RuntimeException("Cannot write to " + tmpPath);
}
is = SecurityUtils.getInputStream(url);
if (is == null) {
os.close();
throw new RuntimeException("Cannot read from URL " + url);
}
FileUtils.copy(is, os);
is.close();
is = null;
os.close();
os = null;
if (!filename.equals(tmpFilename)) {
LOGGER.info("Renaming " + tmpPath + " to " + path);
if (!tmpPath.renameTo(path)) {
LOGGER.error("failed to rename " + tmpPath + " to " + path);
tmpPath.delete();
return false;
}
}
bundle.getAgentProperties().put(BUNDLE_FILE_KEY, path);
return true;
} catch (Exception e) {
LOGGER.error("Failed to install bundle " + bundle + " for feature "
+ feature + ", exception " + e);
if (is != null) {
try {
is.close();
} catch (IOException e1) {
// Complete
}
}
if (os != null) {
try {
os.close();
} catch (IOException e1) {
// Complete.
}
}
try {
if (!tmpPath.delete()) {
LOGGER.warn("Cannot delete file " + tmpPath);
}
} catch (Throwable t) {
// Complete.
}
}
return false;
}
@Override
protected boolean uninstallBundle(Feature feature, Bundle bundle) {
LOGGER.info("Uninstalling bundle " + bundle + " for feature " + feature);
Object o = bundle.getAgentProperties().get(BUNDLE_FILE_KEY);
if (o instanceof File) {
File path = (File) o;
LOGGER.debug("Path: " + path);
if (!path.delete()) {
LOGGER.warn("Cannot delete resource " + path);
}
bundle.getAgentProperties().remove(BUNDLE_FILE_KEY);
}
LOGGER.warn("cannot find installed file for bundle " + bundle);
return true;
}
private String getFilename(Bundle bundle) {
String name = bundle.getName();
if (name != null && !"".equals(name)) {
return name;
}
try {
String path = new URL(bundle.getUri()).getPath();
int i = path.lastIndexOf('/');
if (i == -1) {
return path;
}
return path.substring(i);
} catch (Throwable t) {
LOGGER.warn("Error getting path from URI " + bundle.getUri());
return null;
}
}
private String getTempFilename(String filename) {
if (tmpSuffix == null || "".equals(tmpSuffix)) {
return filename;
}
return filename + tmpSuffix;
}
}