public class CommonConfigurationKeys {

  /** Location of zookeeper servers */
  public static final String ZOOKEEPER_ADDRESS_KEY = "hms.zookeeper.address";
  /** Default location of zookeeper servers */
  public static final String ZOOKEEPER_ADDRESS_DEFAULT = "localhost:2181";
  
  /** Path to zookeeper cluster root */
  public static final String ZOOKEEPER_CLUSTER_ROOT_KEY = "hms.zookeeper.cluster.path";
  /** Default location of zookeeper cluster root */
  public static final String ZOOKEEPER_CLUSTER_ROOT_DEFAULT = "/clusters";
  
  /** Path to zookeeper command queue */
  public static final String ZOOKEEPER_COMMAND_QUEUE_PATH_KEY = "hms.zookeeper.command.queue.path";
  /** Default location of zookeeper command queue */
  public static final String ZOOKEEPER_COMMAND_QUEUE_PATH_DEFAULT = "/cmdqueue";
  
  /** Path to zookeeper live controller queue */
  public static final String ZOOKEEPER_LIVE_CONTROLLER_PATH_KEY = "hms.zookeeper.live.controller.path";
  /** Default location of zookeeper live controller queue */
  public static final String ZOOKEEPER_LIVE_CONTROLLER_PATH_DEFAULT = "/livecontrollers";
  
  /** Path to zookeeper lock queue */
  public static final String ZOOKEEPER_LOCK_QUEUE_PATH_KEY = "hms.zookeeper.lock.queue.path";
  /** Default location of zookeeper lock queue */
  public static final String ZOOKEEPER_LOCK_QUEUE_PATH_DEFAULT = "/locks";
 
  /** Reference key for path to nodes manifest */
  public static final String ZOOKEEPER_NODES_MANIFEST_KEY = "hms.nodes.manifest.path";
  /** Default location of nodes manifest */
  public static final String ZOOKEEPER_NODES_MANIFEST_PATH_DEFAULT = "/nodes-manifest";
  
  /** Zeroconf zookeeper type */
  public static final String ZEROCONF_ZOOKEEPER_TYPE = "_zookeeper._tcp.local.";
  
  /** Path to zookeeper status qeueue */
  public static final String ZOOKEEPER_STATUS_QUEUE_PATH_KEY = "hms.zookeeper.status.queue.path";
  /** Default location of zookeeper status queue */
  public static final String ZOOKEEPER_STATUS_QUEUE_PATH_DEFAULT = "/status";
  
  /** Path to zookeeper software manifest */
  public static final String ZOOKEEPER_SOFTWARE_MANIFEST_KEY = "hms.software.manifest.path";
  
  /** Default location of software manifest */
  public static final String ZOOKEEPER_SOFTWARE_MANIFEST_PATH_DEFAULT = "/software-manifest";
  
  /** Path to zookeeper config blueprint */
  public static final String ZOOKEEPER_CONFIG_BLUEPRINT_PATH_DEFAULT = "/config-blueprint";
} @XmlRootElement
public class Response extends RestSource {
  @XmlElement(name="exit_code")
  public int code;
  @XmlElement
  public String output;
  @XmlElement
  public String error;
  
  public int getCode() {
    return code;
  }
  
  public String getOutput() {
    return output;
  }
  
  public String getError() {
    return error;
  }
  
  public void setCode(int code) {
    this.code = code;  
  }
  
  public void setOutput(String output) {
    this.output = output;
  }
  
  public void setError(String error) {
    this.error = error;
  }
  
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("exit code:");
    sb.append(code);
    sb.append("\nstdout:\n");
    sb.append(output);
    sb.append("\nstderr:\n");
    sb.append(error);
    sb.append("\n");
    return sb.toString();
  }
} @XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(propOrder = { "roles" })
@XmlRootElement
public class NodesManifest extends Manifest {
  @XmlElement
  public List<Role> roles;
  
  public List<Role> getRoles() {
    return this.roles;
  }
  
  public void setNodes(List<Role> roles) {
    this.roles = roles;
  }
} public class PackageInfo extends RestSource {
  @XmlElement
  private String name;
  @XmlElement
  private String[] relocate;
  
  public String getName() {
    return name;
  }
  
  public String[] getRelocate() {
    return relocate;
  }
  
  public void setName(String name) {
    this.name = name;
  }
  
  public void setRelocate(String[] relocate) {
    this.relocate = relocate;
  }
  
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("package: ");
    sb.append(name);
    return sb.toString();
  }
  
  @Override
  public boolean equals(Object obj) {
    if(obj == null) {
      return false;
    }
    return name.equals(((PackageInfo) obj).getName());
  }
  
  @Override
  public int hashCode() {
    return name.hashCode();
  }
} public class Role extends RestSource {
  @XmlAttribute
  public String name;
  @XmlElement(name="package")
  private PackageInfo[] packages;
  @XmlElement(name="host")
  private String[] hosts;
  
  public String getName() {
    return this.name;
  }
  
  public PackageInfo[] getPackages() {
    return this.packages;
  }
  
  public String[] getHosts() {
    return this.hosts;
  }
  
  public void setName(String name) {
    this.name = name;
  }
  
  public void setPackages(PackageInfo[] packages) {
    this.packages = packages;
  }
  
  public void setHosts(String[] hosts) {
    this.hosts = hosts;
  }
} @XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name="", propOrder = {})
@XmlRootElement
public class SoftwareManifest extends Manifest {
  @XmlAttribute
  private String name;
  @XmlAttribute
  private String version;
  @XmlElement
  private List<Role> roles;
  
  public String getName() {
    return this.name;
  }
  
  public String getVersion() {
    return this.version;
  }
  
  public List<Role> getRoles() {
    return this.roles;
  }
  
  public void setName(String name) {
    this.name = name;
  }
  
  public void setVersion(String version) {
    this.version = version;
  }
  
  public void setRoles(List<Role> roles) {
    this.roles = roles;
  }
} public class ExceptionUtil {
  public static String getStackTrace(Throwable t) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);
    t.printStackTrace(pw);
    pw.flush();
    return sw.toString();
  }
} public class HostUtil {
  private static int MAX = 100000;
  private static String regex = "\\[(\\d+)-(\\d+)\\]";
  private static Pattern p = Pattern.compile(regex);
  
  private static List<NumberRange> ranges;
  private List<Integer> rangesPaddingSize = null;
  private String[] expressions = null;
  private static Integer[] indices;
  private static List<String> hosts;
  
  public HostUtil(String[] expressions) {
//    this.automaton = new RegExp(regex).toAutomaton();
    this.ranges = new ArrayList<NumberRange>();
    this.rangesPaddingSize = new ArrayList<Integer>();
    this.expressions = expressions;
    this.hosts = new ArrayList<String>();
  }
  
  /*
   * Compile a list of nodes by range expression like [1-10] or [01-10]
   */
  public List<String> generate() {
    for(String exp : expressions) {
      if(exp.indexOf('[')>=0) {
        ranges.clear();
        rangesPaddingSize.clear();
        findRange(exp);
        String template = generateTemplate(exp);
        indices = new Integer[ranges.size()];
        compute(0, ranges.get(0), template);
      } else {
        hosts.add(exp);
      }
    }
    return hosts;
  }

  private void findRange(String exp) {
    Matcher m = p.matcher(exp);
    while(m.find()) {
      int low = Integer.parseInt(m.group(1));
      int high = Integer.parseInt(m.group(2));
      int padding = checkPadding(m.group(1));
      if(low > high) {
        throw new RuntimeException("Invalid range - low: "+low+" high: "+high);
      }
      NumberRange range = new NumberRange(low, high);
      ranges.add(range);
      rangesPaddingSize.add(padding);
    }
  }

  private String generateTemplate(String exp) {
    String template = exp;
    for(int i = 0; i < rangesPaddingSize.size(); i++) {
      if(rangesPaddingSize.get(i)>0) {
        StringBuilder s = new StringBuilder();
        s.append("%0");
        s.append(rangesPaddingSize.get(i));
        s.append("d");
        template = template.replaceFirst(regex, s.toString());
      } else {
        template = template.replaceFirst(regex, "\\%d");        
      }
    }
    return template;
  }
  
//  private List<String> populateNames(List<NumberRange> ranges) {
//    List<String> list = new ArrayList<String>();
//    int[] index = new int[ranges.size()];
//    int tracker = 0;
//    for(NumberRange range : ranges) {
//      for(int current = range.getMinimumInteger();current < range.getMaximumInteger(); current++)
//      index[tracker] = current;
//      locateName(tracker, index, range);
//      tracker++;
//    }
//    return list;    
//  }

  private static void compute(int depth, NumberRange range, String template) {
    int depth2 = depth;
    for (int i=range.getMinimumInteger(); i<=range.getMaximumInteger(); i++) {
      indices[depth] = new Integer(i);
      if(depth < ranges.size() - 1 ) {
        depth++;
        compute(depth, ranges.get(depth), template);
        depth = depth2;
      } else {
        String buffer = String.format(template, indices);
        hosts.add(buffer);
        //System.out.println(buffer);
      }
    }
   }
  
  private int checkPadding(String start) {
    if(start.indexOf("0")==0) {
      return start.length();
    }
    return 0;
  }
  
  public List<String> generateFromCluster(String cluster) {
    // TODO Auto-generated method stub
    return null;
  }
  
//  private List<String> range(String exp) {
//    List<String> range = new ArrayList<String>();
//    return range;
//  }
//  
//  private final Automaton automaton;
  
//  public String[] generate() {
//    String[] hosts = null;
//    int size = 1;
//    ArrayList<byte[]> array = new ArrayList<byte[]>();
//    generate(array, automaton.getInitialState());
//    for(byte[] choices : array) {
//      size=size*choices.length;
//      for(int loop = 0; loop<choices.length; loop++) {
//        System.out.print((char) choices[loop]);
//      }
//      System.out.println("");
//    }
//    hosts = new String[size];
//
//    return hosts;
//  }

//  private void generate(ArrayList<byte[]> array, State state) {
//    List<Transition> transitions = state.getSortedTransitions(true);
//    if (transitions.size() == 0) {
//        assert state.isAccept();
//        return;
//    }
//    int nroptions = state.isAccept() ? transitions.size() : transitions.size() - 1;
//    int option = transitions.size() -1;
//    if (state.isAccept() && option == 0) {          // 0 is considered stop
//        return;
//    }
//    // Moving on to next transition
//    Transition transition = transitions.get(option - (state.isAccept() ? 1 : 0));
//    findChoice(array, transition);
//    generate(array, transition.getDest());
//  }
//
//  private void findChoice(ArrayList<byte[]> array, Transition transition) {
//    byte[] list= new byte[transition.getMax()-transition.getMin()+1];
//    int j = 0;
//    for(int i = transition.getMin(); i<= transition.getMax(); i++) {
//      list[j] =(byte) i;
//      j++;
//    }
//    array.add(list);
//  }
  
//  private String walk(ArrayList<byte[]> tree, StringBuilder buffer) {
//    if(tree != null) {
//      for(int i=0; i<tree.size(); i++) {
//        if(tree.get(i)!=null) {
//          walk(tree.get(i), buffer);
//        } else {
//          return buffer.toString();
//        }
//      }
//    }
//    return buffer.toString();
//  }
  
  public static void main(String[] args) {
    HostUtil util = new HostUtil(args);
    List<String> hosts = util.generate();
    for(String host : hosts) {
      System.out.println(host);
    }
  }

} public class JAXBUtil {

  private static ObjectMapper mapper = new ObjectMapper();
  private static AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();
  
  public JAXBUtil() {
    mapper.getDeserializationConfig().setAnnotationIntrospector(introspector);
    mapper.getSerializationConfig().setAnnotationIntrospector(introspector);    
  }
  
  public static byte[] write(RestSource x) throws IOException {
    try {
      return mapper.writeValueAsBytes(x);
    } catch (Throwable e) {
      throw new IOException(e);
    }
  }
  
  public static <T> T read(byte[] buffer, java.lang.Class<T> c) throws IOException {
    return (T) mapper.readValue(buffer, 0, buffer.length, c);
  }

  public static String print(RestSource x) throws IOException {
    try {
      JsonFactory jf = new JsonFactory();
      StringWriter sw = new StringWriter();
      JsonGenerator jp = jf.createJsonGenerator(sw);
      jp.useDefaultPrettyPrinter();
      mapper.writeValue(jp, x);
      jp.close();
      String buffer = sw.toString(); 
      return buffer;
    } catch (Throwable e) {
      throw new IOException(e);
    }    
  }
} public class ZookeeperUtil {
  public static String COMMAND_STATUS = "/status";
  private static final Pattern BASENAME = Pattern.compile(".*?([^/]*)$");
  
  public static String getClusterPath(String clusterName) {
    StringBuilder clusterNode = new StringBuilder();
    clusterNode.append(CommonConfigurationKeys.ZOOKEEPER_CLUSTER_ROOT_DEFAULT);
    clusterNode.append("/");
    clusterNode.append(clusterName);
    return clusterNode.toString();
  }
  
  public static String getCommandStatusPath(String cmdPath) {
    StringBuilder cmdStatusPath = new StringBuilder();
    cmdStatusPath.append(cmdPath);
    cmdStatusPath.append(COMMAND_STATUS);
    return cmdStatusPath.toString();
  }
  
  public static String getBaseURL(String url) {
      Matcher matcher = BASENAME.matcher(url);
      if (matcher.matches()) {
        return matcher.group(1);
      } else {
        throw new IllegalArgumentException("Can't parse " + url);
      }
  }
  
  public static String getNodesManifestPath(String id) {
    StringBuilder nodesPath = new StringBuilder();
    nodesPath.append(CommonConfigurationKeys.ZOOKEEPER_NODES_MANIFEST_PATH_DEFAULT);
    nodesPath.append("/");
    nodesPath.append(id);
    return nodesPath.toString();
  }

  public static String getSoftwareManifestPath(String id) {
    StringBuilder nodesPath = new StringBuilder();
    nodesPath.append(CommonConfigurationKeys.ZOOKEEPER_SOFTWARE_MANIFEST_PATH_DEFAULT);
    nodesPath.append("/");
    nodesPath.append(id);
    return nodesPath.toString();
  }
  
  public static String getConfigManifestPath(String id) {
    StringBuilder configPath = new StringBuilder();
    configPath.append(CommonConfigurationKeys.ZOOKEEPER_CONFIG_BLUEPRINT_PATH_DEFAULT);
    configPath.append("/");
    configPath.append(id);
    return configPath.toString();
  }
} public class Controller implements Watcher {
  private static Log LOG = LogFactory.getLog(Controller.class);
  public static String CONTROLLER_PREFIX = "v1";
  public static int CONTROLLER_PORT = 4080;
  private static Controller instance = new Controller();
  private Server server = null;
  private String credential = null;
  
  private ZooKeeper zk;
  private ClientHandler clientHandler;
  private CommandHandler commandHandler;
  public volatile boolean running = true; // true while controller runs
  private String zookeeperAddress = CommonConfigurationKeys.ZOOKEEPER_ADDRESS_DEFAULT;

  public static Controller getInstance() {
    return instance;
  }

  public ZooKeeper getZKInstance() {
    return this.zk;
  }
  
  public ClientHandler getClientHandler() {
    return clientHandler;
  }
  
  public CommandHandler getCommandHandler() {
    return commandHandler;
  }
  
  public void process(WatchedEvent event) {
    if (event.getType() == Event.EventType.None) {
        // We are are being told that the state of the
        // connection has changed
        switch (event.getState()) {
        case SyncConnected:
            // In this particular example we don't need to do anything
            // here - watches are automatically re-registered with 
            // server and any watches triggered while the client was 
            // disconnected will be delivered (in order of course)
            break;
        case Expired:
            // It's all over
            running = false;
            commandHandler.stop();
            break;
        }
    }
  }
  
  public void parseConfig() {
    StringBuilder confPath = new StringBuilder();
    String confDir = System.getProperty("HMS_CONF_DIR");
    if(confDir==null) {
      confDir = "/etc/hms";
    }
    confPath.append(confDir);
    confPath.append("/hms.ini");
    try {
      HierarchicalINIConfiguration ini = new HierarchicalINIConfiguration(confPath.toString());
      zookeeperAddress = ini.getSection("zookeeper").getString("quorum", null);
      String user = ini.getSection("zookeeper").getString("user", null);
      String password = ini.getSection("zookeeper").getString("password", null);
      if(user!=null && password!=null) {
        credential = new StringBuilder().append(user).append(":").append(password).toString();
      }
    } catch (Exception e) {
      LOG.warn("Invalid HMS configuration file: " + confPath);
      zookeeperAddress = null;
    }
    LOG.info("ZooKeeper Quorum in "+confPath.toString()+": "+zookeeperAddress);
  }
  
  // Resolve the list of zookeeper hosts from HMS beacons
  public void initmDNS() {
    try {
      ServiceDiscoveryUtil sdu = new ServiceDiscoveryUtil(CommonConfigurationKeys.ZEROCONF_ZOOKEEPER_TYPE);
      sdu.start();
      Thread.sleep(5000);
      Collection<String> list = sdu.resolve();
      if(list.size()>0) {
        StringBuffer buf = new StringBuffer();
        String delimiter = "";
        for(String addr : list) {
          buf.append(delimiter);
          buf.append(addr);
          delimiter = ",";
        }
        zookeeperAddress = buf.toString();
      }
      sdu.close();
      if(zookeeperAddress.equals("")) {
        throw new RuntimeException("Unknown ZooKeeper location.");
      }
      LOG.info("Discovered zookeeper location: "+zookeeperAddress);
    } catch(Exception e) {
      zookeeperAddress = CommonConfigurationKeys.ZOOKEEPER_ADDRESS_DEFAULT;
      LOG.info("Use default zookeeper location: "+zookeeperAddress);
    }
  }
  
  public void start() {
    try {
      //System.out.close();
      //System.err.close();
      parseConfig();
      if(zookeeperAddress == null) {
        initmDNS();
      }
      run();
    } catch(Exception e) {
      LOG.error(ExceptionUtil.getStackTrace(e));
      System.exit(-1);
    }
  }

  private void createDirectory(String path) throws KeeperException, InterruptedException {
    try {
      zk.create(path, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
      if(credential!=null) {
        zk.setACL(path, Ids.CREATOR_ALL_ACL, -1);
      }
      LOG.info("Created HMS cluster root at " + CommonConfigurationKeys.ZOOKEEPER_CLUSTER_ROOT_DEFAULT);        
    } catch (KeeperException.NodeExistsException e) {
    } catch (KeeperException.AuthFailedException e) {
      LOG.warn("Failed to authenticate for "+path);
    }
  }
  
  private void initializeZooKeeper() throws KeeperException, InterruptedException, IOException {
    zk = new ZooKeeper(zookeeperAddress, 600000, this);
    if(credential!=null) {
      zk.addAuthInfo("digest", credential.getBytes());
    }
    String[] list = {
        CommonConfigurationKeys.ZOOKEEPER_CLUSTER_ROOT_DEFAULT,
        CommonConfigurationKeys.ZOOKEEPER_COMMAND_QUEUE_PATH_DEFAULT,
        CommonConfigurationKeys.ZOOKEEPER_LOCK_QUEUE_PATH_DEFAULT,
        CommonConfigurationKeys.ZOOKEEPER_LIVE_CONTROLLER_PATH_DEFAULT,
        CommonConfigurationKeys.ZOOKEEPER_NODES_MANIFEST_PATH_DEFAULT,
        CommonConfigurationKeys.ZOOKEEPER_STATUS_QUEUE_PATH_DEFAULT,
        CommonConfigurationKeys.ZOOKEEPER_SOFTWARE_MANIFEST_PATH_DEFAULT,
        CommonConfigurationKeys.ZOOKEEPER_CONFIG_BLUEPRINT_PATH_DEFAULT
    };
    for(String path : list) {
      createDirectory(path);
    }
    
    // Populate default configuration
    zk.create(CommonConfigurationKeys.ZOOKEEPER_CONFIG_BLUEPRINT_PATH_DEFAULT+"/delete-hadoop-1.0-cluster", JAXBUtil.write(Examples.deleteHadoopCluster), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
    zk.create(CommonConfigurationKeys.ZOOKEEPER_CONFIG_BLUEPRINT_PATH_DEFAULT+"/create-hadoop-1.0-cluster", JAXBUtil.write(Examples.createHadoopCluster), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
  }
  
  public void run() {
    try {
      initializeZooKeeper();
      LOG.info("Connected to ZooKeeper");
      clientHandler = new ClientHandler(zk);
      commandHandler = new CommandHandler(zk, 200);
      commandHandler.start();
    } catch (Exception e) {
      LOG.error(ExceptionUtil.getStackTrace(e));
    }
    server = new Server(CONTROLLER_PORT);

    try {
      Context root = new Context(server, "/", Context.SESSIONS);
      String HMS_HOME = System.getenv("HMS_HOME");
      root.setBaseResource(new ResourceCollection(new Resource[]
        {
          Resource.newResource(HMS_HOME+"/webapps/")
        }));
      ServletHolder rootServlet = root.addServlet(DefaultServlet.class, "/");
      rootServlet.setInitOrder(1);
      
      ServletHolder sh = new ServletHolder(ServletContainer.class);
      sh.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", "com.sun.jersey.api.core.PackagesResourceConfig");
      sh.setInitParameter("com.sun.jersey.config.property.packages", "org.apache.hms.controller.rest");      
      root.addServlet(sh, "/"+CONTROLLER_PREFIX+"/*");
      sh.setInitOrder(2);
      server.setStopAtShutdown(true);
      server.start();
    } catch (Exception e) {
      LOG.error(ExceptionUtil.getStackTrace(e));
    }
  }
  
  public void stop() throws Exception {
    try {
      commandHandler.stop();
      server.stop();
    } catch (Exception e) {
      LOG.error(ExceptionUtil.getStackTrace(e));
    }
  }
  
  /**
   * Wait for service to finish.
   * (Normally, it runs forever.)
   */
  public void join() {
    try {
      this.commandHandler.join();
    } catch (InterruptedException ie) {
    }
  }

  public static void main(String[] args) {
    DaemonWatcher.createInstance(System.getProperty("PID"), 9100);
    try {
      Controller controller = Controller.getInstance();
      if (controller != null) {
        controller.start();
        controller.join();
      }
    } catch(Throwable t) {
      DaemonWatcher.bailout(1);
    }
  }

}
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hms.common.conf.CommonConfigurationKeys;
import org.apache.hms.common.entity.Response;
import org.apache.hms.common.entity.manifest.NodesManifest;
import org.apache.hms.common.entity.manifest.PackageInfo;
import org.apache.hms.common.entity.manifest.Role;
import org.apache.hms.common.entity.manifest.SoftwareManifest;
import org.apache.hms.common.util.ExceptionUtil;
import org.apache.hms.common.util.HostUtil;
import org.apache.hms.common.util.JAXBUtil;
import org.apache.hms.common.util.ZookeeperUtil;
import org.apache.hms.controller.Controller;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.data.Stat;
/*
 * 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.
 */

package org.apache.hms.controller.rest;




@Path("software")
public class SoftwareManager {
  private static Log LOG = LogFactory.getLog(SoftwareManager.class);
  
  @GET
  @Path("stack/sample")
  public SoftwareManifest getSample() {
    SoftwareManifest sm = new SoftwareManifest();
    sm.setName("hadoop");
    sm.setVersion("0.23");
    PackageInfo[] packages = new PackageInfo[1];
    packages[0]= new PackageInfo();
    packages[0].setName("http://hrt8n36.cc1.ygridcore.net/hadoop-0.23.torrent");

    List<Role> roles = new ArrayList<Role>();
    Role role = new Role();
    role.setName("namenode");
    role.setPackages(packages);
    roles.add(role);
    
    role = new Role();
    role.setName("datanode");
    role.setPackages(packages);
    roles.add(role);
    
    role = new Role();
    role.setName("jobtracker");
    role.setPackages(packages);
    roles.add(role);
    
    role = new Role();
    role.setName("tasktracker");
    role.setPackages(packages);
    roles.add(role);

    sm.setRoles(roles);
    return sm;
  }
  
  @GET
  @Path("stack")
  public List<SoftwareManifest> getList() {
    List<SoftwareManifest> list = new ArrayList<SoftwareManifest>();
    try {
      ZooKeeper zk = Controller.getInstance().getZKInstance();