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;
}
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();
}
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;
}
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;
}
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;
}
}
Aggregations