Search in sources :

Example 1 with ComponentCommandPreallocate

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

the class ManagerImpl method internalNoSyncRequestComponent.

/**
	 * Internal method for requesting components (non sync).
	 * @param	requestor		requestor of the component.
	 * @param	name			name of component to be requested, non-<code>null</code>.
	 * @param	type			type of component to be requested; if <code>null</code> CDB will be queried.
	 * @param	code			code of component to be requested; if <code>null</code> CDB will be queried.
	 * @param	containerName	container name of component to be requested; if <code>null</code> CDB will be queried.
	 * @param	status			returned completion status of the request.
	 * @param	activate		<code>true</code> if component has to be activated
	 * @return	componentInfo	<code>ComponentInfo</code> of requested component.
	 */
private ComponentInfo internalNoSyncRequestComponent(int requestor, String name, String type, String code, String containerName, int keepAliveTime, StatusHolder status, boolean activate) throws AcsJCannotGetComponentEx, AcsJComponentSpecIncompatibleWithActiveComponentEx {
    AcsJCannotGetComponentEx bcex = null;
    if (name == null) {
        bcex = new AcsJCannotGetComponentEx();
        bcex.setReason("Cannot activate component with NULL name.");
        throw bcex;
    }
    if (status == null) {
        bcex = new AcsJCannotGetComponentEx();
        bcex.setReason("Component " + name + " has NULL status.");
        throw bcex;
    }
    boolean isOtherDomainComponent = name.startsWith(CURL_URI_SCHEMA);
    boolean isDynamicComponent = isOtherDomainComponent ? false : (type != null || code != null || containerName != null);
    //
    // check if component is already activated
    //
    int h;
    // if true, component with handle h will be reactivated
    boolean reactivate = false;
    ComponentInfo componentInfo = null;
    componentsLock.lock();
    try {
        h = components.first();
        while (h != 0) {
            componentInfo = (ComponentInfo) components.get(h);
            if (componentInfo.getName().equals(name)) {
                // check if component is unavailable
                synchronized (unavailableComponents) {
                    if (unavailableComponents.containsKey(name)) {
                        // try to reactivate, possible component reallocation
                        reactivate = true;
                    }
                }
                // check for consistency
                ContainerInfo containerInfo = getContainerInfo(componentInfo.getContainer());
                if ((type != null && !componentInfo.getType().equals(type)) || (code != null && componentInfo.getCode() != null && !componentInfo.getCode().equals(code)) || (!reactivate && containerInfo != null && containerName != null && !containerInfo.getName().equals(containerName))) {
                    AcsJComponentSpecIncompatibleWithActiveComponentEx ciwace = new AcsJComponentSpecIncompatibleWithActiveComponentEx();
                    ciwace.setCURL(componentInfo.getName());
                    ciwace.setComponentType(componentInfo.getType());
                    ciwace.setComponentCode(componentInfo.getCode() != null ? componentInfo.getCode() : "<unknown>");
                    ciwace.setContainerName(containerInfo != null ? containerInfo.getName() : "<none>");
                    throw ciwace;
                }
                if (activate) {
                    // bail out and reactivate
                    if (reactivate)
                        break;
                    // add client/component as an owner (if requestor is not 'reactivation')
                    if (requestor != 0) {
                        // !!! ACID
                        if (!componentInfo.getClients().contains(requestor))
                            executeCommand(new ComponentCommandClientAdd(componentInfo.getHandle() & HANDLE_MASK, requestor));
                    //componentInfo.getClients().add(requestor);
                    }
                    // add component to client component list (if requestor is not manager or 'reactivation')
                    if (requestor != this.getHandle() && requestor != 0)
                        addComponentOwner(componentInfo.getHandle(), requestor);
                    // inform administrators about component request
                    notifyComponentRequested(new int[] { requestor }, new int[] { componentInfo.getHandle() }, System.currentTimeMillis());
                    // on complete system shutdown sort will be done anyway
                    if ((requestor & TYPE_MASK) == COMPONENT_MASK) {
                        ComponentInfo requestorComponentInfo = getComponentInfo(requestor);
                        if (requestorComponentInfo != null && requestorComponentInfo.getContainerName() != null && requestorComponentInfo.getContainerName().equals(componentInfo.getContainerName()))
                            topologySortManager.notifyTopologyChange(componentInfo.getContainer());
                    }
                    // return info
                    status.setStatus(ComponentStatus.COMPONENT_ACTIVATED);
                    return componentInfo;
                } else {
                    if (reactivate)
                        status.setStatus(ComponentStatus.COMPONENT_NOT_ACTIVATED);
                    else
                        status.setStatus(ComponentStatus.COMPONENT_ACTIVATED);
                    return componentInfo;
                }
            }
            h = components.next(h);
        }
    } finally {
        componentsLock.unlock();
    }
    // and do not touch CDB
    if (reactivate && componentInfo.isDynamic()) {
        if (componentInfo.getType() == null || componentInfo.getCode() == null || componentInfo.getDynamicContainerName() == null) {
            // failed
            bcex = new AcsJCannotGetComponentEx();
            bcex.setReason("Failed to reactivate dynamic component '" + componentInfo + "'.");
            status.setStatus(ComponentStatus.COMPONENT_DOES_NO_EXIST);
            throw bcex;
        } else {
            // reread info
            type = componentInfo.getType();
            code = componentInfo.getCode();
            containerName = componentInfo.getDynamicContainerName();
            keepAliveTime = componentInfo.getKeepAliveTime();
        }
    } else // is CDB lookup needed
    if (!isOtherDomainComponent && (type == null || code == null || containerName == null)) {
        //
        // read component info from CDB / remote directory lookup
        //
        DAOProxy dao = getComponentsDAOProxy();
        if (dao == null || readStringCharacteristics(dao, name, true) == null) {
            // component with this name does not exists,
            // make a remote directory lookup
            Object ref = lookup(name, null);
            if (ref != null) {
                // found
                status.setStatus(ComponentStatus.COMPONENT_ACTIVATED);
                return new ComponentInfo(0, name, null, null, new ServiceComponent(ref));
            } else {
                // not found
                bcex = new AcsJCannotGetComponentEx();
                bcex.setReason("Component " + name + " not found in CDB.");
                status.setStatus(ComponentStatus.COMPONENT_DOES_NO_EXIST);
                throw bcex;
            }
        }
        if (code == null) {
            code = readStringCharacteristics(dao, name + "/Code");
            if (code == null) {
                bcex = new AcsJCannotGetComponentEx();
                bcex.setReason("Misconfigured CDB, there is no code of component '" + name + "' defined.");
                status.setStatus(ComponentStatus.COMPONENT_DOES_NO_EXIST);
                throw bcex;
            }
        }
        if (type == null) {
            type = readStringCharacteristics(dao, name + "/Type");
            if (type == null) {
                bcex = new AcsJCannotGetComponentEx();
                bcex.setReason("Misconfigured CDB, there is no type of component '" + name + "' defined.");
                status.setStatus(ComponentStatus.COMPONENT_DOES_NO_EXIST);
                throw bcex;
            }
        }
        if (containerName == null) {
            containerName = readStringCharacteristics(dao, name + "/Container");
            if (containerName == null) {
                bcex = new AcsJCannotGetComponentEx();
                bcex.setReason("Misconfigured CDB, there is no container of component '" + name + "' defined.");
                status.setStatus(ComponentStatus.COMPONENT_DOES_NO_EXIST);
                throw bcex;
            }
        }
        if (keepAliveTime == RELEASE_TIME_UNDEFINED) {
            // defaults to 0 == RELEASE_IMMEDIATELY
            keepAliveTime = readLongCharacteristics(dao, name + "/KeepAliveTime", RELEASE_IMMEDIATELY, true);
        }
    }
    // we have keepAlive missing, try to get it
    if (keepAliveTime == RELEASE_TIME_UNDEFINED) {
        DAOProxy dao = getComponentsDAOProxy();
        if (dao != null) {
            // defaults to 0 == RELEASE_IMMEDIATELY
            keepAliveTime = readLongCharacteristics(dao, name + "/KeepAliveTime", RELEASE_IMMEDIATELY, true);
        } else {
            // this is a case where all data for dynamic component is specified and there is not entry in CDB
            keepAliveTime = RELEASE_IMMEDIATELY;
        }
    }
    // read impl. language.
    DAOProxy dao = getComponentsDAOProxy();
    String componentImplLang = null;
    if (dao != null) {
        // silent read
        componentImplLang = readStringCharacteristics(dao, name + "/ImplLang", true);
    }
    // if requestor did not request activation we are finished
    if (!activate) {
        status.setStatus(ComponentStatus.COMPONENT_NOT_ACTIVATED);
        return null;
    }
    /****************** component activation ******************/
    //
    // get container/remote manager
    //
    Container container = null;
    ContainerInfo containerInfo = null;
    Manager remoteManager = null;
    if (isOtherDomainComponent) {
        // @todo MF do the login?
        try {
            String domainName = CURLHelper.createURI(name).getAuthority();
            remoteManager = getManagerForDomain(domainName);
            if (remoteManager == null) {
                bcex = new AcsJCannotGetComponentEx();
                bcex.setReason("Failed to obtain manager for domain '" + domainName + "'.");
                throw bcex;
            }
        } catch (Throwable th) {
            bcex = new AcsJCannotGetComponentEx(th);
            bcex.setReason("Failed to obtain non-local manager required by component '" + name + "'.'");
            status.setStatus(ComponentStatus.COMPONENT_NOT_ACTIVATED);
            throw bcex;
        }
    } else {
        // search for container by its name
        containerInfo = getContainerInfo(containerName);
        // try to start-up container
        if (containerInfo == null)
            containerInfo = startUpContainer(containerName);
        // check state and get container
        if (containerInfo != null) {
            checkContainerShutdownState(containerInfo);
            container = containerInfo.getContainer();
        }
        // required container is not logged in
        if (container == null) {
            bcex = new AcsJCannotGetComponentEx();
            bcex.setReason("Container '" + containerName + "' required by component '" + name + "' is not logged in.");
            status.setStatus(ComponentStatus.COMPONENT_NOT_ACTIVATED);
            throw bcex;
        }
    }
    // check container vs component ImplLang
    ImplLang containerImplLang = containerInfo.getImplLang();
    if (containerImplLang != null && containerImplLang != ImplLang.not_specified) {
        if (componentImplLang != null && ImplLang.fromString(componentImplLang) != containerImplLang) {
            AcsJCannotGetComponentEx af = new AcsJCannotGetComponentEx();
            af.setReason("Component and container implementation language do not match (" + componentImplLang + " != " + containerImplLang.name() + ")");
            throw af;
        }
    }
    //
    // get handle
    //
    // obtain handle
    componentsLock.lock();
    try {
        // only preallocate (if necessary)
        if (!reactivate) {
            // !!! ACID 2
            Integer objHandle = (Integer) executeCommand(new ComponentCommandPreallocate());
            h = (objHandle == null) ? 0 : objHandle.intValue();
        //h = components.preallocate();
        }
        // failed to obtain handle
        if (h == 0) {
            AcsJCannotGetComponentEx af = new AcsJCannotGetComponentEx();
            af.setReason("Preallocation of new handle failed, too many registered components.");
            throw af;
        }
        // create temporary ComponentInfo - to allow hierarchical components
        if (!reactivate) {
            ComponentInfo data = new ComponentInfo(h | COMPONENT_MASK, name, type, code, null);
            data.setKeepAliveTime(keepAliveTime);
            // !!! ACID
            executeCommand(new ComponentCommandSet(h, data));
            // add to pending activation list
            synchronized (pendingActivations) {
                pendingActivations.put(name, data);
            }
            // add component to client component list to allow dependency checks
            if ((requestor & TYPE_MASK) == COMPONENT_MASK)
                addComponentOwner(data.getHandle(), requestor);
        }
    } finally {
        componentsLock.unlock();
    }
    //
    // invoke get_component
    //
    componentInfo = null;
    long executionId = 0;
    long activationTime = 0;
    boolean timeoutError = false;
    if (isOtherDomainComponent) {
        try {
            URI curlName = CURLHelper.createURI(name);
            StatusHolder statusHolder = new StatusHolder();
            // @todo MF tmp (handle)
            remoteManager.getComponent(INTERDOMAIN_MANAGER_HANDLE, curlName, true, statusHolder);
            activationTime = System.currentTimeMillis();
            if (statusHolder.getStatus() == ComponentStatus.COMPONENT_ACTIVATED) {
                // local name to be used
                String localName = curlName.getPath();
                if (localName.charAt(0) == '/')
                    localName = localName.substring(1);
                /// @TODO MF tmp (handle)
                ComponentInfo[] infos = remoteManager.getComponentInfo(INTERDOMAIN_MANAGER_HANDLE, new int[0], localName, "*", true);
                if (infos != null && infos.length == 1) {
                    componentInfo = infos[0];
                    // fix container name
                    componentInfo.setContainerName(CURL_URI_SCHEMA + curlName.getAuthority() + "/" + componentInfo.getContainerName());
                }
            //else
            //    throw new RemoteException("Failed to obtain component info for '"+name+"' from remote manager.");
            }
        //else
        //    throw new RemoteException("Failed to obtain component '"+name+"' from remote manager, status: " + statusHolder.getStatus() + ".");
        } catch (Throwable ex) {
            bcex = new AcsJCannotGetComponentEx(ex);
            bcex.setReason("Failed to obtain component '" + name + "' from remote manager.");
            timeoutError = (ex instanceof TimeoutRemoteException);
        }
    } else {
        //
        // invoke get_component on container
        //
        // log info
        String handleReadable = HandleHelper.toString(h | COMPONENT_MASK);
        logger.log(Level.INFO, "Activating component '" + name + "' (" + handleReadable + ") on container '" + containerInfo.getName() + "'.");
        boolean callSyncActivate = System.getProperties().containsKey(NAME_SYNC_ACTIVATE);
        if (callSyncActivate) {
            // sync
            try {
                executionId = generateExecutionId();
                activationTime = System.currentTimeMillis();
                componentInfo = container.activate_component(h | COMPONENT_MASK, executionId, name, code, type);
            } catch (Throwable ex) {
                bcex = new AcsJCannotGetComponentEx(ex);
                bcex.setReason("Failed to activate component '" + name + "' on container '" + containerName + "'.");
                timeoutError = (ex instanceof TimeoutRemoteException);
            }
        } else {
            // async
            try {
                executionId = generateExecutionId();
                activationTime = System.currentTimeMillis();
                ComponentInfoCompletionCallbackImpl callback = new ComponentInfoCompletionCallbackImpl(requestor, name, type, code, containerName, keepAliveTime, status, isOtherDomainComponent, isDynamicComponent, h, reactivate, container, containerInfo, executionId, activationTime);
                addPendingContainerAsyncRequest(containerName, callback);
                try {
                    container.activate_component_async(h | COMPONENT_MASK, executionId, name, code, type, callback);
                } catch (Throwable t) {
                    // failed call, remove async request from the list
                    removePendingContainerAsyncRequest(containerName, callback);
                    throw t;
                }
                logger.log(AcsLogLevel.DELOUSE, "Asynchronous activation of component '" + name + "' (" + handleReadable + ") is running on container '" + containerInfo.getName() + "'.");
                ComponentInfo ret;
                try {
                    ret = callback.waitUntilActivated(getLockTimeout());
                } catch (Throwable t) {
                    // failed call (most likely timeout), remove async request from the list
                    removePendingContainerAsyncRequest(containerName, callback);
                    throw t;
                }
                logger.log(AcsLogLevel.DELOUSE, "Asynchronous activation of component '" + name + "' (" + handleReadable + ") has finished on container '" + containerInfo.getName() + "'.");
                return ret;
            } catch (Throwable ex) {
                bcex = new AcsJCannotGetComponentEx(ex);
                bcex.setReason("Failed to activate component '" + name + "' on container '" + containerName + "'.");
                throw bcex;
            }
        }
    }
    // call this immediately if bcex != null or sync call
    return internalNoSyncRequestComponentPhase2(requestor, name, type, code, containerName, keepAliveTime, status, bcex, isOtherDomainComponent, isDynamicComponent, h, reactivate, componentInfo, container, containerInfo, executionId, activationTime, timeoutError);
}
Also used : AcsJComponentSpecIncompatibleWithActiveComponentEx(alma.maciErrType.wrappers.AcsJComponentSpecIncompatibleWithActiveComponentEx) ComponentCommandClientAdd(com.cosylab.acs.maci.manager.recovery.ComponentCommandClientAdd) DAOProxy(com.cosylab.cdb.client.DAOProxy) Manager(com.cosylab.acs.maci.Manager) URI(java.net.URI) AcsJCannotGetComponentEx(alma.maciErrType.wrappers.AcsJCannotGetComponentEx) StatusHolder(com.cosylab.acs.maci.StatusHolder) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Container(com.cosylab.acs.maci.Container) ComponentCommandSet(com.cosylab.acs.maci.manager.recovery.ComponentCommandSet) ContainerInfo(com.cosylab.acs.maci.ContainerInfo) TimeoutRemoteException(com.cosylab.acs.maci.TimeoutRemoteException) ComponentInfo(com.cosylab.acs.maci.ComponentInfo) ImplLang(com.cosylab.acs.maci.ImplLang) ComponentCommandPreallocate(com.cosylab.acs.maci.manager.recovery.ComponentCommandPreallocate)

Aggregations

AcsJCannotGetComponentEx (alma.maciErrType.wrappers.AcsJCannotGetComponentEx)1 AcsJComponentSpecIncompatibleWithActiveComponentEx (alma.maciErrType.wrappers.AcsJComponentSpecIncompatibleWithActiveComponentEx)1 ComponentInfo (com.cosylab.acs.maci.ComponentInfo)1 Container (com.cosylab.acs.maci.Container)1 ContainerInfo (com.cosylab.acs.maci.ContainerInfo)1 ImplLang (com.cosylab.acs.maci.ImplLang)1 Manager (com.cosylab.acs.maci.Manager)1 StatusHolder (com.cosylab.acs.maci.StatusHolder)1 TimeoutRemoteException (com.cosylab.acs.maci.TimeoutRemoteException)1 ComponentCommandClientAdd (com.cosylab.acs.maci.manager.recovery.ComponentCommandClientAdd)1 ComponentCommandPreallocate (com.cosylab.acs.maci.manager.recovery.ComponentCommandPreallocate)1 ComponentCommandSet (com.cosylab.acs.maci.manager.recovery.ComponentCommandSet)1 DAOProxy (com.cosylab.cdb.client.DAOProxy)1 URI (java.net.URI)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1