From d704290b178888ec8a8e3d4360799b37f2236cb1 Mon Sep 17 00:00:00 2001 From: Luca Frosini Date: Tue, 20 Oct 2020 16:25:30 +0200 Subject: [PATCH] Cdoe refactored to achieve the feature --- .../handler/resourceregistry/Constants.java | 18 +- .../resourceregistry/ContextUtility.java | 50 ++ .../resourceregistry/EServiceHandler.java | 266 ++++++ .../resourceregistry/EServiceManager.java | 538 ----------- .../resourceregistry/HostingNodeHandler.java | 249 ++++++ .../resourceregistry/HostingNodeManager.java | 835 ------------------ .../resourcemanager/EServiceManager.java | 271 ++++++ .../resourcemanager/HostingNodeManager.java | 517 +++++++++++ ...rs.handlers.application.ApplicationHandler | 2 +- ...tgears.handlers.container.ContainerHandler | 2 +- 10 files changed, 1364 insertions(+), 1384 deletions(-) create mode 100644 src/main/java/org/gcube/smartgears/handler/resourceregistry/ContextUtility.java create mode 100644 src/main/java/org/gcube/smartgears/handler/resourceregistry/EServiceHandler.java delete mode 100644 src/main/java/org/gcube/smartgears/handler/resourceregistry/EServiceManager.java create mode 100644 src/main/java/org/gcube/smartgears/handler/resourceregistry/HostingNodeHandler.java delete mode 100644 src/main/java/org/gcube/smartgears/handler/resourceregistry/HostingNodeManager.java create mode 100644 src/main/java/org/gcube/smartgears/handler/resourceregistry/resourcemanager/EServiceManager.java create mode 100644 src/main/java/org/gcube/smartgears/handler/resourceregistry/resourcemanager/HostingNodeManager.java diff --git a/src/main/java/org/gcube/smartgears/handler/resourceregistry/Constants.java b/src/main/java/org/gcube/smartgears/handler/resourceregistry/Constants.java index d433218..d55ce98 100644 --- a/src/main/java/org/gcube/smartgears/handler/resourceregistry/Constants.java +++ b/src/main/java/org/gcube/smartgears/handler/resourceregistry/Constants.java @@ -1,7 +1,7 @@ package org.gcube.smartgears.handler.resourceregistry; -import org.gcube.resourcemanagement.model.reference.entities.resources.EService; -import org.gcube.resourcemanagement.model.reference.entities.resources.HostingNode; +import org.gcube.smartgears.handler.resourceregistry.resourcemanager.EServiceManager; +import org.gcube.smartgears.handler.resourceregistry.resourcemanager.HostingNodeManager; /** * Library-wide constants. @@ -10,17 +10,17 @@ import org.gcube.resourcemanagement.model.reference.entities.resources.HostingNo */ public class Constants { - public static final String HOSTING_NODE_PROPERTY = HostingNode.NAME; - - /** - * The configuration name of {@link EServiceManager} and {@link HostingNodeManager}. - */ - public static final String RESOURCE_MANAGEMENT = "resource-management"; + 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_PROPERTY = EService.NAME; + 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; diff --git a/src/main/java/org/gcube/smartgears/handler/resourceregistry/ContextUtility.java b/src/main/java/org/gcube/smartgears/handler/resourceregistry/ContextUtility.java new file mode 100644 index 0000000..9279a67 --- /dev/null +++ b/src/main/java/org/gcube/smartgears/handler/resourceregistry/ContextUtility.java @@ -0,0 +1,50 @@ +package org.gcube.smartgears.handler.resourceregistry; + +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.smartgears.provider.ProviderFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +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 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; + } + } + +} diff --git a/src/main/java/org/gcube/smartgears/handler/resourceregistry/EServiceHandler.java b/src/main/java/org/gcube/smartgears/handler/resourceregistry/EServiceHandler.java new file mode 100644 index 0000000..d93f1b0 --- /dev/null +++ b/src/main/java/org/gcube/smartgears/handler/resourceregistry/EServiceHandler.java @@ -0,0 +1,266 @@ +package org.gcube.smartgears.handler.resourceregistry; + +import static org.gcube.common.events.Observes.Kind.resilient; +import static org.gcube.smartgears.handler.resourceregistry.Constants.RESOURCE_MANAGEMENT; +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.Set; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +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.Resource; +import org.gcube.informationsystem.model.reference.relations.ConsistsOf; +import org.gcube.resourcemanagement.model.reference.entities.facets.ServiceStateFacet; +import org.gcube.resourcemanagement.model.reference.entities.resources.EService; +import org.gcube.smartgears.context.Property; +import org.gcube.smartgears.context.application.ApplicationContext; +import org.gcube.smartgears.handler.resourceregistry.resourcemanager.EServiceManager; +import org.gcube.smartgears.handlers.application.ApplicationLifecycleEvent; +import org.gcube.smartgears.handlers.application.ApplicationLifecycleHandler; +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. + *

+ * The manager: + *

+ *

+ * + * @author Luca Frosini + */ +@XmlRootElement(name = RESOURCE_MANAGEMENT) +public class EServiceHandler extends ApplicationLifecycleHandler { + + private static final Logger logger = LoggerFactory.getLogger(EServiceHandler.class); + + private ApplicationContext applicationContext; + private ScheduledFuture periodicUpdates; + + protected EServiceManager eServiceManager; + + public EServiceHandler() { + super(); + eServiceManager = new EServiceManager(); + } + + @Override + public void onStart(ApplicationLifecycleEvent.Start e) { + try { + logger.info("{} onStart started", this.getClass().getSimpleName()); + this.applicationContext = e.context(); + init(); + registerObservers(); + schedulePeriodicUpdates(); + logger.info("{} onStart finished", this.getClass().getSimpleName()); + } catch (Throwable re) { + logger.error("onStart failed", re); + } + } + + private void init() { + ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); + String previousToken = SecurityTokenProvider.instance.get(); + try { + Thread.currentThread().setContextClassLoader(EServiceHandler.class.getClassLoader()); + boolean create = true; + Set startTokens = applicationContext.configuration().startTokens(); + for (String token : startTokens) { + ContextUtility.setContextFromToken(token); + try { + if (create) { + eServiceManager.createEService(applicationContext); + applicationContext.properties().add(new Property(Constants.ESERVICE_MANAGER_PROPERTY, eServiceManager)); + create = false; + } else { + eServiceManager.addToContext(applicationContext); + } + } catch (Exception e) { + logger.error("Unable to add {} to current context ({})", eServiceManager.geteService(), + ContextUtility.getContextName(token), e); + } + } + } 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 }) + @Observes({ activation }) + void onChanged(ApplicationLifecycle lc) { + ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); + String currentToken = SecurityTokenProvider.instance.get(); + if (currentToken == null) + currentToken = applicationContext.configuration().startTokens().iterator().next(); + + ContextUtility.setContextFromToken(currentToken); + + try { + Thread.currentThread().setContextClassLoader(EServiceHandler.class.getClassLoader()); + eServiceManager.updateServiceStateFacet(applicationContext); + } catch (Exception e) { + logger.error("Failed to update {} State", EService.NAME, e); + } finally { + Thread.currentThread().setContextClassLoader(contextCL); + } + + } + + @Observes({ stop, failure }) + void onStop(ApplicationLifecycle lc) { + ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); + String currentToken = SecurityTokenProvider.instance.get(); + if (currentToken == null) + currentToken = applicationContext.configuration().startTokens().iterator().next(); + + ContextUtility.setContextFromToken(currentToken); + + try { + Thread.currentThread().setContextClassLoader(EServiceHandler.class.getClassLoader()); + eServiceManager.removeEService(applicationContext); + } catch (Exception e) { + logger.error("Failed to update Service State", e); + } finally { + 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); + eServiceManager.addToContext(applicationContext); + } catch (Exception e) { + logger.error("Failed to add HostingNode to current context ({})", + 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()); + ContextUtility.setContextFromToken(token); + eServiceManager.removeFromContext(); + } catch (Exception e) { + logger.error("Failed to remove HostingNode from current context ({})", + 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; + } + + if (lc.state() == ApplicationState.active) { + logger.info("scheduling periodic updates of application {} EService", + applicationContext.name()); + } else { + logger.info("resuming periodic updates of application {} EService", + applicationContext.name()); + } + + final Runnable updateTask = new Runnable() { + public void run() { + try { + String currentToken = SecurityTokenProvider.instance.get(); + if (currentToken == null) + currentToken = applicationContext.configuration().startTokens().iterator().next(); + + ContextUtility.setContextFromToken(currentToken); + eServiceManager.updateServiceStateFacet(applicationContext); + } catch (Exception e) { + logger.error("Cannot complete periodic update of EService", e); + } + } + }; + + periodicUpdates = Utils.scheduledServicePool.scheduleAtFixedRate(updateTask, + Constants.application_republish_frequency_in_minutes, + Constants.application_republish_frequency_in_minutes, TimeUnit.MINUTES); + + } + + @Observes(value = { stop, failure }, kind = resilient) + synchronized void cancelPeriodicUpdates(ContainerLifecycle ignore) { + + if (periodicUpdates != null) { + logger.trace("stopping periodic updates of application {} EService", + applicationContext.name()); + + try { + periodicUpdates.cancel(true); + periodicUpdates = null; + } catch (Exception e) { + logger.warn("could not stop periodic updates of application {}", + applicationContext.name(), e); + } + } + } + + }); + + } + + @Override + public String toString() { + return RESOURCE_MANAGEMENT; + } + +} diff --git a/src/main/java/org/gcube/smartgears/handler/resourceregistry/EServiceManager.java b/src/main/java/org/gcube/smartgears/handler/resourceregistry/EServiceManager.java deleted file mode 100644 index ebe14fe..0000000 --- a/src/main/java/org/gcube/smartgears/handler/resourceregistry/EServiceManager.java +++ /dev/null @@ -1,538 +0,0 @@ -package org.gcube.smartgears.handler.resourceregistry; - -import static org.gcube.common.events.Observes.Kind.resilient; -import static org.gcube.smartgears.handler.resourceregistry.Constants.ESERVICE_PROPERTY; -import static org.gcube.smartgears.handler.resourceregistry.Constants.RESOURCE_MANAGEMENT; -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.net.URI; -import java.util.Arrays; -import java.util.List; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -import javax.servlet.ServletRegistration; -import javax.xml.bind.annotation.XmlRootElement; - -import org.gcube.common.authorization.client.proxy.AuthorizationProxy; -import org.gcube.common.authorization.library.provider.SecurityTokenProvider; -import org.gcube.common.events.Observes; -import org.gcube.common.scope.api.ScopeProvider; -import org.gcube.informationsystem.model.impl.properties.HeaderImpl; -import org.gcube.informationsystem.model.impl.properties.PropagationConstraintImpl; -import org.gcube.informationsystem.model.impl.relations.ConsistsOfImpl; -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.exceptions.AvailableInAnotherContextException; -import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException; -import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; -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.resourcemanagement.model.impl.entities.facets.AccessPointFacetImpl; -import org.gcube.resourcemanagement.model.impl.entities.facets.ServiceStateFacetImpl; -import org.gcube.resourcemanagement.model.impl.entities.facets.SoftwareFacetImpl; -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.ServiceStateFacet; -import org.gcube.resourcemanagement.model.reference.entities.facets.SoftwareFacet; -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.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.Property; -import org.gcube.smartgears.context.application.ApplicationContext; -import org.gcube.smartgears.handlers.application.ApplicationLifecycleEvent; -import org.gcube.smartgears.handlers.application.ApplicationLifecycleHandler; -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.provider.ProviderFactory; -import org.gcube.smartgears.utils.Utils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Manages the {@link EService} {@link Resource} of the application. - *

- * The manager: - *

- *

- * - * @author Luca Frosini - */ -@XmlRootElement(name = RESOURCE_MANAGEMENT) -public class EServiceManager extends ApplicationLifecycleHandler { - - private static final Logger logger = LoggerFactory - .getLogger(EServiceManager.class); - - private ApplicationContext applicationContext; - private AuthorizationProxy authorizationProxy; - private ScheduledFuture periodicUpdates; - - private static List servletExcludes = Arrays.asList("default","jsp"); - - public EServiceManager() { - super(); - this.authorizationProxy = ProviderFactory.provider() - .authorizationProxy(); - } - - private void setContextFromToken(String token) { - if (token == null || token.compareTo("") == 0) { - SecurityTokenProvider.instance.reset(); - ScopeProvider.instance.reset(); - } else { - SecurityTokenProvider.instance.set(token); - String scope = getContextName(token); - ScopeProvider.instance.set(scope); - } - - } - - @Override - public void onStart(ApplicationLifecycleEvent.Start e) { - try{ - logger.info("onStart started"); - this.applicationContext = e.context(); - init(); - registerObservers(); - schedulePeriodicUpdates(); - logger.info("onStart finished"); - }catch(Throwable re){ - logger.error("onStart failed", re); - } - } - - - private void init() { - ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); - String previousToken = SecurityTokenProvider.instance.get(); - try { - Thread.currentThread().setContextClassLoader( - EServiceManager.class.getClassLoader()); - - EService eService = null; - - Set startTokens = applicationContext.configuration().startTokens(); - for (String token : startTokens) { - setContextFromToken(token); - if(eService != null){ - ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory.create(); - addToContext(resourceRegistryPublisher); - } - eService= getEService(); - share(eService); - } - } catch (Throwable e) { - rethrowUnchecked(e); - } finally { - setContextFromToken(previousToken); - Thread.currentThread().setContextClassLoader(contextCL); - } - logger.info("init for EService executed"); - } - - private void share(EService eService) { - logger.trace("sharing EService for {}", applicationContext.name()); - applicationContext.properties().add( - new Property(ESERVICE_PROPERTY, eService)); - } - - // helpers - private void registerObservers() { - - applicationContext.events().subscribe(new Object() { - - @Observes({ activation, stop, failure }) - void onChanged(ApplicationLifecycle lc) { - String state = getState(lc); - logger.debug("Moving app {} to {}", applicationContext.name(), state); - - ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); - String previousToken = SecurityTokenProvider.instance.get(); - if(previousToken==null) - previousToken = applicationContext.configuration().startTokens().iterator().next(); - - setContextFromToken(previousToken); - - try { - Thread.currentThread().setContextClassLoader(EServiceManager.class.getClassLoader()); - createOrUpdateServiceStateFacet(state); - } catch (Exception e) { - logger.error("Failed to update Service State", e); - } finally { - 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(EServiceManager.class.getClassLoader()); - setContextFromToken(token); - - ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory.create(); - addToContext(resourceRegistryPublisher); - - } catch (Exception e) { - logger.error("Failed to add HostingNode to current context ({})", getCurrentContextName(), e); - } finally { - 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(EServiceManager.class.getClassLoader()); - setContextFromToken(token); - - ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory.create(); - removeFromContext(resourceRegistryPublisher); - - } catch (Exception e) { - logger.error("Failed to remove HostingNode from current context ({})", getCurrentContextName(), e); - } finally { - setContextFromToken(previousToken); - Thread.currentThread().setContextClassLoader(contextCL); - } - - } - - }); - } - - - private String getState(ApplicationLifecycle lc){ - return lc.state().remoteForm().toLowerCase(); - } - - 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; - } - - if (lc.state() == ApplicationState.active) { - logger.info( - "scheduling periodic updates of application {} EService", - applicationContext.name()); - } else { - logger.info( - "resuming periodic updates of application {} EService", - applicationContext.name()); - } - - final Runnable updateTask = new Runnable() { - public void run() { - try { - String state = getState(lc); - String selectedToken = applicationContext.configuration().startTokens().toArray(new String[0])[0]; - setContextFromToken(selectedToken); - createOrUpdateServiceStateFacet(state); - } catch (Exception e) { - logger.error("Cannot complete periodic update of EService", e); - } - } - }; - - periodicUpdates = Utils.scheduledServicePool - .scheduleAtFixedRate( - updateTask, - Constants.application_republish_frequency_in_minutes, - Constants.application_republish_frequency_in_minutes, - TimeUnit.MINUTES); - - } - - @Observes(value = { stop, failure }, kind = resilient) - synchronized void cancelPeriodicUpdates(ContainerLifecycle ignore) { - - if (periodicUpdates != null) { - logger.trace( - "stopping periodic updates of application {} EService", - applicationContext.name()); - - try { - periodicUpdates.cancel(true); - periodicUpdates = null; - } catch (Exception e) { - logger.warn( - "could not stop periodic updates of application {} EService", - applicationContext.name(), e); - } - } - } - - }); - - } - - private Activates createActivatesRelation(EService eService, - ResourceRegistryPublisher resourceRegistryPublisher) throws ResourceRegistryException{ - - HostingNode hostingNode = applicationContext.container().properties().lookup(Constants.HOSTING_NODE_PROPERTY).value(HostingNode.class); - addToContext(resourceRegistryPublisher); - - - PropagationConstraint propagationConstraint = new PropagationConstraintImpl(); - propagationConstraint.setRemoveConstraint(RemoveConstraint.cascade); - propagationConstraint.setAddConstraint(AddConstraint.propagate); - Activates activates = new ActivatesImpl<>(hostingNode, eService, propagationConstraint); - - try { - activates = resourceRegistryPublisher.createIsRelatedTo(activates); - } catch (NotFoundException e) { - logger.error("THIS IS REALLY STRANGE. YOU SHOULD NE BE HERE. Error while creating {}.", activates, e); - throw e; - } catch (ResourceRegistryException e) { - logger.error("Error while creating {}", activates, e); - throw e; - } - - hostingNode.attachResource(activates); - shareHostingNode(hostingNode); - - return activates; - - } - - private EService getEService() throws ResourceRegistryException { - EService eService = null; - ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create(); - ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory.create(); - UUID eServiceUUID = UUID.fromString(this.applicationContext.id()); - try { - resourceRegistryClient.exists(EService.class, eServiceUUID); - eService = resourceRegistryClient.getInstance(EService.class, eServiceUUID); - } catch (NotFoundException e) { - eService = instantiateEService(eServiceUUID); - eService = createActivatesRelation(eService, resourceRegistryPublisher).getTarget(); - } catch (AvailableInAnotherContextException e) { - addToContext(resourceRegistryPublisher); - eService = resourceRegistryClient.getInstance(EService.class, eServiceUUID); - } catch (ResourceRegistryException e) { - throw e; - } - return eService; - } - - - private void shareHostingNode(HostingNode hostingNode) { - logger.trace("sharing {} {}", HostingNode.NAME, Resource.NAME); - applicationContext.container().properties().add( - new Property(Constants.HOSTING_NODE_PROPERTY, hostingNode)); - } - - - - private String getCurrentContextName() { - String token = SecurityTokenProvider.instance.get(); - return getContextName(token); - } - - private String getContextName(String token) { - try { - return this.authorizationProxy.get(token).getContext(); - } catch (Exception e) { - logger.error("Error retrieving token {}, it should never happen", token); - return null; - } - } - - private void addToContext(ResourceRegistryPublisher resourceRegistryPublisher) throws ResourceRegistryException { - HostingNode hostingNode = applicationContext.container().properties().lookup(Constants.HOSTING_NODE_PROPERTY).value(HostingNode.class); - resourceRegistryPublisher.addResourceToCurrentContext(hostingNode); - logger.info("{} successfully added to current context ({})", - hostingNode, getCurrentContextName()); - shareHostingNode(hostingNode); - } - - private void removeFromContext(ResourceRegistryPublisher resourceRegistryPublisher) throws ResourceRegistryException { - HostingNode hostingNode = applicationContext.container().properties().lookup(Constants.HOSTING_NODE_PROPERTY).value(HostingNode.class); - resourceRegistryPublisher.removeResourceFromCurrentContext(hostingNode); - logger.info("{} successfully removed from current context ({})", hostingNode, getCurrentContextName()); - shareHostingNode(hostingNode); - } - - - - private void createOrUpdateServiceStateFacet(String state) throws ResourceRegistryException { - - ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory - .create(); - - EService eService = getEService(); - - ServiceStateFacet serviceStateFacet = null; - - List serviceStateFacets = eService.getFacets(ServiceStateFacet.class); - if(serviceStateFacets !=null && serviceStateFacets.size()>=1){ - serviceStateFacet = serviceStateFacets.get(0); - serviceStateFacet.setValue(state); - serviceStateFacet = resourceRegistryPublisher.updateFacet(serviceStateFacet); - - for(int i=1; i consistsOf = new ConsistsOfImpl( - eService, serviceStateFacet, null); - consistsOf = resourceRegistryPublisher.createConsistsOf(consistsOf); - - } - - // Newly created ServiceStateFacet must be added to all context - ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); - try { - Thread.currentThread().setContextClassLoader( - EServiceManager.class.getClassLoader()); - - Set startTokens = applicationContext.configuration().startTokens(); - for (String token : startTokens) { - setContextFromToken(token); - addToContext(resourceRegistryPublisher); - } - - } catch (ResourceRegistryException e) { - throw e; - } finally { - setContextFromToken(null); - Thread.currentThread().setContextClassLoader(contextCL); - } - - - //UUID eServiceUUID = eService.getHeader().getUUID(); - //eService = resourceRegistryClient.getInstance(EService.class, eServiceUUID); - share(eService); - - } - - private static String getBaseAddress(ApplicationContext context){ - ApplicationConfiguration configuration = context.configuration(); - ContainerConfiguration container = context.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,context.application().getContextPath()); - } else { - String protocol = container.protocol(); - int port = container.port(); - - baseAddress=String.format("%s://%s:%d%s", protocol , container.hostname(), port,context.application().getContextPath()); - } - return baseAddress; - } - - private EService instantiateEService(UUID uuid) { - logger.info("Creating EService for {}", applicationContext.name()); - - ApplicationConfiguration applicationConfiguration = applicationContext - .configuration(); - - 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 isIdentifiedBy = new IsIdentifiedByImpl( - eService, softwareFacet, null); - eService.addFacet(isIdentifiedBy); - - String baseAddress = EServiceManager.getBaseAddress(applicationContext); - 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); - } - } - } - - ServiceStateFacet serviceStateFacet = new ServiceStateFacetImpl(); - String state = getState(applicationContext.lifecycle()); - serviceStateFacet.setValue(state.toLowerCase()); - eService.addFacet(serviceStateFacet); - - return eService; - } - - @Override - public String toString() { - return RESOURCE_MANAGEMENT; - } - -} diff --git a/src/main/java/org/gcube/smartgears/handler/resourceregistry/HostingNodeHandler.java b/src/main/java/org/gcube/smartgears/handler/resourceregistry/HostingNodeHandler.java new file mode 100644 index 0000000..558413f --- /dev/null +++ b/src/main/java/org/gcube/smartgears/handler/resourceregistry/HostingNodeHandler.java @@ -0,0 +1,249 @@ +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.List; +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.resourcemanagement.model.reference.entities.facets.ContainerStateFacet; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Manages the {@link HostingNode} {@link Resource} of the application. + *

+ * The manager: + *

    + *
  • creates the {@link HostingNode} {@link Resource} and the facets it + * {@link ConsistsOf} when the container starts for the first time;
  • + *
  • update the {@link ContainerStateFacet} when the application becomes + * active, and at any lifecycle change thereafter;
  • + *
  • schedule a periodic update of {@link Facet}s containing variables + * information.
  • + *
+ *

+ * + * @author Luca Frosini + */ +@XmlRootElement(name = Constants.RESOURCE_MANAGEMENT) +public class HostingNodeHandler extends ContainerHandler { + + private static Logger logger = LoggerFactory.getLogger(HostingNodeHandler.class); + + private ContainerContext containerContext; + private ScheduledFuture periodicUpdates; + + protected HostingNodeManager hostingNodeManager; + + public HostingNodeHandler() { + super(); + hostingNodeManager = new HostingNodeManager(); + } + + @Override + public void onStart(Start event) { + try { + logger.info("{} onStart started", this.getClass().getSimpleName()); + containerContext = event.context(); + init(); + registerObservers(); + schedulePeriodicUpdates(); + logger.info("{} onStart terminated", this.getClass().getSimpleName()); + } catch (Throwable re) { + logger.error("onStart failed", re); + } + } + + private void init() { + ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); + String previousToken = SecurityTokenProvider.instance.get(); + try { + Thread.currentThread().setContextClassLoader(HostingNodeHandler.class.getClassLoader()); + boolean create = true; + List startTokens = containerContext.configuration().startTokens(); + for (String token : startTokens) { + ContextUtility.setContextFromToken(token); + try { + if (create) { + hostingNodeManager.createHostingNode(containerContext); + containerContext.properties().add(new Property(Constants.HOSTING_NODE_MANAGER_PROPERTY, hostingNodeManager)); + create = false; + } else { + hostingNodeManager.addToContext(); + } + } catch (Exception e) { + logger.error("Unable to add {} to current context ({})", hostingNodeManager.getHostingNode(), + ContextUtility.getContextName(token), e); + } + } + } 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 lc) { + ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); + String currentToken = SecurityTokenProvider.instance.get(); + if (currentToken == null) + currentToken = containerContext.configuration().startTokens().iterator().next(); + + ContextUtility.setContextFromToken(currentToken); + + try { + Thread.currentThread().setContextClassLoader(EServiceHandler.class.getClassLoader()); + hostingNodeManager.updateFacets(containerContext); + } catch (Exception e) { + logger.error("Failed to update {} State", HostingNode.NAME, e); + } finally { + Thread.currentThread().setContextClassLoader(contextCL); + } + + + } + + @Observes(value = addToContext) + void addTo(String token) { + ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); + String currentToken = SecurityTokenProvider.instance.get(); + if (currentToken == null) + currentToken = containerContext.configuration().startTokens().iterator().next(); + + ContextUtility.setContextFromToken(currentToken); + + try { + Thread.currentThread().setContextClassLoader(EServiceHandler.class.getClassLoader()); + hostingNodeManager.addToContext(); + } catch (Exception e) { + logger.error("Failed to update Service State", e); + } finally { + Thread.currentThread().setContextClassLoader(contextCL); + } + + } + + @Observes(value = removeFromContext) + void removeFrom(String token) { + ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); + String currentToken = SecurityTokenProvider.instance.get(); + if (currentToken == null) + currentToken = containerContext.configuration().startTokens().iterator().next(); + + ContextUtility.setContextFromToken(currentToken); + + try { + Thread.currentThread().setContextClassLoader(EServiceHandler.class.getClassLoader()); + hostingNodeManager.removeFromContext(); + } catch (Exception e) { + logger.error("Failed to update Service State", e); + } finally { + 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 lc) { + + // already running + if (periodicUpdates != null) { + return; + } + + if (lc.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 currentToken = SecurityTokenProvider.instance.get(); + if (currentToken == null) + currentToken = containerContext.configuration().startTokens().iterator().next(); + + ContextUtility.setContextFromToken(currentToken); + try { + hostingNodeManager.updateFacets(containerContext); + } catch (Exception e) { + logger.error("cannot complete periodic update of {}", HostingNode.NAME, e); + } + } + }; + + periodicUpdates = service.scheduleAtFixedRate(updateTask, 3, + containerContext.configuration().publicationFrequency(), SECONDS); + + } + + @Observes(value = { stop, failure, shutdown }, kind = resilient) + synchronized void cancelPeriodicUpdates(ContainerLifecycle ignore) { + + 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; + } + +} diff --git a/src/main/java/org/gcube/smartgears/handler/resourceregistry/HostingNodeManager.java b/src/main/java/org/gcube/smartgears/handler/resourceregistry/HostingNodeManager.java deleted file mode 100644 index bab110a..0000000 --- a/src/main/java/org/gcube/smartgears/handler/resourceregistry/HostingNodeManager.java +++ /dev/null @@ -1,835 +0,0 @@ -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.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.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -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 javax.xml.bind.annotation.XmlRootElement; - -import org.gcube.common.authorization.client.proxy.AuthorizationProxy; -import org.gcube.common.authorization.library.provider.SecurityTokenProvider; -import org.gcube.common.events.Observes; -import org.gcube.common.scope.api.ScopeProvider; -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.exceptions.AlreadyPresentException; -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.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.resourcemanagement.model.impl.entities.facets.CPUFacetImpl; -import org.gcube.resourcemanagement.model.impl.entities.facets.ContainerStateFacetImpl; -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.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.ContainerStateFacet; -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.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.library.SmartGearsConfiguration; -import org.gcube.smartgears.context.Property; -import org.gcube.smartgears.context.container.ContainerContext; -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.provider.ProviderFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Manages the {@link HostingNode} {@link Resource} of the application. - *

- * The manager: - *

    - *
  • - * creates the {@link HostingNode} {@link Resource} and the facets it - * {@link ConsistsOf} when the container starts for the first time;
  • - *
  • - * update the {@link ContainerStateFacet} when the application becomes active, - * and at any lifecycle change thereafter;
  • - *
  • - * schedule a periodic update of {@link Facet}s containing variables - * information.
  • - *
- *

- * - * @author Luca Frosini - */ -@XmlRootElement(name = Constants.RESOURCE_MANAGEMENT) -public class HostingNodeManager extends ContainerHandler { - - 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 context; - private AuthorizationProxy authorizationProxy; - - private ScheduledFuture periodicUpdates; - - public HostingNodeManager() { - super(); - this.authorizationProxy = ProviderFactory.provider() - .authorizationProxy(); - } - - private void setContextFromToken(String token) { - if (token == null || token.compareTo("") == 0) { - SecurityTokenProvider.instance.reset(); - ScopeProvider.instance.reset(); - } else { - SecurityTokenProvider.instance.set(token); - String scope = getCurrentContextName(token); - ScopeProvider.instance.set(scope); - } - - } - - @Override - public void onStart(Start e) { - try{ - logger.info("onStart started"); - context = e.context(); - HostingNode hostingNode = instantiateHostingNode(); - hostingNode = publishHostingNode(hostingNode); - registerObservers(); - schedulePeriodicUpdates(); - logger.info("onStart finished"); - }catch(Throwable re){ - logger.error("onStart failed",re); - } - } - - private void share(HostingNode hostingNode) { - logger.trace("sharing {} {}", HostingNode.NAME, Resource.NAME); - context.properties().add( - new Property(Constants.HOSTING_NODE_PROPERTY, hostingNode)); - } - - private void registerObservers() { - - context.events().subscribe(new Object() { - - @Observes({ activation, part_activation, shutdown, stop, failure }) - void onChanged(ContainerLifecycle lc) { - HostingNode hostingNode = context.properties().lookup(Constants.HOSTING_NODE_PROPERTY).value(HostingNode.class); - updateHostingNode(hostingNode); - } - - @Observes(value = addToContext) - void addTo(String token) { - HostingNode hostingNode = context.properties().lookup(Constants.HOSTING_NODE_PROPERTY).value(HostingNode.class); - addToContext(hostingNode, token); - } - - @Observes(value = removeFromContext) - void removeFrom(String token) { - HostingNode hostingNode = context.properties().lookup(Constants.HOSTING_NODE_PROPERTY).value(HostingNode.class); - removeFromContext(hostingNode, token); - } - - }); - } - - private void schedulePeriodicUpdates() { - - // register to cancel updates - context.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 lc) { - - // already running - if (periodicUpdates != null) { - return; - } - - if (lc.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() { - HostingNode hostingNode = context.properties().lookup(Constants.HOSTING_NODE_PROPERTY).value(HostingNode.class); - try { - updateHostingNode(hostingNode); - } catch (Exception e) { - logger.error( - "cannot complete periodic update of {}", - HostingNode.NAME, e); - } - } - }; - - periodicUpdates = service - .scheduleAtFixedRate(updateTask, 3, context - .configuration().publicationFrequency(), - SECONDS); - - } - - @Observes(value = { stop, failure, shutdown }, kind = resilient) - synchronized void cancelPeriodicUpdates(ContainerLifecycle ignore) { - - 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); - } - } - } - - }); - - } - - private HostingNode publishHostingNode(HostingNode hostingNode) { - ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); - String previousToken = SecurityTokenProvider.instance.get(); - try { - Thread.currentThread().setContextClassLoader( - HostingNodeManager.class.getClassLoader()); - - boolean create = true; - - List startTokens = context.configuration().startTokens(); - for (String token : startTokens) { - setContextFromToken(token); - - try { - ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory - .create(); - - if (create) { - - try { - hostingNode = resourceRegistryPublisher - .createResource(hostingNode); - share(hostingNode); - - // TODO Add a Reference to Site - /* - * node.profile().newSite().country(cfg.site().country - * ()).location(cfg.site ().location()) - * .latitude(cfg - * .site().latitude()).longitude(cfg.site - * ().longitude - * ()).domain(domainIn(cfg.hostname())); - */ - - } catch (AlreadyPresentException e) { - ResourceRegistryClient registryClient = ResourceRegistryClientFactory - .create(); - hostingNode = registryClient.getInstance( - HostingNode.class, hostingNode.getHeader() - .getUUID()); - updateHostingNode(hostingNode); - } catch (AvailableInAnotherContextException e) { - addToContext(hostingNode, token); - } - - create = false; - - } else { - addToContext(hostingNode, token); - } - - } catch (Exception e) { - logger.error("Unable to add {} to current context ({})", - hostingNode, getCurrentContextName(token), e); - } - - } - - } catch (Throwable e) { - rethrowUnchecked(e); - } finally { - setContextFromToken(previousToken); - Thread.currentThread().setContextClassLoader(contextCL); - } - logger.info("hosting node published"); - return hostingNode; - } - - private String getCurrentContextName(String token) { - try { - return this.authorizationProxy.get(token).getContext(); - } catch (Exception e) { - logger.error("Error retrieving context form token {}, it should never happen", - token, e); - return null; - } - } - - private void removeFromContext(HostingNode hostingNode, String token) { - ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); - String previousToken = SecurityTokenProvider.instance.get(); - try { - Thread.currentThread().setContextClassLoader( - HostingNodeManager.class.getClassLoader()); - setContextFromToken(token); - - boolean removed = false; - - ResourceRegistryPublisher resourceRegistryPublisher = - ResourceRegistryPublisherFactory.create(); - removed = resourceRegistryPublisher. - removeResourceFromCurrentContext(hostingNode); - - if (removed) { - logger.info( - "{} successfully removed from current context ({})", - hostingNode, getCurrentContextName(token)); - share(hostingNode); - } else { - logger.error("Unable to remove {} from current context ({})", - hostingNode, getCurrentContextName(token)); - } - - share(hostingNode); - - } catch (Exception e) { - logger.error("Unable to remove {} from current context ({})", - hostingNode, getCurrentContextName(token), e); - rethrowUnchecked(e); - } finally { - setContextFromToken(previousToken); - Thread.currentThread().setContextClassLoader(contextCL); - } - } - - private void addToContext(HostingNode hostingNode, String token) { - ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); - String previousToken = SecurityTokenProvider.instance.get(); - try { - Thread.currentThread().setContextClassLoader( - HostingNodeManager.class.getClassLoader()); - setContextFromToken(token); - - ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory - .create(); - boolean added = resourceRegistryPublisher - .addResourceToCurrentContext(hostingNode); - - if (added) { - logger.info("{} successfully added to current context ({})", - hostingNode, getCurrentContextName(token)); - share(hostingNode); - } else { - logger.error("Unable to add {} to current context ({})", - hostingNode, getCurrentContextName(token)); - } - - share(hostingNode); - - } catch (Exception e) { - logger.error("Unable to add {} to current context ({})", - hostingNode, getCurrentContextName(token), e); - rethrowUnchecked(e); - } finally { - setContextFromToken(previousToken); - Thread.currentThread().setContextClassLoader(contextCL); - } - } - - private HostingNode updateHostingNode(HostingNode hostingNode) { - ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); - String previousToken = SecurityTokenProvider.instance.get(); - try { - - if (previousToken == null) { - setContextFromToken((String) context.configuration() - .startTokens().toArray()[0]); - } - Thread.currentThread().setContextClassLoader( - HostingNodeManager.class.getClassLoader()); - - hostingNode = updateFacets(hostingNode); - - share(hostingNode); - - } catch (Exception e) { - rethrowUnchecked(e); - } finally { - setContextFromToken(previousToken); - Thread.currentThread().setContextClassLoader(contextCL); - } - return hostingNode; - - } - - private HostingNode updateFacets(HostingNode hostingNode) throws ResourceRegistryException { - logger.debug("Updating HostingNode"); - - ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory - .create(); - - ContainerStateFacet containerStateFacet = null; - MemoryFacet ramFacet = null; - MemoryFacet jvmMemoryFacet = null; - MemoryFacet disk = null; - - List> consistsOfToRemove = new ArrayList<>(); - - List> consistsOfList = hostingNode - .getConsistsOf(); - for (ConsistsOf c : consistsOfList) { - if (c.getTarget() instanceof ContainerStateFacet) { - containerStateFacet = (ContainerStateFacet) c.getTarget(); - containerStateFacet = getContainerStateFacet(containerStateFacet); - 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; - } - - consistsOfToRemove.add(c); - - } - - // Resource Update has effect only on specified facet. - // Removing the one that have not to be changed - consistsOfList.removeAll(consistsOfToRemove); - - try { - hostingNode = resourceRegistryPublisher.updateResource(hostingNode); - } catch (NotFoundException e) { - /* Update failed trying to recreate it */ - // ReAdding the removed relations to recreate all - consistsOfList.addAll(consistsOfToRemove); - hostingNode = resourceRegistryPublisher.createResource(hostingNode); - } catch (AvailableInAnotherContextException e) { - addToContext(hostingNode, SecurityTokenProvider.instance.get()); - hostingNode = resourceRegistryPublisher.updateResource(hostingNode); - } catch (ResourceRegistryException e) { - logger.error("error trying to publish hosting node",e); - } - - return hostingNode; - } - - private HostingNode instantiateHostingNode() { - logger.info("Creating {} {}", HostingNode.NAME, Resource.NAME); - - ContainerConfiguration containerConfiguration = context.configuration(); - - UUID uuid = UUID.fromString(this.context.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 isIdentifiedBy = new IsIdentifiedByImpl<>( - hostingNode, networkingFacet, null); - hostingNode.addFacet(isIdentifiedBy); - - List cpuFacets = getCPUFacets(); - for (CPUFacet cpuFacet : cpuFacets) { - hostingNode.addFacet(cpuFacet); - } - - SoftwareFacet softwareFacet = new SoftwareFacetImpl(); - OperatingSystemMXBean mxbean = ManagementFactory - .getOperatingSystemMXBean(); - softwareFacet.setGroup(mxbean.getName()); // softwareFacet.setGroup(System.getProperty("os.name")); - softwareFacet.setName(mxbean.getArch()); // softwareFacet.setName(System.getProperty("os.arch")); - softwareFacet.setVersion(mxbean.getVersion()); // softwareFacet.setName(System.getProperty("os.version")); - hostingNode.addFacet(softwareFacet); - - SimplePropertyFacet simplePropertyFacet = addEnvironmentVariables(); - hostingNode.addFacet(simplePropertyFacet); - - ContainerStateFacet containerStateFacet = getContainerStateFacet(null); - hostingNode.addFacet(containerStateFacet); - - MemoryFacet ramFacet = getRamInfo(null); - HasVolatileMemory hasVolatileRAMMemory = new HasVolatileMemoryImpl( - hostingNode, ramFacet, null); - hasVolatileRAMMemory - .setAdditionalProperty(MEMORY_TYPE, MEMORY_TYPE_RAM); - hostingNode.addFacet(hasVolatileRAMMemory); - - MemoryFacet jvmMemoryFacet = getJVMMemoryInfo(null); - HasVolatileMemory hasVolatileJVMMemory = new HasVolatileMemoryImpl( - hostingNode, jvmMemoryFacet, null); - hasVolatileJVMMemory - .setAdditionalProperty(MEMORY_TYPE, MEMORY_TYPE_JVM); - hostingNode.addFacet(hasVolatileJVMMemory); - - MemoryFacet diskFacet = getDiskSpace(null); - HasPersistentMemory hasPersistentMemory = new HasPersistentMemoryImpl( - hostingNode, diskFacet, null); - hostingNode.addFacet(hasPersistentMemory); - logger.info("hostingNode instanciated"); - return hostingNode; - } - - private ContainerStateFacet getContainerStateFacet( - ContainerStateFacet containerStateFacet) { - if (containerStateFacet == null) { - containerStateFacet = new ContainerStateFacetImpl(); - } - containerStateFacet.setValue(context.lifecycle().state().remoteForm()); - return containerStateFacet; - } - - private MemoryFacet getDiskSpace(MemoryFacet memoryFacet) { - if (memoryFacet == null) { - memoryFacet = new MemoryFacetImpl(); - } - - long free = 0; - long total = 0; - try { - FileStore fileStore = Files.getFileStore(Paths.get(context - .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 cfg = context.configuration(); - - Map map = new HashMap(); - map.putAll(cfg.properties()); - map.putAll(System.getenv()); - - SimplePropertyFacet simplePropertyFacet = new SimplePropertyFacetImpl(); - simplePropertyFacet.setName("ENVIRONMENT_VARIABLES"); - simplePropertyFacet.setValue(""); - - for (Map.Entry 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()); - - } - - simplePropertyFacet.setAdditionalProperty("Java", - System.getProperty("java.version")); - SmartGearsConfiguration config = ProviderFactory.provider() - .smartgearsConfiguration(); - - simplePropertyFacet.setAdditionalProperty("SmartGears", - config.version()); - simplePropertyFacet.setAdditionalProperty( - "ghn-update-interval-in-secs", - String.valueOf(cfg.publicationFrequency())); - - 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 getCPUFacets() { - - List 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; - } - - @Override - public String toString() { - return Constants.RESOURCE_MANAGEMENT; - } -} diff --git a/src/main/java/org/gcube/smartgears/handler/resourceregistry/resourcemanager/EServiceManager.java b/src/main/java/org/gcube/smartgears/handler/resourceregistry/resourcemanager/EServiceManager.java new file mode 100644 index 0000000..24dd86b --- /dev/null +++ b/src/main/java/org/gcube/smartgears/handler/resourceregistry/resourcemanager/EServiceManager.java @@ -0,0 +1,271 @@ +package org.gcube.smartgears.handler.resourceregistry.resourcemanager; + +import java.net.URI; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import javax.servlet.ServletRegistration; + +import org.gcube.informationsystem.model.impl.properties.HeaderImpl; +import org.gcube.informationsystem.model.impl.properties.PropagationConstraintImpl; +import org.gcube.informationsystem.model.impl.relations.ConsistsOfImpl; +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.exceptions.AlreadyPresentException; +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.context.ContextNotFoundException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceNotFoundException; +import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisher; +import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisherFactory; +import org.gcube.resourcemanagement.model.impl.entities.facets.AccessPointFacetImpl; +import org.gcube.resourcemanagement.model.impl.entities.facets.ServiceStateFacetImpl; +import org.gcube.resourcemanagement.model.impl.entities.facets.SoftwareFacetImpl; +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.ServiceStateFacet; +import org.gcube.resourcemanagement.model.reference.entities.facets.SoftwareFacet; +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.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.gcube.smartgears.handler.resourceregistry.EServiceHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EServiceManager { + + private static Logger logger = LoggerFactory.getLogger(HostingNodeManager.class); + + private static List servletExcludes = Arrays.asList("default", "jsp"); + + private ResourceRegistryPublisher resourceRegistryPublisher; + + private Activates activates; + private EService eService; + + public EServiceManager() { + this.resourceRegistryPublisher = ResourceRegistryPublisherFactory.create(); + } + + public EService geteService() { + return eService; + } + + public void addToContext(ApplicationContext applicationContext) throws ResourceNotFoundException, ContextNotFoundException, ResourceRegistryException { + HostingNode hostingNode = applicationContext.container().properties().lookup(Constants.HOSTING_NODE_MANAGER_PROPERTY) + .value(HostingNodeManager.class).getHostingNode(); + boolean added = resourceRegistryPublisher.addResourceToCurrentContext(hostingNode); + if (added) { + logger.info("{} successfully added to current context ({})", eService, + ContextUtility.getCurrentContextName()); + } else { + logger.error("Unable to add {} to current context ({})", eService, + ContextUtility.getCurrentContextName()); + } + } + + public void removeFromContext() throws ResourceNotFoundException, ContextNotFoundException, ResourceRegistryException { + boolean removed = false; + removed = resourceRegistryPublisher.removeResourceFromCurrentContext(eService); + if (removed) { + logger.info("{} successfully removed from current context ({})", eService, + ContextUtility.getCurrentContextName()); + } else { + logger.error("Unable to remove {} from current context ({})", eService, + ContextUtility.getCurrentContextName()); + } + } + + private String getBaseAddress(ApplicationContext context) { + ApplicationConfiguration configuration = context.configuration(); + ContainerConfiguration container = context.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, + context.application().getContextPath()); + } else { + String protocol = container.protocol(); + int port = container.port(); + + baseAddress = String.format("%s://%s:%d%s", protocol, container.hostname(), port, + context.application().getContextPath()); + } + return baseAddress; + } + + public String getState(ApplicationContext applicationContext) { + return applicationContext.lifecycle().state().remoteForm().toLowerCase(); + } + + private EService instantiateEService(ApplicationContext applicationContext) { + 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 isIdentifiedBy = new IsIdentifiedByImpl( + eService, softwareFacet); + eService.addFacet(isIdentifiedBy); + + String baseAddress = getBaseAddress(applicationContext); + 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); + } + } + } + + ServiceStateFacet serviceStateFacet = new ServiceStateFacetImpl(); + serviceStateFacet.setValue(getState(applicationContext)); + eService.addFacet(serviceStateFacet); + + return eService; + } + + public EService createEService(ApplicationContext applicationContext) throws ResourceRegistryException { + try { + eService = instantiateEService(applicationContext); + activates = createActivatesRelation(applicationContext, eService); + //eService = resourceRegistryPublisher.createResource(eService); + } catch (AvailableInAnotherContextException | AlreadyPresentException e) { + // resourceRegistryPublisher.delete(eService); + // eService = resourceRegistryPublisher.createResource(eService); + resourceRegistryPublisher.delete(activates); + activates = createActivatesRelation(applicationContext, eService); + } + return eService; + } + + + public void updateServiceStateFacet(ApplicationContext applicationContext) throws ResourceRegistryException { + String state = getState(applicationContext); + ServiceStateFacet serviceStateFacet = null; + + List serviceStateFacets = eService.getFacets(ServiceStateFacet.class); + if (serviceStateFacets != null && serviceStateFacets.size() >= 1) { + serviceStateFacet = serviceStateFacets.get(0); + serviceStateFacet.setValue(state); + serviceStateFacet = resourceRegistryPublisher.updateFacet(serviceStateFacet); + + for (int i = 1; i < serviceStateFacets.size(); i++) { + try { + logger.warn("You should not be here. There are more than one {}. Anyway deleting it : {}", + ServiceStateFacet.class.getSimpleName(), serviceStateFacets.get(i)); + resourceRegistryPublisher.deleteFacet(serviceStateFacets.get(i)); + } catch (Exception e) { + logger.warn("Unable to delete {} which should not exists : {}", + ServiceStateFacet.class.getSimpleName(), serviceStateFacets.get(i)); + } + } + + } else { + serviceStateFacet = new ServiceStateFacetImpl(); + serviceStateFacet.setValue(state); + serviceStateFacet = resourceRegistryPublisher.createFacet(serviceStateFacet); + + ConsistsOf consistsOf = new ConsistsOfImpl( + eService, serviceStateFacet, null); + consistsOf = resourceRegistryPublisher.createConsistsOf(consistsOf); + + } + + // Newly created ServiceStateFacet must be added to all context + ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(EServiceHandler.class.getClassLoader()); + + Set startTokens = applicationContext.configuration().startTokens(); + for (String token : startTokens) { + ContextUtility.setContextFromToken(token); + addToContext(applicationContext); + } + + } catch (ResourceRegistryException e) { + throw e; + } finally { + ContextUtility.resetContex(); + Thread.currentThread().setContextClassLoader(contextCL); + } + + } + + private Activates createActivatesRelation(ApplicationContext applicationContext, EService eService) + throws ResourceRegistryException { + + HostingNode hostingNode = applicationContext.container().properties().lookup(Constants.HOSTING_NODE_MANAGER_PROPERTY) + .value(HostingNodeManager.class).getHostingNode(); + + PropagationConstraint propagationConstraint = new PropagationConstraintImpl(); + propagationConstraint.setRemoveConstraint(RemoveConstraint.cascade); + propagationConstraint.setAddConstraint(AddConstraint.propagate); + Activates activates = new ActivatesImpl<>(hostingNode, eService, propagationConstraint); + + try { + activates = resourceRegistryPublisher.createIsRelatedTo(activates); + } catch (NotFoundException e) { + logger.error("THIS IS REALLY STRANGE. YOU SHOULD NE BE HERE. Error while creating {}.", activates, e); + throw e; + } catch (ResourceRegistryException e) { + logger.error("Error while creating {}", activates, e); + throw e; + } + + hostingNode.attachResource(activates); + + return activates; + + } + + public void removeEService(ApplicationContext applicationContext) throws ResourceRegistryException { + try { + resourceRegistryPublisher.delete(eService); + } catch (ResourceRegistryException e) { + logger.error("Unable to delete {}. Going to set the state to {}", applicationContext.name(), getState(applicationContext)); + updateServiceStateFacet(applicationContext); + } + } + +} diff --git a/src/main/java/org/gcube/smartgears/handler/resourceregistry/resourcemanager/HostingNodeManager.java b/src/main/java/org/gcube/smartgears/handler/resourceregistry/resourcemanager/HostingNodeManager.java new file mode 100644 index 0000000..1601462 --- /dev/null +++ b/src/main/java/org/gcube/smartgears/handler/resourceregistry/resourcemanager/HostingNodeManager.java @@ -0,0 +1,517 @@ +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.HashMap; +import java.util.List; +import java.util.Map; +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.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.exceptions.AlreadyPresentException; +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.context.ContextNotFoundException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceNotFoundException; +import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisher; +import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisherFactory; +import org.gcube.resourcemanagement.model.impl.entities.facets.CPUFacetImpl; +import org.gcube.resourcemanagement.model.impl.entities.facets.ContainerStateFacetImpl; +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.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.ContainerStateFacet; +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.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.library.SmartGearsConfiguration; +import org.gcube.smartgears.context.container.ContainerContext; +import org.gcube.smartgears.handler.resourceregistry.ContextUtility; +import org.gcube.smartgears.provider.ProviderFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +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 ResourceRegistryPublisher resourceRegistryPublisher; + private HostingNode hostingNode; + + public HostingNodeManager() { + this.resourceRegistryPublisher = ResourceRegistryPublisherFactory.create(); + } + + public HostingNode getHostingNode() { + return hostingNode; + } + + public void addToContext() throws ResourceNotFoundException, ContextNotFoundException, ResourceRegistryException { + boolean added = resourceRegistryPublisher.addResourceToCurrentContext(hostingNode); + if (added) { + logger.info("{} successfully added to current context ({})", hostingNode, + ContextUtility.getCurrentContextName()); + } else { + logger.error("Unable to add {} to current context ({})", hostingNode, + ContextUtility.getCurrentContextName()); + } + } + + public void removeFromContext() throws ResourceNotFoundException, ContextNotFoundException, ResourceRegistryException { + boolean removed = false; + removed = resourceRegistryPublisher.removeResourceFromCurrentContext(hostingNode); + if (removed) { + logger.info("{} successfully removed from current context ({})", hostingNode, + ContextUtility.getCurrentContextName()); + } else { + logger.error("Unable to remove {} from current context ({})", hostingNode, + ContextUtility.getCurrentContextName()); + } + } + + + public HostingNode updateFacets(ContainerContext containerContext) throws ResourceRegistryException { + logger.debug("Updating HostingNode"); + + ContainerConfiguration containerConfiguration = containerContext.configuration(); + + ContainerStateFacet containerStateFacet = null; + MemoryFacet ramFacet = null; + MemoryFacet jvmMemoryFacet = null; + MemoryFacet disk = null; + + List> consistsOfToRemove = new ArrayList<>(); + + List> consistsOfList = hostingNode.getConsistsOf(); + for (ConsistsOf c : consistsOfList) { + if (c.getTarget() instanceof ContainerStateFacet) { + containerStateFacet = (ContainerStateFacet) c.getTarget(); + containerStateFacet = getContainerStateFacet(containerStateFacet, containerContext); + 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, containerConfiguration); + continue; + } + + consistsOfToRemove.add(c); + + } + + // Resource Update has effect only on specified facet. + // Removing the one that have not to be changed + consistsOfList.removeAll(consistsOfToRemove); + + try { + hostingNode = resourceRegistryPublisher.updateResource(hostingNode); + } catch (NotFoundException e) { + /* Update failed trying to recreate it */ + // ReAdding the removed relations to recreate all + consistsOfList.addAll(consistsOfToRemove); + hostingNode = resourceRegistryPublisher.createResource(hostingNode); + } catch (AvailableInAnotherContextException e) { + addToContext(); + hostingNode = resourceRegistryPublisher.updateResource(hostingNode); + } catch (ResourceRegistryException e) { + logger.error("error trying to publish hosting node", e); + } + + return hostingNode; + } + + private String getState(ContainerContext containerContext) { + return containerContext.lifecycle().state().remoteForm().toLowerCase(); + } + + private HostingNode instantiateHostingNode(ContainerContext containerContext) { + 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 isIdentifiedBy = new IsIdentifiedByImpl<>(hostingNode, + networkingFacet, null); + hostingNode.addFacet(isIdentifiedBy); + + List cpuFacets = getCPUFacets(); + for (CPUFacet cpuFacet : cpuFacets) { + hostingNode.addFacet(cpuFacet); + } + + SoftwareFacet softwareFacet = new SoftwareFacetImpl(); + OperatingSystemMXBean mxbean = ManagementFactory.getOperatingSystemMXBean(); + softwareFacet.setGroup(mxbean.getName()); // softwareFacet.setGroup(System.getProperty("os.name")); + softwareFacet.setName(mxbean.getArch()); // softwareFacet.setName(System.getProperty("os.arch")); + softwareFacet.setVersion(mxbean.getVersion()); // softwareFacet.setName(System.getProperty("os.version")); + hostingNode.addFacet(softwareFacet); + + SimplePropertyFacet simplePropertyFacet = addEnvironmentVariables(containerConfiguration); + hostingNode.addFacet(simplePropertyFacet); + + ContainerStateFacet containerStateFacet = getContainerStateFacet(null, containerContext); + hostingNode.addFacet(containerStateFacet); + + MemoryFacet ramFacet = getRamInfo(null); + HasVolatileMemory hasVolatileRAMMemory = new HasVolatileMemoryImpl( + hostingNode, ramFacet, null); + hasVolatileRAMMemory.setAdditionalProperty(MEMORY_TYPE, MEMORY_TYPE_RAM); + hostingNode.addFacet(hasVolatileRAMMemory); + + MemoryFacet jvmMemoryFacet = getJVMMemoryInfo(null); + HasVolatileMemory hasVolatileJVMMemory = new HasVolatileMemoryImpl( + hostingNode, jvmMemoryFacet, null); + hasVolatileJVMMemory.setAdditionalProperty(MEMORY_TYPE, MEMORY_TYPE_JVM); + hostingNode.addFacet(hasVolatileJVMMemory); + + MemoryFacet diskFacet = getDiskSpace(null, containerConfiguration); + HasPersistentMemory hasPersistentMemory = new HasPersistentMemoryImpl( + hostingNode, diskFacet, null); + hostingNode.addFacet(hasPersistentMemory); + + // TODO Add a Reference to Site + /* + * node.profile().newSite().country(cfg.site().country ()).location(cfg.site + * ().location()) .latitude(cfg .site().latitude()).longitude(cfg.site + * ().longitude ()).domain(domainIn(cfg.hostname())); + */ + + logger.info("hostingNode instanciated"); + return hostingNode; + } + + public HostingNode createHostingNode(ContainerContext containerContext) throws ResourceRegistryException { + try { + hostingNode = instantiateHostingNode(containerContext); + hostingNode = resourceRegistryPublisher.createResource(hostingNode); + } catch (AvailableInAnotherContextException | AlreadyPresentException e) { + resourceRegistryPublisher.delete(hostingNode); + hostingNode = resourceRegistryPublisher.createResource(hostingNode); + } + return hostingNode; + } + + private ContainerStateFacet getContainerStateFacet(ContainerStateFacet containerStateFacet, ContainerContext containerContext) { + if(containerStateFacet==null) { + containerStateFacet = new ContainerStateFacetImpl(); + } + containerStateFacet.setValue(getState(containerContext)); + return containerStateFacet; + } + + private MemoryFacet getDiskSpace(MemoryFacet memoryFacet, ContainerConfiguration containerConfiguration) { + if (memoryFacet == null) { + memoryFacet = new MemoryFacetImpl(); + } + + long free = 0; + long total = 0; + try { + FileStore fileStore = Files + .getFileStore(Paths.get(containerConfiguration.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 map = new HashMap(); + map.putAll(containerConfiguration.properties()); + map.putAll(System.getenv()); + + SimplePropertyFacet simplePropertyFacet = new SimplePropertyFacetImpl(); + simplePropertyFacet.setName("ENVIRONMENT_VARIABLES"); + simplePropertyFacet.setValue(""); + + for (Map.Entry 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()); + + } + + simplePropertyFacet.setAdditionalProperty("Java", System.getProperty("java.version")); + SmartGearsConfiguration config = ProviderFactory.provider().smartgearsConfiguration(); + + simplePropertyFacet.setAdditionalProperty("SmartGears", config.version()); + simplePropertyFacet.setAdditionalProperty("ghn-update-interval-in-secs", + String.valueOf(containerConfiguration.publicationFrequency())); + + 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 getCPUFacets() { + + List 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; + } + +} diff --git a/src/main/resources/META-INF/services/org.gcube.smartgears.handlers.application.ApplicationHandler b/src/main/resources/META-INF/services/org.gcube.smartgears.handlers.application.ApplicationHandler index 5fa2b01..4543da6 100644 --- a/src/main/resources/META-INF/services/org.gcube.smartgears.handlers.application.ApplicationHandler +++ b/src/main/resources/META-INF/services/org.gcube.smartgears.handlers.application.ApplicationHandler @@ -1 +1 @@ -org.gcube.smartgears.handler.resourceregistry.EServiceManager \ No newline at end of file +org.gcube.smartgears.handler.resourceregistry.EServiceHandler \ No newline at end of file diff --git a/src/main/resources/META-INF/services/org.gcube.smartgears.handlers.container.ContainerHandler b/src/main/resources/META-INF/services/org.gcube.smartgears.handlers.container.ContainerHandler index 469f25f..6a534a6 100644 --- a/src/main/resources/META-INF/services/org.gcube.smartgears.handlers.container.ContainerHandler +++ b/src/main/resources/META-INF/services/org.gcube.smartgears.handlers.container.ContainerHandler @@ -1 +1 @@ -org.gcube.smartgears.handler.resourceregistry.HostingNodeManager \ No newline at end of file +org.gcube.smartgears.handler.resourceregistry.HostingNodeHandler \ No newline at end of file