Package SystemMonitor

Source Code of SystemMonitor.SystemAgent$ListenerInfo

/*
Copyright (c) 2003-2008 ITerative Consulting Pty Ltd. All Rights Reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:

o Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
 
o Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the distribution.
   
o This jcTOOL Helper Class software, whether in binary or source form may not be used within,
or to derive, any other product without the specific prior written permission of the copyright holder

 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


*/
package SystemMonitor;

import java.beans.PropertyChangeSupport;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.management.Attribute;
import javax.management.AttributeChangeNotification;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.DynamicMBean;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.InvalidAttributeValueException;
import javax.management.JMException;
import javax.management.JMRuntimeException;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.Notification;
import javax.management.NotificationEmitter;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.timer.Timer;

import org.apache.log4j.Logger;
import org.springframework.jmx.export.naming.ObjectNamingStrategy;
import org.springframework.jmx.support.JmxUtils;

import DisplayProject.binding.beans.ExtendedPropertyChangeSupport;
import Framework.Array_Of_CommandDesc;
import Framework.Array_Of_Object;
import Framework.Array_Of_TextData;
import Framework.CloneHelper;
import Framework.CommandDesc;
import Framework.CommandProcessor;
import Framework.DataValue;
import Framework.DoubleData;
import Framework.DynamicArray;
import Framework.ErrorMgr;
import Framework.File;
import Framework.FrameworkUtils;
import Framework.IntegerData;
import Framework.Partition;
import Framework.PropertiesMgr;
import Framework.ServiceObjectRegistry;
import Framework.Stream;
import Framework.TextData;
import Framework.UsageException;
/**
* The SystemAgent class is an abstract class that represents an agent that manages an object in a deployed application.
* It is implemented as a Dynamic Management Bean
*
*/
@SuppressWarnings("serial")
public abstract class SystemAgent implements Serializable, DynamicMBean, NotificationEmitter {

    // -----------------
    // Event Definitions
    // -----------------

    public static final String cEVENT_SUB_AGENT_CHANGE = "SubAgentChange";
    public static final String cEVENT_LOG_INSTRUMENTS = "LogInstruments";
    protected static final int initialIID = 100;
    public static final int initialCID = 100;

    // ----------
    // Attributes
    // ----------
    public PropertyChangeSupport qq_Listeners = new ExtendedPropertyChangeSupport(this, true);
    private transient File logFile = null;
    private Object managedObject = null;
    private final Array_Of_Instrument<Instrument> instruments = new Array_Of_Instrument<Instrument>();
    private final Array_Of_AgentInfo<AgentInfo> subAgentInfo = new Array_Of_AgentInfo<AgentInfo>();
    private final AgentInfo agentInfo = new AgentInfo();
    private CommandProcessor commandProcessor = null;
    private SystemAgent parentAgent = null;
    private TextData name = new TextData("");

    private List<MBeanAttributeInfo> attributeInfo = new ArrayList<MBeanAttributeInfo>();
    private List<MBeanOperationInfo> operationInfo = new ArrayList<MBeanOperationInfo>();
    private ObjectName objectName = null;
    private String domainName = null;
   
    // FIX:TF:28 Sep 2009:Made these resources static to prevent looking them up multiple times.
    private static ObjectNamingStrategy strategy;
    private static ActivePartitionAgent activePartitionAgent; //PM:Aug 12, 2008:find it once
    private static EnvironmentAgent environmentAgent; //PM:Aug 12, 2008:find it once
    private static MBeanServer mbServer = null;
   
    private static final boolean useSpringForLookup = false;

    protected ConfigValueInst nameInst = null;
    private int sequenceNumber = 1;
   
    /**
     * this field holds a list of sub agents yet to be registered with the JMX server
     */
    private final List<SystemAgent> unregisteredSubAgents = new ArrayList<SystemAgent>();
    /**
     * This field holds the list of all the sub agents that have been registered with the JMX server
     */
    private final List<SystemAgent> registeredSubAgents = new Array_Of_SystemAgent<SystemAgent>();
    /**
     * This is a list of all the subagents, irrespective of whether they've been registered with the
     * JMX server or not. It should always be the case that values(allSubAgents) = unregisteredSubAgents + registeredSubAgents
     */
    private final Map<String, SystemAgent> allSubAgents = new HashMap<String, SystemAgent>();

    private static final Logger _log = Logger.getLogger(SystemAgent.class);
  /*
   * the last command ID
   */
    private static int lastCID;

    public SystemAgent() {
        String logLocation = PropertiesMgr.getProperty(PropertiesMgr.cLOGS_LOCATION);
        this.logFile = new File();
        this.logFile.setLocalName(logLocation + "/" + this.getClass().getName() + ".log");
        this.logFile.open(Framework.Constants.SP_AM_READ_WRITE);

        this.initCmdProcessor();

        this.agentInfo.setAgent(this);

        int systemID = getLastIID();
       
//        int systemCID = getLastCID();

        this.nameInst = new ConfigValueInst();
        this.nameInst.getName().setValue("Name");
        this.nameInst.updateData(new TextData(this.getClass().getSimpleName()));
        this.nameInst.setIsReadOnly(true);
        this.nameInst.setInstrumentID(systemID + 1);
        this.addInstrument(this.nameInst);
        //PM:19/2/08 removed the set name
//        this.setName(this.getClass().getSimpleName());
        this.processCmdDescriptors();
    }
   
    public SystemAgent(ObjectNamingStrategy strategy){
        this();
        this.setStrategy(strategy);
    }
   
    public SystemAgent(TextData name) {
        this();
        this.setName(name);
    }
   
    public SystemAgent(String name) {
        this();
        this.setNameAsString(name);
    }
   
    private static MBeanServer getMBeanServer() {
      synchronized (SystemAgent.class) {
        if (mbServer == null) {
          mbServer = JmxUtils.locateMBeanServer();;
        }
      }
        return mbServer;
    }

    public static ObjectNamingStrategy getStrategy() {
      if (strategy == null) {
          if (useSpringForLookup) {
            strategy = ServiceObjectRegistry.getService("namingStrategy", ObjectNamingStrategy.class);
          }
          else {
            initialiseLocalManagementBeans();
          }
      }
        return strategy;
    }
   
    public void setStrategy(ObjectNamingStrategy strategy) {
        SystemAgent.strategy = strategy;
    }
    public ObjectName getObjectName() {
        return this.objectName;
    }

    public void setObjectName(ObjectName objectName) {
        this.objectName = objectName;
    }

    /**
     * @return Returns the domainName.
     */
    private String getDomainName() {
      // FIX:TF:28 Sep 2009:Cached the domain name based on the strategy
      if (domainName == null) {
          if (SystemAgent.strategy instanceof SimpleNamingStrategy) {
              setDomainName(((SimpleNamingStrategy)SystemAgent.strategy).getDomainName());
          }
          else if (SystemAgent.strategy instanceof WebsphereNamingStrategy) {
              setDomainName(((WebsphereNamingStrategy)SystemAgent.strategy).getDomainName());
          }
          else {
              setDomainName("jcTOOL");
          }
    }
        return this.domainName;
    }

    /**
     * @param domainName The domainName to set.
     */
    private void setDomainName(String domainName) {
      this.domainName = domainName;
    }

    public void setManagedObject(Object pValue) {
        this.managedObject = pValue;
    }

    public Object getManagedObject() {
        return this.managedObject;
    }

    public void setCommandProcessor(CommandProcessor pValue) {
        this.commandProcessor = pValue;
    }

    public CommandProcessor getCommandProcessor() {
        return this.commandProcessor;
    }

    public void setName(TextData pValue) {
        this.name = pValue;
        //PM:19/2/08 setting the name uses the naming strategy
        try {
            ObjectName objectName  = SystemAgent.getStrategy().getObjectName(this, pValue.toString());
            this.setObjectName(objectName);
        } catch (MalformedObjectNameException e) {
            UsageException errorVar = new UsageException("Cannot set SystemAgent name to: " + pValue, e);
            ErrorMgr.addError(errorVar);
            throw errorVar;
        } catch (NullPointerException e) {
            UsageException errorVar = new UsageException("Cannot set SystemAgent name to: " + pValue, e);
            ErrorMgr.addError(errorVar);
            throw errorVar;
        }

        this.agentInfo.setAgentName(pValue.toString());
        this.nameInst.setIsReadOnly(false);
        this.nameInst.updateData(pValue);
        this.nameInst.setIsReadOnly(true);

    }
    public TextData getName() {
        return this.name;
    }
    //PM:18/07/2008: AXA
    public void setNameAsString(String pValue) {
        this.setName(new TextData(pValue));
    }
    //PM:18/07/2008: AXA
    public String getNameAsString(){
      return this.getName().toString();
    }
    public void setProperties(short pValue) {
        this.agentInfo.setProperties(pValue);
    }

    public short getProperties() {
        return this.agentInfo.getProperties();
    }

    public Array_Of_Instrument<Instrument> getInstrumentation() {
        return this.instruments;
    }

    /**
     * Obtain a list of all the sub-agents of this agent.
     * @return all the subagents of this agent
     */
    public Array_Of_SystemAgent<SystemAgent> getSubAgents() {
      Array_Of_SystemAgent<SystemAgent> list = new Array_Of_SystemAgent<SystemAgent>();
      list.addAll(this.allSubAgents.values());
      return list;
    }

    /**
     * Get the information associated with this agent
     * @return
     */
    public Array_Of_AgentInfo<AgentInfo> getSubAgentInfo() {
        return this.subAgentInfo;
    }

    /**
     * @return Returns the parent agent of this agent.
     */
    public SystemAgent getParentAgent() {
        return this.parentAgent;
    }

    /**
     * @param parentAgent The _ParentAgent to set.
     */
    public void setParentAgent(SystemAgent parentAgent) {
    if (this.parentAgent != null) {
      this.parentAgent.deleteSubAgent(this);
    }
      if (parentAgent != null) {
        parentAgent.addSubAgent(this, this.getInfo());
      }
    }

    /**
     *  checkAndSetState
     * <p>
     * <p>
     * @param state Type: int
     * @return boolean
     */
    public boolean checkAndSetState(int pState){
      // FIX:TF:1 Oct 2009:Fixed this to check the state first, then set it.
      try {
        return this.agentInfo.getState() == pState;
      }
      finally {
        this.agentInfo.setState(pState);
      }
    }

    /**
     *  checkState
     * <p>
     * <p>
     * @param state Type: int
     * @return boolean
     */
    public boolean checkState(int pState) {
        return agentInfo.getState() == pState;
    }

    public void setState(int state) {
        this.checkAndSetState(state);
    }

    public void deleteInstrument(Instrument instrument) {
        Object[] params = new Object[1];
        params[0] = instrument;
        try {
      this.invokeJMXCmd(Constants.SM_CI_DELETE_INSTRUMENT,params);
    } catch (InstanceNotFoundException e) { //PM:16/07/2008:
      //ignore
    }
        this.commonDeleteInstrument(instrument);
    }

    private void commonDeleteInstrument(Instrument instrument) {
        Instrument tmpInstrument;

        for (int i=0; i < this.instruments.size(); i++) {
            tmpInstrument = this.instruments.get(i);
            if (tmpInstrument.getInstrumentID() == instrument.getInstrumentID()) {
                this.instruments.deleteRow(i);
                break;
            }
        }
    }

    private void remoteDeleteInstrument(Instrument instrument) {
        this.commonDeleteInstrument(instrument);
        if (instrument instanceof TimerInst) {
            this.stopAndUnregisterTimer((TimerInst)instrument);
        }
        this.attributeInfo.clear();
        for (Instrument tmpInstrument : this.instruments) {
            this.processInstrument(tmpInstrument);
        }
    }

    /**
     * Remove the passed subAgent from this agent. This will deregister it from the JMX server if appropriate
     * @param subAgent
     */
    public void deleteSubAgent(SystemAgent subAgent) {
      if (subAgent == null) {
        return;
      }
        Object[] params = new Object[1];
        params[0] = subAgent;
        // FIX:TF:1 Oct 2009: If this is a registered sub-agent then try to remove it from the JMX container
        if (this.registeredSubAgents.contains(subAgent)) {
          try {
        this.invokeJMXCmd(Constants.SM_CI_DELETE_SUBAGENT,params);
      } catch (InstanceNotFoundException e) { //PM:16/07/2008:added catch
        // ignore
      }
        }
        // Remove from the registeredAgents, the unregisteredAgents and allAgents
        this.registeredSubAgents.remove(subAgent);
        this.unregisteredSubAgents.remove(subAgent);
        this.allSubAgents.remove(subAgent.getName().toString());
        this.subAgentInfo.remove(subAgent.getInfo());
        this.getInfo().setIsLeafAgent(this.subAgentInfo.size() == 0);
    }

    /**
     * This method is used to remove a subAgent and any of its registered agents and
     * instruments from the JMX server
     * @param subAgent
     */
    private void remoteDeleteSubAgent(SystemAgent subAgent) {
        //
        // There can be a side-effect of deleting a subAgent as
        // a subAgent may have a Timer instrument. The NotificationHandler
        // must be removed and the Timer unregistered, first...
        //
      // FIX:TF:1 Oct 2009:Changed this to pick up the instrumentation of the sub-agent
      // not this, the parent agent.
      for (Instrument tmpInst : subAgent.instruments) {
            if (tmpInst instanceof TimerInst) {
                this.stopAndUnregisterTimer((TimerInst)tmpInst);
            }
        }
        // FIX:TF:1 Oct 2009:In java, if we have any sub-agents, we also need to remove
        // these subagents as they may be registered with the MBean server. Note that we
      // don't remove the sub-sub agents from their parent (our sub-agent) we just
      // deregsiter them.
      SystemAgent[] clonedRegisteredSubAgents = subAgent.registeredSubAgents.toArray(new SystemAgent[0]);
     
        for (SystemAgent subSubAgent : clonedRegisteredSubAgents) {
          remoteDeleteSubAgent(subSubAgent);
          subAgent.registeredSubAgents.remove(subSubAgent);
          subAgent.unregisteredSubAgents.add(subSubAgent);
        }
        // this.commonDeleteSubAgent(subAgent);
        // Now actually unregister this from the JMX server. We don't remove this bean from the registered
        // agents, etc because we assume whoever calls us will do this.
        try {
            unregisterMBean(subAgent.getObjectName());
        } catch (InstanceNotFoundException e) {
            _log.error(e);
        } catch (MBeanRegistrationException e) {
            _log.error(e);
        }
    }
   
    /**
     *  execCmdOnSubAgents
     * <p>
     * <p>
     * @param command Type: TextData
     * @param objList Type: DynamicArray (default in Forte: NIL)
     * @param outStream Type: Stream (default in Forte: NIL)
     *
     */
    public void execCmdOnSubAgents(TextData command) {
        this.execCmdOnSubAgents(TextData.valueOf(command), null, null);
    }

    /**
     *  execCmdOnSubAgents
     * <p>
     * <p>
     * @param command Type: TextData
     * @param objList Type: DynamicArray (default in Forte: NIL)
     * @param outStream Type: Stream (default in Forte: NIL)
     *
     */
    public void execCmdOnSubAgents(TextData command, Stream outStream) {
        this.execCmdOnSubAgents(TextData.valueOf(command), null, outStream);
    }

    /**
     *  execCmdOnSubAgents
     * <p>
     * <p>
     * @param command Type: TextData
     * @param objList Type: DynamicArray (default in Forte: NIL)
     * @param outStream Type: Stream (default in Forte: NIL)
     *
     */
    public void execCmdOnSubAgents(TextData command, Array_Of_Object<Object> objList) {
        this.execCmdOnSubAgents(TextData.valueOf(command), objList, null);
    }

    /**
     *  execCmdOnSubAgents
     * <p>
     * <p>
     * @param command Type: TextData
     * @param objList Type: DynamicArray (default in Forte: NIL)
     * @param outStream Type: Stream (default in Forte: NIL)
     *
     */
    public void execCmdOnSubAgents(TextData command, Array_Of_Object<Object> objList, Stream outStream) {
        this.execCmdOnSubAgents(TextData.valueOf(command), objList, outStream);
    }

    /**
     *  execCmdOnSubAgents
     * <p>
     * <p>
     * @param command Type: String
     *
     */
    public void execCmdOnSubAgents(String command) {
      execCmdOnSubAgents(command, null, null);
    }
   
    /**
     *  execCmdOnSubAgents
     * <p>
     * <p>
     * @param command Type: String
     * @param objList Type: DynamicArray (default in Forte: NIL)
     *
     */
    public void execCmdOnSubAgents(String command, Array_Of_Object<Object> objList) {
      execCmdOnSubAgents(command, objList, null);
    }

    /**
     *  execCmdOnSubAgents
     * <p>
     * <p>
     * @param command Type: String
     * @param outStream Type: Stream (default in Forte: NIL)
     *
     */
    public void execCmdOnSubAgents(String command, Stream outStream) {
      execCmdOnSubAgents(command, null, outStream);
    }
   
    /**
     *  execCmdOnSubAgents
     * <p>
     * <p>
     * @param command Type: String
     * @param objList Type: DynamicArray (default in Forte: NIL)
     * @param outStream Type: Stream (default in Forte: NIL)
     *
     */
    public void execCmdOnSubAgents(String command, Array_Of_Object<Object> objList, Stream outStream)
    {
        objList = CloneHelper.deepClone(objList);

        for (SystemAgent tmpSubAgent : this.getSubAgents() ) {
            tmpSubAgent.executeCommand(command, objList, outStream);
        }
    }
   
    public Object executeCommand(TextData command) {
        return this.executeCommand(command.toString(), null, null);
    }

    public Object executeCommand(String command) {
        return this.executeCommand(command, null, null);

    }
    /**
     *  executeCommand
     * <p>
     * <p>
     * @param command Type: TextData
     * @param objList Type: DynamicArray (default in Forte: NIL)
     * @param outStream Type: Stream (default in Forte: NIL)
     * @return Object
     */
    public Object executeCommand(TextData command, DynamicArray<Object> objList, Stream outStream) {
        return this.executeCommand(command.toString(), objList, outStream);
    }

    /**
     *  executeCommand
     * <p>
     * <p>
     * @param command Type: String
     * @param objList Type: DynamicArray (default in Forte: NIL)
     * @param outStream Type: Stream (default in Forte: NIL)
     * @return Object
     */
    public Object executeCommand(String command, List<Object> objList, Stream outStream)
    {
        Object result = null;
        Array_Of_CommandDesc<CommandDesc> descs = this.getCommands();
        for (CommandDesc tmpDesc : descs) {
            if (tmpDesc.getMenuString().equalsIgnoreCase(command)) {  //PM:6 Nov 2008:changed to use the menu string
                result = this.processCmdRequest(tmpDesc.getCmdIndex(), (Array_Of_Object<Object>)objList, outStream);
                break;
            }
        }
        if (result == null) {
          result = "Success";
        }
        return result;
    }
   

    /**
     *  addSubAgent
     * <p>
     * <p>
     * @param subAgent Type: SystemAgent
     * @param subAgentInfo Type: AgentInfo
     *
     */
    public synchronized void addSubAgent(SystemAgent subAgent, AgentInfo subAgentInfo){
      if (subAgent.getParentAgent() == this) {
        // Null operation, do nothing.
        return;
      }
    // FIX:TF:1 Oct 2009:If the subagent is already parented, remove the subagent from
    // its parent first, then add it here.
      if (subAgent.getParentAgent() != null) {
        subAgent.getParentAgent().deleteSubAgent(subAgent);
      }
     
        subAgent.parentAgent = this;
        subAgent.agentInfo.setParentName(this.getName().toString());

        Object[] params = new Object[2];
        params[0] = subAgent;
        params[1] = subAgentInfo;
        try {
      this.invokeJMXCmd(Constants.SM_CI_ADD_SUB_AGENT,params);
      this.registeredSubAgents.add(subAgent);
        } catch (javax.management.RuntimeOperationsException e){
      /* PM:16/07/2008:
       * if we are here, the child agent is being added to a parent agent
       * and the parent has not yet been added to the JMX server
       */
          this.unregisteredSubAgents.add(subAgent);
    } catch (InstanceNotFoundException e) {
      /* PM:16/07/2008:
       * if we are here, the child agent is being added to a parent agent
       * and the parent has not yet been added to the JMX server
       */
      this.unregisteredSubAgents.add(subAgent);
    }
    this.allSubAgents.put(subAgent.getName().toString(), subAgent);
        this.subAgentInfo.add(subAgentInfo);
        //
        // By adding this sub-agent, this agent is no longer a "leaf" node
        // so change the default value from SM_AGENTPROP_ISLEAF.
        // This probably has no meaning in the JMX sense but is
        // supported just in case UDS client code uses it...
        //
        this.agentInfo.setIsLeafAgent(false);
    }


    /**
     * Add this sub-agent to the JMX agent. If there are any unregistered sub agents, we will also
     * register them here. This method will affect the registeredSubAgents and unregisteredSubAgents
     * fields on its parent agent.
     * @param subAgent
     * @param subAgentInfo
     */
    private void remoteAddSubAgent(SystemAgent subAgent, AgentInfo subAgentInfo){
        try {
          // FIX:TF:28 Sep 2009:Used the lookup method instead
          ObjectNamingStrategy strat = SystemAgent.getStrategy();
          // FIX:TF:1 Oct 2009:Changed the first parameter to be the passed subAgent, as this is now used in the naming strategy
            ObjectName objectName  = strat.getObjectName(subAgent, subAgent.getName().toString());
            //ObjectName objectName = new ObjectName(this.getDomainName()+":Name="+subAgent.getName());
            subAgent.setObjectName(objectName);
            subAgent.setDomainName(this.getDomainName() + "." + subAgent.getName());
            registerMBean(subAgent, objectName);
           
            // Iterate through our unregistered sub agents and try to add them too.
          SystemAgent[] clonedRegisteredSubAgents = subAgent.unregisteredSubAgents.toArray(new SystemAgent[0]);
         
            for (SystemAgent subSubAgent : clonedRegisteredSubAgents) {
              try {
                remoteAddSubAgent(subSubAgent, subSubAgent.getInfo());
                subAgent.unregisteredSubAgents.remove(subSubAgent);
                subAgent.registeredSubAgents.add(subSubAgent);
              }
              catch (Exception e) {
                _log.error("Could not register agent "+ subSubAgent.getNameAsString());
              }
            }
        } catch (Exception e) {
            RuntimeException errorVar = new RuntimeException(e.getMessage());
            ErrorMgr.addError(errorVar);
            throw errorVar;
        }
    }

    /**
     *  addInstrument
     * <p>
     * <p>
     * @param inst Type: Instrument
     *
     */
    public void addInstrument(Instrument instrument) {
        this.instruments.add(instrument);

        this.processInstrument(instrument);
        //PM:7 Nov 2008:removed this because the instrument id was wrong
//        setLastIID(instrument.getInstrumentID() - initialIID);
       
    }

    protected void processInstrument(Instrument instrument) {
      boolean isWritable = false;
      String typeName = null;

      //PM:16/07/2008:
      instrument.setOwnerInfo(this.getInfo());

      if (instrument instanceof ConfigValueInst) {
        if (((ConfigValueInst)instrument).getData() == null ) {
          // Need to know its type in order to property register it as an attribute of the MBean
          // FIX:TF:30 Sep 2009:Forte did not update the instruments at this point in time, so some
          // of them may not be set up properly. Hence we shouldn't do this (they can null pointer
          // for example)
          //this.updateInstrument(instrument);
        }
        // TF:6/6/07: if updateData() has not been called on the instrument, we won't know it's type
        // so we are going to have to assume string
        DataValue value = ((ConfigValueInst)instrument).getData();
        if (value != null) {
          String frameworkName = value.getClass().getName();
          if (frameworkName.equalsIgnoreCase("Framework.IntegerData")) {
            typeName = "java.lang.Integer";
          }
          else if (frameworkName.equalsIgnoreCase("Framework.DoubleData")) {
            typeName = "java.lang.Double";
          }
          else if (frameworkName.equalsIgnoreCase("Framework.TextData")) {
            typeName = "java.lang.String";
          }
          else if (frameworkName.equalsIgnoreCase("Framework.DateTimeData")) {
            typeName = "java.lang.String";
          }
        }
        else {
          typeName = "java.lang.String";
        }
        isWritable = !((ConfigValueInst)instrument).isReadOnly();
      }
      else if (instrument instanceof CounterInst) {
        typeName = "java.lang.Integer";
      }
      else if (instrument instanceof AverageInst) {
        typeName = "java.lang.Double";
      }
      else if (instrument instanceof TimerInst) {
        typeName = "java.lang.Integer";
        ((TimerInst)instrument).setOwningSystemAgent(this);
      }
      else if (instrument instanceof SubObjectInst) {
        //            typeName = "com.kwe.ufs.systemmonitor.Array_Of_Instrument";
        typeName = "java.lang.String";
      }
      else if (instrument instanceof CompoundInst){
        for (Instrument kid : ((CompoundInst)instrument).getSubInstruments()){
          processInstrument(kid);
        }
      } else {
        // Transform the Instrument into something that JMX understands
        MBeanAttributeInfo info = new MBeanAttributeInfo(
            instrument.getName().toString(),
            typeName,
            "This is the Instrument " + instrument.getName().toString() + ". It is a " + instrument.getClass().getName(),
            true,  // Is Readable
            isWritable,
            false)// Is a boolean. For UDS cases this will always be false.
        this.attributeInfo.add(info);
      }

      //PM:19/09/2008: add a command for updateable instruments
      if (isWritable){
        addCommandForAttribute(instrument);
      }
    }

    public void processTimer(TimerInst timerInst) {
        Timer theTimer = new Timer();
        try {
            ObjectName timerName = new ObjectName(Constants.SM_BASE_DOMAIN + "." + Partition.getAppTitle()+ ".Timers:" +
                    "Timer=" + timerInst.getOwningSystemAgent().getName() + "." + timerInst.getName());
            registerMBean(theTimer, timerName);
            theTimer.start();
            theTimer.addNotification(timerInst.getName().toString(),"message","data",new Date(),timerInst.getTickInterval());
            getMBeanServer().addNotificationListener(timerName, timerInst, null, null);
        } catch (Exception e) {
            _log.error(e);
        }
    }

    private void stopAndUnregisterTimer(TimerInst timerInst) {
        try {
            ObjectName timerName = new ObjectName(Constants.SM_BASE_DOMAIN + "." + Partition.getAppTitle()+ ".Timers:" +
                    "Timer=" + timerInst.getOwningSystemAgent().getName() + "." + timerInst.getName());
            getMBeanServer().removeNotificationListener(timerName, timerInst);
            unregisterMBean(timerName);
        } catch (Exception e) {
            _log.error(e);
        }
    }

    /**
     *  findInstrument
     * <p>
     * <p>
     * @param instId Type: int
     * @return Instrument
     */
    public Instrument findInstrument(int instId)
    {
        Instrument inst = null;
      if (this.instruments != null){
        for (Instrument tmpInst : this.instruments) {
          if (tmpInst.getInstrumentID() == instId) {
            inst = tmpInst;
            this.updateInstrument(inst);
            break;
          }
        }
      }
        return inst;
    }

    /**
     *  findInstrument
     * <p>
     * <p>
     * @param name Type: String
     * @return Instrument
     */
    public Instrument findInstrument(String name){
        Instrument inst = null;
        if (this.instruments != null) {
          for (Instrument tmpInst : this.instruments) {
              if (tmpInst.getName().toString().equalsIgnoreCase(name)) {
                  inst = tmpInst;
                  this.updateInstrument(inst);
                  break;
              }
          }
        }
        return inst;
    };

    /**
     *  findInstrument
     * <p>
     * <p>
     * @param name Type: TextData
     * @return Instrument
     */
    public Instrument findInstrument(TextData name){
        return this.findInstrument(name.toString());
    };

    /**
     *  findSubAgent
     * <p>
     * <p>
     * @param name Type: TextData
     * @return SystemAgent
     */
    public SystemAgent findSubAgent(TextData name){
        return this.findSubAgent(name.toString());
    };

    /**
     *  findSubAgent
     * <p>
     * <p>
     * @param name Type: String
     * @return SystemAgent
     */
    public SystemAgent findSubAgent(String name){
      return this.allSubAgents.get(name);      //PM:Aug 12, 2008: changed to use the named list
    }

    /**
     *  findSubAgentInfo
     * <p>
     * <p>
     * @param name Type: TextData
     * @return AgentInfo
     */
    public AgentInfo findSubAgentInfo(TextData name){
        return this.findSubAgentInfo(name.toString());
    }

    /**
     *  findSubAgentInfo
     * <p>
     * <p>
     * @param name Type: String
     * @return AgentInfo
     */
    public AgentInfo findSubAgentInfo(String name){
      SystemAgent agent = findSubAgent(name);
      if (agent == null) {
        return null;
      }
      else {
        return agent.getInfo();
      }
    }

    /**
     *  getCommands
     * <p>
     * <p>
     * @return Array_Of_CommandDesc
     */
    public Array_Of_CommandDesc<CommandDesc> getCommands(){
        return this.getCommandProcessor().getCommandList();
    }

    /**
     *  getInfo
     * <p>
     * <p>
     * @return AgentInfo
     */
    public AgentInfo getInfo(){
        return this.agentInfo;
    }

    /**
     *  getLogFile
     * <p>
     * <p>
     * @return File
     */
    public File getLogFile(){
        return this.logFile;
    }

    /**
     *  getMO
     * <p>
     * <p>
     * @return Object
     */
    public Object getMO(){
        return this.managedObject;
    }

    /**
     *  listInstruments
     * <p>
     * <p>
     * @return Array_Of_TextData
     */
    public Array_Of_TextData<TextData> listInstruments(){
        Array_Of_TextData<TextData> instruments = new Array_Of_TextData<TextData>();
        for (Instrument tmpInstrument : this.instruments) {
            instruments.add(new TextData(tmpInstrument.getName()));
        }
        return instruments;
    }

    /**
     *  setMOType
     * <p>
     * <p>
     * @param moType Type: Class
     *
     */
    public void setMOType(Class<?> moType) {
        //this.moType = MOType;
        this.agentInfo.setMOTypeName(moType.getName());
    }

    /**
     *  setParentAgent
     * <p>
     * <p>
     * @param parentAgent Type: SystemAgent
     * @param name Type: TextData
     *
     */
    public void setParentAgent(SystemAgent parentAgent, TextData name){
        this.setParentAgent(parentAgent/*, name.toString()*/);
    }

    /**
     *  setParentAgent
     * <p>
     * <p>
     * @param parentAgent Type: SystemAgent
     * @param name Type: String
     *
     */
    public void setParentAgent(SystemAgent parentAgent, String name){
//    Object[] params = new Object[2];
//    params[0] = parentAgent;
//    params[1] = name;
//    this.invokeJMXCmd(Constants.SM_CI_SET_PARENT_AGENT,params);
//        this._ParentName = new TextData(name);
//        this.agentInfo.setParentName(parentAgent.getName().toString());
//        this.parentAgent = parentAgent;
//        //
//        // By adding this sub-agent, this agent is no longer a "leaf" node
//        // so change the default value from SM_AGENTPROP_ISLEAF.
//        // This probably has no meaning in the JMX sense but is
//        // supported just in case UDS client code uses it...
//        //
//        this.parentAgent.agentInfo.setIsLeafAgent(false);
//        if (parentAgent == null && this.parentAgent != null) {
//          this.parentAgent.deleteSubAgent(this);
//        }
      setParentAgent(parentAgent);
    }

    /**
     *  setParentAgent
     * <p>
     * <p>
     * @param parentAgent Type: SystemAgent
     * @param name Type: String
     *
     */
    public void remoteSetParentAgent(SystemAgent parentAgent, String name){
//        this._ParentName = new TextData(name);
//        this.agentInfo.setParentName(parentAgent.getName().toString());
//        this._ParentAgent = parentAgent;
      // FIX:TF:30 Sep 2009:Changed this to use the method above
      setParentAgent(parentAgent, name);
    }


    //
    // Methods that should be overridden by the extending class
    //

    public String getMOTypeName() {
        return this.agentInfo.getMOTypeName();
    }

    public void initCmdProcessor() {
      if (this.commandProcessor == null) {
        this.commandProcessor = new CommandProcessor();
      }
    }

    public Object processCmdRequest(short cmdIndex, Array_Of_Object<Object> parameters, Stream outStream) {
        return new Object();
    }

    public void attachMO(Object managedObject) {
        this.setManagedObject(managedObject);
    }

    public void instrumentUpdated(Instrument inst) {
    }

    public void updateInstrument(Instrument inst) {
            String name = inst.getName().toString();
            Notification n = new AttributeChangeNotification(this,
                    sequenceNumber ++,
                    System.currentTimeMillis(),
                    name + " updated",
                    name,
                    inst.getTypeString(),
                    null,
                    inst.getInstrumentValue());
            sendNotification(n);
    }

    //
    // Other interesting common methods
    //

    protected transient String changePrefix = "";

    public String getChangePrefix() {
        return changePrefix;
    }
    public void setChangePrefix(String pChangePrefix) {
        this.changePrefix = pChangePrefix;
    }

    //
    //Common JMX Methods
    //

    private Object invokeJMXCmd(int commandIndex, Object[] pParams) throws InstanceNotFoundException{//PM:16/07/2008: added throws clause
        Object result = null;
        List<Object> execList = new ArrayList<Object>();
        execList.add(new Integer(commandIndex));
        if (pParams != null) {
            for (int i=0, size=pParams.length; i<size; i++) {
                execList.add(pParams[i]);
            }
        }
        Object[] params = (Object[])execList.toArray(new Object[0]);
        try {
          MBeanServer server = getMBeanServer();
          result = server.invoke(this.objectName, "invoker", params, new String[0]);
//        } catch (InstanceNotFoundException e) {
//          RuntimeException errorVar = new RuntimeException(e.getMessage(), e);
//          ErrorMgr.addError(errorVar);
//          throw errorVar;

        } catch (MBeanException e) {
          RuntimeException errorVar = new RuntimeException(e.getMessage(), e);
          ErrorMgr.addError(errorVar);
          throw errorVar;
        } catch (ReflectionException e) {
          RuntimeException errorVar = new RuntimeException(e.getMessage(), e);
          ErrorMgr.addError(errorVar);
          throw errorVar;
        }
        return result;
    }

    /**
     * The description of the bean as shown in the java console. This method will provide a default implementation, however
     * it should be overridden by subclasses for more detailed information.
     * @return the description of this bean
     */
    public String getDescription() {
      return "A " + this.getClass().getName();
    }
   
    public MBeanInfo getMBeanInfo() {
        MBeanAttributeInfo[] attrInfoArray = (MBeanAttributeInfo[])attributeInfo.toArray(new MBeanAttributeInfo[0]);
        MBeanOperationInfo[] opInfoArray = (MBeanOperationInfo[])operationInfo.toArray(new MBeanOperationInfo[0]);
        MBeanInfo beanInfo = new MBeanInfo(this.getClass().getName(),
                                    getDescription(),
                                    attrInfoArray,
                                    new MBeanConstructorInfo[0],
                                    opInfoArray,
                                    new MBeanNotificationInfo[0]);
        return beanInfo;
    }

    public Object getAttribute(String name) throws AttributeNotFoundException, MBeanException, ReflectionException {
        Instrument instrument = this.findInstrument(name);
        Object result = null;
        if (instrument instanceof ConfigValueInst) {
            DataValue value = ((ConfigValueInst)instrument).getData();
            result = value.toString();
        }
        if (instrument instanceof CounterInst) {
            result = ((CounterInst)instrument).getIntegerValue();
        }
        if (instrument instanceof AverageInst) {
            result = ((AverageInst)instrument).getDoubleValue();
        }
        if (instrument instanceof TimerInst) {
            result = ((TimerInst)instrument).getIntegerValue();
        }
        if (instrument instanceof SubObjectInst) {
            _log.debug("Found a SubObjectInst...");
            result = ((SubObjectInst)instrument).toString();
        }
        return result;
    }

    public void setAttribute (Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
        Instrument instrument = this.findInstrument(attribute.getName());
        if (instrument instanceof ConfigValueInst) {
            DataValue theAttribute = null;
            if (attribute.getValue() instanceof java.lang.Integer) {
                theAttribute = new IntegerData((Integer)attribute.getValue());
            }
            if (attribute.getValue() instanceof java.lang.Double) {
                theAttribute = new DoubleData((Double)attribute.getValue());
            }
            if (attribute.getValue() instanceof java.lang.String) {
                theAttribute = new TextData((String)attribute.getValue());
            }
            ((ConfigValueInst)instrument).updateData(theAttribute);
        }
        if (instrument instanceof CounterInst) {
            ((CounterInst)instrument).setIntegerValue((Integer)attribute.getValue());
        }
        if (instrument instanceof AverageInst) {
            ((AverageInst)instrument).setDoubleValue((Double)attribute.getValue());
        }
        if (instrument instanceof TimerInst) {
            ((TimerInst)instrument).setIntegerValue((Integer)attribute.getValue());
        }

        this.instrumentUpdated(instrument);

        // since the instrument reference is all in process, it
        // is un-necessary to put it back into the Instruments collection.
    }

    public AttributeList getAttributes(String[] attributeNames) {
        AttributeList atts = new AttributeList();
        for (String name : attributeNames) {
            try {
                Attribute att = new Attribute(name, getAttribute(name));
                atts.add(att);
            } catch (AttributeNotFoundException e) {
                _log.error(e);
            } catch (MBeanException e) {
                _log.error(e);
            } catch (ReflectionException e) {
                _log.error(e);
            }
        }
        return atts;
    }

    public AttributeList setAttributes(AttributeList attributes) {
        return null;
    }

    private void processCmdDescriptors() {
        Array_Of_CommandDesc<CommandDesc> descs = this.commandProcessor.getCommandList();
        Iterator<CommandDesc> itr = descs.iterator();
        while (itr.hasNext()) {
            processOneCommandDescriptor(itr.next()); //PM:19/09/2008:move to a method
        }
    }
    private void processOneCommandDescriptor(CommandDesc command){
      MBeanOperationInfo optInfo = null;
      // TF:1/4/08:Made this handle return codes (just |d at the moment) and cater for null arguments lists
      String argDesc = command.getArgDesc();
      if (argDesc.endsWith("|d")) {
        argDesc = argDesc.substring(0, argDesc.length() - 2);
      }
      String[] argDescs;
      if (!"".equals(argDesc)) {
        argDescs = argDesc.split(",");
      }
      else {
        argDescs = new String[0];
      }

      String[] argNames = null;
      String argNameString = command.getArgNames();
      if (argNameString != null) {
        argNames =argNameString.split(",");
      }
      else {
        argNames = new String[0];
      }

      if (argDescs.length == 0) {
        optInfo = new MBeanOperationInfo(command.getMenuString(), //PM:Aug 21, 2008:changed to menu string
            command.getHelpText(),
            new MBeanParameterInfo[0],
            "Object",
            MBeanOperationInfo.ACTION);
      } else {
        ArrayList<MBeanParameterInfo> paramInfo = new ArrayList<MBeanParameterInfo>();

        for (int i = 0; i < argDescs.length; i++){
          String type = "";
          if (argDescs.length > i) {
            switch (argDescs[i].charAt(0)) {
            case 'S':
            case 's':
              type = "java.lang.String";
              break;

            case 'B':
            case 'b':
              type = "boolean";
              break;

            case 'F':
            case 'f':
              type = "float";
              break;

            default:
              type = "int";
            break;
            }
          }
          String name = "";
          if (argNames.length > i) {
            name = argNames[i];
          }
          MBeanParameterInfo mbean = new MBeanParameterInfo(name,
              type,
              name);
          paramInfo.add(mbean);
        }
        MBeanParameterInfo[] paramInfoArray = (MBeanParameterInfo[])paramInfo.toArray(new MBeanParameterInfo[0]);
        optInfo = new MBeanOperationInfo(command.getMenuString(),
            command.getHelpText(),
            paramInfoArray,
            "Object",
            MBeanOperationInfo.ACTION);
      }
      this.operationInfo.add(optInfo);
    }
    //PM:19/09/2008:
    private void removeOneCommandDescriptor(CommandDesc command){

      Iterator<MBeanOperationInfo> it = this.operationInfo.iterator();
      while (it.hasNext()){
        MBeanOperationInfo op = it.next();
        if (op.getName().equals(command.getMenuString())){
          it.remove();
          break;
        }
      }
    }

    public Object invoke(String operationName, Object params[], String signature[]) throws MBeanException, ReflectionException {
        Object result = null;
        if (operationName.equalsIgnoreCase("invoker")) {
            result = this.executeSystemAgentCmd(params);
            return result;
        }

        // TF:1/4/08:Corrected these to map java types to forte types, and then back again on the result
        Array_Of_Object<Object> parameters = new Array_Of_Object<Object>();
        for (Object thisParam : params) {
          parameters.add(FrameworkUtils.mapToDataValue(thisParam));
        }
        result = this.executeCommand(operationName, parameters, this.getLogFile());

        return FrameworkUtils.mapToJavaPrimitiveType(result);
    }

    private Object executeSystemAgentCmd(Object... params) {
        Object result = null;
        Integer operationName = (Integer)params[0];
        switch (operationName.intValue()) {
        case Constants.SM_CI_RETURN_SELF : {
            result = this;
            break;
        }
        case Constants.SM_CI_SET_MANAGED_OBJECT :  {
            this.setManagedObject(params[1]);
            break;
        }

        case Constants.SM_CI_SET_COMMAND_PROCESSOR : {
            this.setCommandProcessor((CommandProcessor)params[1]);
            break;
        }
        case Constants.SM_CI_SET_PROPERTIES : {
            this.setProperties(((Integer)params[1]).shortValue());
            break;
        }

        case Constants.SM_CI_ADD_SUB_AGENT :  {
            this.remoteAddSubAgent((SystemAgent)params[1], (AgentInfo)params[2]);
            break;
        }
        case Constants.SM_CI_ATTACH_MO : {
            this.attachMO(params[1]);
            break;
        }
//      case Constants.SM_CI_CHECK_AND_SET_STATE : {
//        result = new Boolean(this.remoteCheckAndSetState(((Integer)params[1]).intValue()));
//        break;
//      }
        case Constants.SM_CI_DELETE_INSTRUMENT : {
            this.remoteDeleteInstrument((Instrument)params[1]);
            break;
        }
        case Constants.SM_CI_DELETE_SUBAGENT : {
            this.remoteDeleteSubAgent((SystemAgent)params[1]);
            break;
        }
        case Constants.SM_CI_SET_MO_TYPE : {
            this.setMOType((Class<?>)params[1]);
            break;
        }
        case Constants.SM_CI_SET_PARENT_AGENT : {
            this.remoteSetParentAgent((SystemAgent)params[1], (String)params[2]);
            break;
        }
//      case Constants.SM_CI_ADD_INSTRUMENT : {
//        this.remoteAddInstrument((Instrument)params[1]);
//      }
        }

        return result;
    }
    public int getState(){
        return Constants.SM_ONLINE;
    }
    public String toString(){
        return this.getClass().getName() + "[" + this.getName() + "]";
    }
    public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws IllegalArgumentException {
        synchronized (lock) {
            List<ListenerInfo> newList = new ArrayList<ListenerInfo>(listenerList.size() + 1);
            newList.addAll(listenerList);
            newList.add(new ListenerInfo(listener, filter, handback));
            listenerList = newList;
        }   
    }
    public MBeanNotificationInfo[] getNotificationInfo() {
        String[] types = new String[] {
            AttributeChangeNotification.ATTRIBUTE_CHANGE
        };
        String name = AttributeChangeNotification.class.getName();
        String description = "An attribute of this MBean has changed";
        MBeanNotificationInfo info =
            new MBeanNotificationInfo(types, name, description);
        return new MBeanNotificationInfo[] {info};

    }
    public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException {

        synchronized (lock) {
            List<ListenerInfo> newList = new ArrayList<ListenerInfo>(listenerList);
            final int size = newList.size();
            for (int i = 0; i < size; i++) {
                ListenerInfo li = (ListenerInfo) newList.get(i);

                if (li.listener == listener) {
                    newList.remove(i);
                    listenerList = newList;
                    return;
                }
            }
        }

        ListenerNotFoundException errorVar = new ListenerNotFoundException("Listener not registered");
        ErrorMgr.addError(errorVar);
        throw errorVar;
    }
    public void removeNotificationListener(NotificationListener listener,
            NotificationFilter filter, Object handback)
            throws ListenerNotFoundException {
        this.removeNotificationListener(listener);

    }
    public void sendNotification(Notification notification) {

        if (notification == null) {
            return;
        }

        List<ListenerInfo> currentList;
        synchronized (lock) {
            currentList = listenerList;
        }

        final int size = currentList.size();
        for (int i = 0; i < size; i++) {
            ListenerInfo li = (ListenerInfo) currentList.get(i);

            if (li.filter == null
                    || li.filter.isNotificationEnabled(notification)) {
                try {
                    this.handleNotification(li.listener, notification,
                            li.handback);
                } catch (Exception e) {
                    Logger.getLogger(SystemAgent.class).error("sendNotification exception from listener: " + e);
                }
            }
        }
    }
    protected void handleNotification(NotificationListener listener,
            Notification notif, Object handback) {
        listener.handleNotification(notif, handback);
    }

    private final Object lock = new Object();
    private List<ListenerInfo> listenerList = Collections.emptyList();
    private class ListenerInfo {
        public NotificationListener listener;
        NotificationFilter filter;
        Object handback;

        public ListenerInfo(NotificationListener listener,
                NotificationFilter filter,
                Object handback) {
            this.listener = listener;
            this.filter = filter;
            this.handback = handback;
        }
    }

    public abstract int getLastIID();
   
    public abstract void setLastIID(int id);
   
    public static int getLastCID(){
      return lastCID;
    }
   
    public static void setLastCID(int id){
      lastCID = id;
    }
    //PM:04/09/2008:Adding modifiable config instruments as operations
    protected void addCommandForAttribute(Instrument inst){
      if (inst instanceof ConfigValueInst){
        CommandDesc desc = new CommandDesc();
            desc.setCmdName("set" + inst.Name.asString());
            desc.setArgDesc("s");
            desc.setCmdIndex((short) (getLastCID() + 1000 + inst.getInstrumentID()));
            desc.setHelpText("set the value of " + inst.Name.asString());
            desc.setCmdFlags((short)1);
            desc.setArgNames("set " + inst.getName());
            desc.setGroupName("");
            desc.setMenuString("Utility");
        processOneCommandDescriptor(desc);
      }
    }
    protected void removeCommandForAttribute(Instrument inst){
      if (inst instanceof ConfigValueInst){
        CommandDesc desc = new CommandDesc();
            desc.setCmdName("set" + inst.Name.asString());
            desc.setArgDesc("s");
            desc.setCmdIndex((short) (getLastCID() + 1000 + inst.getInstrumentID()));
            desc.setHelpText("set the value of " + inst.Name.asString());
            desc.setCmdFlags((short)1);
            desc.setArgNames("set " + inst.getName());
            desc.setGroupName("");
            desc.setMenuString("Utility");
        removeOneCommandDescriptor(desc);
      }
    }
   
    /*
     * TF:26/9/09:Moved all the static system management information into this class to attempt to get some
     * separation between the packages, most notably remove the reliance on SystemMonitor by the Framework
     */
    public static ActivePartitionAgent getActPartAgent() {

        if (activePartitionAgent == null) { //PM:Aug 12, 2008:load it once
          if (useSpringForLookup) {
            try {
              // TF:26/09/2009:Try to create the beans normally, and if we fail then try to create them locally
              activePartitionAgent = (ActivePartitionAgent)ServiceObjectRegistry.getService("ActivePartitionAgent", ActivePartitionAgent.class);
            }
            catch (Exception e) {
              _log.error("Could not create environment agent via normal means. Trying to create it locally...", e);
              initialiseLocalManagementBeans();
            }
          }
          else {
            initialiseLocalManagementBeans();
          }
        }
        return activePartitionAgent;
    }

    public static EnvironmentAgent getEnvironmentMgr() {
        if (environmentAgent == null){
          if (useSpringForLookup) {
            try {
              // TF:26/09/2009:Try to create the beans normally, and if we fail then try to create them locally
              environmentAgent = (EnvironmentAgent)ServiceObjectRegistry.getService("EnvironmentAgent", EnvironmentAgent.class);
            }
            catch (Exception e) {
              _log.error("Could not create environment agent via normal means. Trying to create it locally...", e);
              initialiseLocalManagementBeans();
            }
          }
          else {
            initialiseLocalManagementBeans();
          }
        }
        return environmentAgent;
    }

    /**
     * This is the "management beans of last resort" initialiser. We anticipate that the beans will be instantiated via Spring, however
     * for whatever reason it appears that this has not happened. Try to create them locally and log a message.
     */
    private synchronized static void initialiseLocalManagementBeans() {
      if (environmentAgent == null) {
        SimpleNamingStrategy namingStrategy = new SimpleNamingStrategy();
        SystemAgent.strategy = namingStrategy;
        namingStrategy.setDomainName("jcTOOL");
        EnvironmentAgent envAgent = new EnvironmentAgent(namingStrategy);
        NodeAgent nodeAgent = new NodeAgent(namingStrategy);
        ActivePartitionAgent partAgent = new ActivePartitionAgent(namingStrategy);
        TransactionMgrAgent txnAgent = new TransactionMgrAgent(namingStrategy);
        TaskMgrAgent taskAgent = new TaskMgrAgent(namingStrategy);
        try {
          registerMBean(envAgent, namingStrategy.getObjectName(envAgent, "EnvironmentAgent"));
          registerMBean(nodeAgent, namingStrategy.getObjectName(nodeAgent, "NodeAgent"));
          registerMBean(partAgent, partAgent.getObjectName());
          registerMBean(txnAgent, namingStrategy.getObjectName(txnAgent, "TransactionAgent"));
          registerMBean(taskAgent, namingStrategy.getObjectName(taskAgent, "TaskAgent"));
          environmentAgent = envAgent;
          activePartitionAgent = partAgent;
      }
      catch (RuntimeException e) {
        _log.error("Could not create management beans locally. The error returned was: " + e.getMessage(), e);
        throw e;
      } catch (JMException e) {
        _log.error("Could not create management beans locally. The error returned was: " + e.getMessage(), e);
        // Helpfully, there is no JMRuntimeException(String, Throwable) constructor that is visible. So we won't call
        // it for the moment. We could do it via introspection, but this is nasty and a poor way of overcoming a JMX limitation
        JMRuntimeException ex = new JMRuntimeException("Error creating management beans locally");
        ex.setStackTrace(e.getStackTrace());
        throw ex;
      }
      }
    }
   
    private static void registerMBean(Object object, ObjectName name) throws MBeanRegistrationException, NotCompliantMBeanException, InstanceNotFoundException, InstanceAlreadyExistsException {
      // FIX:TF:29 Sep 2009:If we have a bean registered with the same name, we need to remove this bean
      // and then register our current bean. We cannot leave the original bean there, because it may have
      // been loaded by a different class loader (eg during app server startup) and this will result in
      // strange class-cast exceptions where things cannot be cast to SystemAgents even though they are
      // subclasses of system agents.
      MBeanServer mbs = getMBeanServer();
      if (mbs.isRegistered(name)) {
        mbs.unregisterMBean(name);
      }
      mbs.registerMBean(object, name);
//      if (!mbs.isRegistered(name)) {
//        try {
//        mbs.registerMBean(object, name);
//      } catch (InstanceAlreadyExistsException e) {
//        // We should never get here, the !isRegistered should prevent it
//      }
//      }
    }
   
    private static void unregisterMBean(ObjectName name) throws InstanceNotFoundException, MBeanRegistrationException {
      MBeanServer mbs = getMBeanServer();
      mbs.unregisterMBean(name);     
    }
   
  public static void shutdownSystemAgents(){
        String appTitle = Partition.getAppTitle().toString();
        String companyName = PropertiesMgr.getProperty(PropertiesMgr.cCOMPANY_NAME,"ITC");
        try {
            unregisterMBean(new ObjectName(companyName + Constants.SM_BASE_DOMAIN+":Partition="+appTitle));
            unregisterMBean(new ObjectName(companyName + "Agents.NodeAgent:Node=" + FrameworkUtils.getNodeName()+"Agent"));
            unregisterMBean(new ObjectName(companyName + Constants.SM_BASE_ENVIRONMENT+":Environment=" + companyName + "Environment"));
        } catch (Exception e) {
            _log.debug(e);
        }
    }

    /**
     * This method recursively cleans up sub agent connections to the MBean server. It is called automatically as the destroy
     * method on the Spring bean
     */
    public void unregisterSubAgents(){
        // get a copy of the list first, as the remoteDeleteSubAgent method will delete agents from the original list, confusing the iterator
      List<SystemAgent> systemAgents = CloneHelper.shallowClone(this.registeredSubAgents);
        for(SystemAgent agent : systemAgents){
            agent.unregisterSubAgents();
            remoteDeleteSubAgent(agent);
        }
    }
}
TOP

Related Classes of SystemMonitor.SystemAgent$ListenerInfo

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.