V2 Here is what you get when you add the second instance to a cluster C:\WINDOWS>asadmin create-instance --cluster c1 --nodeagent vaio i2 Using 38,081 for HTTP_LISTENER_PORT. Using 38,182 for HTTP_SSL_LISTENER_PORT. Using 33,821 for IIOP_SSL_LISTENER_PORT. Using 37,677 for JMS_PROVIDER_PORT. Using 33,701 for IIOP_LISTENER_PORT. Using 38,687 for JMX_SYSTEM_CONNECTOR_PORT. Using 33,921 for IIOP_SSL_MUTUALAUTH_PORT. Command create-instance executed successfully. Wow! This was super-hard to find in V2 code. Also the main class is PortConflictCheckerConfigBean admin/mbeans /** * Check to see if any of the ports defined as system properties are in use or conflict with * other ports in domain.xml (i.e. with other server instances on the same machine -- with * the same node agent). If there are conflicts, then we pick new port numbers. */ private ArrayList resolvePortConflicts(Server server, Properties newProps) throws Exception { PortConflictCheckerConfigBean portChecker = getPortConflictCheckerConfigBean(); String serverName = server.getName(); ArrayList portsInUse = null; try { //First check to see whether any of the user specified ports are in use, if //so an exception must be thrown if (newProps != null) { portChecker.checkForPortConflicts(server, newProps, newProps, false); } int i = 0; //We loop trying trying to incrementally assign new ports. while (true) { //Perform some sort of sanity check to ensure //that the port numbers do not conflict for other servers on the same //node agent. This is accomplished by comparing properties whose //name contains "port" and whose value is numeric. NOTE: port validation //is done after adding the server. For this reason, we must rollback the //addition of the server if the port check fails. try { portChecker.checkForPortConflicts(server, null, false); //stop when there are no port conflicts break; } catch (PortInUseException ex) { if (i++ > 25) { //We do not want to throw the PortInUseException since it is an internal //class and protected. throw new InstanceException(ex.getMessage()); } //If there were port conflicts, then we pick unused ports. ArrayList newPorts = pickNonConflictingPorts(server, ex.getConflictingPorts()); //Keep track of the initial list of conflicting ports. This is tricky //since the list in the PortInUseException will shrink as conflicts //are resolved. if (portsInUse == null) { portsInUse = newPorts; } else { //Now take all the newly resolved ports and apply them to the original list, updating //only the new port. for (int j = 0; j < newPorts.size(); j++) { PortInUse newPort = (PortInUse)newPorts.get(j); for (int k = 0; k < portsInUse.size(); k++) { PortInUse port = (PortInUse)portsInUse.get(k); if (port.getPropertyName().equals(newPort.getPropertyName())) { port.setNewPort(newPort.getNewPort()); break; } } } } } } } catch (Exception ex) { try { deleteServerInstance(serverName); } catch (Exception ex2) { //Log StringManagerBase sm = StringManagerBase.getStringManager(getLogger().getResourceBundleName()); getLogger().log(Level.WARNING, sm.getString("eeadmin.createServerInstance.Exception", serverName), ex2); } throw (ex); } return portsInUse; } /** * Creates a new server instance. This operation is invoked by the asadmin create-instance * command. */ public void createServerInstance( String nodeAgentName, String serverName, String configName, String clusterName, Properties props) throws InstanceException, PortReplacedException { ArrayList conflictingPorts = null; try { final ConfigContext configContext = getConfigContext(); //validate name uniqueness if (!ConfigAPIHelper.isNameUnique(configContext, serverName)) { throw new InstanceException(_strMgr.getString("serverNameNotUnique", serverName)); } ConfigAPIHelper.checkLegalName(serverName); // see if nodeagent exists, if not create an empty reference Domain domain = ConfigAPIHelper.getDomainConfigBean(configContext); NodeAgents agents=domain.getNodeAgents(); NodeAgent agent=agents.getNodeAgentByName(nodeAgentName); if (agent == null) { // create an implnodeagent reference NodeAgentsConfigBean naMBean = getNodeAgentsConfigBean(); naMBean.createNodeAgentConfig(nodeAgentName); } //a configuration and cluster cannot both be specified if (configName != null && clusterName != null) { throw new InstanceException(_strMgr.getString("configAndClusterMutuallyExclusive")); } //Ensure that server specified by serverName does not already exist. //Given that we've already checked for uniqueness earlier, this should never //be the case, but we'll be extra safe here. Servers servers = domain.getServers(); Server server = servers.getServerByName(serverName); if (server != null) { throw new InstanceException(_strMgr.getString("serverAlreadyExists", serverName)); } //Create the new server instance server = new Server(); server.setNodeAgentRef(nodeAgentName); server.setName(serverName); if (configName != null) { createSharedServerInstance(configName, server, props); } else if (clusterName != null) { createClusteredServerInstance(clusterName, server, props); } else { //FIXTHIS: One issue is that the call below will result in a call to flushAll //which is also called below. This must be taken into account when we //figure out the notification story. createStandAloneServerInstance(server, props); } //Check for and resolve port conflicts. The list of port conflicts is maintained. //This is called after creating the server. This is due to the fact that port //conflicts are resolved and a marker PortReplacedException is thrown; however //the server is still created. conflictingPorts = resolvePortConflicts(server, props); //Notify the node agent that a new server has been added to it so it can //resynchronize. //FIXTHIS: We force persistence, clear any notifications, and update the //Application server's config context explicitely. Until this is modelled //as an event notification (TBD) we need this to happen before notifying or //the Node Agent will not synchronize the correct data. //QUESTION: What happens if an exception is thrown above (e.g. in addNodeAgent). How do //we restore the admin config context to its previous (and unpersisted value)??? flushAll(); NodeAgentMBean agentMBean = NodeAgentProxy.getNodeAgentProxy(nodeAgentName); agentMBean.synchronizeWithDAS(); } catch (Exception ex) { throw getExceptionHandler().handleInstanceException( ex, "eeadmin.createServerInstance.Exception", serverName); } //Finally after all is said and done, we throw an exception if there were port //conflicts. if (conflictingPorts != null) { throw new PortReplacedException(conflictingPorts); } } private String[] toStringArray(Server[] sa) { int numServers = sa.length; final String[] result = new String[numServers]; for (int i = 0; i < numServers; i++) { result[i] = sa[i].getName(); } return result; } V2 Algorithmif(there are user-specified port numbers AND any are non-number values or out of range)
Unknown macro: { FATAL();} if(internal duplicate port numbers in the one server 9e.g. HTTP and SSL are same number) FATAL(); if(server isn't running -- check that every port is free at host}
Old URL (read-only): |