different management of exceptions

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/Common/resource-registry-handlers@148301 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Luca Frosini 2017-05-04 17:44:59 +00:00
parent b5416a1731
commit d639fe3e9d
1 changed files with 157 additions and 306 deletions

View File

@ -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.ResourceRegistryException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceAvailableInAnotherContextException; 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.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.ResourceRegistryClient;
import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClientFactory; import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClientFactory;
import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisher; import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisher;
@ -121,12 +119,39 @@ public class EServiceManager extends ApplicationLifecycleHandler {
@Override @Override
public void onStart(ApplicationLifecycleEvent.Start e) { public void onStart(ApplicationLifecycleEvent.Start e) {
this.applicationContext = e.context(); this.applicationContext = e.context();
EService eService = instantiateEService(); init();
eService = publishEservice(eService);
registerObservers(); registerObservers();
schedulePeriodicUpdates(); 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<String> 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) { private void share(EService eService) {
logger.trace("sharing EService for {}", applicationContext.name()); logger.trace("sharing EService for {}", applicationContext.name());
applicationContext.properties().add( applicationContext.properties().add(
@ -141,27 +166,62 @@ public class EServiceManager extends ApplicationLifecycleHandler {
@Observes({ activation, stop, failure }) @Observes({ activation, stop, failure })
void onChanged(ApplicationLifecycle lc) { void onChanged(ApplicationLifecycle lc) {
String state = getState(lc); String state = getState(lc);
logger.debug("Moving app {} to {}", applicationContext.name(), logger.debug("Moving app {} to {}", applicationContext.name(), state);
state);
try { ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
createOrUpdateServiceStateFacet(getEService(), state); String previousToken = SecurityTokenProvider.instance.get();
} catch (ResourceRegistryException e) { if(previousToken==null){
rethrowUnchecked(e); 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) @Observes(value = addToContext)
void addTo(String token) { void addTo(String token) {
//EService eService = applicationContext.properties().lookup(Constants.ESERVICE_PROPERTY).value(EService.class); ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
//addToContext(eService, token); String previousToken = SecurityTokenProvider.instance.get();
addHostingNodeToContext(token); 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) @Observes(value = removeFromContext)
void removeFrom(String token) { void removeFrom(String token) {
// EService eService = applicationContext.properties().lookup(Constants.ESERVICE_PROPERTY).value(EService.class); ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
// removeFromContext(eService, token); String previousToken = SecurityTokenProvider.instance.get();
removeHostingNodeFromContext(token); 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() { public void run() {
try { try {
String state = getState(lc); String state = getState(lc);
createOrUpdateServiceStateFacet(getEService(), state); createOrUpdateServiceStateFacet(state);
} catch (Exception e) { } catch (Exception e) {
logger.error( logger.error("Cannot complete periodic update of EService", e);
"cannot complete periodic update of EService",
e);
} }
} }
}; };
@ -247,143 +305,63 @@ public class EServiceManager extends ApplicationLifecycleHandler {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void createHostsRelation(EService eService, private Hosts<HostingNode, EService> createHostsRelation(EService eService,
ResourceRegistryPublisher resourceRegistryPublisher) { ResourceRegistryPublisher resourceRegistryPublisher) throws ResourceRegistryException{
HostingNode hostingNode = applicationContext.container().properties().lookup(Constants.HOSTING_NODE_PROPERTY).value(HostingNode.class); HostingNode hostingNode = applicationContext.container().properties().lookup(Constants.HOSTING_NODE_PROPERTY).value(HostingNode.class);
addHostingNodeToCurrentContext(); addToContext(resourceRegistryPublisher);
Hosts<HostingNode, EService> hosts = null;
PropagationConstraint propagationConstraint = new PropagationConstraintImpl(); PropagationConstraint propagationConstraint = new PropagationConstraintImpl();
propagationConstraint.setRemoveConstraint(RemoveConstraint.cascade); propagationConstraint.setRemoveConstraint(RemoveConstraint.cascade);
propagationConstraint.setAddConstraint(AddConstraint.propagate); propagationConstraint.setAddConstraint(AddConstraint.propagate);
hosts = new HostsImpl<>(hostingNode, eService, propagationConstraint); Hosts<HostingNode, EService> hosts = new HostsImpl<>(hostingNode, eService, propagationConstraint);
try { try {
hosts = resourceRegistryPublisher.createIsRelatedTo(Hosts.class, hosts); hosts = resourceRegistryPublisher.createIsRelatedTo(Hosts.class, hosts);
} catch (ResourceNotFoundException e) { } catch (ResourceNotFoundException e) {
logger.error("THIS IS REALLY STRANGE. YOU SHOULD NE BE HERE. Error while creating {}.", hosts, e); logger.error("THIS IS REALLY STRANGE. YOU SHOULD NE BE HERE. Error while creating {}.", hosts, e);
throw e;
} catch (ResourceRegistryException e) { } catch (ResourceRegistryException e) {
logger.error("Error while creating {}", hosts, e); logger.error("Error while creating {}", hosts, e);
throw e;
} }
hostingNode.attachResource(hosts);
shareHostingNode(hostingNode);
return hosts;
} }
private EService getEService() throws ResourceRegistryException { private EService getEService() throws ResourceRegistryException {
EService eService = null; EService eService = null;
ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create(); ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory.create();
UUID eServiceUUID = UUID.fromString(this.applicationContext.id()); UUID eServiceUUID = UUID.fromString(this.applicationContext.id());
try { try {
resourceRegistryClient.exists(EService.class, eServiceUUID); resourceRegistryClient.exists(EService.class, eServiceUUID);
eService = resourceRegistryClient.getInstance(EService.class, eServiceUUID); eService = resourceRegistryClient.getInstance(EService.class, eServiceUUID);
} catch (ERNotFoundException e) { } catch (ResourceNotFoundException e) {
eService = instantiateEService(); eService = instantiateEService(eServiceUUID);
eService = publishEservice(eService); eService = createHostsRelation(eService, resourceRegistryPublisher).getTarget();
} catch (ERAvailableInAnotherContextException e) { } catch (ResourceAvailableInAnotherContextException e) {
addHostingNodeToCurrentContext(); addToContext(resourceRegistryPublisher);
eService = resourceRegistryClient.getInstance(EService.class, eServiceUUID); eService = resourceRegistryClient.getInstance(EService.class, eServiceUUID);
} catch (ResourceRegistryException e) { } catch (ResourceRegistryException e) {
throw e; throw e;
} }
return eService; 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) { private void shareHostingNode(HostingNode hostingNode) {
logger.trace("sharing {} {}", HostingNode.NAME, Resource.NAME); logger.trace("sharing {} {}", HostingNode.NAME, Resource.NAME);
applicationContext.container().properties().add( applicationContext.container().properties().add(
new Property(Constants.HOSTING_NODE_PROPERTY, hostingNode)); 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<String> 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() { private String getCurrentContextName() {
String token = SecurityTokenProvider.instance.get(); String token = SecurityTokenProvider.instance.get();
@ -394,217 +372,91 @@ public class EServiceManager extends ApplicationLifecycleHandler {
try { try {
return this.authorizationProxy.get(token).getContext(); return this.authorizationProxy.get(token).getContext();
} catch (Exception e) { } catch (Exception e) {
logger.error("Error retrieving token {}, it should never happen", logger.error("Error retrieving token {}, it should never happen", token);
token);
return null; return null;
} }
} }
private boolean addHostingNodeToCurrentContext(){ private void addToContext(ResourceRegistryPublisher resourceRegistryPublisher) throws ResourceRegistryException {
String token = SecurityTokenProvider.instance.get();
return addHostingNodeToContext(token);
}
private boolean addHostingNodeToContext(String token){
HostingNode hostingNode = applicationContext.container().properties().lookup(Constants.HOSTING_NODE_PROPERTY).value(HostingNode.class); HostingNode hostingNode = applicationContext.container().properties().lookup(Constants.HOSTING_NODE_PROPERTY).value(HostingNode.class);
resourceRegistryPublisher.addResourceToContext(hostingNode);
ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); logger.info("{} successfully added to current context ({})",
String previousToken = SecurityTokenProvider.instance.get(); hostingNode, getCurrentContextName());
shareHostingNode(hostingNode);
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);
}
} }
/* private void removeFromContext(ResourceRegistryPublisher resourceRegistryPublisher) throws ResourceRegistryException {
private boolean removeHostingNodeFromContext() {
String token = SecurityTokenProvider.instance.get();
return removeHostingNodeFromContext(token);
}
*/
private boolean removeHostingNodeFromContext(String token) {
HostingNode hostingNode = applicationContext.container().properties().lookup(Constants.HOSTING_NODE_PROPERTY).value(HostingNode.class); HostingNode hostingNode = applicationContext.container().properties().lookup(Constants.HOSTING_NODE_PROPERTY).value(HostingNode.class);
resourceRegistryPublisher.removeResourceFromContext(hostingNode);
ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); logger.info("{} successfully removed from current context ({})", hostingNode, getCurrentContextName());
String previousToken = SecurityTokenProvider.instance.get(); shareHostingNode(hostingNode);
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);
}
} }
/*
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") @SuppressWarnings("unchecked")
private void createOrUpdateServiceStateFacet(EService eService, String state) throws ResourceRegistryException { private void createOrUpdateServiceStateFacet(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());
ResourceRegistryClient resourceRegistryClient= ResourceRegistryClientFactory ResourceRegistryClient resourceRegistryClient= ResourceRegistryClientFactory
.create(); .create();
ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory
.create(); .create();
UUID eServiceUUID = eService.getHeader().getUUID(); EService eService = getEService();
try {
ServiceStateFacet serviceStateFacet = null; ServiceStateFacet serviceStateFacet = null;
List<ServiceStateFacet> serviceStateFacets = eService.getFacets(ServiceStateFacet.class);
List<ServiceStateFacet> serviceStateFacets = eService.getFacets(ServiceStateFacet.class); if(serviceStateFacets !=null && serviceStateFacets.size()>=1){
if(serviceStateFacets !=null && serviceStateFacets.size()>=1){ serviceStateFacet = serviceStateFacets.get(0);
serviceStateFacet = serviceStateFacets.get(0); serviceStateFacet.setValue(state);
serviceStateFacet.setValue(state); serviceStateFacet = resourceRegistryPublisher.updateFacet(ServiceStateFacet.class, serviceStateFacet);
serviceStateFacet = resourceRegistryPublisher.updateFacet(ServiceStateFacet.class, serviceStateFacet);
for(int i=1; i<serviceStateFacets.size(); i++){
for(int i=1; i<serviceStateFacets.size(); i++){ try {
try { logger.warn("You should not be here. There are more than one {}. Anyway deleting it : {}", ServiceStateFacet.class.getSimpleName(), serviceStateFacets.get(i));
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));
resourceRegistryPublisher.deleteFacet(serviceStateFacets.get(i)); }catch (Exception e) {
}catch (Exception e) { logger.warn("Unable to delete {} which should not exists : {}", ServiceStateFacet.class.getSimpleName(), serviceStateFacets.get(i));
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.class, serviceStateFacet);
ConsistsOf<EService, ServiceStateFacet> consistsOf = new ConsistsOfImpl<EService, ServiceStateFacet>(
eService, serviceStateFacet, null);
consistsOf = resourceRegistryPublisher.createConsistsOf(ConsistsOf.class, consistsOf);
} }
eService = resourceRegistryClient.getInstance(EService.class, eServiceUUID); }else {
share(eService); serviceStateFacet = new ServiceStateFacetImpl();
serviceStateFacet.setValue(state);
serviceStateFacet = resourceRegistryPublisher.createFacet(ServiceStateFacet.class, serviceStateFacet);
ConsistsOf<EService, ServiceStateFacet> consistsOf = new ConsistsOfImpl<EService, ServiceStateFacet>(
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) { Set<String> startTokens = applicationContext.configuration().startTokens();
rethrowUnchecked(e); for (String token : startTokens) {
} finally { setContextFromToken(token);
Thread.currentThread().setContextClassLoader(contextCL); 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; return baseAddress;
} }
private EService instantiateEService() { private EService instantiateEService(UUID uuid) {
logger.info("Creating EService for {}", applicationContext.name()); logger.info("Creating EService for {}", applicationContext.name());
ApplicationConfiguration applicationConfiguration = applicationContext ApplicationConfiguration applicationConfiguration = applicationContext
.configuration(); .configuration();
UUID uuid = UUID.fromString(this.applicationContext.id());
EService eService = new EServiceImpl(); EService eService = new EServiceImpl();
Header header = new HeaderImpl(uuid); Header header = new HeaderImpl(uuid);
eService.setHeader(header); eService.setHeader(header);