Search in sources :

Example 31 with ClientInfo

use of com.cosylab.acs.maci.ClientInfo 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)

Example 32 with ClientInfo

use of com.cosylab.acs.maci.ClientInfo in project ACS by ACS-Community.

the class ManagerImpl method getRequestorName.

/*****************************************************************************/
/*************************** [ Utility methods ] *****************************/
/*****************************************************************************/
/**
	 * Returns human-readable and meaningful name of handle.
	 *
	 * @param	id	handle to stringifys
	 * @return	human-readable and meaningful name of handle.
	 */
private String getRequestorName(int id) {
    // parse handle part
    int reqHandle = id & HANDLE_MASK;
    boolean invalidHandle = true;
    StringBuffer name = new StringBuffer(30);
    switch(id & TYPE_MASK) {
        case CONTAINER_MASK:
            //name.append("Container ");
            synchronized (containers) {
                if (containers.isAllocated(reqHandle)) {
                    ContainerInfo info = (ContainerInfo) containers.get(reqHandle);
                    if (info.getHandle() == id) {
                        invalidHandle = false;
                        name.append(info.getName());
                    }
                }
            }
            break;
        case CLIENT_MASK:
            //name.append("Client ");
            synchronized (clients) {
                if (clients.isAllocated(reqHandle)) {
                    ClientInfo info = (ClientInfo) clients.get(reqHandle);
                    if (info.getHandle() == id) {
                        invalidHandle = false;
                        name.append(info.getName());
                    }
                }
            }
            break;
        case ADMINISTRATOR_MASK:
            //name.append("Administrator ");
            synchronized (administrators) {
                if (administrators.isAllocated(reqHandle)) {
                    ClientInfo info = (ClientInfo) administrators.get(reqHandle);
                    if (info.getHandle() == id) {
                        invalidHandle = false;
                        name.append(info.getName());
                    }
                }
            }
            break;
        case COMPONENT_MASK:
            //name.append("Component ");
            componentsLock.lock();
            try {
                if (components.isAllocated(reqHandle)) {
                    ComponentInfo info = (ComponentInfo) components.get(reqHandle);
                    // do additional preallocation check
                    if (info != null && info.getHandle() == id) {
                        invalidHandle = false;
                        name.append(info.getName());
                    }
                }
            } finally {
                componentsLock.unlock();
            }
            break;
        case MANAGER_MASK:
            //name.append("Manager ");
            name.append("Manager");
            invalidHandle = false;
            break;
    }
    if (invalidHandle)
        name.append("<unknown>");
    return name.toString();
}
Also used : ContainerInfo(com.cosylab.acs.maci.ContainerInfo) ClientInfo(com.cosylab.acs.maci.ClientInfo) ComponentInfo(com.cosylab.acs.maci.ComponentInfo)

Example 33 with ClientInfo

use of com.cosylab.acs.maci.ClientInfo in project ACS by ACS-Community.

the class ManagerImpl method noSyncGetClientInfo.

/**
	 * Get client info. (no sync version) for specified id of <code>Client</code> or <code>Administrator</code>.
	 *
	 * @param	id	handle of the client whose info. should be returned
	 * @param	returns	requested info, <code>null</code> if client with requested handle does not exits
	 */
public ClientInfo noSyncGetClientInfo(int id) {
    // parse handle part
    int handle = id & HANDLE_MASK;
    // info to be returned
    ClientInfo info = null;
    switch(id & TYPE_MASK) {
        case CLIENT_MASK:
            {
                if (clients.isAllocated(handle))
                    info = (ClientInfo) clients.get(handle);
            }
            break;
        case ADMINISTRATOR_MASK:
            {
                if (administrators.isAllocated(handle))
                    info = (ClientInfo) administrators.get(handle);
            }
            break;
    }
    return info;
}
Also used : ClientInfo(com.cosylab.acs.maci.ClientInfo)

Example 34 with ClientInfo

use of com.cosylab.acs.maci.ClientInfo in project ACS by ACS-Community.

the class ManagerImpl method clientLogin.

/**
	 * Client specific login method.
	 * @param	name	name of the client
	 * @param	reply	reply to authenticate method
	 * @param	client	client that is logging in
	 * @return	ClientInfo	client info. of newly logged client
	 */
private ClientInfo clientLogin(String name, AuthenticationData reply, Client client, long timeStamp, long executionId) throws AcsJNoPermissionEx {
    assert (name != null);
    assert (client != null);
    TimerTaskClientInfo clientInfo = null;
    synchronized (clients) {
        // check if client is already logged in,
        // if it is, return existing info
        int h = clients.first();
        while (h != 0) {
            ClientInfo loggedClientInfo = (ClientInfo) clients.get(h);
            if (client.equals(loggedClientInfo.getClient()))
                return loggedClientInfo;
            h = clients.next(h);
        }
        // check thread resources
        int usage = threadsUsedPercentage.get();
        if (usage > 90) {
            throw new NoResourcesException("Thread usage too high (%" + usage + "), rejecting login.");
        }
        // allocate new handle
        // !!! ACID 2
        Integer objHandle = (Integer) executeCommand(new ClientCommandAllocate());
        int handle;
        //int handle = clients.allocate();
        if (objHandle == null || (handle = objHandle.intValue()) == 0) {
            NoResourcesException af = new NoResourcesException("Generation of new handle failed, too many clients logged in.");
            throw af;
        }
        // generate external handle
        h = handle | CLIENT_MASK;
        // add generated key
        h |= (random.nextInt(0x100)) << 16;
        // create new client info
        clientInfo = new TimerTaskClientInfo(h, name, client);
        clientInfo.setAccessRights(AccessRights.REGISTER_COMPONENT);
        // register client to the heartbeat manager
        PingTimerTask task = new PingTimerTask(this, logger, clientInfo, null);
        clientInfo.setTask(task);
        heartbeatTask.schedule(task, clientPingInterval, clientPingInterval);
        // !!! ACID - register AddClientCommand
        executeCommand(new ClientCommandSet(handle, clientInfo));
    // store info
    //clients.set(handle, clientInfo);
    }
    // notify administrators about the login
    notifyClientLogin(clientInfo, timeStamp, executionId);
    logger.log(Level.INFO, "Client '" + name + "' logged in.");
    return clientInfo;
}
Also used : NoResourcesException(com.cosylab.acs.maci.NoResourcesException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ClientCommandAllocate(com.cosylab.acs.maci.manager.recovery.ClientCommandAllocate) ClientInfo(com.cosylab.acs.maci.ClientInfo) ClientCommandSet(com.cosylab.acs.maci.manager.recovery.ClientCommandSet)

Example 35 with ClientInfo

use of com.cosylab.acs.maci.ClientInfo in project ACS by ACS-Community.

the class ManagerImpl method securityCheck.

/**
	 * Performs security check on given handle and if check if owner has <code>rights</code> permissions granted.
	 *
	 * Validating means checking key part (KEY_MASK) of the handle.
	 *
	 * @param	id	handle to be checked.
	 * @param	rights	checks if owner of the handle has this permissions granted, can be 0.
	 * @throws	AcsJNoPermissionEx	thrown if handle is not valid or handle owner has not enough permissions
	 */
private void securityCheck(int id, int requiredRights) throws AcsJNoPermissionEx {
    try {
        // check if already shutdown
        if (id != this.getHandle() && shutdown.get()) {
            // already shutdown
            AcsJNoPermissionEx npe = new AcsJNoPermissionEx();
            npe.setID(HandleHelper.toString(id));
            npe.setReason("Manager in shutdown state.");
            throw npe;
        }
        // parse handle part
        int handle = id & HANDLE_MASK;
        int grantedRights = 0;
        boolean invalidHandle = true;
        switch(id & TYPE_MASK) {
            case CONTAINER_MASK:
                synchronized (containers) {
                    if (containers.isAllocated(handle)) {
                        ContainerInfo info = (ContainerInfo) containers.get(handle);
                        if (info.getHandle() == id)
                            invalidHandle = false;
                        grantedRights = CONTAINER_RIGHTS;
                    }
                }
                break;
            case CLIENT_MASK:
                synchronized (clients) {
                    if (clients.isAllocated(handle)) {
                        ClientInfo info = (ClientInfo) clients.get(handle);
                        if (info.getHandle() == id)
                            invalidHandle = false;
                        grantedRights = info.getAccessRights();
                    }
                }
                break;
            case ADMINISTRATOR_MASK:
                synchronized (administrators) {
                    if (administrators.isAllocated(handle)) {
                        ClientInfo info = (ClientInfo) administrators.get(handle);
                        if (info.getHandle() == id)
                            invalidHandle = false;
                        grantedRights = info.getAccessRights();
                    }
                }
                break;
            case COMPONENT_MASK:
                componentsLock.lock();
                try {
                    if (components.isAllocated(handle)) {
                        ComponentInfo info = (ComponentInfo) components.get(handle);
                        if (info != null && info.getHandle() == id)
                            invalidHandle = false;
                        grantedRights = AccessRights.REGISTER_COMPONENT;
                    }
                } finally {
                    componentsLock.unlock();
                }
                break;
            case MANAGER_MASK:
                invalidHandle = false;
                grantedRights = AccessRights.REGISTER_COMPONENT | AccessRights.SHUTDOWN_SYSTEM | AccessRights.INTROSPECT_MANAGER;
                break;
        }
        if (invalidHandle) {
            // NO_PERMISSION
            AcsJNoPermissionEx npe = new AcsJNoPermissionEx();
            npe.setID(HandleHelper.toString(id));
            HandleMonitorEntry hme = getHandleReleaseLog(id);
            if (hme != null) {
                final String timeISO = IsoDateFormat.formatDate(new Date(hme.timestamp));
                switch(hme.reason) {
                    case REMOVED:
                        npe.setReason("Invalid handle, handle was properly removed at " + timeISO + ".");
                        break;
                    case TIMEOUT:
                        npe.setReason("Invalid handle, handle was removed due to timeout at " + timeISO + ".");
                        break;
                    case DISAPPEARED:
                        npe.setReason("Invalid handle, handle was removed due to client/container/component disappearing at " + timeISO + ".");
                        break;
                }
            } else {
                if (enableHandleMonitoringDurationMins <= 0)
                    npe.setReason("Invalid handle, handle was never known.");
                else
                    npe.setReason("Invalid handle, handle is not known for the last " + enableHandleMonitoringDurationMins + " minutes.");
            }
            throw npe;
        }
        if ((grantedRights & requiredRights) != requiredRights) {
            // NO_PERMISSION
            AcsJNoPermissionEx npe = new AcsJNoPermissionEx();
            npe.setID(HandleHelper.toString(id));
            npe.setReason("Insufficient rights.");
            throw npe;
        }
    } catch (AcsJNoPermissionEx ex) {
        logger.log(AcsLogLevel.DELOUSE, "securityCheck fails with AcsJNoPermissionEx:", ex);
        throw ex;
    }
}
Also used : AcsJNoPermissionEx(alma.maciErrType.wrappers.AcsJNoPermissionEx) ContainerInfo(com.cosylab.acs.maci.ContainerInfo) ClientInfo(com.cosylab.acs.maci.ClientInfo) ComponentInfo(com.cosylab.acs.maci.ComponentInfo) Date(java.util.Date)

Aggregations

ClientInfo (com.cosylab.acs.maci.ClientInfo)56 AcsJNoPermissionEx (alma.maciErrType.wrappers.AcsJNoPermissionEx)39 BadParametersException (com.cosylab.acs.maci.BadParametersException)23 ComponentInfo (com.cosylab.acs.maci.ComponentInfo)23 NoResourcesException (com.cosylab.acs.maci.NoResourcesException)21 HashMap (java.util.HashMap)21 Map (java.util.Map)21 Component (com.cosylab.acs.maci.Component)18 RemoteException (com.cosylab.acs.maci.RemoteException)18 URI (java.net.URI)18 NoDefaultComponentException (com.cosylab.acs.maci.NoDefaultComponentException)17 URISyntaxException (java.net.URISyntaxException)17 StatusHolder (com.cosylab.acs.maci.StatusHolder)16 AcsJBadParameterEx (alma.ACSErrTypeCommon.wrappers.AcsJBadParameterEx)8 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)8 AcsJCannotGetComponentEx (alma.maciErrType.wrappers.AcsJCannotGetComponentEx)7 ContainerInfo (com.cosylab.acs.maci.ContainerInfo)7 ArrayList (java.util.ArrayList)7 Client (com.cosylab.acs.maci.Client)6 Administrator (com.cosylab.acs.maci.Administrator)5