Added inital code

This commit is contained in:
Luca Frosini 2022-06-16 13:54:13 +02:00
parent d1e6ab2f0f
commit f12f541b11
8 changed files with 1841 additions and 0 deletions

26
FUNDING.md Normal file
View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}