| 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): |