diff --git a/src/main/java/org/gcube/smartgears/handler/resourceregistry/EServiceManager.java b/src/main/java/org/gcube/smartgears/handler/resourceregistry/EServiceManager.java index 6ba2ee3..86ed1de 100644 --- a/src/main/java/org/gcube/smartgears/handler/resourceregistry/EServiceManager.java +++ b/src/main/java/org/gcube/smartgears/handler/resourceregistry/EServiceManager.java @@ -52,8 +52,6 @@ import org.gcube.informationsystem.model.relation.isrelatedto.Hosts; import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceAvailableInAnotherContextException; import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceNotFoundException; -import org.gcube.informationsystem.resourceregistry.api.exceptions.er.ERAvailableInAnotherContextException; -import org.gcube.informationsystem.resourceregistry.api.exceptions.er.ERNotFoundException; import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClient; import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClientFactory; import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisher; @@ -121,12 +119,39 @@ public class EServiceManager extends ApplicationLifecycleHandler { @Override public void onStart(ApplicationLifecycleEvent.Start e) { this.applicationContext = e.context(); - EService eService = instantiateEService(); - eService = publishEservice(eService); + init(); registerObservers(); schedulePeriodicUpdates(); } + + + 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 (Exception e) { + rethrowUnchecked(e); + } finally { + setContextFromToken(previousToken); + Thread.currentThread().setContextClassLoader(contextCL); + } + } + private void share(EService eService) { logger.trace("sharing EService for {}", applicationContext.name()); applicationContext.properties().add( @@ -141,27 +166,62 @@ public class EServiceManager extends ApplicationLifecycleHandler { @Observes({ activation, stop, failure }) void onChanged(ApplicationLifecycle lc) { String state = getState(lc); - logger.debug("Moving app {} to {}", applicationContext.name(), - state); - try { - createOrUpdateServiceStateFacet(getEService(), state); - } catch (ResourceRegistryException e) { - rethrowUnchecked(e); + 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) { - //EService eService = applicationContext.properties().lookup(Constants.ESERVICE_PROPERTY).value(EService.class); - //addToContext(eService, token); - addHostingNodeToContext(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) { - // EService eService = applicationContext.properties().lookup(Constants.ESERVICE_PROPERTY).value(EService.class); - // removeFromContext(eService, token); - removeHostingNodeFromContext(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); + } } @@ -205,11 +265,9 @@ public class EServiceManager extends ApplicationLifecycleHandler { public void run() { try { String state = getState(lc); - createOrUpdateServiceStateFacet(getEService(), state); + createOrUpdateServiceStateFacet(state); } catch (Exception e) { - logger.error( - "cannot complete periodic update of EService", - e); + logger.error("Cannot complete periodic update of EService", e); } } }; @@ -247,143 +305,63 @@ public class EServiceManager extends ApplicationLifecycleHandler { } @SuppressWarnings("unchecked") - private void createHostsRelation(EService eService, - ResourceRegistryPublisher resourceRegistryPublisher) { + private Hosts createHostsRelation(EService eService, + ResourceRegistryPublisher resourceRegistryPublisher) throws ResourceRegistryException{ HostingNode hostingNode = applicationContext.container().properties().lookup(Constants.HOSTING_NODE_PROPERTY).value(HostingNode.class); - addHostingNodeToCurrentContext(); + addToContext(resourceRegistryPublisher); - Hosts hosts = null; PropagationConstraint propagationConstraint = new PropagationConstraintImpl(); propagationConstraint.setRemoveConstraint(RemoveConstraint.cascade); propagationConstraint.setAddConstraint(AddConstraint.propagate); - hosts = new HostsImpl<>(hostingNode, eService, propagationConstraint); + Hosts hosts = new HostsImpl<>(hostingNode, eService, propagationConstraint); try { hosts = resourceRegistryPublisher.createIsRelatedTo(Hosts.class, hosts); } catch (ResourceNotFoundException e) { logger.error("THIS IS REALLY STRANGE. YOU SHOULD NE BE HERE. Error while creating {}.", hosts, e); + throw e; } catch (ResourceRegistryException e) { logger.error("Error while creating {}", hosts, e); + throw e; } + + hostingNode.attachResource(hosts); + shareHostingNode(hostingNode); + + return hosts; } 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 (ERNotFoundException e) { - eService = instantiateEService(); - eService = publishEservice(eService); - } catch (ERAvailableInAnotherContextException e) { - addHostingNodeToCurrentContext(); + } catch (ResourceNotFoundException e) { + eService = instantiateEService(eServiceUUID); + eService = createHostsRelation(eService, resourceRegistryPublisher).getTarget(); + } catch (ResourceAvailableInAnotherContextException e) { + addToContext(resourceRegistryPublisher); eService = resourceRegistryClient.getInstance(EService.class, eServiceUUID); } catch (ResourceRegistryException e) { throw e; } - return eService; } - private EService createEServiceAndHosts( - ResourceRegistryPublisher resourceRegistryPublisher, - EService eService) throws ResourceRegistryException { - - ResourceRegistryClient registryClient = ResourceRegistryClientFactory.create(); - - UUID eServiceUUID = eService.getHeader().getUUID(); - - try { - registryClient.exists(EService.class, eServiceUUID); - } catch (ResourceAvailableInAnotherContextException e) { - addHostingNodeToCurrentContext(); - try { - eService = registryClient.getInstance(EService.class, eServiceUUID); - }catch (ResourceAvailableInAnotherContextException e1) { - String token = SecurityTokenProvider.instance.get(); - addToContext(eService, token); - logger.warn("Trying to add hosting node to current context did not affect the eService with UUID {}. The {} Relation was not created of the propagation constaint were modified. Please check it", eServiceUUID, Hosts.NAME); - } catch (ResourceRegistryException e1) { - throw e1; - } - } catch (ResourceNotFoundException e) { - try { - createHostsRelation(eService, resourceRegistryPublisher); - } catch (Exception ex) { - String error = String.format( - "Unable to Create %s relation from % to % (%s : %s)", - Hosts.NAME, HostingNode.NAME, EService.NAME, - applicationContext.name(), eService.getHeader().getUUID()); - logger.error(error, ex); - throw new ResourceRegistryException(error, ex); - } - } 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 EService publishEservice(EService eService) { - ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); - String previousToken = SecurityTokenProvider.instance.get(); - try { - Thread.currentThread().setContextClassLoader( - EServiceManager.class.getClassLoader()); - - boolean create = true; - - Set startTokens = applicationContext.configuration().startTokens(); - for (String token : startTokens) { - setContextFromToken(token); - - try { - ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory - .create(); - if (create) { - - eService = createEServiceAndHosts( - resourceRegistryPublisher, eService); - - share(eService); - - create = false; - - } else { - addHostingNodeToContext(token); - } - - } catch (ResourceRegistryException e) { - logger.error("Unable to add {} to current context ({})", - eService, getContextName(token), e); - } - - } - - } catch (Exception e) { - rethrowUnchecked(e); - } finally { - setContextFromToken(previousToken); - Thread.currentThread().setContextClassLoader(contextCL); - } - - return eService; - - } + private String getCurrentContextName() { String token = SecurityTokenProvider.instance.get(); @@ -394,217 +372,91 @@ public class EServiceManager extends ApplicationLifecycleHandler { try { return this.authorizationProxy.get(token).getContext(); } catch (Exception e) { - logger.error("Error retrieving token {}, it should never happen", - token); + logger.error("Error retrieving token {}, it should never happen", token); return null; } } - private boolean addHostingNodeToCurrentContext(){ - String token = SecurityTokenProvider.instance.get(); - return addHostingNodeToContext(token); - } - - private boolean addHostingNodeToContext(String token){ - + private void addToContext(ResourceRegistryPublisher resourceRegistryPublisher) throws ResourceRegistryException { HostingNode hostingNode = applicationContext.container().properties().lookup(Constants.HOSTING_NODE_PROPERTY).value(HostingNode.class); - - ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); - String previousToken = SecurityTokenProvider.instance.get(); - - try { - Thread.currentThread().setContextClassLoader( - EServiceManager.class.getClassLoader()); - setContextFromToken(token); - - ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory.create(); - resourceRegistryPublisher.addResourceToContext(hostingNode); - - logger.info("{} successfully added to current context ({})", - hostingNode, getContextName(token)); - shareHostingNode(hostingNode); - - return true; - } catch (Exception e) { - logger.error("Unable to add {} to current context ({})", hostingNode, - getCurrentContextName(), e); - rethrowUnchecked(e); - return false; - } finally { - setContextFromToken(previousToken); - Thread.currentThread().setContextClassLoader(contextCL); - } + resourceRegistryPublisher.addResourceToContext(hostingNode); + logger.info("{} successfully added to current context ({})", + hostingNode, getCurrentContextName()); + shareHostingNode(hostingNode); } - /* - private boolean removeHostingNodeFromContext() { - String token = SecurityTokenProvider.instance.get(); - return removeHostingNodeFromContext(token); - } - */ - - private boolean removeHostingNodeFromContext(String token) { - + private void removeFromContext(ResourceRegistryPublisher resourceRegistryPublisher) throws ResourceRegistryException { HostingNode hostingNode = applicationContext.container().properties().lookup(Constants.HOSTING_NODE_PROPERTY).value(HostingNode.class); - - ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); - String previousToken = SecurityTokenProvider.instance.get(); - try { - Thread.currentThread().setContextClassLoader( - EServiceManager.class.getClassLoader()); - setContextFromToken(token); - - ResourceRegistryPublisher resourceRegistryPublisher = - ResourceRegistryPublisherFactory.create(); - resourceRegistryPublisher - .removeResourceFromContext(hostingNode); - - logger.info("{} successfully removed from current context ({})", - hostingNode, getContextName(token)); - shareHostingNode(hostingNode); - - return true; - } catch (Exception e) { - logger.error("Unable to remove {} from current context ({})", - hostingNode, getContextName(token), e); - rethrowUnchecked(e); - return false; - } finally { - setContextFromToken(previousToken); - Thread.currentThread().setContextClassLoader(contextCL); - } + resourceRegistryPublisher.removeResourceFromContext(hostingNode); + logger.info("{} successfully removed from current context ({})", hostingNode, getCurrentContextName()); + shareHostingNode(hostingNode); } - /* - private void removeFromContext(EService eService, String token) { - ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); - String previousToken = SecurityTokenProvider.instance.get(); - try { - Thread.currentThread().setContextClassLoader( - EServiceManager.class.getClassLoader()); - setContextFromToken(token); - - boolean removed = false; - - ResourceRegistryPublisher resourceRegistryPublisher = - ResourceRegistryPublisherFactory.create(); - removed = resourceRegistryPublisher - .removeResourceFromContext(eService); - - if (removed) { - logger.info( - "{} successfully removed from current context ({})", - eService, getContextName(token)); - share(eService); - } else { - logger.error("Unable to remove {} from current context ({})", - eService, getContextName(token)); - } - - share(eService); - - } catch (Exception e) { - logger.error("Unable to remove {} from current context ({})", - eService, getContextName(token), e); - rethrowUnchecked(e); - } finally { - setContextFromToken(previousToken); - Thread.currentThread().setContextClassLoader(contextCL); - } - } - */ - - private void addToContext(EService eService, 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(); - boolean added = resourceRegistryPublisher - .addResourceToContext(eService); - - if (added) { - logger.info("{} successfully added to current context ({})", - eService, getContextName(token)); - share(eService); - } else { - logger.error("Unable to add {} to current context ({})", - eService, getContextName(token)); - } - - share(eService); - - } catch (Exception e) { - logger.error("Unable to add {} to current context ({})", eService, - getContextName(token), e); - rethrowUnchecked(e); - } finally { - setContextFromToken(previousToken); - Thread.currentThread().setContextClassLoader(contextCL); - } - } + @SuppressWarnings("unchecked") - private void createOrUpdateServiceStateFacet(EService eService, String state) throws ResourceRegistryException { - String previousToken = SecurityTokenProvider.instance.get(); - if (previousToken == null) { - setContextFromToken((String) applicationContext.configuration().startTokens().toArray()[0]); - } - - ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(EServiceManager.class.getClassLoader()); - + private void createOrUpdateServiceStateFacet(String state) throws ResourceRegistryException { ResourceRegistryClient resourceRegistryClient= ResourceRegistryClientFactory .create(); ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory .create(); - UUID eServiceUUID = eService.getHeader().getUUID(); + EService eService = getEService(); - try { - 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.class, serviceStateFacet); - - for(int i=1; i serviceStateFacets = eService.getFacets(ServiceStateFacet.class); + if(serviceStateFacets !=null && serviceStateFacets.size()>=1){ + serviceStateFacet = serviceStateFacets.get(0); + serviceStateFacet.setValue(state); + serviceStateFacet = resourceRegistryPublisher.updateFacet(ServiceStateFacet.class, serviceStateFacet); + + for(int i=1; i consistsOf = new ConsistsOfImpl( - eService, serviceStateFacet, null); - consistsOf = resourceRegistryPublisher.createConsistsOf(ConsistsOf.class, consistsOf); - } - eService = resourceRegistryClient.getInstance(EService.class, eServiceUUID); - share(eService); + }else { + serviceStateFacet = new ServiceStateFacetImpl(); + serviceStateFacet.setValue(state); + serviceStateFacet = resourceRegistryPublisher.createFacet(ServiceStateFacet.class, serviceStateFacet); + + ConsistsOf consistsOf = new ConsistsOfImpl( + eService, serviceStateFacet, null); + consistsOf = resourceRegistryPublisher.createConsistsOf(ConsistsOf.class, consistsOf); + + + // Newly created ServiceStateFacet must be added to all context + ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); + String previousToken = SecurityTokenProvider.instance.get(); + try { + Thread.currentThread().setContextClassLoader( + EServiceManager.class.getClassLoader()); - } catch (Exception e) { - rethrowUnchecked(e); - } finally { - Thread.currentThread().setContextClassLoader(contextCL); + Set startTokens = applicationContext.configuration().startTokens(); + for (String token : startTokens) { + setContextFromToken(token); + addToContext(resourceRegistryPublisher); + } + + } catch (ResourceRegistryException e) { + throw e; + } finally { + setContextFromToken(previousToken); + Thread.currentThread().setContextClassLoader(contextCL); + } + } + + UUID eServiceUUID = eService.getHeader().getUUID(); + eService = resourceRegistryClient.getInstance(EService.class, eServiceUUID); + share(eService); } @@ -626,13 +478,12 @@ public class EServiceManager extends ApplicationLifecycleHandler { return baseAddress; } - private EService instantiateEService() { + private EService instantiateEService(UUID uuid) { logger.info("Creating EService for {}", applicationContext.name()); ApplicationConfiguration applicationConfiguration = applicationContext .configuration(); - UUID uuid = UUID.fromString(this.applicationContext.id()); EService eService = new EServiceImpl(); Header header = new HeaderImpl(uuid); eService.setHeader(header);