resource-registry-handlers/src/main/java/org/gcube/smartgears/handler/resourceregistry/resourcemanager/EServiceManager.java

240 lines
11 KiB
Java
Raw Normal View History

2020-10-20 16:25:30 +02:00
package org.gcube.smartgears.handler.resourceregistry.resourcemanager;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
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.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.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;
2020-10-22 12:10:37 +02:00
import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClient;
import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClientFactory;
2020-10-20 16:25:30 +02:00
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class EServiceManager {
private static Logger logger = LoggerFactory.getLogger(HostingNodeManager.class);
2020-10-22 12:10:37 +02:00
2020-10-20 16:25:30 +02:00
private static List<String> servletExcludes = Arrays.asList("default", "jsp");
2020-10-22 12:10:37 +02:00
2020-10-20 16:25:30 +02:00
private ResourceRegistryPublisher resourceRegistryPublisher;
2020-10-22 12:10:37 +02:00
2020-10-20 16:25:30 +02:00
private Activates<HostingNode, EService> activates;
private EService eService;
2020-10-22 12:10:37 +02:00
private ServiceStateFacet serviceStateFacet;
2020-10-20 16:25:30 +02:00
public EServiceManager() {
this.resourceRegistryPublisher = ResourceRegistryPublisherFactory.create();
}
2020-10-22 12:10:37 +02:00
2020-10-20 16:25:30 +02:00
public EService geteService() {
return eService;
}
2020-10-22 12:10:37 +02:00
public void addToContext(ApplicationContext applicationContext)
throws ResourceNotFoundException, ContextNotFoundException, ResourceRegistryException {
HostingNode hostingNode = applicationContext.container().properties()
.lookup(Constants.HOSTING_NODE_MANAGER_PROPERTY).value(HostingNodeManager.class).getHostingNode();
2020-10-20 16:25:30 +02:00
boolean added = resourceRegistryPublisher.addResourceToCurrentContext(hostingNode);
if (added) {
logger.info("{} successfully added to current context ({})", eService,
ContextUtility.getCurrentContextName());
} else {
2020-10-22 12:10:37 +02:00
logger.error("Unable to add {} to current context ({})", eService, ContextUtility.getCurrentContextName());
2020-10-20 16:25:30 +02:00
}
}
2020-10-22 12:10:37 +02:00
public void removeFromContext()
throws ResourceNotFoundException, ContextNotFoundException, ResourceRegistryException {
2020-10-20 16:25:30 +02:00
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();
}
2020-10-22 12:10:37 +02:00
2020-10-20 16:25:30 +02:00
private EService instantiateEService(ApplicationContext applicationContext) {
logger.info("Creating {} for {}", EService.NAME, applicationContext.name());
ApplicationConfiguration applicationConfiguration = applicationContext.configuration();
String id = applicationContext.id();
2020-10-22 12:10:37 +02:00
2020-10-20 16:25:30 +02:00
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<EService, SoftwareFacet> isIdentifiedBy = new IsIdentifiedByImpl<EService, SoftwareFacet>(
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);
}
}
}
2020-10-22 12:10:37 +02:00
serviceStateFacet = new ServiceStateFacetImpl();
String state = getState(applicationContext);
serviceStateFacet.setValue(state);
2020-10-20 16:25:30 +02:00
eService.addFacet(serviceStateFacet);
return eService;
}
2020-10-22 12:10:37 +02:00
2020-10-20 16:25:30 +02:00
public EService createEService(ApplicationContext applicationContext) throws ResourceRegistryException {
try {
2020-10-22 12:10:37 +02:00
ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
UUID uuid = UUID.fromString(applicationContext.id());
try {
eService = resourceRegistryClient.getInstance(EService.class, uuid);
// It is not convenient to update the node because the contexts could be changed
// so we should remove from all contexts and then it will be added again.
// It is more efficient to delete it.
resourceRegistryPublisher.delete(eService);
} catch (NotFoundException e) {
// Fine we are going to create it again
}
2020-10-20 16:25:30 +02:00
eService = instantiateEService(applicationContext);
2020-10-22 12:10:37 +02:00
// eService = resourceRegistryPublisher.createResource(eService);
activates = createActivatesRelation(applicationContext, eService);
2020-10-20 16:25:30 +02:00
} catch (AvailableInAnotherContextException | AlreadyPresentException e) {
// resourceRegistryPublisher.delete(eService);
// eService = resourceRegistryPublisher.createResource(eService);
resourceRegistryPublisher.delete(activates);
2020-10-22 12:10:37 +02:00
activates = createActivatesRelation(applicationContext, eService);
2020-10-20 16:25:30 +02:00
}
2020-10-22 12:10:37 +02:00
eService = activates.getTarget();
serviceStateFacet = eService.getFacets(ServiceStateFacet.class).get(0);
2020-10-20 16:25:30 +02:00
return eService;
}
public void updateServiceStateFacet(ApplicationContext applicationContext) throws ResourceRegistryException {
String state = getState(applicationContext);
2020-10-22 12:10:37 +02:00
serviceStateFacet.setValue(state);
serviceStateFacet = resourceRegistryPublisher.updateFacet(serviceStateFacet);
}
2020-10-20 16:25:30 +02:00
2020-10-22 12:10:37 +02:00
private Activates<HostingNode, EService> createActivatesRelation(ApplicationContext applicationContext,
EService eService) throws ResourceRegistryException {
2020-10-20 16:25:30 +02:00
2020-10-22 12:10:37 +02:00
HostingNode hostingNode = applicationContext.container().properties()
.lookup(Constants.HOSTING_NODE_MANAGER_PROPERTY).value(HostingNodeManager.class).getHostingNode();
2020-10-20 16:25:30 +02:00
PropagationConstraint propagationConstraint = new PropagationConstraintImpl();
propagationConstraint.setRemoveConstraint(RemoveConstraint.cascade);
propagationConstraint.setAddConstraint(AddConstraint.propagate);
Activates<HostingNode, EService> 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;
}
2020-10-22 12:10:37 +02:00
2020-10-20 16:25:30 +02:00
public void removeEService(ApplicationContext applicationContext) throws ResourceRegistryException {
try {
resourceRegistryPublisher.delete(eService);
} catch (ResourceRegistryException e) {
2020-10-22 12:10:37 +02:00
logger.error("Unable to delete {}. Going to set the state to {}", applicationContext.name(),
getState(applicationContext));
2020-10-20 16:25:30 +02:00
updateServiceStateFacet(applicationContext);
}
}
}