Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[incubator-kie-issues#1473] Introduce Transactional annotation, conditionally deleted #3671

Merged
merged 27 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
40313da
[incubator-kie-issues#1473] WIP - Implemented transactional imports a…
Sep 17, 2024
5b54d4e
Merge remote-tracking branch 'origin/main' into incubator-kie-issues#…
Sep 18, 2024
5875d51
[incubator-kie-issues#1473] Simplified following suggestions.
Sep 18, 2024
da675e1
[incubator-kie-issues#1473] Implemented KogitoContextTestUtils#restCo…
Sep 18, 2024
8102962
[incubator-kie-issues#1473] Set log level to debug inside manageTrans…
Sep 18, 2024
cfa7584
[incubator-kie-issues#1473] Add spring-tx dependency to jbpm-spring-b…
Sep 18, 2024
6f7a76e
[incubator-kie-issues#1473] Add quarkus-narayana-jta dependency to ko…
Sep 19, 2024
dae9508
Merge remote-tracking branch 'origin/main' into incubator-kie-issues#…
Sep 23, 2024
078e758
[incubator-kie-issues#1473] Add quarkus-narayana-jta-deployment depen…
Sep 23, 2024
1b679f4
Merge remote-tracking branch 'origin/main' into incubator-kie-issues#…
Sep 25, 2024
d4414a5
Merge remote-tracking branch 'origin/main' into incubator-kie-issues#…
Sep 25, 2024
41a42ba
[incubator-kie-issues#1473] Introduce nasty workaround (delay) to avo…
Sep 25, 2024
2534cfa
[incubator-kie-issues#1473] Disabling transaction for sonataflow-quar…
Sep 25, 2024
9fad45d
Merge remote-tracking branch 'origin/main' into incubator-kie-issues#…
Sep 26, 2024
ca99f4f
[incubator-kie-issues#1473] Conditionally add the thread sleep. Fix k…
Sep 26, 2024
5a0d748
[incubator-kie-issues#1473] Importing new wait strategy.
Sep 26, 2024
d128790
Merge remote-tracking branch 'origin/main' into incubator-kie-issues#…
Sep 27, 2024
7805381
[incubator-kie-issues#1473] WIP - Experimenting Thread.join inside tr…
Sep 27, 2024
d8761b6
[incubator-kie-issues#1473] WIP - fix formatting
Sep 27, 2024
aa96611
[incubator-kie-issues#1473] WIP - commented out conditionally exclude…
Sep 30, 2024
9c4d4e7
[incubator-kie-issues#1473] WIP - commented out conditionally exclude…
Sep 30, 2024
9359c55
[incubator-kie-issues#1473] Disabling transaction for serverless
Sep 30, 2024
ac5adfb
Merge remote-tracking branch 'origin/main' into incubator-kie-issues#…
Oct 1, 2024
3ffa165
[incubator-kie-issues#1473] Fix formatting
Oct 1, 2024
2bed966
[incubator-kie-issues#1473] Fix test
Oct 1, 2024
990cbd9
[incubator-kie-issues#1473] Fixed as per PR suggestion. Using context…
Oct 2, 2024
351145f
Merge remote-tracking branch 'origin/main' into incubator-kie-issues#…
Oct 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ public static Stream<Arguments> contextBuilders() {
Arguments.of(SpringBootKogitoBuildContext.builder()));
}

public static Stream<Arguments> restContextBuilders() {
return Stream.of(
Arguments.of(QuarkusKogitoBuildContext.builder()),
Arguments.of(SpringBootKogitoBuildContext.builder()));
}

public static Predicate<String> mockClassAvailabilityResolver(Collection<String> includedClasses, Collection<String> excludedClasses) {
return mockClassAvailabilityResolver(includedClasses, excludedClasses, KogitoContextTestUtils.class.getClassLoader());
}
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
gitgabrio marked this conversation as resolved.
Show resolved Hide resolved
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
Expand All @@ -55,8 +56,6 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,17 @@
import java.util.Optional;
import java.util.function.Predicate;

import org.assertj.core.api.ListAssert;
import org.drools.io.FileSystemResource;
import org.jbpm.compiler.canonical.ProcessMetaData;
import org.jbpm.compiler.canonical.ProcessToExecModelGenerator;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
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.internal.process.runtime.KogitoWorkflowProcess;

import com.github.javaparser.StaticJavaParser;
Expand All @@ -45,14 +48,28 @@
import com.github.javaparser.ast.expr.StringLiteralExpr;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

class ProcessResourceGeneratorTest {

private static final String SIGNAL_METHOD = "signal_";
private static final List<String> JAVA_AND_QUARKUS_REST_ANNOTATIONS = List.of("DELETE", "GET", "POST");
private static final List<String> SPRING_BOOT_REST_ANNOTATIONS = List.of("DeleteMapping", "GetMapping", "PostMapping");
private static final List<String> SPRING_BOOT_REST_ANNOTATIONS = List.of("DeleteMapping", "GetMapping",
"PostMapping");

@Test
void testProcessResourceGeneratorForJava() {
KogitoBuildContext.Builder contextBuilder = JavaKogitoBuildContext.builder();
String fileName = "src/test/resources/startsignal/StartSignalEventNoPayload.bpmn2"; // not relevant
boolean transactionEnabled = true; // not relevant
assertThatThrownBy(() -> getProcessResourceGenerator(contextBuilder, fileName,
transactionEnabled))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("ProcessResourceGenerator can't be used for Java context");
}

@ParameterizedTest
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#contextBuilders")
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
void testGenerateProcessWithDocumentation(KogitoBuildContext.Builder contextBuilder) {
String fileName = "src/test/resources/ProcessWithDocumentation.bpmn";
String expectedSummary = "This is the documentation";
Expand All @@ -62,7 +79,7 @@ void testGenerateProcessWithDocumentation(KogitoBuildContext.Builder contextBuil
}

@ParameterizedTest
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#contextBuilders")
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
void testGenerateProcessWithoutDocumentation(KogitoBuildContext.Builder contextBuilder) {
String fileName = "src/test/resources/ProcessWithoutDocumentation.bpmn";
String expectedSummary = "ProcessWithoutDocumentation";
Expand All @@ -72,7 +89,7 @@ void testGenerateProcessWithoutDocumentation(KogitoBuildContext.Builder contextB
}

@ParameterizedTest
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#contextBuilders")
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
void testGenerateBoundarySignalEventOnTask(KogitoBuildContext.Builder contextBuilder) {
String fileName = "src/test/resources/signalevent/BoundarySignalEventOnTask.bpmn2";

Expand All @@ -88,7 +105,7 @@ void testGenerateBoundarySignalEventOnTask(KogitoBuildContext.Builder contextBui
}

@ParameterizedTest
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#contextBuilders")
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
void testGenerateStartSignalEventStringPayload(KogitoBuildContext.Builder contextBuilder) {
String fileName = "src/test/resources/startsignal/StartSignalEventStringPayload.bpmn2";
String signalName = "start";
Expand Down Expand Up @@ -121,7 +138,7 @@ void testGenerateStartSignalEventStringPayload(KogitoBuildContext.Builder contex
}

@ParameterizedTest
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#contextBuilders")
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
void testGenerateStartSignalEventNoPayload(KogitoBuildContext.Builder contextBuilder) {
String fileName = "src/test/resources/startsignal/StartSignalEventNoPayload.bpmn2";
String signalName = "start";
Expand Down Expand Up @@ -152,31 +169,102 @@ void testGenerateStartSignalEventNoPayload(KogitoBuildContext.Builder contextBui
.forEach(method -> assertMethodOutputModelType(method, outputType));
}

void testOpenApiDocumentation(KogitoBuildContext.Builder contextBuilder, String fileName, String expectedSummary, String expectedDescription) {
@ParameterizedTest
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
void testManageTransactionalEnabled(KogitoBuildContext.Builder contextBuilder) {
String fileName = "src/test/resources/startsignal/StartSignalEventNoPayload.bpmn2";

boolean transactionEnabled = true;
ProcessResourceGenerator processResourceGenerator = getProcessResourceGenerator(contextBuilder, fileName,
transactionEnabled);
CompilationUnit compilationUnit =
processResourceGenerator.createCompilationUnit(processResourceGenerator.createTemplatedGeneratorBuilder());
assertThat(compilationUnit).isNotNull();
KogitoBuildContext kogitoBuildContext = contextBuilder.build();
Collection<MethodDeclaration> restEndpoints = processResourceGenerator.getRestMethods(compilationUnit);
// before processResourceGenerator.manageTransactional, the annotation is not there
testTransaction(restEndpoints, kogitoBuildContext, false);
processResourceGenerator.manageTransactional(compilationUnit);
// the annotation is (conditionally) add after processResourceGenerator.manageTransactional
testTransaction(restEndpoints, kogitoBuildContext, transactionEnabled);
}

@ParameterizedTest
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
void testManageTransactionalDisabled(KogitoBuildContext.Builder contextBuilder) {
String fileName = "src/test/resources/startsignal/StartSignalEventNoPayload.bpmn2";
boolean transactionEnabled = false;
ProcessResourceGenerator processResourceGenerator = getProcessResourceGenerator(contextBuilder, fileName,
transactionEnabled);
CompilationUnit compilationUnit =
processResourceGenerator.createCompilationUnit(processResourceGenerator.createTemplatedGeneratorBuilder());
assertThat(compilationUnit).isNotNull();
KogitoBuildContext kogitoBuildContext = contextBuilder.build();
Collection<MethodDeclaration> restEndpoints = processResourceGenerator.getRestMethods(compilationUnit);
// before processResourceGenerator.manageTransactional, the annotation is not there
testTransaction(restEndpoints, kogitoBuildContext, false);
processResourceGenerator.manageTransactional(compilationUnit);
// the annotation is (conditionally) add after processResourceGenerator.manageTransactional
testTransaction(restEndpoints, kogitoBuildContext, transactionEnabled);
}

void testTransaction(Collection<MethodDeclaration> restEndpoints,
KogitoBuildContext kogitoBuildContext,
boolean enabled) {
String transactionalAnnotation =
kogitoBuildContext.getDependencyInjectionAnnotator().getTransactionalAnnotation();
restEndpoints.forEach(methodDeclaration -> {
ListAssert<?> assertion = assertThat(
methodDeclaration.getAnnotations().stream().filter(annotationExpr -> annotationExpr.getNameAsString().equals(transactionalAnnotation)));
if (enabled) {
assertion.hasSize(1);
} else {
assertion.isEmpty();
}
});
}

void testOpenApiDocumentation(KogitoBuildContext.Builder contextBuilder, String fileName, String expectedSummary,
String expectedDescription) {
ClassOrInterfaceDeclaration classDeclaration = getResourceClassDeclaration(contextBuilder, fileName);

classDeclaration.getMethods().stream()
.filter(this::isRestMethod)
.forEach(method -> assertThatMethodHasOpenApiDocumentation(method, expectedSummary, expectedDescription));
.forEach(method -> assertThatMethodHasOpenApiDocumentation(method, expectedSummary,
expectedDescription));
}

private ClassOrInterfaceDeclaration getResourceClassDeclaration(KogitoBuildContext.Builder contextBuilder, String fileName) {
private ClassOrInterfaceDeclaration getResourceClassDeclaration(KogitoBuildContext.Builder contextBuilder,
String fileName) {
KogitoWorkflowProcess process = parseProcess(fileName);
CompilationUnit compilationUnit = getCompilationUnit(contextBuilder, process);
Optional<ClassOrInterfaceDeclaration> classDeclaration = compilationUnit.getClassByName(process.getId() + "Resource");
Optional<ClassOrInterfaceDeclaration> classDeclaration = compilationUnit.getClassByName(process.getId() +
"Resource");
assertThat(classDeclaration).isNotEmpty();
return classDeclaration.orElseThrow();
}

private CompilationUnit getCompilationUnit(KogitoBuildContext.Builder contextBuilder, KogitoWorkflowProcess process) {
private CompilationUnit getCompilationUnit(KogitoBuildContext.Builder contextBuilder,
KogitoWorkflowProcess process) {
ProcessResourceGenerator processResourceGenerator = getProcessResourceGenerator(contextBuilder, process, true);
return StaticJavaParser.parse(processResourceGenerator.generate());
}

private ProcessResourceGenerator getProcessResourceGenerator(KogitoBuildContext.Builder contextBuilder,
String fileName, boolean withTransaction) {
return getProcessResourceGenerator(contextBuilder, parseProcess(fileName), withTransaction);
}

private ProcessResourceGenerator getProcessResourceGenerator(KogitoBuildContext.Builder contextBuilder,
KogitoWorkflowProcess process,
boolean withTransaction) {
KogitoBuildContext context = createContext(contextBuilder);

ProcessExecutableModelGenerator execModelGen =
new ProcessExecutableModelGenerator(process, new ProcessToExecModelGenerator(context.getClassLoader()));

KogitoWorkflowProcess workFlowProcess = execModelGen.process();

ProcessResourceGenerator processResourceGenerator = new ProcessResourceGenerator(
ProcessResourceGenerator toReturn = new ProcessResourceGenerator(
context,
workFlowProcess,
new ModelClassGenerator(context, workFlowProcess).className(),
Expand All @@ -185,11 +273,11 @@ private CompilationUnit getCompilationUnit(KogitoBuildContext.Builder contextBui

ProcessMetaData metaData = execModelGen.generate();

processResourceGenerator
toReturn
.withSignals(metaData.getSignals())
.withTriggers(metaData.isStartable(), metaData.isDynamic(), metaData.getTriggers());

return StaticJavaParser.parse(processResourceGenerator.generate());
.withTriggers(metaData.isStartable(), metaData.isDynamic(), metaData.getTriggers())
.withTransaction(withTransaction);
return toReturn;
}

private void assertThatMethodHasOpenApiDocumentation(MethodDeclaration method, String summary, String description) {
Expand All @@ -203,7 +291,8 @@ private void assertMethodOutputModelType(MethodDeclaration method, String output
assertThat(method.getType().asString()).isEqualTo(outputType);
}

private void assertThatAnnotationHasSummaryAndDescription(AnnotationExpr annotation, String summary, String description) {
private void assertThatAnnotationHasSummaryAndDescription(AnnotationExpr annotation, String summary,
String description) {
NodeList<MemberValuePair> pairs = ((NormalAnnotationExpr) annotation).getPairs();

assertThat(pairs).containsExactlyInAnyOrder(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public class CodegenMessageStartEventTest {
private static final Path MESSAGE_START_END_EVENT_SOURCE_FULL_SOURCE = BASE_PATH.resolve(MESSAGE_START_END_EVENT_SOURCE);

@ParameterizedTest
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#contextBuilders")
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
public void testRESTApiForMessageStartEvent(KogitoBuildContext.Builder contextBuilder) {

KogitoBuildContext context = contextBuilder.build();
Expand Down Expand Up @@ -80,7 +80,7 @@ public void testRESTApiForMessageStartEvent(KogitoBuildContext.Builder contextBu
}

@ParameterizedTest
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#contextBuilders")
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
public void testRESTApiForMessageEndEvent(KogitoBuildContext.Builder contextBuilder) {

KogitoBuildContext context = contextBuilder.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
<groupId>io.smallrye.reactive</groupId>
<artifactId>smallrye-mutiny-vertx-web-client</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-narayana-jta</artifactId>
</dependency>
<dependency>
<groupId>org.kie.kogito</groupId>
<artifactId>jbpm-deps-group-engine</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
</dependencies>

</project>
Loading