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:
+ *
+ * - creates the {@link EService} {@link Resource} and the facets it
+ * {@link ConsistsOf} when the application starts for the first time;
+ * - update the {@link ServiceStateFacet} when the application becomes active,
+ * and at any lifecycle change thereafter;
+ *
+ *
+ *
+ * @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:
- *
- * -
- * creates the {@link EService} {@link Resource} and the facets it
- * {@link ConsistsOf} when the application starts for the first time;
- * -
- * update the {@link ServiceStateFacet} when the application becomes active, and
- * at any lifecycle change thereafter;
- *
- *
- *
- * @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 extends Resource, ? extends Facet> 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 extends Resource, ? extends Facet> 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