smart-executor/src/main/java/org/gcube/vremanagement/executor/ispublisher/RestISPublisher.java

276 lines
13 KiB
Java

package org.gcube.vremanagement.executor.ispublisher;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.gcube.informationsystem.base.reference.Direction;
import org.gcube.informationsystem.model.impl.properties.HeaderImpl;
import org.gcube.informationsystem.model.impl.properties.PropagationConstraintImpl;
import org.gcube.informationsystem.model.reference.entities.Facet;
import org.gcube.informationsystem.model.reference.entities.Resource;
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.DeleteConstraint;
import org.gcube.informationsystem.model.reference.properties.PropagationConstraint.RemoveConstraint;
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.EventFacetImpl;
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.facets.StateFacetImpl;
import org.gcube.resourcemanagement.model.impl.entities.resources.RunningPluginImpl;
import org.gcube.resourcemanagement.model.impl.relations.consistsof.IsIdentifiedByImpl;
import org.gcube.resourcemanagement.model.impl.relations.isrelatedto.ActivatesImpl;
import org.gcube.resourcemanagement.model.impl.relations.isrelatedto.EnablesImpl;
import org.gcube.resourcemanagement.model.reference.entities.facets.AccessPointFacet;
import org.gcube.resourcemanagement.model.reference.entities.facets.EventFacet;
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.facets.StateFacet;
import org.gcube.resourcemanagement.model.reference.entities.resources.EService;
import org.gcube.resourcemanagement.model.reference.entities.resources.RunningPlugin;
import org.gcube.resourcemanagement.model.reference.entities.resources.Service;
import org.gcube.resourcemanagement.model.reference.entities.resources.Software;
import org.gcube.resourcemanagement.model.reference.relations.consistsof.IsIdentifiedBy;
import org.gcube.resourcemanagement.model.reference.relations.isrelatedto.Activates;
import org.gcube.resourcemanagement.model.reference.relations.isrelatedto.Enables;
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.lifecycle.application.ApplicationState;
import org.gcube.vremanagement.executor.ResourceInitializer;
import org.gcube.vremanagement.executor.plugin.Plugin;
import org.gcube.vremanagement.executor.pluginmanager.PluginManager;
import org.gcube.vremanagement.executor.rest.RestSmartExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class RestISPublisher extends ISPublisher {
private static Logger logger = LoggerFactory.getLogger(RestISPublisher.class);
protected final UUID eServiceUUID;
protected ResourceRegistryClient resourceRegistryClient;
protected ResourceRegistryPublisher resourceRegistryPublisher;
public RestISPublisher(ApplicationContext applicationContext) {
super(applicationContext);
this.eServiceUUID = UUID.fromString(applicationContext.id());
this.resourceRegistryClient = ResourceRegistryClientFactory.create();
this.resourceRegistryPublisher = ResourceRegistryPublisherFactory.create();
}
protected URI getPluginEndpoint(String pluginName, AccessPointFacet smartExecutorAccessPointFacet) throws Exception {
URI smartExecutorEndpoint = getSmartExecutorEndpoint(smartExecutorAccessPointFacet);
String pluginPath = String.format(RestSmartExecutor.PLUGIN_ENDPOINT_FORMAT,pluginName);
URI pluginEndpoint = new URI(smartExecutorEndpoint + pluginPath);
return pluginEndpoint;
}
protected AccessPointFacet getPluginAccessPointFacet(Plugin plugin, AccessPointFacet smartExecutorAccessPointFacet) throws Exception {
AccessPointFacet accessPointFacet = new AccessPointFacetImpl();
URI pluginEndpoint = getPluginEndpoint(plugin.getName(), smartExecutorAccessPointFacet);
accessPointFacet.setEndpoint(pluginEndpoint);
accessPointFacet.setDescription("The " + plugin.getName() + " smart-executor plugin endpoint");
if(smartExecutorAccessPointFacet!=null) {
accessPointFacet.setAuthorization(smartExecutorAccessPointFacet.getAuthorization());
}
accessPointFacet.setEntryName(plugin.getClass().getName());
return accessPointFacet;
}
protected AccessPointFacet getSmartExecutorAccessPointFacet(EService smartExecutorEService) {
AccessPointFacet smartExecutorAccessPointFacet = null;
List<AccessPointFacet> smartExecutorAccessPointFacets = smartExecutorEService.getFacets(AccessPointFacet.class);
for(AccessPointFacet accessPointFacet : smartExecutorAccessPointFacets) {
if(accessPointFacet.getEntryName().compareTo(ResourceInitializer.class.getName())==0) {
smartExecutorAccessPointFacet = accessPointFacet;
break;
}
}
return smartExecutorAccessPointFacet;
}
protected URI getSmartExecutorEndpoint(AccessPointFacet smartExecutorAccessPointFacet) throws URISyntaxException {
URI smartExecutorEndpoint = null;
if(smartExecutorAccessPointFacet != null) {
smartExecutorEndpoint = smartExecutorAccessPointFacet.getEndpoint();
}else {
// fallback
smartExecutorEndpoint = new URI(getBaseAddress());
}
return smartExecutorEndpoint;
}
/**
* Keep this function aligned with resource-registry-handlers/resource-registry-connector
* @return
*/
private String getBaseAddress() {
ApplicationConfiguration configuration = applicationContext.configuration();
ContainerConfiguration container = applicationContext.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,
applicationContext.application().getContextPath());
} else {
String protocol = container.protocol();
int port = container.port();
baseAddress = String.format("%s://%s:%d%s", protocol, container.hostname(), port,
applicationContext.application().getContextPath());
}
return baseAddress;
}
@SuppressWarnings("unused")
protected RunningPlugin publishRunningPluginWithRelations(Plugin plugin, UUID pluginUUID) throws Exception {
RunningPlugin runningPlugin = new RunningPluginImpl();
runningPlugin.setHeader(new HeaderImpl(pluginUUID));
SoftwareFacet softwareFacet = new SoftwareFacetImpl();
softwareFacet.setGroup(plugin.getGroup());
softwareFacet.setName(plugin.getName());
softwareFacet.setVersion(plugin.getVersion());
softwareFacet.setDescription(plugin.getDescription());
IsIdentifiedBy<Resource, Facet> isIdentifiedBy = new IsIdentifiedByImpl<Resource, Facet>(runningPlugin, softwareFacet);
runningPlugin.addFacet(isIdentifiedBy);
Map<String,String> pluginCapabilities = plugin.getSupportedCapabilities();
if(pluginCapabilities!=null) {
for(String capabilityName : pluginCapabilities.keySet()) {
SimplePropertyFacet simplePropertyFacet = new SimplePropertyFacetImpl();
simplePropertyFacet.setName(capabilityName);
simplePropertyFacet.setValue(pluginCapabilities.get(capabilityName));
runningPlugin.addFacet(simplePropertyFacet);
}
}
EService smartExecutorEService = resourceRegistryClient.getInstance(EService.class, eServiceUUID);
PropagationConstraint usesPropagationConstraint = new PropagationConstraintImpl();
usesPropagationConstraint.setAddConstraint(AddConstraint.propagate);
usesPropagationConstraint.setRemoveConstraint(RemoveConstraint.cascade);
usesPropagationConstraint.setDeleteConstraint(DeleteConstraint.cascade);
AccessPointFacet smartExecutorAccessPointFacet = getSmartExecutorAccessPointFacet(smartExecutorEService);
URI smartExecutorEndpoint = getSmartExecutorEndpoint(smartExecutorAccessPointFacet);
AccessPointFacet accessPointFacet = getPluginAccessPointFacet(plugin, smartExecutorAccessPointFacet);
runningPlugin.addFacet(accessPointFacet);
Date date = Calendar.getInstance().getTime();
StateFacet stateFacet = new StateFacetImpl();
stateFacet.setValue(ApplicationState.active.remoteForm().toLowerCase());
stateFacet.setAdditionalProperty("date", date);
runningPlugin.addFacet(stateFacet);
EventFacet eventFacet = new EventFacetImpl();
eventFacet.setDate(date);
eventFacet.setEvent(stateFacet.getValue());
runningPlugin.addFacet(eventFacet);
Activates<EService, RunningPlugin> activates = new ActivatesImpl<EService, RunningPlugin>(smartExecutorEService, runningPlugin, usesPropagationConstraint);
try {
resourceRegistryPublisher.createIsRelatedTo(activates);
} catch (ResourceRegistryException e) {
logger.error("Unable to publish %s instace %s for plugin %s. I'm going to stop the service.", Resource.NAME, RunningPlugin.NAME, plugin.getName());
throw e;
}
// TODO Retrieve Plugin (Software) to create the relation
org.gcube.resourcemanagement.model.reference.entities.resources.Plugin pluginResource = null;
if(pluginResource!=null) {
/*
* The if allows not commenting the following code so that
* the creation of the relation between RunningPlugin and the Plugin (Software)
* is properly developed
*/
PropagationConstraint enablesPropagationConstraint = new PropagationConstraintImpl();
enablesPropagationConstraint.setAddConstraint(AddConstraint.propagate);
enablesPropagationConstraint.setRemoveConstraint(RemoveConstraint.keep);
enablesPropagationConstraint.setDeleteConstraint(DeleteConstraint.keep);
Enables<Service, Software> enables = new EnablesImpl<Service, Software>(runningPlugin, pluginResource, enablesPropagationConstraint);
try {
resourceRegistryPublisher.createIsRelatedTo(enables);
} catch (ResourceRegistryException e) {
logger.error("Unable to publish %s instace %s for plugin %s. I'm going to stop the service.", Resource.NAME, RunningPlugin.NAME, plugin.getName());
throw e;
}
}
return runningPlugin;
}
@Override
public void publishPlugins(Map<String, Class<? extends Plugin>> availablePlugins) throws Exception {
PluginManager pluginManager = PluginManager.getInstance();
for(String pluginName : availablePlugins.keySet()) {
Plugin plugin = pluginManager.getPlugin(pluginName);
UUID pluginUUID = pluginManager.getPluginUUID(pluginName);
RunningPlugin runningPlugin;
try {
runningPlugin = resourceRegistryClient.getInstance(RunningPlugin.class, pluginUUID);
} catch (NotFoundException e) {
runningPlugin = publishRunningPluginWithRelations(plugin, pluginUUID);
} catch (AvailableInAnotherContextException e) {
runningPlugin = new RunningPluginImpl();
runningPlugin.setHeader(new HeaderImpl(pluginUUID));
resourceRegistryPublisher.addToCurrentContext(runningPlugin, false);
} catch (ResourceRegistryException e) {
throw e;
}
}
}
@Override
public void unpublishPlugins(boolean force) throws Exception {
if(force) {
List<RunningPlugin> runningPlugins = resourceRegistryClient.getRelatedResourcesFromReferenceResource(RunningPlugin.class, Activates.class, EService.class, this.eServiceUUID, Direction.IN, true);
for(RunningPlugin runningPlugin : runningPlugins) {
resourceRegistryPublisher.delete(runningPlugin);
}
}else {
logger.info("The Plugin will be removed when the Eservice will be removed thanks to propagation contraints. Nothing to do");
}
}
}