Search in sources :

Example 1 with ContainerCommandUpdate

use of com.cosylab.acs.maci.manager.recovery.ContainerCommandUpdate in project ACS by ACS-Community.

the class ManagerImpl method containerLogin.

/*****************************************************************************/
/**************************** [ Login methods ] ******************************/
/*****************************************************************************/
/**
	 * Container specific login method.
	 * @param	name	name of the container, non-<code>null</code>.
	 * @param	reply	reply to authenticate method, non-<code>null</code>.
	 * @param	container	container that is logging in, non-<code>null</code>.
	 * @return	ClientInfo	client info. of newly logged container
	 */
private ClientInfo containerLogin(String name, AuthenticationData reply, Container container, long timeStamp, long executionId) throws AcsJNoPermissionEx {
    assert (name != null);
    assert (reply != null);
    assert (container != null);
    TimerTaskContainerInfo containerInfo = null;
    ClientInfo clientInfo = null;
    boolean existingLogin = false;
    synchronized (containers) {
        // check if container is already logged in,
        // if it is, return existing info
        int h = containers.first();
        while (h != 0) {
            ContainerInfo loggedContainerInfo = (ContainerInfo) containers.get(h);
            //if (container.equals(loggedContainerInfo.getContainer()))
            if (name.equals(loggedContainerInfo.getName())) {
                Container loggedContainer = loggedContainerInfo.getContainer();
                if (loggedContainer != null) {
                    // if same instance simply recover, if not...
                    if (!loggedContainer.equals(container)) {
                        // check if logged container is alive, if it is reject him
                        boolean alive = false;
                        try {
                            int lh = loggedContainer.get_handle();
                            if (lh != 0 && lh == loggedContainerInfo.getHandle())
                                alive = true;
                        } catch (Throwable th) {
                        // noop
                        }
                        if (alive) {
                            AcsJNoPermissionEx npe = new AcsJNoPermissionEx();
                            String address = "";
                            try {
                                address = " " + loggedContainer.getRemoteLocation();
                            } catch (Throwable th) {
                            /* noop */
                            }
                            npe.setReason("Rejecting container login, container with name '" + name + "'" + address + " already logged in.");
                            npe.setID(HandleHelper.toString(loggedContainerInfo.getHandle()));
                            npe.setProtectedResource(name);
                            throw npe;
                        } else
                            logger.log(Level.FINER, "Container '" + name + "' is no longer functional, new container is taking over.");
                    }
                }
                // !!! ACID 2
                // new reference is considered as better
                executeCommand(new ContainerCommandUpdate(h, container));
                //loggedContainerInfo.setContainer(container);
                existingLogin = true;
                // generate ClientInfo
                containerInfo = (TimerTaskContainerInfo) loggedContainerInfo;
                clientInfo = containerInfo.createClientInfo();
                break;
            }
            h = containers.next(h);
        }
        // new container
        if (h == 0) {
            long pingInterval = 0;
            DAOProxy dao = getContainersDAOProxy();
            if (dao != null) {
                String impLang = readStringCharacteristics(dao, name + "/ImplLang", true);
                ImplLang configuredImplLang = ImplLang.fromString(impLang);
                if (configuredImplLang != ImplLang.not_specified && configuredImplLang != reply.getImplLang()) {
                    AcsJNoPermissionEx npe = new AcsJNoPermissionEx();
                    npe.setReason("Rejecting container login, container reported '" + reply.getImplLang() + "' implementation language, but configured '" + configuredImplLang + "'.");
                    npe.setProtectedResource(name);
                    throw npe;
                }
                pingInterval = readLongCharacteristics(dao, name + "/PingInterval", -1, true) * 1000;
            }
            // allocate new handle
            // !!! ACID 2
            Integer objHandle = (Integer) executeCommand(new ContainerCommandAllocate());
            int handle;
            if (objHandle == null || (handle = objHandle.intValue()) == 0) {
                NoResourcesException af = new NoResourcesException("Generation of new handle failed, too many containers logged in.");
                throw af;
            }
            // generate external handle
            h = handle | CONTAINER_MASK;
            // add generated key
            h |= (random.nextInt(0x100)) << 16;
            // create new container info
            containerInfo = new TimerTaskContainerInfo(h, name, container, containerPingInterval);
            containerInfo.setImplLang(reply.getImplLang());
            if (// safety limit
            pingInterval >= 1000)
                containerInfo.setPingInterval(pingInterval);
            clientInfo = containerInfo.createClientInfo();
            // register container to the heartbeat manager
            PingTimerTask task = new PingTimerTask(this, logger, clientInfo, alarmSource);
            containerInfo.setTask(task);
            heartbeatTask.schedule(task, containerInfo.getPingInterval(), containerInfo.getPingInterval());
            // !!! ACID - register AddContainerCommand
            executeCommand(new ContainerCommandSet(handle, containerInfo));
        // store info
        //containers.set(handle, containerInfo);
        }
    }
    // cancel all "old" container async request
    AcsJCannotGetComponentEx acgcex = new AcsJCannotGetComponentEx();
    acgcex.setReason("Request canceled due to container re-login.");
    cancelPendingContainerAsyncRequestWithException(containerInfo.getName(), acgcex);
    final boolean recoverContainer = reply.isRecover();
    if (existingLogin) {
        // merge container's and manager's internal state
        containerInternalStateMerge(containerInfo, recoverContainer);
    }
    // notify administrators about the login
    notifyContainerLogin(containerInfo, timeStamp, executionId);
    // do container post login activation in separate thread
    final ContainerInfo finalInfo = containerInfo;
    threadPool.execute(new Runnable() {

        public void run() {
            containerPostLoginActivation(finalInfo, recoverContainer);
        }
    });
    logger.log(Level.INFO, "Container '" + name + "' logged in.");
    return clientInfo;
}
Also used : ContainerCommandAllocate(com.cosylab.acs.maci.manager.recovery.ContainerCommandAllocate) ContainerCommandSet(com.cosylab.acs.maci.manager.recovery.ContainerCommandSet) ContainerCommandUpdate(com.cosylab.acs.maci.manager.recovery.ContainerCommandUpdate) DAOProxy(com.cosylab.cdb.client.DAOProxy) AcsJCannotGetComponentEx(alma.maciErrType.wrappers.AcsJCannotGetComponentEx) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) NoResourcesException(com.cosylab.acs.maci.NoResourcesException) Container(com.cosylab.acs.maci.Container) AcsJNoPermissionEx(alma.maciErrType.wrappers.AcsJNoPermissionEx) ContainerInfo(com.cosylab.acs.maci.ContainerInfo) ClientInfo(com.cosylab.acs.maci.ClientInfo) ImplLang(com.cosylab.acs.maci.ImplLang)

Aggregations

AcsJCannotGetComponentEx (alma.maciErrType.wrappers.AcsJCannotGetComponentEx)1 AcsJNoPermissionEx (alma.maciErrType.wrappers.AcsJNoPermissionEx)1 ClientInfo (com.cosylab.acs.maci.ClientInfo)1 Container (com.cosylab.acs.maci.Container)1 ContainerInfo (com.cosylab.acs.maci.ContainerInfo)1 ImplLang (com.cosylab.acs.maci.ImplLang)1 NoResourcesException (com.cosylab.acs.maci.NoResourcesException)1 ContainerCommandAllocate (com.cosylab.acs.maci.manager.recovery.ContainerCommandAllocate)1 ContainerCommandSet (com.cosylab.acs.maci.manager.recovery.ContainerCommandSet)1 ContainerCommandUpdate (com.cosylab.acs.maci.manager.recovery.ContainerCommandUpdate)1 DAOProxy (com.cosylab.cdb.client.DAOProxy)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1