This is an automated email from the ASF dual-hosted git repository.
pefernan pushed a commit to branch main
in repository
https://gitbox.apache.org/repos/asf/incubator-kie-kogito-runtimes.git
The following commit(s) were added to refs/heads/main by this push:
new 6294c3668e [incubator-kie-issues-1959] Process instance out of sync
when completing usertasks in parallel gateway with async Service Tasks (#3919)
6294c3668e is described below
commit 6294c3668e704687ab2911e7085b3ec1d327ced6
Author: Pere Fernández <[email protected]>
AuthorDate: Mon May 19 11:33:49 2025 +0200
[incubator-kie-issues-1959] Process instance out of sync when completing
usertasks in parallel gateway with async Service Tasks (#3919)
* [incubator-kie-issues-1959] Process instance out of sync when completing
usertasks in parallel gateway with async Service Tasks
* - restored legacyConfigRoot
- fixed operation name on SB codegen
* - added validation
---
.../api/context/ContextAttributesConstants.java | 2 +
.../faultTolerance/FaultToleranceAnnotator.java} | 17 ++-
.../codegen/faultTolerance/FaultToleranceUtil.java | 45 ++++++
.../impl/AbstractFaultToleranceAnnotator.java} | 15 +-
.../impl/QuarkusFaultToleranceAnnotator.java} | 26 ++--
.../impl/SpringBootFaultToleranceAnnotator.java | 55 ++++++++
.../kie/kogito/codegen/process/ProcessCodegen.java | 4 +-
.../codegen/process/ProcessResourceGenerator.java | 34 ++++-
.../kogito/codegen/process/util/CodegenUtil.java | 15 ++
.../kogito/codegen/usertask/UserTaskCodegen.java | 74 ++++++++--
.../process/ProcessResourceGeneratorTest.java | 139 ++++++++++---------
.../codegen/usertask/UserTaskCodegenTest.java | 154 +++++++++++++++++++++
.../common/deployment/KogitoAssetsProcessor.java | 8 ++
.../kogito-quarkus-processes-deployment/pom.xml | 4 +
.../deployment/FaultToleranceProcessor.java | 54 ++++++++
.../kogito-quarkus-processes/pom.xml | 4 +
.../kogito-processes-spring-boot-starter/pom.xml | 4 +
17 files changed, 551 insertions(+), 103 deletions(-)
diff --git
a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/context/ContextAttributesConstants.java
b/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/context/ContextAttributesConstants.java
index 826317459e..ce08076802 100644
---
a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/context/ContextAttributesConstants.java
+++
b/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/context/ContextAttributesConstants.java
@@ -27,6 +27,8 @@ public final class ContextAttributesConstants {
public static final String PROCESS_AUTO_SVG_MAPPING =
"processAutoSVGMapping";
+ public static final String KOGITO_FAULT_TOLERANCE_ENABLED =
"kogito.faultToleranceEnabled";
+
private ContextAttributesConstants() {
}
}
diff --git
a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/context/ContextAttributesConstants.java
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/faultTolerance/FaultToleranceAnnotator.java
similarity index 65%
copy from
kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/context/ContextAttributesConstants.java
copy to
kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/faultTolerance/FaultToleranceAnnotator.java
index 826317459e..763a586f13 100644
---
a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/context/ContextAttributesConstants.java
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/faultTolerance/FaultToleranceAnnotator.java
@@ -16,17 +16,16 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.kie.kogito.codegen.api.context;
+package org.kie.kogito.codegen.faultTolerance;
-public final class ContextAttributesConstants {
+import com.github.javaparser.ast.body.MethodDeclaration;
- /**
- * OpenAPI Generator Descriptors with information of every REST client
generated indexed by the spec resource file.
- */
- public static final String OPENAPI_DESCRIPTORS = "openApiDescriptor";
+/**
+ * Helper class to add FaultTolerance annotation
+ */
+public interface FaultToleranceAnnotator {
- public static final String PROCESS_AUTO_SVG_MAPPING =
"processAutoSVGMapping";
+ void addFaultToleranceAnnotations(MethodDeclaration methodDeclaration);
- private ContextAttributesConstants() {
- }
+ String getRetryAnnotationName();
}
diff --git
a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/faultTolerance/FaultToleranceUtil.java
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/faultTolerance/FaultToleranceUtil.java
new file mode 100644
index 0000000000..811d563925
--- /dev/null
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/faultTolerance/FaultToleranceUtil.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.kie.kogito.codegen.faultTolerance;
+
+import org.kie.kogito.codegen.api.context.KogitoBuildContext;
+import org.kie.kogito.codegen.api.context.impl.QuarkusKogitoBuildContext;
+import org.kie.kogito.codegen.api.context.impl.SpringBootKogitoBuildContext;
+import
org.kie.kogito.codegen.faultTolerance.impl.QuarkusFaultToleranceAnnotator;
+import
org.kie.kogito.codegen.faultTolerance.impl.SpringBootFaultToleranceAnnotator;
+import org.kie.kogito.codegen.process.ProcessCodegenException;
+
+public class FaultToleranceUtil {
+
+ private FaultToleranceUtil() {
+ // This is a utility class and shouldn't be instantiated.
+ }
+
+ public static FaultToleranceAnnotator
lookFaultToleranceAnnotatorForContext(KogitoBuildContext context) {
+ if (QuarkusKogitoBuildContext.CONTEXT_NAME.equals(context.name())) {
+ return new QuarkusFaultToleranceAnnotator(context);
+ } else if
(SpringBootKogitoBuildContext.CONTEXT_NAME.equals(context.name())) {
+ return new SpringBootFaultToleranceAnnotator(context);
+ } else {
+ throw new ProcessCodegenException("Kogito Fault Tolerance not
allowed for context: " + context.name());
+ }
+ }
+
+}
diff --git
a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/context/ContextAttributesConstants.java
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/faultTolerance/impl/AbstractFaultToleranceAnnotator.java
similarity index 65%
copy from
kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/context/ContextAttributesConstants.java
copy to
kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/faultTolerance/impl/AbstractFaultToleranceAnnotator.java
index 826317459e..27de34111f 100644
---
a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/context/ContextAttributesConstants.java
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/faultTolerance/impl/AbstractFaultToleranceAnnotator.java
@@ -16,17 +16,16 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.kie.kogito.codegen.api.context;
+package org.kie.kogito.codegen.faultTolerance.impl;
-public final class ContextAttributesConstants {
+import org.kie.kogito.codegen.api.context.KogitoBuildContext;
+import org.kie.kogito.codegen.faultTolerance.FaultToleranceAnnotator;
- /**
- * OpenAPI Generator Descriptors with information of every REST client
generated indexed by the spec resource file.
- */
- public static final String OPENAPI_DESCRIPTORS = "openApiDescriptor";
+public abstract class AbstractFaultToleranceAnnotator implements
FaultToleranceAnnotator {
- public static final String PROCESS_AUTO_SVG_MAPPING =
"processAutoSVGMapping";
+ protected KogitoBuildContext context;
- private ContextAttributesConstants() {
+ public AbstractFaultToleranceAnnotator(KogitoBuildContext context) {
+ this.context = context;
}
}
diff --git
a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/context/ContextAttributesConstants.java
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/faultTolerance/impl/QuarkusFaultToleranceAnnotator.java
similarity index 53%
copy from
kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/context/ContextAttributesConstants.java
copy to
kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/faultTolerance/impl/QuarkusFaultToleranceAnnotator.java
index 826317459e..a4071863c9 100644
---
a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/context/ContextAttributesConstants.java
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/faultTolerance/impl/QuarkusFaultToleranceAnnotator.java
@@ -16,17 +16,27 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.kie.kogito.codegen.api.context;
+package org.kie.kogito.codegen.faultTolerance.impl;
-public final class ContextAttributesConstants {
+import org.kie.kogito.codegen.api.context.KogitoBuildContext;
- /**
- * OpenAPI Generator Descriptors with information of every REST client
generated indexed by the spec resource file.
- */
- public static final String OPENAPI_DESCRIPTORS = "openApiDescriptor";
+import com.github.javaparser.ast.body.MethodDeclaration;
- public static final String PROCESS_AUTO_SVG_MAPPING =
"processAutoSVGMapping";
+public class QuarkusFaultToleranceAnnotator extends
AbstractFaultToleranceAnnotator {
- private ContextAttributesConstants() {
+ public static final String RETRY_ANNOTATION =
"org.eclipse.microprofile.faulttolerance.Retry";
+
+ public QuarkusFaultToleranceAnnotator(KogitoBuildContext context) {
+ super(context);
+ }
+
+ @Override
+ public String getRetryAnnotationName() {
+ return RETRY_ANNOTATION;
+ }
+
+ @Override
+ public void addFaultToleranceAnnotations(MethodDeclaration
methodDeclaration) {
+ methodDeclaration.addAnnotation(RETRY_ANNOTATION);
}
}
diff --git
a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/faultTolerance/impl/SpringBootFaultToleranceAnnotator.java
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/faultTolerance/impl/SpringBootFaultToleranceAnnotator.java
new file mode 100644
index 0000000000..7cff6a6556
--- /dev/null
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/faultTolerance/impl/SpringBootFaultToleranceAnnotator.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.kie.kogito.codegen.faultTolerance.impl;
+
+import org.kie.kogito.codegen.api.context.KogitoBuildContext;
+
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.*;
+
+public class SpringBootFaultToleranceAnnotator extends
AbstractFaultToleranceAnnotator {
+ public static final String RETRY_ANNOTATION =
"io.github.resilience4j.retry.annotation.Retry";
+
+ public SpringBootFaultToleranceAnnotator(KogitoBuildContext context) {
+ super(context);
+ }
+
+ @Override
+ public String getRetryAnnotationName() {
+ return RETRY_ANNOTATION;
+ }
+
+ @Override
+ public void addFaultToleranceAnnotations(MethodDeclaration
methodDeclaration) {
+
+ String name = methodDeclaration.getNameAsString();
+
+ methodDeclaration
+ .addAnnotation(new NormalAnnotationExpr(new
Name(RETRY_ANNOTATION), NodeList.nodeList(new MemberValuePair("name", new
StringLiteralExpr(name)))));
+ }
+
+ private String getOperationName(AnnotationExpr annotationExpr) {
+ return annotationExpr.asNormalAnnotationExpr().getPairs().stream()
+ .filter(memberValuePair ->
memberValuePair.getNameAsString().equals("summary"))
+ .findFirst()
+ .map(memberValuePair ->
memberValuePair.getValue().asStringLiteralExpr().asString())
+ .orElse(null);
+ }
+}
diff --git
a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java
index fdbb2541c3..c6f55b8fc7 100644
---
a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java
@@ -73,6 +73,7 @@ import static java.util.stream.Collectors.toList;
import static
org.jbpm.process.core.constants.CalendarConstants.BUSINESS_CALENDAR_PATH;
import static
org.kie.kogito.codegen.process.util.BusinessCalendarUtil.conditionallyAddCustomBusinessCalendar;
import static
org.kie.kogito.codegen.process.util.CodegenUtil.generatorProperty;
+import static
org.kie.kogito.codegen.process.util.CodegenUtil.isFaultToleranceEnabled;
import static
org.kie.kogito.codegen.process.util.CodegenUtil.isTransactionEnabled;
import static
org.kie.kogito.grafana.GrafanaConfigurationWriter.buildDashboardName;
import static
org.kie.kogito.grafana.GrafanaConfigurationWriter.generateOperationalDashboard;
@@ -378,7 +379,8 @@ public class ProcessCodegen extends AbstractGenerator {
.withWorkItems(processIdToWorkItemModel.get(workFlowProcess.getId()))
.withSignals(metaData.getSignals())
.withTriggers(metaData.isStartable(),
metaData.isDynamic(), metaData.getTriggers())
- .withTransaction(isTransactionEnabled(this,
context()));
+ .withTransaction(isTransactionEnabled(this, context()))
+
.withFaultTolerance(isFaultToleranceEnabled(context()));
rgs.add(processResourceGenerator);
}
diff --git
a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessResourceGenerator.java
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessResourceGenerator.java
index 207af9e636..67a7a7ca4d 100644
---
a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessResourceGenerator.java
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessResourceGenerator.java
@@ -44,6 +44,7 @@ import org.kie.kogito.codegen.api.template.TemplatedGenerator;
import org.kie.kogito.codegen.core.BodyDeclarationComparator;
import org.kie.kogito.codegen.core.CodegenUtils;
import org.kie.kogito.codegen.core.GeneratorConfig;
+import org.kie.kogito.codegen.faultTolerance.FaultToleranceAnnotator;
import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess;
import org.kie.kogito.internal.utils.ConversionUtils;
import org.slf4j.Logger;
@@ -69,6 +70,7 @@ import com.github.javaparser.ast.type.Type;
import static com.github.javaparser.StaticJavaParser.parse;
import static org.kie.kogito.codegen.core.CodegenUtils.interpolateTypes;
+import static
org.kie.kogito.codegen.faultTolerance.FaultToleranceUtil.lookFaultToleranceAnnotatorForContext;
import static org.kie.kogito.internal.utils.ConversionUtils.sanitizeClassName;
import static org.kie.kogito.internal.utils.ConversionUtils.sanitizeJavaName;
@@ -102,6 +104,7 @@ public class ProcessResourceGenerator {
private boolean startable;
private boolean dynamic;
private boolean transactionEnabled;
+ private boolean faultToleranceEnabled;
private List<TriggerMetaData> triggers;
private List<WorkItemModelMetaData> workItems;
@@ -151,6 +154,11 @@ public class ProcessResourceGenerator {
return this;
}
+ public ProcessResourceGenerator withFaultTolerance(boolean
faultToleranceEnabled) {
+ this.faultToleranceEnabled = faultToleranceEnabled;
+ return this;
+ }
+
public String getTaskModelFactory() {
return taskModelFactoryUnit.toString();
}
@@ -241,6 +249,8 @@ public class ProcessResourceGenerator {
manageTransactional(toReturn);
+ manageFaultTolerance(toReturn);
+
template.getMembers().sort(new BodyDeclarationComparator());
return toReturn;
}
@@ -402,6 +412,10 @@ public class ProcessResourceGenerator {
}
}
+ private boolean isTransactionEnabled() {
+ return transactionEnabled && context.hasDI() && !isServerless();
+ }
+
/**
* Conditionally add the <code>Transactional</code> annotation
*
@@ -409,7 +423,7 @@ public class ProcessResourceGenerator {
*
*/
protected void manageTransactional(CompilationUnit compilationUnit) {
- if (transactionEnabled && context.hasDI() && !isServerless()) { //
disabling transaction for serverless
+ if (isTransactionEnabled()) { // disabling transaction for serverless
LOG.debug("Transaction is enabled, adding annotations...");
DependencyInjectionAnnotator dependencyInjectionAnnotator =
context.getDependencyInjectionAnnotator();
getRestMethods(compilationUnit)
@@ -417,6 +431,24 @@ public class ProcessResourceGenerator {
}
}
+ /**
+ * Conditionally add the Fault Tolerance annotations
+ *
+ * @param compilationUnit
+ *
+ */
+ protected void manageFaultTolerance(CompilationUnit compilationUnit) {
+ if (faultToleranceEnabled && !isServerless()) {// disabling fault
tolerance for serverless
+ if (!isTransactionEnabled()) {
+ throw new ProcessCodegenException("Fault tolerance is enabled,
but transactions are disabled. Please enable transactions before fault
tolerance.");
+ }
+ LOG.debug("Fault tolerance is enabled, adding annotations...");
+ FaultToleranceAnnotator annotator =
lookFaultToleranceAnnotatorForContext(context);
+ getRestMethods(compilationUnit)
+ .forEach(annotator::addFaultToleranceAnnotations);
+ }
+ }
+
/**
* Retrieves all the <b>Rest endpoint</b> <code>MethodDeclaration</code>s
from the given
* <code>CompilationUnit</code>
diff --git
a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/util/CodegenUtil.java
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/util/CodegenUtil.java
index 1e33a95861..c7c1d414f7 100644
---
a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/util/CodegenUtil.java
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/util/CodegenUtil.java
@@ -26,6 +26,8 @@ import
org.kie.kogito.codegen.api.context.impl.JavaKogitoBuildContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static
org.kie.kogito.codegen.api.context.ContextAttributesConstants.KOGITO_FAULT_TOLERANCE_ENABLED;
+
public final class CodegenUtil {
private static final Logger LOG =
LoggerFactory.getLogger(CodegenUtil.class);
@@ -34,6 +36,11 @@ public final class CodegenUtil {
*/
public static final String TRANSACTION_ENABLED = "transactionEnabled";
+ /**
+ * Flag used to configure fault tolerance enabling. Default to
<code>true</code>
+ */
+ public static final String FAULT_TOLERANCE_ENABLED =
"faultToleranceEnabled";
+
private CodegenUtil() {
// do nothing
}
@@ -108,4 +115,12 @@ public final class CodegenUtil {
private static String getApplicationProperty(KogitoBuildContext context,
String property) {
return context.getApplicationProperty(property).orElseThrow(() -> new
IllegalArgumentException("Property " + property + " defined but does not
contain proper value"));
}
+
+ public static boolean isFaultToleranceEnabled(KogitoBuildContext context) {
+ boolean isFaultToleranceEnabled =
context.getApplicationProperty(KOGITO_FAULT_TOLERANCE_ENABLED)
+ .map(Boolean::parseBoolean)
+ .orElse(true);
+
+ return !JavaKogitoBuildContext.CONTEXT_NAME.equals(context.name()) &&
isFaultToleranceEnabled;
+ }
}
diff --git
a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegen.java
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegen.java
index 83a6c998f3..5afa147e1c 100644
---
a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegen.java
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/usertask/UserTaskCodegen.java
@@ -33,6 +33,7 @@ import java.util.function.Predicate;
import org.drools.codegen.common.GeneratedFile;
import org.drools.codegen.common.GeneratedFileType;
+import org.drools.codegen.common.rest.RestAnnotator;
import org.jbpm.bpmn2.xml.BPMNDISemanticModule;
import org.jbpm.bpmn2.xml.BPMNExtensionsSemanticModule;
import org.jbpm.bpmn2.xml.BPMNSemanticModule;
@@ -48,9 +49,9 @@ import org.kie.kogito.codegen.api.context.KogitoBuildContext;
import org.kie.kogito.codegen.api.io.CollectedResource;
import org.kie.kogito.codegen.api.template.TemplatedGenerator;
import org.kie.kogito.codegen.core.AbstractGenerator;
+import org.kie.kogito.codegen.faultTolerance.FaultToleranceAnnotator;
import org.kie.kogito.codegen.process.ProcessCodegenException;
import org.kie.kogito.codegen.process.ProcessParsingException;
-import org.kie.kogito.codegen.process.util.CodegenUtil;
import org.kie.kogito.internal.SupportedExtensions;
import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess;
import org.kie.kogito.process.validation.ValidationException;
@@ -77,6 +78,9 @@ import com.github.javaparser.ast.stmt.BlockStmt;
import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
import static java.util.stream.Collectors.toList;
+import static
org.kie.kogito.codegen.faultTolerance.FaultToleranceUtil.lookFaultToleranceAnnotatorForContext;
+import static
org.kie.kogito.codegen.process.util.CodegenUtil.isFaultToleranceEnabled;
+import static
org.kie.kogito.codegen.process.util.CodegenUtil.isTransactionEnabled;
import static
org.kie.kogito.serverless.workflow.utils.ServerlessWorkflowUtils.FAIL_ON_ERROR_PROPERTY;
public class UserTaskCodegen extends AbstractGenerator {
@@ -157,24 +161,78 @@ public class UserTaskCodegen extends AbstractGenerator {
}
if (context().hasRESTForGenerator(this)) {
- generatedFiles.add(generateRestEndpiont());
+ generatedFiles.add(generateRestEndpoint());
}
return generatedFiles;
}
- public GeneratedFile generateRestEndpiont() {
+ public GeneratedFile generateRestEndpoint() {
String packageName = context().getPackageName();
- CompilationUnit compilationUnit =
restTemplateGenerator.compilationUnitOrThrow("Not rest endpoints template found
for user tasks");
+ CompilationUnit compilationUnit = createRestEndpointCompilationUnit();
compilationUnit.setPackageDeclaration(packageName);
- if (CodegenUtil.isTransactionEnabled(this, context())) {
-
compilationUnit.findAll(MethodDeclaration.class).stream().filter(MethodDeclaration::isPublic).forEach(context().getDependencyInjectionAnnotator()::withTransactional);
- }
- String className =
compilationUnit.findFirst(ClassOrInterfaceDeclaration.class).get().getNameAsString();
+
+ manageTransactional(compilationUnit);
+
+ manageFaultTolerance(compilationUnit);
+
+ String className =
compilationUnit.findFirst(ClassOrInterfaceDeclaration.class)
+ .orElseThrow(() -> new
ProcessCodegenException("UserTaskResourceTemplate doesn't contain a class or
interface declaration!"))
+ .getNameAsString();
+
Path basePath = UserTaskCodegenHelper.path(packageName);
+
return new GeneratedFile(GeneratedFileType.REST,
basePath.resolve(className + ".java"), compilationUnit.toString());
}
+ protected CompilationUnit createRestEndpointCompilationUnit() {
+ return restTemplateGenerator.compilationUnitOrThrow("Not rest
endpoints template found for user tasks");
+ }
+
+ /**
+ * Conditionally add the <code>Transactional</code> annotation
+ *
+ * @param compilationUnit
+ *
+ */
+ protected void manageTransactional(CompilationUnit compilationUnit) {
+ if (isTransactionEnabled(this, context())) {
+
getRestMethods(compilationUnit).forEach(context().getDependencyInjectionAnnotator()::withTransactional);
+ }
+ }
+
+ /**
+ * Conditionally add the Fault Tolerance annotations
+ *
+ * @param compilationUnit
+ *
+ */
+ protected void manageFaultTolerance(CompilationUnit compilationUnit) {
+ if (isFaultToleranceEnabled(context())) {
+ if (!isTransactionEnabled(this, context())) {
+ throw new ProcessCodegenException("Fault tolerance is enabled,
but transactions are disabled. Please enable transactions before fault
tolerance.");
+ }
+ FaultToleranceAnnotator annotator =
lookFaultToleranceAnnotatorForContext(context());
+ getRestMethods(compilationUnit)
+ .forEach(annotator::addFaultToleranceAnnotations);
+ }
+ }
+
+ /**
+ * Retrieves all the <b>Rest endpoint</b> <code>MethodDeclaration</code>s
from the given
+ * <code>CompilationUnit</code>
+ *
+ * @param compilationUnit
+ * @return
+ */
+ protected Collection<MethodDeclaration> getRestMethods(CompilationUnit
compilationUnit) {
+ RestAnnotator restAnnotator = context().getRestAnnotator();
+ return compilationUnit.findAll(MethodDeclaration.class)
+ .stream()
+ .filter(restAnnotator::isRestAnnotated)
+ .toList();
+ }
+
public GeneratedFile generateProducer() {
String packageName = context().getPackageName();
CompilationUnit compilationUnit =
producerTemplateGenerator.compilationUnitOrThrow("No producer template found
for user tasks");
diff --git
a/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/ProcessResourceGeneratorTest.java
b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/ProcessResourceGeneratorTest.java
index 551d5b48b5..3babba7116 100644
---
a/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/ProcessResourceGeneratorTest.java
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/ProcessResourceGeneratorTest.java
@@ -20,7 +20,6 @@ package org.kie.kogito.codegen.process;
import java.io.File;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
@@ -36,8 +35,8 @@ import org.kie.api.definition.process.Process;
import org.kie.kogito.codegen.api.AddonsConfig;
import org.kie.kogito.codegen.api.context.KogitoBuildContext;
import org.kie.kogito.codegen.api.context.impl.JavaKogitoBuildContext;
-import org.kie.kogito.codegen.process.util.CodegenUtil;
-import org.kie.kogito.codegen.usertask.UserTaskCodegen;
+import org.kie.kogito.codegen.faultTolerance.FaultToleranceAnnotator;
+import org.kie.kogito.codegen.faultTolerance.FaultToleranceUtil;
import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess;
import com.github.javaparser.StaticJavaParser;
@@ -50,11 +49,10 @@ import com.github.javaparser.ast.expr.MemberValuePair;
import com.github.javaparser.ast.expr.NormalAnnotationExpr;
import com.github.javaparser.ast.expr.StringLiteralExpr;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.assertj.core.api.Assertions.*;
import static
org.kie.kogito.codegen.process.ProcessResourceGenerator.INVALID_CONTEXT_TEMPLATE;
-class ProcessResourceGeneratorTest {
+public class ProcessResourceGeneratorTest {
private static final String SIGNAL_METHOD = "signal_";
private static final List<String> JAVA_AND_QUARKUS_REST_ANNOTATIONS =
List.of("DELETE", "GET", "POST");
@@ -187,10 +185,10 @@ class ProcessResourceGeneratorTest {
KogitoBuildContext kogitoBuildContext = contextBuilder.build();
Collection<MethodDeclaration> restEndpoints =
processResourceGenerator.getRestMethods(compilationUnit);
// before processResourceGenerator.manageTransactional, the annotation
is not there
- testTransaction(restEndpoints, kogitoBuildContext, false);
+ testTransactionAnnotationIsPresent(restEndpoints, kogitoBuildContext,
false);
processResourceGenerator.manageTransactional(compilationUnit);
- // the annotation is (conditionally) add after
processResourceGenerator.manageTransactional
- testTransaction(restEndpoints, kogitoBuildContext, transactionEnabled);
+ // the annotation is (conditionally) added after
processResourceGenerator.manageTransactional
+ testTransactionAnnotationIsPresent(restEndpoints, kogitoBuildContext,
transactionEnabled);
}
@ParameterizedTest
@@ -206,82 +204,80 @@ class ProcessResourceGeneratorTest {
KogitoBuildContext kogitoBuildContext = contextBuilder.build();
Collection<MethodDeclaration> restEndpoints =
processResourceGenerator.getRestMethods(compilationUnit);
// before processResourceGenerator.manageTransactional, the annotation
is not there
- testTransaction(restEndpoints, kogitoBuildContext, false);
+ testTransactionAnnotationIsPresent(restEndpoints, kogitoBuildContext,
false);
processResourceGenerator.manageTransactional(compilationUnit);
- // the annotation is (conditionally) add after
processResourceGenerator.manageTransactional
- testTransaction(restEndpoints, kogitoBuildContext, transactionEnabled);
+ // the annotation is (conditionally) added after
processResourceGenerator.manageTransactional
+ testTransactionAnnotationIsPresent(restEndpoints, kogitoBuildContext,
transactionEnabled);
}
@ParameterizedTest
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
- void
testUserTaskManageTransactionalEnabledByDefault(KogitoBuildContext.Builder
contextBuilder) {
- KogitoBuildContext context = contextBuilder.build();
- UserTaskCodegen userTaskCodegen = new UserTaskCodegen(context,
Collections.emptyList());
- CompilationUnit compilationUnit = StaticJavaParser.parse(new
String(userTaskCodegen.generateRestEndpiont().contents()));
- List<MethodDeclaration> restEndpoints =
compilationUnit.findAll(MethodDeclaration.class).stream().filter(MethodDeclaration::isPublic).toList();
- assertThat(restEndpoints).isNotEmpty();
- for (MethodDeclaration method : restEndpoints) {
- assertThat(findAnnotationExpr(method,
context.getDependencyInjectionAnnotator().getTransactionalAnnotation())).isPresent();
- }
- }
+ void
testProcessRestResourceGenerationWithFaultToleranceDisabled(KogitoBuildContext.Builder
contextBuilder) {
+ String fileName =
"src/test/resources/startsignal/StartSignalEventNoPayload.bpmn2";
+ ProcessResourceGenerator processResourceGenerator =
getProcessResourceGenerator(contextBuilder, fileName, false, false);
+ CompilationUnit compilationUnit =
+
processResourceGenerator.createCompilationUnit(processResourceGenerator.createTemplatedGeneratorBuilder());
+ assertThat(compilationUnit).isNotNull();
- @ParameterizedTest
-
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
- void testUserTaskManageTransactionalDisabled(KogitoBuildContext.Builder
contextBuilder) {
KogitoBuildContext context = contextBuilder.build();
- UserTaskCodegen userTaskCodegen = new UserTaskCodegen(context,
Collections.emptyList());
-
context.setApplicationProperty(CodegenUtil.generatorProperty(userTaskCodegen,
CodegenUtil.TRANSACTION_ENABLED), "false");
- CompilationUnit compilationUnit = StaticJavaParser.parse(new
String(userTaskCodegen.generateRestEndpiont().contents()));
- List<MethodDeclaration> restEndpoints =
compilationUnit.findAll(MethodDeclaration.class).stream().filter(MethodDeclaration::isPublic).toList();
- assertThat(restEndpoints).isNotEmpty();
- for (MethodDeclaration method : restEndpoints) {
- assertThat(findAnnotationExpr(method,
context.getDependencyInjectionAnnotator().getTransactionalAnnotation())).isEmpty();
- }
+ Collection<MethodDeclaration> restEndpoints =
processResourceGenerator.getRestMethods(compilationUnit);
+
+ // before processResourceGenerator.manageFaultTolerance, the
annotation is not there
+ testFaultToleranceAnnotationIsPresent(restEndpoints, context, false);
+
+ processResourceGenerator.manageFaultTolerance(compilationUnit);
+ // the annotation is (conditionally) added after
processResourceGenerator.manageFaultTolerance
+ testFaultToleranceAnnotationIsPresent(restEndpoints, context, false);
}
@ParameterizedTest
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
- void
testUserTaskManageTransactionalGeneratorDisabled(KogitoBuildContext.Builder
contextBuilder) {
+ void
testProcessRestResourceGenerationWithFaultToleranceEnabled(KogitoBuildContext.Builder
contextBuilder) {
+ String fileName =
"src/test/resources/startsignal/StartSignalEventNoPayload.bpmn2";
+ ProcessResourceGenerator processResourceGenerator =
getProcessResourceGenerator(contextBuilder, fileName, true, true);
+ CompilationUnit compilationUnit =
+
processResourceGenerator.createCompilationUnit(processResourceGenerator.createTemplatedGeneratorBuilder());
+ assertThat(compilationUnit).isNotNull();
+
KogitoBuildContext context = contextBuilder.build();
- UserTaskCodegen userTaskCodegen = new UserTaskCodegen(context,
Collections.emptyList());
-
context.setApplicationProperty(CodegenUtil.generatorProperty(userTaskCodegen,
CodegenUtil.TRANSACTION_ENABLED), "false");
- CompilationUnit compilationUnit = StaticJavaParser.parse(new
String(userTaskCodegen.generateRestEndpiont().contents()));
- List<MethodDeclaration> restEndpoints =
compilationUnit.findAll(MethodDeclaration.class).stream().filter(MethodDeclaration::isPublic).toList();
- assertThat(restEndpoints).isNotEmpty();
- for (MethodDeclaration method : restEndpoints) {
- assertThat(findAnnotationExpr(method,
context.getDependencyInjectionAnnotator().getTransactionalAnnotation())).isEmpty();
- }
+ Collection<MethodDeclaration> restEndpoints =
processResourceGenerator.getRestMethods(compilationUnit);
+
+ // before processResourceGenerator.manageFaultTolerance, the
annotation is not there
+ testFaultToleranceAnnotationIsPresent(restEndpoints, context, false);
+
+ processResourceGenerator.manageFaultTolerance(compilationUnit);
+ // the annotation is (conditionally) added after
processResourceGenerator.manageFaultTolerance
+ testFaultToleranceAnnotationIsPresent(restEndpoints, context, true);
}
@ParameterizedTest
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
- void testUserTaskManageTransactionalEnabled(KogitoBuildContext.Builder
contextBuilder) {
- KogitoBuildContext context = contextBuilder.build();
- UserTaskCodegen userTaskCodegen = new UserTaskCodegen(context,
Collections.emptyList());
-
context.setApplicationProperty(CodegenUtil.generatorProperty(userTaskCodegen,
CodegenUtil.TRANSACTION_ENABLED), "true");
- CompilationUnit compilationUnit = StaticJavaParser.parse(new
String(userTaskCodegen.generateRestEndpiont().contents()));
- List<MethodDeclaration> restEndpoints =
compilationUnit.findAll(MethodDeclaration.class).stream().filter(MethodDeclaration::isPublic).toList();
- assertThat(restEndpoints).isNotEmpty();
- for (MethodDeclaration method : restEndpoints) {
- assertThat(findAnnotationExpr(method,
context.getDependencyInjectionAnnotator().getTransactionalAnnotation())).isPresent();
- }
+ void
testProcessRestResourceGenerationWithFaultToleranceEnabledWithTransactionsDisabled(KogitoBuildContext.Builder
contextBuilder) {
+ String fileName =
"src/test/resources/startsignal/StartSignalEventNoPayload.bpmn2";
+ ProcessResourceGenerator processResourceGenerator =
getProcessResourceGenerator(contextBuilder, fileName, false, true);
+ CompilationUnit compilationUnit =
+
processResourceGenerator.createCompilationUnit(processResourceGenerator.createTemplatedGeneratorBuilder());
+ assertThat(compilationUnit).isNotNull();
+
+ assertThatThrownBy(() -> {
+ processResourceGenerator.manageFaultTolerance(compilationUnit);
+ }).isInstanceOf(ProcessCodegenException.class)
+ .hasMessageContaining("Fault tolerance is enabled, but
transactions are disabled. Please enable transactions before fault tolerance.");
}
- @ParameterizedTest
-
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
- void
testUserTaskManageTransactionalGeneratorEnabled(KogitoBuildContext.Builder
contextBuilder) {
- KogitoBuildContext context = contextBuilder.build();
- UserTaskCodegen userTaskCodegen = new UserTaskCodegen(context,
Collections.emptyList());
-
context.setApplicationProperty(CodegenUtil.generatorProperty(userTaskCodegen,
CodegenUtil.TRANSACTION_ENABLED), "true");
- CompilationUnit compilationUnit = StaticJavaParser.parse(new
String(userTaskCodegen.generateRestEndpiont().contents()));
- List<MethodDeclaration> restEndpoints =
compilationUnit.findAll(MethodDeclaration.class).stream().filter(MethodDeclaration::isPublic).toList();
- assertThat(restEndpoints).isNotEmpty();
+ public static void
testFaultToleranceAnnotationIsPresent(Collection<MethodDeclaration>
restEndpoints, KogitoBuildContext context, boolean shouldAnnotationBeThere) {
+ FaultToleranceAnnotator faultToleranceAnnotator =
FaultToleranceUtil.lookFaultToleranceAnnotatorForContext(context);
+
for (MethodDeclaration method : restEndpoints) {
- assertThat(findAnnotationExpr(method,
context.getDependencyInjectionAnnotator().getTransactionalAnnotation())).isPresent();
+ if (shouldAnnotationBeThere) {
+ assertThat(findAnnotationExpr(method,
faultToleranceAnnotator.getRetryAnnotationName())).isPresent();
+ } else {
+ assertThat(findAnnotationExpr(method,
faultToleranceAnnotator.getRetryAnnotationName())).isNotPresent();
+ }
}
}
- Optional<AnnotationExpr> findAnnotationExpr(MethodDeclaration method,
String fqn) {
+ public static Optional<AnnotationExpr>
findAnnotationExpr(MethodDeclaration method, String fqn) {
for (AnnotationExpr expr : method.getAnnotations()) {
if (expr.getNameAsString().equals(fqn)) {
return Optional.of(expr);
@@ -290,7 +286,7 @@ class ProcessResourceGeneratorTest {
return Optional.empty();
}
- void testTransaction(Collection<MethodDeclaration> restEndpoints,
+ public static void
testTransactionAnnotationIsPresent(Collection<MethodDeclaration> restEndpoints,
KogitoBuildContext kogitoBuildContext,
boolean enabled) {
String transactionalAnnotation =
@@ -331,18 +327,24 @@ class ProcessResourceGeneratorTest {
private CompilationUnit getCompilationUnit(KogitoBuildContext.Builder
contextBuilder,
KogitoWorkflowProcess process) {
- ProcessResourceGenerator processResourceGenerator =
getProcessResourceGenerator(contextBuilder, process, true);
+ ProcessResourceGenerator processResourceGenerator =
getProcessResourceGenerator(contextBuilder, process, true, false);
return StaticJavaParser.parse(processResourceGenerator.generate());
}
private ProcessResourceGenerator
getProcessResourceGenerator(KogitoBuildContext.Builder contextBuilder,
String fileName, boolean withTransaction) {
- return getProcessResourceGenerator(contextBuilder,
parseProcess(fileName), withTransaction);
+ return getProcessResourceGenerator(contextBuilder,
parseProcess(fileName), withTransaction, false);
+ }
+
+ private ProcessResourceGenerator
getProcessResourceGenerator(KogitoBuildContext.Builder contextBuilder,
+ String fileName, boolean withTransaction, boolean
wihtFaultTolerance) {
+ return getProcessResourceGenerator(contextBuilder,
parseProcess(fileName), withTransaction, wihtFaultTolerance);
}
private ProcessResourceGenerator
getProcessResourceGenerator(KogitoBuildContext.Builder contextBuilder,
KogitoWorkflowProcess process,
- boolean withTransaction) {
+ boolean withTransaction,
+ boolean withFaultTolerance) {
KogitoBuildContext context = createContext(contextBuilder);
ProcessExecutableModelGenerator execModelGen =
@@ -361,7 +363,8 @@ class ProcessResourceGeneratorTest {
toReturn
.withSignals(metaData.getSignals())
.withTriggers(metaData.isStartable(), metaData.isDynamic(),
metaData.getTriggers())
- .withTransaction(withTransaction);
+ .withTransaction(withTransaction)
+ .withFaultTolerance(withFaultTolerance);
return toReturn;
}
diff --git
a/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/usertask/UserTaskCodegenTest.java
b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/usertask/UserTaskCodegenTest.java
new file mode 100644
index 0000000000..2aa3ad45e4
--- /dev/null
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/usertask/UserTaskCodegenTest.java
@@ -0,0 +1,154 @@
+/*
+ * 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.kie.kogito.codegen.usertask;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.stream.Collectors;
+
+import org.drools.codegen.common.rest.RestAnnotator;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.kie.kogito.codegen.api.context.KogitoBuildContext;
+import org.kie.kogito.codegen.process.ProcessCodegenException;
+import org.kie.kogito.codegen.process.util.CodegenUtil;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+
+import static java.util.Collections.emptyList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.kie.kogito.codegen.process.ProcessResourceGeneratorTest.*;
+
+public class UserTaskCodegenTest {
+
+ @ParameterizedTest
+
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
+ void
testUserTaskManageTransactionalEnabledByDefault(KogitoBuildContext.Builder
contextBuilder) {
+ KogitoBuildContext context = contextBuilder.build();
+ UserTaskCodegen userTaskCodegen = new UserTaskCodegen(context,
Collections.emptyList());
+ CompilationUnit compilationUnit =
userTaskCodegen.createRestEndpointCompilationUnit();
+
+ Collection<MethodDeclaration> restEndpoints =
getRestMethods(compilationUnit, context);
+ assertThat(restEndpoints).isNotEmpty();
+
+ testTransactionAnnotationIsPresent(restEndpoints, context, false);
+
+ userTaskCodegen.manageTransactional(compilationUnit);
+
+ testTransactionAnnotationIsPresent(restEndpoints, context, true);
+ }
+
+ @ParameterizedTest
+
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
+ void testUserTaskManageTransactionalDisabled(KogitoBuildContext.Builder
contextBuilder) {
+ KogitoBuildContext context = contextBuilder.build();
+ UserTaskCodegen userTaskCodegen = new UserTaskCodegen(context,
Collections.emptyList());
+
context.setApplicationProperty(CodegenUtil.globalProperty(CodegenUtil.TRANSACTION_ENABLED),
"false");
+
+ CompilationUnit compilationUnit =
userTaskCodegen.createRestEndpointCompilationUnit();
+
+ Collection<MethodDeclaration> restEndpoints =
getRestMethods(compilationUnit, context);
+ assertThat(restEndpoints).isNotEmpty();
+
+ testTransactionAnnotationIsPresent(restEndpoints, context, false);
+
+ userTaskCodegen.manageTransactional(compilationUnit);
+
+ testTransactionAnnotationIsPresent(restEndpoints, context, false);
+ }
+
+ @ParameterizedTest
+
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
+ void testUserTaskManageTransactionalEnabled(KogitoBuildContext.Builder
contextBuilder) {
+ KogitoBuildContext context = contextBuilder.build();
+ UserTaskCodegen userTaskCodegen = new UserTaskCodegen(context,
Collections.emptyList());
+
context.setApplicationProperty(CodegenUtil.globalProperty(CodegenUtil.TRANSACTION_ENABLED),
"true");
+ CompilationUnit compilationUnit =
userTaskCodegen.createRestEndpointCompilationUnit();
+
+ Collection<MethodDeclaration> restEndpoints =
getRestMethods(compilationUnit, context);
+ assertThat(restEndpoints).isNotEmpty();
+
+ testTransactionAnnotationIsPresent(restEndpoints, context, false);
+
+ userTaskCodegen.manageTransactional(compilationUnit);
+
+ testTransactionAnnotationIsPresent(restEndpoints, context, true);
+ }
+
+ @ParameterizedTest
+
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
+ void testUserTaskFaultToleranceDisabled(KogitoBuildContext.Builder
contextBuilder) {
+ KogitoBuildContext context = contextBuilder.build();
+ UserTaskCodegen userTaskCodegen = new UserTaskCodegen(context,
Collections.emptyList());
+
context.setApplicationProperty(CodegenUtil.globalProperty(CodegenUtil.FAULT_TOLERANCE_ENABLED),
"false");
+ CompilationUnit compilationUnit =
userTaskCodegen.createRestEndpointCompilationUnit();
+
+ Collection<MethodDeclaration> restEndpoints =
getRestMethods(compilationUnit, context);
+ assertThat(restEndpoints).isNotEmpty();
+
+ testFaultToleranceAnnotationIsPresent(restEndpoints, context, false);
+
+ userTaskCodegen.manageFaultTolerance(compilationUnit);
+
+ testFaultToleranceAnnotationIsPresent(restEndpoints, context, false);
+ }
+
+ @ParameterizedTest
+
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
+ void testUserTaskFaultToleranceEnabled(KogitoBuildContext.Builder
contextBuilder) {
+ KogitoBuildContext context = contextBuilder.build();
+ UserTaskCodegen userTaskCodegen = new UserTaskCodegen(context,
Collections.emptyList());
+ CompilationUnit compilationUnit =
userTaskCodegen.createRestEndpointCompilationUnit();
+
+ Collection<MethodDeclaration> restEndpoints =
getRestMethods(compilationUnit, context);
+ assertThat(restEndpoints).isNotEmpty();
+
+ testFaultToleranceAnnotationIsPresent(restEndpoints, context, false);
+
+ userTaskCodegen.manageFaultTolerance(compilationUnit);
+
+ testFaultToleranceAnnotationIsPresent(restEndpoints, context, true);
+ }
+
+ @ParameterizedTest
+
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
+ void
testUserTaskFaultToleranceEnabledWithTransactionsDisabled(KogitoBuildContext.Builder
contextBuilder) {
+ KogitoBuildContext context = contextBuilder.build();
+
context.setApplicationProperty(CodegenUtil.globalProperty(CodegenUtil.TRANSACTION_ENABLED),
"false");
+
+ UserTaskCodegen userTaskCodegen = new UserTaskCodegen(context,
Collections.emptyList());
+
+ CompilationUnit compilationUnit =
userTaskCodegen.createRestEndpointCompilationUnit();
+
+ assertThatThrownBy(() -> {
+ userTaskCodegen.manageFaultTolerance(compilationUnit);
+ }).isInstanceOf(ProcessCodegenException.class)
+ .hasMessageContaining("Fault tolerance is enabled, but
transactions are disabled. Please enable transactions before fault tolerance.");
+ }
+
+ protected Collection<MethodDeclaration> getRestMethods(CompilationUnit
compilationUnit, KogitoBuildContext context) {
+ RestAnnotator restAnnotator = context.getRestAnnotator();
+ return compilationUnit.findAll(MethodDeclaration.class).stream()
+ .filter(restAnnotator::isRestAnnotated)
+ .collect(Collectors.toList());
+ }
+}
diff --git
a/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/main/java/org/kie/kogito/quarkus/common/deployment/KogitoAssetsProcessor.java
b/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/main/java/org/kie/kogito/quarkus/common/deployment/KogitoAssetsProcessor.java
index 346a0f5a40..8dd96912d9 100644
---
a/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/main/java/org/kie/kogito/quarkus/common/deployment/KogitoAssetsProcessor.java
+++
b/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/main/java/org/kie/kogito/quarkus/common/deployment/KogitoAssetsProcessor.java
@@ -80,6 +80,7 @@ import static
org.drools.codegen.common.GeneratedFileType.COMPILED_CLASS;
import static
org.drools.quarkus.util.deployment.DroolsQuarkusResourceUtils.compileGeneratedSources;
import static
org.drools.quarkus.util.deployment.DroolsQuarkusResourceUtils.makeBuildItems;
import static
org.kie.efesto.common.api.constants.Constants.INDEXFILE_DIRECTORY_PROPERTY;
+import static
org.kie.kogito.codegen.api.context.ContextAttributesConstants.KOGITO_FAULT_TOLERANCE_ENABLED;
import static
org.kie.kogito.quarkus.common.deployment.KogitoQuarkusResourceUtils.HOT_RELOAD_SUPPORT_PATH;
import static
org.kie.kogito.quarkus.common.deployment.KogitoQuarkusResourceUtils.dumpFilesToDisk;
import static
org.kie.kogito.quarkus.common.deployment.KogitoQuarkusResourceUtils.getHotReloadSupportSource;
@@ -278,6 +279,13 @@ public class KogitoAssetsProcessor {
if (!hasRestCapabilities && kogitoGenerateRest(context).orElse(true)) {
throw new MissingRestCapabilityException();
}
+
+ // disable Fault Tolerance if SmallRye Fault Tolerance extension is
not available (user can override via property)
+ if (!capabilities.isPresent(Capability.SMALLRYE_FAULT_TOLERANCE)) {
+ context.setApplicationProperty(KOGITO_FAULT_TOLERANCE_ENABLED,
"false");
+ LOGGER.info("Disabling Kogito Fault Tolerance because SmallRye
Fault Tolerance extension is not available");
+ }
+
}
private Optional<Boolean> kogitoGenerateRest(KogitoBuildContext context) {
diff --git
a/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes-deployment/pom.xml
b/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes-deployment/pom.xml
index b1f2fef2c0..0ec1d2bfc4 100644
---
a/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes-deployment/pom.xml
+++
b/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes-deployment/pom.xml
@@ -49,6 +49,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-narayana-jta-deployment</artifactId>
</dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-smallrye-fault-tolerance-deployment</artifactId>
+ </dependency>
<!-- test -->
<dependency>
<groupId>io.quarkus</groupId>
diff --git
a/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes-deployment/src/main/java/org/kie/kogito/quarkus/processes/deployment/FaultToleranceProcessor.java
b/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes-deployment/src/main/java/org/kie/kogito/quarkus/processes/deployment/FaultToleranceProcessor.java
new file mode 100644
index 0000000000..c3a1d49d34
--- /dev/null
+++
b/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes-deployment/src/main/java/org/kie/kogito/quarkus/processes/deployment/FaultToleranceProcessor.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.kie.kogito.quarkus.processes.deployment;
+
+import java.util.function.BooleanSupplier;
+
+import org.eclipse.microprofile.config.ConfigProvider;
+
+import io.quarkus.deployment.Capabilities;
+import io.quarkus.deployment.Capability;
+import io.quarkus.deployment.annotations.BuildProducer;
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.builditem.SystemPropertyBuildItem;
+
+import jakarta.interceptor.Interceptor;
+
+import static
org.kie.kogito.codegen.api.context.ContextAttributesConstants.KOGITO_FAULT_TOLERANCE_ENABLED;
+
+public class FaultToleranceProcessor {
+
+ public static class IsFaultToleranceEnabled implements BooleanSupplier {
+ @Override
+ public boolean getAsBoolean() {
+ return
ConfigProvider.getConfig().getOptionalValue(KOGITO_FAULT_TOLERANCE_ENABLED,
Boolean.class).orElse(true);
+ }
+ }
+
+ @BuildStep(onlyIf = IsFaultToleranceEnabled.class)
+ public void setupKogitoFaultTolerance(
+ BuildProducer<SystemPropertyBuildItem> systemProperties,
+ Capabilities capabilities) {
+
+ if (capabilities.isPresent(Capability.SMALLRYE_FAULT_TOLERANCE)) {
+ systemProperties.produce(new
SystemPropertyBuildItem("mp.fault.tolerance.interceptor.priority",
String.valueOf(Interceptor.Priority.PLATFORM_BEFORE + 100)));
+ }
+ }
+}
diff --git
a/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes/pom.xml
b/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes/pom.xml
index 94220228ad..e3aaeb3909 100644
---
a/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes/pom.xml
+++
b/quarkus/extensions/kogito-quarkus-processes-extension/kogito-quarkus-processes/pom.xml
@@ -60,6 +60,10 @@
<groupId>org.eclipse.microprofile.openapi</groupId>
<artifactId>microprofile-openapi-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-smallrye-fault-tolerance</artifactId>
+ </dependency>
</dependencies>
<build>
diff --git a/springboot/starters/kogito-processes-spring-boot-starter/pom.xml
b/springboot/starters/kogito-processes-spring-boot-starter/pom.xml
index cd9817e03e..637e0f6f9c 100644
--- a/springboot/starters/kogito-processes-spring-boot-starter/pom.xml
+++ b/springboot/starters/kogito-processes-spring-boot-starter/pom.xml
@@ -60,6 +60,10 @@
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
+ <dependency>
+ <groupId>io.github.resilience4j</groupId>
+ <artifactId>resilience4j-spring-boot3</artifactId>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]