Search in sources :

Example 1 with ComponentCommandDeallocate

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

the class ManagerImpl method containerPostLoginActivation.

/**
	 * Container post login activation, activate startup and unavailable components.
	 * NOTE: to be run in separate thread.
	 *
	 * @param	containerInfo	container info for which to perform post login activation.
	 * @param	recoverContainer	recovery mode flag.
	 */
private void containerPostLoginActivation(final ContainerInfo containerInfo, boolean recoverContainer) {
    // give containers some time to fully initialize
    if (containerInfo.getImplLang() == ImplLang.cpp || containerInfo.getImplLang() == ImplLang.not_specified) {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException ie) {
        }
    }
    // shutdown check
    if (isShuttingDown())
        return;
    // CDB startup
    if (cdbActivation != null && containerInfo.getName().equals(cdbActivation.getContainer())) {
        try {
            StatusHolder status = new StatusHolder();
            ComponentInfo cdbInfo = internalRequestComponent(this.getHandle(), cdbActivation.getName(), cdbActivation.getType(), cdbActivation.getCode(), cdbActivation.getContainer(), RELEASE_IMMEDIATELY, status, true);
            if (status.getStatus() != ComponentStatus.COMPONENT_ACTIVATED)
                logger.log(Level.SEVERE, "Failed to activate CDB, reason: '" + status.getStatus() + "'.");
            else if (cdbInfo == null || cdbInfo.getHandle() == 0 || cdbInfo.getComponent() == null)
                logger.log(Level.SEVERE, "Failed to activate CDB, invalid ComponentInfo returned: '" + cdbInfo + "'.");
            else {
                logger.log(Level.INFO, "CDB activated on container '" + containerInfo.getName() + "'.");
            }
        } catch (Throwable ex) {
            logger.log(Level.SEVERE, "Failed to activate CDB on container '" + containerInfo.getName() + "'.", ex);
        }
    }
    // used for fast lookups
    Map<String, Integer> activationRequests = new HashMap<String, Integer>();
    // order is important, preserve it
    ArrayList<URI> activationRequestsList = new ArrayList<URI>();
    // get CDB access daos
    DAOProxy dao = getManagerDAOProxy();
    DAOProxy componentsDAO = getComponentsDAOProxy();
    //
    if (dao != null && componentsDAO != null) {
        try {
            // query startup components
            String[] startup = dao.get_string_seq("Startup");
            final Integer managerHandle = new Integer(this.getHandle());
            for (int i = 0; i < startup.length; i++) {
                // TODO simulator test workaround
                if (startup[i].length() == 0)
                    continue;
                // read container field
                String containerName = readStringCharacteristics(componentsDAO, startup[i] + "/Container");
                if (containerName == null) {
                    logger.log(Level.WARNING, "Misconfigured CDB, there is no container of component '" + startup[i] + "' defined.");
                    continue;
                }
                // if container name matches, add activation request
                if (containerInfo.getName().equals(containerName)) {
                    try {
                        URI curl = CURLHelper.createURI(startup[i]);
                        // check CURL
                        try {
                            checkCURL(curl);
                        } catch (RuntimeException e) {
                            // @todo Auto-generated catch block
                            e.printStackTrace();
                        }
                        activationRequestsList.add(curl);
                        activationRequests.put(startup[i], managerHandle);
                    } catch (URISyntaxException usi) {
                        logger.log(Level.WARNING, "Failed to create URI from component name '" + startup[i] + "'.", usi);
                    }
                }
            }
        } catch (Throwable th) {
            logger.log(Level.WARNING, "Failed to retrieve list of startup components.", th);
        }
    }
    //
    // autostart components (<component>.Autostart attribute)
    //
    final String TRUE_STRING = "true";
    if (componentsDAO != null) {
        try {
            final Integer managerHandle = new Integer(this.getHandle());
            // get names of all components
            // TODO here to check if CDB is available
            componentsDAO.get_field_data("");
            /*String[] ids =*/
            String[] ids = getComponentsList();
            // test names
            for (int i = 0; i < ids.length; i++) {
                // read name
                //readStringCharacteristics(componentsDAO, ids[i]+"/Name");
                String name = ids[i];
                if (name == null) {
                    logger.log(Level.WARNING, "Misconfigured CDB, there is no name of component '" + ids[i] + "' defined.");
                    continue;
                }
                // read autostart silently
                String autostart = readStringCharacteristics(componentsDAO, ids[i] + "/Autostart", true);
                if (autostart == null) {
                    logger.log(Level.WARNING, "Misconfigured CDB, there is no autostart attribute of component '" + ids[i] + "' defined.");
                    continue;
                } else if (autostart.equalsIgnoreCase(TRUE_STRING) && !activationRequests.containsKey(name)) /* TODO to be removed */
                {
                    // read container silently
                    String componentContainer = readStringCharacteristics(componentsDAO, ids[i] + "/Container", true);
                    if (componentContainer == null) {
                        logger.log(Level.WARNING, "Misconfigured CDB, there is no container attribute of component '" + ids[i] + "' defined.");
                        continue;
                    } else if (!containerInfo.getName().equals(componentContainer))
                        continue;
                    try {
                        URI curl = CURLHelper.createURI(name);
                        // check CURL, no non-local curls
                        try {
                            checkCURL(curl, false);
                        } catch (RuntimeException e) {
                            reportException(e);
                        }
                        activationRequestsList.add(curl);
                        activationRequests.put(name, managerHandle);
                    } catch (URISyntaxException usi) {
                        logger.log(Level.WARNING, "Failed to create URI from component name '" + name + "'.", usi);
                    }
                }
            }
        } catch (Throwable ex) {
            logger.log(Level.WARNING, "Failed to retrieve list of components.", ex);
        }
    }
    // list of componentInfo to be cleaned up (cannot be immediately, due to lock)
    ArrayList<ComponentInfo> cleanupList = new ArrayList<ComponentInfo>();
    // check unavailable components
    if (unavailableComponents.size() > 0) {
        if (componentsDAO != null) {
            try {
                final Integer reactivateHandle = new Integer(0);
                synchronized (unavailableComponents) {
                    String[] names = unavailableComponents.keySet().toArray(new String[unavailableComponents.size()]);
                    // reverse
                    for (int i = names.length - 1; i >= 0; i--) {
                        String name = names[i];
                        boolean reactivate = false;
                        // dynamic component check
                        ComponentInfo componentInfo = unavailableComponents.get(name);
                        if (componentInfo != null && componentInfo.isDynamic() && componentInfo.getDynamicContainerName() != null && componentInfo.getDynamicContainerName().equals(containerInfo.getName())) {
                            // reactivate dynamic component
                            reactivate = true;
                        } else {
                            // read container field
                            String containerName = readStringCharacteristics(componentsDAO, name + "/Container");
                            if (containerName == null) {
                                logger.log(Level.WARNING, "Misconfigured CDB, there is no container of component '" + name + "' defined.");
                            //continue;
                            } else // if container name matches, add (override) activation request
                            if (containerInfo.getName().equals(containerName)) {
                                reactivate = true;
                            }
                        }
                        if (reactivate) {
                            // clean up if in non-recovery mode
                            if (!recoverContainer) {
                                // and if not already in activation list (startup component)
                                if (!activationRequests.containsKey(name)) {
                                    cleanupList.add(componentInfo);
                                    continue;
                                }
                            }
                            // this Component needs reactivation
                            if (activationRequests.containsKey(name)) {
                                activationRequests.put(name, reactivateHandle);
                            } else // put to activation list
                            {
                                try {
                                    activationRequestsList.add(CURLHelper.createURI(name));
                                    activationRequests.put(name, reactivateHandle);
                                } catch (URISyntaxException usi) {
                                    logger.log(Level.WARNING, "Failed to create URI from component name '" + name + "'.", usi);
                                }
                            }
                        }
                    }
                }
            } catch (Throwable ex) {
                CoreException ce = new CoreException("Failed to obtain component data from the CDB.", ex);
                reportException(ce);
            }
        }
    }
    if (cleanupList.size() > 0) {
        Iterator<ComponentInfo> iter = cleanupList.iterator();
        while (iter.hasNext()) {
            ComponentInfo componentInfo = iter.next();
            componentsLock.lock();
            try {
                // remove from its owners list ...
                int[] owners = componentInfo.getClients().toArray();
                for (int j = 0; j < owners.length; j++) removeComponentOwner(componentInfo.getHandle(), owners[j]);
                // ... and deallocate
                executeCommand(new ComponentCommandDeallocate(componentInfo.getHandle() & HANDLE_MASK, componentInfo.getHandle(), WhyUnloadedReason.REMOVED));
                executeCommand(new UnavailableComponentCommandRemove(componentInfo.getName()));
                // remove component from container component list
                synchronized (containerInfo.getComponents()) {
                    if (containerInfo.getComponents().contains(componentInfo.getHandle()))
                        executeCommand(new ContainerInfoCommandComponentRemove(containerInfo.getHandle() & HANDLE_MASK, componentInfo.getHandle()));
                }
            } finally {
                componentsLock.unlock();
            }
        // unbind from remote directory
        //unbind(convertToHiearachical(componentInfo.getName()), "O");
        }
    }
    logger.log(Level.INFO, "Container '" + containerInfo.getName() + "' startup statistics: " + activationRequestsList.size() + " components queued to be activated.");
    // send message to the container
    sendMessage(containerInfo.getContainer(), "Startup statistics: " + activationRequestsList.size() + " components queued to be activated.", MessageType.MSG_INFORMATION, ClientOperations.MSGID_AUTOLOAD_START);
    // activate startup components
    int activated = 0;
    StatusHolder status = new StatusHolder();
    Iterator<URI> iterator = activationRequestsList.iterator();
    while (iterator.hasNext()) {
        URI uri = iterator.next();
        try {
            String name = extractName(uri);
            int requestor = activationRequests.get(name);
            internalRequestComponent(requestor, uri, status);
            if (status.getStatus() != ComponentStatus.COMPONENT_ACTIVATED)
                logger.log(Level.WARNING, "Failed to activate autostart component '" + uri + "', reason: '" + status.getStatus() + "'.");
            else
                activated++;
        } catch (Throwable ex) {
            logger.log(Level.WARNING, "Failed to activate autostart component '" + uri + "'.", ex);
        }
    }
    logger.log(Level.INFO, "Container '" + containerInfo.getName() + "' startup statistics: " + activated + " of " + activationRequestsList.size() + " components activated.");
    // send message to the container
    sendMessage(containerInfo.getContainer(), "Startup statistics: " + activated + " of " + activationRequestsList.size() + " components activated.", MessageType.MSG_INFORMATION, ClientOperations.MSGID_AUTOLOAD_END);
    // notify about new container login
    synchronized (containerLoggedInMonitor) {
        containerLoggedInMonitor.notifyAll();
    }
}
Also used : LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) UnavailableComponentCommandRemove(com.cosylab.acs.maci.manager.recovery.UnavailableComponentCommandRemove) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) StatusHolder(com.cosylab.acs.maci.StatusHolder) ContainerInfoCommandComponentRemove(com.cosylab.acs.maci.manager.recovery.ContainerInfoCommandComponentRemove) DAOProxy(com.cosylab.cdb.client.DAOProxy) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CoreException(com.cosylab.acs.maci.CoreException) ComponentCommandDeallocate(com.cosylab.acs.maci.manager.recovery.ComponentCommandDeallocate) ComponentInfo(com.cosylab.acs.maci.ComponentInfo)

Example 2 with ComponentCommandDeallocate

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

the class ManagerImpl method internalNoSyncDeactivateComponent.

/**
	 * Deactivate component, issue deactivate reeust to container (or other manager).
	 * @param componentInfo	info about component to be deactivated.
	 */
private void internalNoSyncDeactivateComponent(ComponentInfo componentInfo) throws Throwable {
    // unbind from remote directory
    //unbind(convertToHiearachical(componentInfo.getName()), "O");
    int handle = componentInfo.getHandle() & HANDLE_MASK;
    int owners = componentInfo.getClients().size();
    try {
        //
        // get container/remote manager
        //
        String name = componentInfo.getName();
        boolean isOtherDomainComponent = name.startsWith(CURL_URI_SCHEMA);
        if (isOtherDomainComponent) {
            Manager remoteManager = null;
            // @todo MF do the login?
            try {
                String domainName = CURLHelper.createURI(name).getAuthority();
                remoteManager = getManagerForDomain(domainName);
                if (remoteManager == null)
                    throw new CoreException("Failed to obtain manager for domain '" + domainName + "'.");
            } catch (Throwable th) {
                logger.log(Level.WARNING, "Failed to obtain non-local manager required by component '" + name + "'.", th);
                throw th;
            }
            // release component
            try {
                URI curlName = CURLHelper.createURI(name);
                // @todo MF tmp (handle)
                remoteManager.releaseComponent(INTERDOMAIN_MANAGER_HANDLE, curlName);
            } catch (Throwable th) {
                logger.log(Level.WARNING, "Failed to release component '" + componentInfo.getName() + "' on remote manager.'", th);
                throw th;
            }
        } else {
            //
            // search for container by its name
            //
            Container container = null;
            ContainerInfo containerInfo = null;
            int containerHandle = componentInfo.getContainer();
            // if containerHandle equals 0, we have unavailable or registered component
            if (containerHandle != 0) {
                containerInfo = getContainerInfo(containerHandle);
                if (containerInfo != null) {
                    // remove component from container component list
                    synchronized (containerInfo.getComponents()) {
                        // !!! ACID
                        if (containerInfo.getComponents().contains(componentInfo.getHandle()))
                            executeCommand(new ContainerInfoCommandComponentRemove(containerInfo.getHandle() & HANDLE_MASK, componentInfo.getHandle()));
                    //containerInfo.getComponents().remove(componentInfo.getHandle());
                    }
                    // we allow this (since releasing components is part of container shutdown procedure)
                    //checkContainerState(containerInfo);
                    container = containerInfo.getContainer();
                }
                // required container is not logged in
                if (container == null) {
                    // then simply do not do the deactivation
                    String containerName;
                    if (containerInfo != null)
                        containerName = containerInfo.getName();
                    else
                        containerName = HandleHelper.toString(componentInfo.getContainer());
                    logger.log(Level.WARNING, "Container '" + containerName + "' required by component '" + componentInfo.getName() + "' is not logged in.");
                }
            }
            if (container != null) {
                // log info
                logger.log(Level.INFO, "Deactivating component '" + componentInfo.getName() + "' (" + HandleHelper.toString(componentInfo.getHandle()) + ") on container '" + containerInfo.getName() + "'.");
                // destruct
                try {
                    componentInfo.getComponent().destruct();
                } catch (Throwable ex) {
                    RemoteException re = new RemoteException("Failed to destruct component '" + componentInfo.getName() + "', exception caught when invoking 'destruct()' method.", ex);
                    logger.log(Level.SEVERE, re.getMessage(), re);
                    throw ex;
                }
                long deactivationTime = 0;
                // deactivate component in anycase
                try {
                    container.deactivate_component(componentInfo.getHandle());
                    deactivationTime = System.currentTimeMillis();
                } catch (AcsJException aex) {
                    logger.log(Level.SEVERE, aex.getMessage(), aex);
                    throw aex;
                } catch (Throwable ex) {
                    RemoteException re = new RemoteException("Failed to deactivate component '" + componentInfo.getName() + "' (" + HandleHelper.toString(componentInfo.getHandle()) + ") on container '" + containerInfo.getName() + "'.", ex);
                    logger.log(Level.SEVERE, re.getMessage(), re);
                    throw ex;
                }
                // notify administrators about deactivation, but not if failed
                if (deactivationTime != 0)
                    notifyComponentDeactivated(componentInfo.getHandle(), deactivationTime);
                // shutdown container if required (and necessary)
                conditionalShutdownContainer(containerInfo);
            }
        }
    } finally {
        if (owners == 0) {
            // deallocate Component
            componentsLock.lock();
            try {
                executeCommand(new ComponentCommandDeallocate(handle, componentInfo.getHandle(), WhyUnloadedReason.REMOVED));
            //components.deallocate(handle);
            } finally {
                componentsLock.unlock();
            }
        }
    }
    // log info
    logger.log(Level.INFO, "Component '" + componentInfo.getName() + "' (" + HandleHelper.toString(componentInfo.getHandle()) + ") deactivated.");
    // release all subcomponents (just like client logoff)
    // component should have already done this by itself, but take care of clean cleanup
    // what about that: if subcomponent becomes unavailable, does component also becomes?!
    // no, it is notified and it handles situation by its own way (e.g. changes component state).
    // Just like it already handles activation (manager does not care for dependecy trees).
    int[] subcomponents = null;
    // no not hold the lock
    synchronized (componentInfo.getComponents()) {
        if (componentInfo.getComponents().size() > 0) {
            IntArray toCleanupList = new IntArray();
            IntArray comps = componentInfo.getComponents();
            for (int i = 0; i < comps.size(); i++) if (components.isAllocated(comps.get(i) & HANDLE_MASK))
                toCleanupList.add(comps.get(i));
            if (toCleanupList.size() > 0)
                subcomponents = toCleanupList.toArray();
        }
    //subcomponents = componentInfo.getComponents().toArray();
    }
    if (subcomponents != null && subcomponents.length > 0)
        new ReleaseComponentTask(componentInfo.getHandle(), subcomponents).run();
    // make unavailable (deactivation was forced)
    if (owners > 0)
        makeUnavailable(componentInfo);
}
Also used : AcsJException(alma.acs.exceptions.AcsJException) Manager(com.cosylab.acs.maci.Manager) URI(java.net.URI) Container(com.cosylab.acs.maci.Container) CoreException(com.cosylab.acs.maci.CoreException) IntArray(com.cosylab.acs.maci.IntArray) ContainerInfoCommandComponentRemove(com.cosylab.acs.maci.manager.recovery.ContainerInfoCommandComponentRemove) ComponentCommandDeallocate(com.cosylab.acs.maci.manager.recovery.ComponentCommandDeallocate) ContainerInfo(com.cosylab.acs.maci.ContainerInfo) RemoteException(com.cosylab.acs.maci.RemoteException) TimeoutRemoteException(com.cosylab.acs.maci.TimeoutRemoteException)

Example 3 with ComponentCommandDeallocate

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

the class ManagerImpl method internalNoSyncRequestComponentPhase2.

private ComponentInfo internalNoSyncRequestComponentPhase2(int requestor, String name, String type, String code, String containerName, int keepAliveTime, StatusHolder status, AcsJCannotGetComponentEx bcex, boolean isOtherDomainComponent, boolean isDynamicComponent, int h, boolean reactivate, ComponentInfo componentInfo, Container container, ContainerInfo containerInfo, long executionId, long activationTime, boolean timeoutError) throws AcsJCannotGetComponentEx {
    // remove component from client component list, will be added later (first lots of checks has to be done)
    if ((requestor & TYPE_MASK) == COMPONENT_MASK) {
        removeComponentOwner(h | COMPONENT_MASK, requestor);
    }
    // remove from pending activation list
    synchronized (pendingActivations) {
        pendingActivations.remove(name);
    }
    // failed to activate
    if (componentInfo == null || componentInfo.getHandle() == 0 || componentInfo.getComponent() == null) {
        if (bcex == null)
            logger.log(Level.SEVERE, "Failed to activate component '" + name + "' (" + HandleHelper.toString(h | COMPONENT_MASK) + ").");
        else
            bcex.setReason("Failed to activate component '" + name + "' (" + HandleHelper.toString(h | COMPONENT_MASK) + ").");
        componentsLock.lock();
        try {
            // !!! ACID 3
            if (!reactivate)
                executeCommand(new ComponentCommandDeallocate(h, h | COMPONENT_MASK, timeoutError ? WhyUnloadedReason.TIMEOUT : WhyUnloadedReason.REMOVED, true));
        //components.deallocate(h, true);
        } finally {
            componentsLock.unlock();
        }
        status.setStatus(ComponentStatus.COMPONENT_NOT_ACTIVATED);
        if (bcex == null)
            return null;
        else
            throw bcex;
    }
    // log info
    logger.log(Level.INFO, "Component '" + name + "' (" + HandleHelper.toString(h | COMPONENT_MASK) + ") activated successfully.");
    //
    if (!isOtherDomainComponent && !componentInfo.getComponent().doesImplement(type)) {
        // just output SEVERE message
        logger.log(Level.SEVERE, "Activated component '" + name + "' does not implement specified type '" + type + "'.");
    }
    // component info (to get type and code, container - prefix name)
    if (isOtherDomainComponent) {
        // @todo MF tmp (for testing)
        componentInfo.setHandle(h | COMPONENT_MASK);
        componentInfo.setClients(new IntArray());
        componentInfo.setComponents(new IntArray(0));
        componentInfo.setContainer(0);
        // set variables
        type = componentInfo.getType();
        code = componentInfo.getCode();
    }
    int[] clients;
    componentsLock.lock();
    try {
        //
        if (componentInfo.getHandle() != (h | COMPONENT_MASK)) {
            // container returned different handle
            // (it seems it has already activated this Component)
            // check if we can accept it
            int componentHandle = componentInfo.getHandle() & HANDLE_MASK;
            if (components.isAllocated(componentHandle)) {
                // cancel preallocation
                if (!reactivate)
                    executeCommand(new ComponentCommandDeallocate(h, componentInfo.getHandle(), WhyUnloadedReason.REMOVED, true));
                //components.deallocate(h, true);
                bcex = new AcsJCannotGetComponentEx();
                bcex.setReason("Container '" + containerName + "' returned another '" + name + "' component handle than given, failed to fix handle since returned handle is already allocated.");
                // log this anyway, since it's an error of a global nature
                logger.log(Level.SEVERE, "Container '" + containerName + "' returned another '" + name + "' component handle than given, failed to fix handle since returned handle is already allocated.", bcex);
                // component is activated, but cannot be managed by the Manager
                status.setStatus(ComponentStatus.COMPONENT_ACTIVATED);
                throw bcex;
            } else {
                // handle is free, relocate handle
                ComponentInfo existingData = null;
                // deallocate old
                if (!reactivate)
                    executeCommand(new ComponentCommandDeallocate(h, componentInfo.getHandle(), WhyUnloadedReason.REPLACED, true));
                else //components.deallocate(h, true);
                {
                    // !!! ACID 3
                    existingData = (ComponentInfo) components.get(h);
                    executeCommand(new ComponentCommandDeallocate(h, componentInfo.getHandle(), WhyUnloadedReason.REPLACED));
                //components.deallocate(h);
                }
                // !!! ACID 3
                // preallocate new
                Integer objHandle = (Integer) executeCommand(new ComponentCommandAllocateHandle(componentHandle, true));
                //h = components.allocate(componentHandle, true);
                if (objHandle == null || (h = objHandle.intValue()) == 0) {
                    // failed to allocate new
                    bcex = new AcsJCannotGetComponentEx();
                    bcex.setReason("Container '" + containerName + "' returned another '" + name + "' component handle than given, failed to fix handle due to handle relocation failure.");
                    // log this anyway, since it's an error of a global nature
                    logger.log(Level.SEVERE, "Container '" + containerName + "' returned another '" + name + "' component handle than given, failed to fix handle due to handle relocation failure.", bcex);
                    // Component is activated, but cannot be managed by the Manager
                    status.setStatus(ComponentStatus.COMPONENT_ACTIVATED);
                    throw bcex;
                } else // !!! ACID 3
                if (existingData != null)
                    executeCommand(new ComponentCommandSet(h, existingData));
                //components.set(h, existingData);
                logger.log(Level.WARNING, "Container '" + containerName + "' returned another '" + name + "' component handle than given, handle fixed.");
            }
        }
        //
        // pre-store data
        //
        ComponentInfo existingData = (ComponentInfo) components.get(h);
        // create a new ComponentInfo - do not trust containers
        ComponentInfo data = new ComponentInfo(componentInfo.getHandle(), name, type, code, componentInfo.getComponent());
        if (existingData != null) {
            data.setClients(existingData.getClients());
            data.setComponents(existingData.getComponents());
        }
        if (requestor != 0)
            if (// hierarchical components need this check
            !data.getClients().contains(requestor))
                data.getClients().add(requestor);
        if (keepAliveTime <= RELEASE_NEVER)
            if (// make component immortal
            !data.getClients().contains(this.getHandle()))
                data.getClients().add(this.getHandle());
        // remember keep alive time
        data.setKeepAliveTime(keepAliveTime);
        if (isOtherDomainComponent) {
            data.setContainer(0);
            data.setContainerName(componentInfo.getContainerName());
        } else {
            data.setContainer(containerInfo.getHandle());
            data.setContainerName(containerInfo.getName());
        }
        data.setAccessRights(0);
        data.setInterfaces(componentInfo.getInterfaces());
        // mark as dynamic component and store its container
        if (isDynamicComponent) {
            data.setDynamic(true);
            data.setDynamicContainerName(containerName);
        }
        // !!! ACID
        executeCommand(new ComponentCommandSet(h, data));
        // acknowledge allocation
        if (!reactivate)
            // !!! ACID 2
            executeCommand(new ComponentCommandAckAlloc(h));
        //components.ackAllocation(h);
        componentInfo = data;
        clients = componentInfo.getClients().toArray();
    } finally {
        componentsLock.unlock();
    }
    if (!isOtherDomainComponent) {
        // add component to client component list to allow dependency checks
        if ((requestor & TYPE_MASK) == COMPONENT_MASK)
            addComponentOwner(componentInfo.getHandle(), requestor);
        //
        // call construct
        //
        boolean constructed = false;
        try {
            componentInfo.getComponent().construct();
            constructed = true;
        } catch (Throwable ex) {
            bcex = new AcsJCannotGetComponentEx(ex);
            bcex.setReason("Failed to construct component '" + name + "', exception caught when invoking 'construct()' method.");
        }
        // remove component from client component list, will be added later
        if ((requestor & TYPE_MASK) == COMPONENT_MASK)
            removeComponentOwner(componentInfo.getHandle(), requestor);
        if (!constructed) {
            // release Component
            componentsLock.lock();
            try {
                // !!! ACID 3
                if (!reactivate)
                    executeCommand(new ComponentCommandDeallocate(h, componentInfo.getHandle(), WhyUnloadedReason.REMOVED));
                // deactivate
                try {
                    container.deactivate_component(componentInfo.getHandle());
                } catch (Exception ex) {
                    bcex = new AcsJCannotGetComponentEx(ex);
                    bcex.setReason("Failed to deactivate component '" + name + "' on container '" + containerName + "'.");
                }
                status.setStatus(ComponentStatus.COMPONENT_NOT_ACTIVATED);
                throw bcex;
            } finally {
                componentsLock.unlock();
            }
        }
    }
    // add component to client component list
    if (requestor != this.getHandle() && requestor != 0)
        addComponentOwner(componentInfo.getHandle(), requestor);
    // add component to container component list
    if (!isOtherDomainComponent)
        synchronized (containerInfo.getComponents()) {
            if (!containerInfo.getComponents().contains(componentInfo.getHandle()))
                executeCommand(new ContainerInfoCommandComponentAdd(containerInfo.getHandle() & HANDLE_MASK, componentInfo.getHandle()));
        //containerInfo.getComponents().add(componentInfo.getHandle());
        }
    // remove component from unavailable list
    if (reactivate) {
        synchronized (unavailableComponents) {
            executeCommand(new UnavailableComponentCommandRemove(name));
        //unavailableComponents.remove(name);
        }
    }
    //
    if (!isOtherDomainComponent)
        notifyComponentActivated(componentInfo, activationTime, executionId);
    //
    if (reactivate) {
        notifyComponentAvailable(requestor, clients, new ComponentInfo[] { componentInfo });
    }
    //
    // notify administrators about the activation
    //
    notifyComponentRequested(new int[] { requestor }, new int[] { componentInfo.getHandle() }, activationTime);
    if (reactivate)
        logger.log(Level.FINE, "Component '" + name + "' (" + HandleHelper.toString(componentInfo.getHandle()) + ") reactivated.");
    else
        logger.log(Level.FINE, "Component '" + name + "' (" + HandleHelper.toString(componentInfo.getHandle()) + ") activated.");
    // notify about the change (only this-domain container which activated the component)...
    if (containerInfo != null)
        topologySortManager.notifyTopologyChange(containerInfo.getHandle());
    status.setStatus(ComponentStatus.COMPONENT_ACTIVATED);
    return componentInfo;
}
Also used : ComponentCommandAllocateHandle(com.cosylab.acs.maci.manager.recovery.ComponentCommandAllocateHandle) UnavailableComponentCommandRemove(com.cosylab.acs.maci.manager.recovery.UnavailableComponentCommandRemove) AcsJCannotGetComponentEx(alma.maciErrType.wrappers.AcsJCannotGetComponentEx) ComponentCommandAckAlloc(com.cosylab.acs.maci.manager.recovery.ComponentCommandAckAlloc) AcsJException(alma.acs.exceptions.AcsJException) NoDefaultComponentException(com.cosylab.acs.maci.NoDefaultComponentException) RemoteTransientException(com.cosylab.acs.maci.RemoteTransientException) NameNotFoundException(javax.naming.NameNotFoundException) NameAlreadyBoundException(javax.naming.NameAlreadyBoundException) IOException(java.io.IOException) NoResourcesException(com.cosylab.acs.maci.NoResourcesException) URISyntaxException(java.net.URISyntaxException) NamingException(javax.naming.NamingException) BadParametersException(com.cosylab.acs.maci.BadParametersException) CoreException(com.cosylab.acs.maci.CoreException) RemoteException(com.cosylab.acs.maci.RemoteException) TimeoutRemoteException(com.cosylab.acs.maci.TimeoutRemoteException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ContainerInfoCommandComponentAdd(com.cosylab.acs.maci.manager.recovery.ContainerInfoCommandComponentAdd) IntArray(com.cosylab.acs.maci.IntArray) ComponentCommandDeallocate(com.cosylab.acs.maci.manager.recovery.ComponentCommandDeallocate) ComponentCommandSet(com.cosylab.acs.maci.manager.recovery.ComponentCommandSet) ComponentInfo(com.cosylab.acs.maci.ComponentInfo)

Example 4 with ComponentCommandDeallocate

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

the class ManagerImpl method containerInternalStateMerge.

/**
	 * Retrieve container's internal state and merge it with manager's.
	 * NOTE: this method should not be run in separate thread since states
	 * should be merged synchronously.
	 * Merge is split to two parts:
	 *
	 * <h2>Container -> Manager</h2>
	 *
	 * If container component handle is also allocated in manager state and components information match,
	 * then we have a perfect fit and no action is required. If they do not match, container is rejected.
	 * If container component handle is not allocated in the manager state and no component with
	 * same name is found in manager state, component information is transferred to the manager,
	 * owtherwise container is rejected.
	 * <p>
	 * NOTE: The second option allows components without owners to be activated.
	 * </p>
	 * <p>
	 * NOTE: Container is rejected due to its state inconsistency which will probably cause
	 * problems in the future. Container has to be restarted.<br/>
	 * (A more sophisticated algorithm could give manager "the power to shape up" container state.)
	 * </p>
	 * <p>
	 * NOTE: Container -> Manager has to work in the way transactions do, i.e. in case of rejection
	 * manager state should no be affected.
	 * </p>
	 *
	 * <h2>Manager -> Container</h2>
	 *
	 * If <code>recoverContainer</code> is <code>true</code>, all components known to the manager to
	 * be activated on this particular container and listed as activated by the container
	 * will be marked as unavailable to be reactivated later by
	 * <code>containerPostLoginActivation</code> method.
	 * If <code>recoverContainer</code> is <code>false</code>, all there information will be discared
	 * (components removed from container component list, deallocated, and removed from their owners list).
	 *
	 * @param	containerInfo	container info for which to perform merge, non-<code>null</code>.
	 * @param	recoverContainer	if <code>true</code> manager state will be 'transferred' to container.
	 */
private void containerInternalStateMerge(ContainerInfo containerInfo, boolean recoverContainer) throws AcsJNoPermissionEx {
    assert (containerInfo != null);
    // firstly, query containers state
    ComponentInfo[] infos = null;
    try {
        infos = containerInfo.getContainer().get_component_info(new int[0]);
    } catch (Throwable ex) {
        logger.log(Level.SEVERE, "Failed to query state of container '" + containerInfo.getName() + "'.", ex);
    }
    boolean requireTopologySort = false;
    // copy elements
    IntArray managerContainersComponents;
    synchronized (containerInfo.getComponents()) {
        managerContainersComponents = new IntArray(containerInfo.getComponents().toArray());
    }
    if (infos != null && infos.length > 0) {
        componentsLock.lock();
        try {
            // phase 1: check for state consistency
            for (int i = 0; i < infos.length; i++) {
                // check if info is valid
                if (infos[i].getHandle() == 0 || (infos[i].getHandle() & COMPONENT_MASK) != COMPONENT_MASK || infos[i].getName() == null || infos[i].getType() == null || infos[i].getCode() == null || infos[i].getComponent() == null || infos[i].getContainer() == 0 || infos[i].getInterfaces() == null) {
                    // bad info
                    // NO_PERMISSION
                    AcsJNoPermissionEx npe = new AcsJNoPermissionEx();
                    npe.setReason("Inconsistent container state - component information is not valid, rejecting container.");
                    npe.setID(containerInfo.getName());
                    npe.setProtectedResource(infos[i].getName());
                    throw npe;
                }
                int handle = infos[i].getHandle() & HANDLE_MASK;
                if (components.isAllocated(handle)) {
                    // handle is allocated
                    // check if components information match
                    ComponentInfo componentInfo = (ComponentInfo) components.get(handle);
                    if (componentInfo == null || componentInfo.getHandle() != infos[i].getHandle() || !componentInfo.getName().equals(infos[i].getName()) || (componentInfo.getContainer() != 0 && componentInfo.getContainer() != infos[i].getContainer())) {
                        // information does not match, reject container
                        // NO_PERMISSION
                        AcsJNoPermissionEx npe = new AcsJNoPermissionEx();
                        npe.setReason("Inconsistent container state - components information do not match, rejecting container.");
                        npe.setID(containerInfo.getName());
                        if (componentInfo != null) {
                            npe.setProtectedResource(componentInfo.getName());
                        }
                        throw npe;
                    }
                } else {
                    // handle is not allocated
                    // check if component with same name is already registered
                    int h = components.first();
                    while (h != 0) {
                        ComponentInfo componentInfo = (ComponentInfo) components.get(h);
                        if (componentInfo.getName().equals(infos[i].getName())) {
                            // yes it does, reject container
                            // NO_PERMISSION
                            AcsJNoPermissionEx npe = new AcsJNoPermissionEx();
                            npe.setReason("Inconsistent container state - component with name '" + componentInfo.getName() + "' already registered with different handle, rejecting container.");
                            npe.setID(containerInfo.getName());
                            npe.setProtectedResource(componentInfo.getName());
                            throw npe;
                        }
                        h = components.next(h);
                    }
                }
            }
            // phase 2: do the transfer
            for (int i = 0; i < infos.length; i++) {
                int handle = infos[i].getHandle() & HANDLE_MASK;
                if (components.isAllocated(handle)) {
                    // handle is allocated and info match
                    // just in case component is not persistent, update the reference
                    // is always non-null - checked already above
                    ComponentInfo componentInfo = (ComponentInfo) components.get(handle);
                    componentInfo.setComponent(infos[i].getComponent());
                    componentInfo.setContainer(infos[i].getContainer());
                    componentInfo.setContainerName(infos[i].getContainerName());
                    // remove if unavailable and notify
                    synchronized (unavailableComponents) {
                        // !!! ACID 3
                        executeCommand(new UnavailableComponentCommandRemove(componentInfo.getName()));
                    //unavailableComponents.remove(componentInfo.getName());
                    }
                    int[] clients = componentInfo.getClients().toArray();
                    notifyComponentAvailable(0, clients, new ComponentInfo[] { componentInfo });
                } else {
                    // handle is not allocated
                    // transfer component
                    // create new ComponentInfo (we do not trust containers)
                    ComponentInfo info = new ComponentInfo(infos[i].getHandle(), infos[i].getName(), infos[i].getType(), infos[i].getCode(), infos[i].getComponent());
                    info.setContainer(infos[i].getContainer());
                    info.setContainerName(infos[i].getContainerName());
                    info.setInterfaces(infos[i].getInterfaces());
                    info.setAccessRights(0);
                    // if it has a CDB entry or if there is no CDB available
                    if (!hasCDBEntry(info)) {
                        info.setDynamic(true);
                        info.setDynamicContainerName(containerInfo.getName());
                    }
                    // !!! ACID 3
                    // allocate and store
                    executeCommand(new ComponentCommandAllocateHandle(handle));
                    //components.allocate(handle);
                    executeCommand(new ComponentCommandSet(handle, info));
                    //components.set(handle, info);
                    requireTopologySort = true;
                }
                // we handled this component
                managerContainersComponents.remove(infos[i].getHandle());
                // add to container component list
                synchronized (containerInfo.getComponents()) {
                    // !!! ACID 3
                    if (!containerInfo.getComponents().contains(infos[i].getHandle()))
                        executeCommand(new ContainerInfoCommandComponentAdd(containerInfo.getHandle() & HANDLE_MASK, infos[i].getHandle()));
                //containerInfo.getComponents().add(infos[i].getHandle());
                }
            }
        } finally {
            componentsLock.unlock();
        }
    }
    // managerContainersComponents contains component handles not handled yet
    for (int i = 0; i < managerContainersComponents.size(); i++) {
        int componentHandle = managerContainersComponents.get(i);
        // remove component handle from container component list
        // will be added when actually activated
        // !!! ACID 3
        executeCommand(new ContainerInfoCommandComponentRemove(containerInfo.getHandle() & HANDLE_MASK, componentHandle));
        //containerInfo.getComponents().remove(componentHandle);
        // marked as unavailable to be reactivated later (or discarded)
        componentsLock.lock();
        try {
            int handle = componentHandle & HANDLE_MASK;
            if (components.isAllocated(handle)) {
                ComponentInfo componentInfo = (ComponentInfo) components.get(handle);
                // what if null (very not likely to happen, but possible)
                if (componentInfo == null) {
                    // internal error, this should not happen
                    logger.log(Level.SEVERE, "Internal state is not consistent (no ComponentInfo).");
                    continue;
                }
                // notify component owners about Component deactivation
                makeUnavailable(componentInfo);
                if (!recoverContainer) {
                    // discard all Component information
                    // remove from its owners list ...
                    int[] owners = componentInfo.getClients().toArray();
                    for (int j = 0; j < owners.length; j++) removeComponentOwner(componentHandle, owners[j]);
                    // !!! ACID 3
                    // ... and deallocate
                    executeCommand(new ComponentCommandDeallocate(handle, componentInfo.getHandle(), WhyUnloadedReason.REMOVED));
                    //components.deallocate(handle);
                    requireTopologySort = true;
                }
            } else {
                // internal error, this should not happen
                logger.log(Level.SEVERE, "Internal state is not consistent.");
            }
        } finally {
            componentsLock.unlock();
        }
    }
    if (requireTopologySort)
        topologySortManager.notifyTopologyChange(containerInfo.getHandle());
}
Also used : ComponentCommandAllocateHandle(com.cosylab.acs.maci.manager.recovery.ComponentCommandAllocateHandle) UnavailableComponentCommandRemove(com.cosylab.acs.maci.manager.recovery.UnavailableComponentCommandRemove) ContainerInfoCommandComponentAdd(com.cosylab.acs.maci.manager.recovery.ContainerInfoCommandComponentAdd) IntArray(com.cosylab.acs.maci.IntArray) AcsJNoPermissionEx(alma.maciErrType.wrappers.AcsJNoPermissionEx) ContainerInfoCommandComponentRemove(com.cosylab.acs.maci.manager.recovery.ContainerInfoCommandComponentRemove) ComponentCommandDeallocate(com.cosylab.acs.maci.manager.recovery.ComponentCommandDeallocate) ComponentCommandSet(com.cosylab.acs.maci.manager.recovery.ComponentCommandSet) ComponentInfo(com.cosylab.acs.maci.ComponentInfo)

Aggregations

ComponentCommandDeallocate (com.cosylab.acs.maci.manager.recovery.ComponentCommandDeallocate)4 ComponentInfo (com.cosylab.acs.maci.ComponentInfo)3 CoreException (com.cosylab.acs.maci.CoreException)3 IntArray (com.cosylab.acs.maci.IntArray)3 ContainerInfoCommandComponentRemove (com.cosylab.acs.maci.manager.recovery.ContainerInfoCommandComponentRemove)3 UnavailableComponentCommandRemove (com.cosylab.acs.maci.manager.recovery.UnavailableComponentCommandRemove)3 AcsJException (alma.acs.exceptions.AcsJException)2 RemoteException (com.cosylab.acs.maci.RemoteException)2 TimeoutRemoteException (com.cosylab.acs.maci.TimeoutRemoteException)2 ComponentCommandAllocateHandle (com.cosylab.acs.maci.manager.recovery.ComponentCommandAllocateHandle)2 ComponentCommandSet (com.cosylab.acs.maci.manager.recovery.ComponentCommandSet)2 ContainerInfoCommandComponentAdd (com.cosylab.acs.maci.manager.recovery.ContainerInfoCommandComponentAdd)2 URI (java.net.URI)2 URISyntaxException (java.net.URISyntaxException)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 AcsJCannotGetComponentEx (alma.maciErrType.wrappers.AcsJCannotGetComponentEx)1 AcsJNoPermissionEx (alma.maciErrType.wrappers.AcsJNoPermissionEx)1 BadParametersException (com.cosylab.acs.maci.BadParametersException)1 Container (com.cosylab.acs.maci.Container)1 ContainerInfo (com.cosylab.acs.maci.ContainerInfo)1