Package com.sun.enterprise.ee.nodeagent

Source Code of com.sun.enterprise.ee.nodeagent.NodeAgent

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.enterprise.ee.nodeagent;

import com.sun.enterprise.ee.admin.servermgmt.InstanceDirs;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.logging.Handler;
import java.util.Vector;
import java.util.Set;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.io.IOException;
import java.io.File;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.RMIClientSocketFactory;
import java.security.cert.CertificateNotYetValidException;

import javax.management.MBeanException;
import javax.management.remote.JMXServiceURL;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.MBeanServerFactory;
import javax.management.AttributeList;
import javax.management.remote.JMXAuthenticator;
import javax.management.remote.JMXConnectorServer;

import com.sun.appserv.management.client.RedirectException;
import com.sun.appserv.management.client.AdminRMISSLClientSocketFactory;
import com.sun.enterprise.admin.jmx.remote.server.rmi.JmxConnectorServerDriver;
import com.sun.enterprise.admin.jmx.remote.server.rmi.RemoteJmxProtocol;
import com.sun.enterprise.admin.server.core.jmx.auth.ASJMXAuthenticator;
import com.sun.enterprise.admin.server.core.jmx.auth.ASLoginDriverImpl;
import com.sun.enterprise.admin.pluggable.ClientPluggableFeatureFactory;
import com.sun.enterprise.admin.pluggable.ClientPluggableFeatureFactoryImpl;
import com.sun.enterprise.admin.common.Status;
import com.sun.enterprise.admin.server.core.jmx.ssl.AdminSslServerSocketFactory;
import com.sun.enterprise.admin.server.core.jmx.nonssl.RMIMultiHomedServerSocketFactory;
import com.sun.enterprise.admin.servermgmt.InstanceException;
import com.sun.enterprise.admin.servermgmt.RuntimeStatus;
import com.sun.enterprise.admin.servermgmt.RuntimeStatusList;
import com.sun.enterprise.admin.servermgmt.RepositoryException;
import com.sun.enterprise.admin.util.IAdminConstants;
import com.sun.enterprise.admin.servermgmt.pe.PEFileLayout;
import com.sun.enterprise.admin.util.JMXConnectorConfig;
import com.sun.enterprise.admin.jmx.remote.https.NoCertCheckX509TrustManager;
import com.sun.enterprise.admin.server.core.jmx.ssl.NodeAgentSyncWithDAS_TlsClientEnvSetter;
import com.sun.enterprise.admin.jmx.remote.DefaultConfiguration;
import com.sun.enterprise.config.serverbeans.ConfigAPIHelper;
import com.sun.enterprise.config.ConfigContext;
import com.sun.enterprise.config.ConfigException;
import com.sun.enterprise.config.serverbeans.Domain;
import com.sun.enterprise.config.serverbeans.Cluster;
import com.sun.enterprise.config.serverbeans.ClusterHelper;
import com.sun.enterprise.config.serverbeans.AuthRealm;
import com.sun.enterprise.config.serverbeans.AdminService;
import com.sun.enterprise.config.serverbeans.Server;
import com.sun.enterprise.config.serverbeans.ServerHelper;
import com.sun.enterprise.config.serverbeans.LogService;
import com.sun.enterprise.config.serverbeans.NodeAgentHelper;
import com.sun.enterprise.config.serverbeans.JmxConnector;
import com.sun.enterprise.config.serverbeans.ElementProperty;
import com.sun.enterprise.config.ConfigFactory;
import com.sun.enterprise.config.serverbeans.Config;
import com.sun.enterprise.ee.admin.concurrent.Task;
import com.sun.enterprise.ee.admin.concurrent.Executor;   
import com.sun.enterprise.ee.admin.configbeans.PortConflictCheckerConfigBean;
import com.sun.enterprise.ee.admin.configbeans.NodeAgentsConfigBean;
import com.sun.enterprise.ee.admin.servermgmt.*;
import com.sun.enterprise.ee.admin.servermgmt.InstanceConfig;
import com.sun.enterprise.ee.admin.servermgmt.EEInstancesManager;
import com.sun.enterprise.ee.admin.servermgmt.DASPropertyReader;
import com.sun.enterprise.ee.admin.servermgmt.NodeAgentPropertyReader;
import com.sun.enterprise.ee.admin.servermgmt.AgentException;
import com.sun.enterprise.ee.admin.servermgmt.AgentManager;
import com.sun.enterprise.ee.admin.servermgmt.EEScriptsTokens;
import com.sun.enterprise.ee.synchronization.DASCommunicationException;
import com.sun.enterprise.ee.synchronization.NonMatchingDASContactedException;
import com.sun.enterprise.ee.synchronization.SynchronizationDriver;
import com.sun.enterprise.ee.synchronization.SynchronizationDriverFactory;
import com.sun.enterprise.ee.synchronization.http.HttpUtils;
import com.sun.enterprise.ee.admin.clientreg.MBeanServerConnectionInfo;
import com.sun.enterprise.ee.admin.clientreg.InstanceRegistry;
import com.sun.enterprise.naming.SerialInitContextFactory;
import com.sun.enterprise.server.logging.LogMBean;
import com.sun.enterprise.server.logging.SystemOutandErrHandler;
import com.sun.enterprise.security.store.IdentityManager;
import com.sun.enterprise.security.SecurityUtil;
import com.sun.enterprise.security.RealmConfig;
import com.sun.enterprise.util.i18n.StringManager;
import com.sun.enterprise.util.i18n.StringManagerBase;
import com.sun.enterprise.util.io.StreamFlusher;
import com.sun.enterprise.util.SystemPropertyConstants;

import static com.sun.enterprise.util.SystemPropertyConstants.AGENT_CERT_NICKNAME;
import static com.sun.enterprise.util.SystemPropertyConstants.AGENT_ROOT_PROPERTY;
import static com.sun.enterprise.util.SystemPropertyConstants.AGENT_NAME_PROPERTY;
import static com.sun.enterprise.util.SystemPropertyConstants.CLUSTER_NAME;
import static com.sun.enterprise.util.SystemPropertyConstants.CONFIG_ROOT_PROPERTY;
import static com.sun.enterprise.util.SystemPropertyConstants.INSTANCE_ROOT_PROPERTY;
import static com.sun.enterprise.util.SystemPropertyConstants.INSTALL_ROOT_PROPERTY;
import static com.sun.enterprise.util.SystemPropertyConstants.JAVA_ROOT_PROPERTY;
import static com.sun.enterprise.util.SystemPropertyConstants.JKS_KEYSTORE;
import static com.sun.enterprise.util.SystemPropertyConstants.JKS_TRUSTSTORE;
import static com.sun.enterprise.util.SystemPropertyConstants.KEYSTORE_PROPERTY;
import static com.sun.enterprise.util.SystemPropertyConstants.NSS_ROOT_PROPERTY;
import static com.sun.enterprise.util.SystemPropertyConstants.NSS_DB_PROPERTY;
import static com.sun.enterprise.util.SystemPropertyConstants.NSS_DB_PASSWORD_PROPERTY;
import static com.sun.enterprise.util.SystemPropertyConstants.SERVER_NAME;
import static com.sun.enterprise.util.SystemPropertyConstants.TRUSTSTORE_PROPERTY;
import com.sun.enterprise.admin.servermgmt.launch.ASLauncher;

/**
* This class is run as part of a standalone application that is instantiated by
* NodeAgentMain. Its primary purpose is to keep the instances that belong to
* the NodeAgent, and the NodeAgent itself, in-sync with the Domain Admin Server
* (DAS). The NodeAgent also facilites creating, deleting and the starting of
* instances that belongs to it. The NodeAgent uses JMX Connectors for
* communication to and from the DAS and uses the internal RMI Admin Channel to
* check the state of the instances' that currently exist.
*/
public class NodeAgent extends BaseNodeAgent implements
    NodeAgentMBean, IAdminConstants {

    private static final Object synchronizationLock = new Object();
   
    private static final String
        DOMAIN_XML_DOMAIN_NAME_PROPERTY_NAME = "administrative.domain.name";
               
    protected static final String
        MBEAN_SERVER_DOMAIN = "com.sun.appserver.nodeagent";      
       
    private AgentConfig _agentConfig;     
  
    public static Properties env;
       
    public NodeAgent() throws Exception {       
        this(new DASPropertyReader(new AgentConfig()),
             new NodeAgentPropertyReader(new AgentConfig()), new AgentConfig());
    }

    public NodeAgent(AgentConfig agentConfig) throws Exception {
        this(new DASPropertyReader(agentConfig),
             new NodeAgentPropertyReader(agentConfig), agentConfig);
        // now reset InstanceDirs properly.
        // Note this is a create-node-agent call.  We are running in DAS, not NA
        InstanceDirs.initialize(agentConfig);
    }         

    public NodeAgent(
        DASPropertyReader dasReader, NodeAgentPropertyReader naReader)
    throws Exception {
        this(dasReader, naReader, new AgentConfig());
    }
   
    /**
     * @param dasReader Reads from das.properties
     * @param naReader  Reads from nodeagent.properties
     * @throws Exception 
     */
    public NodeAgent(DASPropertyReader dasReader,
        NodeAgentPropertyReader naReader, AgentConfig agentConfig)
    throws Exception {
        // we are running inside NA, not DAS, so use the System Properties
        InstanceDirs.initialize( System.getProperty(INSTANCE_ROOT_PROPERTY));
        setDASPropertyReader(dasReader);
        setNodeAgentPropertyReader(naReader);
        _agentConfig = agentConfig;
       
        // read in domain.xml from the nodeagent config directory
        String domainXMLLocation = System.getProperty(INSTANCE_ROOT_PROPERTY)
                                 + RELATIVE_LOCATION_DOMAIN_XML;
        setConfigContext(ConfigFactory.createConfigContext(domainXMLLocation));
    }

    // ********************************************************************
    // ********************* NodeAgentMBean interface *********************
    // ********************************************************************      
       
    /**
     * This method is used to remotely start an instance
     *
     * @param instanceName      instance to start
     * @throws AgentException   Exception thrown if anything goes wrong
     *                          with starting the instance
     */   
    public void startInstance(String instanceName) throws AgentException {
  
        // call startInstance with sync option
        startInstance(instanceName, true);

    }
   
    /**
     * This method is used to remotely start an instance
     *
     * @param instanceName      instance to start
     * @param env               environment keys to be used while starting instance
     * @throws AgentException   Exception thrown if anything goes wrong
     *                          with starting the instance
     */   
    public void startInstance(String instanceName, Properties env) throws AgentException {
  
        // call startInstance with sync option
        ASLauncher.setEnvironment(env);
        startInstance(instanceName, true);

    }
    /**
     * This method is used to remotly stop an instance
     *
     * @param instanceName    instance to stop
     * @throws AgentException Exception thrown if anything goes wrong with
     *                        stopping the instance
     */   
    public void stopInstance(String instanceName) throws AgentException {
        getLogger().log(Level.INFO, "nodeagent.stoppingInstance", instanceName);                       
            stopInstance(instanceName, false, -1);   
    }

    /**
     * This method is used to remotly stop an instance forcible
     *
     * @param instanceName    instance to stop
     * @param timeout         timeout before process killed forcibly
     * @throws AgentException Exception thrown if anything goes wrong with
     *                        stopping the instance
     */   
    public void stopInstance(String instanceName, int timeout)
    throws AgentException {
        stopInstance(instanceName, true, timeout);
    }

    /**
     * This method is used to remotly stop an instance forcibly
     *
     * @param instanceName    instance to stop
     * @param force           flag for force kill or normal kill
     * @param timeout         timeout before process killed forcibly
     * @throws AgentException Exception thrown if anything goes wrong with
     *                        stopping the instance
     */   
    private void stopInstance(String instanceName, boolean force, int timeout)
    throws AgentException {
        getLogger().log(Level.INFO, "nodeagent.stoppingInstance", instanceName);                       
       
        // make sure instance exists to start it
        if (!instanceExists(instanceName)) {
            // instance doesn't exist, this could be caused by a sync error
            // with the nodeagent so it doesn't know to create the instance
            // and then someone tries to start or stop it
            throw new AgentException(_strMgr.getString(
                "nodeAgent.instanceDoesNotExist", instanceName));
        }

        checkOnInstanceIsStarted(instanceName);
       
        try {          
            //beginning instance stopping
            InstanceStatus.getInstance().updateStatus(
                instanceName, Status.kInstanceStoppingCode);
            // stop instance and remove it from the ProcessManager
            if (!ProcessManager.getInstance().processExists(instanceName)){
                // create the process so it can be stopped this solves the
                // case of an instance being started outside the NA, like call
                // startserv script directly or NA reconvery from failure.
                // watchdogging can not be done, because associated process
                // can not be recaptured
                ProcessManager.getInstance().addProcessInstance(instanceName,
                                    new ProcessInstanceInternal(instanceName));
            }

            if (!force)  {
                ProcessManager.getInstance().stopProcess(instanceName);       
            } else {
                ProcessManager.getInstance().stopProcess(instanceName, timeout);
            }
            ProcessManager.getInstance().removeProcessInstance(instanceName);
            //instance successfully stopped
            InstanceStatus.getInstance().updateStatusFromAdminChannel(
                instanceName, Status.kInstanceNotRunningCode);
        } catch (Exception e) {
            //stop failed. We mark the instance running so that the user can
            //attempt to issue the stop a second time..
            InstanceStatus.getInstance().updateStatusFromAdminChannel(
                instanceName, Status.kInstanceRunningCode);
            ProcessInstance pInstance =
                ProcessManager.getInstance().getProcess(instanceName);
            if (pInstance !=null) pInstance.setStopping(false);
            StringManagerBase sm = StringManagerBase.getStringManager(
                                   getLogger().getResourceBundleName())
            getLogger().log(Level.WARNING, sm.getString(
                "nodeagent.stop.instance.exception", instanceName), e);            
            throw new AgentException(e);
        }   
    }
  
    /**
     * Notifies this NodeAgent that a sync of domain.xml is required. 
     * It also initiates a reconcilation with the configuration for the node
     * described in domain.xml and the current node's configuration. This method
     * is usually call via a notification from the DAS, but it also can be
     * called by a third party.
     *
     * @throws AgentException Exception thrown if anything goes wrong with sync
     *                        and reconciliation
     */   
    public void synchronizeWithDAS() throws AgentException {
        // this methos returns the created instances which is
        // not needed as part of the exposed api
        synchronizeWithDASInternal(
            SynchronizationDriverFactory.NODE_AGENT_CONFIG_URL);
    }
   
    public void clearRuntimeStatus() {
        RuntimeStatus.clearRuntimeStatus();
    }
           
    public RuntimeStatus getRuntimeStatus() throws AgentException {       
        try {           
            final AgentManager manager = new AgentManager(getNodeAgentConfig());
            return RuntimeStatus.getRuntimeStatus(getNodeAgentName(),
                manager);
        } catch (Exception ex) {
            StringManagerBase sm = StringManagerBase.getStringManager(
                getLogger().getResourceBundleName())
            getLogger().log(Level.INFO, sm.getString(
                "nodeagent.getStatus.exception", getNodeAgentName()), ex);            
            throw new AgentException(ex);
        }
    }           

    public void rotateLog() {
        LogMBean.getInstance().rotateNow();
        getLogger().log(Level.INFO, "nodeagent.rotateLog");                       
    }
   
    public String getLogFilesDirectory(String componentName)
    throws AgentException {
        String logDir="";
        try {
            logDir=getLogFileForConponent(componentName, null);
            // remove default log file from path
            logDir=logDir.substring(0, logDir.lastIndexOf("/"));
            getLogger().log(Level.FINE, "Log directory of component " +
                                        componentName + " - " + logDir);
        } catch (Exception e) {
            throw new AgentException(e);
        }
        return logDir;
    }
   
    public AttributeList getLogRecordsUsingQuery(String componentName,
        String logFile, Long fromRecord, Boolean next, Boolean forward,
        Integer requestedCount, Date fromDate, Date toDate, String logLevel,
        Boolean onlyLevel, List listOfModules, Properties nameValueMap)
    throws AgentException {
        try {
            logFile=getLogFileForConponent(componentName, logFile);
            getLogger().log(Level.FINE, "Querying logfile  - " + logFile);

            return LogMBean.getInstance().getLogRecordsUsingQuery(logFile,
                    fromRecord, next, forward, requestedCount, fromDate, toDate,
                    logLevel, onlyLevel, listOfModules, nameValueMap);
        } catch (Exception e) {
            throw new AgentException(e);
        }
    }
   
    public void dasHasMoved(String newHost, String newPort)
    throws AgentException, MBeanException {
        try {
            if (haveDASCoordinatesChanged(newHost, newPort) == false)
                return;
            StringManagerBase sm = StringManagerBase.getStringManager(
                                        getLogger().getResourceBundleName());             
            _logger.log(Level.INFO, "nodeagent.das_has_moved.info",
                        new Object[] {newHost, newPort});
            writeToDASPropertyReader(newHost, newPort);
            setJMXConnectorInfo(newHost, newPort);
            cleanCachedConnectionToDAS();
        } catch (IOException ex) {
            throw new AgentException(ex);
        } catch (ConfigException ex) {
            throw new AgentException(ex);
        } catch (InstanceException ex) {
            throw new AgentException(ex);
        }
    }
   
    private void writeToDASPropertyReader(String newHost, String newPort)
    throws IOException {
        // get appropriate das properties
        DASPropertyReader dasProperty = getDASPropertyReader();
        // something changed for the das connection, update das properties
        dasProperty.setPort(newPort);
        dasProperty.setHost(newHost);
        // logmessage so the user will know to change say /etc/hosts file
        // so it becomes pingable.
        dasProperty.write();

        getLogger().log(Level.CONFIG, "nodeagent.changeOfDASValues",
                        new Object[] {newHost + ":" + newPort, newHost} );   
    }

    private void setJMXConnectorInfo(String newHost, String newPort
    throws ConfigException {    
        AdminService as = ServerHelper.getAdminServiceForServer(
                            getConfigContext(), "server");
        JmxConnector jmxConn = as.getJmxConnectorByName(
                                as.getSystemJmxConnectorName());
        jmxConn.setPort(newPort);

        ElementProperty clientHostname =
            jmxConn.getElementPropertyByName(HOST_PROPERTY_NAME);
        clientHostname.setValue(HOST_PROPERTY_NAME, newHost);

        getConfigContext().flush(true);
      
    }
   
    private void cleanCachedConnectionToDAS()
    throws ConfigException, InstanceException {
   
        Server das = ServerHelper.getDAS(getConfigContext());
        InstanceRegistry.removeInstanceConnection(das.getName());
        try {
            InstanceRegistry.getDASConnection(getConfigContext());
        } catch (InstanceException ex) {
            // nothing more can be done, next attempt to connect to DAS
            // hopefully works     
        }
    }
   
    private AgentConfig getNodeAgentConfig() {
        return _agentConfig;
    }

    private void checkOnInstanceIsStarted(String instanceName)
    throws AgentException {
        // The instance must be stoppped before we proceed. This check is here
        // to prevent the same server being started multiple times.  We must
        // synchronize on status to guard agains the case when the same instance
        // is stopped at exactly the same time (and they both attempt to update
        // the status).
       
        // WBN June 12, 2007
        // this method also ensures that we can never stop an instance
        // that is stuck in the starting state (Zombie).
        // Instead we just go ahead and stop it anyways.
        // Change -- do not throw an Exception if it is not "running"

        boolean wasRunning = InstanceStatus.getInstance().updateStatusIfRunning(
                                instanceName, Status.kInstanceStoppingCode);
        if (!wasRunning) {
            StringManagerBase sm = StringManagerBase.getStringManager(
                getLogger().getResourceBundleName());
            String msg = sm.getString(
                "nodeagent.couldNotStopInstance", instanceName,
                InstanceStatus.getInstance().getStatus(
                    instanceName).getStatus().getStatusString());
            getLogger().log(Level.WARNING, msg);                                      
            //throw new AgentException(msg);
        }     
    }

    public String getNodeAgentName() {
        return getNodeAgentConfig().getRepositoryName();
    }
   
    // ********************* NodeAgent supporting methods******************

    protected String getLogFileForConponent(String componentName, String logFile)
    throws Exception {
        // see if nodeagent or server that nodeagent manages.
        if (componentName == null ||
            componentName.equals(getNodeAgentConfig().getRepositoryName())) {
            // nodeagent log, should be able to fall through and the
            // LogMBean work correctly
        } else {
            // make sure instance exists
            if (!instanceExists(componentName)) {
                // instance doesn't exist, this could be caused by a sync error
                // with the nodeagent so it doesn't know to create the instance
                // and then someone tries to start or stop it
                throw new AgentException(_strMgr.getString(
                    "nodeAgent.instanceDoesNotExist", componentName));
            }
            // create log prefix
            String logFileX = "";
            String logPrefix = getNodeAgentConfig().getRepositoryRoot() + "/" +
                               getNodeAgentConfig().getRepositoryName() + "/" +
                               componentName + "/" ;
            boolean bFound = false;
            Config config = ServerHelper.getConfigForServer(
                    getConfigContext(), componentName);
            if (config != null) {
                LogService logservice=config.getLogService();
                if (logservice != null) {
                    logFileX = logservice.getFile();
                    if (logFileX != null && !logFileX.equals("")) {
                        // set that is was found
                        bFound=true;
                        // see if log file set on the way in
                        if (logFile == null) {
                            // no log file set, use log-service default
                            logFile=logFileX;
                        } else {
                            // log file specified, remove last file, so can
                            // concatinate logFile that is passed in
                            logFile = logFileX.substring(0,
                                    logFileX.lastIndexOf("/") + 1) + logFile;
                        }

                        // see if instanceroot used in logfile location
                        // (currently it is)
                        String instanceRoot =
                            System.getProperty(INSTANCE_ROOT_PROPERTY);
                        int iPos = logFile.indexOf(instanceRoot);
                        if (iPos == 0) {
                            // remove instance root and build location of log
                            logFile = logPrefix + logFile.substring(
                                                     instanceRoot.length() + 1);
                        }
                    }
                }
            }
            // see if have found a logfile
            if (!bFound) {
                // no log set in domain.xml, but must set a fully qualified
                // path to instance use defaults
                if (logFile == null) {
                    // use all defaults
                    logFile= logPrefix + "logs/server.log";
                } else {
                    // specific log file set
                    logFile= logPrefix + "logs/" + logFile;
                }
            }
        }
        return logFile;
    }

    /**
     * This method is called to notify NodeAgent that a sync of domain.xml is
     * required. It also initiates a reconcilation with the configuration for
     * the node described in domain.xml and the current node's configuration.
     * This method is usually call via a notification from the DAS, but it
     * also can be called by a third party.
     *
     * @throws AgentException Exception thrown if anything goes wrong with
     *                        sync and reconciliation
     */   
    protected Vector synchronizeWithDASInternal() throws AgentException {       
        return synchronizeWithDASInternal(
                SynchronizationDriverFactory.NODE_AGENT_STARTUP_CONFIG_URL);
    }
   
    private Vector synchronizeWithDASInternal(String url) throws AgentException {
        getLogger().log(Level.INFO, "nodeagent.ExecutingSync");
        final DASPropertyReader dasEnv = getDASPropertyReader();
       
        // We want to control initialization ourselves. The issue is that we do
        // not want initialization (i.e.loading of NSS) to happen implicitly
        // here or we will not able to synchronize the NSS database on Windows
        // platforms since it will be in use. For this reason, we do not want
        // orb initialization in our InitialContextFactory to occur.
        SerialInitContextFactory.setInitializeOrbManager(false);
       
        // Setup as an SSL client
        if (Boolean.valueOf(dasEnv.isDASSecure()).booleanValue()) {
            String certNickname = "s1as";
            /*try {
                if (getConfigContext() != null)
                    certNickname = ServerHelper.getCertNickname(
                        getConfigContext(), DAS_SERVER_NAME);

            } catch(Exception ex) {
                getLogger().log(
                    Level.WARNING, "nodeagent.synchronization.Exception",ex);
                throw new AgentException(ex);
            }*/
            new NodeAgentSyncWithDAS_TlsClientEnvSetter(certNickname).setup();
        }
        Vector createdInstances=null;
        // check to see if bound, check here because this method is in
        // mbean interface
        if (getNodeAgentPropertyReader().isBound()) {
            // Synchronise with DAS, which will put domain.xml in
            // config directory
            long startSync=System.currentTimeMillis();
            try {
                try {
                    SynchronizationDriver sd = SynchronizationDriverFactory.
                        getSynchronizationDriver(
                            System.getProperty(INSTANCE_ROOT_PROPERTY),
                        url, null);
                    sd.synchronize();
    } catch(final DASCommunicationException de) {
                    new CommunicationExceptionLogUtils(getLogger(),
                      Level.SEVERE, dasEnv).handleDASCommunicationException(de);
                } catch (NonMatchingDASContactedException ex) {
                    stopAgentWithPause();
                } catch (Exception se) {
                    // An exception is now thrown when the das can't be reached
                    // this is an acceptable case for the nodeagent, so just
                    // log at fine level
                    getLogger().log(Level.FINE,"Synchronization Exception", se);                   
                }

                // check to make sure there is a domain.xml to use, this could
                // happen as a result of a rendezvous with the das during create
                // time and a sync never being successfully completed. Like if
                // the nodeagent is initially started when the das is down
                File domain_xml_file = new File(
                                    System.getProperty(INSTANCE_ROOT_PROPERTY) +
                                    RELATIVE_LOCATION_DOMAIN_XML);
                if (!domain_xml_file.exists()) {
                    // domain.xml doesn't exists, can't continue
                    getLogger().log(Level.SEVERE, "nodeagent.initialSyncFailed");
                    stopAgentWithPause();
                }

                // Now validate the admin-password against admin-keyfile which
                // might be in synch.
                if (domain_xml_file.exists()) {
                    try {
                        validateAdminUserAndPassword();
                    } catch (final Exception ae) {
                        this.stopAgentWithPause();
                    }
                }
                // Resync our config context in case domain.xml
                // has changed on disk.
                ConfigContext configContext = getConfigContext();
                if (configContext.isFileChangedExternally()) {
                    configContext.refresh();
                }

                String instanceRoot =
                    (String) System.getProperty(INSTANCE_ROOT_PROPERTY);
                System.setProperty( KEYSTORE_PROPERTY,
                                    instanceRoot + JKS_KEYSTORE);
                System.setProperty( TRUSTSTORE_PROPERTY,
                                    instanceRoot + JKS_TRUSTSTORE);

                // check to see if the nodeagent still exists
                if(getNodeAgentConfigBean(getConfigContext()) == null) {
                    // nodeagent has been removed
                    getLogger().log(Level.WARNING, "nodeagent.hasBeenDeleted");   
                    // finished synchonizing now reconcile configuration
                    // and remove instances
                    reconcileNodeConfiguration();
                    // clear das.properties
                    getDASPropertyReader().clearProperties();
                    getDASPropertyReader().write();
                    // set nodeAgent to deleted, as per spec it will never be
                    // able to start again
                    setNodeAgentBindStatus(AgentConfig.NODEAGENT_DELETED_STATUS);
                    // remove local domain.xml and .domain.xml.timestamp
                    // files that are used in sync
                    File file = null;
                    for (int ii = 0; ii < LOCAL_DAS_SYNC_FILES.length; ii++) {
                        file = new File(System.getProperty(INSTANCE_ROOT_PROPERTY)
                                      + LOCAL_DAS_SYNC_FILES[ii]);
                        file.delete();
                    }
                    // stop nodeagent after delete
                    System.exit(0);                   
                else {
                    // check to see if config for communication with DAS
                    // has changes
                    updateDASConnectionInfo();                   
                    // reinitialize NodeAgent with updated domain.xml
                    init();
                    // finished synchonizing now reconcile configuration
                    createdInstances=reconcileNodeConfiguration();                   
                }
               
            } catch (Exception e) {
                getLogger().log(Level.WARNING,
                                "nodeagent.synchronization.Exception",e);
                throw new AgentException(e);
            }       
        } else {
            // not bound
            getLogger().log(Level.FINE,
                            "Error on Synchronization, NodeAgent is not bound");
            throw new AgentException(
                    _strMgr.getString("nodeAgent.unboundSyncError"));
        }          
        return createdInstances;
    }           
   

    private void ensureInstanceIsStopped(
        String instanceName, boolean synchronizeInstance)
    throws AgentException {
        // The instance must be stoppped before we proceed. This check is here
        // to prevent the same server being started multiple times. We must
        // synchronize on status to guard agains the case when the same instance
        // is started at exactly the same time (and they both attempt to update
        // the status).
        int newStatus = Status.kInstanceStartingCode;
        if (synchronizeInstance)  {
            newStatus = Status.kInstanceSynchronizingCode;
        }
        boolean wasStopped = InstanceStatus.getInstance().updateStatusIfStopped(
                                instanceName, newStatus);

        if (!wasStopped) {
            StringManagerBase sm = StringManagerBase.getStringManager(
                getLogger().getResourceBundleName())
            String msg =
                sm.getString("nodeagent.couldNotStartInstance", instanceName,
                             InstanceStatus.getInstance().getStatus(
                                instanceName).getStatus().getStatusString());
            getLogger().log(Level.WARNING, msg);               
            throw new AgentException(msg);
        }
    }
 
   
   
   
   
    private void debug(String s) {
        getLogger().log(Level.INFO, "NA-DEBUG: " + s);
    }
   
    /**
     * This method is used to remotely start an instance
     *
     * @param instanceName      instance to start
     * @throws AgentException   Exception thrown if anything goes wrong with
     *                          starting the instance
     */   
    protected void startInstance(String instanceName,
        boolean synchronizeInstance) throws AgentException {

        debug("startInstance(" + instanceName + ", " + synchronizeInstance + ")");
        //debug("InstanceDirs: " + InstanceDirs.toStringStatic());

        //validate that the server exists and return its node agent
        synchronized(synchronizationLock) {
            debug("Got Lock: " + instanceName);
            getLogger().log(Level.INFO, "nodeagent.startingInstance", instanceName);
            if (bDebug) System.out.println("Starting instance " +
                instanceName + " with synch flag set to " + synchronizeInstance);

            // make sure instance exists to start it
            if (!instanceExists(instanceName)) {
                // instance doesn't exist, this could be caused by a sync error
                // with the nodeagent so it doesn't know to create the instance
                // and then someone tries to start or stop it
                throw new AgentException(_strMgr.getString(
                        "nodeAgent.instanceDoesNotExist", instanceName));
            }       
            //Ensure that the instance is in a stopped state before starting it.
            ensureInstanceIsStopped(instanceName, synchronizeInstance);       
            if (synchronizeInstance)  {           
                try {
                    //beginning instance synchronization
                    InstanceStatus.getInstance().updateStatus(
                        instanceName, Status.kInstanceSynchronizingCode);
                    // synchronise of behalf of the instance, should only be done
                    // on direct start invocation
                    getLogger().log(Level.INFO,
                        "NodeAgent synchronizing for instance", instanceName);
                    synchronizeInstanceWithDAS(instanceName);
                } catch (AgentException ae) {
                    //synchronization failed
                    InstanceStatus.getInstance().updateStatusFromAdminChannel(
                        instanceName, Status.kInstanceNotRunningCode);
                    // need to throw exception so start-instance command show
                    // proper error and fails
                   
                    debug("ERROR IN SYNCHRONIZATION!!!! " + ae);
                   
                    throw ae;
                }
            }
            debug("Release Lock: " + instanceName);
        }

        // there was no sync or it succeeded
        try {               
            //beginning instance startup
            debug("Getting ready to have ProcessManger start the instance: " + instanceName);
            InstanceStatus.getInstance().updateStatus(
                instanceName, Status.kInstanceStartingCode);                          
            // always start when asked (not checking for now)
            // add instance to ProcessManager & start it
            ProcessManager.getInstance().addProcessInstance(instanceName,
                new ProcessInstanceInternal(instanceName));
            ProcessManager.getInstance().startProcess(instanceName);
            //startup succeeded
            InstanceStatus.getInstance().updateStatusFromAdminChannel(
                instanceName, Status.kInstanceRunningCode);  
        } catch (Exception e) {
            //startup failed. We put the instance in a not running state so that
            // the user can attempt to start it again.
            InstanceStatus.getInstance().updateStatusFromAdminChannel(
                instanceName, Status.kInstanceNotRunningCode);                 
            StringManagerBase sm = StringManagerBase.getStringManager(
                getLogger().getResourceBundleName())
            getLogger().log(Level.WARNING,
              sm.getString("nodeagent.start.instance.exception", instanceName), e);                 
            throw new AgentException(e);
        }
    }
   
    private com.sun.enterprise.config.serverbeans.NodeAgent
        getNodeAgentConfigBean(ConfigContext configCtxt)
        throws ConfigException {                       
        // get the servers that currently exist in domain xml
        Domain domain = ConfigAPIHelper.getDomainConfigBean(configCtxt)
        // get node controller config bean       
        return domain.getNodeAgents().getNodeAgentByName(getNodeAgentName());
    }

    Vector reconcileNodeConfiguration() throws AgentException {       
        getLogger().log(Level.FINE,
                        "Reconciling existing Node Configuration with " +
                        "configuration that is in domain.xml");
        Vector createdInstances=new Vector();
        try {           
            // get the servers that currently exist in domain xml
            Domain domain = ConfigAPIHelper.getDomainConfigBean(
                                getConfigContext())
            Server[] servers=domain.getServers().getServer();
           
            // get EEInstancesManager and get instances that currently
            // physically exist in repository
            InstanceConfig instanceConfig = new InstanceConfig(
                                            InstanceDirs.getInstanceRoot());
            EEInstancesManager eeInstancesManager = new EEInstancesManager(
                                                    instanceConfig);
            HashMap hmInstances = getInstancesAndStatus(
                                  instanceConfig, eeInstancesManager);
            // loop through for creatation of instances boolean match = false;
            Iterator serverIt = null;
            String instanceName = null;
            int status = 0;
           
            // get node controller config bean from domain
            com.sun.enterprise.config.serverbeans.NodeAgent nodeController
        = getNodeAgentConfigBean(getConfigContext());

            if (nodeController != null) {
                Properties props = null;
                ElementProperty elementProperty = null;
                Cluster cluster = null;
                // need a default, can't have %%%DOMAIN_NAME%%% go into
                // running server
                String domainName="DomainPropertyNotFound";
                // set default to "" because this string will actual be placed
                // in the startserv's java command for starting the instance
                // via the ProcessLauncher. This is the easiest way to have the
                // com.sun.aas.clusterName set to null for a standalone Instance
                String clusterArg = "";
               
                for (int ii = 0; ii < servers.length; ii++) {
                    // check to see if the server belongs to this
                    // node agent (repository)
                    if (instanceConfig.getRepositoryName().equals(
                            servers[ii].getNodeAgentRef())) {
                        // check if instance already exists or
                        // needs to be created.
                        if (instanceExists(servers[ii].getName())) {
                            getLogger().log(Level.INFO,
                            "nodeagent.instance.exists", servers[ii].getName());
                        } else {
                            // instance does not exist so create it
                            getLogger().log(Level.INFO,
                            "nodeagent.create.instance", servers[ii].getName());
                            instanceConfig.setInstanceName(servers[ii].getName());
                            // set properties for token replacing startserv scripts
                            props = new Properties();
                            // add proper domain
                            elementProperty = domain.getElementPropertyByName(
                                           DOMAIN_XML_DOMAIN_NAME_PROPERTY_NAME);
                            if (elementProperty != null)
                               domainName=elementProperty.getValue();
                           
                            getLogger().log(Level.INFO,
                                        "domain for instance - " + domainName);
                            props.setProperty(EEScriptsTokens.DOMAIN_NAME,
                                              domainName);

                            if (ServerHelper.isServerClustered(
                                  getConfigContext(), servers[ii].getName())) {
                                try {
                                    // see if part of cluster
                                    cluster = ClusterHelper.getClusterForInstance(
                                      getConfigContext(), servers[ii].getName());
                                    if (cluster != null)
                                        clusterArg = "-D" + CLUSTER_NAME + "=\""
                                                   + cluster.getName() + "\"";                                   
                                } catch (ConfigException ce) {
                                    // show at finest, because the server may
                                    // not be part of cluster
                                    getLogger().log(Level.FINEST,
                                        "Server isn't part of cluster", ce);
                                }
                            }
                            props.setProperty(EEScriptsTokens.CLUSTER_NAME, clusterArg);                           
                            // set the overriding properties used in token replacement
                            eeInstancesManager.setOverridingProperties(props);
                            // create instance
                            eeInstancesManager.createInstance();                           
                            // make list of created server instances to know which ones to
                            // sync on nodeagent startup.
                            createdInstances.add(servers[ii].getName());
                        }
                        // remove it from delete instances array
                        hmInstances.remove(servers[ii].getName());
                    }
                }
            }
           
            // loop through and delete instances if nessesary
            serverIt = hmInstances.keySet().iterator();
            while (serverIt.hasNext()) {
                instanceName = (String)serverIt.next();
                status = ((Status)hmInstances.get(instanceName)).getStatusCode();
               
                // delete instances
                if (bDebug) System.out.println("Delete Server =" + instanceName
                                             + " with status:" + status);
                getLogger().log(Level.INFO, "nodeagent.delete.instance",
                                instanceName);
                instanceConfig.setInstanceName(instanceName);
               
                // check to see if instances is
                if(status != Status.kInstanceNotRunningCode) {
                    try {
                        stopInstance(instanceName);
                    } catch (AgentException e) {
                        // only log exception, and continue deleting
                        StringManagerBase sm = StringManagerBase.getStringManager(
                            getLogger().getResourceBundleName())
                        getLogger().log(
                          Level.INFO,
                          sm.getString(
                             "nodeagent.stop.instance.exception", instanceName),
                          e);                         
                    }
                }
                // delete instance, without checking for JMS
                // instances (RepositoryManager)
                eeInstancesManager.deleteInstance(false);
            }
           
            // after all has been completed successfully
            // synchonize newly created instances to make sure that the new
            // synchroniztion strategy doesn't leave an instance without a
            // config, which could be potentially started by a nodeagent restart
            // loop through and delete instances if nessesary
            serverIt = createdInstances.iterator();
            while (serverIt.hasNext()) {
                instanceName = (String)serverIt.next();
                // sync instance, if failed it should have been logged
                try {
                    synchronizeInstanceWithDAS(instanceName);
                } catch (AgentException ae) {
                    // exception should already be logged
                    // don't stop creation loop, so just keep looping
                    // this was only a fail safe on restart
                }
            }
        } catch (Exception e) {
            throw new AgentException(e);
        }
        return createdInstances;
    }
   
    protected boolean instanceExists(String iName) throws AgentException {
        boolean match=false;
        Iterator serverIt=null;
        String instanceName=null;

        // get instance and status' in repository
        try {
            HashMap hmInstances=getInstancesAndStatus();
            serverIt=hmInstances.keySet().iterator();

            while(serverIt.hasNext()) {
                instanceName=(String)serverIt.next();
                if(instanceName.equals(iName)) {
                    match=true;
                    break;
                }
            }
        } catch (RepositoryException e) {
            throw new AgentException(e);
        }
        return match;
    }
   
    /**
     * This method gets the reposority instances and their status
     *
     * @return HashMap of instance names as the key and the status as the value
     */
    protected HashMap getInstancesAndStatus() throws RepositoryException {
        InstanceConfig instanceConfig =
            new InstanceConfig(InstanceDirs.getInstanceRoot());
        EEInstancesManager eeInstancesManager =
            new EEInstancesManager(instanceConfig);
        return getInstancesAndStatus(instanceConfig, eeInstancesManager);
    }
   
   
    /**
     * This method gets the reposority instances and their status
     *
     * @param instanceConfig
     * @param eeInstancesManager
     * @return HashMap of instance names as the key and the status as value
     */
    protected HashMap getInstancesAndStatus(InstanceConfig instanceConfig,
        EEInstancesManager eeInstancesManager) throws RepositoryException {
       
        // get EEInstancesManager and get instances that currently physically
        // exist in repository
        HashMap hmInstances = new HashMap();

        RuntimeStatusList rtstatusList =
            eeInstancesManager.getRuntimeStatus(instanceConfig);
        RuntimeStatus rtstatus = null;
        for (int i = 0; i < rtstatusList.size(); i++) {
            rtstatus = rtstatusList.getStatus(i);
            hmInstances.put(rtstatus.getName(), rtstatus.getStatus());
        }
        return hmInstances;
    }
         
    /**
     * This method attempts a "local" rendezvous. We look for all the domains
     * at the same level (i.e. same parent directory) as this node agent, and we
     * register ourselves with the first domain without checking host and port.
     * This code is meant to be called by the installer only and is potentially
     * dangerous since it is common to create multiple domains with the same
     * port, etc in testing scenerios. Furthermore, it is important that the DAS
     * not be running when this is invoked. This writes domain.xml directly, and
     * could result in issues if the DAS is running since the DAS config context
     * will not be refreshed with the new domain.xml.
     * @throws Exception
     */   
    public void localRendezvousWithDAS() throws Exception
    {
        getLogger().log(Level.FINE, "Attempting to Rendezvous with local DAS...");
        AgentConfig agentConfig = getNodeAgentConfig();
        File root = new File(
                      new File(agentConfig.getRepositoryRoot()).getParentFile(),         
                      "domains");       
        NodeAgentPropertyReader naReader = getNodeAgentPropertyReader()
        DASPropertyReader dasReader = getDASPropertyReader();       
        ConfigContext goodConfigContext = null;       
        boolean tooMany = false;
        String dasHost2 = dasReader.getHost();
        String dasPort2 = dasReader.getPort();
        if (root.exists()) {
            //Find all the domains with the same parent as this node agent
            File[] domains = root.listFiles();           
            if (domains != null) {                               
                for (int i = 0; i < domains.length; i++) {                                       
                    File domainXml = new File(new File(domains[i], "config")
                        PEFileLayout.DOMAIN_XML_FILE);                   
                    getLogger().log(Level.FINE, "Looking for " +
                                                domainXml.getAbsolutePath());
                    if (domainXml.exists()) {                       
                        ConfigContext configContext =
                            ConfigFactory.createConfigContext(
                                domainXml.getAbsolutePath());                       
                        String dasName =
                            ServerHelper.getDAS(configContext).getName();           
                        Config dasConfig = ServerHelper.getConfigForServer(
                                                configContext, dasName);
                        JMXConnectorConfig dasInfo =
                            ServerHelper.getJMXConnectorInfo(configContext, 
                                                             dasName);
                        String dasPort =
                            dasConfig.getHttpService().getHttpListenerById(
                            "admin-listener").getPort();
                        String dasHost = dasInfo.getHost();                       
                       
                        getLogger().log(Level.FINE, "dasHost: " + dasHost +
                              " dasPort: " + dasPort + " dasHost2: " + dasHost2
                            + " dasPort2: " + dasPort2);
                       
                        // Look for the first domain matching the specified host
                        // and port. There must be exactly one or we error out.
                        if (dasPort.equals(dasPort2) && (dasHost.equals(dasHost2) ||
                            PortConflictCheckerConfigBean.isLocalHost(dasHost2))) {
                            if (goodConfigContext != null) {
                                tooMany = true;
                                break; //we have found more than 1 matching domain
                            }                                          
                            goodConfigContext = configContext;
                            getLogger().log(Level.INFO,
                                "nodeagent.attemptingRendezvousedWithDAS",
                                domainXml.getAbsolutePath());
                        }
                    }
                }
            }
        }
        if (tooMany) {
            // There were more than one domain matching the specified host & port
            throw new AgentException(_strMgr.getString(
                "nodeAgent.attemptLocalRendezvous.TooManyLocalDomains",
                dasHost2 + ":" + dasPort2, root.getAbsolutePath()));
        } else if (goodConfigContext == null) {
            // There were no domains matching the specified host
            // and port NoLocalDomains
            throw new AgentException(_strMgr.getString(
                "nodeAgent.attemptLocalRendezvous.NoLocalDomains",
                dasHost2 + ":" + dasPort2, root.getAbsolutePath()));
        } else {
            // There was exactly one domain, flush out its domain.xml
            NodeAgentsConfigBean ncb =
                new NodeAgentsConfigBean(goodConfigContext);                           
            String retDasString = ncb.rendezvousWithDAS(
                naReader.getHost(), naReader.getPort(), getNodeAgentName(),
                naReader.getProtocol(), naReader.getClientHost());    
            goodConfigContext.flush();           
            markAsBound(retDasString);                        
        }       
    }
   
    /**
     * @throws Exception  */   
    public void rendezvousWithDAS() throws Exception {
        getLogger().log(Level.FINE, "Attempting to Rendezvous with DAS...");
        DASPropertyReader dasReader=null;
        String reportingUrl=null;
        try {                                     
            // create JMXConnector to DAS using user and password as necessary
            // call MBean to add this NodeAgent
            NodeAgentPropertyReader naReader = getNodeAgentPropertyReader();           
            String agentName = getNodeAgentName();
            dasReader = getDASPropertyReader();
            ObjectName objname  = new ObjectName(DAS_NODECONTROLLER_MBEAN_NAME);
           
            int port=Integer.parseInt(dasReader.getPort());
            String jmxProtocol = null;
           
            //The secure property indicates whether we should initiate a
            // secure connection to the DAS.
            Boolean isDASSecure = new Boolean(dasReader.isDASSecure());
            if (isDASSecure.booleanValue()) {           
                jmxProtocol = DefaultConfiguration.S1_HTTPS_PROTOCOL;
            } else {
                jmxProtocol = DefaultConfiguration.S1_HTTP_PROTOCOL;
            }
            final JMXServiceURL url =
                new JMXServiceURL(jmxProtocol, dasReader.getHost(), port);
            reportingUrl=url.toString();
            getLogger().log(Level.INFO,
                "nodeagent.attemptingRendezvousedWithDAS", url);

            final JMXConnector conn =
                JMXConnectorFactory.connect(url, initEnvironment(url));
            MBeanServerConnection serverConn=conn.getMBeanServerConnection();
           
            Object[] params = { naReader.getHost(), naReader.getPort(),
                agentName, naReader.getProtocol(), naReader.getClientHost() };
            String[] signature = {"java.lang.String", "java.lang.String",
                    "java.lang.String", "java.lang.String", "java.lang.String"};
            Object oret = serverConn.invoke(objname, "rendezvousWithDAS",
                                            params,  signature);
            if (oret == null) {
                // problem with return from rendezvous, can't continue
                getLogger().log(Level.SEVERE, "nodeagent.invalidRendezvous");
                getLogger().log(Level.WARNING, "nodeAgent.stopping.agent");
                System.exit(1);
            }                 

            reportingUrl=dasReader.getJMXURL();
            if (bDebug)
                System.err.println("BACK FROM HTTP CONNECT " + ((String)oret));
            markAsBound((String)oret);
           
            getLogger().log(Level.INFO, "nodeagent.rendezvousedWithDAS",
                            dasReader.getJMXURL());
           
        } catch (RedirectException e) {
            getLogger().log(Level.SEVERE,
                _strMgr.getString("nodeAgent.invalidRedirectAttempted"));
            throw e;
        } catch (Exception e) {
            // proxy throws throwable, can't tightem up exceptions
            getLogger().log(Level.SEVERE, "nodeagent.failedRendezvousWithDAS",
                reportingUrl  + " == " + e.toString());
            // set full exception to fine
            getLogger().log(
                Level.FINE, "nodeagent.rendezvous.with.das.Exception", e);
           
            // get cause to see it if is because CertificateNotYetValidException
            Throwable cause = e.getCause();
            if (cause instanceof CertificateNotYetValidException) {
                // this could be caused by miss-match is systems times,
                // log detailed message of resolution
              getLogger().log(Level.WARNING, "nodeagent.CertificateNotYetValid",
                  reportingUrl  + " == " + e.toString());
            }
            throw e;
        }
    }

    private void markAsBound(String dasRetString) throws IOException {
       
        // the das return string is expected in the form port|securityEnabled
        int iPos=dasRetString.indexOf("|");
        String port=dasRetString.substring(0, iPos);
        String securityFlag=dasRetString.substring(iPos + 1);
        // set and write out das properties
        DASPropertyReader dasReader = getDASPropertyReader();
        dasReader.setPort(port);
        dasReader.setIsDASSecure(securityFlag);
        dasReader.write();

        // nodeagent bound
        setNodeAgentBindStatus(AgentConfig.NODEAGENT_BOUND_STATUS);
    }
    /**
     *  This method initialize the environment for creating the JMXConnector.
     *  @return Map - HashMap of environemtn
     */
    private Map initEnvironment(JMXServiceURL serviceUrl) {
        final Map env = new HashMap();
        final String PKGS = "com.sun.enterprise.admin.jmx.remote.protocol";

        env.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, PKGS);
        env.put(DefaultConfiguration.ADMIN_USER_ENV_PROPERTY_NAME,
                IdentityManager.getUser());
        env.put(DefaultConfiguration.ADMIN_PASSWORD_ENV_PROPERTY_NAME,
                IdentityManager.getPassword());
        env.put(DefaultConfiguration.HTTP_AUTH_PROPERTY_NAME,
    DefaultConfiguration.DEFAULT_HTTP_AUTH_SCHEME);
        // If the do not confirm server cert flag is set, we must instantiate
        // a new trustmanager and register it with the connector. The
        // NoCertCheckX509TrustManager implicitly accepts the certificate of DAS
        // (without user confirmation) and enters it into the asadmintruststore.
        Boolean doNotConfirmCert = new Boolean(
            getNodeAgentPropertyReader().doNotConfirmServerCert());
        if (doNotConfirmCert.booleanValue()) {
            if (bDebug) System.out.println("do not confirm server certificate");           
            NoCertCheckX509TrustManager tm =
                new NoCertCheckX509TrustManager(serviceUrl);
            env.put(DefaultConfiguration.TRUST_MANAGER_PROPERTY_NAME, tm);
        } else if (bDebug) {
            System.out.println("confirm server certificate");
        }
        return env;
    }
   
    protected void configureLogger() {
        try {
            getLogger().log(Level.FINE, "Configuring Logger...");
            String logFileDefault = System.getProperty(INSTANCE_ROOT_PROPERTY)
                                  + File.separator + "logs/server.log";
            String logFile = logFileDefault;
            if (getNodeAgentPropertyReader().isBound()) {
                // go through domain.xm
                com.sun.enterprise.config.serverbeans.NodeAgent nodeController =
                    getNodeAgentConfigBean(getConfigContext());
                if (nodeController != null) {
                    LogService logService=nodeController.getLogService();
                    if (logService != null) {
                        // get logservice info from config beans           
                        logFile=logService.getFile();
                        if (logFile == null) logFile = logFileDefault;
                       
                        logFile = System.getProperty(logFile);
                        String logHandler = logService.getLogHandler();
                        String logLevel =
                            logService.getModuleLogLevels().getNodeAgent();
                        Handler[] handlers = getLogger().getHandlers();

                        if (bDebug) System.out.println("Log config number of " +
                            "handlers that currently exist:" + handlers.length +
                            " - " + logFile + " - " + logHandler  + " - " +
                            logLevel);
                       
                        // register default logger
                        registerLogger(Level.parse(logLevel), logFile);

      // fix for CR# 6443219
                        configureSynchronizationLogger(
                           logService.getModuleLogLevels().getSynchronization());
                    }
                }
            } else {
                // register default logger from nodeagent properties
                registerLogger(Level.INFO, logFile);
            }
           
            // Redirect stdout and stderr to appropriate location
            // NOTE: In verbose more the stderr only goes to the console,
            // this is exactly the way the apache commons-launcher functioned.
            String verboseMode = System.getProperty(
                                    "com.sun.aas.verboseMode", "false");
            if (bDebug) System.out.println(
                    "******* Redirecting stdout & stderr to : " + logFile);
            if (logFile != null && !verboseMode.equals("true")) {
                // If applicable, redirect output and error streams
                // PrintStream printStream =
                //   new PrintStream(new FileOutputStream(logFile, true), true);
                // System.setOut(printStream);
                // System.setErr(printStream);
                new SystemOutandErrHandler();
            }
        } catch (Exception e) {
      getLogger().info("nodeagent.noLogger");
        }
    }

    private void initializeSecurity(JmxConnector jmxConnector,
        com.sun.enterprise.config.serverbeans.NodeAgent nodeController)
    throws Exception {                       
        // Force static initialization of NSS store. This causes the NSS
        // database to be read into an in memory java keystore and will be
        // used NSS.       
        SecurityUtil.getSecuritySupport();
       
        //Realm initializtion
        String realmName = jmxConnector.getAuthRealmName();                           
        RealmConfig.createRealms(realmName,
            new AuthRealm[] {nodeController.getAuthRealm()});                            
    }   

    private String getObjectName() {
       return ":type=NodeAgent,name=" + getNodeAgentName() + ",category=config";
    }
   
    /**
     * Registers a JMXConnector in the MBeanServer based on the parameters
     *
     * @param protocol   protocol of JmxConnector
     * @param host       hostname for jmxConnector to listen on
     * @param port       port for the jmxConnector to listen on
     * @throws           Exception 
     *
     */   
    protected void registerJmxConnector(
        String protocol, String host, String port) throws Exception {
        if (bDebug)
            System.out.println(this.getClass().getName() +
                ": Trying to start jmx connector:" + "service:jmx:" + protocol
              + "://" + host + ":"  + port);

        /* TODO - changes required here ... */       
        ConfigContext configContext = getConfigContext();
        JmxConnector connector = NodeAgentHelper.getNodeAgentSystemConnector(
            configContext, getNodeAgentName());       
        final int iPort = Integer.parseInt(port);       
        final JmxConnectorServerDriver dr = new JmxConnectorServerDriver();
        dr.setAuthentication(true);
        dr.setAuthenticator(createJMXAuthenticator(connector));
        dr.setMBeanServer(_server);
        dr.setBindAddress(connector.getAddress());
        dr.setPort(iPort);
        dr.setProtocol(RemoteJmxProtocol.instance(protocol));
        handleSsl(dr, connector);
        dr.setLogger(_logger);
        dr.setRmiRegistrySecureFlag(false); //TODO
        final JMXConnectorServer serverEnd = dr.startConnectorServer();
        getLogger().log(Level.INFO, "NodeAgent url  = " +
                                      "service:jmx:" + connector.getProtocol() +
                                      "://" + connector.getAddress() +
                                      ":"  + connector.getPort());

        registerMBean(serverEnd, JMX_SERVER_MBEAN_PREFIX + port);
        if (bDebug) query();
    }
   
    private JMXAuthenticator createJMXAuthenticator(JmxConnector connector)
        throws ConfigException {
        final ASJMXAuthenticator authenticator = new ASJMXAuthenticator();               
        authenticator.setRealmName(connector.getAuthRealmName());       
        authenticator.setLoginDriver(new ASLoginDriverImpl());
        return authenticator;
    }
   
    private void handleSsl(JmxConnectorServerDriver dr, JmxConnector connector) {
        final boolean ssl = connector.isSecurityEnabled();
        if (bDebug) System.out.println(
                "DEBUG MESSAGE: SSL Status for System Jmx Connector: " + ssl);
        dr.setSsl(ssl);       
        RMIServerSocketFactory sf = null;
        if (ssl) {                         
            sf = new AdminSslServerSocketFactory(connector.getSsl(),
                                                 connector.getAddress());
            RMIClientSocketFactory cf = new AdminRMISSLClientSocketFactory();
            dr.setRmiClientSocketFactory(cf);
        } else sf = new RMIMultiHomedServerSocketFactory(connector.getAddress());
        dr.setRmiServerSocketFactory(sf);
    }
   
    protected void configureAgent() throws Exception {
        try {
            getLogger().log(Level.FINEST, "Configuring Agent...");

            if (_server == null) {
                // create mbean server only once
                _server =
                    MBeanServerFactory.createMBeanServer(MBEAN_SERVER_DOMAIN);
                // register the nodeagent mbean
                registerMBean(this, getObjectName());
            }

            // get JmxConnectors that already exist in MBeanServer
            ObjectName nameSearch = new ObjectName(
                _server.getDefaultDomain() + JMX_SERVER_MBEAN_SEARCH);

            // query on all ports to find the JMXConnectors that exist
            Set ls = _server.queryNames(nameSearch, null);

            Iterator it = ls.iterator();
            ObjectName objectName = null;
            String currPort = null;
            Vector vtCurrent = new Vector();
            while (it.hasNext()) {
                objectName = (ObjectName)it.next();
                if (bDebug) System.out.println(
                    "*** currently registered connectors: " + objectName);
               // break down list an get actual port numbers
                currPort = objectName.getKeyProperty("port");
                vtCurrent.add(objectName);
            }

            if (getNodeAgentPropertyReader().isBound()) {
                // go through domain.xml and register connector
                com.sun.enterprise.config.serverbeans.NodeAgent nodeController
                    = getNodeAgentConfigBean(getConfigContext());
                if (nodeController != null) {
                    final JmxConnector jmxConnector =
                        nodeController.getJmxConnector();
                    if (jmxConnector != null) {
                        initializeSecurity(jmxConnector, nodeController);
                        if (!isPortRegistered(
                                vtCurrent, jmxConnector.getPort())) {
                            // if not registered in mbean server,
                            // create and register it
                            registerJmxConnector(jmxConnector.getProtocol(),
                                                 jmxConnector.getAddress(),
                                                 jmxConnector.getPort());
                        }                                                          
                    }
                }
            } else {
                // register default jmx connector
                if (!isPortRegistered(vtCurrent,
                        getNodeAgentPropertyReader().getPort())) {
                    // if not registered in mbean server, create and register it
                    registerJmxConnector(
                        getNodeAgentPropertyReader().getProtocol(),
                        getNodeAgentPropertyReader().getHost(),
                        getNodeAgentPropertyReader().getPort());
                }
            }

            // now remove any JmxConnectors from the mbean server that should
            // no longer exist
            it = vtCurrent.iterator();
            while (it.hasNext()) {
                objectName = (ObjectName)it.next();
                if (bDebug) System.out.println(
                    "Removing JmxConnectorServer - " + objectName);

                // invoke stop on the jmxConnectors mbean and unregister it
                _server.invoke(objectName, "stop",
                               new Object[]{}, new String[]{});               
                _server.unregisterMBean(objectName);
            }
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * Invoked by the BaseNodeagent after intialization has been completed.
     *
     * @param startInstancesOverride  Whether to override the attribute
     *                                in node-agent element in domain.xml
     */
    protected void postStartupProcessing(String startInstancesOverride,
        boolean syncInstancesOverride, int monitorInterval, boolean restartIntancesOverride) throws Exception {

        // currently only startup all servers managed by nodeagent if BOUND
        // andset in domain.xml get node controller config bean from domain
        if (getNodeAgentPropertyReader().isBound()) {
            com.sun.enterprise.config.serverbeans.NodeAgent nodeController =
                getNodeAgentConfigBean(getConfigContext());

            if (bDebug) {
                String defaultStartup=null;
                if (nodeController != null)
                  defaultStartup =
                    String.valueOf(nodeController.isStartServersInStartup());
                System.out.println(
                    "Node Agent PostStartUpProcessing: domain.xml " +
                    "startup attibute = " + defaultStartup +
                    " startup override = " + startInstancesOverride);
            }

            // protect against null from all source,
            // including command line invoke
            if (startInstancesOverride == null) startInstancesOverride="NOTSET";
           
            // check to see if should start from domain.xml attribute or override
            if (  (startInstancesOverride.equals("NOTSET") &&
                   nodeController != null &&
                   nodeController.isStartServersInStartup())
                || startInstancesOverride.toLowerCase().equals("true") ) {

                // get servers that are associated with nodeagent
                // since this is post processing, all servers should be already
                // created it is possible that a race condition could be
                // encountered so startup errors are just logged               
                Server[] servers = ServerHelper.getServersOfANodeAgent(
                                        getConfigContext(), getNodeAgentName());
                if (servers.length > 0) {
                    long timeout = getStartServersTimeout();
                    //Start all the server instances in parallel
                    StartServerTask tasks[] = new StartServerTask[servers.length];
                    for (int ii = 0; ii < servers.length; ii++) {
                        tasks[ii] = new StartServerTask(
                                  servers[ii].getName(), syncInstancesOverride,
                                  monitorInterval, restartIntancesOverride, timeout);
                    }
                    Executor e = new Executor(tasks);
                    e.run();
                }
            } else {
                // since the instances are not started now, need to retain the restart flag
                ProcessManager.setRestartInstance(restartIntancesOverride);
            }
        }
    }
   
    /**
     * Invoked by the NodeagentMain before the nodeagent is shutdown
     */
    protected void shutdownProcessing(String stopInstancesOverride) throws Exception {
        // currently only shutdown all servers managed by nodeagent (not just
        // the ones you specifically started) if BOUND and set in domain.xml
        // get node controller config bean from domain
        if (getNodeAgentPropertyReader().isBound()) {
            com.sun.enterprise.config.serverbeans.NodeAgent nodeController =
                getNodeAgentConfigBean(getConfigContext());

            // stop all instances that belong to nodeagent
            if (nodeController != null) {
                // get instances that currently reside in repository
                HashMap hmInstances=getInstancesAndStatus();
                Iterator serverIt=hmInstances.keySet().iterator();
                String instanceName=null;
                Status instanceStatus=null;
                ArrayList runningInstances = new ArrayList();
                //Get a list of the running server instances
                while(serverIt.hasNext()) {
                    // get instance name of server
                    instanceName=(String)serverIt.next();
                    instanceStatus=(Status)hmInstances.get(instanceName);
                    if (bDebug) System.out.println("Shutdown processing, " +
                      "seeing if need to shutdown - " + instanceName  +
                      " with status " + instanceStatus);
                  
                    if (instanceStatus != null &&
                        instanceStatus.getStatusCode() ==
                            Status.kInstanceRunningCode) {
                        // stop instance
                        if (bDebug) System.out.println("Shutdown processing, "
                                           + "shutting down - " + instanceName);
                        getLogger().log(Level.FINE,
                            "NodeAgent Shutdown processing, Shutting " +
                            "down instance - " + instanceName);                       
                        runningInstances.add(instanceName);                           
                    }
                }
                      
                if (stopInstancesOverride != null && !stopInstancesOverride.equals("false")) {
                    //Stop the server instances
                    String[] servers = (String[]) runningInstances.toArray(
                            new String[runningInstances.size()]);
                    if (servers.length > 0) {
                        long timeout = getStopServersTimeout();
                        //Start all the server instances in parallel
                        StopServerTask tasks[] = new StopServerTask[servers.length];
                        for (int ii = 0; ii < servers.length; ii++) {
                             tasks[ii] = new StopServerTask(servers[ii], timeout);
                        }
                        Executor e = new Executor(tasks);
                        e.run();
                    }
                }
            }
        }
    }

    /**
     * Performs synchronization on behalf of the instance
     * @param instance - name of instance to synchronize
     */
    protected int synchronizeInstanceWithDAS(String instance)
    throws AgentException {
        // synchronize instance before starting in same jvm as ProcessLauncher
        // Synchronise with DAS, which will put domain.xml in config directory
        // need to use runtime exec until Nazrul finishes removing env
        // dependency so it can be called in process
       
        int iret = 1;
        String sxRet = "FAILED!";
      
        if(isInstanceStarted(instance)) {
      getLogger().log(Level.FINE,
                            "Returning from synchronizeInstanceWithDAS as " +
                            "instance is already running");
      // FIXME: This return value causes the stopInstance method to
            // return silently instead of throwing exception saying that the
            // instance is already running. This is a TBD.
      return 90; // 90 indicates that the server instance is running
  }
        // get node controller config bean from domain to see if there
        // is a jvm are for synchronization
        String instanceSyncJvmOptions = "";
        try {
            com.sun.enterprise.config.serverbeans.NodeAgent nodeagent
                = getNodeAgentConfigBean(getConfigContext());
            ElementProperty instanceSyncJvmOptionsProperty =
                nodeagent.getElementPropertyByName(INSTANCE_SYNC_JVM_OPTIONS);
            if (instanceSyncJvmOptionsProperty != null)
               instanceSyncJvmOptions=instanceSyncJvmOptionsProperty.getValue();
        } catch (ConfigException ce) {
            getLogger().log(Level.WARNING,
               "nodeagent.synchronization.Exception", ce);
        }
       
        long startSync = System.currentTimeMillis();
        try {
            InstanceConfig instanceConfig = new InstanceConfig(
                InstanceDirs.getRepositoryName(),
                InstanceDirs.getRepositoryRoot(), instance);
            String iRoot = instanceConfig.getRepositoryRoot() + File.separator +
                           instanceConfig.getRepositoryName() + File.separator +
                           instance;
            if (bDebug) System.out.println("*** SYNCHRONIZE INSTANCE: "+ iRoot);

            //SynchronizationDriver sd =
            // new SynchronizationDriverFactory.getSynchronizationDriver(
            // iRoot, SynchronizationDriverFactory.INSTANCE_CONFIG_URL);
            //sd.synchronize();
            String installRoot = System.getProperty(INSTALL_ROOT_PROPERTY);
            ArrayList ar = new ArrayList();
            ar.add(System.getProperty(JAVA_ROOT_PROPERTY) + File.separator +
                                      "bin" + File.separator + "java");
            // add jvm options from domain.xml
            if ( instanceSyncJvmOptions != null &&
                !instanceSyncJvmOptions.equals("")) {
                String[] opts = instanceSyncJvmOptions.split(" ");
                for (int i=0;i<opts.length;i++) {
                   ar.add(opts[i]);
                }
            }

            String logFileDefault = System.getProperty(INSTANCE_ROOT_PROPERTY) +
                                            File.separator + "logs/server.log";
            /*String logFile=logFileDefault;
            com.sun.enterprise.config.serverbeans.NodeAgent nodeController =
             getNodeAgentConfigBean(getConfigContext());
            LogService logService=nodeController.getLogService();
            if(logService != null) {
                // get logservice info from config beans           
                logFile=logService.getFile();
                if (logFile == null) {
                    logFile=logFileDefault;
                }
            }
            logFile=System.getProperty(logFile);*/
           
            //ar.add("-Xdebug");
            //ar.add("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=9119");
           
            ar.add("-Djava.util.logging.manager" +
                    "=" + "com.sun.enterprise.server.logging.ServerLogManager");
            ar.add("-D" + INSTALL_ROOT_PROPERTY + "=" + installRoot);
            ar.add("-D" + AGENT_ROOT_PROPERTY +
                    "=" + System.getProperty(INSTANCE_ROOT_PROPERTY));
            ar.add("-D" + AGENT_NAME_PROPERTY +
                    "=" + System.getProperty(SERVER_NAME));
            ar.add("-D" + AGENT_CERT_NICKNAME +
                    "=" + ServerHelper.getCertNickname(getConfigContext(),
                          IAdminConstants.DAS_SERVER_NAME));
            setKeyAndTrustStoresForInstanceSync(ar);
            ar.add("-D" + "com.sun.aas.defaultLogFile" +
                    "=" + logFileDefault);          
                     
            ar.add("-D" + INSTANCE_ROOT_PROPERTY + "=" + iRoot);
            ar.add("-D" + CONFIG_ROOT_PROPERTY +
                    "=" + System.getProperty(CONFIG_ROOT_PROPERTY));
            ar.add("-D" + SystemPropertyConstants.SERVER_NAME + "=" + instance);
            ar.add("-D" + "com.sun.appserv.pluggable.features" +
                   "=" + "com.sun.enterprise.ee.server." +
                         "pluggable.EEPluggableFeatureImpl");
            ar.add("-D" "com.sun.aas.promptForIdentity" + "=" + "true");
            ar.add("-cp");
            String fs = File.separator;
            String fps = File.pathSeparator;
            ar.add(installRoot + fs + "lib" + fs + "appserv-admin.jar" + fps +
                   installRoot + fs + "lib" + fs + "comms-appserv-rt.jar" + fps +
                   installRoot + fs + "lib" + fs + "appserv-rt.jar" + fps +
                   installRoot + fs + "lib" + fs + "javaee.jar" + fps +
                   installRoot + fs + "lib" + fs + "appserv-se.jar" + fps +
                   installRoot + fs + "lib" + fs + "appserv-ee.jar");

            ar.add("com.sun.enterprise.ee.synchronization.SynchronizationMain");
            String synUrl = HttpUtils.getSynchronizationURL(getConfigContext());
            if (synUrl != null) ar.add(synUrl);
           
            String[] command=new String[ar.size()];
            command = (String[])ar.toArray(command);

            if (getLogger().isLoggable(Level.FINE)) {
                StringBuffer sb=new StringBuffer();
                for(int ii=0; ii < command.length; ii++) {
                    sb.append(command[ii] + " ");
                }
                getLogger().log(Level.FINE, sb.toString());
            }
           
            Process process = Runtime.getRuntime().exec(command);
            IdentityManager.writeToOutputStream(process.getOutputStream());
            StreamFlusher sfOut =
                new StreamFlusher(process.getInputStream(), System.err);
            StreamFlusher sfErr =
                new StreamFlusher(process.getErrorStream(), System.err);
            sfOut.start();
            sfErr.start();
            iret=process.waitFor();

            // logs a severe msg when synchronization fails
            Level sLoglevel = Level.SEVERE;
            if (iret == 0) {
                sxRet="SUCCEEDED!";
                sLoglevel = Level.INFO;
            }
            getLogger().log(sLoglevel, "nodeagent.syncStatus",
                new Object[]{ instance, sxRet,
                    String.valueOf(System.currentTimeMillis() - startSync)});
           
        } catch (Exception e) {
            // need to catch specific exception for sync
            getLogger().log(Level.WARNING,
                "nodeagent.synchronization.Exception",e);
            throw new AgentException(e);
        }
        return iret;
    }
   
   /**
    * @param instance name of the instance
    */
    private boolean isInstanceStarted(String instance) {
  try {
      HashMap h = getInstancesAndStatus();
      Status s = (Status) h.get(instance);
      if (s.getStatusCode() == Status.kInstanceRunningCode ||
          s.getStatusCode() == Status.kInstanceStoppingCode ||
          s.getStatusCode() == Status.kInstanceStartingCode ) {
          return true;
      }
  } catch(Exception e){
      //ignore
        }
  return false;
    }

    /**
     * Updates the das properties from domain.xml if they have changed
     */
    protected void updateDASConnectionInfo() throws Exception {

        MBeanServerConnectionInfo dasInfo =
            InstanceRegistry.getDASConnectionInfo(getConfigContext());
        boolean bWrite = false;

        // get appropriate das properties
        DASPropertyReader dasProperty = getDASPropertyReader();
        if (!dasProperty.getProtocol().equals(dasInfo.getProtocol()) ||
            !dasProperty.getPort().equals(dasInfo.getPort()) ||
            !dasProperty.getHost().equals(dasInfo.getHost())) {

            // something changed for the das connection, update das properties
            dasProperty.setProtocol(dasInfo.getProtocol());
            dasProperty.setPort(dasInfo.getPort());
            dasProperty.setHost(dasInfo.getHost());
            bWrite = true;
           
            // log message so the user will know to change hosts file
            // so it is pingable.
            getLogger().log(Level.CONFIG, "nodeagent.changeOfDASValues",
                new Object[] {dasInfo.getHost() + ":" + dasInfo.getPort(),
                              dasInfo.getHost()});
           
        }
       
        // check to see if jmx secure flas has changed
        Server das = ServerHelper.getDAS(getConfigContext());
        if (das != null) {
            String dasName=das.getName();
            JmxConnector dasConnector = ServerHelper.getServerSystemConnector(
                                            getConfigContext(), dasName);
            if (dasConnector != null) {
                String jmxConnSecure =
                    String.valueOf(dasConnector.isSecurityEnabled());
                if (!String.valueOf(
                        dasProperty.isDASSecure()).equals(jmxConnSecure)) {
                    dasProperty.setIsDASSecure(jmxConnSecure);
                    bWrite = true;
                }
            }
        }
        // only write if you have to
        if (bWrite) dasProperty.write();
    }   
   
    protected void validateAdminUserAndPassword() throws AgentException {
        final AgentConfig ac = getAgentConfig();
        setPasswords(ac);
        final AgentManager am = getAgentManager(ac);
        am.validateAdminUserAndPassword(ac);
    }
   
    private AgentConfig getAgentConfig() {
        final String myName = System.getProperty(SERVER_NAME);
        final String myPath = getMyPath();
        final AgentConfig ac = new AgentConfig(myName, myPath);
        return ac;
    }
   
    private String getMyPath() {
        final String path = System.getProperty(INSTANCE_ROOT_PROPERTY);
        final File f = new File(path);
        final String parent = new File(f.getParent()).getParent();
        return parent;
    }

    private AgentManager getAgentManager(AgentConfig agentConfig) {
        EEDomainsManager domainsManager =
            (EEDomainsManager)getFeatureFactory().getDomainsManager();
        return domainsManager.getAgentManager(agentConfig);
    }

     private void setPasswords(final AgentConfig ac) {
         String mp = IdentityManager.getMasterPassword();
         ac.put(AgentConfig.K_MASTER_PASSWORD, mp);
         // Also make sure to have the system properties new JKS loading will
         // require in the NodeAgent VM. This was missed during JKS changes
         System.setProperty("javax.net.ssl.keyStorePassword", mp);
         System.setProperty("javax.net.ssl.trustStorePassword", mp);
         ac.put(AgentConfig.K_DAS_USER, IdentityManager.getUser());
         ac.put(AgentConfig.K_DAS_PASSWORD, IdentityManager.getPassword());
     }

     private ClientPluggableFeatureFactory getFeatureFactory() {
        final String featurePropClass = System.getProperty(
            ClientPluggableFeatureFactory.PLUGGABLE_FEATURES_PROPERTY_NAME,
            null);
         ClientPluggableFeatureFactoryImpl featureFactoryImpl =
            new ClientPluggableFeatureFactoryImpl(getLogger());
         ClientPluggableFeatureFactory featureFactory =
            (ClientPluggableFeatureFactory)featureFactoryImpl.getInstance(
            featurePropClass);
         return featureFactory;
     }

    // This is a quick solution to fix the synchronization logging domain's
    // log level since its broken in ServerLogManager within the
    // node agent process
    private void configureSynchronizationLogger(String level) {
        Level ll = Level.INFO;
        try {
            ll = Level.parse(level);
        } catch(Exception e) {
            getLogger().log(Level.FINE, "Exception: " + e.getMessage());
        }
        Logger syncLogger = Logger.getLogger(
            com.sun.logging.ee.EELogDomains.SYNCHRONIZATION_LOGGER);

        getLogger().log(Level.FINE, "Setting synchronization loglevel to "+ ll);
        syncLogger.setLevel(ll);
    }
    //XXX temp, need to change after profile is done
    private void setKeyAndTrustStoresForInstanceSync(ArrayList ar)
    throws AgentException {
        String configDir = System.getProperty("com.sun.aas.instanceRoot") +
                           File.separator + "config";
        java.io.File nssFile = new File(configDir, "key3.db");
        if (!nssFile.exists()) {
            if (System.getProperty("javax.net.ssl.keyStore") == null) {
                StringManagerBase sm = StringManagerBase.getStringManager(
                                        getLogger().getResourceBundleName());
                String msg = sm.getString(
                    "nodeagent.noKeyStoreFoundForInstanceSync");
                getLogger().log(Level.SEVERE, msg);                                      
                throw new AgentException(msg);
            } else {
                ar.add("-D" + "javax.net.ssl.keyStore" + "=" +
                    System.getProperty("javax.net.ssl.keyStore"));
                ar.add("-D" + "javax.net.ssl.trustStore" + "=" +
                    System.getProperty("javax.net.ssl.trustStore"));
                ar.add("-D" + "javax.net.ssl.keyStorePassword" + "=" +
                    System.getProperty("javax.net.ssl.keyStorePassword"));
                ar.add("-D" + "javax.net.ssl.trustStorePassword" + "=" +
                    System.getProperty("javax.net.ssl.trustStorePassword"));
            }
        } else {
            ar.add("-D" + NSS_ROOT_PROPERTY + "=" +
                    System.getProperty(NSS_ROOT_PROPERTY));
            ar.add("-D" + NSS_DB_PROPERTY + "=" +
                    System.getProperty(NSS_DB_PROPERTY));
            ar.add("-D" + NSS_DB_PASSWORD_PROPERTY + "=" +
                    System.getProperty(NSS_DB_PASSWORD_PROPERTY));
        }
    }

    public static void main(String args[]) {
        try {
            final int numArgs = args.length;
            int port = DEFAULT_CONNECTOR_PORT;

            if (numArgs == 1) {
                port = Integer.parseInt(args[0]);
            } else if (numArgs != 0) {
                System.out.println("USAGE: Server <port");           
            }
            NodeAgent nas = new NodeAgent();
            nas.run(null, false, 0, true);
            System.exit(0);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }  

    private boolean haveDASCoordinatesChanged(String newHost, String newPort)
    throws ConfigException {
       
        AdminService as =
            ServerHelper.getAdminServiceForServer(getConfigContext(), "server");
        JmxConnector jmxConn =
            as.getJmxConnectorByName(as.getSystemJmxConnectorName());
       
        if (!jmxConn.getPort().equals(newPort)) return true;

        ElementProperty clientHostname =
            jmxConn.getElementPropertyByName(HOST_PROPERTY_NAME);
        if (!newHost.equals((String)clientHostname.getValue())) return true;
       
        return false;
    }

    class StartServerTask extends Task {
           
        private String _serverName;       
        private boolean _syncInstance;
        private int _monitorInterval;
        private boolean _restartInstance;
       
        public StartServerTask(String serverName, boolean syncInstance, int monitorInterval, boolean restartInstance, long timeout){
            super(timeout);
            _serverName = serverName;           
            _syncInstance = syncInstance;
            _monitorInterval = monitorInterval;
            _restartInstance = restartInstance;
        }
               
        public void run() {           
            try {
                getLogger().log(Level.INFO, "Node agent overriding sleep time = " +  _monitorInterval*1000);                       
                ProcessManager.setRestartInstance(_restartInstance);
                ProcessManager.getInstance().setMonitorSleepInterval(_monitorInterval*1000);
                startInstance(_serverName, _syncInstance);
            } catch (AgentException ex) {
                // Eat the exception. It has already been logged by startInstance.                
            }           
        }
    }

    class StopServerTask extends Task {
          
        private String _serverName;       
       
        public StopServerTask(String serverName, long timeout) {
            super(timeout);
            _serverName = serverName;           
        }
               
        public void run() {           
            try {
                stopInstance(_serverName);
            } catch (AgentException ex) {
                // Eat the exception. It has already been logged by stopInstance.
            }           
        }
    }
}
TOP

Related Classes of com.sun.enterprise.ee.nodeagent.NodeAgent

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.