/*
* 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);
}
}