Package xcat.services

Source Code of xcat.services.XCATBuilderServiceImpl

/*
* Indiana University Extreme! Lab Software License, Version 1.2
*
* Copyright (C) 2002 The Trustees of Indiana University.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1) All redistributions of source code must retain the above
*    copyright notice, the list of authors in the original source
*    code, this list of conditions and the disclaimer listed in this
*    license;
*
* 2) All redistributions in binary form must reproduce the above
*    copyright notice, this list of conditions and the disclaimer
*    listed in this license in the documentation and/or other
*    materials provided with the distribution;
*
* 3) Any documentation included with all redistributions must include
*    the following acknowledgement:
*
*      "This product includes software developed by the Indiana
*      University Extreme! Lab.  For further information please visit
*      http://www.extreme.indiana.edu/"
*
*    Alternatively, this acknowledgment may appear in the software
*    itself, and wherever such third-party acknowledgments normally
*    appear.
*
* 4) The name "Indiana Univeristy" or "Indiana Univeristy
*    Extreme! Lab" shall not be used to endorse or promote
*    products derived from this software without prior written
*    permission from Indiana University.  For written permission,
*    please contact http://www.extreme.indiana.edu/.
*
* 5) Products derived from this software may not use "Indiana
*    Univeristy" name nor may "Indiana Univeristy" appear in their name,
*    without prior written permission of the Indiana University.
*
* Indiana University provides no reassurances that the source code
* provided does not infringe the patent or any other intellectual
* property rights of any other entity.  Indiana University disclaims any
* liability to any recipient for claims brought by any other entity
* based on infringement of intellectual property rights or otherwise.
*
* LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH
* NO WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA
* UNIVERSITY GIVES NO WARRANTIES AND MAKES NO REPRESENTATION THAT
* SOFTWARE IS FREE OF INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR
* OTHER PROPRIETARY RIGHTS.  INDIANA UNIVERSITY MAKES NO WARRANTIES THAT
* SOFTWARE IS FREE FROM "BUGS", "VIRUSES", "TROJAN HORSES", "TRAP
* DOORS", "WORMS", OR OTHER HARMFUL CODE.  LICENSEE ASSUMES THE ENTIRE
* RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR ASSOCIATED MATERIALS,
* AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION GENERATED USING
* SOFTWARE.
*/

/**
* @version $Revision: 1.35 $ $Author: srikrish $ $Date: 2004/09/07 23:22:30 $ (GMT)
* @author Sriram Krishnan [mailto:srikrish@extreme.indiana.edu]
*/

package xcat.services;

import java.util.Hashtable;
import java.io.File;
import java.io.FileInputStream;

import intf.ports.XCATPort;
import intf.ccacore.XCATComponentID;
import intf.ccacore.XCATConnectionID;
import intf.services.XCATBuilderService;
import intf.container.XCATContainer;

import xcat.ports.BasicPortImpl;
import xcat.ccacore.XCATServicesImpl;
import xcat.ccacore.XCATComponentIDClientImpl;
import xcat.ccacore.XCATConnectionIDImpl;
import xcat.mobile.ccacore.MobileComponentIDClientImpl;
import xcat.container.BasicContainer;
import xcat.container.MobileContainer;
import xcat.exceptions.NonstandardException;
import xcat.util.HandleResolver;
import xcat.types.TypeUtil;
import soaprmi.soaprpc.SoapServices;
import soaprmi.server.UnicastRemoteObject;
import soaprmi.ogsi.service.handle_resolver.HandleResolverImpl;

import org.globus.gram.Gram;
import org.globus.gram.GramJob;
import org.globus.gsi.GlobusCredential;
import org.gridforum.jgss.ExtendedGSSManager;
import org.gridforum.jgss.ExtendedGSSCredential;
import org.ietf.jgss.GSSCredential;

import soaprmi.util.logging.Logger;

/**
* Implementation of XCAT's BuilderService
*/
public class XCATBuilderServiceImpl extends HandleResolverImpl
  implements XCATBuilderService {

  private static Logger logger = Logger.getLogger();

  // Hashtable with instance names as keys and ComponentIDs as values
  private Hashtable namedComponentIDs;
  // Hashtable with ComponentIDs as keys and TypeMap Properties as values
  private Hashtable componentIDProps;

  // the GSH for the Builder
  String builderGSH;

  /**
   * Default constructor, this Builder is used as a HandleResolver by default
   */
  public XCATBuilderServiceImpl() throws Exception {
    this(true);
  }

  /**
   * Constructor
   * @param isHandleResolver true if this Builder should function as HandleResolver
   *                         false if it shouldn't
   */
  public XCATBuilderServiceImpl(boolean isHandleResolver) throws Exception {
    super();

    logger.finest("called");

    // instantiate the Hashtables
    namedComponentIDs = new Hashtable();
    componentIDProps = new Hashtable();

    // export this object as a Grid service
    UnicastRemoteObject.exportObject(this,
             new Class[]{XCATBuilderService.class});

    // make this the default Handle Resolver if the boolean value is set
    if (isHandleResolver)
      HandleResolver.setHandleResolverURL(SoapServices.getDefault().
            getStartpointLocation(this));
  }

  /**
   *   Creates an instance of a CCA component of the type defined by the
   *   string className.  The string classname uniquely defines the
   *   "type" of the component, e.g.
   *       doe.cca.Library.GaussianElmination.
   *   It has an instance name given by the string instanceName.
   *   The instanceName may be empty (zero length) in which case
   *   the instanceName will be assigned to the component automatically.
   *   @throws CCAException If the Component className is unknown, or if the
   *     instanceName has already been used, a CCAException is thrown.
   *   @return A ComponentID corresponding to the created component. Destroying
   *     the returned ID does not destroy the component;
   *     see destroyInstance instead.
   */
  public gov.cca.ComponentID createInstance(java.lang.String instanceName,
              java.lang.String className,
              gov.cca.TypeMap properties)
    throws gov.cca.CCAException {
   
    logger.finest("called with parameters: " +
      " instanceName = " + instanceName +
      " className = " + className +
      " properties = " + properties);

    // declare the return value
    gov.cca.ComponentID cid;

    // if this is a reinstantiation of the component, remove the old ComponentIDs
    if (!properties.getString("componentHandle", "None").equals("None")) {
      gov.cca.ComponentID oldCID =
  (gov.cca.ComponentID) namedComponentIDs.remove(instanceName);
      if (oldCID != null)
  componentIDProps.remove(oldCID);
    }

    // check if the instance name is being used
    if (namedComponentIDs.containsKey(instanceName))
      throw new NonstandardException("Instance name : " + instanceName +
             " already in use");
   
    // check if properties is null
    if (properties == null)
      throw new NonstandardException("Properties object should not be null");

    // call the appropriate instantiation method depending on creationProto
    String creationProto = properties.getString("creationProto", "None");
    if (creationProto.equals("local"))
      cid = createInstanceInProc(instanceName, className, properties);
    else if (creationProto.equals("gram"))
      cid = createInstanceUsingGram(instanceName, className, properties);
    else if (creationProto.equals("ssh"))
      cid = createInstanceUsingSSH(instanceName, className, properties);
    else
      throw new NonstandardException("Creation protocol : " + creationProto +
             " not supported");

    // update the componentIDProps hashMap
    componentIDProps.put(cid, properties);

    // return the ComponentID
    return cid;
  }

  /**
   *  Get component list.
   *  @return a ComponentID for each component currently created.
   */
  public java.util.Collection getComponentIDs()
    throws gov.cca.CCAException {
    logger.finest("called");
    return namedComponentIDs.values();
  }

  /**
   *  Get property map for component.
   *  @return the public properties associated with the component referred to by
   *  ComponentID.
   *  @throws a CCAException if the ComponentID is invalid.
   */
  public gov.cca.TypeMap getComponentProperties(gov.cca.ComponentID cid)
    throws gov.cca.CCAException {
    logger.finest("called for Component: " + cid.getInstanceName());
    return (gov.cca.TypeMap) componentIDProps.get(cid);
  }

  /**
   *   Causes the framework implementation to associate the given properties
   *   with the component designated by cid.
   *   @throws CCAException if cid is invalid or if there is an attempted
   *   change to a property locked by the framework implementation.
   *
   *    This method is not implemented, and a NonstandardException is thrown
   */
  public void setComponentProperties(gov.cca.ComponentID cid,
             gov.cca.TypeMap map)
    throws gov.cca.CCAException {
    throw new NonstandardException("Setting component properties after " +
           "instantiation is not permitted");
  }

  /**
   * Get component id from stringified reference.
   *    @return a ComponentID from the string produced by
   *   ComponentID.getSerialization().
   *    @throws CCAException if the string does not represent the appropriate
   *    serialization of a ComponentID for the underlying framework.
   */
  public gov.cca.ComponentID getDeserialization(java.lang.String s)
    throws gov.cca.CCAException {
    logger.finest("called");
      XCATComponentID componentID = (XCATComponentID)
  HandleResolver.resolveHandle(s, XCATComponentID.class.getName());

      return componentID;
  }

  /**
   * Get id from name by which it was created.
   *  @return a ComponentID from the instance name of the component
   *  produced by ComponentID.getInstanceName().
   *  @throws CCAException if there is no component matching the
   *  given componentInstanceName.
   */
  public gov.cca.ComponentID getComponentID(java.lang.String componentInstanceName)
    throws gov.cca.CCAException {
    logger.finest("called for Component: " + componentInstanceName);
    return (gov.cca.ComponentID) namedComponentIDs.get(componentInstanceName);
  }

  /**
   *  Eliminate the Component instance, from the scope of the framework.
   *  @param toDie the component to be removed.
   *  @param timeout the allowable wait; 0 means up to the framework.
   *  @throws CCAException if toDie refers to an invalid component, or
   *  if the operation takes longer than timeout seconds.
   */
  public void destroyInstance(gov.cca.ComponentID toDie,
            float timeout)
    throws gov.cca.CCAException {
    logger.finest("called for Component: " + toDie.getInstanceName());

    // confirm that this is an XCATComponentID
    if (!(toDie instanceof XCATComponentID))
      throw new NonstandardException("ComponentID not an instance of XCATComponentID");
    else {
      try {
  // ignore the timeout value for now
  ((XCATComponentID) toDie).destroy();

  // Q: SHOULD WE REMOVE THIS COMPONENTID FROM OUR HASHMAPS?
      } catch (soaprmi.RemoteException re) {
  throw new NonstandardException("Can't destroy component", re);
      }
    }
  }

  /**
   *  Get the names of Port instances provided by the identified component.
   *  @param cid the component.
   *  @throws CCAException if cid refers to an invalid component.
   */
  public String[] getProvidedPortNames(gov.cca.ComponentID cid)
    throws gov.cca.CCAException {
    logger.finest("called for Component: " + cid.getInstanceName());
    if (!(cid instanceof XCATComponentID))
      throw new NonstandardException("ComponentID not an instance of XCATComponentID");
    else {
      return ((XCATComponentID) cid).getProvidedPortNames();
    }
  }

  /**
   *  Get the names of Port instances used by the identified component.
   *  @param cid the component.
   *  @throws CCAException if cid refers to an invalid component.
   */
  public String[] getUsedPortNames(gov.cca.ComponentID cid)
    throws gov.cca.CCAException {
    logger.finest("called for Component: " + cid.getInstanceName());
    if (!(cid instanceof XCATComponentID))
      throw new NonstandardException("ComponentID not an instance of XCATComponentID");
    else {
      return ((XCATComponentID) cid).getUsedPortNames();
    }
  }

  /**
   *  Fetch map of Port properties exposed by the framework.
   *  @return the public properties pertaining to the Port instance
   *    portname on the component referred to by cid.
   *  @throws CCAException when any one of the following conditions occur:<ul>
   *    <li>portname is not a registered Port on the component indicated by cid,
   *    <li>cid refers to an invalid component. </ul>
   *
   *  This method is currently not implemented
   */
  public gov.cca.TypeMap getPortProperties(gov.cca.ComponentID cid,
             java.lang.String portName)
    throws gov.cca.CCAException {
    throw new NonstandardException("This method currently not supported");
  }

  /**
   *  Associates the properties given in map with the Port indicated by
   *  portname. The component must have a Port known by portname.
   *  @throws CCAException if either cid or portname are
   *   invalid, or if this a changed property is locked by
   *    the underlying framework or component.
   *
   *  This method is not implemented, and throws a NonstandardException
   */
  public void setPortProperties(gov.cca.ComponentID cid,
        java.lang.String portName,
        gov.cca.TypeMap map)
    throws gov.cca.CCAException {
    throw new NonstandardException("Can't set port properties after instantiation");
  }

  /**
   *   Creates a connection between ports on component user and
   *   component provider. Destroying the ConnectionID does not
   *   cause a disconnection; for that, see disconnect().
   *   @throws CCAException when any one of the following conditions occur:<ul>
   *   <li>If either user or provider refer to an invalid component,
   *   <li>If either usingPortName or providingPortName refer to a
   *    nonexistent Port on their respective component,
   *   <li>If other-- In reality there are a lot of things that can go wrong
   *    with this operation, especially if the underlying connections
   *    involve networking.</ul>
   */
  public gov.cca.ConnectionID connect(gov.cca.ComponentID user,
              java.lang.String usingPortName,
              gov.cca.ComponentID provider,
              java.lang.String providingPortName)
    throws gov.cca.CCAException {
    logger.finest("called for uses port " + usingPortName +
      " of component " + user.getInstanceName() +
      " and provides port " + providingPortName +
      " of component " + provider.getInstanceName()
      );

    // make sure that the ComponentIDs are XCATComponentIDs
    if (!(user instanceof XCATComponentID) ||
  !(provider instanceof XCATComponentID))
      throw new NonstandardException("ComponentID is not an instance of XCATComponentID");

    // make sure the ports are compatible
    if (!(((XCATComponentID) provider).getProvidesPortType(providingPortName).
    equals(((XCATComponentID) user).getUsesPortType(usingPortName))))
      throw new NonstandardException("Ports are not compatible with each other");

    // increment the number of users on the provides side
    String providesPortHandle = ((XCATComponentID) provider).incrementUsers(providingPortName);

    // add the received provides port information to Uses side
    ((XCATComponentID) user).addUsesConnection(provider.getInstanceName(),
                 provider.getSerialization(),
                 user.getInstanceName(),
                 user.getSerialization(),
                 providingPortName,
                 usingPortName,
                 providesPortHandle);

    // return the connectionID for this connection
    XCATConnectionID connectionID = new XCATConnectionIDImpl(provider,
                   user,
                   providingPortName,
                   usingPortName,
                   providesPortHandle);
    return connectionID;
  }

  /**
   * Returns a list of connections as an array of
   *   handles. This will return all connections involving components
   *   in the given componentList of ComponentIDs. This
   *   means that ConnectionID's will be returned even if only one
   *   of the participants in the connection appears in componentList.
   *
   *   @throws CCAException if any component in componentList is invalid.
   *
   * This method is currently not implemented, and a NonstandardException is
   * thrown
   */
  public java.lang.Object getConnectionIDs(java.lang.Object componentList)
    throws gov.cca.CCAException {
    throw new NonstandardException("This method currently not supported");
  }

  /**
   *   Fetch property map of a connection.
   *   @return the properties for the given connection.
   *   @throws CCAException if connID is invalid.
   *
   *  This method is not implemented, and throws a NonstandardException
   */
  public gov.cca.TypeMap getConnectionProperties(gov.cca.ConnectionID connID)
    throws gov.cca.CCAException {
    throw new NonstandardException("This method currently not supported");
  }

  /**
   * Associates the properties with the connection.
   *   @param map the source of the properties.
   *   @param connID connection to receive property values.
   *   @throws CCAException if connID is invalid, or if this changes
   *    a property locked by the underlying framework.
   *
   * This method is not implemented, and a NonstandardException is thrown
   */
  public void setConnectionProperties(gov.cca.ConnectionID connID,
              gov.cca.TypeMap map)
    throws gov.cca.CCAException {
    throw new NonstandardException("Can't set properties after connection is made");
  }

  /**
   * Disconnect the connection indicated by connID before the indicated
   *     timeout in secs. Upon successful completion, connID and the connection
   *     it represents become invalid.
   *     @param timeout the time in seconds to wait for a connection to close; 0
   *     means to use the framework implementation default.
   *     @throws CCAException when any one of the following conditions occur: <ul>
   *     <li>id refers to an invalid ConnectionID,
   *     <li>timeout is exceeded, after which, if id was valid before
   * disconnect() was invoked, it remains valid
   * </ul>
   *
   */
  public void disconnect(gov.cca.ConnectionID connID,
       float timeout)
    throws gov.cca.CCAException {
    logger.finest("called for connection between uses port of " +
      connID.getUser().getInstanceName() +
      " and provides port of " +
      connID.getProvider().getInstanceName());

    if (!(connID instanceof XCATConnectionID))
      throw new NonstandardException("ConnectionID not an instance of XCATConnectionID");
   
    if (!(connID.getProvider() instanceof XCATComponentID) ||
  !(connID.getUser() instanceof XCATComponentID))
      throw new NonstandardException("ComponentIDs not instances of XCATComponentID");

    XCATComponentID provider = (XCATComponentID) connID.getProvider();
    XCATComponentID user = (XCATComponentID) connID.getUser();

    // remove the connection of the user's side
    user.disconnectProvider(connID.getUserPortName());

    // notify the provider's side
    provider.disconnectUser(connID.getProviderPortName());
  }

  /**
   * Remove all connections between components id1 and id2 within
   *   the period of timeout secs. If id2 is null, then all connections
   *   to id1 are removed (within the period of timeout secs).
   *   @throws CCAException when any one of the following conditions occur:<ul>
   *     <li>id1 or id2 refer to an invalid ComponentID (other than id2 == null),
   *     <li>The timeout period is exceeded before the disconnections can be made.
   *     </ul>
   *
   * This method is currently not implemented. A NonstandardException is thrown.
   */
  public void disconnectAll(gov.cca.ComponentID id1,
          gov.cca.ComponentID id2,
          float timeout)
    throws gov.cca.CCAException {
    throw new NonstandardException("This method currently not supported");
  }

  //-------------------------------------------------//
  // List of private component instantiation methods //
  //-------------------------------------------------//

  private gov.cca.ComponentID createInstanceInProc(java.lang.String instanceName,
               java.lang.String className,
               gov.cca.TypeMap properties)
    throws gov.cca.CCAException {
    logger.finest("called with parameters: " +
      " instanceName = " + instanceName +
      " className = " + className +
      " properties = " + properties);

    // Create a container for this component, and instantiate the component
    String componentType = properties.getString("componentType", "basic");
    logger.finest("componentType: " + componentType);

    // Create a GSH for this component, if it has not been provided already
    String componentHandle =
      properties.getString("componentHandle",
         HandleResolver.createGSH(instanceName));

    XCATContainer container = null;
    XCATComponentID cid = null;
    if (componentType.equals("basic")) {
      container = new BasicContainer();

      // Instantiate the component
      container.createComponentInstance(instanceName,
          componentHandle,
          className);     
      // Create an instance of the client side of XCATComponentID
      cid = new XCATComponentIDClientImpl(instanceName, componentHandle);
    } else if (componentType.equals("mobile")) {
      container = new MobileContainer();

      if (properties.getBool("isMigrated", false))
  ((MobileContainer) container).setIsMigrated();

      // Instantiate the component
      container.createComponentInstance(instanceName,
          componentHandle,
          className);     
      // Create an instance of the client side of XCATComponentID
      cid = new MobileComponentIDClientImpl(instanceName, componentHandle);
    } else
      throw new NonstandardException("Unknown componentType: " + componentType);

    // transfer the properties object to the component
    cid.setProperties(TypeUtil.toXML(properties));

    // update the namedComponentIDs hashMap
    namedComponentIDs.put(instanceName, cid);
   
    // return the ComponentID
    return cid;
  }

  private gov.cca.ComponentID createInstanceUsingGram(java.lang.String instanceName,
                  java.lang.String className,
                  gov.cca.TypeMap properties)
    throws gov.cca.CCAException {
    logger.finest("called with parameters: " +
      " instanceName = " + instanceName +
      " className = " + className +
      " properties = " + properties);
   
    // get all the required properties
    String execHost = properties.getString("execHost", "None");
    if (execHost.equals("None"))
      throw new NonstandardException("Property execHost is not set");
    String execDir = properties.getString("execDir", "None");
    if (execDir.equals("None"))
      throw new NonstandardException("Property execDir is not set");
    String execName = properties.getString("execName", "None");
    if (execName.equals("None"))
      throw new NonstandardException("Property execName is not set");
    String componentType = properties.getString("componentType", "basic");
    if (!(componentType.equals("basic") || componentType.equals("mobile")))
      throw new NonstandardException("Unknown componentType: " + componentType);

    logger.finest(" execHost = " + execHost +
      " execDir = " + execDir +
      " execName = " + execName +
      " componentType = " + componentType);

    try {
      // Create a GSH for this component, if it has not been provided already
      String componentHandle =
  properties.getString("componentHandle",
           HandleResolver.createGSH(instanceName));
     
      // retrieve the URL of the Handle Resolver
      String handleResolverURL = HandleResolver.getHandleResolverURL();

      // get the stdOut and stdErr variables
      String stdOut = properties.getString("stdOut", "None");
      String stdErr = properties.getString("stdErr", "None");
      if (stdOut.equals("None"))
  stdOut = instanceName + ".out";
      if (stdErr.equals("None"))
  stdErr = instanceName + ".err";
     
      // check if the component has been migrated
      boolean isMigrated = properties.getBool("isMigrated", false);
 
      // construct the RSL
      String theRSL =
  "&(executable=" + execName + ")" +
  "(arguments=" + componentType + " " + instanceName +
  " " + className + " " + handleResolverURL + " " +
  builderGSH + " " + componentHandle + " " +
  isMigrated + ")" +
  "(directory=" + execDir + ")" +
  "(stdout=" + stdOut + ")" +
  "(stderr=" + stdErr + ")";
     
      // create a Gram Job
      GramJob theJob = new GramJob(theRSL);

      // if a proxy is passed via the typeMap, use it
      String proxyPath = properties.getString("X509_USER_PROXY", "None");
      if(!proxyPath.equals("None")) {
  File f = new File(proxyPath);
  byte [] data = new byte[(int) f.length()];
  FileInputStream in = new FileInputStream(f);
  // read in the credential data
  in.read(data);
  in.close();
 
  ExtendedGSSManager manager =
    (ExtendedGSSManager) ExtendedGSSManager.getInstance();
  GSSCredential proxy =
    manager.createCredential(data,
           ExtendedGSSCredential.IMPEXP_OPAQUE,
           GSSCredential.DEFAULT_LIFETIME,
           null, // use default mechanism - GSI
           GSSCredential.INITIATE_AND_ACCEPT);
  theJob.setCredentials(proxy);
      }

      // request execution of the job
      boolean NOT_BATCH = false;
      boolean NOT_LIMITED = false;
      Gram.request(execHost, theJob, NOT_BATCH, NOT_LIMITED);
    } catch (Exception e) {
      logger.severe("Can not launch remote component", e);
      throw new NonstandardException("Can not launch remote component", e);
    }

    // initialize XCATComponentIDClient with a null GSH
    XCATComponentID cid = null;
    if (componentType.equals("basic"))
      cid = new XCATComponentIDClientImpl(instanceName, null);
    else if (componentType.equals("mobile"))
      cid = new MobileComponentIDClientImpl(instanceName, null);
    else // shouldn't get here, since we have thrown this exception before
      throw new NonstandardException("Unknown componentType: " + componentType);

    // insert into the namedComponentIDs hashMap
    namedComponentIDs.put(instanceName, cid);

    synchronized(cid) {
      if (cid.getSerialization() == null)
  try {
    logger.finest("waiting to receive ComponentID");

    // wait to receive the ComponentID from remote component
    long timeout = properties.getLong("timeout", DEFAULT_TIMEOUT);
    logger.finest("received timeout: " + timeout);
    cid.wait(timeout);
 
    logger.finest("woken up after waiting to receive ComponentID");
  } catch (InterruptedException ie) {
    logger.severe(ie.toString(), ie);
  }
    }

    // check if the ComponentiD has been received
    if (cid.getSerialization() == null)
      throw new NonstandardException("Timed out while receiving ComponentID");

    // transfer the properties object to the component
    cid.setProperties(TypeUtil.toXML(properties));

    // return the ComponentID from the namedComponentIDs hashMap
    return cid;
  }

  private gov.cca.ComponentID createInstanceUsingSSH(java.lang.String instanceName,
                 java.lang.String className,
                 gov.cca.TypeMap properties)
    throws gov.cca.CCAException {
    logger.finest("called with parameters: " +
      " instanceName = " + instanceName +
      " className = " + className +
      " properties = " + properties);
   
    // get all the required properties
    String execHost = properties.getString("execHost", "None");
    if (execHost.equals("None"))
      throw new NonstandardException("Property execHost is not set");
    String execDir = properties.getString("execDir", "None");
    if (execDir.equals("None"))
      throw new NonstandardException("Property execDir is not set");
    String execName = properties.getString("execName", "None");
    if (execName.equals("None"))
      throw new NonstandardException("Property execName is not set");
    String sshHome = properties.getString("sshHome", "None");
    if (sshHome.equals("None"))
      throw new NonstandardException("Property sshHome is not set");
    String componentType = properties.getString("componentType", "basic");
    if (!(componentType.equals("basic") || componentType.equals("mobile")))
      throw new NonstandardException("Unknown componentType: " + componentType);

    logger.finest(" execHost = " + execHost +
      " execDir = " + execDir +
      " execName = " + execName +
      " componentType = " + componentType +
      " sshHome = " + sshHome);
    try {
      // Create a GSH for this component, if it has not been provided already
      String componentHandle =
  properties.getString("componentHandle",
           HandleResolver.createGSH(instanceName));

      // retrieve the URL of the Handle Resolver
      String handleResolverURL = HandleResolver.getHandleResolverURL();

      // get the names for the stdOut and stdErr
      String stdOut = properties.getString("stdOut", "None");
      String stdErr = properties.getString("stdErr", "None");
      if (stdOut.equals("None"))
  stdOut = instanceName + ".out";
      if (stdErr.equals("None"))
  stdErr = instanceName + ".err";

      // check if the component has been migrated
      boolean isMigrated = properties.getBool("isMigrated", false);
 
      // construct the executable
      String command =
  "/bin/sh -c \"cd " + execDir + "; " + "./" + execName + " " +
  componentType + " " + instanceName + " " + className + " " +
  handleResolverURL + " " + builderGSH + " " + componentHandle +
  " " + isMigrated + " >> " + stdOut + " 2>> " + stdErr + "\"";
     
      // Launch this executable in a separate process
      String[] fullCommand = new String[] {sshHome, execHost, command};
      Runtime.getRuntime().exec(fullCommand);
    } catch (Exception e) {
      logger.severe("Can not launch remote component", e);
      throw new NonstandardException("Can not launch remote component", e);
    }

    // initialize XCATComponentIDClient with a null GSH
    XCATComponentID cid = null;
    if (componentType.equals("basic"))
      cid = new XCATComponentIDClientImpl(instanceName, null);
    else if (componentType.equals("mobile"))
      cid = new MobileComponentIDClientImpl(instanceName, null);
    else // shouldn't get here, since we have thrown this exception before
      throw new NonstandardException("Unknown componentType: " + componentType);
   
    // insert into the namedComponentIDs hashMap
    namedComponentIDs.put(instanceName, cid);

    synchronized(cid) {
      if (cid.getSerialization() == null)
  try {
    logger.finest("waiting to receive ComponentID");

    // wait to receive the ComponentID from remote component
    long timeout = properties.getLong("timeout", DEFAULT_TIMEOUT);
    logger.finest("received timeout: " + timeout);
    cid.wait(timeout);
 
    logger.finest("woken up after waiting to receive ComponentID");
  } catch (InterruptedException ie) {
    logger.severe(ie.toString(), ie);
  }
    }

    // check if the ComponentiD has been received
    if (cid.getSerialization() == null)
      throw new NonstandardException("Timed out while receiving ComponentID");

    // transfer the properties object to the component
    cid.setProperties(TypeUtil.toXML(properties));

    // return the ComponentID from the namedComponentIDs hashMap
    return cid;
  }

  //-----------------------------------------------------//
  // Methods defined by the XCATBuilderService interface //
  //-----------------------------------------------------//

  /**
   * The remote instantiator uses this method on the Builder Service to
   * notify successful creation of a component
   *
   * @param instanceName the name of the component instance
   * @param componentIDHandle the GSH of the remote component
   */
  public void instantiationComplete(String instanceName,
            String componentIDHandle)
    throws gov.cca.CCAException {
    logger.finest("called for instanceName: " + instanceName);

    XCATComponentIDClientImpl cid =
      (XCATComponentIDClientImpl) namedComponentIDs.get(instanceName);

    if (cid == null)
      throw new NonstandardException("Instance name : " + instanceName +
             " is unknown");

    synchronized(cid) {
     
      // set the GSH for the ComponentIDClient
      cid.setSerialization(componentIDHandle);

      // notify thread waiting to receive this ComponentID
      cid.notify();
    }
  }


  //------------------------------------------------------------//
  // Methods defined by the XSoapGridServiceInterface interface //
  //------------------------------------------------------------//

  /**
   * Destroy the builder after 5 seconds
   */
  public void destroyImpl() {
    logger.finest("called; going down in 5 seconds");

    // wait for 5 seconds, and die in a separate thread
    new Thread() {
  public void run() {
    try {
      Thread.sleep(5000);
    } catch (Exception e) {
      logger.severe(e.toString(), e);
      System.exit(-1);
    }
    System.exit(0);
  }
      }.start();
  }

  //-----------------------------------------------------//
  //      Methods defined in the XCATPort Interface      //
  //-----------------------------------------------------//

  /**
   * Get the GSH for this Port
   */
  public String getGSH()
    throws gov.cca.CCAException {
    logger.finest("called");
    if (builderGSH == null)
      throw new NonstandardException("GSH for this port is not set");
    return builderGSH;
  }

  /**
   * Set the GSH for this Port
   * @param handle the GSH for this port
   */
  public void setGSH(String handle)
    throws gov.cca.CCAException {
    logger.finest("called with handle: " + handle);
    if (builderGSH != null)
      throw new NonstandardException("GSH for this port is already set");
    builderGSH = handle;
  }

  //-------------------------------------------------------------------/
  //   Methods for additions of connections to standard Web services   /
  //-------------------------------------------------------------------/

  /**
   * Connect a WS port of a component to a Web service endpoint
   * @param user the ComponentID for the component that is to be connected
   * @param wsPortName the name of the port that is to be connected
   * @param endPointLocation the URL for the Web service endpoint
   */
  public void connectToWS(XCATComponentID user,
        String wsPortName,
        String endPointLocation)
    throws gov.cca.CCAException {
    logger.finest("called for component: " + user.getInstanceName() +
      " and port: " + wsPortName);
    user.addWSConnection(wsPortName,
       endPointLocation);
  }

  /**
   * Disconnect a WS port of a component that is connected to a Web service
   * @param user the ComponentID for the component that is to be connected
   * @param wsPortName the name of the port that is to be connected
   */
  public void disconnectFromWS(XCATComponentID user,
             String wsPortName)
    throws gov.cca.CCAException {
    logger.finest("called for component: " + user.getInstanceName() +
      " and port: " + wsPortName);
    user.disconnectWS(wsPortName);
  }
}
TOP

Related Classes of xcat.services.XCATBuilderServiceImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.