338 lines
11 KiB
Java
338 lines
11 KiB
Java
package org.gcube.common.core.publisher.is.legacy;
|
|
|
|
import java.io.StringWriter;
|
|
import java.util.Collection;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.stream.Collectors;
|
|
|
|
import org.gcube.common.core.publisher.is.legacy.application.ApplicationProfileBuilder;
|
|
import org.gcube.common.core.publisher.is.legacy.container.ContainerProfileBuilder;
|
|
import org.gcube.common.resources.gcore.GCoreEndpoint;
|
|
import org.gcube.common.resources.gcore.HostingNode;
|
|
import org.gcube.common.resources.gcore.Resource;
|
|
import org.gcube.common.resources.gcore.ResourceMediator;
|
|
import org.gcube.common.resources.gcore.Resources;
|
|
import org.gcube.common.security.AuthorizedTasks;
|
|
import org.gcube.common.security.ContextBean;
|
|
import org.gcube.common.security.ContextBean.Type;
|
|
import org.gcube.smartgears.context.application.ApplicationContext;
|
|
import org.gcube.smartgears.context.container.ContainerContext;
|
|
import org.gcube.smartgears.publishing.Publisher;
|
|
import org.gcube.smartgears.publishing.SmartgearsProfilePublisher;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
@SmartgearsProfilePublisher
|
|
public class LegacyISPublisher implements Publisher {
|
|
|
|
private static Logger logger = LoggerFactory.getLogger(LegacyISPublisher.class);
|
|
|
|
private Registry registry = new Registry();
|
|
|
|
private static Map<String, Resource> resourcesCache = new HashMap<String, Resource>();
|
|
|
|
@Override
|
|
public boolean create(ContainerContext container, Set<String> contexts) {
|
|
ContainerProfileBuilder cpb = new ContainerProfileBuilder(container);
|
|
|
|
HostingNode hostingNode;
|
|
synchronized (resourcesCache) {
|
|
String id = container.id();
|
|
|
|
if (!resourcesCache.containsKey(id))
|
|
hostingNode = cpb.create();
|
|
else {
|
|
hostingNode = (HostingNode) resourcesCache.get(id);
|
|
cpb.update(hostingNode);
|
|
}
|
|
|
|
for (String context : contexts)
|
|
ResourceMediator.setScope(hostingNode, context);
|
|
|
|
resourcesCache.put(id, hostingNode);
|
|
}
|
|
|
|
for (String context : filterICContexts(hostingNode.scopes().asCollection())) {
|
|
logger.info("publishing container in context {}", context);
|
|
AuthorizedTasks.executeSafely(() -> {
|
|
try {
|
|
registry.getStubs().create(toXml(hostingNode), hostingNode.type().toString());
|
|
} catch (Throwable e) {
|
|
logger.error("error publishing container in context {}", context, e);
|
|
}
|
|
|
|
}, new ICSecret(context));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public synchronized boolean create(ApplicationContext application, Set<String> contexts) {
|
|
ApplicationProfileBuilder cpb = new ApplicationProfileBuilder(application);
|
|
GCoreEndpoint endpoint;
|
|
synchronized (resourcesCache) {
|
|
String id = application.id();
|
|
|
|
if (!resourcesCache.containsKey(id))
|
|
endpoint = cpb.create();
|
|
else {
|
|
endpoint = (GCoreEndpoint) resourcesCache.get(id);
|
|
}
|
|
|
|
for (String context : contexts)
|
|
ResourceMediator.setScope(endpoint, context);
|
|
|
|
resourcesCache.put(id, endpoint);
|
|
}
|
|
|
|
for (String context : filterICContexts(endpoint.scopes().asCollection())) {
|
|
logger.info("publishing application in context {}", context);
|
|
AuthorizedTasks.executeSafely(() -> {
|
|
try {
|
|
String resource = toXml(endpoint);
|
|
registry.getStubs().create(resource, endpoint.type().toString());
|
|
} catch (Throwable e) {
|
|
logger.error("error publishing application in {}", context, e);
|
|
}
|
|
}, new ICSecret(context));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public synchronized boolean remove(ContainerContext container, Set<String> contexts) {
|
|
ContainerProfileBuilder cpb = new ContainerProfileBuilder(container);
|
|
|
|
HostingNode hostingNode;
|
|
synchronized (resourcesCache) {
|
|
String id = container.id();
|
|
|
|
if (!resourcesCache.containsKey(id))
|
|
hostingNode = cpb.create();
|
|
else {
|
|
hostingNode = (HostingNode) resourcesCache.get(id);
|
|
cpb.update(hostingNode);
|
|
}
|
|
|
|
for (String context : contexts)
|
|
ResourceMediator.removeScope(hostingNode, context);
|
|
|
|
resourcesCache.put(id, hostingNode);
|
|
}
|
|
|
|
for (String context : contexts)
|
|
if (isCompatibleScopeForRemove(hostingNode, context))
|
|
try {
|
|
AuthorizedTasks.executeSafely(() -> {
|
|
try {
|
|
logger.info("removing container from context {}", context);
|
|
registry.getStubs().remove(hostingNode.id(), hostingNode.type().toString());
|
|
} catch (Throwable e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
|
|
}, new ICSecret(context));
|
|
} catch (Throwable e) {
|
|
logger.error("error removing container in context {}", context, e);
|
|
}
|
|
|
|
for (String context : filterICContexts(hostingNode.scopes().asCollection()))
|
|
try {
|
|
logger.info("updating container in context {}", context);
|
|
AuthorizedTasks.executeSafely(() -> {
|
|
try {
|
|
registry.getStubs().update(hostingNode.id(), hostingNode.type().toString(), toXml(hostingNode));
|
|
} catch (Throwable e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
|
|
}, new ICSecret(context));
|
|
} catch (Throwable e) {
|
|
logger.error("error updating container in context {}", context, e);
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
@Override
|
|
public synchronized boolean remove(ApplicationContext application, Set<String> contexts) {
|
|
ApplicationProfileBuilder cpb = new ApplicationProfileBuilder(application);
|
|
GCoreEndpoint endpoint;
|
|
synchronized (resourcesCache) {
|
|
String id = application.id();
|
|
|
|
if (!resourcesCache.containsKey(id))
|
|
endpoint = cpb.create();
|
|
else {
|
|
endpoint = (GCoreEndpoint) resourcesCache.get(id);
|
|
}
|
|
|
|
for (String context : contexts)
|
|
ResourceMediator.removeScope(endpoint, context);
|
|
|
|
resourcesCache.put(id, endpoint);
|
|
}
|
|
|
|
// TODO: Review this
|
|
for (String context : contexts)
|
|
if (isCompatibleScopeForRemove(endpoint, context))
|
|
try {
|
|
AuthorizedTasks.executeSafely(() -> {
|
|
try {
|
|
logger.info("removing container in context {}", context);
|
|
registry.getStubs().remove(endpoint.id(), endpoint.type().toString());
|
|
} catch (Throwable e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
|
|
}, new ICSecret(context));
|
|
} catch (Throwable e) {
|
|
logger.error("error removing container in context {}", context, e);
|
|
}
|
|
|
|
for (String context : filterICContexts(endpoint.scopes().asCollection()))
|
|
try {
|
|
AuthorizedTasks.executeSafely(() -> {
|
|
try {
|
|
logger.info("updating application in context {}", context);
|
|
String resource = toXml(endpoint);
|
|
registry.getStubs().update(endpoint.id(), endpoint.type().toString(), resource);
|
|
} catch (Throwable e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}, new ICSecret(context));
|
|
} catch (Throwable e) {
|
|
logger.error("error updating application profile in context {}", context, e);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean update(ApplicationContext application) {
|
|
|
|
GCoreEndpoint endpoint;
|
|
synchronized (resourcesCache) {
|
|
String id = application.id();
|
|
endpoint = (GCoreEndpoint) resourcesCache.get(id);
|
|
}
|
|
|
|
for (String context : filterICContexts(endpoint.scopes().asCollection())) {
|
|
logger.info("updating application in context {}", context);
|
|
AuthorizedTasks.executeSafely(() -> {
|
|
try {
|
|
String resource = toXml(endpoint);
|
|
registry.getStubs().update(endpoint.id(), endpoint.type().toString(), resource);
|
|
} catch (Throwable e) {
|
|
logger.error("error updating application profile in context {}", context, e);
|
|
}
|
|
}, new ICSecret(context));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean update(ContainerContext container) {
|
|
ContainerProfileBuilder cpb = new ContainerProfileBuilder(container);
|
|
|
|
HostingNode hostingNode;
|
|
synchronized (resourcesCache) {
|
|
String id = container.id();
|
|
|
|
hostingNode = (HostingNode) resourcesCache.get(id);
|
|
cpb.update(hostingNode);
|
|
|
|
resourcesCache.put(id, hostingNode);
|
|
}
|
|
|
|
for (String context : filterICContexts(hostingNode.scopes().asCollection())) {
|
|
logger.info("updating container in context {}", context);
|
|
AuthorizedTasks.executeSafely(() -> {
|
|
try {
|
|
logger.info("updating container in context {}", context);
|
|
registry.getStubs().update(hostingNode.id(), hostingNode.type().toString(), toXml(hostingNode));
|
|
} catch (Throwable e) {
|
|
logger.error("error updating container in context {}", context, e);
|
|
}
|
|
|
|
}, new ICSecret(context));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private String toXml(Resource resource) {
|
|
StringWriter writer = new StringWriter();
|
|
Resources.marshal(resource, writer);
|
|
return writer.toString();
|
|
}
|
|
|
|
private Set<String> filterICContexts(Collection<String> contexts) {
|
|
return contexts.stream().map((c) -> {
|
|
ContextBean bean = new ContextBean(c);
|
|
return bean.is(Type.VRE) ? bean.enclosingScope().toString() : c;
|
|
}).collect(Collectors.toSet());
|
|
}
|
|
|
|
private <T extends Resource> boolean isCompatibleScopeForRemove(T resource, String scope) {
|
|
if (resource.scopes().size() == 0)
|
|
return true;
|
|
if (new ContextBean(scope).is(Type.VRE))
|
|
return !anotherBrotherVREOrVOOnResource(resource, scope);
|
|
else if (new ContextBean(scope).is(Type.VO))
|
|
return !anotherSonVREOnResource(resource, scope);
|
|
else
|
|
return !anotherInfraScopeOnResource(resource, scope);
|
|
|
|
}
|
|
|
|
private <T extends Resource> boolean anotherBrotherVREOrVOOnResource(T resource, String scope) {
|
|
if (!new ContextBean(scope).is(Type.VRE))
|
|
throw new IllegalArgumentException(
|
|
"anotherBrotherVREOrVOOnResource method: the input scope must be a VRE scope");
|
|
String enclosedScope = new ContextBean(scope).enclosingScope().toString();
|
|
for (String s : resource.scopes()) {
|
|
if (isChildScope(enclosedScope, s) || ((enclosedScope != null) && (enclosedScope.toString().equals(s))))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private <T extends Resource> boolean anotherSonVREOnResource(T resource, String scope) {
|
|
if (!new ContextBean(scope).is(Type.VO))
|
|
throw new IllegalArgumentException("anotherSonVREOnResource method: the input scope must be a VO scope");
|
|
for (String s : resource.scopes()) {
|
|
if (isChildScope(scope, s))
|
|
return true;
|
|
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private boolean isChildScope(String fatherScope, String sonScope) {
|
|
ContextBean currentEnclosedScope = new ContextBean(sonScope).enclosingScope();
|
|
return (currentEnclosedScope != null) && (currentEnclosedScope.toString().equals(fatherScope));
|
|
|
|
}
|
|
|
|
private <T extends Resource> boolean anotherInfraScopeOnResource(T resource, String scope) {
|
|
if (!new ContextBean(scope).is(Type.INFRASTRUCTURE))
|
|
throw new IllegalArgumentException(
|
|
"anotherInfraScopeOnResource method: the input scope must be a INFRASTRUCTURE scope");
|
|
String infraScopeFound = null;
|
|
for (String s : resource.scopes()) {
|
|
while (new ContextBean(s).enclosingScope() != null)
|
|
s = new ContextBean(s).enclosingScope().toString();
|
|
infraScopeFound = s;
|
|
if (infraScopeFound.equals(scope))
|
|
return true;
|
|
|
|
}
|
|
return false;
|
|
}
|
|
|
|
}
|