use of com.cosylab.acs.maci.ComponentInfo in project ACS by ACS-Community.
the class ManagerImpl method getCollocatedComponent.
/**
* @see com.cosylab.acs.maci.Manager#getCollocatedComponent(int, com.cosylab.acs.maci.ComponentSpec, boolean, URI)
*/
/// @todo MF not supported
public ComponentInfo getCollocatedComponent(int id, ComponentSpec componentSpec, boolean markAsDefault, URI targetComponentURI) throws AcsJCannotGetComponentEx, AcsJNoPermissionEx, AcsJIncompleteComponentSpecEx, AcsJInvalidComponentSpecEx, AcsJComponentSpecIncompatibleWithActiveComponentEx {
try {
// check if null
if (componentSpec == null) {
AcsJNullPointerEx ex = new AcsJNullPointerEx();
ex.setVariable("componentSpec");
throw ex;
}
// check componentSpec components are null
if (componentSpec.getName() == null) {
AcsJNullPointerEx ex = new AcsJNullPointerEx();
ex.setVariable("componentSpec.Name");
throw ex;
}
if (componentSpec.getType() == null) {
AcsJNullPointerEx ex = new AcsJNullPointerEx();
ex.setVariable("componentSpec.Type");
throw ex;
}
if (componentSpec.getCode() == null) {
AcsJNullPointerEx ex = new AcsJNullPointerEx();
ex.setVariable("componentSpec.Code");
throw ex;
}
if (componentSpec.getContainer() == null) {
AcsJNullPointerEx ex = new AcsJNullPointerEx();
ex.setVariable("componentSpec.Container");
throw ex;
}
// check for empty componentSpec.name
if (componentSpec.getName().length() == 0) {
AcsJBadParameterEx ex = new AcsJBadParameterEx();
ex.setParameter("componentSpec.Name");
ex.setParameterValue("EMPTY");
ex.setReason("Non empty Component Name expected");
throw ex;
}
// check if null
if (targetComponentURI == null) {
AcsJNullPointerEx ex = new AcsJNullPointerEx();
ex.setVariable("targetComponentURI");
throw ex;
}
if (!componentSpec.getContainer().equals(ComponentSpec.COMPSPEC_ANY)) {
AcsJBadParameterEx ex = new AcsJBadParameterEx();
ex.setParameter("componentSpec.Container");
ex.setParameterValue(componentSpec.getContainer());
ex.setReason("COMPSPEC_ANY expected");
throw ex;
}
} catch (AcsJNullPointerEx e) {
AcsJInvalidComponentSpecEx ex = new AcsJInvalidComponentSpecEx(e);
throw ex;
} catch (AcsJBadParameterEx e) {
AcsJInvalidComponentSpecEx ex = new AcsJInvalidComponentSpecEx(e);
throw ex;
}
// check handle and NONE permissions
// Throws AcsJNoPermissionEx that is let flying up
securityCheck(id, AccessRights.NONE);
/****************************************************************/
/// @todo temporary quick implementation (does not look in the CDB if component is not activated)
String name = extractName(targetComponentURI);
int h = 0;
ComponentInfo targetComponentInfo = null;
componentsLock.lock();
try {
h = components.first();
while (h != 0) {
ComponentInfo componentInfo = (ComponentInfo) components.get(h);
if (componentInfo.getName().equals(name)) {
targetComponentInfo = componentInfo;
break;
}
h = components.next(h);
}
} finally {
componentsLock.unlock();
}
// if not found, check the CDB
if (targetComponentInfo == null) {
DAOProxy componentsDAO = getComponentsDAOProxy();
if (componentsDAO != null) {
// read container name
String containerName = readStringCharacteristics(componentsDAO, name + "/Container", true);
if (containerName != null)
componentSpec.setContainer(containerName);
}
} else
componentSpec.setContainer(targetComponentInfo.getContainerName());
// failed to detemine a target container
if (componentSpec.getContainer().equals(ComponentSpec.COMPSPEC_ANY)) {
AcsJIncompleteComponentSpecEx ex = new AcsJIncompleteComponentSpecEx();
ex.setCURL(name);
ex.setContainerName(componentSpec.getContainer());
throw ex;
}
// request for component
// same exceptions are let flying up.
ComponentInfo componentInfo = null;
try {
componentInfo = internalRequestDynamicComponent(id, componentSpec);
} catch (AcsJSyncLockFailedEx e) {
AcsJCannotGetComponentEx ex = new AcsJCannotGetComponentEx();
ex.setCURL(name);
ex.setReason("Failed to get Synchronisation lock");
throw ex;
}
// update default components table
if (componentInfo != null && markAsDefault) {
synchronized (defaultComponents) {
// !!! ACID 3
executeCommand(new DefaultComponentCommandPut(componentInfo.getType(), componentInfo));
//defaultComponents.put(componentInfo.getType(), componentInfo.getName());
}
logger.log(Level.INFO, "'" + componentInfo.getName() + "' has been marked as a default component of type '" + componentInfo.getType() + "'.");
}
if (componentInfo == null) {
AcsJCannotGetComponentEx ex = new AcsJCannotGetComponentEx();
ex.setCURL(name);
throw ex;
}
return componentInfo;
}
use of com.cosylab.acs.maci.ComponentInfo in project ACS by ACS-Community.
the class ManagerImpl method registerComponent.
/**
* @see com.cosylab.acs.maci.Manager#registerComponent(int, URI, String, Component)
*/
public int registerComponent(int id, URI curl, String type, Component component) throws AcsJNoPermissionEx, AcsJBadParameterEx {
// check for null
if (curl == null) {
AcsJBadParameterEx af = new AcsJBadParameterEx();
af.setParameter("curl");
af.setParameterValue("null");
throw af;
}
if (type == null) {
AcsJBadParameterEx af = new AcsJBadParameterEx();
af.setParameter("type");
af.setParameterValue("null");
throw af;
}
if (component == null) {
AcsJBadParameterEx af = new AcsJBadParameterEx();
af.setParameter("component");
af.setParameterValue("null");
throw af;
}
// Just rethrow the exception
try {
checkCURL(curl, false);
} catch (AcsJBadParameterEx e) {
throw e;
}
// check handle and REGISTER_COMPONENT permissions
securityCheck(id, AccessRights.REGISTER_COMPONENT);
/****************************************************************/
// extract name
String name = extractName(curl);
int h = 0;
componentsLock.lock();
try {
// check if Component is already registred
// if it is, return existing info
h = components.first();
while (h != 0) {
ComponentInfo registeredComponentInfo = (ComponentInfo) components.get(h);
if (registeredComponentInfo.getName().equals(name)) {
if (registeredComponentInfo.getType().equals(type)) {
// it is already activated, add manager as an owner and return handle
if (!registeredComponentInfo.getClients().contains(this.getHandle())) {
// ACID - !!!
executeCommand(new ComponentCommandClientAdd(registeredComponentInfo.getHandle() & HANDLE_MASK, this.getHandle()));
//registredComponentInfo.getClients().add(this.getHandle());
}
return registeredComponentInfo.getHandle();
} else {
AcsJNoPermissionEx npe = new AcsJNoPermissionEx();
npe.setReason("Component with name '" + name + "' but different type already registered.");
npe.setID(HandleHelper.toString(id));
npe.setProtectedResource(name);
throw npe;
}
}
h = components.next(h);
}
// allocate new handle
// !!! ACID 2
Integer objHandle = (Integer) executeCommand(new ComponentCommandAllocate());
int handle;
//int handle = components.allocate();
if (objHandle == null || (handle = objHandle.intValue()) == 0) {
NoResourcesException af = new NoResourcesException("Generation of new handle failed, too many components registred.");
throw af;
}
// generate external handle
h = handle | COMPONENT_MASK;
// add generated key
h |= (random.nextInt(0x100)) << 16;
// create new component info
ComponentInfo componentInfo = new ComponentInfo(h, name, type, null, component);
// no container
componentInfo.setContainer(0);
componentInfo.setContainerName(null);
// components can register other components
componentInfo.setAccessRights(AccessRights.REGISTER_COMPONENT);
// set Manager as client of the Component (to keep it immortal)
componentInfo.getClients().add(this.getHandle());
// set interfaces
// NOTE: this could block since it is a remote call
componentInfo.setInterfaces(component.implementedInterfaces());
// !!! ACID - register AddComponentCommand
executeCommand(new ComponentCommandSet(handle, componentInfo));
// store info
//components.set(handle, componentInfo);
} finally {
componentsLock.unlock();
}
// bind to remote directory
// NOTE: this could block since it is a remote call
//bind(convertToHiearachical(name), "O", component);
logger.log(Level.INFO, "Component '" + name + "' registered.");
return h;
}
use of com.cosylab.acs.maci.ComponentInfo in project ACS by ACS-Community.
the class ManagerImpl method makeComponentImmortal.
/**
* @see com.cosylab.acs.maci.Manager#makeComponentImmortal(int, java.net.URI, boolean)
*/
public void makeComponentImmortal(int id, URI curl, boolean immortalState) throws AcsJCannotGetComponentEx, AcsJNoPermissionEx, AcsJBadParameterEx {
// extract name
String name = extractName(curl);
// let same exception flying up
try {
checkCURL(curl);
} catch (AcsJBadParameterEx e) {
throw e;
}
// check handle and NONE permissions
securityCheck(id, AccessRights.NONE);
/****************************************************************/
int h;
ComponentInfo componentInfo = null;
componentsLock.lock();
try {
h = components.first();
while (h != 0) {
componentInfo = (ComponentInfo) components.get(h);
if (componentInfo.getName().equals(name)) {
h = componentInfo.getHandle();
break;
}
h = components.next(h);
}
// component not yet activated check
if (h == 0) {
NoResourcesException af = new NoResourcesException("Component not activated.");
throw af;
}
// if not an owner of the component, check administrator rights
if (!componentInfo.getClients().contains(id)) {
securityCheck(id, AccessRights.INTROSPECT_MANAGER);
}
if (immortalState) {
// finally, add manager as an owner
if (!componentInfo.getClients().contains(this.getHandle())) {
// ACID - !!!
executeCommand(new ComponentCommandClientAdd(componentInfo.getHandle() & HANDLE_MASK, this.getHandle()));
//componentInfo.getClients().add(this.getHandle());
}
logger.log(Level.INFO, "Component " + name + " was made immortal.");
}
} finally {
componentsLock.unlock();
}
// this must be done outside component sync. block
if (!immortalState) {
logger.log(Level.INFO, "Component " + name + " was made mortal.");
// finally, can happen that the manager is the only owner
// so release could be necessary
internalReleaseComponent(this.getHandle(), h, false);
}
/****************************************************************/
}
use of com.cosylab.acs.maci.ComponentInfo 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());
}
use of com.cosylab.acs.maci.ComponentInfo in project ACS by ACS-Community.
the class ManagerImpl method internalRestartComponent.
/**
* Internal method for restarting components.
*
* @param owner owner of the component.
* @param curl CURL of the component to be restarted.
* @return Newly restarted component, <code>null</code> if failed.
*/
private Component internalRestartComponent(int owner, URI curl) throws AcsJNoPermissionEx {
// resolve handle from curl
int h = 0;
String name = extractName(curl);
componentsLock.lock();
try {
h = components.first();
while (h != 0) {
ComponentInfo componentInfo = (ComponentInfo) components.get(h);
if (componentInfo.getName().equals(name)) {
h = componentInfo.getHandle();
break;
}
h = components.next(h);
}
} finally {
componentsLock.unlock();
}
// if found, delegate operation, otherwise do nothing
if (h != 0)
return internalRestartComponent(owner, h);
else
return null;
}
Aggregations