Skip to content

Commit

Permalink
[DROOLS-7555] move automatic rest endpoints generation from Kogito to…
Browse files Browse the repository at this point in the history
… Drools (apache#5548)

* [DROOLS-7555] move automatic rest endpoints generation from Kogito to Drools

* wip
  • Loading branch information
mariofusco authored and rgdoliveira committed Dec 13, 2023
1 parent e1c2c53 commit 878850c
Show file tree
Hide file tree
Showing 50 changed files with 2,379 additions and 294 deletions.
27 changes: 23 additions & 4 deletions drools-drl-quarkus-extension/drools-drl-quarkus-deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@
<groupId>org.drools</groupId>
<artifactId>drools-model-codegen</artifactId>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-drl-map-input-runtime</artifactId>
</dependency>

<!-- quarkus -->
<dependency>
Expand All @@ -84,6 +80,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-spi-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-http-deployment-spi</artifactId>
Expand Down Expand Up @@ -149,6 +149,25 @@
</systemPropertyVariables>
</configuration>
</plugin>

<!-- quarkus-resteasy brings in a couple of dependencies in the javax.* namespace that cannot be excluded -->
<!-- that's why it is necessary to disable the plugin that checks for banned dependencies -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>ban-blacklisted-dependencies</id>
<phase>validate</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<fail>false</fail>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,19 @@
*/
package org.drools.drl.quarkus.deployment;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import javax.inject.Inject;

import io.quarkus.arc.deployment.GeneratedBeanBuildItem;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.Produce;
import io.quarkus.deployment.builditem.ArchiveRootBuildItem;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.GeneratedResourceBuildItem;
import io.quarkus.deployment.builditem.LiveReloadBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.pkg.builditem.ArtifactResultBuildItem;
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem;
import io.quarkus.maven.dependency.ResolvedDependency;
import io.quarkus.resteasy.reactive.spi.GeneratedJaxRsResourceBuildItem;
import io.quarkus.vertx.http.deployment.spi.AdditionalStaticResourceBuildItem;
import org.drools.codegen.common.DroolsModelBuildContext;
import org.drools.codegen.common.GeneratedFile;
Expand All @@ -53,17 +41,22 @@
import org.drools.model.codegen.execmodel.PackageModel;
import org.drools.model.codegen.project.RuleCodegen;
import org.kie.api.io.Resource;
import org.kie.drl.engine.runtime.mapinput.service.KieRuntimeServiceDrlMapInput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;

import static org.drools.drl.quarkus.util.deployment.DroolsQuarkusResourceUtils.HOT_RELOAD_SUPPORT_PATH;
import static org.drools.drl.quarkus.util.deployment.DroolsQuarkusResourceUtils.compileGeneratedSources;
import static org.drools.drl.quarkus.util.deployment.DroolsQuarkusResourceUtils.createDroolsBuildContext;
import static org.drools.drl.quarkus.util.deployment.DroolsQuarkusResourceUtils.dumpFilesToDisk;
import static org.drools.drl.quarkus.util.deployment.DroolsQuarkusResourceUtils.getHotReloadSupportSource;
import static org.drools.drl.quarkus.util.deployment.DroolsQuarkusResourceUtils.getRuleUnitDefProducerSource;
import static org.drools.drl.quarkus.util.deployment.DroolsQuarkusResourceUtils.registerResources;
import static org.drools.drl.quarkus.util.deployment.DroolsQuarkusResourceUtils.toClassName;
import static org.drools.model.codegen.project.RuleCodegen.ofResources;

public class DroolsAssetsProcessor {
Expand Down Expand Up @@ -95,7 +88,8 @@ public void generateSources( BuildProducer<GeneratedBeanBuildItem> generatedBean
BuildProducer<GeneratedResourceBuildItem> genResBI,
BuildProducer<PatternsTypesBuildItem> otnClasesBI,
BuildProducer<KmoduleKieBaseModelsBuiltItem> kbaseModelsBI,
BuildProducer<GlobalsBuildItem> globalsBI) {
BuildProducer<GlobalsBuildItem> globalsBI,
BuildProducer<GeneratedJaxRsResourceBuildItem> jaxrsProducer) {
DroolsModelBuildContext context =
createDroolsBuildContext(outputTargetBuildItem.getOutputDirectory(), root.getPaths(), combinedIndexBuildItem.getIndex());

Expand Down Expand Up @@ -128,14 +122,13 @@ public void generateSources( BuildProducer<GeneratedBeanBuildItem> generatedBean
kbaseModelsBI.produce(new KmoduleKieBaseModelsBuiltItem(ruleCodegen.getKmoduleKieBaseModels()));
}
globalsBI.produce(new GlobalsBuildItem(ruleCodegen.getPackageModels().stream().collect(Collectors.toMap(PackageModel::getName, PackageModel::getGlobals))));
}

@BuildStep
public List<ReflectiveClassBuildItem> reflectiveEfestoRules() {
LOGGER.debug("reflectiveEfestoRules()");
final List<ReflectiveClassBuildItem> toReturn = new ArrayList<>();
toReturn.add(new ReflectiveClassBuildItem(true, true, KieRuntimeServiceDrlMapInput.class));
LOGGER.debug("toReturn {}", toReturn.size());
return toReturn;
Set<String> restResourceClassNameSet = generatedFiles.stream()
.filter(file -> file.type() == GeneratedFileType.REST)
.map(file -> toClassName(file.path().toString()))
.collect(Collectors.toSet());
generatedBeanBuildItems.stream()
.filter(b -> restResourceClassNameSet.contains(b.getName()))
.forEach(b -> jaxrsProducer.produce(new GeneratedJaxRsResourceBuildItem(b.getName(), b.getData())));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,37 @@
</execution>
</executions>
</plugin>

<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>

<!-- quarkus-resteasy brings in a couple of dependencies in the javax.* namespace that cannot be excluded -->
<!-- that's why it is necessary to disable the plugin that checks for banned dependencies -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>ban-blacklisted-dependencies</id>
<phase>validate</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<fail>false</fail>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency> <!-- enable assertions in REST endpoint as hook point for E2E opaque testing -->
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
Expand Down Expand Up @@ -182,6 +186,37 @@
</execution>
</executions>
</plugin>

<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>

<!-- quarkus-resteasy brings in a couple of dependencies in the javax.* namespace that cannot be excluded -->
<!-- that's why it is necessary to disable the plugin that checks for banned dependencies -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>ban-blacklisted-dependencies</id>
<phase>validate</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<fail>false</fail>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.drools.quarkus.ruleunit.test;
unit AlertingService;

import org.drools.ruleunits.api.DataStream;
import org.drools.ruleunits.api.RuleUnitData


declare Event
type: String
value: int
end

declare Alert
severity: String
message: String
end

declare AlertingService extends RuleUnitData
eventData: DataStream<Event>
alertData: DataStream<Alert>
end


rule IncomingEvent when
// matches when a temperature higher than 30 °C is registered (OOPath syntax)
$e : /eventData [ type == "temperature", value >= 30 ]
then
System.out.println("incoming event: "+ $e);
alertData.append( new Alert( "warning", $e.toString() ) );
end

query Warnings
alerts: /alertData [ severity == "warning" ]
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.drools.quarkus.ruleunit.test;

import io.quarkus.test.junit.QuarkusIntegrationTest;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.Test;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.startsWith;

@QuarkusIntegrationTest
public class AutomaticRestEndpointIT {

@Test
public void test() {
String payload = "{ \"eventData\": [{ \"type\": \"temperature\", \"value\" : 40 }] }";
RestAssured.given()
.contentType(ContentType.JSON)
.accept(ContentType.JSON)
.body(payload)
.when()
.post("/warnings/first")
.then()
.statusCode(200)
.body("severity", is("warning"))
.body("message", startsWith("Event"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,19 @@
*/
package org.drools.drl.quarkus.util.deployment;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import io.quarkus.arc.deployment.GeneratedBeanBuildItem;
import io.quarkus.bootstrap.classloading.QuarkusClassLoader;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.builditem.GeneratedResourceBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
import io.quarkus.maven.dependency.ResolvedDependency;
import io.quarkus.vertx.http.deployment.spi.AdditionalStaticResourceBuildItem;
import org.drools.base.util.Drools;
import org.drools.codegen.common.AppPaths;
import org.drools.codegen.common.DroolsModelBuildContext;
import org.drools.codegen.common.GeneratedFile;
import org.drools.codegen.common.GeneratedFileType;
import org.drools.codegen.common.context.QuarkusDroolsModelBuildContext;
import org.drools.base.util.Drools;
import org.drools.wiring.api.ComponentsSupplier;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
Expand All @@ -44,12 +41,15 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.quarkus.arc.deployment.GeneratedBeanBuildItem;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.builditem.GeneratedResourceBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
import io.quarkus.maven.dependency.ResolvedDependency;
import io.quarkus.vertx.http.deployment.spi.AdditionalStaticResourceBuildItem;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import static org.drools.util.Config.getConfig;
import static org.kie.memorycompiler.KieMemoryCompiler.compileNoLoad;
Expand Down Expand Up @@ -92,7 +92,7 @@ public static DroolsModelBuildContext createDroolsBuildContext(Path outputTarget
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
DroolsModelBuildContext context = QuarkusDroolsModelBuildContext.builder()
.withClassLoader(classLoader)
.withClassAvailabilityResolver(className -> classAvailabilityResolver(classLoader, index, className))
.withClassAvailabilityResolver(className -> classAvailabilityResolver(index, className))
.withAppPaths(appPaths)
.build();

Expand All @@ -101,12 +101,8 @@ public static DroolsModelBuildContext createDroolsBuildContext(Path outputTarget

/**
* Verify if a class is available. First uses jandex indexes, then fallback on classLoader
*
* @param classLoader
* @param className
* @return
*/
private static boolean classAvailabilityResolver(ClassLoader classLoader, IndexView index, String className) {
private static boolean classAvailabilityResolver(IndexView index, String className) {
if (index != null) {
DotName classDotName = DotName.createSimple(className);
boolean classFound = !index.getAnnotations(classDotName).isEmpty() ||
Expand All @@ -115,12 +111,8 @@ private static boolean classAvailabilityResolver(ClassLoader classLoader, IndexV
return true;
}
}
try {
classLoader.loadClass(className);
return true;
} catch (ClassNotFoundException e) {
return false;
}

return QuarkusClassLoader.isClassPresentAtRuntime(className);
}

public static void dumpFilesToDisk(AppPaths appPaths, Collection<GeneratedFile> generatedFiles) {
Expand Down
Loading

0 comments on commit 878850c

Please sign in to comment.