legacy-is-publisher-connector/src/main/java/org/gcube/common/core/publisher/is/legacy/LegacyISPublisher.java

338 lines
11 KiB
Java
Raw Normal View History

2022-06-10 17:06:28 +02:00
package org.gcube.common.core.publisher.is.legacy;
import java.io.StringWriter;
2022-06-28 17:29:30 +02:00
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
2022-06-10 17:06:28 +02:00
import java.util.Set;
2022-06-28 17:29:30 +02:00
import java.util.stream.Collectors;
2022-06-10 17:06:28 +02:00
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;
2022-06-28 17:29:30 +02:00
import org.gcube.common.security.ContextBean;
import org.gcube.common.security.ContextBean.Type;
2022-06-10 17:06:28 +02:00
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
2024-03-12 17:28:51 +01:00
public class LegacyISPublisher implements Publisher {
2022-06-10 17:06:28 +02:00
private static Logger logger = LoggerFactory.getLogger(LegacyISPublisher.class);
private Registry registry = new Registry();
2022-06-28 17:29:30 +02:00
private static Map<String, Resource> resourcesCache = new HashMap<String, Resource>();
2022-06-10 17:06:28 +02:00
@Override
2022-06-28 17:29:30 +02:00
public boolean create(ContainerContext container, Set<String> contexts) {
2022-06-10 17:06:28 +02:00
ContainerProfileBuilder cpb = new ContainerProfileBuilder(container);
2022-06-28 17:29:30 +02:00
HostingNode hostingNode;
synchronized (resourcesCache) {
String id = container.id();
2024-03-12 17:28:51 +01:00
if (!resourcesCache.containsKey(id))
2022-06-28 17:29:30 +02:00
hostingNode = cpb.create();
else {
hostingNode = (HostingNode) resourcesCache.get(id);
2022-07-18 11:27:20 +02:00
cpb.update(hostingNode);
2022-06-28 17:29:30 +02:00
}
2024-03-12 17:28:51 +01:00
for (String context : contexts)
2022-06-28 17:29:30 +02:00
ResourceMediator.setScope(hostingNode, context);
resourcesCache.put(id, hostingNode);
}
2024-03-12 17:28:51 +01:00
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);
}
2022-06-28 17:29:30 +02:00
2024-03-12 17:28:51 +01:00
}, new ICSecret(context));
}
2022-06-28 17:29:30 +02:00
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();
2024-03-12 17:28:51 +01:00
if (!resourcesCache.containsKey(id))
2022-06-28 17:29:30 +02:00
endpoint = cpb.create();
else {
endpoint = (GCoreEndpoint) resourcesCache.get(id);
}
2024-03-12 17:28:51 +01:00
for (String context : contexts)
2022-06-28 17:29:30 +02:00
ResourceMediator.setScope(endpoint, context);
resourcesCache.put(id, endpoint);
}
2024-03-12 17:28:51 +01:00
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));
}
2022-06-28 17:29:30 +02:00
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();
2024-03-12 17:28:51 +01:00
if (!resourcesCache.containsKey(id))
2022-06-28 17:29:30 +02:00
hostingNode = cpb.create();
else {
hostingNode = (HostingNode) resourcesCache.get(id);
2022-07-18 11:27:20 +02:00
cpb.update(hostingNode);
2022-06-28 17:29:30 +02:00
}
2024-03-12 17:28:51 +01:00
for (String context : contexts)
2022-06-28 17:29:30 +02:00
ResourceMediator.removeScope(hostingNode, context);
2022-06-10 17:06:28 +02:00
2022-06-28 17:29:30 +02:00
resourcesCache.put(id, hostingNode);
}
for (String context : contexts)
if (isCompatibleScopeForRemove(hostingNode, context))
try {
2024-03-12 17:28:51 +01:00
AuthorizedTasks.executeSafely(() -> {
2022-06-10 17:06:28 +02:00
try {
2022-06-28 17:29:30 +02:00
logger.info("removing container from context {}", context);
2024-03-12 17:28:51 +01:00
registry.getStubs().remove(hostingNode.id(), hostingNode.type().toString());
} catch (Throwable e) {
2022-06-10 17:06:28 +02:00
throw new RuntimeException(e);
}
2022-07-04 16:31:48 +02:00
}, new ICSecret(context));
2024-03-12 17:28:51 +01:00
} catch (Throwable e) {
2022-06-28 17:29:30 +02:00
logger.error("error removing container in context {}", context, e);
}
for (String context : filterICContexts(hostingNode.scopes().asCollection()))
try {
logger.info("updating container in context {}", context);
2024-03-12 17:28:51 +01:00
AuthorizedTasks.executeSafely(() -> {
2022-06-28 17:29:30 +02:00
try {
2024-03-12 17:28:51 +01:00
registry.getStubs().update(hostingNode.id(), hostingNode.type().toString(), toXml(hostingNode));
} catch (Throwable e) {
2022-06-28 17:29:30 +02:00
throw new RuntimeException(e);
2022-06-10 17:06:28 +02:00
}
2022-06-28 17:29:30 +02:00
2022-07-04 16:31:48 +02:00
}, new ICSecret(context));
2024-03-12 17:28:51 +01:00
} catch (Throwable e) {
2022-06-28 17:29:30 +02:00
logger.error("error updating container in context {}", context, e);
2022-06-10 17:06:28 +02:00
}
return true;
2022-06-28 17:29:30 +02:00
2022-06-10 17:06:28 +02:00
}
@Override
2022-06-28 17:29:30 +02:00
public synchronized boolean remove(ApplicationContext application, Set<String> contexts) {
2022-06-10 17:06:28 +02:00
ApplicationProfileBuilder cpb = new ApplicationProfileBuilder(application);
2022-06-28 17:29:30 +02:00
GCoreEndpoint endpoint;
synchronized (resourcesCache) {
String id = application.id();
2024-03-12 17:28:51 +01:00
if (!resourcesCache.containsKey(id))
2022-06-28 17:29:30 +02:00
endpoint = cpb.create();
else {
endpoint = (GCoreEndpoint) resourcesCache.get(id);
}
2024-03-12 17:28:51 +01:00
for (String context : contexts)
2022-06-28 17:29:30 +02:00
ResourceMediator.removeScope(endpoint, context);
resourcesCache.put(id, endpoint);
}
2024-03-12 17:28:51 +01:00
// TODO: Review this
2022-06-28 17:29:30 +02:00
for (String context : contexts)
if (isCompatibleScopeForRemove(endpoint, context))
try {
2024-03-12 17:28:51 +01:00
AuthorizedTasks.executeSafely(() -> {
2022-06-10 17:06:28 +02:00
try {
2022-06-28 17:29:30 +02:00
logger.info("removing container in context {}", context);
2024-03-12 17:28:51 +01:00
registry.getStubs().remove(endpoint.id(), endpoint.type().toString());
} catch (Throwable e) {
2022-06-10 17:06:28 +02:00
throw new RuntimeException(e);
}
2022-07-04 16:31:48 +02:00
}, new ICSecret(context));
2024-03-12 17:28:51 +01:00
} catch (Throwable e) {
2022-06-28 17:29:30 +02:00
logger.error("error removing container in context {}", context, e);
}
for (String context : filterICContexts(endpoint.scopes().asCollection()))
try {
2024-03-12 17:28:51 +01:00
AuthorizedTasks.executeSafely(() -> {
2022-06-28 17:29:30 +02:00
try {
logger.info("updating application in context {}", context);
String resource = toXml(endpoint);
registry.getStubs().update(endpoint.id(), endpoint.type().toString(), resource);
2024-03-12 17:28:51 +01:00
} catch (Throwable e) {
2022-06-28 17:29:30 +02:00
throw new RuntimeException(e);
2022-06-10 17:06:28 +02:00
}
2022-07-04 16:31:48 +02:00
}, new ICSecret(context));
2024-03-12 17:28:51 +01:00
} catch (Throwable e) {
2022-06-28 17:29:30 +02:00
logger.error("error updating application profile in context {}", context, e);
2022-06-10 17:06:28 +02:00
}
return true;
}
@Override
2022-06-28 17:29:30 +02:00
public boolean update(ApplicationContext application) {
2024-03-12 17:28:51 +01:00
2022-06-28 17:29:30 +02:00
GCoreEndpoint endpoint;
synchronized (resourcesCache) {
String id = application.id();
endpoint = (GCoreEndpoint) resourcesCache.get(id);
}
2024-03-12 17:28:51 +01:00
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));
}
2022-06-28 17:29:30 +02:00
return true;
2022-06-10 17:06:28 +02:00
}
@Override
2022-06-28 17:29:30 +02:00
public boolean update(ContainerContext container) {
ContainerProfileBuilder cpb = new ContainerProfileBuilder(container);
HostingNode hostingNode;
synchronized (resourcesCache) {
String id = container.id();
hostingNode = (HostingNode) resourcesCache.get(id);
2022-07-18 11:27:20 +02:00
cpb.update(hostingNode);
2022-06-28 17:29:30 +02:00
resourcesCache.put(id, hostingNode);
}
2024-03-12 17:28:51 +01:00
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);
}
2022-06-28 17:29:30 +02:00
2024-03-12 17:28:51 +01:00
}, new ICSecret(context));
}
2022-06-28 17:29:30 +02:00
return true;
2022-06-10 17:06:28 +02:00
}
2024-03-12 17:28:51 +01:00
private String toXml(Resource resource) {
2022-06-10 17:06:28 +02:00
StringWriter writer = new StringWriter();
Resources.marshal(resource, writer);
return writer.toString();
}
2024-03-12 17:28:51 +01:00
private Set<String> filterICContexts(Collection<String> contexts) {
return contexts.stream().map((c) -> {
2022-06-28 17:29:30 +02:00
ContextBean bean = new ContextBean(c);
2024-03-12 17:28:51 +01:00
return bean.is(Type.VRE) ? bean.enclosingScope().toString() : c;
2022-06-28 17:29:30 +02:00
}).collect(Collectors.toSet());
}
2024-03-12 17:28:51 +01:00
private <T extends Resource> boolean isCompatibleScopeForRemove(T resource, String scope) {
if (resource.scopes().size() == 0)
2022-06-28 17:29:30 +02:00
return true;
2024-03-12 17:28:51 +01:00
if (new ContextBean(scope).is(Type.VRE))
2022-06-28 17:29:30 +02:00
return !anotherBrotherVREOrVOOnResource(resource, scope);
2024-03-12 17:28:51 +01:00
else if (new ContextBean(scope).is(Type.VO))
2022-06-28 17:29:30 +02:00
return !anotherSonVREOnResource(resource, scope);
else
return !anotherInfraScopeOnResource(resource, scope);
}
2024-03-12 17:28:51 +01:00
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))))
2022-06-28 17:29:30 +02:00
return true;
}
return false;
}
2024-03-12 17:28:51 +01:00
private <T extends Resource> boolean anotherSonVREOnResource(T resource, String scope) {
if (!new ContextBean(scope).is(Type.VO))
2022-06-28 17:29:30 +02:00
throw new IllegalArgumentException("anotherSonVREOnResource method: the input scope must be a VO scope");
2024-03-12 17:28:51 +01:00
for (String s : resource.scopes()) {
if (isChildScope(scope, s))
2022-06-28 17:29:30 +02:00
return true;
}
return false;
}
2024-03-12 17:28:51 +01:00
2022-06-28 17:29:30 +02:00
private boolean isChildScope(String fatherScope, String sonScope) {
2024-03-12 17:28:51 +01:00
ContextBean currentEnclosedScope = new ContextBean(sonScope).enclosingScope();
2022-06-28 17:29:30 +02:00
return (currentEnclosedScope != null) && (currentEnclosedScope.toString().equals(fatherScope));
}
2024-03-12 17:28:51 +01:00
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))
2022-06-28 17:29:30 +02:00
return true;
}
return false;
}
2022-06-10 17:06:28 +02:00
}