Package xcat.ccacore

Source Code of xcat.ccacore.XCATServicesImpl

/*
* 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.29 $ $Author: srikrish $ $Date: 2004/09/07 23:21:24 $ (GMT)
* @author Sriram Krishnan [mailto:srikrish@extreme.indiana.edu]
*/

package xcat.ccacore;

import gov.cca.Services;
import gov.cca.TypeMap;
import gov.cca.ComponentID;

import intf.ports.XCATPort;
import intf.ccacore.XCATServices;
import intf.ccacore.XCATComponentID;
import intf.ccacore.XCATConnectionID;
import intf.ccacore.XCATConnectionInfo;

import xcat.types.TypeMapImpl;
import xcat.ports.WSPortInfo;
import xcat.ports.UsesPortInfo;
import xcat.ports.ProvidesPortInfo;
import xcat.util.HandleResolver;
import xcat.exceptions.UsesPortNotReleasedException;
import xcat.exceptions.PortAlreadyDefinedException;
import xcat.exceptions.PortNotConnectedException;
import xcat.exceptions.PortNotDefinedException;
import xcat.exceptions.PortNotInUseException;
import xcat.exceptions.NonstandardException;
import xcat.exceptions.UnexpectedException;

import soaprmi.Remote;
import soaprmi.util.logging.Logger;
import soaprmi.server.UnicastRemoteObject;

import java.util.Hashtable;

/**
* Implementation of the XCATServices interface
*/
public class XCATServicesImpl
  implements XCATServices {

  protected static Logger logger = Logger.getLogger();

  protected Hashtable usesPortMap; // map of registered uses ports
  protected Hashtable providesPortMap; // map of added provides ports
  protected Hashtable wsPortMap; // map of registered WS ports

  protected XCATComponentID componentID; // componentID associated with this object
  protected TypeMap compProperties; // properties for the component, set by the user

  /**
   * Default constructor, needed by subclasses
   */
  protected XCATServicesImpl() {
    logger.finest("called");
  }

  /**
   * Constructor
   * @param name The name given to this services object by the Builder service
   */
  public XCATServicesImpl(String name)
    throws gov.cca.CCAException {
    logger.finest("called with name: " + name);

    try {
      // initialize componentID
      componentID = new XCATComponentIDServerImpl(name, this);

      // instantiate the Hashtables
      usesPortMap = new Hashtable();
      providesPortMap = new Hashtable();
      wsPortMap = new Hashtable();

      // initialize the properties
      compProperties = createTypeMap();
    } catch (Exception e) {
      logger.severe("Can not instantiate ComponentID", e);
      throw new UnexpectedException("Can not instantiate ComponentID", e);
    }
  }

  /**
   * Fetch a previously registered Port (defined by either
   * addProvidePort or (more typically) registerUsesPort). 
   * @return Will return the Port (possibly waiting forever while
   * attempting to acquire it) or throw an exception. Does not return
   * NULL, even in the case where no connection has been made.
   * If a Port is returned,
   * there is then a contract that the port will remain valid for use
   * by the caller until the port is released via releasePort(), or a
   * Disconnect Event is successfully dispatched to the caller,
   * or a runtime exception (such as network failure) occurs during
   * invocation of some function in the Port.
   * <p>
   * Subtle interpretation: If the Component is not listening for
   * Disconnect events, then the framework has no clean way to
   * break the connection until after the component calls releasePort.
   * </p>
   * <p>The framework may go through some machinations to obtain
   *    the port, possibly involving an interactive user or network
   *    queries, before giving up and throwing an exception.
   * </p>
   *
   * @param portName The previously registered or provide port which
   *      the component now wants to use.
   * @exception CCAException with following types: PortNotConnected, PortNotDefined,
   *                NetworkError, OutOfMemory.
   */
  public gov.cca.Port getPort(java.lang.String portName)
    throws gov.cca.CCAException {
    logger.finest("called for portName: " + portName);
   
    // For provides ports
    ProvidesPortInfo pInfo =
      (ProvidesPortInfo) providesPortMap.get(portName);
    if (pInfo != null) {
      synchronized(pInfo) {
  while (pInfo.getInUse()) {
    try {
      logger.finest("wait till the port is released");
      pInfo.wait();
    } catch (InterruptedException ie) {
      logger.severe("Exception while waiting for port to be released", ie);
    }
  }
  if (pInfo.isRemoved())
    throw new PortNotDefinedException("Provides port : " + portName +
              " has been removed");
  pInfo.setInUse(true);
  return pInfo.getProvidesPortReference();
      }
    }

    // For uses ports
    UsesPortInfo uInfo =
      (UsesPortInfo) usesPortMap.get(portName);
    if (uInfo != null) {
      synchronized(uInfo) {
  while (uInfo.getInUse() || uInfo.getInMigration()) {
    try {
      logger.finest("wait till the port is available");
      uInfo.wait();
    } catch (InterruptedException ie) {
      logger.severe("Exception while waiting for port to be released", ie);
    }
  }
  if (uInfo.isUnregistered())
    throw new PortNotDefinedException("Uses port: " + portName +
              " has been unregistered");
  if (uInfo.getConnectionID() == null)
    throw new PortNotConnectedException("Port " + portName
                + " not connected");
  uInfo.setInUse(true);
  return uInfo.getProvidesPortReference();
      }
    }

    logger.severe("Port " + portName + " not defined");
    throw new PortNotDefinedException("Port " + portName + " not defined");
  }

  /**
   * Get a previously registered Port (defined by
   * either addProvide or registerUses) and return that
   * Port if it is available immediately (already connected
   * without further connection machinations).
   * There is an contract that the
   * port will remain valid per the description of getPort.
   * @return The named port, if it exists and is connected or self-provided,
   *         or NULL if it is registered and is not yet connected. Does not
   *         return if the Port is neither registered nor provided, but rather
   *         throws an exception.
   * @param portName registered or provided port that
   *        the component now wants to use.
   * @exception CCAException with the following types: PortNotConnected,
   *                                                   PortNotDefined, OutOfMemory.
   */
  public gov.cca.Port getPortNonblocking(java.lang.String portName)
    throws gov.cca.CCAException {
    logger.finest("called for portName: " + portName);

    // For provides ports
    ProvidesPortInfo pInfo =
      (ProvidesPortInfo) providesPortMap.get(portName);
    if (pInfo != null) {
      synchronized(pInfo) {
  if (pInfo.isRemoved())
    throw new PortNotDefinedException("Provides port : " + portName +
              " has been removed");
  if (pInfo.getInUse()) {
    logger.finest("port is in use");
    return null;
  }
  else {
    pInfo.setInUse(true);
    return pInfo.getProvidesPortReference();
  }
      }
    }

    // For uses ports
    UsesPortInfo uInfo =
      (UsesPortInfo) usesPortMap.get(portName);
    if (uInfo != null) {
      synchronized(uInfo) {
  if (uInfo.isUnregistered())
    throw new PortNotDefinedException("Uses port: " + portName +
              " has been unregistered");
  if (uInfo.getInUse() || uInfo.getInMigration()) {
    logger.finest("port not available");
    return null;
  }
  else if (uInfo.getConnectionID() == null)
    throw new PortNotConnectedException("Port " + portName + " not connected");
  else {
    uInfo.setInUse(true);
    // return the reference to the provides port
    return uInfo.getProvidesPortReference();
  }
      }
    }

    logger.severe("Port " + portName + " not defined");
    throw new PortNotDefinedException("Port " + portName + " not defined");
  }

  /**
   * Notifies the framework that this component is finished
   * using the previously fetched Port that is named.    
   * The releasePort() method calls should be paired with
   * getPort() method calls; however, an extra call to releasePort()
   * for the same name may (is not required to) generate an exception.
   * Calls to release ports which are not defined or have never be fetched
   * with one of the getPort functions generate exceptions.
   * @param portName The name of a port.
   * @exception CCAException with the following types: PortNotDefined, PortNotInUse.
   */
  public void releasePort(java.lang.String portName)
    throws gov.cca.CCAException {
    logger.finest("called for portName: " + portName);

    // For provides ports
    ProvidesPortInfo pInfo =
      (ProvidesPortInfo) providesPortMap.get(portName);
    if (pInfo != null) {
      synchronized(pInfo) {
  if (pInfo.isRemoved())
    throw new PortNotDefinedException("Provides port : " + portName +
              " has been removed");
  if (pInfo.getInUse()) {
    pInfo.setInUse(false);
    logger.finest("wake up sleeper waiting for port to be released");
    pInfo.notify();
    return;
  }
  else
    throw new PortNotInUseException("Port " + portName + " not in use");
      }
    }

    // For uses ports
    UsesPortInfo uInfo =
      (UsesPortInfo) usesPortMap.get(portName);
    if (uInfo != null) {
      synchronized(uInfo) {
  if (uInfo.isUnregistered())
    throw new PortNotDefinedException("Uses port: " + portName +
              " has been unregistered");
  if (uInfo.getInUse()) {
    uInfo.setInUse(false);
    logger.finest("wake up sleeper waiting for port to be released");
    uInfo.notify();
    return;
  }
  else
    throw new PortNotInUseException("Port " + portName + " not in use");
      }
    }

    logger.severe("Port " + portName + " not defined");
    throw new PortNotDefinedException("Port " + portName + " not defined");
  }

  /**
   * Creates a TypeMap, potentially to be used in subsequent
   * calls to describe a Port.  Initially, this map is empty.
   */
  public gov.cca.TypeMap createTypeMap()
    throws gov.cca.CCAException {
    return new xcat.types.TypeMapImpl();
  }

  /**
   * Register a request for a Port that will be retrieved subsequently
   * with a call to getPort().
   * @param portName A string uniquely describing this port.  This string
   * must be unique for this component, over both uses and provides ports.
   * @param type A string describing the type of this port (a namespace in XCAT3)
   * @param properties A TypeMap describing properties associated with this port.
   *
   * Required properties for XCAT3 are:
   *    portClass: Fully qualified class name for the interface defining the port
   * @exception CCAException with the following types: PortAlreadyDefined, OutOfMemory.
   */
  public void registerUsesPort(java.lang.String portName,
             java.lang.String type,
             gov.cca.TypeMap properties)
    throws gov.cca.CCAException {
    logger.finest(" called with parameters: " +
      " portName = " + portName +
      " type = " + type +
      " properties = " + properties);
   
    synchronized(this) {
      if (usesPortMap.containsKey(portName) ||
    (providesPortMap.containsKey(portName)))
  throw new PortAlreadyDefinedException("Port " + portName +
                " already defined");
      else {
  // check if the portClass property is present
  if (properties == null)
    throw new NonstandardException("TypeMap should not be empty: " +
           "need property portClass");
  String intfClassName = properties.getString("portClass",
                "None");
  if (intfClassName.equals("None"))
    throw new NonstandardException("TypeMap should contain property " +
           "portClass");

  // add a couple of standard properties
  properties.putString("cca.portName", portName);
  properties.putString("cca.portType", type);

  // create a new UsesPortInfo object and add it to usesPortMap
  UsesPortInfo uInfo = new UsesPortInfo(portName, type, properties);
  usesPortMap.put(portName, uInfo);
      }
    }
  }

  /**
   * Notify the framework that a Port, previously registered by this
   * component but currently not in use, is no longer desired.
   * Unregistering a port that is currently
   * in use (i.e. an unreleased getPort() being outstanding)
   * is an error.
   * @param portName The name of a registered Port.
   * @exception CCAException with the following types: UsesPortNotReleased, PortNotDefined.
   */
  public void unregisterUsesPort(java.lang.String portName)
    throws gov.cca.CCAException {
    logger.finest("called with portName: " + portName);

    UsesPortInfo uInfo = (UsesPortInfo) usesPortMap.get(portName);
    if (uInfo != null) {
      synchronized(uInfo) {
  if (uInfo.getInUse())
    throw new UsesPortNotReleasedException("Port " + portName + " still in use");
  else {
    uInfo.unregisterPort();
    usesPortMap.remove(portName);
  }
      }
    } else
      throw new PortNotDefinedException("Port " + portName + " not defined");
  }

  /**
   * Exposes a Port from this component to the framework. 
   * This Port is now available for the framework to connect
   * to other components.
   * @param inPort An abstract interface (tagged with CCA-ness
   *   by inheriting from gov.cca.Port) the framework will
   *   make available to other components.
   *
   * @param portName string uniquely describing this port.  This string
   * must be unique for this component, over both uses and provides ports.
   *
   * @param type string describing the type (class) of this port.
   *
   * @param properties A TypeMap describing properties associated with this port.
   *
   * Required properties for XCAT3 are:
   *    portClass: Fully qualified class name for the interface defining the port
   *
   * @exception CCAException with the following types: PortAlreadyDefined, OutOfMemory.
   */
  public void addProvidesPort(gov.cca.Port inPort,
            java.lang.String portName,
            java.lang.String type,
            gov.cca.TypeMap properties)
    throws gov.cca.CCAException {
    logger.finest("called with parameters: " +
      " portName = " + portName +
      " type = " + type +
      " properties = " + properties);

    synchronized(this) {
      if (providesPortMap.containsKey(portName) ||
    (usesPortMap.containsKey(portName)))
  throw new PortAlreadyDefinedException("Port " + portName +
                " already defined");
      else {
  // check if the TypeMap is null
  if (properties == null)
    throw new NonstandardException("TypeMap should not be empty: " +
           "need property portClass");

  // add two special properties to typeMap
  properties.putString("cca.portName", portName);
  properties.putString("cca.portType", type);
 
  // add the classname of the port implementation as a property
  properties.putString("cca.portImpl", inPort.getClass().getName());

  // extract the class for the interface describing the port
  String intfClassName = properties.getString("portClass",
                "None");
  if (intfClassName.equals("None"))
    throw new NonstandardException("TypeMap should contain property " +
           "portClass");

  // export the provides port as a Grid service
  try {
    UnicastRemoteObject.exportObject(inPort,
             new Class[]{Class.forName(intfClassName)});
  } catch (Exception e) {
    logger.severe("Can't export the port as a Grid service", e);
    throw new NonstandardException("Can't export the port as a Grid service", e);
  }
 
  // create an entry for this port in the providesPortMap
  if (!(inPort instanceof XCATPort))
    throw new NonstandardException("Port to be added not an instance of XCATPort");

  // Set the GSH for the provides port
  String providesPortHandle = HandleResolver.createGSH(portName);
  ((XCATPort) inPort).setGSH(providesPortHandle);

  logger.finest("adding port with handle: " + providesPortHandle);
  ProvidesPortInfo pInfo = new ProvidesPortInfo(portName,
                  type,
                  properties,
                  providesPortHandle);
  providesPortMap.put(portName, pInfo);

  // create an entry for this port in the handle resolver
  HandleResolver.addReference(providesPortHandle, (XCATPort) inPort);
      }
    }
  }

  /**
   * Returns the complete list of the properties for a Port.  This
   * includes the properties defined when the port was registered
   * (these properties can be modified by the framework), two special
   * properties "cca.portName" and "cca.portType", and any other
   * properties that the framework wishes to disclose to the component.
   * The framework may also choose to provide only the subset of input
   * properties (i.e. from addProvidesPort/registerUsesPort) that it
   * will honor.     
   */
  public gov.cca.TypeMap getPortProperties(java.lang.String name)
    throws gov.cca.CCAException {
    logger.finest("called for portName: " + name);

    // provides ports
    if (providesPortMap.containsKey(name)) {
      ProvidesPortInfo pInfo = (ProvidesPortInfo) providesPortMap.get(name);
      return pInfo.getProperties();
    }

    // uses ports
    if (usesPortMap.containsKey(name)) {
      UsesPortInfo uInfo = (UsesPortInfo) usesPortMap.get(name);
      return uInfo.getProperties();
    }
   
    // port not found
    throw new PortNotDefinedException("Port " + name + " not defined");
  }

  /**
   * Notifies the framework that a previously exposed Port is no longer
   * available for use. The Port being removed must exist
   * until this call returns, or a CCAException may occur.
   * @param portName The name of a provided Port.
   * @exception PortNotDefined. In general, the framework will not dictate
   * when the component chooses to stop offering services.
   */
  public void removeProvidesPort(java.lang.String portName)
    throws gov.cca.CCAException {
    logger.finest("called for portName: " + portName);

    ProvidesPortInfo pInfo = (ProvidesPortInfo) providesPortMap.get(portName);
    if (pInfo != null) {
      synchronized(pInfo) {
  if (pInfo.getInUse())
    // Can't remove if port is still in use
    throw new NonstandardException("ProvidesPort " + portName + " still in use");
  else if (pInfo.getNumConnections() != 0)
    // Can't remove if port is still connected remotely
    throw new NonstandardException("ProvidesPort " + portName + " still connected");
  else {
    pInfo.removePort();
    // NOTE: SHOULD I SHUTDOWN THE XSOAP SERVICE HERE?
    providesPortMap.remove(portName);
  }
      }
    } else
      throw new PortNotDefinedException("Port " + portName + " not defined");
  }

  /**
   * Get a reference to the component to which this
   * Services object belongs.
   */
  public gov.cca.ComponentID getComponentID() {
    return componentID;
  }

  //------------------------------------------------------//
  // List of methods added by the XCATServices interface  //
  //------------------------------------------------------//

  /**
   * Returns an array of registered provides ports
   */
  public String[] getProvidedPortNames()
    throws gov.cca.CCAException {
    Object[] keyObjArray = providesPortMap.keySet().toArray();
    String[] keyStrArray = new String[keyObjArray.length];
    for (int i = 0; i < keyObjArray.length; i++)
      keyStrArray[i] = (String) keyObjArray[i];
    return keyStrArray;
  }
 
  /**
   * Returns an array of registered uses ports
   */
  public String[] getUsedPortNames()
    throws gov.cca.CCAException {
    Object[] keyObjArray = usesPortMap.keySet().toArray();
    String[] keyStrArray = new String[keyObjArray.length];
    for (int i = 0; i < keyObjArray.length; i++)
      keyStrArray[i] = (String) keyObjArray[i];
    return keyStrArray;
  }

  /**
   * Returns the type of the port specified
   * @param providesPortName the name of the provides port whose type is desired
   */
  public String getProvidesPortType(String providesPortName)
    throws gov.cca.CCAException {
    logger.finest("called for port: " + providesPortName);

    ProvidesPortInfo pInfo = (ProvidesPortInfo) providesPortMap.get(providesPortName);
    if (pInfo != null) {
      synchronized(pInfo) {
  TypeMap pMap = pInfo.getProperties();
  return pMap.getString("cca.portType", "None");
      }
    } else
      throw new PortNotDefinedException("Port " + providesPortName + " not defined");
  }
 
  /**
   * Returns the type of the port specified
   * @param usesPortName the name of the uses port whose type is desired
   */
  public String getUsesPortType(String usesPortName)
    throws gov.cca.CCAException {
    logger.finest("called for port: " + usesPortName);

    UsesPortInfo uInfo = (UsesPortInfo) usesPortMap.get(usesPortName);
    if (uInfo != null) {
      synchronized(uInfo) {
  TypeMap uMap = uInfo.getProperties();
  return uMap.getString("cca.portType", "None");
      }
    } else
      throw new PortNotDefinedException("Port " + usesPortName + " not defined");
  }

  /**
   * Returns the GSH for the specified provides port
   * @param providesPortName the name by which the Provides Port is registered
   */
  public String getPortHandle(String providesPortName)
    throws gov.cca.CCAException {
    logger.finest("called for provides port: " + providesPortName);

    ProvidesPortInfo pInfo =
      (ProvidesPortInfo) providesPortMap.get(providesPortName);
    if (pInfo != null) {
      synchronized(pInfo) {
  if (pInfo.isRemoved())
    throw new PortNotDefinedException("Provides Port : " + providesPortName +
              " has been removed");
  String retVal = pInfo.getProvidesPortHandle();
  return retVal;
      }
    } else
      throw new PortNotDefinedException("Provides Port : " + providesPortName +
          " not defined");
  }

  /**
   * Returns a GSH for the requested portName, and increments the number of users
   * for this port
   * @param providesPortName the name by which the Provides Port is registered
   */
  public String incrementUsers(String providesPortName)
    throws gov.cca.CCAException {
    logger.finest("called for provides port: " + providesPortName);

    ProvidesPortInfo pInfo =
      (ProvidesPortInfo) providesPortMap.get(providesPortName);
    if (pInfo != null) {
      synchronized(pInfo) {
  if (pInfo.isRemoved())
    throw new PortNotDefinedException("Provides Port : " + providesPortName +
              " has been removed");
  String retVal = pInfo.getProvidesPortHandle();
  pInfo.incrNumConnections();
  return retVal;
      }
    } else
      throw new PortNotDefinedException("Provides Port : " + providesPortName +
          " not defined");
  }
 
  /**
   * Sets the Provides Port GSH for a uses port during a connect call
   * @param providerComponentName the instanceName of the component providing the port
   * @param providerComponentHandle the GSH for the providing component
   * @param userComponentName the instanceName of the component using the port
   * @param userComponentHandle the GSH for the using component
   * @param providingPortName the name by which the Provides Port is registered
   * @param usingPortName the name by which the Uses Port is registered
   * @param providesPortHandle GSH for the Provides Port after the connect
   */
  public void addUsesConnection(String providerComponentName,
        String providerComponentHandle,
        String userComponentName,
        String userComponentHandle,
        String providingPortName,
        String usingPortName,
        String providesPortHandle)
    throws gov.cca.CCAException {
    logger.finest("called with parameters: " +
      " provider component = " + providerComponentName +
      " user component = " + userComponentName +
      " provides port name = " + providingPortName +
      " uses port name = " + usingPortName);

    // Create ComponentID objects for the provider and user
    XCATComponentIDClientImpl provider =
      new XCATComponentIDClientImpl(providerComponentName,
            providerComponentHandle);
    XCATComponentIDClientImpl user =
      new XCATComponentIDClientImpl(userComponentName,
            userComponentHandle);

    // Add a ConnectionID object if all checks are successful
    UsesPortInfo uInfo =
      (UsesPortInfo) usesPortMap.get(usingPortName);
    if (uInfo != null) {
      synchronized(uInfo) {
  if (uInfo.isUnregistered())
    throw new PortNotDefinedException("Uses port: " + usingPortName +
              " has been unregistered");
  if (uInfo.getConnectionID() != null)
    throw new NonstandardException("Uses Port : " + usingPortName +
           " is already connected");
  XCATConnectionID connectionID =
    new XCATConnectionIDImpl(provider,
           user,
           providingPortName,
           usingPortName,
           providesPortHandle);
  uInfo.setConnectionID(connectionID);
      }
    } else
      throw new PortNotDefinedException("Uses Port : " + usingPortName +
          " not defined");
  }

  /**
   * Disconnects the uses side from a connection
   * @param usingPortName the name of the uses port which is connected
   */
  public void disconnectProvider(String usingPortName)
    throws gov.cca.CCAException {
    logger.finest("called with uses port: " + usingPortName);

    UsesPortInfo uInfo =
      (UsesPortInfo) usesPortMap.get(usingPortName);
    if (uInfo != null) {
      synchronized(uInfo) {
  if (uInfo.isUnregistered())
    throw new PortNotDefinedException("Uses port: " + usingPortName +
              " has been unregistered");
  if (uInfo.getInUse())
    throw new NonstandardException("Uses Port : " + usingPortName +
           " still in use");
  uInfo.setConnectionID(null);
      }
    } else
      throw new PortNotDefinedException("Uses Port : " + usingPortName +
          " not defined");
  }

  /**
   * Disconnects the provides side from a connection
   * @param providingPortName the name of the provides port which is connected
   */
  public void disconnectUser(String providingPortName)
    throws gov.cca.CCAException {
    logger.finest("called with provides port: " + providingPortName);

    ProvidesPortInfo pInfo =
      (ProvidesPortInfo) providesPortMap.get(providingPortName);
    if (pInfo != null) {
      synchronized(pInfo) {
  if (pInfo.isRemoved())
    throw new PortNotDefinedException("Provides Port : " + providingPortName +
              " has been removed");
  pInfo.decrNumConnections();
      }
    } else
      throw new PortNotDefinedException("Provides Port : " + providingPortName +
          " not defined");
  }

  /**
   * Returns the connection information for this uses port
   * @param usingPortName the name of the uses port which is connected
   */
  public XCATConnectionInfo getConnectionInfo(String usingPortName)
    throws gov.cca.CCAException {
    logger.finest("called with uses port: " + usingPortName);
   
    if (!usesPortMap.containsKey(usingPortName))
      throw new NonstandardException("Uses Port: " + usingPortName +
             " not defined");
    UsesPortInfo uInfo =
      (UsesPortInfo) usesPortMap.get(usingPortName);
    if (uInfo.getConnectionID() == null)
      return null;
    else
      return uInfo.getConnectionID().getConnectionInfo();
  }

  /**
   * Sets the TypeMap properties for the component
   * @param properties the TypeMap properties object for the component
   */
  public void setProperties(gov.cca.TypeMap properties)
    throws gov.cca.CCAException {
    logger.finest("called");
    compProperties = properties;
  }

  /**
   * Gets the TypeMap properties for the component
   */
  public gov.cca.TypeMap getProperties()
    throws gov.cca.CCAException {
    logger.finest("called");
    return compProperties;
  }

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

  /**
   * Register a request for a Port that will be retrieved subsequently
   * with a call to getPort().
   * @param portName A string uniquely describing this port.  This string
   * must be unique for this component, over WS, uses and provides ports.
   * @param type A string desribing the type of this port.
   * @param properties A TypeMap describing properties
   * associated with this port. The property "portClass" which specifies
   * the fully qualified class name of the interface is mandatory
   */
  public void registerWSPort(java.lang.String portName,
           java.lang.String type,
           gov.cca.TypeMap properties)
    throws gov.cca.CCAException {
    logger.finest(" called with parameters: " +
      " portName = " + portName +
      " type = " + type +
      " properties = " + properties);
   
    synchronized(this) {
      if (usesPortMap.containsKey(portName) ||
    (providesPortMap.containsKey(portName)) ||
    (wsPortMap.containsKey(portName)))
  throw new PortAlreadyDefinedException("Port " + portName +
                " already defined");
      else {
  // check if the portClass property is present
  if (properties == null)
    throw new NonstandardException("TypeMap should not be empty: " +
           "need property portClass");
  String intfClassName = properties.getString("portClass",
                "None");
  if (intfClassName.equals("None"))
    throw new NonstandardException("TypeMap should contain property " +
           "portClass");

  // add a couple of standard properties
  properties.putString("cca.portName", portName);
  properties.putString("cca.portType", type);

  // create a new WSPortInfo object and add it to wsPortMap
  WSPortInfo wsInfo = new WSPortInfo(portName, type, properties);
  wsPortMap.put(portName, wsInfo);
      }
    }
  }

  /**
   * Notify the framework that a Port, previously registered by this
   * component but currently not in use, is no longer desired.
   * @param portName The name of a registered Port.
   */
  public void unregisterWSPort(java.lang.String portName)
    throws gov.cca.CCAException {
    logger.finest("called with portName: " + portName);

    WSPortInfo wsInfo = (WSPortInfo) wsPortMap.get(portName);
    if (wsInfo != null) {
      synchronized(wsInfo) {
  if (wsInfo.getInUse())
    throw new UsesPortNotReleasedException("Port " + portName + " still in use");
  else {
    wsInfo.unregisterPort();
    wsPortMap.remove(portName);
  }
      }
    } else
      throw new PortNotDefinedException("Port " + portName + " not defined");
  }

  /**
   * Sets the connection information for a Web service connection
   * @param wsPortName the name that a WS port has been registered as
   * @param endPointLocation the URL for the Web service to connect to
   */
  public void addWSConnection(String wsPortName,
            String endPointLocation)
    throws gov.cca.CCAException {
    logger.finest("called with parameters: " +
      " WS port name: " + wsPortName +
      " endpoint location: " + endPointLocation);

    // Add connection information if all checks are successful
    WSPortInfo wsInfo =
      (WSPortInfo) wsPortMap.get(wsPortName);
    if (wsInfo != null) {
      synchronized(wsInfo) {
  if (wsInfo.isUnregistered())
    throw new PortNotDefinedException("WS port: " + wsPortName +
              " has been unregistered");
  if (wsInfo.isConnected())
    throw new NonstandardException("WS Port : " + wsPortName +
           " is already connected");
  wsInfo.setEndPointLocation(endPointLocation);
      }
    } else
      throw new PortNotDefinedException("WS Port : " + wsPortName +
          " not defined");
  }

  /**
   * Disconnects the Web services connection
   * @param wsPortName the name that a WS port has been registered as
   */
  public void disconnectWS(String wsPortName)
    throws gov.cca.CCAException {
    logger.finest("called with WS port: " + wsPortName);

    WSPortInfo wsInfo =
      (WSPortInfo) wsPortMap.get(wsPortName);
    if (wsInfo != null) {
      synchronized(wsInfo) {
  if (wsInfo.isUnregistered())
    throw new PortNotDefinedException("WS port: " + wsPortName +
              " has been unregistered");
  if (wsInfo.getInUse())
    throw new NonstandardException("WS Port : " + wsPortName +
           " still in use");
  wsInfo.disconnectPort();
      }
    } else
      throw new PortNotDefinedException("WS Port : " + wsPortName +
          " not defined");
  }

  /**
   * Fetch a remote reference for a previously register port (defined by either
   * addProvidesPort or (more typically) registerUsesPort, registerWSPort). 
   * @param portName The previously registered uses/provides/WS port which
   *      the component now wants to use.
   */
  public Remote getRemoteRef(String portName)
    throws gov.cca.CCAException {

    // For WS ports
    WSPortInfo wsInfo =
      (WSPortInfo) wsPortMap.get(portName);
    if (wsInfo != null) {
      synchronized(wsInfo) {
  while (wsInfo.getInUse()) {
    try {
      logger.finest("wait till the port is available");
      wsInfo.wait();
    } catch (InterruptedException ie) {
      logger.severe("Exception while waiting for port to be released", ie);
    }
  }
  if (wsInfo.isUnregistered())
    throw new PortNotDefinedException("WS port: " + portName +
              " has been unregistered");
  if (!wsInfo.isConnected())
    throw new PortNotConnectedException("WS Port " + portName
                + " not connected");
  wsInfo.setInUse(true);
  return wsInfo.getRemoteReference();
      }
    }
 
    // if it is not a WS port, check if it is a regular CCA port
    return getPort(portName);
  }

  /**
   * Release a remote reference being held by a getPort/getRemoteRef invocation
   * @param portName The previously fetched remote reference that needs to be
   *                 released
   */
  public void releaseRemoteRef(String portName)
    throws gov.cca.CCAException {

    // For WS ports
    WSPortInfo wsInfo =
      (WSPortInfo) wsPortMap.get(portName);
    if (wsInfo != null) {
      synchronized(wsInfo) {
  if (wsInfo.isUnregistered())
    throw new PortNotDefinedException("WS port: " + portName +
              " has been unregistered");
  if (wsInfo.getInUse()) {
    wsInfo.setInUse(false);
    logger.finest("wake up sleeper waiting for port to be released");
    wsInfo.notify();
    return;
  }
  else
    throw new PortNotInUseException("WS Port " + portName + " not in use");
      }
    }

    // if it is not a WS port, check to see if it is regular CCA port
    releasePort(portName);
  }
}
TOP

Related Classes of xcat.ccacore.XCATServicesImpl

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.