This is an automated email from the ASF dual-hosted git repository.
egonzalez 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 9d37dc2ff4 [incubator-kie-issues-1517] Add Transactional Rest
endpoints to UserTasks (#3701)
9d37dc2ff4 is described below
commit 9d37dc2ff46afd8f244adfb4bf629aa6f6211725
Author: Enrique <[email protected]>
AuthorDate: Mon Oct 14 12:39:15 2024 +0200
[incubator-kie-issues-1517] Add Transactional Rest endpoints to UserTasks
(#3701)
---
.../kie/kogito/codegen/process/ProcessCodegen.java | 9 +-
.../codegen/process/ProcessResourceGenerator.java | 5 -
.../kogito/codegen/process/util/CodegenUtil.java | 105 +++++++++++++++++++++
.../kogito/codegen/usertask/UserTaskCodegen.java | 21 +++--
.../process/ProcessResourceGeneratorTest.java | 81 ++++++++++++++++
5 files changed, 201 insertions(+), 20 deletions(-)
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 86e6bd8053..528a9e081a 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
@@ -62,6 +62,7 @@ import
org.kie.kogito.codegen.core.DashboardGeneratedFileUtils;
import org.kie.kogito.codegen.process.config.ProcessConfigGenerator;
import org.kie.kogito.codegen.process.events.ProcessCloudEventMeta;
import
org.kie.kogito.codegen.process.events.ProcessCloudEventMetaFactoryGenerator;
+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;
@@ -76,7 +77,6 @@ import
com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import static java.lang.String.format;
import static java.util.stream.Collectors.toList;
-import static
org.kie.kogito.codegen.process.ProcessResourceGenerator.TRANSACTION_ENABLED;
import static
org.kie.kogito.grafana.GrafanaConfigurationWriter.buildDashboardName;
import static
org.kie.kogito.grafana.GrafanaConfigurationWriter.generateOperationalDashboard;
import static org.kie.kogito.internal.utils.ConversionUtils.sanitizeClassName;
@@ -369,7 +369,7 @@ public class ProcessCodegen extends AbstractGenerator {
.withWorkItems(processIdToWorkItemModel.get(workFlowProcess.getId()))
.withSignals(metaData.getSignals())
.withTriggers(metaData.isStartable(),
metaData.isDynamic(), metaData.getTriggers())
- .withTransaction(isTransactionEnabled());
+
.withTransaction(CodegenUtil.isTransactionEnabled(this, context()));
rgs.add(processResourceGenerator);
}
@@ -511,11 +511,6 @@ public class ProcessCodegen extends AbstractGenerator {
return generatedFiles;
}
- protected boolean isTransactionEnabled() {
- String processTransactionProperty = String.format("kogito.%s.%s",
GENERATOR_NAME, TRANSACTION_ENABLED);
- return
"true".equalsIgnoreCase(context().getApplicationProperty(processTransactionProperty).orElse("true"));
- }
-
private void storeFile(GeneratedFileType type, String path, String source)
{
if (generatedFiles.stream().anyMatch(f ->
path.equals(f.relativePath()))) {
LOGGER.warn("There's already a generated file named {} to be
compiled. Ignoring.", path);
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 3e2f8765a4..207af9e636 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
@@ -77,11 +77,6 @@ import static
org.kie.kogito.internal.utils.ConversionUtils.sanitizeJavaName;
*/
public class ProcessResourceGenerator {
- /**
- * Flag used to configure transaction enablement. Default to
<code>true</code>
- */
- public static final String TRANSACTION_ENABLED = "transactionEnabled";
-
static final String INVALID_CONTEXT_TEMPLATE = "ProcessResourceGenerator
can't be used for context without Rest %s";
private static final Logger LOG =
LoggerFactory.getLogger(ProcessResourceGenerator.class);
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
new file mode 100644
index 0000000000..658507ca1b
--- /dev/null
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/util/CodegenUtil.java
@@ -0,0 +1,105 @@
+/*
+ * 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.process.util;
+
+import java.util.function.Function;
+
+import org.kie.kogito.codegen.api.Generator;
+import org.kie.kogito.codegen.api.context.KogitoBuildContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class CodegenUtil {
+
+ private static final Logger LOG =
LoggerFactory.getLogger(CodegenUtil.class);
+ /**
+ * Flag used to configure transaction enabling. Default to
<code>true</code>
+ */
+ public static final String TRANSACTION_ENABLED = "transactionEnabled";
+
+ private CodegenUtil() {
+ // do nothing
+ }
+
+ /**
+ * Creates the property for a certain generator.
+ *
+ * @param generator
+ * @param propertyName
+ * @return returns the property for certain generator
+ */
+ public static String generatorProperty(Generator generator, String
propertyName) {
+ return String.format("kogito.%s.%s", generator.name(), propertyName);
+ }
+
+ /**
+ * Creates the property for global application
+ *
+ * @param propertyName
+ * @return
+ */
+ public static String globalProperty(String propertyName) {
+ return String.format("kogito.%s", propertyName);
+ }
+
+ /**
+ * This computes the boolean value of the transaction being enabled based
on the logic specified
+ * the property. Default value it is true
+ *
+ * @see CodegenUtil#getProperty
+ */
+ public static boolean isTransactionEnabled(Generator generator,
KogitoBuildContext context) {
+ boolean propertyValue = getProperty(generator, context,
TRANSACTION_ENABLED, Boolean::parseBoolean, true);
+ LOG.info("trying to compute property {} for generator {} property with
value {}", TRANSACTION_ENABLED, generator.name(), propertyValue);
+ return propertyValue;
+ }
+
+ /**
+ * This method is a generic method to compute certain property of the
given type.
+ * 1. we compute the global property applicable for all the application.
+ * 2. we compute the property only applicable for certain generator.
+ *
+ * @see CodegenUtil#getApplicationProperty
+ * @see CodegenUtil#globalProperty
+ * @see CodegenUtil#generatorProperty
+ */
+ public static <T> T getProperty(Generator generator, KogitoBuildContext
context, String propertyName, Function<String, T> converter, T defaultValue) {
+
+ String generatorProperty = generatorProperty(generator, propertyName);
+ if (isApplicationPropertyDefined(context, generatorProperty)) {
+ return converter.apply(getApplicationProperty(context,
generatorProperty));
+ }
+
+ String globalProperty = globalProperty(propertyName);
+
+ if (isApplicationPropertyDefined(context, globalProperty)) {
+ return converter.apply(getApplicationProperty(context,
globalProperty));
+ }
+
+ return defaultValue;
+ }
+
+ private static boolean isApplicationPropertyDefined(KogitoBuildContext
context, String property) {
+ return context.getApplicationProperty(property).isPresent();
+ }
+
+ private static String getApplicationProperty(KogitoBuildContext context,
String property) {
+ return context.getApplicationProperty(property).orElseThrow(() -> new
IllegalArgumentException("Property " + property + " defined but does not
contain proper value"));
+ }
+}
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 bd10069d47..c145c332ee 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
@@ -51,6 +51,7 @@ import org.kie.kogito.codegen.api.template.TemplatedGenerator;
import org.kie.kogito.codegen.core.AbstractGenerator;
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;
@@ -62,6 +63,7 @@ import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.expr.CastExpr;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.IntegerLiteralExpr;
@@ -97,9 +99,9 @@ public class UserTaskCodegen extends AbstractGenerator {
BPMN_SEMANTIC_MODULES.addSemanticModule(new BPMNDISemanticModule());
}
- public static final String SECTION_CLASS_NAME = "usertask";
+ public static final String SECTION_CLASS_NAME = "usertasks";
- TemplatedGenerator templateGenerator;
+ private TemplatedGenerator templateGenerator;
private List<Work> descriptors;
private TemplatedGenerator producerTemplateGenerator;
private TemplatedGenerator restTemplateGenerator;
@@ -158,25 +160,28 @@ public class UserTaskCodegen extends AbstractGenerator {
return generatedFiles;
}
- private GeneratedFile generateRestEndpiont() {
+ public GeneratedFile generateRestEndpiont() {
String packageName = context().getPackageName();
- CompilationUnit compilationUnit =
producerTemplateGenerator.compilationUnitOrThrow("Not rest endpoints template
found for user tasks");
+ CompilationUnit compilationUnit =
restTemplateGenerator.compilationUnitOrThrow("Not rest endpoints template found
for user tasks");
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();
String urlBase = packageName.replaceAll("\\.", File.separator);
- return new GeneratedFile(GeneratedFileType.SOURCE,
Path.of(urlBase).resolve(className + ".java"), compilationUnit.toString());
+ return new GeneratedFile(GeneratedFileType.REST,
Path.of(urlBase).resolve(className + ".java"), compilationUnit.toString());
}
- private GeneratedFile generateProducer() {
+ public GeneratedFile generateProducer() {
String packageName = context().getPackageName();
- CompilationUnit compilationUnit =
restTemplateGenerator.compilationUnitOrThrow("No producer template found for
user tasks");
+ CompilationUnit compilationUnit =
producerTemplateGenerator.compilationUnitOrThrow("No producer template found
for user tasks");
compilationUnit.setPackageDeclaration(packageName);
String className =
compilationUnit.findFirst(ClassOrInterfaceDeclaration.class).get().getNameAsString();
String urlBase = packageName.replaceAll("\\.", File.separator);
return new GeneratedFile(GeneratedFileType.SOURCE,
Path.of(urlBase).resolve(className + ".java"), compilationUnit.toString());
}
- private List<GeneratedFile> generateUserTask() {
+ public List<GeneratedFile> generateUserTask() {
List<GeneratedFile> generatedFiles = new ArrayList<>();
for (Work info : descriptors) {
CompilationUnit unit = templateGenerator.compilationUnit().get();
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 52d1665166..551d5b48b5 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,6 +20,7 @@ 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;
@@ -35,6 +36,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.internal.process.runtime.KogitoWorkflowProcess;
import com.github.javaparser.StaticJavaParser;
@@ -209,6 +212,84 @@ class ProcessResourceGeneratorTest {
testTransaction(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();
+ }
+ }
+
+ @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();
+ }
+ }
+
+ @ParameterizedTest
+
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
+ void
testUserTaskManageTransactionalGeneratorDisabled(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();
+ }
+ }
+
+ @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();
+ }
+ }
+
+ @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();
+ for (MethodDeclaration method : restEndpoints) {
+ assertThat(findAnnotationExpr(method,
context.getDependencyInjectionAnnotator().getTransactionalAnnotation())).isPresent();
+ }
+ }
+
+ Optional<AnnotationExpr> findAnnotationExpr(MethodDeclaration method,
String fqn) {
+ for (AnnotationExpr expr : method.getAnnotations()) {
+ if (expr.getNameAsString().equals(fqn)) {
+ return Optional.of(expr);
+ }
+ }
+ return Optional.empty();
+ }
+
void testTransaction(Collection<MethodDeclaration> restEndpoints,
KogitoBuildContext kogitoBuildContext,
boolean enabled) {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]