Added inital code
This commit is contained in:
parent
d1e6ab2f0f
commit
f12f541b11
|
@ -0,0 +1,26 @@
|
|||
# Acknowledgments
|
||||
|
||||
The projects leading to this software have received funding from a series of European Union programmes including:
|
||||
|
||||
- the Sixth Framework Programme for Research and Technological Development
|
||||
- [DILIGENT](https://cordis.europa.eu/project/id/004260) (grant no. 004260).
|
||||
- the Seventh Framework Programme for research, technological development and demonstration
|
||||
- [D4Science](https://cordis.europa.eu/project/id/212488) (grant no. 212488);
|
||||
- [D4Science-II](https://cordis.europa.eu/project/id/239019) (grant no.239019);
|
||||
- [ENVRI](https://cordis.europa.eu/project/id/283465) (grant no. 283465);
|
||||
- [iMarine](https://cordis.europa.eu/project/id/283644) (grant no. 283644);
|
||||
- [EUBrazilOpenBio](https://cordis.europa.eu/project/id/288754) (grant no. 288754).
|
||||
- the H2020 research and innovation programme
|
||||
- [SoBigData](https://cordis.europa.eu/project/id/654024) (grant no. 654024);
|
||||
- [PARTHENOS](https://cordis.europa.eu/project/id/654119) (grant no. 654119);
|
||||
- [EGI-Engage](https://cordis.europa.eu/project/id/654142) (grant no. 654142);
|
||||
- [ENVRI PLUS](https://cordis.europa.eu/project/id/654182) (grant no. 654182);
|
||||
- [BlueBRIDGE](https://cordis.europa.eu/project/id/675680) (grant no. 675680);
|
||||
- [PerformFISH](https://cordis.europa.eu/project/id/727610) (grant no. 727610);
|
||||
- [AGINFRA PLUS](https://cordis.europa.eu/project/id/731001) (grant no. 731001);
|
||||
- [DESIRA](https://cordis.europa.eu/project/id/818194) (grant no. 818194);
|
||||
- [ARIADNEplus](https://cordis.europa.eu/project/id/823914) (grant no. 823914);
|
||||
- [RISIS 2](https://cordis.europa.eu/project/id/824091) (grant no. 824091);
|
||||
- [EOSC-Pillar](https://cordis.europa.eu/project/id/857650) (grant no. 857650);
|
||||
- [Blue Cloud](https://cordis.europa.eu/project/id/862409) (grant no. 862409);
|
||||
- [SoBigData-PlusPlus](https://cordis.europa.eu/project/id/871042) (grant no. 871042);
|
|
@ -0,0 +1,28 @@
|
|||
package org.gcube.smartgears.handler.resourceregistry;
|
||||
|
||||
import org.gcube.smartgears.handler.resourceregistry.resourcemanager.HostingNodeManager;
|
||||
|
||||
/**
|
||||
* Library-wide constants.
|
||||
* @author Luca Frosini
|
||||
* @author Lucio Lelii
|
||||
*/
|
||||
public class Constants {
|
||||
|
||||
public static final String HOSTING_NODE_MANAGER_PROPERTY = HostingNodeManager.class.getSimpleName();
|
||||
|
||||
// /**
|
||||
// * The name of the context property that contains the EService Resource.
|
||||
// */
|
||||
// public static final String ESERVICE_MANAGER_PROPERTY = EServiceManager.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* The configuration name of {@link EServiceHandler} and {@link HostingNodeHandler}.
|
||||
*/
|
||||
public static final String RESOURCE_MANAGEMENT = "resource-management";
|
||||
|
||||
public static final long default_container_publication_frequency_in_seconds = 60;
|
||||
|
||||
public static final int application_republish_frequency_in_minutes = 20;
|
||||
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package org.gcube.smartgears.handler.resourceregistry;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.gcube.common.authorization.client.proxy.AuthorizationProxy;
|
||||
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
||||
import org.gcube.common.scope.api.ScopeProvider;
|
||||
import org.gcube.informationsystem.resourceregistry.api.contexts.ContextCache;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
|
||||
import org.gcube.smartgears.provider.ProviderFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI-CNR)
|
||||
*/
|
||||
public class ContextUtility {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(ContextUtility.class);
|
||||
|
||||
private static AuthorizationProxy authorizationProxy;
|
||||
|
||||
static {
|
||||
authorizationProxy = ProviderFactory.provider().authorizationProxy();
|
||||
}
|
||||
|
||||
public static void resetContex() {
|
||||
SecurityTokenProvider.instance.reset();
|
||||
ScopeProvider.instance.reset();
|
||||
}
|
||||
|
||||
public static void setContextFromToken(String token) {
|
||||
if (token == null || token.compareTo("") == 0) {
|
||||
resetContex();
|
||||
} else {
|
||||
SecurityTokenProvider.instance.set(token);
|
||||
String scope = getContextName(token);
|
||||
ScopeProvider.instance.set(scope);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static String getCurrentContextName() {
|
||||
String token = SecurityTokenProvider.instance.get();
|
||||
return getContextName(token);
|
||||
}
|
||||
|
||||
public static UUID getContextUUID(String token) throws ResourceRegistryException {
|
||||
ContextCache contextCache = ContextCache.getInstance();
|
||||
String contextFullName = getContextName(token);
|
||||
UUID contextUUID = contextCache.getUUIDByFullName(contextFullName);
|
||||
return contextUUID;
|
||||
}
|
||||
|
||||
public static String getContextName(String token) {
|
||||
try {
|
||||
return authorizationProxy.get(token).getContext();
|
||||
} catch (Exception e) {
|
||||
logger.error("Error retrieving context form token {}, it should never happen", token, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static SortedSet<String> getContextFullNamesFromTokens(Set<String> tokens){
|
||||
SortedSet<String> contextFullNames = new TreeSet<>();
|
||||
for(String token : tokens) {
|
||||
String contextFullName = getContextName(token);
|
||||
contextFullNames.add(contextFullName);
|
||||
}
|
||||
return contextFullNames;
|
||||
}
|
||||
|
||||
public static SortedSet<UUID> getContextUUIDFromTokens(Set<String> tokens) throws ResourceRegistryException {
|
||||
SortedSet<UUID> contextsUUID = new TreeSet<>();
|
||||
ContextCache contextCache = ContextCache.getInstance();
|
||||
for(String token : tokens) {
|
||||
String contextFullName = getContextName(token);
|
||||
UUID contextUUID = contextCache.getUUIDByFullName(contextFullName);
|
||||
contextsUUID.add(contextUUID);
|
||||
}
|
||||
return contextsUUID;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,275 @@
|
|||
package org.gcube.smartgears.handler.resourceregistry;
|
||||
|
||||
import static org.gcube.common.events.Observes.Kind.resilient;
|
||||
import static org.gcube.smartgears.handlers.ProfileEvents.addToContext;
|
||||
import static org.gcube.smartgears.handlers.ProfileEvents.removeFromContext;
|
||||
import static org.gcube.smartgears.lifecycle.application.ApplicationLifecycle.activation;
|
||||
import static org.gcube.smartgears.lifecycle.application.ApplicationLifecycle.failure;
|
||||
import static org.gcube.smartgears.lifecycle.application.ApplicationLifecycle.stop;
|
||||
import static org.gcube.smartgears.utils.Utils.rethrowUnchecked;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
||||
import org.gcube.common.events.Observes;
|
||||
import org.gcube.informationsystem.model.reference.entities.Resource;
|
||||
import org.gcube.informationsystem.model.reference.relations.ConsistsOf;
|
||||
import org.gcube.informationsystem.resourceregistry.api.contexts.ContextCache;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.facets.StateFacet;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.resources.EService;
|
||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
||||
import org.gcube.smartgears.handler.resourceregistry.resourcemanager.EServiceManager;
|
||||
import org.gcube.smartgears.handlers.application.ApplicationLifecycleEvent.Start;
|
||||
import org.gcube.smartgears.lifecycle.application.ApplicationLifecycle;
|
||||
import org.gcube.smartgears.lifecycle.application.ApplicationState;
|
||||
import org.gcube.smartgears.lifecycle.container.ContainerLifecycle;
|
||||
import org.gcube.smartgears.utils.Utils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Manages the {@link EService} {@link Resource} of the application.
|
||||
* <p>
|
||||
* The manager:
|
||||
* <ul>
|
||||
* <li>creates the {@link EService} {@link Resource} and the facets it
|
||||
* {@link ConsistsOf} when the application starts for the first time;</li>
|
||||
* <li>update the {@link StateFacet} when the application becomes active,
|
||||
* and at any lifecycle change thereafter;</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @author Luca Frosini (ISTI-CNR)
|
||||
*/
|
||||
public class EServiceHandler {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(EServiceHandler.class);
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
private ScheduledFuture<?> periodicUpdates;
|
||||
|
||||
protected EServiceManager eServiceManager;
|
||||
|
||||
public EServiceHandler() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void onStart(Start event) {
|
||||
try {
|
||||
logger.info("{} onStart started", this.getClass().getSimpleName());
|
||||
this.applicationContext = event.context();
|
||||
init();
|
||||
registerObservers();
|
||||
schedulePeriodicUpdates();
|
||||
logger.info("{} onStart terminated", this.getClass().getSimpleName());
|
||||
} catch (Throwable re) {
|
||||
logger.error("onStart failed", re);
|
||||
}
|
||||
}
|
||||
|
||||
protected void removeResourceFromOldContexts(Set<UUID> startContexts, Set<UUID> resourceContexts) {
|
||||
Set<UUID> contextsToRemove = new HashSet<>(resourceContexts);
|
||||
contextsToRemove.removeAll(startContexts);
|
||||
for(UUID contextToRemove : contextsToRemove) {
|
||||
try {
|
||||
eServiceManager.removeFromContext(contextToRemove);
|
||||
}catch (Exception e) {
|
||||
try {
|
||||
String contextFullName = ContextCache.getInstance().getContextFullNameByUUID(contextToRemove);
|
||||
logger.warn("Unable to remove {} from Context {} UUID {}", EService.NAME, contextFullName, contextsToRemove, e);
|
||||
}catch (Exception ex) {
|
||||
logger.warn("Unable to remove {} from Context with UUID {}.", EService.NAME, contextsToRemove, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
|
||||
String previousToken = SecurityTokenProvider.instance.get();
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(EServiceHandler.class.getClassLoader());
|
||||
boolean create = true;
|
||||
|
||||
Set<String> startTokens = applicationContext.configuration().startTokens();
|
||||
|
||||
String firstToken = startTokens.iterator().next();
|
||||
ContextUtility.setContextFromToken(firstToken);
|
||||
eServiceManager = new EServiceManager(applicationContext);
|
||||
|
||||
|
||||
Set<UUID> startContextsUUID = new HashSet<>();
|
||||
for (String token : startTokens) {
|
||||
UUID contextUUID = ContextUtility.getContextUUID(token);
|
||||
startContextsUUID.add(contextUUID);
|
||||
if (create) {
|
||||
eServiceManager.createEService();
|
||||
create = false;
|
||||
} else {
|
||||
eServiceManager.addToContext(contextUUID);
|
||||
}
|
||||
}
|
||||
|
||||
Set<UUID> resourceContextsUUID = eServiceManager.getContextsUUID().keySet();
|
||||
removeResourceFromOldContexts(startContextsUUID, resourceContextsUUID);
|
||||
|
||||
} catch (Throwable e) {
|
||||
rethrowUnchecked(e);
|
||||
} finally {
|
||||
ContextUtility.setContextFromToken(previousToken);
|
||||
Thread.currentThread().setContextClassLoader(contextCL);
|
||||
}
|
||||
logger.info("{} init() terminated", this.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
private void registerObservers() {
|
||||
|
||||
applicationContext.events().subscribe(new Object() {
|
||||
|
||||
@Observes({ activation, stop, failure })
|
||||
void onChanged(ApplicationLifecycle lc) {
|
||||
ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
|
||||
String previousToken = SecurityTokenProvider.instance.get();
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(EServiceHandler.class.getClassLoader());
|
||||
if(previousToken==null) {
|
||||
String token = applicationContext.configuration().startTokens().iterator().next();
|
||||
ContextUtility.setContextFromToken(token);
|
||||
}
|
||||
eServiceManager.updateFacets();
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to update {} State", EService.NAME, e);
|
||||
} finally {
|
||||
ContextUtility.setContextFromToken(previousToken);
|
||||
Thread.currentThread().setContextClassLoader(contextCL);
|
||||
}
|
||||
}
|
||||
|
||||
@Observes(value = addToContext)
|
||||
void addTo(String token) {
|
||||
ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
|
||||
String previousToken = SecurityTokenProvider.instance.get();
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(EServiceHandler.class.getClassLoader());
|
||||
ContextUtility.setContextFromToken(token);
|
||||
UUID contextUUID = ContextUtility.getContextUUID(token);
|
||||
eServiceManager.addToContext(contextUUID);
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to add {} to current context ({})", EService.NAME,
|
||||
ContextUtility.getCurrentContextName(), e);
|
||||
} finally {
|
||||
ContextUtility.setContextFromToken(previousToken);
|
||||
Thread.currentThread().setContextClassLoader(contextCL);
|
||||
}
|
||||
}
|
||||
|
||||
@Observes(value = removeFromContext)
|
||||
void removeFrom(String token) {
|
||||
ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
|
||||
String previousToken = SecurityTokenProvider.instance.get();
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(EServiceHandler.class.getClassLoader());
|
||||
eServiceManager.removeFromCurrentContext();
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to remove {} from current context ({})",
|
||||
EService.NAME, ContextUtility.getCurrentContextName(), e);
|
||||
} finally {
|
||||
ContextUtility.setContextFromToken(previousToken);
|
||||
Thread.currentThread().setContextClassLoader(contextCL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void schedulePeriodicUpdates() {
|
||||
|
||||
// register to cancel updates
|
||||
applicationContext.events().subscribe(
|
||||
|
||||
new Object() {
|
||||
|
||||
// we register it in response to lifecycle events so that we can
|
||||
// stop and resume along with application
|
||||
@Observes(value = { activation }, kind = resilient)
|
||||
synchronized void restartPeriodicUpdates(final ApplicationLifecycle lc) {
|
||||
|
||||
// already running
|
||||
if (periodicUpdates != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String applicationName = applicationContext.name();
|
||||
|
||||
if (lc.state() == ApplicationState.active) {
|
||||
logger.info("Scheduling periodic updates of {} for application {}",
|
||||
EService.NAME, applicationName);
|
||||
} else {
|
||||
logger.info("Resuming periodic updates of {} for application {}",
|
||||
EService.NAME, applicationName);
|
||||
}
|
||||
|
||||
final Runnable updateTask = new Runnable() {
|
||||
public void run() {
|
||||
String previousToken = SecurityTokenProvider.instance.get();
|
||||
if (previousToken == null) {
|
||||
String token = applicationContext.configuration().startTokens().iterator().next();
|
||||
ContextUtility.setContextFromToken(token);
|
||||
}
|
||||
try {
|
||||
eServiceManager.updateFacets();
|
||||
} catch (Exception e) {
|
||||
logger.error("Cannot complete periodic update of {} for application {}", EService.NAME, applicationName, e);
|
||||
} finally {
|
||||
ContextUtility.setContextFromToken(previousToken);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
periodicUpdates = Utils.scheduledServicePool.scheduleAtFixedRate(updateTask,
|
||||
Constants.application_republish_frequency_in_minutes,
|
||||
Constants.application_republish_frequency_in_minutes, TimeUnit.MINUTES);
|
||||
|
||||
/*
|
||||
* The following line is used for testing purposes during development.
|
||||
* If you uncomment this, you need to comment the line above
|
||||
*/
|
||||
// periodicUpdates = Utils.scheduledServicePool.scheduleAtFixedRate(updateTask, 120, 120, TimeUnit.SECONDS);
|
||||
|
||||
}
|
||||
|
||||
@Observes(value = { stop, failure }, kind = resilient)
|
||||
synchronized void cancelPeriodicUpdates(ContainerLifecycle ignore) {
|
||||
|
||||
if (periodicUpdates != null) {
|
||||
|
||||
String applicationName = applicationContext.name();
|
||||
|
||||
logger.trace("Stopping periodic updates of {} for application {} ",
|
||||
EService.NAME, applicationName);
|
||||
|
||||
try {
|
||||
periodicUpdates.cancel(true);
|
||||
periodicUpdates = null;
|
||||
} catch (Exception e) {
|
||||
logger.warn("Could not stop periodic updates of {} for application {}",
|
||||
EService.NAME, applicationName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Constants.RESOURCE_MANAGEMENT;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,263 @@
|
|||
package org.gcube.smartgears.handler.resourceregistry;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.gcube.common.events.Observes.Kind.resilient;
|
||||
import static org.gcube.smartgears.handlers.ProfileEvents.addToContext;
|
||||
import static org.gcube.smartgears.handlers.ProfileEvents.removeFromContext;
|
||||
import static org.gcube.smartgears.lifecycle.container.ContainerLifecycle.activation;
|
||||
import static org.gcube.smartgears.lifecycle.container.ContainerLifecycle.failure;
|
||||
import static org.gcube.smartgears.lifecycle.container.ContainerLifecycle.part_activation;
|
||||
import static org.gcube.smartgears.lifecycle.container.ContainerLifecycle.shutdown;
|
||||
import static org.gcube.smartgears.lifecycle.container.ContainerLifecycle.stop;
|
||||
import static org.gcube.smartgears.lifecycle.container.ContainerState.active;
|
||||
import static org.gcube.smartgears.utils.Utils.rethrowUnchecked;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
||||
import org.gcube.common.events.Observes;
|
||||
import org.gcube.informationsystem.model.reference.entities.Facet;
|
||||
import org.gcube.informationsystem.model.reference.entities.Resource;
|
||||
import org.gcube.informationsystem.model.reference.relations.ConsistsOf;
|
||||
import org.gcube.informationsystem.resourceregistry.api.contexts.ContextCache;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.facets.StateFacet;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.resources.HostingNode;
|
||||
import org.gcube.smartgears.context.Property;
|
||||
import org.gcube.smartgears.context.container.ContainerContext;
|
||||
import org.gcube.smartgears.handler.resourceregistry.resourcemanager.HostingNodeManager;
|
||||
import org.gcube.smartgears.handlers.container.ContainerHandler;
|
||||
import org.gcube.smartgears.handlers.container.ContainerLifecycleEvent.Start;
|
||||
import org.gcube.smartgears.lifecycle.container.ContainerLifecycle;
|
||||
import org.gcube.smartgears.lifecycle.container.ContainerState;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Manages the {@link HostingNode} {@link Resource} of the application.
|
||||
* <p>
|
||||
* The manager:
|
||||
* <ul>
|
||||
* <li>creates the {@link HostingNode} {@link Resource} and the facets it
|
||||
* {@link ConsistsOf} when the container starts for the first time;</li>
|
||||
* <li>update the {@link StateFacet} when the application becomes
|
||||
* active, and at any lifecycle change thereafter;</li>
|
||||
* <li>schedule a periodic update of {@link Facet}s containing variables
|
||||
* information.</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @author Luca Frosini (ISTI-CNR)
|
||||
*/
|
||||
public class HostingNodeHandler {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(HostingNodeHandler.class);
|
||||
|
||||
private ContainerContext containerContext;
|
||||
private ScheduledFuture<?> periodicUpdates;
|
||||
|
||||
protected HostingNodeManager hostingNodeManager;
|
||||
|
||||
public HostingNodeHandler() {
|
||||
super();
|
||||
|
||||
}
|
||||
|
||||
public void onStart(Start event) {
|
||||
try {
|
||||
logger.info("{} onStart started", this.getClass().getSimpleName());
|
||||
this.containerContext = event.context();
|
||||
init();
|
||||
registerObservers();
|
||||
schedulePeriodicUpdates();
|
||||
logger.info("{} onStart terminated", this.getClass().getSimpleName());
|
||||
} catch (Throwable re) {
|
||||
logger.error("onStart failed", re);
|
||||
}
|
||||
}
|
||||
|
||||
protected void removeResourceFromOldContexts(Set<UUID> startContexts, Set<UUID> resourceContexts) throws ResourceRegistryException {
|
||||
Set<UUID> contextsToRemove = new HashSet<>(resourceContexts);
|
||||
contextsToRemove.removeAll(startContexts);
|
||||
for(UUID contextToRemove : contextsToRemove) {
|
||||
hostingNodeManager.removeFromContext(contextToRemove);
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
|
||||
String previousToken = SecurityTokenProvider.instance.get();
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(HostingNodeHandler.class.getClassLoader());
|
||||
boolean create = true;
|
||||
|
||||
List<String> startTokens = containerContext.configuration().startTokens();
|
||||
|
||||
String firstToken = startTokens.iterator().next();
|
||||
ContextUtility.setContextFromToken(firstToken);
|
||||
hostingNodeManager = new HostingNodeManager(containerContext);
|
||||
|
||||
Set<UUID> startContextsUUID = new HashSet<>();
|
||||
for (String token : startTokens) {
|
||||
UUID contextUUID = ContextUtility.getContextUUID(token);
|
||||
startContextsUUID.add(contextUUID);
|
||||
if (create) {
|
||||
hostingNodeManager.createHostingNode();
|
||||
containerContext.properties().add(new Property(Constants.HOSTING_NODE_MANAGER_PROPERTY, hostingNodeManager));
|
||||
create = false;
|
||||
} else {
|
||||
hostingNodeManager.addToContext(contextUUID);
|
||||
}
|
||||
}
|
||||
|
||||
Set<UUID> resourceContextsUUID = hostingNodeManager.getContextsUUID().keySet();
|
||||
removeResourceFromOldContexts(startContextsUUID, resourceContextsUUID);
|
||||
|
||||
} catch (Throwable e) {
|
||||
rethrowUnchecked(e);
|
||||
} finally {
|
||||
ContextUtility.setContextFromToken(previousToken);
|
||||
Thread.currentThread().setContextClassLoader(contextCL);
|
||||
}
|
||||
logger.info("{} init() terminated", this.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
private void registerObservers() {
|
||||
|
||||
containerContext.events().subscribe(new Object() {
|
||||
|
||||
@Observes({ activation, part_activation, shutdown, stop, failure })
|
||||
void onChanged(ContainerLifecycle cl) {
|
||||
ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
|
||||
String previousToken = SecurityTokenProvider.instance.get();
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(HostingNodeHandler.class.getClassLoader());
|
||||
if (previousToken == null) {
|
||||
String token = containerContext.configuration().startTokens().iterator().next();
|
||||
ContextUtility.setContextFromToken(token);
|
||||
}
|
||||
hostingNodeManager.updateFacets();
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to update {} State", HostingNode.NAME, e);
|
||||
} finally {
|
||||
ContextUtility.setContextFromToken(previousToken);
|
||||
Thread.currentThread().setContextClassLoader(contextCL);
|
||||
}
|
||||
}
|
||||
|
||||
@Observes(value = addToContext)
|
||||
void addTo(String token) {
|
||||
ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
|
||||
String previousToken = SecurityTokenProvider.instance.get();
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(HostingNodeHandler.class.getClassLoader());
|
||||
ContextUtility.setContextFromToken(token);
|
||||
UUID contextUUID = ContextUtility.getContextUUID(token);
|
||||
hostingNodeManager.addToContext(contextUUID);
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to update Service State", e);
|
||||
} finally {
|
||||
ContextUtility.setContextFromToken(previousToken);
|
||||
Thread.currentThread().setContextClassLoader(contextCL);
|
||||
}
|
||||
}
|
||||
|
||||
@Observes(value = removeFromContext)
|
||||
void removeFrom(String token) {
|
||||
ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
|
||||
String previousToken = SecurityTokenProvider.instance.get();
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(HostingNodeHandler.class.getClassLoader());
|
||||
ContextUtility.setContextFromToken(token);
|
||||
UUID contextUUID = ContextUtility.getContextUUID(token);
|
||||
hostingNodeManager.removeFromContext(contextUUID);
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to update Service State", e);
|
||||
} finally {
|
||||
ContextUtility.setContextFromToken(previousToken);
|
||||
Thread.currentThread().setContextClassLoader(contextCL);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void schedulePeriodicUpdates() {
|
||||
// register to cancel updates
|
||||
containerContext.events().subscribe(
|
||||
|
||||
new Object() {
|
||||
|
||||
final ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
|
||||
|
||||
// we register it in response to lifecycle events so that we can
|
||||
// stop and resume along with application
|
||||
@Observes(value = { activation, part_activation }, kind = resilient)
|
||||
synchronized void restartPeriodicUpdates(ContainerLifecycle cl) {
|
||||
|
||||
// already running
|
||||
if (periodicUpdates != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cl.state() == active) {
|
||||
logger.info("Scheduling periodic updates of {}", HostingNode.NAME);
|
||||
} else {
|
||||
logger.info("Resuming periodic updates of {}", HostingNode.NAME);
|
||||
}
|
||||
|
||||
final Runnable updateTask = new Runnable() {
|
||||
public void run() {
|
||||
String previousToken = SecurityTokenProvider.instance.get();
|
||||
if (previousToken == null) {
|
||||
String token = containerContext.configuration().startTokens().iterator().next();
|
||||
ContextUtility.setContextFromToken(token);
|
||||
}
|
||||
try {
|
||||
hostingNodeManager.updateFacets();
|
||||
} catch (Exception e) {
|
||||
logger.error("Cannot complete periodic update of {}", HostingNode.NAME, e);
|
||||
}finally {
|
||||
ContextUtility.setContextFromToken(previousToken);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
periodicUpdates = service.scheduleAtFixedRate(updateTask, 3,
|
||||
containerContext.configuration().publicationFrequency(), SECONDS);
|
||||
|
||||
}
|
||||
|
||||
@Observes(value = { stop, failure, shutdown }, kind = resilient)
|
||||
synchronized void cancelPeriodicUpdates(ContainerLifecycle cl) {
|
||||
|
||||
if (periodicUpdates != null) {
|
||||
logger.trace("Stopping periodic updates of {}", HostingNode.NAME);
|
||||
try {
|
||||
periodicUpdates.cancel(true);
|
||||
service.shutdownNow();
|
||||
periodicUpdates = null;
|
||||
} catch (Exception e) {
|
||||
logger.warn("Could not stop periodic updates of {}", HostingNode.NAME, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Constants.RESOURCE_MANAGEMENT;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,410 @@
|
|||
package org.gcube.smartgears.handler.resourceregistry.resourcemanager;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.servlet.ServletRegistration;
|
||||
|
||||
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
||||
import org.gcube.informationsystem.model.impl.properties.HeaderImpl;
|
||||
import org.gcube.informationsystem.model.impl.properties.PropagationConstraintImpl;
|
||||
import org.gcube.informationsystem.model.reference.entities.Facet;
|
||||
import org.gcube.informationsystem.model.reference.entities.Resource;
|
||||
import org.gcube.informationsystem.model.reference.properties.Header;
|
||||
import org.gcube.informationsystem.model.reference.properties.PropagationConstraint;
|
||||
import org.gcube.informationsystem.model.reference.properties.PropagationConstraint.AddConstraint;
|
||||
import org.gcube.informationsystem.model.reference.properties.PropagationConstraint.RemoveConstraint;
|
||||
import org.gcube.informationsystem.model.reference.relations.ConsistsOf;
|
||||
import org.gcube.informationsystem.resourceregistry.api.contexts.ContextCache;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.AvailableInAnotherContextException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.contexts.ContextNotFoundException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.resource.ResourceNotFoundException;
|
||||
import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClient;
|
||||
import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClientFactory;
|
||||
import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisher;
|
||||
import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisherFactory;
|
||||
import org.gcube.informationsystem.utils.ElementMapper;
|
||||
import org.gcube.resourcemanagement.model.impl.entities.facets.AccessPointFacetImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.entities.facets.EventFacetImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.entities.facets.SoftwareFacetImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.entities.facets.StateFacetImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.entities.resources.EServiceImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.properties.ValueSchemaImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.relations.consistsof.IsIdentifiedByImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.relations.isrelatedto.ActivatesImpl;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.facets.AccessPointFacet;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.facets.EventFacet;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.facets.MemoryFacet;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.facets.SoftwareFacet;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.facets.StateFacet;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.resources.EService;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.resources.HostingNode;
|
||||
import org.gcube.resourcemanagement.model.reference.properties.ValueSchema;
|
||||
import org.gcube.resourcemanagement.model.reference.relations.consistsof.HasPersistentMemory;
|
||||
import org.gcube.resourcemanagement.model.reference.relations.consistsof.HasVolatileMemory;
|
||||
import org.gcube.resourcemanagement.model.reference.relations.consistsof.IsIdentifiedBy;
|
||||
import org.gcube.resourcemanagement.model.reference.relations.isrelatedto.Activates;
|
||||
import org.gcube.smartgears.configuration.application.ApplicationConfiguration;
|
||||
import org.gcube.smartgears.configuration.container.ContainerConfiguration;
|
||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
||||
import org.gcube.smartgears.handler.resourceregistry.Constants;
|
||||
import org.gcube.smartgears.handler.resourceregistry.ContextUtility;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI-CNR)
|
||||
*/
|
||||
public class EServiceManager {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(HostingNodeManager.class);
|
||||
|
||||
private static List<String> servletExcludes = Arrays.asList("default", "jsp");
|
||||
|
||||
private ResourceRegistryPublisher resourceRegistryPublisher;
|
||||
|
||||
private EService eService;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
public EServiceManager(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
this.resourceRegistryPublisher = ResourceRegistryPublisherFactory.create();
|
||||
}
|
||||
|
||||
public void addEServiceToCurrentContext() throws ResourceNotFoundException, ContextNotFoundException, ResourceRegistryException {
|
||||
String currentToken = SecurityTokenProvider.instance.get();
|
||||
UUID contextUUID = ContextUtility.getContextUUID(currentToken);
|
||||
|
||||
/* Trying to get a context which is not the current to properly invoke the addToContext without forcing the operation using addResourceToCurrentContext */
|
||||
boolean anotherContextSet = false;
|
||||
Set<String> startTokens = applicationContext.configuration().startTokens();
|
||||
for (String token : startTokens) {
|
||||
UUID anotherContextUUID = ContextUtility.getContextUUID(token);
|
||||
if(anotherContextUUID.compareTo(contextUUID)!=0) {
|
||||
ContextUtility.setContextFromToken(token);
|
||||
anotherContextSet = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UUID uuid = UUID.fromString(applicationContext.id());
|
||||
try {
|
||||
if(anotherContextSet) {
|
||||
resourceRegistryPublisher.addResourceToContext(EService.NAME, uuid, contextUUID, false);
|
||||
}else {
|
||||
resourceRegistryPublisher.addResourceToCurrentContext(HostingNode.NAME, uuid, false);
|
||||
}
|
||||
logger.info("{} with UUID {} successfully added to context ({})", EService.NAME, uuid, ContextUtility.getCurrentContextName());
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to add {} with UUID {} to context ({})", EService.NAME, uuid, ContextUtility.getCurrentContextName(), e);
|
||||
}finally {
|
||||
ContextUtility.setContextFromToken(currentToken);
|
||||
}
|
||||
}
|
||||
|
||||
public void addHostingNodeToCurrentContext() throws ResourceNotFoundException, ContextNotFoundException, ResourceRegistryException {
|
||||
String currentToken = SecurityTokenProvider.instance.get();
|
||||
UUID contextUUID = ContextUtility.getContextUUID(currentToken);
|
||||
|
||||
/* Trying to get a context which is not the current to properly invoke the addToContext without forcing the operation using addResourceToCurrentContext */
|
||||
boolean anotherContextSet = false;
|
||||
Set<String> startTokens = applicationContext.configuration().startTokens();
|
||||
for (String token : startTokens) {
|
||||
UUID anotherContextUUID = ContextUtility.getContextUUID(token);
|
||||
if(anotherContextUUID.compareTo(contextUUID)!=0) {
|
||||
ContextUtility.setContextFromToken(token);
|
||||
anotherContextSet = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UUID uuid = UUID.fromString(applicationContext.container().id());
|
||||
try {
|
||||
if(anotherContextSet) {
|
||||
resourceRegistryPublisher.addResourceToContext(HostingNode.NAME, uuid, contextUUID, false);
|
||||
}else {
|
||||
resourceRegistryPublisher.addResourceToCurrentContext(HostingNode.NAME, uuid, false);
|
||||
}
|
||||
logger.info("{} with UUID {} successfully added to context ({})", HostingNode.NAME, uuid, ContextUtility.getCurrentContextName());
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to add {} with UUID {} to context ({})", HostingNode.NAME, uuid, ContextUtility.getCurrentContextName(), e);
|
||||
}finally {
|
||||
ContextUtility.setContextFromToken(currentToken);
|
||||
}
|
||||
}
|
||||
|
||||
public void addToContext(UUID contextUUID) throws ResourceNotFoundException, ContextNotFoundException, ResourceRegistryException {
|
||||
UUID uuid = UUID.fromString(applicationContext.container().id());
|
||||
try {
|
||||
resourceRegistryPublisher.addToContext(HostingNode.NAME, uuid, contextUUID, false);
|
||||
logger.info("{} with UUID {} successfully added to context ({})", HostingNode.NAME, uuid, ContextUtility.getCurrentContextName());
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to add {} with UUID {} to context ({})", HostingNode.NAME, uuid, ContextUtility.getCurrentContextName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeFromCurrentContext()
|
||||
throws ResourceNotFoundException, ContextNotFoundException, ResourceRegistryException {
|
||||
UUID uuid = UUID.fromString(applicationContext.container().id());
|
||||
try {
|
||||
resourceRegistryPublisher.removeResourceFromCurrentContext(HostingNode.NAME, uuid, false);
|
||||
logger.info("{} with UUID {} successfully removed from context ({})", HostingNode.NAME, uuid,
|
||||
ContextUtility.getCurrentContextName());
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to remove {} with UUID {} from context ({})", HostingNode.NAME, uuid, ContextUtility.getCurrentContextName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeFromContext(UUID contextUUID)
|
||||
throws ResourceNotFoundException, ContextNotFoundException, ResourceRegistryException {
|
||||
String contextFullName = ContextCache.getInstance().getContextFullNameByUUID(contextUUID);
|
||||
UUID uuid = UUID.fromString(applicationContext.container().id());
|
||||
try {
|
||||
resourceRegistryPublisher.removeResourceFromContext(HostingNode.NAME, uuid, contextUUID, false);
|
||||
logger.info("{} with UUID {} successfully removed from context ({})", HostingNode.NAME, uuid, contextFullName);
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to remove {} from context ({})", HostingNode.NAME, uuid, contextFullName, e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getBaseAddress() {
|
||||
ApplicationConfiguration configuration = applicationContext.configuration();
|
||||
ContainerConfiguration container = applicationContext.container().configuration();
|
||||
String baseAddress;
|
||||
if (configuration.proxied()) {
|
||||
String protocol = configuration.proxyAddress().protocol();
|
||||
String port = configuration.proxyAddress().port() != null ? ":" + configuration.proxyAddress().port() : "";
|
||||
|
||||
baseAddress = String.format("%s://%s%s%s", protocol, configuration.proxyAddress().hostname(), port,
|
||||
applicationContext.application().getContextPath());
|
||||
} else {
|
||||
String protocol = container.protocol();
|
||||
int port = container.port();
|
||||
|
||||
baseAddress = String.format("%s://%s:%d%s", protocol, container.hostname(), port,
|
||||
applicationContext.application().getContextPath());
|
||||
}
|
||||
return baseAddress;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return applicationContext.lifecycle().state().remoteForm().toLowerCase();
|
||||
}
|
||||
|
||||
private StateFacet getStateFacet(StateFacet stateFacet, Date date) {
|
||||
if (stateFacet == null) {
|
||||
stateFacet = new StateFacetImpl();
|
||||
}
|
||||
String state = getState();
|
||||
stateFacet.setValue(state);
|
||||
stateFacet.setAdditionalProperty("date", date);
|
||||
return stateFacet;
|
||||
}
|
||||
|
||||
private EventFacet getEventFacet(Date date) {
|
||||
EventFacet eventFacet = new EventFacetImpl();
|
||||
eventFacet.setDate(date);
|
||||
String state = getState();
|
||||
eventFacet.setEvent(state);
|
||||
return eventFacet;
|
||||
}
|
||||
|
||||
private EService instantiateEService() {
|
||||
logger.info("Creating {} for {}", EService.NAME, applicationContext.name());
|
||||
|
||||
ApplicationConfiguration applicationConfiguration = applicationContext.configuration();
|
||||
String id = applicationContext.id();
|
||||
|
||||
UUID uuid = UUID.fromString(id);
|
||||
EService eService = new EServiceImpl();
|
||||
Header header = new HeaderImpl(uuid);
|
||||
eService.setHeader(header);
|
||||
|
||||
SoftwareFacet softwareFacet = new SoftwareFacetImpl();
|
||||
softwareFacet.setDescription(applicationConfiguration.description());
|
||||
softwareFacet.setGroup(applicationConfiguration.serviceClass());
|
||||
softwareFacet.setName(applicationConfiguration.name());
|
||||
softwareFacet.setVersion(applicationConfiguration.version());
|
||||
|
||||
IsIdentifiedBy<EService, SoftwareFacet> isIdentifiedBy = new IsIdentifiedByImpl<EService, SoftwareFacet>(
|
||||
eService, softwareFacet);
|
||||
eService.addFacet(isIdentifiedBy);
|
||||
|
||||
String baseAddress = getBaseAddress();
|
||||
for (ServletRegistration servlet : applicationContext.application().getServletRegistrations().values()) {
|
||||
if (!servletExcludes.contains(servlet.getName())) {
|
||||
for (String mapping : servlet.getMappings()) {
|
||||
|
||||
String address = baseAddress
|
||||
+ (mapping.endsWith("*") ? mapping.substring(0, mapping.length() - 2) : mapping);
|
||||
|
||||
AccessPointFacet accessPointFacet = new AccessPointFacetImpl();
|
||||
accessPointFacet.setEntryName(servlet.getName());
|
||||
accessPointFacet.setEndpoint(URI.create(address));
|
||||
ValueSchema valueSchema = new ValueSchemaImpl();
|
||||
valueSchema.setValue("gcube-token");
|
||||
|
||||
accessPointFacet.setAuthorization(valueSchema);
|
||||
|
||||
eService.addFacet(accessPointFacet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Date date = Calendar.getInstance().getTime();
|
||||
|
||||
StateFacet stateFacet = getStateFacet(null, date);
|
||||
eService.addFacet(stateFacet);
|
||||
|
||||
EventFacet eventFacet = getEventFacet(date);;
|
||||
eService.addFacet(eventFacet);
|
||||
|
||||
return eService;
|
||||
}
|
||||
|
||||
public EService createEService() throws ResourceRegistryException {
|
||||
ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
|
||||
UUID eServiceUUID = UUID.fromString(applicationContext.id());
|
||||
try {
|
||||
ResourceRegistryClientFactory.includeContextsInInstanceHeader(true);
|
||||
eService = resourceRegistryClient.getInstance(EService.class, eServiceUUID);
|
||||
updateFacets();
|
||||
} catch (NotFoundException e) {
|
||||
eService = instantiateEService();
|
||||
eService = createActivatesRelation(eService).getTarget();
|
||||
} catch (AvailableInAnotherContextException e) {
|
||||
addHostingNodeToCurrentContext();
|
||||
try {
|
||||
eService = resourceRegistryClient.getInstance(EService.class, eServiceUUID);
|
||||
} catch (AvailableInAnotherContextException ex) {
|
||||
addEServiceToCurrentContext();
|
||||
eService = resourceRegistryClient.getInstance(EService.class, eServiceUUID);
|
||||
// addToContext() is executed on HostingNode.
|
||||
// If the EService is still not available we need to create activates
|
||||
// relation because does not exists otherwise the EService should
|
||||
// already be in the context due to propagation constraint.
|
||||
eService = createActivatesRelation(eService).getTarget();
|
||||
}
|
||||
updateFacets();
|
||||
} catch (ResourceRegistryException e) {
|
||||
throw e;
|
||||
}
|
||||
return eService;
|
||||
}
|
||||
|
||||
public EService updateFacets() throws ResourceRegistryException {
|
||||
logger.debug("Updating {} for {}", EService.NAME, applicationContext.configuration().name());
|
||||
|
||||
StateFacet stateFacet = null;
|
||||
EventFacet eventFacet = null;
|
||||
|
||||
Date date = Calendar.getInstance().getTime();
|
||||
|
||||
List<ConsistsOf<? extends Resource, ? extends Facet>> consistsOfToRemove = new ArrayList<>();
|
||||
|
||||
List<ConsistsOf<? extends Resource, ? extends Facet>> consistsOfList = eService.getConsistsOf();
|
||||
for (ConsistsOf<? extends Resource, ? extends Facet> c : consistsOfList) {
|
||||
if (c.getTarget() instanceof StateFacet) {
|
||||
stateFacet = (StateFacet) c.getTarget();
|
||||
stateFacet = getStateFacet(stateFacet, date);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(c.getTarget() instanceof EventFacet) {
|
||||
eventFacet = (EventFacet) c.getTarget();
|
||||
String value = eventFacet.getEvent();
|
||||
if(value.compareTo(getState())==0) {
|
||||
// This facet must be updated (the date must be updated) so it must not be removed from udpate
|
||||
eventFacet.setDate(date);
|
||||
continue;
|
||||
}else {
|
||||
// This is not the event facet to be updated
|
||||
// Setting the variable to null so it will be created if the event does not already exists.
|
||||
eventFacet = null;
|
||||
}
|
||||
}
|
||||
|
||||
consistsOfToRemove.add(c);
|
||||
|
||||
}
|
||||
|
||||
// Resource Update has effect only on specified facets.
|
||||
// Removing the ones that have not to be changed.
|
||||
consistsOfList.removeAll(consistsOfToRemove);
|
||||
|
||||
|
||||
if(eventFacet == null) {
|
||||
eventFacet = getEventFacet(date);
|
||||
eService.addFacet(eventFacet);
|
||||
}
|
||||
|
||||
try {
|
||||
logger.trace("Updating {} for {} : {}", EService.NAME, applicationContext.configuration().name(), ElementMapper.marshal(eService));
|
||||
}catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
eService = resourceRegistryPublisher.updateResource(eService);
|
||||
}catch (ResourceRegistryException e) {
|
||||
logger.error("Error trying to publish hosting node", e);
|
||||
}
|
||||
|
||||
return eService;
|
||||
}
|
||||
|
||||
private Activates<HostingNode, EService> createActivatesRelation(EService eService)
|
||||
throws ResourceRegistryException {
|
||||
|
||||
HostingNode hostingNode = ((HostingNodeManager) applicationContext.container().properties().lookup(Constants.HOSTING_NODE_MANAGER_PROPERTY).value()).getHostingNode();
|
||||
|
||||
PropagationConstraint propagationConstraint = new PropagationConstraintImpl();
|
||||
propagationConstraint.setRemoveConstraint(RemoveConstraint.cascade);
|
||||
propagationConstraint.setAddConstraint(AddConstraint.propagate);
|
||||
Activates<HostingNode, EService> activates = new ActivatesImpl<>(hostingNode, eService, propagationConstraint);
|
||||
|
||||
try {
|
||||
logger.trace("Going to create {} and {} for application {} : {}", Activates.NAME, EService.NAME, applicationContext.configuration().name(), ElementMapper.marshal(activates));
|
||||
}catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
activates = resourceRegistryPublisher.createIsRelatedTo(activates);
|
||||
hostingNode.attachResource(activates);
|
||||
} catch (NotFoundException e) {
|
||||
logger.error("THIS IS REALLY STRANGE. YOU SHOULD NOT BE HERE. Error while creating {}.", activates, e);
|
||||
throw e;
|
||||
} catch (ResourceRegistryException e) {
|
||||
logger.error("Error while creating {}", activates, e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
return activates;
|
||||
|
||||
}
|
||||
|
||||
// public void removeEService() throws ResourceRegistryException {
|
||||
// try {
|
||||
// resourceRegistryPublisher.delete(eService);
|
||||
// } catch (ResourceRegistryException e) {
|
||||
// logger.error("Unable to delete {}. Going to set the state to {}", applicationContext.name(), getState());
|
||||
// updateFacets();
|
||||
// }
|
||||
// }
|
||||
|
||||
public Map<UUID,String> getContextsUUID() throws Exception {
|
||||
return resourceRegistryPublisher.getResourceContexts(eService);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,659 @@
|
|||
package org.gcube.smartgears.handler.resourceregistry.resourcemanager;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.file.FileStore;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.management.AttributeNotFoundException;
|
||||
import javax.management.InstanceNotFoundException;
|
||||
import javax.management.MBeanException;
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.ReflectionException;
|
||||
|
||||
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
|
||||
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
||||
import org.gcube.informationsystem.model.impl.properties.HeaderImpl;
|
||||
import org.gcube.informationsystem.model.reference.entities.Facet;
|
||||
import org.gcube.informationsystem.model.reference.entities.Resource;
|
||||
import org.gcube.informationsystem.model.reference.properties.Header;
|
||||
import org.gcube.informationsystem.model.reference.relations.ConsistsOf;
|
||||
import org.gcube.informationsystem.resourceregistry.api.contexts.ContextCache;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.AvailableInAnotherContextException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.contexts.ContextNotFoundException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.resource.ResourceNotFoundException;
|
||||
import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClient;
|
||||
import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClientFactory;
|
||||
import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisher;
|
||||
import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisherFactory;
|
||||
import org.gcube.informationsystem.utils.ElementMapper;
|
||||
import org.gcube.resourcemanagement.model.impl.entities.facets.CPUFacetImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.entities.facets.EventFacetImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.entities.facets.LocationFacetImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.entities.facets.MemoryFacetImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.entities.facets.NetworkingFacetImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.entities.facets.SimplePropertyFacetImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.entities.facets.SoftwareFacetImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.entities.facets.StateFacetImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.entities.resources.HostingNodeImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.relations.consistsof.HasPersistentMemoryImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.relations.consistsof.HasVolatileMemoryImpl;
|
||||
import org.gcube.resourcemanagement.model.impl.relations.consistsof.IsIdentifiedByImpl;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.facets.CPUFacet;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.facets.EventFacet;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.facets.LocationFacet;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.facets.MemoryFacet;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.facets.MemoryFacet.MemoryUnit;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.facets.NetworkingFacet;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.facets.SimplePropertyFacet;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.facets.SoftwareFacet;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.facets.StateFacet;
|
||||
import org.gcube.resourcemanagement.model.reference.entities.resources.HostingNode;
|
||||
import org.gcube.resourcemanagement.model.reference.relations.consistsof.HasPersistentMemory;
|
||||
import org.gcube.resourcemanagement.model.reference.relations.consistsof.HasVolatileMemory;
|
||||
import org.gcube.resourcemanagement.model.reference.relations.consistsof.IsIdentifiedBy;
|
||||
import org.gcube.smartgears.configuration.container.ContainerConfiguration;
|
||||
import org.gcube.smartgears.configuration.container.Site;
|
||||
import org.gcube.smartgears.configuration.library.SmartGearsConfiguration;
|
||||
import org.gcube.smartgears.context.container.ContainerContext;
|
||||
import org.gcube.smartgears.handler.resourceregistry.ContextUtility;
|
||||
import org.gcube.smartgears.lifecycle.container.ContainerState;
|
||||
import org.gcube.smartgears.provider.ProviderFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI-CNR)
|
||||
*/
|
||||
public class HostingNodeManager {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(HostingNodeManager.class);
|
||||
|
||||
public static final String MEMORY_TYPE = "memoryType";
|
||||
public static final String MEMORY_TYPE_RAM = "RAM";
|
||||
public static final String MEMORY_TYPE_JVM = "JVM";
|
||||
public static final String JVM_MAX_MEMORY = "jvmMaxMemory";
|
||||
|
||||
public static final String MESSAGE = "message";
|
||||
|
||||
private ContainerContext containerContext;
|
||||
private ResourceRegistryPublisher resourceRegistryPublisher;
|
||||
private HostingNode hostingNode;
|
||||
|
||||
public HostingNodeManager(ContainerContext containerContext) {
|
||||
this.containerContext = containerContext;
|
||||
this.resourceRegistryPublisher = ResourceRegistryPublisherFactory.create();
|
||||
}
|
||||
|
||||
public HostingNode getHostingNode() {
|
||||
return hostingNode;
|
||||
}
|
||||
|
||||
public void addToCurrentContext() throws ResourceNotFoundException, ContextNotFoundException, ResourceRegistryException {
|
||||
String currentToken = SecurityTokenProvider.instance.get();
|
||||
UUID contextUUID = ContextUtility.getContextUUID(currentToken);
|
||||
|
||||
/* Trying to get a context which is not the current to properly invoke the addToContext without forcing the operation using addResourceToCurrentContext */
|
||||
boolean anotherContextSet = false;
|
||||
List<String> startTokens = containerContext.configuration().startTokens();
|
||||
for (String token : startTokens) {
|
||||
UUID anotherContextUUID = ContextUtility.getContextUUID(token);
|
||||
if(anotherContextUUID.compareTo(contextUUID)!=0) {
|
||||
ContextUtility.setContextFromToken(token);
|
||||
anotherContextSet = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UUID uuid = UUID.fromString(containerContext.id());
|
||||
try {
|
||||
if(anotherContextSet) {
|
||||
resourceRegistryPublisher.addToContext(HostingNode.NAME, uuid, contextUUID, false);
|
||||
}else {
|
||||
resourceRegistryPublisher.addResourceToCurrentContext(HostingNode.NAME, uuid, false);
|
||||
}
|
||||
logger.info("{} with UUID {} successfully added to context ({})", HostingNode.NAME, uuid, ContextUtility.getCurrentContextName());
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to add {} with UUID {} to context ({})", HostingNode.NAME, uuid, ContextUtility.getCurrentContextName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void addToContext(UUID contextUUID) throws ResourceNotFoundException, ContextNotFoundException, ResourceRegistryException {
|
||||
UUID uuid = UUID.fromString(containerContext.id());
|
||||
try {
|
||||
resourceRegistryPublisher.addToContext(HostingNode.NAME, uuid, contextUUID, false);
|
||||
logger.info("{} with UUID {} successfully added to context ({})", HostingNode.NAME, uuid, ContextUtility.getCurrentContextName());
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to add {} with UUID {} to context ({})", HostingNode.NAME, uuid, ContextUtility.getCurrentContextName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeFromCurrentContext()
|
||||
throws ResourceNotFoundException, ContextNotFoundException, ResourceRegistryException {
|
||||
UUID uuid = UUID.fromString(containerContext.id());
|
||||
try {
|
||||
resourceRegistryPublisher.removeResourceFromCurrentContext(HostingNode.NAME, uuid, false);
|
||||
logger.info("{} with UUID {} successfully removed from context ({})", HostingNode.NAME, uuid,
|
||||
ContextUtility.getCurrentContextName());
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to remove {} with UUID {} from context ({})", HostingNode.NAME, uuid, ContextUtility.getCurrentContextName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeFromContext(UUID contextUUID)
|
||||
throws ResourceNotFoundException, ContextNotFoundException, ResourceRegistryException {
|
||||
String contextFullName = ContextCache.getInstance().getContextFullNameByUUID(contextUUID);
|
||||
UUID uuid = UUID.fromString(containerContext.id());
|
||||
try {
|
||||
resourceRegistryPublisher.removeResourceFromContext(HostingNode.NAME, uuid, contextUUID, false);
|
||||
logger.info("{} with UUID {} successfully removed from context ({})", HostingNode.NAME, uuid, contextFullName);
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to remove {} from context ({})", HostingNode.NAME, uuid, contextFullName, e);
|
||||
}
|
||||
}
|
||||
|
||||
public HostingNode updateFacets() throws ResourceRegistryException {
|
||||
logger.debug("Updating {}", HostingNode.NAME);
|
||||
|
||||
MemoryFacet ramFacet = null;
|
||||
MemoryFacet jvmMemoryFacet = null;
|
||||
MemoryFacet disk = null;
|
||||
StateFacet stateFacet = null;
|
||||
EventFacet eventFacet = null;
|
||||
|
||||
Date date = Calendar.getInstance().getTime();
|
||||
|
||||
List<ConsistsOf<? extends Resource, ? extends Facet>> consistsOfToRemove = new ArrayList<>();
|
||||
|
||||
List<ConsistsOf<? extends Resource, ? extends Facet>> consistsOfList = hostingNode.getConsistsOf();
|
||||
for (ConsistsOf<? extends Resource, ? extends Facet> c : consistsOfList) {
|
||||
if (c.getTarget() instanceof StateFacet) {
|
||||
stateFacet = (StateFacet) c.getTarget();
|
||||
stateFacet = getStateFacet(stateFacet, date);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c instanceof HasVolatileMemory) {
|
||||
String memoryType = (String) c.getAdditionalProperty(MEMORY_TYPE);
|
||||
if (memoryType.compareTo(MEMORY_TYPE_RAM) == 0) {
|
||||
ramFacet = (MemoryFacet) c.getTarget();
|
||||
ramFacet = getRamInfo(ramFacet);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (memoryType.compareTo(MEMORY_TYPE_JVM) == 0) {
|
||||
jvmMemoryFacet = (MemoryFacet) c.getTarget();
|
||||
jvmMemoryFacet = getJVMMemoryInfo(jvmMemoryFacet);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (c instanceof HasPersistentMemory) {
|
||||
disk = (MemoryFacet) c.getTarget();
|
||||
disk = getDiskSpace(disk);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(c.getTarget() instanceof EventFacet) {
|
||||
eventFacet = (EventFacet) c.getTarget();
|
||||
String value = eventFacet.getEvent();
|
||||
if(value.compareTo(getState())==0) {
|
||||
// This facet must be updated (the date must be updated) so it must not be removed from udpate
|
||||
eventFacet.setDate(date);
|
||||
continue;
|
||||
}else {
|
||||
// This is not the event facet to be updated
|
||||
// Setting the variable to null so it will be created if the event does not already exists.
|
||||
eventFacet = null;
|
||||
}
|
||||
}
|
||||
|
||||
consistsOfToRemove.add(c);
|
||||
|
||||
}
|
||||
|
||||
// Resource Update has effect only on specified facets.
|
||||
// Removing the ones that have not to be changed.
|
||||
consistsOfList.removeAll(consistsOfToRemove);
|
||||
|
||||
if(eventFacet == null) {
|
||||
eventFacet = getEventFacet(date);
|
||||
hostingNode.addFacet(eventFacet);
|
||||
}
|
||||
|
||||
try {
|
||||
hostingNode = resourceRegistryPublisher.updateResource(hostingNode);
|
||||
} catch (ResourceRegistryException e) {
|
||||
logger.error("error trying to publish hosting node", e);
|
||||
}
|
||||
|
||||
return hostingNode;
|
||||
}
|
||||
|
||||
public static SoftwareFacet getOperativeSystem() {
|
||||
SoftwareFacet osSoftwareFacet = new SoftwareFacetImpl();
|
||||
OperatingSystemMXBean mxbean = ManagementFactory.getOperatingSystemMXBean();
|
||||
String osName = mxbean.getName();
|
||||
osSoftwareFacet.setGroup(osName); // softwareFacet.setGroup(System.getProperty("os.name"));
|
||||
osSoftwareFacet.setName(mxbean.getArch()); // softwareFacet.setName(System.getProperty("os.arch"));
|
||||
osSoftwareFacet.setVersion(mxbean.getVersion()); // softwareFacet.setVersion(System.getProperty("os.version"));
|
||||
|
||||
JsonNode jsonNode = ElementMapper.getObjectMapper().valueToTree(osSoftwareFacet);
|
||||
Set<String> fieldNames = new TreeSet<>();
|
||||
Iterator<String> it = jsonNode.fieldNames();
|
||||
while (it.hasNext()) fieldNames.add(it.next());
|
||||
|
||||
if(osName.compareTo("Linux")==0) {
|
||||
// Adding Linux Distribution Info
|
||||
LinuxDistributionInfo linuxDistributionInfo = new LinuxDistributionInfo();
|
||||
Map<String, String> map = linuxDistributionInfo.getInfo();
|
||||
Set<String> keys = map.keySet();
|
||||
for(String key : keys) {
|
||||
String k = key;
|
||||
if(fieldNames.contains(key)) {
|
||||
k = "linuxDistribution-" + k;
|
||||
}
|
||||
osSoftwareFacet.setAdditionalProperty(k, map.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
return osSoftwareFacet;
|
||||
}
|
||||
|
||||
private HostingNode instantiateHostingNode() {
|
||||
logger.info("Creating {}", HostingNode.NAME);
|
||||
|
||||
ContainerConfiguration containerConfiguration = containerContext.configuration();
|
||||
String id = containerContext.id();
|
||||
|
||||
UUID uuid = UUID.fromString(id);
|
||||
HostingNode hostingNode = new HostingNodeImpl();
|
||||
Header header = new HeaderImpl(uuid);
|
||||
hostingNode.setHeader(header);
|
||||
|
||||
NetworkingFacet networkingFacet = new NetworkingFacetImpl();
|
||||
try {
|
||||
networkingFacet.setIPAddress(InetAddress.getLocalHost().getHostAddress());
|
||||
} catch (UnknownHostException e) {
|
||||
logger.warn("unable to detect the IP address of the host");
|
||||
}
|
||||
String hostname = containerConfiguration.hostname();
|
||||
networkingFacet.setHostName(hostname);
|
||||
networkingFacet.setDomainName(getDomain(hostname));
|
||||
|
||||
networkingFacet.setAdditionalProperty("Port", containerConfiguration.port());
|
||||
IsIdentifiedBy<HostingNode, NetworkingFacet> isIdentifiedBy = new IsIdentifiedByImpl<>(hostingNode,
|
||||
networkingFacet, null);
|
||||
hostingNode.addFacet(isIdentifiedBy);
|
||||
|
||||
List<CPUFacet> cpuFacets = getCPUFacets();
|
||||
for (CPUFacet cpuFacet : cpuFacets) {
|
||||
hostingNode.addFacet(cpuFacet);
|
||||
}
|
||||
|
||||
SoftwareFacet osSoftwareFacet = getOperativeSystem();
|
||||
hostingNode.addFacet(osSoftwareFacet);
|
||||
|
||||
|
||||
SmartGearsConfiguration config = ProviderFactory.provider().smartgearsConfiguration();
|
||||
SoftwareFacet smartgearsSoftwareFacet = new SoftwareFacetImpl();
|
||||
smartgearsSoftwareFacet.setGroup("gCube");
|
||||
smartgearsSoftwareFacet.setName("SmartGears");
|
||||
smartgearsSoftwareFacet.setVersion(config.version());
|
||||
hostingNode.addFacet(smartgearsSoftwareFacet);
|
||||
|
||||
SoftwareFacet smartgearsDistributionSoftwareFacet = new SoftwareFacetImpl();
|
||||
smartgearsDistributionSoftwareFacet.setGroup("gCube");
|
||||
smartgearsDistributionSoftwareFacet.setName("SmartGearsDistribution");
|
||||
String smartgearsDistributionVersion = containerConfiguration.properties().get("SmartGearsDistribution");
|
||||
smartgearsDistributionSoftwareFacet.setVersion(smartgearsDistributionVersion);
|
||||
smartgearsDistributionSoftwareFacet.setAdditionalProperty("publication-frequency",
|
||||
String.valueOf(containerConfiguration.publicationFrequency()));
|
||||
hostingNode.addFacet(smartgearsDistributionSoftwareFacet);
|
||||
|
||||
|
||||
SoftwareFacet javaSoftwareFacet = new SoftwareFacetImpl();
|
||||
javaSoftwareFacet.setGroup(System.getProperty("java.vendor"));
|
||||
javaSoftwareFacet.setName("Java");
|
||||
javaSoftwareFacet.setVersion(System.getProperty("java.version"));
|
||||
javaSoftwareFacet.setAdditionalProperty("java.vendor.url", System.getProperty("java.vendor.url"));
|
||||
javaSoftwareFacet.setAdditionalProperty("java.specification.version", System.getProperty("java.specification.version"));
|
||||
hostingNode.addFacet(javaSoftwareFacet);
|
||||
|
||||
SimplePropertyFacet simplePropertyFacet = addEnvironmentVariables(containerConfiguration);
|
||||
hostingNode.addFacet(simplePropertyFacet);
|
||||
|
||||
Date date = Calendar.getInstance().getTime();
|
||||
|
||||
StateFacet stateFacet = getStateFacet(null, date);
|
||||
hostingNode.addFacet(stateFacet);
|
||||
|
||||
EventFacet eventFacet = getEventFacet(date);
|
||||
hostingNode.addFacet(eventFacet);
|
||||
|
||||
MemoryFacet ramFacet = getRamInfo(null);
|
||||
HasVolatileMemory<HostingNode, MemoryFacet> hasVolatileRAMMemory = new HasVolatileMemoryImpl<HostingNode, MemoryFacet>(
|
||||
hostingNode, ramFacet, null);
|
||||
hasVolatileRAMMemory.setAdditionalProperty(MEMORY_TYPE, MEMORY_TYPE_RAM);
|
||||
hostingNode.addFacet(hasVolatileRAMMemory);
|
||||
|
||||
MemoryFacet jvmMemoryFacet = getJVMMemoryInfo(null);
|
||||
HasVolatileMemory<HostingNode, MemoryFacet> hasVolatileJVMMemory = new HasVolatileMemoryImpl<HostingNode, MemoryFacet>(
|
||||
hostingNode, jvmMemoryFacet, null);
|
||||
hasVolatileJVMMemory.setAdditionalProperty(MEMORY_TYPE, MEMORY_TYPE_JVM);
|
||||
hostingNode.addFacet(hasVolatileJVMMemory);
|
||||
|
||||
MemoryFacet diskFacet = getDiskSpace(null);
|
||||
HasPersistentMemory<HostingNode, MemoryFacet> hasPersistentMemory = new HasPersistentMemoryImpl<HostingNode, MemoryFacet>(
|
||||
hostingNode, diskFacet, null);
|
||||
hostingNode.addFacet(hasPersistentMemory);
|
||||
|
||||
LocationFacet locationFacet = new LocationFacetImpl();
|
||||
Site site = containerConfiguration.site();
|
||||
locationFacet.setCountry(site.country());
|
||||
locationFacet.setLocation(site.location());
|
||||
locationFacet.setLatitude(site.latitude());
|
||||
locationFacet.setLongitude(site.longitude());
|
||||
hostingNode.addFacet(locationFacet);
|
||||
|
||||
logger.info("{} with UUID {} instantiated", HostingNode.NAME, uuid);
|
||||
return hostingNode;
|
||||
}
|
||||
|
||||
public HostingNode createHostingNode() throws ResourceRegistryException {
|
||||
ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
|
||||
UUID uuid = UUID.fromString(containerContext.id());
|
||||
try {
|
||||
hostingNode = resourceRegistryClient.getInstance(HostingNode.class, uuid);
|
||||
hostingNode = updateFacets();
|
||||
} catch (NotFoundException e) {
|
||||
hostingNode = instantiateHostingNode();
|
||||
hostingNode = resourceRegistryPublisher.createResource(hostingNode);
|
||||
} catch (AvailableInAnotherContextException e) {
|
||||
addToCurrentContext();
|
||||
hostingNode = resourceRegistryClient.getInstance(HostingNode.class, uuid);
|
||||
} catch (ResourceRegistryException e) {
|
||||
logger.error("", e);
|
||||
}
|
||||
return hostingNode;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return containerContext.lifecycle().state().remoteForm().toLowerCase();
|
||||
}
|
||||
|
||||
|
||||
private StateFacet getStateFacet(StateFacet stateFacet, Date date) {
|
||||
if (stateFacet == null) {
|
||||
stateFacet = new StateFacetImpl();
|
||||
}
|
||||
String state = getState();
|
||||
stateFacet.setValue(state);
|
||||
stateFacet.setAdditionalProperty("date", date);
|
||||
return stateFacet;
|
||||
}
|
||||
|
||||
private EventFacet getEventFacet(Date date) {
|
||||
EventFacet eventFacet = new EventFacetImpl();
|
||||
eventFacet.setDate(date);
|
||||
String state = getState();
|
||||
eventFacet.setEvent(state);
|
||||
return eventFacet;
|
||||
}
|
||||
|
||||
private MemoryFacet getDiskSpace(MemoryFacet memoryFacet) {
|
||||
if (memoryFacet == null) {
|
||||
memoryFacet = new MemoryFacetImpl();
|
||||
}
|
||||
|
||||
long free = 0;
|
||||
long total = 0;
|
||||
try {
|
||||
FileStore fileStore = Files
|
||||
.getFileStore(Paths.get(containerContext.configuration().persistence().location()));
|
||||
free = fileStore.getUsableSpace() / 1048576; // 1048576 = 1024*1024
|
||||
// user to convert
|
||||
// bytes in MByte
|
||||
total = fileStore.getTotalSpace() / 1048576; // 1048576 = 1024*1024
|
||||
// user to convert
|
||||
// bytes in MByte
|
||||
} catch (IOException ioe) {
|
||||
logger.warn("Unable to detect disk space information", ioe);
|
||||
memoryFacet.setAdditionalProperty(MESSAGE, "Unable to detect disk space information.");
|
||||
}
|
||||
|
||||
memoryFacet.setUnit(MemoryUnit.MB);
|
||||
memoryFacet.setSize(total);
|
||||
memoryFacet.setUsed(total - free);
|
||||
|
||||
return memoryFacet;
|
||||
}
|
||||
|
||||
private static final long BYTE_TO_MB = 1024 * 1024;
|
||||
|
||||
private MemoryFacet getRamInfo(MemoryFacet memoryFacet) {
|
||||
if (memoryFacet == null) {
|
||||
memoryFacet = new MemoryFacetImpl();
|
||||
}
|
||||
|
||||
/*
|
||||
* OperatingSystemMXBean mxbean = ManagementFactory.getOperatingSystemMXBean();
|
||||
* com.sun.management.OperatingSystemMXBean sunmxbean =
|
||||
* (com.sun.management.OperatingSystemMXBean) mxbean; long freeMemory =
|
||||
* sunmxbean.getFreePhysicalMemorySize() / 1048576; // in MB long totalMemory =
|
||||
* sunmxbean.getTotalPhysicalMemorySize() / 1048576; // in MB
|
||||
*/
|
||||
|
||||
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||
long freeMemory;
|
||||
try {
|
||||
freeMemory = Long.parseLong(mBeanServer
|
||||
.getAttribute(new ObjectName("java.lang", "type", "OperatingSystem"), "FreePhysicalMemorySize")
|
||||
.toString()) / BYTE_TO_MB;
|
||||
} catch (NumberFormatException | InstanceNotFoundException | AttributeNotFoundException
|
||||
| MalformedObjectNameException | ReflectionException | MBeanException e) {
|
||||
logger.warn(
|
||||
"Unable to get free memory from Operating System. Going to get JVM Memory. Better than nothing");
|
||||
long allocatedMemory = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
|
||||
freeMemory = Runtime.getRuntime().maxMemory() - allocatedMemory;
|
||||
}
|
||||
long totalMemory;
|
||||
try {
|
||||
totalMemory = Long.parseLong(mBeanServer
|
||||
.getAttribute(new ObjectName("java.lang", "type", "OperatingSystem"), "TotalPhysicalMemorySize")
|
||||
.toString()) / BYTE_TO_MB;
|
||||
} catch (NumberFormatException | InstanceNotFoundException | AttributeNotFoundException
|
||||
| MalformedObjectNameException | ReflectionException | MBeanException e) {
|
||||
logger.warn("Unable to total memory from Operating System. Going to get JVM Memory. Better than nothing");
|
||||
totalMemory = Runtime.getRuntime().maxMemory();
|
||||
}
|
||||
|
||||
memoryFacet.setUnit(MemoryUnit.MB);
|
||||
memoryFacet.setSize(totalMemory);
|
||||
memoryFacet.setUsed(totalMemory - freeMemory);
|
||||
|
||||
return memoryFacet;
|
||||
}
|
||||
|
||||
private MemoryFacet getJVMMemoryInfo(MemoryFacet memoryFacet) {
|
||||
if (memoryFacet == null) {
|
||||
memoryFacet = new MemoryFacetImpl();
|
||||
}
|
||||
|
||||
/* 1048576 = 1024*1024 used to convert bytes in MByte */
|
||||
long jvmFreeMemory = Runtime.getRuntime().freeMemory() / 1048576;
|
||||
long jvmTotalMemory = Runtime.getRuntime().totalMemory() / 1048576;
|
||||
long jvmMaxMemory = Runtime.getRuntime().maxMemory() / 1048576;
|
||||
|
||||
memoryFacet.setUnit(MemoryUnit.MB);
|
||||
memoryFacet.setSize(jvmTotalMemory);
|
||||
memoryFacet.setUsed(jvmTotalMemory - jvmFreeMemory);
|
||||
memoryFacet.setAdditionalProperty(JVM_MAX_MEMORY, jvmMaxMemory);
|
||||
|
||||
return memoryFacet;
|
||||
}
|
||||
|
||||
private static String sanitizeKey(String key) {
|
||||
return key.trim().replace(" ", "_");
|
||||
}
|
||||
|
||||
private SimplePropertyFacet addEnvironmentVariables(ContainerConfiguration containerConfiguration) {
|
||||
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.putAll(containerConfiguration.properties());
|
||||
map.putAll(System.getenv());
|
||||
|
||||
SimplePropertyFacet simplePropertyFacet = new SimplePropertyFacetImpl();
|
||||
simplePropertyFacet.setName("ENVIRONMENT_VARIABLES");
|
||||
simplePropertyFacet.setValue("");
|
||||
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
String varname = entry.getKey();
|
||||
if ((varname.compareToIgnoreCase("CLASSPATH") == 0) || (varname.compareToIgnoreCase("PATH") == 0)
|
||||
|| (varname.contains("SSH")) || (varname.contains("MAIL"))
|
||||
|| (varname.compareToIgnoreCase("LS_COLORS") == 0)) {
|
||||
continue;
|
||||
}
|
||||
simplePropertyFacet.setAdditionalProperty(sanitizeKey(entry.getKey()), entry.getValue());
|
||||
}
|
||||
|
||||
return simplePropertyFacet;
|
||||
}
|
||||
|
||||
private static String getDomain(String hostname) {
|
||||
try {
|
||||
Pattern pattern = Pattern.compile("([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})");
|
||||
Matcher regexMatcher = pattern.matcher(hostname);
|
||||
if (regexMatcher.matches()) { // it's an IP address, nothing to trim
|
||||
return hostname;
|
||||
}
|
||||
return hostname.substring(hostname.indexOf(".") + 1);
|
||||
} catch (Exception e) {
|
||||
logger.warn("Error while getting domain from hostname");
|
||||
return hostname;
|
||||
}
|
||||
}
|
||||
|
||||
public static final String CPU_PROCESSOR = "processor";
|
||||
public static final String CPU_VENDOR_ID = "vendor_id";
|
||||
public static final String CPU_MODEL_NAME = "model name";
|
||||
public static final String CPU_CPU_MHZ = "cpu MHz";
|
||||
public static final String CPU_MODEL_T = "model\t";
|
||||
public static final String CPU_MODEL_B = "model\b";
|
||||
public static final String CPU_MODEL_NUMBER = "modelNumber";
|
||||
|
||||
public static List<CPUFacet> getCPUFacets() {
|
||||
|
||||
List<CPUFacet> cpuFacets = new ArrayList<>();
|
||||
|
||||
File file = new File("/proc/cpuinfo");
|
||||
|
||||
if (!file.exists()) {
|
||||
logger.warn("cannot acquire CPU info (no /proc/cpuinfo)");
|
||||
return cpuFacets;
|
||||
}
|
||||
|
||||
BufferedReader input = null;
|
||||
|
||||
try {
|
||||
input = new BufferedReader(new FileReader(file));
|
||||
|
||||
String line = null;
|
||||
|
||||
CPUFacet cpuFacet = null;
|
||||
|
||||
while ((line = input.readLine()) != null) {
|
||||
|
||||
if ((line.startsWith(CPU_PROCESSOR))) { // add the current
|
||||
// processor to the map
|
||||
cpuFacet = new CPUFacetImpl();
|
||||
cpuFacets.add(cpuFacet);
|
||||
}
|
||||
|
||||
try {
|
||||
if (line.contains(CPU_VENDOR_ID)) {
|
||||
cpuFacet.setVendor(line.split(":")[1].trim());
|
||||
continue;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
if (line.contains(CPU_MODEL_NAME)) {
|
||||
cpuFacet.setModel(line.split(":")[1].trim());
|
||||
continue;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
if (line.contains(CPU_CPU_MHZ)) {
|
||||
cpuFacet.setClockSpeed(line.split(":")[1].trim());
|
||||
continue;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
if ((line.contains(CPU_MODEL_T)) || (line.contains(CPU_MODEL_B))) {
|
||||
cpuFacet.setAdditionalProperty(CPU_MODEL_NUMBER, line.split(":")[1].trim());
|
||||
continue;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
String[] nameValue = line.split(":");
|
||||
cpuFacet.setAdditionalProperty(sanitizeKey(nameValue[0]), line.split(":")[1].trim());
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("unable to acquire CPU info", e);
|
||||
} finally {
|
||||
if (input != null) {
|
||||
try {
|
||||
input.close();
|
||||
} catch (IOException e) {
|
||||
logger.warn("unable to close stream", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return cpuFacets;
|
||||
}
|
||||
|
||||
public Map<UUID,String> getContextsUUID() throws Exception {
|
||||
return resourceRegistryPublisher.getResourceContexts(hostingNode);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package org.gcube.smartgears.handler.resourceregistry.resourcemanager;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI-CNR)
|
||||
*/
|
||||
public class LinuxDistributionInfo {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(LinuxDistributionInfo.class);
|
||||
|
||||
public static final String LSB_RELEASE_COMMAND = "lsb_release -a";
|
||||
public static final String OS_RELEASE_FILE_PATH = "/etc/os-release";
|
||||
|
||||
protected Map<String, String> info;
|
||||
|
||||
protected Map<String, String> getInfoViaLsbReleaseCommand() throws IOException {
|
||||
logger.trace("Going to exec {}", LSB_RELEASE_COMMAND);
|
||||
Process process = Runtime.getRuntime().exec(LSB_RELEASE_COMMAND);
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
Map<String, String> map = parseBufferedReader(bufferedReader);
|
||||
bufferedReader.close();
|
||||
return map;
|
||||
}
|
||||
|
||||
private Map<String, String> parseBufferedReader(BufferedReader bufferedReader) throws IOException {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
String line = "";
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
String[] nameValue = parseLine(line);
|
||||
map.put(nameValue[0], nameValue[1]);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private String[] parseLine(String line) {
|
||||
String[] splitted = line.split("=");
|
||||
if (splitted.length < 2) {
|
||||
splitted = line.split(":");
|
||||
}
|
||||
String[] ret = new String[2];
|
||||
ret[0] = splitted[0].trim();
|
||||
ret[1] = splitted[1].trim().replace("\"", "");
|
||||
return ret;
|
||||
}
|
||||
|
||||
private Map<String, String> getInfoViaFile(File file) throws IOException {
|
||||
logger.trace("Going to read file {}", file.getAbsolutePath());
|
||||
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
|
||||
Map<String, String> map = parseBufferedReader(bufferedReader);
|
||||
bufferedReader.close();
|
||||
return map;
|
||||
|
||||
}
|
||||
|
||||
protected Map<String, String> getInfoViaOsReleaseFile() throws IOException {
|
||||
File osReleaseFile = new File(OS_RELEASE_FILE_PATH);
|
||||
return getInfoViaFile(osReleaseFile);
|
||||
}
|
||||
|
||||
private Map<String, String> retriveInfo() {
|
||||
try {
|
||||
return getInfoViaLsbReleaseCommand();
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
return getInfoViaOsReleaseFile();
|
||||
}catch (IOException e) {
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<String, String> getInfo() {
|
||||
if (info == null) {
|
||||
info = retriveInfo();
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue