WfNode annotation management

This commit is contained in:
Michele Artini 2023-04-20 13:57:27 +02:00
parent 5cd6efbba6
commit f2eb88a3f8
2 changed files with 60 additions and 15 deletions

View File

@ -110,7 +110,7 @@ public class GraphLoader {
if (n.isStart()) {
foundStart = true;
}
if (!this.nodeHelper.isValidType(n.getType())) { throw new WorkflowManagerException("Invalid node type: " + n.getType()); }
if (!this.nodeHelper.isValid(n)) { throw new WorkflowManagerException("Invalid node type: " + n.getType()); }
}
if (!foundStart) { throw new WorkflowManagerException("Start node not found"); }
}

View File

@ -1,14 +1,22 @@
package eu.dnetlib.manager.wf.workflows.util;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.stereotype.Component;
import eu.dnetlib.errors.WorkflowManagerException;
import eu.dnetlib.manager.wf.annotations.WfNode;
import eu.dnetlib.manager.wf.nodes.DefaultJobNode;
import eu.dnetlib.manager.wf.nodes.ProcessNode;
import eu.dnetlib.manager.wf.nodes.SuccessNode;
@ -19,7 +27,6 @@ import eu.dnetlib.manager.wf.workflows.procs.WorkflowProcess;
@Component
public class NodeHelper implements ApplicationContextAware {
public static final String beanNamePrefix = "wfNode";
private static final Log log = LogFactory.getLog(NodeHelper.class);
private ApplicationContext applicationContext;
@ -30,25 +37,63 @@ public class NodeHelper implements ApplicationContextAware {
} else if (StringUtils.isBlank(node.getType())) {
return new DefaultJobNode(node.getName());
} else {
try {
Class<? extends ProcessNode> clazz;
// TODO: Considerare i nodi annotati con WfNode
final ProcessNode pnode = this.applicationContext.getBean(beanNamePrefix + node.getType(), ProcessNode.class);
if (pnode != null) {
pnode.setNodeName(node.getName());
if (pnode instanceof ProcessAware) {
((ProcessAware) pnode).setProcess(process);
clazz = findClassForNodeType(node.getType());
final ProcessNode pnode = this.applicationContext.getBean(clazz);
if (pnode != null) {
pnode.setNodeName(node.getName());
if (pnode instanceof ProcessAware) {
((ProcessAware) pnode).setProcess(process);
}
return pnode;
} else {
log.error("cannot find bean of type " + node.getType());
throw new WorkflowManagerException("cannot find bean of type " + node.getType());
}
return pnode;
} else {
log.error("cannot find bean " + beanNamePrefix + node.getType());
throw new WorkflowManagerException("cannot find bean " + beanNamePrefix + node.getType());
} catch (final ClassNotFoundException e) {
throw new WorkflowManagerException("Class not found for node " + node.getType());
}
}
}
public boolean isValidType(final String type) {
return StringUtils.isBlank(type) || this.applicationContext.isPrototype(beanNamePrefix + type) && this.applicationContext
.isTypeMatch(beanNamePrefix + type, ProcessNode.class);
private Class<? extends ProcessNode> findClassForNodeType(final String type) throws ClassNotFoundException {
final ClassPathScanningCandidateComponentProvider provider =
new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new AnnotationTypeFilter(WfNode.class));
final Set<BeanDefinition> beanDefs = provider.findCandidateComponents("eu.dnetlib.wf.nodes");
for (final BeanDefinition bd : beanDefs) {
if (bd instanceof AnnotatedBeanDefinition) {
final Map<String, Object> annotAttributeMap = ((AnnotatedBeanDefinition) bd)
.getMetadata()
.getAnnotationAttributes(WfNode.class.getCanonicalName());
if (type.equals(annotAttributeMap.get("value"))) {
final Class<?> clazz = Class.forName(bd.getBeanClassName());
if (ProcessNode.class.isAssignableFrom(clazz)) { return (Class<? extends ProcessNode>) Class.forName(bd.getBeanClassName()); }
}
}
}
throw new ClassNotFoundException("Class not found for type " + type);
}
public boolean isValid(final GraphNode n) {
if (n.getType() == null) {
return true;
} else {
try {
return findClassForNodeType(n.getType()) != null;
} catch (final ClassNotFoundException e) {
return false;
}
}
}
@Override