/**************************************************************************************
* Copyright (C) 2009 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.mop;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.fusesource.cloudmix.agent.Feature;
import org.fusesource.cloudmix.agent.InstallerAgent;
import org.fusesource.cloudmix.common.GridClients;
import org.fusesource.cloudmix.common.dto.Dependency;
import org.fusesource.cloudmix.common.dto.ProfileDetails;
import org.fusesource.cloudmix.common.dto.ProvisioningAction;
/**
* @version $Revision: 1.1 $
*/
public class MopAgent extends InstallerAgent {
public static final String MOP_URI_PREFIX = "mop:";
private Map<String, MopProcess> processes = Maps.newHashMap();
private ClassLoader mopClassLoader;
public MopAgent() {
// lets default the profile
setProfile("*");
mopClassLoader = getClass().getClassLoader();
}
@Override
public File getWorkDirectory() {
File answer = super.getWorkDirectory();
if (answer == null) {
setWorkDirectory(new File("mopAgentWork"));
answer = super.getWorkDirectory();
}
return answer;
}
/**
* Returns the currently active processes this agent is running
*/
public ImmutableMap<String, MopProcess> getProcesses() {
synchronized (processes) {
// lets remove all the dead processes
List<MopProcess> list = Lists.newArrayList(processes.values());
for (MopProcess process : list) {
if (process.isCompleted()) {
processes.remove(process.getId());
}
}
return ImmutableMap.copyOf(processes);
}
}
/**
* A helper method for testing mostly
*
* @param commandLine
*/
public void installMopFeature(String commandLine) throws Exception {
String resource = MOP_URI_PREFIX + commandLine;
String feature = "feature:" + UUID.randomUUID().toString();
ProvisioningAction action = new ProvisioningAction(feature, resource);
String credentials = "";
installFeatures(action, credentials, resource);
}
@Override
public void init() throws Exception {
System.out.println("==================== CREATING MOP AGENT " + this
+ " = " + System.identityHashCode(this));
super.init();
mopClassLoader = Thread.currentThread().getContextClassLoader();
}
@Override
protected void installFeatures(ProvisioningAction action,
String credentials,
String resource) throws Exception {
System.out.println("Installing FEATURES: " + resource);
if (resource.startsWith(MOP_URI_PREFIX)) {
String commandLine = resource.substring(MOP_URI_PREFIX.length());
// Lets set the context class loader to the one that loaded me!
Thread currentThread = Thread.currentThread();
ClassLoader oldClassLoader = currentThread.getContextClassLoader();
currentThread.setContextClassLoader(mopClassLoader);
try {
MopProcess process = new MopProcess(this, action, credentials, commandLine, mopClassLoader);
String id = process.getId();
synchronized (processes) {
MopProcess oldProcess = processes.get(id);
if (oldProcess != null) {
oldProcess.stop();
}
processes.put(id, process);
}
process.start();
// now lets update the current features
Feature feature = new Feature(id);
addAgentFeature(feature);
// TODO also need to update the current features!
} finally {
currentThread.setContextClassLoader(oldClassLoader);
}
} else {
System.out.println("Could not install FEATURES, due to invalid syntax: " + resource);
}
}
@Override
protected void uninstallFeature(Feature feature) throws Exception {
System.out.println("Uninstalling FEATURE: " + feature);
String id = feature.getName();
synchronized (processes) {
MopProcess oldProcess = processes.get(id);
if (oldProcess != null) {
oldProcess.stop();
}
}
super.uninstallFeature(feature);
removeFeatureId(id);
}
public File createProcessDirectory(ProvisioningAction action) {
return new File(getWorkDirectory(), action.getFeature().replace(':', '_'));
}
public String getProfileFor(ProvisioningAction action) {
String feature = action.getFeature();
List<ProfileDetails> list = getClient().getProfiles();
for (ProfileDetails profileDetails : list) {
List<Dependency> dependencies = profileDetails.getFeatures();
for (Dependency dependency : dependencies) {
if (Objects.equal(dependency.getFeatureId(), feature)) {
return profileDetails.getId();
}
}
}
return null;
}
}