2017-04-03 17:15:36 +02:00
|
|
|
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.impl.embedded.HeaderImpl;
|
|
|
|
import org.gcube.informationsystem.impl.embedded.PropagationConstraintImpl;
|
|
|
|
import org.gcube.informationsystem.impl.embedded.ValueSchemaImpl;
|
|
|
|
import org.gcube.informationsystem.impl.entity.facet.AccessPointFacetImpl;
|
|
|
|
import org.gcube.informationsystem.impl.entity.facet.ServiceStateFacetImpl;
|
|
|
|
import org.gcube.informationsystem.impl.entity.facet.SoftwareFacetImpl;
|
|
|
|
import org.gcube.informationsystem.impl.entity.resource.EServiceImpl;
|
|
|
|
import org.gcube.informationsystem.impl.relation.ConsistsOfImpl;
|
|
|
|
import org.gcube.informationsystem.impl.relation.IsIdentifiedByImpl;
|
|
|
|
import org.gcube.informationsystem.impl.relation.isrelatedto.HostsImpl;
|
|
|
|
import org.gcube.informationsystem.model.embedded.Header;
|
|
|
|
import org.gcube.informationsystem.model.embedded.PropagationConstraint;
|
|
|
|
import org.gcube.informationsystem.model.embedded.PropagationConstraint.AddConstraint;
|
|
|
|
import org.gcube.informationsystem.model.embedded.PropagationConstraint.RemoveConstraint;
|
|
|
|
import org.gcube.informationsystem.model.embedded.ValueSchema;
|
|
|
|
import org.gcube.informationsystem.model.entity.Facet;
|
|
|
|
import org.gcube.informationsystem.model.entity.Resource;
|
|
|
|
import org.gcube.informationsystem.model.entity.facet.AccessPointFacet;
|
|
|
|
import org.gcube.informationsystem.model.entity.facet.ServiceStateFacet;
|
|
|
|
import org.gcube.informationsystem.model.entity.facet.SoftwareFacet;
|
|
|
|
import org.gcube.informationsystem.model.entity.resource.EService;
|
|
|
|
import org.gcube.informationsystem.model.entity.resource.HostingNode;
|
|
|
|
import org.gcube.informationsystem.model.relation.ConsistsOf;
|
|
|
|
import org.gcube.informationsystem.model.relation.IsIdentifiedBy;
|
|
|
|
import org.gcube.informationsystem.model.relation.IsRelatedTo;
|
|
|
|
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.ResourceAlreadyPresentException;
|
2017-04-04 16:18:14 +02:00
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceAvailableInAnotherContextException;
|
2017-04-03 17:15:36 +02:00
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceNotFoundException;
|
2017-04-04 14:01:32 +02:00
|
|
|
import org.gcube.informationsystem.resourceregistry.client.Direction;
|
|
|
|
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;
|
2017-04-03 17:15:36 +02:00
|
|
|
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.
|
|
|
|
* <p>
|
|
|
|
* The manager:
|
|
|
|
* <ul>
|
|
|
|
* <li>
|
|
|
|
* creates the {@link EService} {@link Resource} and the facets it
|
|
|
|
* {@link ConsistsOf} when the application starts for the first time;</li>
|
|
|
|
* <li>
|
|
|
|
* update the {@link ServiceStateFacet} when the application becomes active, and
|
|
|
|
* at any lifecycle change thereafter;</li>
|
|
|
|
* </ul>
|
|
|
|
* </p>
|
|
|
|
*
|
|
|
|
* @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<String> 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);
|
2017-04-04 16:18:14 +02:00
|
|
|
String scope = getContextName(token);
|
2017-04-03 17:15:36 +02:00
|
|
|
ScopeProvider.instance.set(scope);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onStart(ApplicationLifecycleEvent.Start e) {
|
|
|
|
this.applicationContext = e.context();
|
|
|
|
EService eService = instantiateEService();
|
|
|
|
eService = publishEservice(eService);
|
|
|
|
registerObservers();
|
|
|
|
schedulePeriodicUpdates();
|
|
|
|
}
|
|
|
|
|
|
|
|
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 = lc.state().remoteForm().toLowerCase();
|
|
|
|
logger.debug("Moving app {} to {}", applicationContext.name(),
|
|
|
|
state);
|
|
|
|
EService eService = applicationContext.properties().lookup(Constants.ESERVICE_PROPERTY).value(EService.class);
|
|
|
|
createOrUpdateServiceStateFacet(eService, state);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Observes(value = addToContext)
|
|
|
|
void addTo(String token) {
|
2017-04-04 16:18:14 +02:00
|
|
|
//EService eService = applicationContext.properties().lookup(Constants.ESERVICE_PROPERTY).value(EService.class);
|
|
|
|
//addToContext(eService, token);
|
|
|
|
addHostingNodeToContext(token);
|
2017-04-03 17:15:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Observes(value = removeFromContext)
|
|
|
|
void removeFrom(String token) {
|
2017-04-04 16:18:14 +02:00
|
|
|
// EService eService = applicationContext.properties().lookup(Constants.ESERVICE_PROPERTY).value(EService.class);
|
|
|
|
// removeFromContext(eService, token);
|
|
|
|
removeHostingNodeFromContext(token);
|
|
|
|
|
2017-04-03 17:15:36 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
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() {
|
|
|
|
EService eService = applicationContext.properties().lookup(Constants.ESERVICE_PROPERTY).value(EService.class);
|
|
|
|
try {
|
|
|
|
String state = lc.state().remoteForm()
|
|
|
|
.toLowerCase();
|
|
|
|
createOrUpdateServiceStateFacet(eService, 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
private void createHostsRelation(EService eService,
|
|
|
|
ResourceRegistryPublisher resourceRegistryPublisher) {
|
2017-04-04 16:18:14 +02:00
|
|
|
|
2017-04-03 17:15:36 +02:00
|
|
|
HostingNode hostingNode = applicationContext.container().properties().lookup(Constants.HOSTING_NODE_PROPERTY).value(HostingNode.class);
|
|
|
|
|
|
|
|
if (hostingNode != null) {
|
|
|
|
|
|
|
|
ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
|
|
|
|
|
|
|
|
Hosts<HostingNode, EService> hosts = null;
|
|
|
|
|
|
|
|
try {
|
|
|
|
List<Resource> resources = resourceRegistryClient.getInstancesFromEntity(Hosts.NAME, false, hostingNode.getHeader().getUUID(), Direction.out);
|
|
|
|
for(Resource resource : resources){
|
|
|
|
if(resource instanceof HostingNode && resource.getHeader().getUUID().compareTo(hostingNode.getHeader().getUUID())==0){
|
|
|
|
List<IsRelatedTo<? extends Resource, ? extends Resource>> isRelatedToList = resource.getIsRelatedTo();
|
|
|
|
for (IsRelatedTo<? extends Resource, ? extends Resource> isRelatedTo : isRelatedToList) {
|
|
|
|
if (isRelatedTo instanceof Hosts) {
|
|
|
|
if (isRelatedTo.getTarget().getHeader().getUUID()
|
|
|
|
.compareTo(eService.getHeader().getUUID()) == 0) {
|
|
|
|
hosts = (Hosts<HostingNode, EService>) isRelatedTo;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-04 16:18:14 +02:00
|
|
|
} catch (Exception e) {
|
|
|
|
logger.warn("Error while trying to retrieve Hosts relation", e);
|
2017-04-03 17:15:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (hosts == null) {
|
|
|
|
PropagationConstraint propagationConstraint = new PropagationConstraintImpl();
|
|
|
|
propagationConstraint
|
|
|
|
.setRemoveConstraint(RemoveConstraint.cascade);
|
|
|
|
propagationConstraint
|
|
|
|
.setAddConstraint(AddConstraint.propagate);
|
|
|
|
|
|
|
|
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);
|
|
|
|
} catch (ResourceRegistryException e) {
|
|
|
|
logger.error("Error while creating {}", hosts, e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private EService createEServiceAndHosts(
|
|
|
|
ResourceRegistryPublisher resourceRegistryPublisher,
|
|
|
|
EService eService) throws ResourceRegistryException {
|
2017-04-04 16:18:14 +02:00
|
|
|
|
2017-04-03 17:15:36 +02:00
|
|
|
try {
|
|
|
|
eService = resourceRegistryPublisher.createResource(EService.class,
|
|
|
|
eService);
|
2017-04-04 16:18:14 +02:00
|
|
|
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);
|
|
|
|
}
|
2017-04-03 17:15:36 +02:00
|
|
|
} catch (ResourceAlreadyPresentException e) {
|
2017-04-04 16:18:14 +02:00
|
|
|
ResourceRegistryClient registryClient = ResourceRegistryClientFactory.create();
|
|
|
|
eService = registryClient.getInstance(EService.class, eService.getHeader().getUUID());
|
2017-04-06 15:05:03 +02:00
|
|
|
String state = applicationContext.lifecycle().state().remoteForm().toLowerCase();
|
|
|
|
logger.debug("Moving app {} to {}", applicationContext.name(), state);
|
|
|
|
createOrUpdateServiceStateFacet(eService, state);
|
2017-04-04 16:18:14 +02:00
|
|
|
} catch (ResourceAvailableInAnotherContextException e) {
|
|
|
|
// Adding the HostingNode I also add the EService thanks to propagationConstraint
|
|
|
|
addHostingNodeToCurrentContext();
|
|
|
|
ResourceRegistryClient registryClient = ResourceRegistryClientFactory.create();
|
|
|
|
eService = registryClient.getInstance(EService.class, eService.getHeader().getUUID());
|
2017-04-03 17:15:36 +02:00
|
|
|
}
|
|
|
|
return eService;
|
|
|
|
}
|
2017-04-04 16:18:14 +02:00
|
|
|
|
|
|
|
private void shareHostingNode(HostingNode hostingNode) {
|
|
|
|
logger.trace("sharing {} {}", HostingNode.NAME, Resource.NAME);
|
|
|
|
applicationContext.container().properties().add(
|
|
|
|
new Property(Constants.HOSTING_NODE_PROPERTY, hostingNode));
|
|
|
|
}
|
|
|
|
|
2017-04-03 17:15:36 +02:00
|
|
|
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;
|
|
|
|
|
2017-04-04 16:18:14 +02:00
|
|
|
Set<String> startTokens = applicationContext.configuration().startTokens();
|
2017-04-03 17:15:36 +02:00
|
|
|
for (String token : startTokens) {
|
|
|
|
setContextFromToken(token);
|
|
|
|
|
|
|
|
try {
|
|
|
|
ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory
|
|
|
|
.create();
|
|
|
|
if (create) {
|
|
|
|
|
|
|
|
eService = createEServiceAndHosts(
|
|
|
|
resourceRegistryPublisher, eService);
|
|
|
|
|
2017-04-04 16:18:14 +02:00
|
|
|
share(eService);
|
|
|
|
|
2017-04-03 17:15:36 +02:00
|
|
|
create = false;
|
|
|
|
|
|
|
|
} else {
|
2017-04-04 16:18:14 +02:00
|
|
|
addHostingNodeToContext(token);
|
2017-04-03 17:15:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
} catch (ResourceRegistryException e) {
|
|
|
|
logger.error("Unable to add {} to current context ({})",
|
2017-04-04 16:18:14 +02:00
|
|
|
eService, getContextName(token), e);
|
2017-04-03 17:15:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
rethrowUnchecked(e);
|
|
|
|
} finally {
|
|
|
|
setContextFromToken(previousToken);
|
|
|
|
Thread.currentThread().setContextClassLoader(contextCL);
|
|
|
|
}
|
|
|
|
|
|
|
|
return eService;
|
|
|
|
|
|
|
|
}
|
2017-04-04 16:18:14 +02:00
|
|
|
|
|
|
|
private String getCurrentContextName() {
|
|
|
|
String token = SecurityTokenProvider.instance.get();
|
|
|
|
return getContextName(token);
|
|
|
|
}
|
|
|
|
|
|
|
|
private String getContextName(String token) {
|
2017-04-03 17:15:36 +02:00
|
|
|
try {
|
|
|
|
return this.authorizationProxy.get(token).getContext();
|
|
|
|
} catch (Exception e) {
|
|
|
|
logger.error("Error retrieving token {}, it should never happen",
|
|
|
|
token);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
2017-04-04 16:18:14 +02:00
|
|
|
|
|
|
|
private boolean addHostingNodeToCurrentContext(){
|
|
|
|
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);
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
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);
|
|
|
|
|
|
|
|
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);
|
2017-04-03 17:15:36 +02:00
|
|
|
|
2017-04-04 16:18:14 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2017-04-03 17:15:36 +02:00
|
|
|
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 ({})",
|
2017-04-04 16:18:14 +02:00
|
|
|
eService, getContextName(token));
|
2017-04-03 17:15:36 +02:00
|
|
|
share(eService);
|
|
|
|
} else {
|
|
|
|
logger.error("Unable to remove {} from current context ({})",
|
2017-04-04 16:18:14 +02:00
|
|
|
eService, getContextName(token));
|
2017-04-03 17:15:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
share(eService);
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
logger.error("Unable to remove {} from current context ({})",
|
2017-04-04 16:18:14 +02:00
|
|
|
eService, getContextName(token), e);
|
2017-04-03 17:15:36 +02:00
|
|
|
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 ({})",
|
2017-04-04 16:18:14 +02:00
|
|
|
eService, getContextName(token));
|
2017-04-03 17:15:36 +02:00
|
|
|
share(eService);
|
|
|
|
} else {
|
|
|
|
logger.error("Unable to add {} to current context ({})",
|
2017-04-04 16:18:14 +02:00
|
|
|
eService, getContextName(token));
|
2017-04-03 17:15:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
share(eService);
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
logger.error("Unable to add {} to current context ({})", eService,
|
2017-04-04 16:18:14 +02:00
|
|
|
getContextName(token), e);
|
2017-04-03 17:15:36 +02:00
|
|
|
rethrowUnchecked(e);
|
|
|
|
} finally {
|
|
|
|
setContextFromToken(previousToken);
|
|
|
|
Thread.currentThread().setContextClassLoader(contextCL);
|
|
|
|
}
|
|
|
|
}
|
2017-04-04 16:18:14 +02:00
|
|
|
*/
|
|
|
|
|
2017-04-03 17:15:36 +02:00
|
|
|
private void createOrUpdateServiceStateFacet(EService eService, String state) {
|
|
|
|
|
|
|
|
ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
|
|
|
|
String previousToken = SecurityTokenProvider.instance.get();
|
|
|
|
try {
|
|
|
|
|
|
|
|
if (previousToken == null) {
|
|
|
|
setContextFromToken((String) applicationContext.configuration()
|
|
|
|
.startTokens().toArray()[0]);
|
|
|
|
}
|
|
|
|
Thread.currentThread().setContextClassLoader(
|
|
|
|
EServiceManager.class.getClassLoader());
|
|
|
|
|
|
|
|
ServiceStateFacet serviceStateFacet = null;
|
|
|
|
|
|
|
|
List<ConsistsOf<? extends Resource, ? extends Facet>> consistsOfList = eService
|
|
|
|
.getConsistsOf();
|
|
|
|
for (ConsistsOf<? extends Resource, ? extends Facet> c : consistsOfList) {
|
|
|
|
if (c.getTarget() instanceof ServiceStateFacet) {
|
|
|
|
serviceStateFacet = (ServiceStateFacet) c.getTarget();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory
|
|
|
|
.create();
|
|
|
|
try {
|
|
|
|
serviceStateFacet.setValue(state);
|
|
|
|
serviceStateFacet = resourceRegistryPublisher.updateFacet(
|
|
|
|
ServiceStateFacet.class, serviceStateFacet);
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
try {
|
|
|
|
ConsistsOf<EService, ServiceStateFacet> consistsOf = new ConsistsOfImpl<EService, ServiceStateFacet>(
|
|
|
|
eService, serviceStateFacet, null);
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
ConsistsOf<EService, ServiceStateFacet> createdConsistsOf = resourceRegistryPublisher.createConsistsOf(ConsistsOf.class, consistsOf);
|
|
|
|
|
|
|
|
eService.addFacet(createdConsistsOf);
|
|
|
|
} catch (Exception ex) {
|
|
|
|
eService = createEServiceAndHosts(
|
|
|
|
resourceRegistryPublisher, eService);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
share(eService);
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
rethrowUnchecked(e);
|
|
|
|
} finally {
|
|
|
|
setContextFromToken(previousToken);
|
|
|
|
Thread.currentThread().setContextClassLoader(contextCL);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-04-04 16:55:17 +02:00
|
|
|
private static String getBaseAddress(ApplicationContext context){
|
|
|
|
ApplicationConfiguration configuration = context.configuration();
|
|
|
|
ContainerConfiguration container = context.container().configuration();
|
|
|
|
String baseAddress;
|
|
|
|
if (configuration.proxied()){
|
|
|
|
String protocol = container.proxyAddress().secure()? "https://": "http://";
|
|
|
|
int port = container.proxyAddress().port();
|
|
|
|
|
|
|
|
baseAddress=String.format("%s%s:%d%s", protocol , container.proxyAddress().hostname(), port, context.application().getContextPath());
|
|
|
|
} else {
|
|
|
|
String protocol = configuration.secure()? "https://": "http://";
|
|
|
|
int port = configuration.secure()?container.securePort(): container.port();
|
|
|
|
|
|
|
|
baseAddress=String.format("%s%s:%d%s", protocol , container.hostname(), port, context.application().getContextPath());
|
|
|
|
}
|
|
|
|
return baseAddress;
|
|
|
|
}
|
|
|
|
|
2017-04-03 17:15:36 +02:00
|
|
|
private EService instantiateEService() {
|
|
|
|
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);
|
|
|
|
|
|
|
|
SoftwareFacet softwareFacet = new SoftwareFacetImpl();
|
|
|
|
softwareFacet.setDescription(applicationConfiguration.description());
|
|
|
|
softwareFacet.setGroup(applicationConfiguration.serviceClass());
|
|
|
|
softwareFacet.setName(applicationConfiguration.name());
|
|
|
|
softwareFacet.setVersion(applicationConfiguration.version());
|
|
|
|
|
|
|
|
IsIdentifiedBy<EService, SoftwareFacet> isIdentifiedBy = new IsIdentifiedByImpl<EService, SoftwareFacet>(
|
|
|
|
eService, softwareFacet, null);
|
|
|
|
eService.addFacet(isIdentifiedBy);
|
|
|
|
|
2017-04-04 16:55:17 +02:00
|
|
|
String baseAddress = EServiceManager.getBaseAddress(applicationContext);
|
2017-04-03 17:15:36 +02:00
|
|
|
for (ServletRegistration servlet : applicationContext.application()
|
|
|
|
.getServletRegistrations().values()) {
|
|
|
|
if (!servletExcludes.contains(servlet.getName())) {
|
|
|
|
for (String mapping : servlet.getMappings()) {
|
|
|
|
|
|
|
|
|
|
|
|
/*String address = ProfileBuilder.getAddressFromBaseAddress(
|
|
|
|
baseAddress, mapping);
|
|
|
|
*/
|
|
|
|
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 = applicationContext.lifecycle().state().remoteForm()
|
|
|
|
.toLowerCase();
|
|
|
|
serviceStateFacet.setValue(state.toLowerCase());
|
|
|
|
eService.addFacet(serviceStateFacet);
|
|
|
|
|
|
|
|
return eService;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return RESOURCE_MANAGEMENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|