diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/NodeInstanceContainer.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/NodeInstanceContainer.java index 65c8e09205d..3fb400cc16d 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/NodeInstanceContainer.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/NodeInstanceContainer.java @@ -19,6 +19,7 @@ package org.jbpm.workflow.instance; import java.util.Collection; +import java.util.Map; import org.jbpm.workflow.core.node.AsyncEventNode; import org.kie.api.definition.process.Node; @@ -99,4 +100,6 @@ default Node resolveAsync(Node node) { } return node; } + + Map getIterationLevels(); } diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/CompositeContextNodeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/CompositeContextNodeInstance.java index 8800dda04eb..5d564f4d7a7 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/CompositeContextNodeInstance.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/CompositeContextNodeInstance.java @@ -51,6 +51,7 @@ public void setContextInstance(String contextId, ContextInstance contextInstance this.contextInstances.put(contextId, contextInstance); } + @Override public ContextInstance getContextInstance(String contextId) { ContextInstance contextInstance = this.contextInstances.get(contextId); if (contextInstance != null) { diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/CompositeNodeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/CompositeNodeInstance.java index e7571121645..2612be7998b 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/CompositeNodeInstance.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/CompositeNodeInstance.java @@ -468,6 +468,7 @@ public void setCurrentLevel(int currentLevel) { this.currentLevel = currentLevel; } + @Override public Map getIterationLevels() { return iterationLevels; } diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerContextName.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerContextName.java index e3253299d8c..3ec1d8cc8fa 100644 --- a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerContextName.java +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerContextName.java @@ -18,22 +18,36 @@ */ package org.jbpm.flow.serialization; +import java.util.function.Supplier; + +import org.jbpm.ruleflow.instance.RuleFlowProcessInstance; import org.kie.kogito.process.Process; public final class MarshallerContextName { - public static final MarshallerContextName OBJECT_MARSHALLING_STRATEGIES = new MarshallerContextName<>("OBJECT_MARSHALLING_STRATEGIES"); + public static final MarshallerContextName OBJECT_MARSHALLING_STRATEGIES = + new MarshallerContextName<>("OBJECT_MARSHALLING_STRATEGIES", () -> new ObjectMarshallerStrategy[0]); public static final MarshallerContextName MARSHALLER_FORMAT = new MarshallerContextName<>("FORMAT"); public static final MarshallerContextName> MARSHALLER_PROCESS = new MarshallerContextName<>("PROCESS"); + public static final MarshallerContextName MARSHALLER_PROCESS_INSTANCE = new MarshallerContextName<>("PROCESS_INSTANCE"); public static final MarshallerContextName MARSHALLER_INSTANCE_READ_ONLY = new MarshallerContextName<>("READ_ONLY"); - public static final MarshallerContextName MARSHALLER_INSTANCE_LISTENER = new MarshallerContextName<>("MARSHALLER_INSTANCE_LISTENERS"); + public static final MarshallerContextName MARSHALLER_INSTANCE_LISTENER = + new MarshallerContextName<>("MARSHALLER_INSTANCE_LISTENERS", () -> new ProcessInstanceMarshallerListener[0]); + public static final MarshallerContextName MARSHALLER_NODE_INSTANCE_READER = new MarshallerContextName<>("MARSHALLER_NODE_INSTANCE_READER", () -> new NodeInstanceReader[0]); + public static final MarshallerContextName MARSHALLER_NODE_INSTANCE_WRITER = new MarshallerContextName<>("MARSHALLER_NODE_INSTANCE_WRITER", () -> new NodeInstanceWriter[0]); public static final String MARSHALLER_FORMAT_JSON = "json"; private String name; + private Supplier defaultValue; private MarshallerContextName(String name) { + this(name, () -> null); + } + + private MarshallerContextName(String name, Supplier defaultValue) { this.name = name; + this.defaultValue = defaultValue; } public String name() { @@ -44,4 +58,8 @@ public String name() { public T cast(Object value) { return (T) value; } + + public T defaultValue() { + return defaultValue.get(); + } } diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerReaderContext.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerReaderContext.java index 2ded4cc7b87..8d7e5135504 100644 --- a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerReaderContext.java +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerReaderContext.java @@ -20,8 +20,12 @@ import java.io.InputStream; +import com.google.protobuf.Any; + public interface MarshallerReaderContext extends MarshallerContext { InputStream input(); + NodeInstanceReader findNodeInstanceReader(Any nodeInstance); + } diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerWriterContext.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerWriterContext.java index 0e1cb715b04..32c1c15ffc9 100644 --- a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerWriterContext.java +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerWriterContext.java @@ -20,8 +20,12 @@ import java.io.OutputStream; +import org.kie.api.runtime.process.NodeInstance; + public interface MarshallerWriterContext extends MarshallerContext { OutputStream output(); + NodeInstanceWriter findNodeInstanceWriter(NodeInstance nodeInstance); + } diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/NodeInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/NodeInstanceReader.java new file mode 100644 index 00000000000..2efbca435a5 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/NodeInstanceReader.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization; + +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.Any; +import com.google.protobuf.GeneratedMessageV3; + +public interface NodeInstanceReader extends Comparable { + Integer DEFAULT_ORDER = 10; + + default Integer order() { + return DEFAULT_ORDER; + } + + @Override + default int compareTo(NodeInstanceReader that) { + return this.order().compareTo(that.order()); + } + + Class type(); + + default boolean accept(Any value) { + return value.is(type()); + } + + NodeInstance read(MarshallerReaderContext context, Any value); +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/NodeInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/NodeInstanceWriter.java new file mode 100644 index 00000000000..dec298ba81f --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/NodeInstanceWriter.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization; + +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.GeneratedMessageV3; + +public interface NodeInstanceWriter extends Comparable { + Integer DEFAULT_ORDER = 10; + + default Integer order() { + return DEFAULT_ORDER; + } + + @Override + default int compareTo(NodeInstanceWriter that) { + return this.order().compareTo(that.order()); + } + + boolean accept(NodeInstance value); + + GeneratedMessageV3.Builder write(MarshallerWriterContext writer, NodeInstance value); + +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerException.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerException.java index 14ee48fc655..e7c9719aa13 100644 --- a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerException.java +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerException.java @@ -22,6 +22,10 @@ public class ProcessInstanceMarshallerException extends RuntimeException { private static final long serialVersionUID = -1676023219884892322L; + public ProcessInstanceMarshallerException(Throwable th) { + super(th); + } + public ProcessInstanceMarshallerException(String msg) { super(msg); } diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerService.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerService.java index 0b55ca20330..6b0fbd300d9 100644 --- a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerService.java +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerService.java @@ -31,6 +31,7 @@ import java.util.function.Supplier; import org.jbpm.flow.serialization.impl.ProtobufProcessInstanceMarshallerFactory; +import org.jbpm.util.JbpmClassLoaderUtil; import org.kie.kogito.process.Process; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.ProcessInstanceReadMode; @@ -49,6 +50,9 @@ public class ProcessInstanceMarshallerService { private ProcessInstanceMarshallerFactory processInstanceMarshallerFactory; + private List readers; + private List writers; + public class Builder { public Builder() { @@ -60,9 +64,10 @@ public Builder withProcessInstanceMarshallerFactory(ProcessInstanceMarshallerFac return this; } + @SuppressWarnings("unchecked") public Builder withContextEntries(Map, T> contextEntries) { for (Map.Entry, T> item : contextEntries.entrySet()) { - ProcessInstanceMarshallerService.this.contextEntries.put((MarshallerContextName) item.getKey(), (Object) item.getValue()); + ProcessInstanceMarshallerService.this.contextEntries.put((MarshallerContextName) item.getKey(), item.getValue()); } return this; } @@ -77,11 +82,23 @@ public Builder withDefaultListeners() { } public Builder withDefaultObjectMarshallerStrategies() { - ServiceLoader loader = ServiceLoader.load(ObjectMarshallerStrategy.class); + ServiceLoader loader = ServiceLoader.load(ObjectMarshallerStrategy.class, JbpmClassLoaderUtil.findClassLoader()); for (ObjectMarshallerStrategy strategy : loader) { ProcessInstanceMarshallerService.this.strats.add(strategy); } + + ServiceLoader readerLoader = ServiceLoader.load(NodeInstanceReader.class, JbpmClassLoaderUtil.findClassLoader()); + + for (NodeInstanceReader reader : readerLoader) { + ProcessInstanceMarshallerService.this.readers.add(reader); + } + + ServiceLoader writerLoader = ServiceLoader.load(NodeInstanceWriter.class, JbpmClassLoaderUtil.findClassLoader()); + + for (NodeInstanceWriter writer : writerLoader) { + ProcessInstanceMarshallerService.this.writers.add(writer); + } return this; } @@ -101,6 +118,8 @@ public Builder withObjectMarshallerStrategies(ObjectMarshallerStrategy... strate public ProcessInstanceMarshallerService build() { Collections.sort(ProcessInstanceMarshallerService.this.strats); + Collections.sort(ProcessInstanceMarshallerService.this.readers); + Collections.sort(ProcessInstanceMarshallerService.this.writers); return ProcessInstanceMarshallerService.this; } @@ -113,6 +132,8 @@ public static Builder newBuilder() { private ProcessInstanceMarshallerService() { this.listeners = new ArrayList<>(); this.strats = new ArrayList<>(); + this.readers = new ArrayList<>(); + this.writers = new ArrayList<>(); this.contextEntries = new HashMap<>(); } @@ -129,6 +150,7 @@ public byte[] marshallProcessInstance(ProcessInstance processInstance) { MarshallerWriterContext context = processInstanceMarshallerFactory.newWriterContext(baos); context.set(MarshallerContextName.MARSHALLER_PROCESS, processInstance.process()); context.set(MarshallerContextName.MARSHALLER_INSTANCE_LISTENER, listeners.toArray(ProcessInstanceMarshallerListener[]::new)); + context.set(MarshallerContextName.MARSHALLER_NODE_INSTANCE_WRITER, this.writers.toArray(NodeInstanceWriter[]::new)); setupEnvironment(context); org.jbpm.flow.serialization.ProcessInstanceMarshaller marshaller = processInstanceMarshallerFactory.newKogitoProcessInstanceMarshaller(); marshaller.writeProcessInstance(context, processInstance); @@ -144,6 +166,7 @@ public ProcessInstance unmarshallProcessInstance(byte[] data, Process proc context.set(MarshallerContextName.MARSHALLER_PROCESS, process); context.set(MarshallerContextName.MARSHALLER_INSTANCE_READ_ONLY, readOnly); context.set(MarshallerContextName.MARSHALLER_INSTANCE_LISTENER, listeners.toArray(ProcessInstanceMarshallerListener[]::new)); + context.set(MarshallerContextName.MARSHALLER_NODE_INSTANCE_READER, this.readers.toArray(NodeInstanceReader[]::new)); setupEnvironment(context); org.jbpm.flow.serialization.ProcessInstanceMarshaller marshaller = processInstanceMarshallerFactory.newKogitoProcessInstanceMarshaller(); return marshaller.readProcessInstance(context); @@ -170,6 +193,7 @@ public Consumer> createdReloadFunction(Supplier env; + private Map, Object> env; public ProtobufAbstractMarshallerContext() { this.env = new HashMap<>(); @@ -40,7 +40,8 @@ public ProtobufAbstractMarshallerContext() { @SuppressWarnings("unchecked") @Override public T get(MarshallerContextName key) { - return (T) env.get(key); + T value = (T) env.get(key); + return value != null ? value : key.defaultValue(); } @Override diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufMarshallerReaderContext.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufMarshallerReaderContext.java index 8ebb519caae..a7559dfacc1 100755 --- a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufMarshallerReaderContext.java +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufMarshallerReaderContext.java @@ -20,7 +20,11 @@ import java.io.InputStream; +import org.jbpm.flow.serialization.MarshallerContextName; import org.jbpm.flow.serialization.MarshallerReaderContext; +import org.jbpm.flow.serialization.NodeInstanceReader; + +import com.google.protobuf.Any; public class ProtobufMarshallerReaderContext extends ProtobufAbstractMarshallerContext implements MarshallerReaderContext { @@ -35,4 +39,15 @@ public InputStream input() { return is; } + @Override + public NodeInstanceReader findNodeInstanceReader(Any nodeInstance) { + NodeInstanceReader[] readers = this.get(MarshallerContextName.MARSHALLER_NODE_INSTANCE_READER); + for (NodeInstanceReader reader : readers) { + if (reader.accept(nodeInstance)) { + return reader; + } + } + return null; + } + } diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceReader.java index afb3f851c4c..e42bf3c0a58 100644 --- a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceReader.java +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceReader.java @@ -21,83 +21,42 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.net.URI; -import java.util.ArrayList; import java.util.Arrays; import java.util.Date; -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; -import java.util.UUID; import java.util.function.Function; import java.util.stream.Collectors; import org.jbpm.flow.serialization.MarshallerContextName; import org.jbpm.flow.serialization.MarshallerReaderContext; -import org.jbpm.flow.serialization.ProcessInstanceMarshallerException; +import org.jbpm.flow.serialization.NodeInstanceReader; import org.jbpm.flow.serialization.ProcessInstanceMarshallerListener; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.AsyncEventNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.CompositeContextNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.DynamicNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.EventNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.EventSubProcessNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.ForEachNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.JoinNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.LambdaSubProcessNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.MilestoneNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.RuleSetNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.StateNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.SubProcessNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.TimerNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.WorkItemNodeInstanceContent; import org.jbpm.flow.serialization.protobuf.KogitoProcessInstanceProtobuf; import org.jbpm.flow.serialization.protobuf.KogitoTypesProtobuf; import org.jbpm.flow.serialization.protobuf.KogitoTypesProtobuf.SLAContext; import org.jbpm.flow.serialization.protobuf.KogitoTypesProtobuf.WorkflowContext; -import org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf; -import org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData; import org.jbpm.process.core.context.exclusive.ExclusiveGroup; import org.jbpm.process.core.context.swimlane.SwimlaneContext; import org.jbpm.process.core.context.variable.VariableScope; +import org.jbpm.process.instance.ContextInstanceContainer; +import org.jbpm.process.instance.ContextableInstance; import org.jbpm.process.instance.context.exclusive.ExclusiveGroupInstance; import org.jbpm.process.instance.context.swimlane.SwimlaneContextInstance; import org.jbpm.process.instance.context.variable.VariableScopeInstance; -import org.jbpm.process.instance.impl.humantask.HumanTaskWorkItemImpl; -import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem; -import org.jbpm.process.instance.impl.humantask.Reassignment; import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory; import org.jbpm.ruleflow.instance.RuleFlowProcessInstance; -import org.jbpm.workflow.core.node.AsyncEventNodeInstance; +import org.jbpm.workflow.instance.NodeInstanceContainer; import org.jbpm.workflow.instance.impl.NodeInstanceImpl; -import org.jbpm.workflow.instance.node.CompositeContextNodeInstance; -import org.jbpm.workflow.instance.node.DynamicNodeInstance; -import org.jbpm.workflow.instance.node.EventNodeInstance; -import org.jbpm.workflow.instance.node.EventSubProcessNodeInstance; -import org.jbpm.workflow.instance.node.ForEachNodeInstance; -import org.jbpm.workflow.instance.node.HumanTaskNodeInstance; -import org.jbpm.workflow.instance.node.JoinInstance; -import org.jbpm.workflow.instance.node.LambdaSubProcessNodeInstance; -import org.jbpm.workflow.instance.node.MilestoneNodeInstance; -import org.jbpm.workflow.instance.node.RuleSetNodeInstance; -import org.jbpm.workflow.instance.node.StateNodeInstance; -import org.jbpm.workflow.instance.node.SubProcessNodeInstance; -import org.jbpm.workflow.instance.node.TimerNodeInstance; -import org.jbpm.workflow.instance.node.WorkItemNodeInstance; -import org.kie.api.definition.process.WorkflowElementIdentifier; import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; import org.kie.kogito.internal.process.runtime.KogitoNodeInstanceContainer; import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime; import org.kie.kogito.process.impl.AbstractProcess; -import org.kie.kogito.process.workitem.Attachment; -import org.kie.kogito.process.workitem.Comment; -import org.kie.kogito.process.workitems.InternalKogitoWorkItem; -import org.kie.kogito.process.workitems.impl.KogitoWorkItemImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.protobuf.Any; -import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.GeneratedMessageV3; import com.google.protobuf.util.JsonFormat; import static org.jbpm.flow.serialization.protobuf.ProtobufTypeRegistryFactory.protobufTypeRegistryFactoryInstance; @@ -114,7 +73,7 @@ public ProtobufProcessInstanceReader(MarshallerReaderContext context) { this.ruleFlowProcessInstance = new RuleFlowProcessInstance(); this.varReader = new ProtobufVariableReader(context); this.listeners = context.get(MarshallerContextName.MARSHALLER_INSTANCE_LISTENER); - this.listeners = this.listeners != null ? this.listeners : new ProcessInstanceMarshallerListener[0]; + context.set(MarshallerContextName.MARSHALLER_PROCESS_INSTANCE, ruleFlowProcessInstance); } public RuleFlowProcessInstance read(InputStream input) throws IOException { @@ -212,25 +171,8 @@ private RuleFlowProcessInstance buildWorkflow(KogitoProcessInstanceProtobuf.Proc } WorkflowContext workflowContext = processInstanceProtobuf.getContext(); + buildWorkflowContext(processInstance, workflowContext); - for (KogitoTypesProtobuf.NodeInstance nodeInstanceProtobuf : workflowContext.getNodeInstanceList()) { - buildNodeInstance(nodeInstanceProtobuf, processInstance); - } - - for (KogitoTypesProtobuf.NodeInstanceGroup group : workflowContext.getExclusiveGroupList()) { - Function finder = nodeInstanceId -> processInstance.getNodeInstance(nodeInstanceId, true); - processInstance.addContextInstance(ExclusiveGroup.EXCLUSIVE_GROUP, buildExclusiveGroupInstance(group, finder)); - } - - processInstance.addContextInstance(VariableScope.VARIABLE_SCOPE, new VariableScopeInstance()); - if (workflowContext.getVariableCount() > 0) { - VariableScopeInstance variableScopeInstance = (VariableScopeInstance) processInstance.getContextInstance(VariableScope.VARIABLE_SCOPE); - varReader.buildVariables(workflowContext.getVariableList()).forEach(v -> variableScopeInstance.internalSetVariable(v.getName(), v.getValue())); - } - - if (workflowContext.getIterationLevelsCount() > 0) { - processInstance.getIterationLevels().putAll(buildIterationLevels(workflowContext.getIterationLevelsList())); - } KogitoProcessRuntime runtime = ((AbstractProcess) context.get(MarshallerContextName.MARSHALLER_PROCESS)).getProcessRuntime(); Arrays.stream(listeners).forEach(e -> e.afterUnmarshallProcess(runtime, processInstance)); return processInstance; @@ -257,58 +199,27 @@ private void setCommonNodeInstanceData(RuleFlowProcessInstance processInstance, } protected NodeInstanceImpl buildNodeInstance(KogitoTypesProtobuf.NodeInstance nodeInstance, KogitoNodeInstanceContainer parent) { - final com.google.protobuf.Any nodeContentProtobuf = nodeInstance.getContent(); - NodeInstanceImpl result = null; try { - if (nodeContentProtobuf.is(RuleSetNodeInstanceContent.class)) { - RuleSetNodeInstanceContent content = nodeContentProtobuf.unpack(RuleSetNodeInstanceContent.class); - result = buildRuleSetNodeInstance(content); - } else if (nodeContentProtobuf.is(ForEachNodeInstanceContent.class)) { - ForEachNodeInstanceContent content = nodeContentProtobuf.unpack(ForEachNodeInstanceContent.class); - result = buildForEachNodeInstance(content, nodeInstance, parent); - } else if (nodeContentProtobuf.is(LambdaSubProcessNodeInstanceContent.class)) { - LambdaSubProcessNodeInstanceContent content = nodeContentProtobuf.unpack(LambdaSubProcessNodeInstanceContent.class); - result = buildLambdaSubProcessNodeInstance(content); - } else if (nodeContentProtobuf.is(SubProcessNodeInstanceContent.class)) { - SubProcessNodeInstanceContent content = nodeContentProtobuf.unpack(SubProcessNodeInstanceContent.class); - result = buildSubProcessNodeInstance(content); - } else if (nodeContentProtobuf.is(StateNodeInstanceContent.class)) { - StateNodeInstanceContent content = nodeContentProtobuf.unpack(StateNodeInstanceContent.class); - result = buildStateNodeInstance(content); - } else if (nodeContentProtobuf.is(JoinNodeInstanceContent.class)) { - JoinNodeInstanceContent content = nodeContentProtobuf.unpack(JoinNodeInstanceContent.class); - result = buildJoinInstance(content); - } else if (nodeContentProtobuf.is(TimerNodeInstanceContent.class)) { - TimerNodeInstanceContent content = nodeContentProtobuf.unpack(TimerNodeInstanceContent.class); - result = buildTimerNodeInstance(content); - } else if (nodeContentProtobuf.is(EventNodeInstanceContent.class)) { - result = buildEventNodeInstance(); - } else if (nodeContentProtobuf.is(MilestoneNodeInstanceContent.class)) { - MilestoneNodeInstanceContent content = nodeContentProtobuf.unpack(MilestoneNodeInstanceContent.class); - result = buildMilestoneNodeInstance(content); - } else if (nodeContentProtobuf.is(DynamicNodeInstanceContent.class)) { - DynamicNodeInstanceContent content = nodeContentProtobuf.unpack(DynamicNodeInstanceContent.class); - result = buildDynamicNodeInstance(content, nodeInstance, parent); - } else if (nodeContentProtobuf.is(EventSubProcessNodeInstanceContent.class)) { - EventSubProcessNodeInstanceContent content = nodeContentProtobuf.unpack(EventSubProcessNodeInstanceContent.class); - result = buildEventSubProcessNodeInstance(content); - } else if (nodeContentProtobuf.is(CompositeContextNodeInstanceContent.class)) { - CompositeContextNodeInstanceContent content = nodeContentProtobuf.unpack(CompositeContextNodeInstanceContent.class); - result = buildCompositeContextNodeInstance(content, nodeInstance, parent); - } else if (nodeContentProtobuf.is(WorkItemNodeInstanceContent.class)) { - WorkItemNodeInstanceContent content = nodeContentProtobuf.unpack(WorkItemNodeInstanceContent.class); - result = buildWorkItemNodeInstance(content); - } else if (nodeContentProtobuf.is(AsyncEventNodeInstanceContent.class)) { - AsyncEventNodeInstanceContent content = nodeContentProtobuf.unpack(AsyncEventNodeInstanceContent.class); - result = buildAsyncEventNodeInstance(content); - } + com.google.protobuf.Any nodeContentProtobuf = nodeInstance.getContent(); - if (Objects.isNull(result)) { - throw new IllegalArgumentException("Unknown node instance"); + NodeInstanceReader reader = context.findNodeInstanceReader(nodeContentProtobuf); + if (reader == null) { + throw new IllegalArgumentException("Unknown node instance " + nodeInstance); } - + LOGGER.debug("Node reader {}", reader); + NodeInstanceImpl result = (NodeInstanceImpl) reader.read(context, nodeContentProtobuf); setCommonNodeInstanceData(ruleFlowProcessInstance, parent, nodeInstance, result); + LOGGER.debug("Node {} content {}", reader.type(), nodeContentProtobuf); + GeneratedMessageV3 content = nodeContentProtobuf.unpack(reader.type()); + LOGGER.debug("Node instance being reading {}", result); + FieldDescriptor fieldDescriptor = getContextField(content); + if (fieldDescriptor != null) { + LOGGER.debug("Node instance context being reading {}", result); + KogitoTypesProtobuf.WorkflowContext workflowContext = (KogitoTypesProtobuf.WorkflowContext) content.getField(fieldDescriptor); + buildWorkflowContext((NodeInstanceContainer & ContextInstanceContainer & ContextableInstance) result, workflowContext); + } + SLAContext slaNodeInstanceContext = nodeInstance.getSla(); result.internalSetSlaCompliance(slaNodeInstanceContext.getSlaCompliance()); if (slaNodeInstanceContext.getSlaDueDate() > 0) { @@ -324,282 +235,25 @@ protected NodeInstanceImpl buildNodeInstance(KogitoTypesProtobuf.NodeInstance no Arrays.stream(listeners).forEach(e -> e.afterUnmarshallNode(runtime, kogitoNodeInstance)); return result; } catch (IOException e) { - throw new IllegalArgumentException("Cannot read node instance content"); + throw new IllegalArgumentException("Cannot read node instance content", e); } } - private NodeInstanceImpl buildAsyncEventNodeInstance(AsyncEventNodeInstanceContent content) { - AsyncEventNodeInstance nodeInstance = new AsyncEventNodeInstance(); - nodeInstance.setJobId(content.getJobId()); - return nodeInstance; - } - - private NodeInstanceImpl buildCompositeContextNodeInstance(CompositeContextNodeInstanceContent content, KogitoTypesProtobuf.NodeInstance protoNodeInstance, - KogitoNodeInstanceContainer parentContainer) { - CompositeContextNodeInstance nodeInstance = new CompositeContextNodeInstance(); - - if (content.getTimerInstanceIdCount() > 0) { - List timerInstances = new ArrayList<>(); - for (String _timerId : content.getTimerInstanceIdList()) { - timerInstances.add(_timerId); + public FieldDescriptor getContextField(GeneratedMessageV3 message) { + for (FieldDescriptor field : message.getDescriptorForType().getFields()) { + if ("context".equals(field.getName())) { + return field; } - nodeInstance.internalSetTimerInstances(timerInstances); - } - if (!content.getTimerInstanceReferenceMap().isEmpty()) { - nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); - } - - setCommonNodeInstanceData(ruleFlowProcessInstance, parentContainer, protoNodeInstance, nodeInstance); - - buildWorkflowContext(nodeInstance, content.getContext()); - return nodeInstance; - } - - private NodeInstanceImpl buildEventSubProcessNodeInstance(EventSubProcessNodeInstanceContent content) { - EventSubProcessNodeInstance nodeInstance = new EventSubProcessNodeInstance(); - - if (content.getTimerInstanceIdCount() > 0) { - List timerInstances = new ArrayList<>(); - for (String _timerId : content.getTimerInstanceIdList()) { - timerInstances.add(_timerId); - } - nodeInstance.internalSetTimerInstances(timerInstances); - } - if (!content.getTimerInstanceReferenceMap().isEmpty()) { - nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); - } - buildWorkflowContext(nodeInstance, content.getContext()); - return nodeInstance; - } - - private NodeInstanceImpl buildDynamicNodeInstance(DynamicNodeInstanceContent content, KogitoTypesProtobuf.NodeInstance protoNodeInstance, - KogitoNodeInstanceContainer parentContainer) { - DynamicNodeInstance nodeInstance = new DynamicNodeInstance(); - if (content.getTimerInstanceIdCount() > 0) { - List timerInstances = new ArrayList<>(); - for (String _timerId : content.getTimerInstanceIdList()) { - timerInstances.add(_timerId); - } - nodeInstance.internalSetTimerInstances(timerInstances); - } - if (!content.getTimerInstanceReferenceMap().isEmpty()) { - nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); - } - - setCommonNodeInstanceData(ruleFlowProcessInstance, parentContainer, protoNodeInstance, nodeInstance); - buildWorkflowContext(nodeInstance, content.getContext()); - - return nodeInstance; - - } - - private NodeInstanceImpl buildMilestoneNodeInstance(MilestoneNodeInstanceContent content) { - MilestoneNodeInstance nodeInstance = new MilestoneNodeInstance(); - if (content.getTimerInstanceIdCount() > 0) { - List timerInstances = new ArrayList<>(); - for (String _timerId : content.getTimerInstanceIdList()) { - timerInstances.add(_timerId); - } - nodeInstance.internalSetTimerInstances(timerInstances); - } - if (!content.getTimerInstanceReferenceMap().isEmpty()) { - nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); - } - return nodeInstance; - } - - private NodeInstanceImpl buildEventNodeInstance() { - return new EventNodeInstance(); - } - - private NodeInstanceImpl buildTimerNodeInstance(TimerNodeInstanceContent content) { - TimerNodeInstance nodeInstance = new TimerNodeInstance(); - nodeInstance.internalSetTimerId(content.getTimerId()); - return nodeInstance; - } - - private NodeInstanceImpl buildJoinInstance(JoinNodeInstanceContent content) { - JoinInstance nodeInstance = new JoinInstance(); - if (content.getTriggerCount() > 0) { - Map triggers = new HashMap<>(); - for (JoinNodeInstanceContent.JoinTrigger _join : content.getTriggerList()) { - LOGGER.info("unmarshalling join {}", _join.getNodeId()); - triggers.put(WorkflowElementIdentifierFactory.fromExternalFormat(_join.getNodeId()), _join.getCounter()); - } - nodeInstance.internalSetTriggers(triggers); - } - return nodeInstance; - } - - private NodeInstanceImpl buildStateNodeInstance(StateNodeInstanceContent content) { - StateNodeInstance nodeInstance = new StateNodeInstance(); - if (content.getTimerInstanceIdCount() > 0) { - List timerInstances = new ArrayList<>(); - for (String _timerId : content.getTimerInstanceIdList()) { - timerInstances.add(_timerId); - } - nodeInstance.internalSetTimerInstances(timerInstances); - } - if (!content.getTimerInstanceReferenceMap().isEmpty()) { - nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); } - return nodeInstance; + return null; } - private NodeInstanceImpl buildSubProcessNodeInstance(SubProcessNodeInstanceContent content) { - SubProcessNodeInstance nodeInstance = new SubProcessNodeInstance(); - nodeInstance.internalSetProcessInstanceId(content.getProcessInstanceId()); - if (content.getTimerInstanceIdCount() > 0) { - List timerInstances = new ArrayList<>(); - for (String timerId : content.getTimerInstanceIdList()) { - timerInstances.add(timerId); - } - nodeInstance.internalSetTimerInstances(timerInstances); - } - if (!content.getTimerInstanceReferenceMap().isEmpty()) { - nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); - } - - return nodeInstance; - } - - private NodeInstanceImpl buildLambdaSubProcessNodeInstance(LambdaSubProcessNodeInstanceContent content) { - LambdaSubProcessNodeInstance nodeInstance = new LambdaSubProcessNodeInstance(); - nodeInstance.internalSetProcessInstanceId(content.getProcessInstanceId()); - if (content.getTimerInstanceIdCount() > 0) { - nodeInstance.internalSetTimerInstances(new ArrayList<>(content.getTimerInstanceIdList())); - } - if (!content.getTimerInstanceReferenceMap().isEmpty()) { - nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); - } - return nodeInstance; - } - - private NodeInstanceImpl buildForEachNodeInstance(ForEachNodeInstanceContent content, KogitoTypesProtobuf.NodeInstance protoNodeInstance, KogitoNodeInstanceContainer parentContainer) { - ForEachNodeInstance nodeInstance = new ForEachNodeInstance(); - nodeInstance.setExecutedInstances(content.getExecutedInstances()); - nodeInstance.setTotalInstances(content.getTotalInstances()); - nodeInstance.setHasAsyncInstances(content.getHasAsyncInstances()); - - setCommonNodeInstanceData(ruleFlowProcessInstance, parentContainer, protoNodeInstance, nodeInstance); - buildWorkflowContext(nodeInstance, content.getContext()); - return nodeInstance; - } - - private NodeInstanceImpl buildRuleSetNodeInstance(RuleSetNodeInstanceContent content) { - RuleSetNodeInstance nodeInstance = new RuleSetNodeInstance(); - nodeInstance.setRuleFlowGroup(content.getRuleFlowGroup()); - if (content.getTimerInstanceIdCount() > 0) { - nodeInstance.internalSetTimerInstances(new ArrayList<>(content.getTimerInstanceIdList())); - } - if (!content.getTimerInstanceReferenceMap().isEmpty()) { - nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); - } - - return nodeInstance; - } - - private NodeInstanceImpl buildWorkItemNodeInstance(WorkItemNodeInstanceContent content) { - try { - WorkItemNodeInstance nodeInstance = instanceWorkItem(content); - if (nodeInstance instanceof HumanTaskNodeInstance) { - HumanTaskNodeInstance humanTaskNodeInstance = (HumanTaskNodeInstance) nodeInstance; - InternalHumanTaskWorkItem workItem = humanTaskNodeInstance.getWorkItem(); - Any workItemDataMessage = content.getWorkItemData(); - if (workItemDataMessage.is(HumanTaskWorkItemData.class)) { - HumanTaskWorkItemData workItemData = workItemDataMessage.unpack(HumanTaskWorkItemData.class); - humanTaskNodeInstance.getNotCompletedDeadlineTimers().putAll(buildDeadlines(workItemData.getCompletedDeadlinesMap())); - humanTaskNodeInstance.getNotCompletedReassigments().putAll(buildReassignments(workItemData.getCompletedReassigmentsMap())); - humanTaskNodeInstance.getNotStartedDeadlineTimers().putAll(buildDeadlines(workItemData.getStartDeadlinesMap())); - humanTaskNodeInstance.getNotStartedReassignments().putAll(buildReassignments(workItemData.getStartReassigmentsMap())); - - if (workItemData.hasTaskName()) { - workItem.setTaskName(workItemData.getTaskName()); - } - if (workItemData.hasTaskDescription()) { - workItem.setTaskDescription(workItemData.getTaskDescription()); - } - if (workItemData.hasTaskPriority()) { - workItem.setTaskPriority(workItemData.getTaskPriority()); - } - if (workItemData.hasTaskReferenceName()) { - workItem.setReferenceName(workItemData.getTaskReferenceName()); - } - if (workItemData.hasActualOwner()) { - workItem.setActualOwner(workItemData.getActualOwner()); - } - workItem.getAdminUsers().addAll(workItemData.getAdminUsersList()); - workItem.getAdminGroups().addAll(workItemData.getAdminGroupsList()); - workItem.getPotentialUsers().addAll(workItemData.getPotUsersList()); - workItem.getPotentialGroups().addAll(workItemData.getPotGroupsList()); - workItem.getExcludedUsers().addAll(workItemData.getExcludedUsersList()); - workItem.getComments().putAll(workItemData.getCommentsList().stream().map(this::buildComment).collect(Collectors.toMap(Comment::getId, Function.identity()))); - workItem.getAttachments().putAll(workItemData.getAttachmentsList().stream().map(this::buildAttachment).collect(Collectors.toMap(Attachment::getId, Function.identity()))); - - } - - } - - nodeInstance.internalSetWorkItemId(content.getWorkItemId()); - InternalKogitoWorkItem workItem = (InternalKogitoWorkItem) nodeInstance.getWorkItem(); - workItem.setId(content.getWorkItemId()); - workItem.setProcessInstanceId(ruleFlowProcessInstance.getStringId()); - workItem.setName(content.getName()); - workItem.setState(content.getState()); - workItem.setDeploymentId(ruleFlowProcessInstance.getDeploymentId()); - workItem.setProcessInstance(ruleFlowProcessInstance); - workItem.setPhaseId(content.getPhaseId()); - workItem.setPhaseStatus(content.getPhaseStatus()); - workItem.setStartDate(new Date(content.getStartDate())); - if (content.getCompleteDate() > 0) { - workItem.setCompleteDate(new Date(content.getCompleteDate())); - } - - if (content.getTimerInstanceIdCount() > 0) { - nodeInstance.internalSetTimerInstances(new ArrayList<>(content.getTimerInstanceIdList())); - } - if (!content.getTimerInstanceReferenceMap().isEmpty()) { - nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); - } - nodeInstance.internalSetProcessInstanceId(content.getErrorHandlingProcessInstanceId()); - varReader.buildVariables(content.getVariableList()).forEach(var -> nodeInstance.getWorkItem().getParameters().put(var.getName(), var.getValue())); - varReader.buildVariables(content.getResultList()).forEach(var -> nodeInstance.getWorkItem().getResults().put(var.getName(), var.getValue())); - return nodeInstance; - } catch (InvalidProtocolBufferException ex) { - throw new ProcessInstanceMarshallerException("cannot unpack node instance", ex); - } - } - - private WorkItemNodeInstance instanceWorkItem(WorkItemNodeInstanceContent content) { - if (content.hasWorkItemData()) { - Any workItemDataMessage = content.getWorkItemData(); - if (workItemDataMessage.is(HumanTaskWorkItemData.class)) { - HumanTaskNodeInstance nodeInstance = new HumanTaskNodeInstance(); - HumanTaskWorkItemImpl workItem = new HumanTaskWorkItemImpl(); - nodeInstance.internalSetWorkItem(workItem); - return nodeInstance; - } else { - throw new ProcessInstanceMarshallerException("Don't know which type of work item is"); - } - } else { - WorkItemNodeInstance nodeInstance = new WorkItemNodeInstance(); - KogitoWorkItemImpl workItem = new KogitoWorkItemImpl(); - workItem.setId(UUID.randomUUID().toString()); - nodeInstance.internalSetWorkItem(workItem); - return nodeInstance; - } - } - - private void buildWorkflowContext(CompositeContextNodeInstance container, WorkflowContext workflowContext) { + private void buildWorkflowContext(T container, WorkflowContext workflowContext) { if (workflowContext.getNodeInstanceCount() > 0) { for (KogitoTypesProtobuf.NodeInstance nodeInstanceProtobuf : workflowContext.getNodeInstanceList()) { buildNodeInstance(nodeInstanceProtobuf, container); } } - for (KogitoTypesProtobuf.NodeInstanceGroup group : workflowContext.getExclusiveGroupList()) { - Function finder = nodeInstanceId -> container.getNodeInstance(nodeInstanceId, true); - container.addContextInstance(ExclusiveGroup.EXCLUSIVE_GROUP, buildExclusiveGroupInstance(group, finder)); - } container.addContextInstance(VariableScope.VARIABLE_SCOPE, new VariableScopeInstance()); if (workflowContext.getVariableCount() > 0) { @@ -609,6 +263,10 @@ private void buildWorkflowContext(CompositeContextNodeInstance container, Workfl if (workflowContext.getIterationLevelsCount() > 0) { container.getIterationLevels().putAll(buildIterationLevels(workflowContext.getIterationLevelsList())); } + for (KogitoTypesProtobuf.NodeInstanceGroup group : workflowContext.getExclusiveGroupList()) { + Function finder = nodeInstanceId -> container.getNodeInstance(nodeInstanceId, true); + container.addContextInstance(ExclusiveGroup.EXCLUSIVE_GROUP, buildExclusiveGroupInstance(group, finder)); + } } private ExclusiveGroupInstance buildExclusiveGroupInstance(KogitoTypesProtobuf.NodeInstanceGroup group, Function finder) { @@ -629,39 +287,4 @@ private Map buildIterationLevels(List> buildDeadlines(Map deadlinesProtobuf) { - Map> deadlines = new HashMap<>(); - for (Map.Entry entry : deadlinesProtobuf.entrySet()) { - Map notification = new HashMap<>(); - for (Map.Entry pair : entry.getValue().getContentMap().entrySet()) { - notification.put(pair.getKey(), pair.getValue()); - } - deadlines.put(entry.getKey(), notification); - } - return deadlines; - } - - private Map buildReassignments(Map reassignmentsProtobuf) { - Map reassignments = new HashMap<>(); - for (Map.Entry entry : reassignmentsProtobuf.entrySet()) { - reassignments.put(entry.getKey(), new Reassignment(entry.getValue().getUsersList().stream().collect(Collectors - .toSet()), entry.getValue().getGroupsList().stream().collect(Collectors.toSet()))); - } - return reassignments; - } } diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceWriter.java index 23ffb8becea..b0f67430dbb 100644 --- a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceWriter.java +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceWriter.java @@ -26,72 +26,39 @@ import java.util.Collections; import java.util.Comparator; import java.util.Date; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.stream.Collectors; import org.jbpm.flow.serialization.MarshallerContextName; import org.jbpm.flow.serialization.MarshallerWriterContext; +import org.jbpm.flow.serialization.NodeInstanceWriter; import org.jbpm.flow.serialization.ProcessInstanceMarshallerListener; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.AsyncEventNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.CompositeContextNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.DynamicNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.EventNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.EventSubProcessNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.ForEachNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.JoinNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.JoinNodeInstanceContent.JoinTrigger; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.LambdaSubProcessNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.MilestoneNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.RuleSetNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.StateNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.SubProcessNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.TimerNodeInstanceContent; -import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.WorkItemNodeInstanceContent; import org.jbpm.flow.serialization.protobuf.KogitoProcessInstanceProtobuf; import org.jbpm.flow.serialization.protobuf.KogitoTypesProtobuf; import org.jbpm.flow.serialization.protobuf.KogitoTypesProtobuf.WorkflowContext; -import org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf; -import org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData; import org.jbpm.process.core.context.exclusive.ExclusiveGroup; import org.jbpm.process.core.context.swimlane.SwimlaneContext; import org.jbpm.process.core.context.variable.VariableScope; import org.jbpm.process.instance.ContextInstance; +import org.jbpm.process.instance.ContextInstanceContainer; +import org.jbpm.process.instance.ContextableInstance; import org.jbpm.process.instance.context.exclusive.ExclusiveGroupInstance; import org.jbpm.process.instance.context.swimlane.SwimlaneContextInstance; import org.jbpm.process.instance.context.variable.VariableScopeInstance; -import org.jbpm.process.instance.impl.humantask.Reassignment; -import org.jbpm.workflow.core.node.AsyncEventNodeInstance; +import org.jbpm.ruleflow.instance.RuleFlowProcessInstance; +import org.jbpm.workflow.instance.NodeInstanceContainer; import org.jbpm.workflow.instance.impl.WorkflowProcessInstanceImpl; -import org.jbpm.workflow.instance.node.CompositeContextNodeInstance; -import org.jbpm.workflow.instance.node.DynamicNodeInstance; -import org.jbpm.workflow.instance.node.EventNodeInstance; -import org.jbpm.workflow.instance.node.EventSubProcessNodeInstance; -import org.jbpm.workflow.instance.node.ForEachNodeInstance; -import org.jbpm.workflow.instance.node.HumanTaskNodeInstance; -import org.jbpm.workflow.instance.node.JoinInstance; -import org.jbpm.workflow.instance.node.LambdaSubProcessNodeInstance; -import org.jbpm.workflow.instance.node.MilestoneNodeInstance; -import org.jbpm.workflow.instance.node.RuleSetNodeInstance; -import org.jbpm.workflow.instance.node.StateNodeInstance; -import org.jbpm.workflow.instance.node.SubProcessNodeInstance; -import org.jbpm.workflow.instance.node.TimerNodeInstance; -import org.jbpm.workflow.instance.node.WorkItemNodeInstance; -import org.kie.api.definition.process.WorkflowElementIdentifier; import org.kie.api.runtime.process.NodeInstance; import org.kie.kogito.internal.process.runtime.KogitoNodeInstance; import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime; -import org.kie.kogito.internal.process.runtime.KogitoWorkItem; import org.kie.kogito.process.impl.AbstractProcess; -import org.kie.kogito.process.workitem.Attachment; -import org.kie.kogito.process.workitem.Comment; -import org.kie.kogito.process.workitem.HumanTaskWorkItem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.protobuf.Any; +import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.GeneratedMessageV3; import com.google.protobuf.util.JsonFormat; import static org.jbpm.flow.serialization.MarshallerContextName.MARSHALLER_FORMAT; @@ -108,10 +75,11 @@ public ProtobufProcessInstanceWriter(MarshallerWriterContext context) { this.context = context; this.varWriter = new ProtobufVariableWriter(context); this.listeners = context.get(MarshallerContextName.MARSHALLER_INSTANCE_LISTENER); - this.listeners = this.listeners != null ? this.listeners : new ProcessInstanceMarshallerListener[0]; } public void writeProcessInstance(WorkflowProcessInstanceImpl workFlow, OutputStream os) throws IOException { + context.set(MarshallerContextName.MARSHALLER_PROCESS_INSTANCE, (RuleFlowProcessInstance) workFlow); + LOGGER.debug("writing process instance {}", workFlow.getId()); KogitoProcessRuntime runtime = ((AbstractProcess) context.get(MarshallerContextName.MARSHALLER_PROCESS)).getProcessRuntime(); Arrays.stream(listeners).forEach(e -> e.beforeMarshallProcess(runtime, workFlow)); @@ -166,12 +134,7 @@ public void writeProcessInstance(WorkflowProcessInstanceImpl workFlow, OutputStr instance.addAllSwimlaneContext(buildSwimlaneContexts((SwimlaneContextInstance) workFlow.getContextInstance(SwimlaneContext.SWIMLANE_SCOPE))); - List nodeInstances = new ArrayList<>(workFlow.getNodeInstances()); - List exclusiveGroupInstances = workFlow.getContextInstances(ExclusiveGroup.EXCLUSIVE_GROUP); - VariableScopeInstance variableScopeInstance = (VariableScopeInstance) workFlow.getContextInstance(VariableScope.VARIABLE_SCOPE); - List> variables = new ArrayList<>(variableScopeInstance.getVariables().entrySet()); - List> iterationlevels = new ArrayList<>(workFlow.getIterationLevels().entrySet()); - instance.setContext(buildWorkflowContext(nodeInstances, exclusiveGroupInstances, variables, iterationlevels)); + instance.setContext(buildWorkflowContext(workFlow)); KogitoProcessInstanceProtobuf.ProcessInstance piProtobuf = instance.build(); @@ -251,216 +214,41 @@ private List) context.get(MarshallerContextName.MARSHALLER_PROCESS)).getProcessRuntime(); Arrays.stream(listeners).forEach(e -> e.beforeMarshallNode(runtime, (KogitoNodeInstance) nodeInstance)); - if (nodeInstance instanceof RuleSetNodeInstance) { - return buildRuleSetNodeInstance((RuleSetNodeInstance) nodeInstance); - } else if (nodeInstance instanceof ForEachNodeInstance) { - return buildForEachNodeInstance((ForEachNodeInstance) nodeInstance); - } else if (nodeInstance instanceof LambdaSubProcessNodeInstance) { - return buildLambdaSubProcessNodeInstance((LambdaSubProcessNodeInstance) nodeInstance); - } else if (nodeInstance instanceof SubProcessNodeInstance) { - return buildSubProcessNodeInstance((SubProcessNodeInstance) nodeInstance); - } else if (nodeInstance instanceof StateNodeInstance) { - return buildStateNodeInstance((StateNodeInstance) nodeInstance); - } else if (nodeInstance instanceof JoinInstance) { - return buildJoinInstance((JoinInstance) nodeInstance); - } else if (nodeInstance instanceof TimerNodeInstance) { - return buildTimerNodeInstance((TimerNodeInstance) nodeInstance); - } else if (nodeInstance instanceof AsyncEventNodeInstance) { - return buildAsyncEventNodeInstance((AsyncEventNodeInstance) nodeInstance); - } else if (nodeInstance instanceof EventNodeInstance) { - return buildEventNodeInstance(); - } else if (nodeInstance instanceof MilestoneNodeInstance) { - return buildMilestoneNodeInstance((MilestoneNodeInstance) nodeInstance); - } else if (nodeInstance instanceof DynamicNodeInstance) { - return buildDynamicNodeInstance((DynamicNodeInstance) nodeInstance); - } else if (nodeInstance instanceof EventSubProcessNodeInstance) { - return buildEventSubProcessNodeInstance((EventSubProcessNodeInstance) nodeInstance); - } else if (nodeInstance instanceof CompositeContextNodeInstance) { - return buildCompositeContextNodeInstance((CompositeContextNodeInstance) nodeInstance); - } else if (nodeInstance instanceof HumanTaskNodeInstance) { - return buildHumanTaskNodeInstance((HumanTaskNodeInstance) nodeInstance); - } else if (nodeInstance instanceof WorkItemNodeInstance) { - return buildWorkItemNodeInstance((WorkItemNodeInstance) nodeInstance); - } else { + NodeInstanceWriter writer = context.findNodeInstanceWriter(nodeInstance); + if (writer == null) { throw new IllegalArgumentException("Unknown node instance type: " + nodeInstance); } - } - - private Any buildAsyncEventNodeInstance(AsyncEventNodeInstance nodeInstance) { - AsyncEventNodeInstanceContent.Builder builder = AsyncEventNodeInstanceContent.newBuilder(); - if (nodeInstance.getJobId() != null) { - builder.setJobId(nodeInstance.getJobId()); - } - return Any.pack(builder.build()); - } - - private Any buildRuleSetNodeInstance(RuleSetNodeInstance nodeInstance) { - RuleSetNodeInstanceContent.Builder ruleSet = RuleSetNodeInstanceContent.newBuilder(); - ruleSet.setRuleFlowGroup(nodeInstance.getRuleFlowGroup()); - ruleSet.addAllTimerInstanceId(nodeInstance.getTimerInstances()); - if (nodeInstance.getTimerInstancesReference() != null) { - ruleSet.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); - } - return Any.pack(ruleSet.build()); - } - - private Any buildForEachNodeInstance(ForEachNodeInstance nodeInstance) { - ForEachNodeInstanceContent.Builder foreachBuilder = ForEachNodeInstanceContent.newBuilder(); - - List timerInstances = nodeInstance.getTimerInstances(); - if (timerInstances != null) { - foreachBuilder.addAllTimerInstanceId(timerInstances); - } - if (nodeInstance.getTimerInstancesReference() != null) { - foreachBuilder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); - } - List nodeInstances = nodeInstance.getNodeInstances().stream().filter(CompositeContextNodeInstance.class::isInstance).collect(Collectors.toList()); - - List exclusiveGroupInstances = nodeInstance.getContextInstances(ExclusiveGroup.EXCLUSIVE_GROUP); - VariableScopeInstance variableScopeInstance = (VariableScopeInstance) nodeInstance.getContextInstance(VariableScope.VARIABLE_SCOPE); - List> variables = (variableScopeInstance != null) ? new ArrayList<>(variableScopeInstance.getVariables().entrySet()) : Collections.emptyList(); - List> iterationlevels = new ArrayList<>(nodeInstance.getIterationLevels().entrySet()); - foreachBuilder.setContext(buildWorkflowContext(nodeInstances, exclusiveGroupInstances, variables, iterationlevels)); - - foreachBuilder - .setTotalInstances(nodeInstance.getTotalInstances()) - .setExecutedInstances(nodeInstance.getExecutedInstances()) - .setHasAsyncInstances(nodeInstance.getHasAsyncInstances()); - return Any.pack(foreachBuilder.build()); - } - - private Any buildLambdaSubProcessNodeInstance(LambdaSubProcessNodeInstance nodeInstance) { - LambdaSubProcessNodeInstanceContent.Builder builder = LambdaSubProcessNodeInstanceContent.newBuilder(); - builder.setProcessInstanceId(nodeInstance.getProcessInstanceId()); - List timerInstances = nodeInstance.getTimerInstances(); - if (timerInstances != null) { - builder.addAllTimerInstanceId(timerInstances); - } - if (nodeInstance.getTimerInstancesReference() != null) { - builder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); - } - return Any.pack(builder.build()); - } + LOGGER.debug("Node writer {}", writer); + GeneratedMessageV3.Builder builder = writer.write(context, nodeInstance); - private Any buildSubProcessNodeInstance(SubProcessNodeInstance nodeInstance) { - SubProcessNodeInstanceContent.Builder builder = SubProcessNodeInstanceContent.newBuilder(); - builder.setProcessInstanceId(nodeInstance.getProcessInstanceId()); - List timerInstances = nodeInstance.getTimerInstances(); - if (timerInstances != null) { - builder.addAllTimerInstanceId(timerInstances); + LOGGER.debug("Node instance being writing {}", nodeInstance); + FieldDescriptor fieldContext = getContextField(builder); + if (fieldContext != null) { + LOGGER.debug("Node instance context being writing {}", nodeInstance); + builder.setField(fieldContext, buildWorkflowContext((NodeInstanceContainer & ContextInstanceContainer & ContextableInstance) nodeInstance)); } - if (nodeInstance.getTimerInstancesReference() != null) { - builder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); - } - return Any.pack(builder.build()); - } - private Any buildStateNodeInstance(StateNodeInstance nodeInstance) { - StateNodeInstanceContent.Builder builder = StateNodeInstanceContent.newBuilder(); - List timerInstances = nodeInstance.getTimerInstances(); - if (timerInstances != null) { - builder.addAllTimerInstanceId(timerInstances); - } - if (nodeInstance.getTimerInstancesReference() != null) { - builder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); - } return Any.pack(builder.build()); } - private Any buildJoinInstance(JoinInstance nodeInstance) { - JoinNodeInstanceContent.Builder joinBuilder = JoinNodeInstanceContent.newBuilder(); - Map triggers = nodeInstance.getTriggers(); - List keys = new ArrayList<>(triggers.keySet()); - Collections.sort(keys); - - for (WorkflowElementIdentifier key : keys) { - LOGGER.info("marshalling join {}", key.toExternalFormat()); - joinBuilder.addTrigger(JoinTrigger.newBuilder() - .setNodeId(key.toExternalFormat()) - .setCounter(triggers.get(key)) - .build()); - } - - return Any.pack(joinBuilder.build()); - } - - private Any buildTimerNodeInstance(TimerNodeInstance nodeInstance) { - return Any.pack(TimerNodeInstanceContent.newBuilder().setTimerId(nodeInstance.getTimerId()).build()); - } - - private Any buildEventNodeInstance() { - return Any.pack(EventNodeInstanceContent.newBuilder().build()); - } - - private Any buildMilestoneNodeInstance(MilestoneNodeInstance nodeInstance) { - MilestoneNodeInstanceContent.Builder builder = MilestoneNodeInstanceContent.newBuilder(); - - List timerInstances = nodeInstance.getTimerInstances(); - if (timerInstances != null) { - builder.addAllTimerInstanceId(timerInstances); - } - if (nodeInstance.getTimerInstancesReference() != null) { - builder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); - } - return Any.pack(builder.build()); - } - - private Any buildDynamicNodeInstance(DynamicNodeInstance nodeInstance) { - - DynamicNodeInstanceContent.Builder builder = DynamicNodeInstanceContent.newBuilder(); - List timerInstances = nodeInstance.getTimerInstances(); - if (timerInstances != null) { - builder.addAllTimerInstanceId(timerInstances); - } - if (nodeInstance.getTimerInstancesReference() != null) { - builder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); - } - - builder.setContext(buildWorkflowContext(nodeInstance)); - - return Any.pack(builder.build()); - } - - private Any buildEventSubProcessNodeInstance(EventSubProcessNodeInstance nodeInstance) { - - EventSubProcessNodeInstanceContent.Builder builder = EventSubProcessNodeInstanceContent.newBuilder(); - List timerInstances = nodeInstance.getTimerInstances(); - if (timerInstances != null) { - builder.addAllTimerInstanceId(timerInstances); - } - if (nodeInstance.getTimerInstancesReference() != null) { - builder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); - } - - builder.setContext(buildWorkflowContext(nodeInstance)); - - return Any.pack(builder.build()); - } - - private Any buildCompositeContextNodeInstance(CompositeContextNodeInstance nodeInstance) { - - CompositeContextNodeInstanceContent.Builder builder = CompositeContextNodeInstanceContent.newBuilder(); - List timerInstances = nodeInstance.getTimerInstances(); - if (timerInstances != null) { - builder.addAllTimerInstanceId(timerInstances); - } - if (nodeInstance.getTimerInstancesReference() != null) { - builder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); + public FieldDescriptor getContextField(GeneratedMessageV3.Builder builder) { + for (FieldDescriptor field : builder.getDescriptorForType().getFields()) { + if ("context".equals(field.getName())) { + return field; + } } - - builder.setContext(buildWorkflowContext(nodeInstance)); - - return Any.pack(builder.build()); + return null; } - private WorkflowContext buildWorkflowContext(CompositeContextNodeInstance nodeInstance) { + private WorkflowContext buildWorkflowContext(T nodeInstance) { List nodeInstances = new ArrayList<>(nodeInstance.getNodeInstances()); List exclusiveGroupInstances = nodeInstance.getContextInstances(ExclusiveGroup.EXCLUSIVE_GROUP); VariableScopeInstance variableScopeInstance = (VariableScopeInstance) nodeInstance.getContextInstance(VariableScope.VARIABLE_SCOPE); @@ -469,46 +257,6 @@ private WorkflowContext buildWorkflowContext(CompositeContextNodeInstance nodeIn return buildWorkflowContext(nodeInstances, exclusiveGroupInstances, variables, iterationlevels); } - private Any buildWorkItemNodeInstance(WorkItemNodeInstance nodeInstance) { - return Any.pack(buildWorkItemNodeInstanceBuilder(nodeInstance).build()); - } - - private WorkItemNodeInstanceContent.Builder buildWorkItemNodeInstanceBuilder(WorkItemNodeInstance nodeInstance) { - WorkItemNodeInstanceContent.Builder builder = WorkItemNodeInstanceContent.newBuilder(); - - List timerInstances = nodeInstance.getTimerInstances(); - if (timerInstances != null) { - builder.addAllTimerInstanceId(timerInstances); - } - if (nodeInstance.getTimerInstancesReference() != null) { - builder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); - } - if (nodeInstance.getExceptionHandlingProcessInstanceId() != null) { - builder.setErrorHandlingProcessInstanceId(nodeInstance.getExceptionHandlingProcessInstanceId()); - } - KogitoWorkItem workItem = nodeInstance.getWorkItem(); - - builder.setWorkItemId(nodeInstance.getWorkItemId()) - .setName(workItem.getName()) - .setState(workItem.getState()) - .setPhaseId(workItem.getPhaseId()) - .setPhaseStatus(workItem.getPhaseStatus()) - .setStartDate(workItem.getStartDate().getTime()) - .addAllVariable(varWriter.buildVariables(new ArrayList<>(workItem.getParameters().entrySet()))) - .addAllResult(varWriter.buildVariables(new ArrayList<>(workItem.getResults().entrySet()))); - - if (workItem.getCompleteDate() != null) { - builder.setCompleteDate(workItem.getCompleteDate().getTime()); - } - return builder; - } - - private Any buildHumanTaskNodeInstance(HumanTaskNodeInstance nodeInstance) { - WorkItemNodeInstanceContent.Builder builder = buildWorkItemNodeInstanceBuilder(nodeInstance); - builder.setWorkItemData(Any.pack(buildHumanTaskWorkItemData(nodeInstance, (HumanTaskWorkItem) nodeInstance.getWorkItem()))); - return Any.pack(builder.build()); - } - private List buildGroups(List exclusiveGroupInstances) { if (exclusiveGroupInstances == null) { return Collections.emptyList(); @@ -545,121 +293,4 @@ private List buildIterationLevels(List buildComments(Iterable comments) { - List commentsProtobuf = new ArrayList<>(); - for (Comment comment : comments) { - KogitoWorkItemsProtobuf.Comment workItemComment = KogitoWorkItemsProtobuf.Comment.newBuilder() - .setId(comment.getId().toString()) - .setContent(comment.getContent()) - .setUpdatedBy(comment.getUpdatedBy()) - .setUpdatedAt(comment.getUpdatedAt().getTime()) - .build(); - commentsProtobuf.add(workItemComment); - } - return commentsProtobuf; - } - - private List buildAttachments(Iterable attachments) { - List attachmentProtobuf = new ArrayList<>(); - for (Attachment attachment : attachments) { - KogitoWorkItemsProtobuf.Attachment workItemAttachment = KogitoWorkItemsProtobuf.Attachment.newBuilder() - .setId(attachment.getId().toString()).setContent(attachment.getContent().toString()) - .setUpdatedBy(attachment.getUpdatedBy()).setUpdatedAt(attachment.getUpdatedAt().getTime()) - .setName(attachment.getName()) - .build(); - attachmentProtobuf.add(workItemAttachment); - } - return attachmentProtobuf; - } - - private Map buildDeadlines(Map> deadlines) { - Map deadlinesProtobuf = new HashMap<>(); - for (Map.Entry> entry : deadlines.entrySet()) { - KogitoWorkItemsProtobuf.Deadline.Builder builder = KogitoWorkItemsProtobuf.Deadline.newBuilder(); - entry.getValue().forEach((k, v) -> builder.putContent(k, v.toString())); - deadlinesProtobuf.put(entry.getKey(), builder.build()); - } - return deadlinesProtobuf; - } - - private Map buildReassignments(Map reassignments) { - Map reassignmentsProtobuf = new HashMap<>(); - for (Map.Entry entry : reassignments.entrySet()) { - KogitoWorkItemsProtobuf.Reassignment.Builder builder = KogitoWorkItemsProtobuf.Reassignment.newBuilder(); - builder.addAllGroups(entry.getValue().getPotentialGroups()); - builder.addAllUsers(entry.getValue().getPotentialUsers()); - reassignmentsProtobuf.put(entry.getKey(), builder.build()); - } - return reassignmentsProtobuf; - } - } diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessMarshallerWriteContext.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessMarshallerWriteContext.java index 906bd9da1ae..74fb7a559d8 100755 --- a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessMarshallerWriteContext.java +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessMarshallerWriteContext.java @@ -20,14 +20,16 @@ import java.io.OutputStream; +import org.jbpm.flow.serialization.MarshallerContextName; import org.jbpm.flow.serialization.MarshallerWriterContext; +import org.jbpm.flow.serialization.NodeInstanceWriter; +import org.kie.api.runtime.process.NodeInstance; /** * Extension to default MarshallerWriteContext */ public class ProtobufProcessMarshallerWriteContext extends ProtobufAbstractMarshallerContext implements MarshallerWriterContext { - private OutputStream os; public ProtobufProcessMarshallerWriteContext(OutputStream os) { @@ -39,4 +41,15 @@ public OutputStream output() { return os; } + @Override + public NodeInstanceWriter findNodeInstanceWriter(NodeInstance nodeInstance) { + NodeInstanceWriter[] writers = this.get(MarshallerContextName.MARSHALLER_NODE_INSTANCE_WRITER); + for (NodeInstanceWriter writer : writers) { + if (writer.accept(nodeInstance)) { + return writer; + } + } + return null; + } + } diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/AsyncEventNodeInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/AsyncEventNodeInstanceReader.java new file mode 100644 index 00000000000..285165186c0 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/AsyncEventNodeInstanceReader.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import org.jbpm.flow.serialization.MarshallerReaderContext; +import org.jbpm.flow.serialization.NodeInstanceReader; +import org.jbpm.flow.serialization.ProcessInstanceMarshallerException; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.AsyncEventNodeInstanceContent; +import org.jbpm.workflow.core.node.AsyncEventNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.Any; +import com.google.protobuf.GeneratedMessageV3; + +public class AsyncEventNodeInstanceReader implements NodeInstanceReader { + + @Override + public boolean accept(Any value) { + return value.is(AsyncEventNodeInstanceContent.class); + } + + @Override + public NodeInstance read(MarshallerReaderContext context, Any marshalled) { + try { + AsyncEventNodeInstanceContent content = marshalled.unpack(AsyncEventNodeInstanceContent.class); + AsyncEventNodeInstance nodeInstance = new AsyncEventNodeInstance(); + nodeInstance.setJobId(content.getJobId()); + return nodeInstance; + } catch (Exception e) { + throw new ProcessInstanceMarshallerException(e); + } + } + + @Override + public Class type() { + return AsyncEventNodeInstanceContent.class; + } + +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/AsyncEventNodeInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/AsyncEventNodeInstanceWriter.java new file mode 100644 index 00000000000..69445449f61 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/AsyncEventNodeInstanceWriter.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import org.jbpm.flow.serialization.MarshallerWriterContext; +import org.jbpm.flow.serialization.NodeInstanceWriter; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.AsyncEventNodeInstanceContent; +import org.jbpm.workflow.core.node.AsyncEventNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.GeneratedMessageV3.Builder; + +public class AsyncEventNodeInstanceWriter implements NodeInstanceWriter { + + @Override + public boolean accept(NodeInstance value) { + return value instanceof AsyncEventNodeInstance; + } + + @Override + public Builder write(MarshallerWriterContext context, NodeInstance value) { + AsyncEventNodeInstance nodeInstance = (AsyncEventNodeInstance) value; + AsyncEventNodeInstanceContent.Builder builder = AsyncEventNodeInstanceContent.newBuilder(); + if (nodeInstance.getJobId() != null) { + builder.setJobId(nodeInstance.getJobId()); + } + return builder; + } + +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/CompositeContextNodeInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/CompositeContextNodeInstanceReader.java new file mode 100644 index 00000000000..6f1bdbf3c94 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/CompositeContextNodeInstanceReader.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.jbpm.flow.serialization.MarshallerReaderContext; +import org.jbpm.flow.serialization.NodeInstanceReader; +import org.jbpm.flow.serialization.ProcessInstanceMarshallerException; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.CompositeContextNodeInstanceContent; +import org.jbpm.workflow.instance.node.CompositeContextNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.Any; +import com.google.protobuf.GeneratedMessageV3; + +public class CompositeContextNodeInstanceReader implements NodeInstanceReader { + + @Override + public Integer order() { + return NodeInstanceReader.super.order() + 1; + } + + @Override + public boolean accept(Any value) { + return value.is(CompositeContextNodeInstanceContent.class); + } + + @Override + public NodeInstance read(MarshallerReaderContext context, Any marshalled) { + try { + CompositeContextNodeInstanceContent content = marshalled.unpack(CompositeContextNodeInstanceContent.class); + CompositeContextNodeInstance nodeInstance = new CompositeContextNodeInstance(); + + if (content.getTimerInstanceIdCount() > 0) { + List timerInstances = new ArrayList<>(); + for (String _timerId : content.getTimerInstanceIdList()) { + timerInstances.add(_timerId); + } + nodeInstance.internalSetTimerInstances(timerInstances); + } + if (!content.getTimerInstanceReferenceMap().isEmpty()) { + nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); + } + return nodeInstance; + } catch (Exception e) { + throw new ProcessInstanceMarshallerException(e); + } + } + + @Override + public Class type() { + return CompositeContextNodeInstanceContent.class; + } +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/CompositeContextNodeInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/CompositeContextNodeInstanceWriter.java new file mode 100644 index 00000000000..e80f7179ce6 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/CompositeContextNodeInstanceWriter.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.List; + +import org.jbpm.flow.serialization.MarshallerWriterContext; +import org.jbpm.flow.serialization.NodeInstanceWriter; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.CompositeContextNodeInstanceContent; +import org.jbpm.workflow.instance.node.CompositeContextNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.GeneratedMessageV3.Builder; + +public class CompositeContextNodeInstanceWriter implements NodeInstanceWriter { + + @Override + public Integer order() { + return NodeInstanceWriter.super.order() + 1; + } + + @Override + public boolean accept(NodeInstance value) { + return value instanceof CompositeContextNodeInstance; + } + + @Override + public Builder write(MarshallerWriterContext context, NodeInstance value) { + CompositeContextNodeInstance nodeInstance = (CompositeContextNodeInstance) value; + CompositeContextNodeInstanceContent.Builder builder = CompositeContextNodeInstanceContent.newBuilder(); + List timerInstances = nodeInstance.getTimerInstances(); + if (timerInstances != null) { + builder.addAllTimerInstanceId(timerInstances); + } + if (nodeInstance.getTimerInstancesReference() != null) { + builder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); + } + + return builder; + } + +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/DynamicNodeInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/DynamicNodeInstanceReader.java new file mode 100644 index 00000000000..c59009fe67e --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/DynamicNodeInstanceReader.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.jbpm.flow.serialization.MarshallerReaderContext; +import org.jbpm.flow.serialization.NodeInstanceReader; +import org.jbpm.flow.serialization.ProcessInstanceMarshallerException; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.DynamicNodeInstanceContent; +import org.jbpm.workflow.instance.node.DynamicNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.Any; +import com.google.protobuf.GeneratedMessageV3; + +public class DynamicNodeInstanceReader implements NodeInstanceReader { + + @Override + public boolean accept(Any value) { + return value.is(DynamicNodeInstanceContent.class); + } + + @Override + public NodeInstance read(MarshallerReaderContext context, Any value) { + try { + DynamicNodeInstanceContent content = value.unpack(DynamicNodeInstanceContent.class); + DynamicNodeInstance nodeInstance = new DynamicNodeInstance(); + if (content.getTimerInstanceIdCount() > 0) { + List timerInstances = new ArrayList<>(); + for (String _timerId : content.getTimerInstanceIdList()) { + timerInstances.add(_timerId); + } + nodeInstance.internalSetTimerInstances(timerInstances); + } + if (!content.getTimerInstanceReferenceMap().isEmpty()) { + nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); + } + + return nodeInstance; + } catch (Exception e) { + throw new ProcessInstanceMarshallerException(e); + } + } + + @Override + public Class type() { + return DynamicNodeInstanceContent.class; + } +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/DynamicNodeInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/DynamicNodeInstanceWriter.java new file mode 100644 index 00000000000..325268fbd80 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/DynamicNodeInstanceWriter.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.List; + +import org.jbpm.flow.serialization.MarshallerWriterContext; +import org.jbpm.flow.serialization.NodeInstanceWriter; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.DynamicNodeInstanceContent; +import org.jbpm.workflow.instance.node.DynamicNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.GeneratedMessageV3.Builder; + +public class DynamicNodeInstanceWriter implements NodeInstanceWriter { + + @Override + public boolean accept(NodeInstance value) { + return value instanceof DynamicNodeInstance; + } + + @Override + public Builder write(MarshallerWriterContext context, NodeInstance value) { + DynamicNodeInstance nodeInstance = (DynamicNodeInstance) value; + DynamicNodeInstanceContent.Builder builder = DynamicNodeInstanceContent.newBuilder(); + List timerInstances = nodeInstance.getTimerInstances(); + if (timerInstances != null) { + builder.addAllTimerInstanceId(timerInstances); + } + if (nodeInstance.getTimerInstancesReference() != null) { + builder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); + } + + return builder; + } + +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/EventNodeInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/EventNodeInstanceReader.java new file mode 100644 index 00000000000..165c8448f43 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/EventNodeInstanceReader.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import org.jbpm.flow.serialization.MarshallerReaderContext; +import org.jbpm.flow.serialization.NodeInstanceReader; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.EventNodeInstanceContent; +import org.jbpm.workflow.instance.node.EventNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.Any; +import com.google.protobuf.GeneratedMessageV3; + +public class EventNodeInstanceReader implements NodeInstanceReader { + + @Override + public boolean accept(Any value) { + return value.is(EventNodeInstanceContent.class); + } + + @Override + public NodeInstance read(MarshallerReaderContext context, Any value) { + return new EventNodeInstance(); + } + + @Override + public Class type() { + return EventNodeInstanceContent.class; + } +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/EventNodeInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/EventNodeInstanceWriter.java new file mode 100644 index 00000000000..6d4cd4216f1 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/EventNodeInstanceWriter.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import org.jbpm.flow.serialization.MarshallerWriterContext; +import org.jbpm.flow.serialization.NodeInstanceWriter; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.EventNodeInstanceContent; +import org.jbpm.workflow.instance.node.EventNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.GeneratedMessageV3.Builder; + +public class EventNodeInstanceWriter implements NodeInstanceWriter { + + @Override + public boolean accept(NodeInstance value) { + return value instanceof EventNodeInstance; + } + + @Override + public Builder write(MarshallerWriterContext context, NodeInstance value) { + return EventNodeInstanceContent.newBuilder(); + } + +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/EventSubProcessNodeInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/EventSubProcessNodeInstanceReader.java new file mode 100644 index 00000000000..150fa8c012e --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/EventSubProcessNodeInstanceReader.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.jbpm.flow.serialization.MarshallerReaderContext; +import org.jbpm.flow.serialization.NodeInstanceReader; +import org.jbpm.flow.serialization.ProcessInstanceMarshallerException; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.EventSubProcessNodeInstanceContent; +import org.jbpm.workflow.instance.node.EventSubProcessNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.Any; +import com.google.protobuf.GeneratedMessageV3; + +public class EventSubProcessNodeInstanceReader implements NodeInstanceReader { + + @Override + public boolean accept(Any value) { + return value.is(EventSubProcessNodeInstanceContent.class); + } + + @Override + public NodeInstance read(MarshallerReaderContext context, Any marshalled) { + try { + EventSubProcessNodeInstanceContent content = marshalled.unpack(EventSubProcessNodeInstanceContent.class); + EventSubProcessNodeInstance nodeInstance = new EventSubProcessNodeInstance(); + + if (content.getTimerInstanceIdCount() > 0) { + List timerInstances = new ArrayList<>(); + for (String _timerId : content.getTimerInstanceIdList()) { + timerInstances.add(_timerId); + } + nodeInstance.internalSetTimerInstances(timerInstances); + } + if (!content.getTimerInstanceReferenceMap().isEmpty()) { + nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); + } + return nodeInstance; + } catch (Exception e) { + throw new ProcessInstanceMarshallerException(e); + } + } + + @Override + public Class type() { + return EventSubProcessNodeInstanceContent.class; + } +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/EventSubProcessNodeInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/EventSubProcessNodeInstanceWriter.java new file mode 100644 index 00000000000..10cc62573ab --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/EventSubProcessNodeInstanceWriter.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.List; + +import org.jbpm.flow.serialization.MarshallerWriterContext; +import org.jbpm.flow.serialization.NodeInstanceWriter; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.EventSubProcessNodeInstanceContent; +import org.jbpm.workflow.instance.node.EventSubProcessNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.GeneratedMessageV3.Builder; + +public class EventSubProcessNodeInstanceWriter implements NodeInstanceWriter { + + @Override + public boolean accept(NodeInstance value) { + return value instanceof EventSubProcessNodeInstance; + } + + @Override + public Builder write(MarshallerWriterContext context, NodeInstance value) { + EventSubProcessNodeInstance nodeInstance = (EventSubProcessNodeInstance) value; + EventSubProcessNodeInstanceContent.Builder builder = EventSubProcessNodeInstanceContent.newBuilder(); + List timerInstances = nodeInstance.getTimerInstances(); + if (timerInstances != null) { + builder.addAllTimerInstanceId(timerInstances); + } + if (nodeInstance.getTimerInstancesReference() != null) { + builder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); + } + + return builder; + } + +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/ForEachNodeInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/ForEachNodeInstanceReader.java new file mode 100644 index 00000000000..06899ece2a4 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/ForEachNodeInstanceReader.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import org.jbpm.flow.serialization.MarshallerReaderContext; +import org.jbpm.flow.serialization.NodeInstanceReader; +import org.jbpm.flow.serialization.ProcessInstanceMarshallerException; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.ForEachNodeInstanceContent; +import org.jbpm.workflow.instance.node.ForEachNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.Any; +import com.google.protobuf.GeneratedMessageV3; + +public class ForEachNodeInstanceReader implements NodeInstanceReader { + + @Override + public boolean accept(Any value) { + return value.is(ForEachNodeInstanceContent.class); + } + + @Override + public NodeInstance read(MarshallerReaderContext context, Any value) { + try { + ForEachNodeInstanceContent content = value.unpack(ForEachNodeInstanceContent.class); + ForEachNodeInstance nodeInstance = new ForEachNodeInstance(); + if (content.getTimerInstanceIdCount() > 0) { + nodeInstance.internalSetTimerInstances(content.getTimerInstanceIdList().stream().toList()); + } + if (content.getTimerInstanceReferenceCount() > 0) { + nodeInstance.internalSetTimerInstancesReference(content.getTimerInstanceReferenceMap()); + } + nodeInstance.setExecutedInstances(content.getExecutedInstances()); + nodeInstance.setTotalInstances(content.getTotalInstances()); + nodeInstance.setHasAsyncInstances(content.getHasAsyncInstances()); + return nodeInstance; + } catch (Exception e) { + throw new ProcessInstanceMarshallerException(e); + } + } + + @Override + public Class type() { + return ForEachNodeInstanceContent.class; + } +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/ForEachNodeInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/ForEachNodeInstanceWriter.java new file mode 100644 index 00000000000..4051e5534e1 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/ForEachNodeInstanceWriter.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.List; + +import org.jbpm.flow.serialization.MarshallerWriterContext; +import org.jbpm.flow.serialization.NodeInstanceWriter; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.ForEachNodeInstanceContent; +import org.jbpm.workflow.instance.node.ForEachNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.GeneratedMessageV3.Builder; + +public class ForEachNodeInstanceWriter implements NodeInstanceWriter { + + @Override + public boolean accept(NodeInstance value) { + return value instanceof ForEachNodeInstance; + } + + @Override + public Builder write(MarshallerWriterContext context, NodeInstance value) { + ForEachNodeInstance nodeInstance = (ForEachNodeInstance) value; + ForEachNodeInstanceContent.Builder foreachBuilder = ForEachNodeInstanceContent.newBuilder(); + + List timerInstances = nodeInstance.getTimerInstances(); + if (timerInstances != null) { + foreachBuilder.addAllTimerInstanceId(timerInstances); + } + if (nodeInstance.getTimerInstancesReference() != null) { + foreachBuilder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); + } + + foreachBuilder + .setTotalInstances(nodeInstance.getTotalInstances()) + .setExecutedInstances(nodeInstance.getExecutedInstances()) + .setHasAsyncInstances(nodeInstance.getHasAsyncInstances()); + + return foreachBuilder; + } + +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/JoinNodeInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/JoinNodeInstanceReader.java new file mode 100644 index 00000000000..9ed9866936e --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/JoinNodeInstanceReader.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.HashMap; +import java.util.Map; + +import org.jbpm.flow.serialization.MarshallerReaderContext; +import org.jbpm.flow.serialization.NodeInstanceReader; +import org.jbpm.flow.serialization.ProcessInstanceMarshallerException; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.JoinNodeInstanceContent; +import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory; +import org.jbpm.workflow.instance.node.JoinInstance; +import org.kie.api.definition.process.WorkflowElementIdentifier; +import org.kie.api.runtime.process.NodeInstance; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.protobuf.Any; +import com.google.protobuf.GeneratedMessageV3; + +public class JoinNodeInstanceReader implements NodeInstanceReader { + + private static Logger LOGGER = LoggerFactory.getLogger(JoinNodeInstanceReader.class); + + @Override + public boolean accept(Any value) { + return value.is(JoinNodeInstanceContent.class); + } + + @Override + public NodeInstance read(MarshallerReaderContext context, Any value) { + try { + JoinNodeInstanceContent content = value.unpack(JoinNodeInstanceContent.class); + JoinInstance nodeInstance = new JoinInstance(); + if (content.getTriggerCount() > 0) { + Map triggers = new HashMap<>(); + for (JoinNodeInstanceContent.JoinTrigger _join : content.getTriggerList()) { + LOGGER.debug("unmarshalling join {}", _join.getNodeId()); + triggers.put(WorkflowElementIdentifierFactory.fromExternalFormat(_join.getNodeId()), _join.getCounter()); + } + nodeInstance.internalSetTriggers(triggers); + } + return nodeInstance; + } catch (Exception e) { + throw new ProcessInstanceMarshallerException(e); + } + } + + @Override + public Class type() { + return JoinNodeInstanceContent.class; + } +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/JoinNodeInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/JoinNodeInstanceWriter.java new file mode 100644 index 00000000000..041150d1d06 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/JoinNodeInstanceWriter.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.jbpm.flow.serialization.MarshallerWriterContext; +import org.jbpm.flow.serialization.NodeInstanceWriter; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.JoinNodeInstanceContent; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.JoinNodeInstanceContent.JoinTrigger; +import org.jbpm.workflow.instance.node.JoinInstance; +import org.kie.api.definition.process.WorkflowElementIdentifier; +import org.kie.api.runtime.process.NodeInstance; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.protobuf.GeneratedMessageV3.Builder; + +public class JoinNodeInstanceWriter implements NodeInstanceWriter { + + private static final Logger LOGGER = LoggerFactory.getLogger(JoinNodeInstanceWriter.class); + + @Override + public boolean accept(NodeInstance value) { + return value instanceof JoinInstance; + } + + @Override + public Builder write(MarshallerWriterContext context, NodeInstance value) { + JoinInstance nodeInstance = (JoinInstance) value; + JoinNodeInstanceContent.Builder joinBuilder = JoinNodeInstanceContent.newBuilder(); + Map triggers = nodeInstance.getTriggers(); + List keys = new ArrayList<>(triggers.keySet()); + Collections.sort(keys); + + for (WorkflowElementIdentifier key : keys) { + LOGGER.info("marshalling join {}", key.toExternalFormat()); + joinBuilder.addTrigger(JoinTrigger.newBuilder() + .setNodeId(key.toExternalFormat()) + .setCounter(triggers.get(key)) + .build()); + } + + return joinBuilder; + } + +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/LambdaSubProcessNodeInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/LambdaSubProcessNodeInstanceReader.java new file mode 100644 index 00000000000..2c9ee577d97 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/LambdaSubProcessNodeInstanceReader.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.jbpm.flow.serialization.MarshallerReaderContext; +import org.jbpm.flow.serialization.NodeInstanceReader; +import org.jbpm.flow.serialization.ProcessInstanceMarshallerException; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.LambdaSubProcessNodeInstanceContent; +import org.jbpm.workflow.instance.node.LambdaSubProcessNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.Any; +import com.google.protobuf.GeneratedMessageV3; + +public class LambdaSubProcessNodeInstanceReader implements NodeInstanceReader { + + @Override + public boolean accept(Any value) { + return value.is(LambdaSubProcessNodeInstanceContent.class); + } + + @Override + public NodeInstance read(MarshallerReaderContext context, Any value) { + try { + LambdaSubProcessNodeInstanceContent content = value.unpack(LambdaSubProcessNodeInstanceContent.class); + LambdaSubProcessNodeInstance nodeInstance = new LambdaSubProcessNodeInstance(); + nodeInstance.internalSetProcessInstanceId(content.getProcessInstanceId()); + if (content.getTimerInstanceIdCount() > 0) { + nodeInstance.internalSetTimerInstances(new ArrayList<>(content.getTimerInstanceIdList())); + } + if (!content.getTimerInstanceReferenceMap().isEmpty()) { + nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); + } + return nodeInstance; + } catch (Exception e) { + throw new ProcessInstanceMarshallerException(e); + } + } + + @Override + public Class type() { + return LambdaSubProcessNodeInstanceContent.class; + } +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/LambdaSubProcessNodeInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/LambdaSubProcessNodeInstanceWriter.java new file mode 100644 index 00000000000..31178c2f6c2 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/LambdaSubProcessNodeInstanceWriter.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.List; + +import org.jbpm.flow.serialization.MarshallerWriterContext; +import org.jbpm.flow.serialization.NodeInstanceWriter; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.LambdaSubProcessNodeInstanceContent; +import org.jbpm.workflow.instance.node.LambdaSubProcessNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.GeneratedMessageV3.Builder; + +public class LambdaSubProcessNodeInstanceWriter implements NodeInstanceWriter { + + @Override + public boolean accept(NodeInstance value) { + return value instanceof LambdaSubProcessNodeInstance; + } + + @Override + public Builder write(MarshallerWriterContext context, NodeInstance value) { + LambdaSubProcessNodeInstance nodeInstance = (LambdaSubProcessNodeInstance) value; + LambdaSubProcessNodeInstanceContent.Builder builder = LambdaSubProcessNodeInstanceContent.newBuilder(); + builder.setProcessInstanceId(nodeInstance.getProcessInstanceId()); + List timerInstances = nodeInstance.getTimerInstances(); + if (timerInstances != null) { + builder.addAllTimerInstanceId(timerInstances); + } + if (nodeInstance.getTimerInstancesReference() != null) { + builder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); + } + + return builder; + } + +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/MilestoneNodeInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/MilestoneNodeInstanceReader.java new file mode 100644 index 00000000000..59398746c26 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/MilestoneNodeInstanceReader.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.jbpm.flow.serialization.MarshallerReaderContext; +import org.jbpm.flow.serialization.NodeInstanceReader; +import org.jbpm.flow.serialization.ProcessInstanceMarshallerException; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.MilestoneNodeInstanceContent; +import org.jbpm.workflow.instance.node.MilestoneNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.Any; +import com.google.protobuf.GeneratedMessageV3; + +public class MilestoneNodeInstanceReader implements NodeInstanceReader { + + @Override + public boolean accept(Any value) { + return value.is(MilestoneNodeInstanceContent.class); + } + + @Override + public NodeInstance read(MarshallerReaderContext context, Any value) { + try { + MilestoneNodeInstanceContent content = value.unpack(MilestoneNodeInstanceContent.class); + MilestoneNodeInstance nodeInstance = new MilestoneNodeInstance(); + if (content.getTimerInstanceIdCount() > 0) { + List timerInstances = new ArrayList<>(); + for (String _timerId : content.getTimerInstanceIdList()) { + timerInstances.add(_timerId); + } + nodeInstance.internalSetTimerInstances(timerInstances); + } + if (!content.getTimerInstanceReferenceMap().isEmpty()) { + nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); + } + return nodeInstance; + } catch (Exception e) { + throw new ProcessInstanceMarshallerException(e); + } + } + + @Override + public Class type() { + return MilestoneNodeInstanceContent.class; + } +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/MilestoneNodeInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/MilestoneNodeInstanceWriter.java new file mode 100644 index 00000000000..3a6bfc694dc --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/MilestoneNodeInstanceWriter.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.List; + +import org.jbpm.flow.serialization.MarshallerWriterContext; +import org.jbpm.flow.serialization.NodeInstanceWriter; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.MilestoneNodeInstanceContent; +import org.jbpm.workflow.instance.node.MilestoneNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.GeneratedMessageV3.Builder; + +public class MilestoneNodeInstanceWriter implements NodeInstanceWriter { + + @Override + public boolean accept(NodeInstance value) { + return value instanceof MilestoneNodeInstance; + } + + @Override + public Builder write(MarshallerWriterContext context, NodeInstance value) { + MilestoneNodeInstance nodeInstance = (MilestoneNodeInstance) value; + MilestoneNodeInstanceContent.Builder builder = MilestoneNodeInstanceContent.newBuilder(); + + List timerInstances = nodeInstance.getTimerInstances(); + if (timerInstances != null) { + builder.addAllTimerInstanceId(timerInstances); + } + if (nodeInstance.getTimerInstancesReference() != null) { + builder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); + } + return builder; + } + +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/RuleSetNodeInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/RuleSetNodeInstanceReader.java new file mode 100644 index 00000000000..9123a520a5d --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/RuleSetNodeInstanceReader.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.jbpm.flow.serialization.MarshallerReaderContext; +import org.jbpm.flow.serialization.NodeInstanceReader; +import org.jbpm.flow.serialization.ProcessInstanceMarshallerException; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.RuleSetNodeInstanceContent; +import org.jbpm.workflow.instance.node.RuleSetNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.Any; +import com.google.protobuf.GeneratedMessageV3; + +public class RuleSetNodeInstanceReader implements NodeInstanceReader { + + @Override + public boolean accept(Any value) { + return value.is(RuleSetNodeInstanceContent.class); + } + + @Override + public NodeInstance read(MarshallerReaderContext context, Any value) { + try { + RuleSetNodeInstanceContent content = value.unpack(RuleSetNodeInstanceContent.class); + RuleSetNodeInstance nodeInstance = new RuleSetNodeInstance(); + nodeInstance.setRuleFlowGroup(content.getRuleFlowGroup()); + if (content.getTimerInstanceIdCount() > 0) { + nodeInstance.internalSetTimerInstances(new ArrayList<>(content.getTimerInstanceIdList())); + } + if (!content.getTimerInstanceReferenceMap().isEmpty()) { + nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); + } + + return nodeInstance; + } catch (Exception e) { + throw new ProcessInstanceMarshallerException(e); + } + } + + @Override + public Class type() { + return RuleSetNodeInstanceContent.class; + } +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/RuleSetNodeInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/RuleSetNodeInstanceWriter.java new file mode 100644 index 00000000000..8b86f45a294 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/RuleSetNodeInstanceWriter.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import org.jbpm.flow.serialization.MarshallerWriterContext; +import org.jbpm.flow.serialization.NodeInstanceWriter; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.RuleSetNodeInstanceContent; +import org.jbpm.workflow.instance.node.RuleSetNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.GeneratedMessageV3.Builder; + +public class RuleSetNodeInstanceWriter implements NodeInstanceWriter { + + @Override + public boolean accept(NodeInstance value) { + return value instanceof RuleSetNodeInstance; + } + + @Override + public Builder write(MarshallerWriterContext context, NodeInstance value) { + RuleSetNodeInstance nodeInstance = (RuleSetNodeInstance) value; + RuleSetNodeInstanceContent.Builder ruleSet = RuleSetNodeInstanceContent.newBuilder(); + ruleSet.setRuleFlowGroup(nodeInstance.getRuleFlowGroup()); + ruleSet.addAllTimerInstanceId(nodeInstance.getTimerInstances()); + if (nodeInstance.getTimerInstancesReference() != null) { + ruleSet.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); + } + + return ruleSet; + } + +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/StateNodeInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/StateNodeInstanceReader.java new file mode 100644 index 00000000000..7f8df9c41e7 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/StateNodeInstanceReader.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.jbpm.flow.serialization.MarshallerReaderContext; +import org.jbpm.flow.serialization.NodeInstanceReader; +import org.jbpm.flow.serialization.ProcessInstanceMarshallerException; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.StateNodeInstanceContent; +import org.jbpm.workflow.instance.node.StateNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.Any; +import com.google.protobuf.GeneratedMessageV3; + +public class StateNodeInstanceReader implements NodeInstanceReader { + + @Override + public Integer order() { + return NodeInstanceReader.super.order() + 1; + } + + @Override + public boolean accept(Any value) { + return value.is(StateNodeInstanceContent.class); + } + + @Override + public NodeInstance read(MarshallerReaderContext context, Any value) { + try { + StateNodeInstanceContent content = value.unpack(StateNodeInstanceContent.class); + StateNodeInstance nodeInstance = new StateNodeInstance(); + if (content.getTimerInstanceIdCount() > 0) { + List timerInstances = new ArrayList<>(); + for (String _timerId : content.getTimerInstanceIdList()) { + timerInstances.add(_timerId); + } + nodeInstance.internalSetTimerInstances(timerInstances); + } + if (!content.getTimerInstanceReferenceMap().isEmpty()) { + nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); + } + return nodeInstance; + } catch (Exception e) { + throw new ProcessInstanceMarshallerException(e); + } + } + + @Override + public Class type() { + return StateNodeInstanceContent.class; + } +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/StateNodeInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/StateNodeInstanceWriter.java new file mode 100644 index 00000000000..a9ff770c2e1 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/StateNodeInstanceWriter.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.List; + +import org.jbpm.flow.serialization.MarshallerWriterContext; +import org.jbpm.flow.serialization.NodeInstanceWriter; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.StateNodeInstanceContent; +import org.jbpm.workflow.instance.node.StateNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.GeneratedMessageV3.Builder; + +public class StateNodeInstanceWriter implements NodeInstanceWriter { + + @Override + public Integer order() { + return NodeInstanceWriter.super.order() + 1; + } + + @Override + public boolean accept(NodeInstance value) { + return value instanceof StateNodeInstance; + } + + @Override + public Builder write(MarshallerWriterContext context, NodeInstance value) { + StateNodeInstance nodeInstance = (StateNodeInstance) value; + StateNodeInstanceContent.Builder builder = StateNodeInstanceContent.newBuilder(); + List timerInstances = nodeInstance.getTimerInstances(); + if (timerInstances != null) { + builder.addAllTimerInstanceId(timerInstances); + } + if (nodeInstance.getTimerInstancesReference() != null) { + builder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); + } + return builder; + } + +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/SubProcessNodeInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/SubProcessNodeInstanceReader.java new file mode 100644 index 00000000000..5581620d6bb --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/SubProcessNodeInstanceReader.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.jbpm.flow.serialization.MarshallerReaderContext; +import org.jbpm.flow.serialization.NodeInstanceReader; +import org.jbpm.flow.serialization.ProcessInstanceMarshallerException; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.SubProcessNodeInstanceContent; +import org.jbpm.workflow.instance.node.SubProcessNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.Any; +import com.google.protobuf.GeneratedMessageV3; + +public class SubProcessNodeInstanceReader implements NodeInstanceReader { + + @Override + public boolean accept(Any value) { + return value.is(SubProcessNodeInstanceContent.class); + } + + @Override + public NodeInstance read(MarshallerReaderContext context, Any value) { + try { + SubProcessNodeInstanceContent content = value.unpack(SubProcessNodeInstanceContent.class); + SubProcessNodeInstance nodeInstance = new SubProcessNodeInstance(); + nodeInstance.internalSetProcessInstanceId(content.getProcessInstanceId()); + if (content.getTimerInstanceIdCount() > 0) { + List timerInstances = new ArrayList<>(); + for (String timerId : content.getTimerInstanceIdList()) { + timerInstances.add(timerId); + } + nodeInstance.internalSetTimerInstances(timerInstances); + } + if (!content.getTimerInstanceReferenceMap().isEmpty()) { + nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); + } + + return nodeInstance; + } catch (Exception e) { + throw new ProcessInstanceMarshallerException(e); + } + } + + @Override + public Class type() { + return SubProcessNodeInstanceContent.class; + } +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/SubProcessNodeInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/SubProcessNodeInstanceWriter.java new file mode 100644 index 00000000000..c53fc1e0816 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/SubProcessNodeInstanceWriter.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.List; + +import org.jbpm.flow.serialization.MarshallerWriterContext; +import org.jbpm.flow.serialization.NodeInstanceWriter; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.SubProcessNodeInstanceContent; +import org.jbpm.workflow.instance.node.SubProcessNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.GeneratedMessageV3.Builder; + +public class SubProcessNodeInstanceWriter implements NodeInstanceWriter { + + @Override + public boolean accept(NodeInstance value) { + return value instanceof SubProcessNodeInstance; + } + + @Override + public Builder write(MarshallerWriterContext context, NodeInstance value) { + SubProcessNodeInstance nodeInstance = (SubProcessNodeInstance) value; + SubProcessNodeInstanceContent.Builder builder = SubProcessNodeInstanceContent.newBuilder(); + builder.setProcessInstanceId(nodeInstance.getProcessInstanceId()); + List timerInstances = nodeInstance.getTimerInstances(); + if (timerInstances != null) { + builder.addAllTimerInstanceId(timerInstances); + } + if (nodeInstance.getTimerInstancesReference() != null) { + builder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); + } + + return builder; + } + +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/TimerNodeInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/TimerNodeInstanceReader.java new file mode 100644 index 00000000000..757daa8ae15 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/TimerNodeInstanceReader.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import org.jbpm.flow.serialization.MarshallerReaderContext; +import org.jbpm.flow.serialization.NodeInstanceReader; +import org.jbpm.flow.serialization.ProcessInstanceMarshallerException; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.TimerNodeInstanceContent; +import org.jbpm.workflow.instance.node.TimerNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.Any; +import com.google.protobuf.GeneratedMessageV3; + +public class TimerNodeInstanceReader implements NodeInstanceReader { + + @Override + public boolean accept(Any value) { + return value.is(TimerNodeInstanceContent.class); + } + + @Override + public NodeInstance read(MarshallerReaderContext context, Any value) { + try { + TimerNodeInstanceContent content = value.unpack(TimerNodeInstanceContent.class); + TimerNodeInstance nodeInstance = new TimerNodeInstance(); + nodeInstance.internalSetTimerId(content.getTimerId()); + return nodeInstance; + } catch (Exception e) { + throw new ProcessInstanceMarshallerException(e); + } + } + + @Override + public Class type() { + return TimerNodeInstanceContent.class; + } +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/TimerNodeInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/TimerNodeInstanceWriter.java new file mode 100644 index 00000000000..67d5e5ac4cd --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/TimerNodeInstanceWriter.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import org.jbpm.flow.serialization.MarshallerWriterContext; +import org.jbpm.flow.serialization.NodeInstanceWriter; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.TimerNodeInstanceContent; +import org.jbpm.workflow.instance.node.TimerNodeInstance; +import org.kie.api.runtime.process.NodeInstance; + +import com.google.protobuf.GeneratedMessageV3.Builder; + +public class TimerNodeInstanceWriter implements NodeInstanceWriter { + + @Override + public boolean accept(NodeInstance value) { + return value instanceof TimerNodeInstance; + } + + @Override + public Builder write(MarshallerWriterContext context, NodeInstance value) { + TimerNodeInstance nodeInstance = (TimerNodeInstance) value; + return TimerNodeInstanceContent.newBuilder().setTimerId(nodeInstance.getTimerId()); + } + +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/WorkItemNodeInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/WorkItemNodeInstanceReader.java new file mode 100644 index 00000000000..115c7510d02 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/WorkItemNodeInstanceReader.java @@ -0,0 +1,196 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.jbpm.flow.serialization.MarshallerContextName; +import org.jbpm.flow.serialization.MarshallerReaderContext; +import org.jbpm.flow.serialization.NodeInstanceReader; +import org.jbpm.flow.serialization.ProcessInstanceMarshallerException; +import org.jbpm.flow.serialization.impl.ProtobufVariableReader; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.WorkItemNodeInstanceContent; +import org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf; +import org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData; +import org.jbpm.process.instance.impl.humantask.HumanTaskWorkItemImpl; +import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem; +import org.jbpm.process.instance.impl.humantask.Reassignment; +import org.jbpm.ruleflow.instance.RuleFlowProcessInstance; +import org.jbpm.workflow.instance.node.HumanTaskNodeInstance; +import org.jbpm.workflow.instance.node.WorkItemNodeInstance; +import org.kie.api.runtime.process.NodeInstance; +import org.kie.kogito.process.workitem.Attachment; +import org.kie.kogito.process.workitem.Comment; +import org.kie.kogito.process.workitems.InternalKogitoWorkItem; +import org.kie.kogito.process.workitems.impl.KogitoWorkItemImpl; + +import com.google.protobuf.Any; +import com.google.protobuf.GeneratedMessageV3; +import com.google.protobuf.InvalidProtocolBufferException; + +public class WorkItemNodeInstanceReader implements NodeInstanceReader { + + @Override + public boolean accept(Any value) { + return value.is(WorkItemNodeInstanceContent.class); + } + + @Override + public Class type() { + return WorkItemNodeInstanceContent.class; + } + + @Override + public NodeInstance read(MarshallerReaderContext context, Any value) { + try { + ProtobufVariableReader varReader = new ProtobufVariableReader(context); + WorkItemNodeInstanceContent content = value.unpack(WorkItemNodeInstanceContent.class); + WorkItemNodeInstance nodeInstance = instanceWorkItem(content); + if (nodeInstance instanceof HumanTaskNodeInstance) { + HumanTaskNodeInstance humanTaskNodeInstance = (HumanTaskNodeInstance) nodeInstance; + InternalHumanTaskWorkItem workItem = humanTaskNodeInstance.getWorkItem(); + Any workItemDataMessage = content.getWorkItemData(); + if (workItemDataMessage.is(HumanTaskWorkItemData.class)) { + HumanTaskWorkItemData workItemData = workItemDataMessage.unpack(HumanTaskWorkItemData.class); + humanTaskNodeInstance.getNotCompletedDeadlineTimers().putAll(buildDeadlines(workItemData.getCompletedDeadlinesMap())); + humanTaskNodeInstance.getNotCompletedReassigments().putAll(buildReassignments(workItemData.getCompletedReassigmentsMap())); + humanTaskNodeInstance.getNotStartedDeadlineTimers().putAll(buildDeadlines(workItemData.getStartDeadlinesMap())); + humanTaskNodeInstance.getNotStartedReassignments().putAll(buildReassignments(workItemData.getStartReassigmentsMap())); + + if (workItemData.hasTaskName()) { + workItem.setTaskName(workItemData.getTaskName()); + } + if (workItemData.hasTaskDescription()) { + workItem.setTaskDescription(workItemData.getTaskDescription()); + } + if (workItemData.hasTaskPriority()) { + workItem.setTaskPriority(workItemData.getTaskPriority()); + } + if (workItemData.hasTaskReferenceName()) { + workItem.setReferenceName(workItemData.getTaskReferenceName()); + } + if (workItemData.hasActualOwner()) { + workItem.setActualOwner(workItemData.getActualOwner()); + } + workItem.getAdminUsers().addAll(workItemData.getAdminUsersList()); + workItem.getAdminGroups().addAll(workItemData.getAdminGroupsList()); + workItem.getPotentialUsers().addAll(workItemData.getPotUsersList()); + workItem.getPotentialGroups().addAll(workItemData.getPotGroupsList()); + workItem.getExcludedUsers().addAll(workItemData.getExcludedUsersList()); + workItem.getComments().putAll(workItemData.getCommentsList().stream().map(this::buildComment).collect(Collectors.toMap(Comment::getId, Function.identity()))); + workItem.getAttachments().putAll(workItemData.getAttachmentsList().stream().map(this::buildAttachment).collect(Collectors.toMap(Attachment::getId, Function.identity()))); + + } + + } + + RuleFlowProcessInstance ruleFlowProcessInstance = context.get(MarshallerContextName.MARSHALLER_PROCESS_INSTANCE); + nodeInstance.internalSetWorkItemId(content.getWorkItemId()); + InternalKogitoWorkItem workItem = (InternalKogitoWorkItem) nodeInstance.getWorkItem(); + workItem.setId(content.getWorkItemId()); + workItem.setProcessInstanceId(ruleFlowProcessInstance.getStringId()); + workItem.setName(content.getName()); + workItem.setState(content.getState()); + workItem.setDeploymentId(ruleFlowProcessInstance.getDeploymentId()); + workItem.setProcessInstance(ruleFlowProcessInstance); + workItem.setPhaseId(content.getPhaseId()); + workItem.setPhaseStatus(content.getPhaseStatus()); + workItem.setStartDate(new Date(content.getStartDate())); + if (content.getCompleteDate() > 0) { + workItem.setCompleteDate(new Date(content.getCompleteDate())); + } + + if (content.getTimerInstanceIdCount() > 0) { + nodeInstance.internalSetTimerInstances(new ArrayList<>(content.getTimerInstanceIdList())); + } + if (!content.getTimerInstanceReferenceMap().isEmpty()) { + nodeInstance.internalSetTimerInstancesReference(new HashMap<>(content.getTimerInstanceReferenceMap())); + } + nodeInstance.internalSetProcessInstanceId(content.getErrorHandlingProcessInstanceId()); + varReader.buildVariables(content.getVariableList()).forEach(var -> nodeInstance.getWorkItem().getParameters().put(var.getName(), var.getValue())); + varReader.buildVariables(content.getResultList()).forEach(var -> nodeInstance.getWorkItem().getResults().put(var.getName(), var.getValue())); + return nodeInstance; + } catch (InvalidProtocolBufferException ex) { + throw new ProcessInstanceMarshallerException("cannot unpack node instance", ex); + } + } + + private WorkItemNodeInstance instanceWorkItem(WorkItemNodeInstanceContent content) { + if (content.hasWorkItemData()) { + Any workItemDataMessage = content.getWorkItemData(); + if (workItemDataMessage.is(HumanTaskWorkItemData.class)) { + HumanTaskNodeInstance nodeInstance = new HumanTaskNodeInstance(); + HumanTaskWorkItemImpl workItem = new HumanTaskWorkItemImpl(); + nodeInstance.internalSetWorkItem(workItem); + return nodeInstance; + } else { + throw new ProcessInstanceMarshallerException("Don't know which type of work item is"); + } + } else { + WorkItemNodeInstance nodeInstance = new WorkItemNodeInstance(); + KogitoWorkItemImpl workItem = new KogitoWorkItemImpl(); + workItem.setId(UUID.randomUUID().toString()); + nodeInstance.internalSetWorkItem(workItem); + return nodeInstance; + } + } + + private Comment buildComment(KogitoWorkItemsProtobuf.Comment comment) { + Comment result = new Comment(comment.getId(), comment.getUpdatedBy()); + result.setContent(comment.getContent()); + result.setUpdatedAt(new Date(comment.getUpdatedAt())); + return result; + } + + private Attachment buildAttachment(KogitoWorkItemsProtobuf.Attachment attachment) { + Attachment result = new Attachment(attachment.getId(), attachment.getUpdatedBy()); + result.setContent(URI.create(attachment.getContent())); + result.setUpdatedAt(new Date(attachment.getUpdatedAt())); + result.setName(attachment.getName()); + return result; + } + + private Map> buildDeadlines(Map deadlinesProtobuf) { + Map> deadlines = new HashMap<>(); + for (Map.Entry entry : deadlinesProtobuf.entrySet()) { + Map notification = new HashMap<>(); + for (Map.Entry pair : entry.getValue().getContentMap().entrySet()) { + notification.put(pair.getKey(), pair.getValue()); + } + deadlines.put(entry.getKey(), notification); + } + return deadlines; + } + + private Map buildReassignments(Map reassignmentsProtobuf) { + Map reassignments = new HashMap<>(); + for (Map.Entry entry : reassignmentsProtobuf.entrySet()) { + reassignments.put(entry.getKey(), new Reassignment(entry.getValue().getUsersList().stream().collect(Collectors + .toSet()), entry.getValue().getGroupsList().stream().collect(Collectors.toSet()))); + } + return reassignments; + } +} diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/WorkItemNodeInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/WorkItemNodeInstanceWriter.java new file mode 100644 index 00000000000..50609b1ffd3 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/state/WorkItemNodeInstanceWriter.java @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jbpm.flow.serialization.impl.marshallers.state; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.jbpm.flow.serialization.MarshallerWriterContext; +import org.jbpm.flow.serialization.NodeInstanceWriter; +import org.jbpm.flow.serialization.impl.ProtobufVariableWriter; +import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.WorkItemNodeInstanceContent; +import org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf; +import org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData; +import org.jbpm.process.instance.impl.humantask.Reassignment; +import org.jbpm.workflow.instance.node.HumanTaskNodeInstance; +import org.jbpm.workflow.instance.node.WorkItemNodeInstance; +import org.kie.api.runtime.process.NodeInstance; +import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.process.workitem.Attachment; +import org.kie.kogito.process.workitem.Comment; +import org.kie.kogito.process.workitem.HumanTaskWorkItem; + +import com.google.protobuf.Any; +import com.google.protobuf.GeneratedMessageV3.Builder; + +public class WorkItemNodeInstanceWriter implements NodeInstanceWriter { + + @Override + public boolean accept(NodeInstance value) { + return value instanceof WorkItemNodeInstance; + } + + @Override + public Builder write(MarshallerWriterContext context, NodeInstance value) { + ProtobufVariableWriter varWriter = new ProtobufVariableWriter(context); + WorkItemNodeInstance nodeInstance = (WorkItemNodeInstance) value; + WorkItemNodeInstanceContent.Builder builder = WorkItemNodeInstanceContent.newBuilder(); + + List timerInstances = nodeInstance.getTimerInstances(); + if (timerInstances != null) { + builder.addAllTimerInstanceId(timerInstances); + } + if (nodeInstance.getTimerInstancesReference() != null) { + builder.putAllTimerInstanceReference(nodeInstance.getTimerInstancesReference()); + } + if (nodeInstance.getExceptionHandlingProcessInstanceId() != null) { + builder.setErrorHandlingProcessInstanceId(nodeInstance.getExceptionHandlingProcessInstanceId()); + } + KogitoWorkItem workItem = nodeInstance.getWorkItem(); + + builder.setWorkItemId(nodeInstance.getWorkItemId()) + .setName(workItem.getName()) + .setState(workItem.getState()) + .setPhaseId(workItem.getPhaseId()) + .setPhaseStatus(workItem.getPhaseStatus()) + .setStartDate(workItem.getStartDate().getTime()) + .addAllVariable(varWriter.buildVariables(new ArrayList<>(workItem.getParameters().entrySet()))) + .addAllResult(varWriter.buildVariables(new ArrayList<>(workItem.getResults().entrySet()))); + + if (workItem.getCompleteDate() != null) { + builder.setCompleteDate(workItem.getCompleteDate().getTime()); + } + + if (nodeInstance instanceof HumanTaskNodeInstance) { + builder.setWorkItemData(Any.pack(buildHumanTaskWorkItemData((HumanTaskNodeInstance) nodeInstance, (HumanTaskWorkItem) nodeInstance.getWorkItem()))); + } + return builder; + } + + private HumanTaskWorkItemData buildHumanTaskWorkItemData(HumanTaskNodeInstance nodeInstance, HumanTaskWorkItem workItem) { + HumanTaskWorkItemData.Builder builder = HumanTaskWorkItemData.newBuilder(); + + if (workItem.getTaskPriority() != null) { + builder.setTaskPriority(workItem.getTaskPriority()); + } + + if (workItem.getReferenceName() != null) { + builder.setTaskReferenceName(workItem.getReferenceName()); + } + if (workItem.getTaskDescription() != null) { + builder.setTaskDescription(workItem.getTaskDescription()); + } + + if (workItem.getActualOwner() != null) { + builder.setActualOwner(workItem.getActualOwner()); + } + + if (workItem.getTaskName() != null) { + builder.setTaskName(workItem.getTaskName()); + } + + if (workItem.getPotentialUsers() != null) { + builder.addAllPotUsers(workItem.getPotentialUsers()); + } + + if (workItem.getPotentialGroups() != null) { + builder.addAllPotGroups(workItem.getPotentialGroups()); + } + + if (workItem.getExcludedUsers() != null) { + builder.addAllExcludedUsers(workItem.getExcludedUsers()); + } + + if (workItem.getAdminUsers() != null) { + builder.addAllAdminUsers(workItem.getAdminUsers()); + } + + if (workItem.getAdminGroups() != null) { + builder.addAllAdminGroups(workItem.getAdminGroups()); + } + + if (workItem.getComments() != null) { + builder.addAllComments(buildComments(workItem.getComments().values())); + } + + if (workItem.getAttachments() != null) { + builder.addAllAttachments(buildAttachments(workItem.getAttachments().values())); + } + + if (nodeInstance.getNotStartedDeadlineTimers() != null) { + builder.putAllStartDeadlines(buildDeadlines(nodeInstance.getNotStartedDeadlineTimers())); + } + + if (nodeInstance.getNotStartedReassignments() != null) { + builder.putAllStartReassigments(buildReassignments(nodeInstance.getNotStartedReassignments())); + } + + if (nodeInstance.getNotCompletedDeadlineTimers() != null) { + builder.putAllCompletedDeadlines(buildDeadlines(nodeInstance.getNotCompletedDeadlineTimers())); + } + + if (nodeInstance.getNotCompletedReassigments() != null) { + builder.putAllCompletedReassigments(buildReassignments(nodeInstance.getNotCompletedReassigments())); + } + + return builder.build(); + } + + private List buildComments(Iterable comments) { + List commentsProtobuf = new ArrayList<>(); + for (Comment comment : comments) { + KogitoWorkItemsProtobuf.Comment workItemComment = KogitoWorkItemsProtobuf.Comment.newBuilder() + .setId(comment.getId().toString()) + .setContent(comment.getContent()) + .setUpdatedBy(comment.getUpdatedBy()) + .setUpdatedAt(comment.getUpdatedAt().getTime()) + .build(); + commentsProtobuf.add(workItemComment); + } + return commentsProtobuf; + } + + private List buildAttachments(Iterable attachments) { + List attachmentProtobuf = new ArrayList<>(); + for (Attachment attachment : attachments) { + KogitoWorkItemsProtobuf.Attachment workItemAttachment = KogitoWorkItemsProtobuf.Attachment.newBuilder() + .setId(attachment.getId().toString()).setContent(attachment.getContent().toString()) + .setUpdatedBy(attachment.getUpdatedBy()).setUpdatedAt(attachment.getUpdatedAt().getTime()) + .setName(attachment.getName()) + .build(); + attachmentProtobuf.add(workItemAttachment); + } + return attachmentProtobuf; + } + + private Map buildDeadlines(Map> deadlines) { + Map deadlinesProtobuf = new HashMap<>(); + for (Map.Entry> entry : deadlines.entrySet()) { + KogitoWorkItemsProtobuf.Deadline.Builder builder = KogitoWorkItemsProtobuf.Deadline.newBuilder(); + entry.getValue().forEach((k, v) -> builder.putContent(k, v.toString())); + deadlinesProtobuf.put(entry.getKey(), builder.build()); + } + return deadlinesProtobuf; + } + + private Map buildReassignments(Map reassignments) { + Map reassignmentsProtobuf = new HashMap<>(); + for (Map.Entry entry : reassignments.entrySet()) { + KogitoWorkItemsProtobuf.Reassignment.Builder builder = KogitoWorkItemsProtobuf.Reassignment.newBuilder(); + builder.addAllGroups(entry.getValue().getPotentialGroups()); + builder.addAllUsers(entry.getValue().getPotentialUsers()); + reassignmentsProtobuf.put(entry.getKey(), builder.build()); + } + return reassignmentsProtobuf; + } +} diff --git a/jbpm/process-serialization-protobuf/src/main/resources/META-INF/services/org.jbpm.flow.serialization.NodeInstanceReader b/jbpm/process-serialization-protobuf/src/main/resources/META-INF/services/org.jbpm.flow.serialization.NodeInstanceReader new file mode 100644 index 00000000000..77fa53e0dd3 --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/resources/META-INF/services/org.jbpm.flow.serialization.NodeInstanceReader @@ -0,0 +1,14 @@ +org.jbpm.flow.serialization.impl.marshallers.state.AsyncEventNodeInstanceReader +org.jbpm.flow.serialization.impl.marshallers.state.CompositeContextNodeInstanceReader +org.jbpm.flow.serialization.impl.marshallers.state.DynamicNodeInstanceReader +org.jbpm.flow.serialization.impl.marshallers.state.EventNodeInstanceReader +org.jbpm.flow.serialization.impl.marshallers.state.EventSubProcessNodeInstanceReader +org.jbpm.flow.serialization.impl.marshallers.state.ForEachNodeInstanceReader +org.jbpm.flow.serialization.impl.marshallers.state.JoinNodeInstanceReader +org.jbpm.flow.serialization.impl.marshallers.state.LambdaSubProcessNodeInstanceReader +org.jbpm.flow.serialization.impl.marshallers.state.MilestoneNodeInstanceReader +org.jbpm.flow.serialization.impl.marshallers.state.RuleSetNodeInstanceReader +org.jbpm.flow.serialization.impl.marshallers.state.StateNodeInstanceReader +org.jbpm.flow.serialization.impl.marshallers.state.SubProcessNodeInstanceReader +org.jbpm.flow.serialization.impl.marshallers.state.TimerNodeInstanceReader +org.jbpm.flow.serialization.impl.marshallers.state.WorkItemNodeInstanceReader \ No newline at end of file diff --git a/jbpm/process-serialization-protobuf/src/main/resources/META-INF/services/org.jbpm.flow.serialization.NodeInstanceWriter b/jbpm/process-serialization-protobuf/src/main/resources/META-INF/services/org.jbpm.flow.serialization.NodeInstanceWriter new file mode 100644 index 00000000000..293ab4529da --- /dev/null +++ b/jbpm/process-serialization-protobuf/src/main/resources/META-INF/services/org.jbpm.flow.serialization.NodeInstanceWriter @@ -0,0 +1,14 @@ +org.jbpm.flow.serialization.impl.marshallers.state.AsyncEventNodeInstanceWriter +org.jbpm.flow.serialization.impl.marshallers.state.CompositeContextNodeInstanceWriter +org.jbpm.flow.serialization.impl.marshallers.state.DynamicNodeInstanceWriter +org.jbpm.flow.serialization.impl.marshallers.state.EventNodeInstanceWriter +org.jbpm.flow.serialization.impl.marshallers.state.EventSubProcessNodeInstanceWriter +org.jbpm.flow.serialization.impl.marshallers.state.ForEachNodeInstanceWriter +org.jbpm.flow.serialization.impl.marshallers.state.JoinNodeInstanceWriter +org.jbpm.flow.serialization.impl.marshallers.state.LambdaSubProcessNodeInstanceWriter +org.jbpm.flow.serialization.impl.marshallers.state.MilestoneNodeInstanceWriter +org.jbpm.flow.serialization.impl.marshallers.state.RuleSetNodeInstanceWriter +org.jbpm.flow.serialization.impl.marshallers.state.StateNodeInstanceWriter +org.jbpm.flow.serialization.impl.marshallers.state.SubProcessNodeInstanceWriter +org.jbpm.flow.serialization.impl.marshallers.state.TimerNodeInstanceWriter +org.jbpm.flow.serialization.impl.marshallers.state.WorkItemNodeInstanceWriter \ No newline at end of file