SlideShare una empresa de Scribd logo
1 de 30
Descargar para leer sin conexión
How and why I turned my old
Java projects into a first-class
serverless component
by Mario Fusco
Red Hat – Principal Software Engineer
@mariofusco
● A cloud-native development, deployment and execution platform for
business automation:
○ Rules and Decisions (Drools)
○ Processes and Cases (jBPM)
● ... under the covers
○ the backbone is code generation based on business assets
○ executable model for the process/rule/decision definitions
○ type safe data model that encapsulates variables
○ REST api for each public business process/decision/rule
Introducing
Demo
Kogito + Quarkus
Cool, but ... how did we get there?
A minimal agenda
⮚GraalVM features and limitations
⮚How (and why) we made Drools
natively compilable on GraalVM
⮚How we integrated Kogito with
Quarkus: creating a Quarkus extension
⮚Enabling hot reload of rules, decision
tables and processes
⮚One last demo
What is
used by Quarkus
➢
A polyglot VM with cross-language JIT
supporting
●
Java Bytecode and JVM languages
●
Interop with different languages
●
Dynamic languages through Truffle API
➢
Cross-language interop out of the box
●
Simple AST-based interpreter
●
JIT across language boundaries
➢
Support for native binary compilation
(SubstrateVM)
●
faster boot-up
●
lower memory footprint
AoT compilation with GraalVM
➢
Static analysis
➢
Closed world assumption
➢
Dead code elimination:
     classes, fields, methods, branches
AoT compilation with GraalVM
➢
Static analysis
➢
Closed world assumption
➢
Dead code elimination:
     classes, fields, methods, branches
🚀 Fast process start
🔬 Less memory
💾 Small size on disk
GraalVM Limitations
Dynaminc Classloading
Deloying jars, wars, etc. at runtime impossible
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
return defineClass( name, bytecode, 0, bytecode.length );
}
}
GraalVM Limitations
Dynaminc Classloading
Deloying jars, wars, etc. at runtime impossible
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
return defineClass( name, bytecode, 0, bytecode.length );
}
}
GraalVM Limitations
Dynaminc Classloading
Deloying jars, wars, etc. at runtime impossible
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
return defineClass( name, bytecode, 0, bytecode.length );
}
}
JVMTI, JMX + other
native VM interfaces
No agents → No JRebel, Byteman, profilers, tracers
Miscellaneous
➢
Security Manager
➢ finalize() (depreceated anyway)
➢ InvokeDynamic and MethodHandle
GraalVM Limitations
Dynaminc Classloading
Deloying jars, wars, etc. at runtime impossible
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
return defineClass( name, bytecode, 0, bytecode.length );
}
}
JVMTI, JMX + other
native VM interfaces
No agents → No JRebel, Byteman, profilers, tracers
Miscellaneous
➢
Security Manager
➢ finalize() (depreceated anyway)
➢ InvokeDynamic and MethodHandle
GraalVM Limitations
Dynaminc Classloading
Deloying jars, wars, etc. at runtime impossible
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
return defineClass( name, bytecode, 0, bytecode.length );
}
}
JVMTI, JMX + other
native VM interfaces
No agents → No JRebel, Byteman, profilers, tracers
Miscellaneous
➢
Security Manager
➢ finalize() (depreceated anyway)
➢ InvokeDynamic and MethodHandle
Reflection
Requires registration (closed world assumption)
GraalVM Limitations
Dynaminc Classloading
Deloying jars, wars, etc. at runtime impossible
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
return defineClass( name, bytecode, 0, bytecode.length );
}
}
JVMTI, JMX + other
native VM interfaces
No agents → No JRebel, Byteman, profilers, tracers
Miscellaneous
➢
Security Manager
➢ finalize() (depreceated anyway)
➢ InvokeDynamic and MethodHandle
[
{
"name" : "org.domain.model.Person",
"allPublicConstructors" : true,
"allPublicMethods" : true
}
]
Reflection
Requires registration (closed world assumption)
-H:ReflectionConfigurationFiles=src/main/resources/reflection.json
Drools on GraalVM - Executable Model
rule "Older than Mark" when
$p1: Person( name == "Mark" )
$p2: Person( name != "Mark", age > $p1.age )
then
System.out.println( $p1.getName() +
" is older than " + $p2.getName() );
end
Variable<Person> markV = declarationOf( Person.class );
Variable<Person> olderV = declarationOf( Person.class );
Rule rule = rule( "Older than Mark" )
.build(
pattern(markV)
.expr("exprA", p -> p.getName().equals( "Mark" ),
alphaIndexedBy( String.class, ConstraintType.EQUAL, 1, p -> p.getName(), "Mark" ),
reactOn( "name", "age" )),
pattern(olderV)
.expr("exprB", p -> !p.getName().equals("Mark"),
alphaIndexedBy( String.class, ConstraintType.NOT_EQUAL, 1, p -> p.getName(), "Mark" ),
reactOn( "name" ))
.expr("exprC", markV, (p1, p2) -> p1.getAge() > p2.getAge(),
betaIndexedBy( int.class, ConstraintType.GREATER_THAN, 0, p -> p.getAge(), p -> p.getAge() ),
reactOn( "age" )),
on(olderV, markV).execute((p1, p2) -> System.out.println( p1.getName() + " is older than " + p2.getName() ))
)
Drools on GraalVM - Executable Model
rule "Older than Mark" when
$p1: Person( name == "Mark" )
$p2: Person( name != "Mark", age > $p1.age )
then
System.out.println( $p1.getName() +
" is older than " + $p2.getName() );
end
Variable<Person> markV = declarationOf( Person.class );
Variable<Person> olderV = declarationOf( Person.class );
Rule rule = rule( "Older than Mark" )
.build(
pattern(markV)
.expr("exprA", p -> p.getName().equals( "Mark" ),
alphaIndexedBy( String.class, ConstraintType.EQUAL, 1, p -> p.getName(), "Mark" ),
reactOn( "name", "age" )),
pattern(olderV)
.expr("exprB", p -> !p.getName().equals("Mark"),
alphaIndexedBy( String.class, ConstraintType.NOT_EQUAL, 1, p -> p.getName(), "Mark" ),
reactOn( "name" ))
.expr("exprC", markV, (p1, p2) -> p1.getAge() > p2.getAge(),
betaIndexedBy( int.class, ConstraintType.GREATER_THAN, 0, p -> p.getAge(), p -> p.getAge() ),
reactOn( "age" )),
on(olderV, markV).execute((p1, p2) -> System.out.println( p1.getName() + " is older than " + p2.getName() ))
)
Drools on GraalVM - Executable Model
rule "Older than Mark" when
$p1: Person( name == "Mark" )
$p2: Person( name != "Mark", age > $p1.age )
then
System.out.println( $p1.getName() +
" is older than " + $p2.getName() );
end
Variable<Person> markV = declarationOf( Person.class );
Variable<Person> olderV = declarationOf( Person.class );
Rule rule = rule( "Older than Mark" )
.build(
pattern(markV)
.expr("exprA", p -> p.getName().equals( "Mark" ),
alphaIndexedBy( String.class, ConstraintType.EQUAL, 1, p -> p.getName(), "Mark" ),
reactOn( "name", "age" )),
pattern(olderV)
.expr("exprB", p -> !p.getName().equals("Mark"),
alphaIndexedBy( String.class, ConstraintType.NOT_EQUAL, 1, p -> p.getName(), "Mark" ),
reactOn( "name" ))
.expr("exprC", markV, (p1, p2) -> p1.getAge() > p2.getAge(),
betaIndexedBy( int.class, ConstraintType.GREATER_THAN, 0, p -> p.getAge(), p -> p.getAge() ),
reactOn( "age" )),
on(olderV, markV).execute((p1, p2) -> System.out.println( p1.getName() + " is older than " + p2.getName() ))
)
Executable
model
Indexes and
reactivity
explicitly defined
Executable Model at a glance
➢
A pure Java DSL for Drools rules authoring
➢
A pure Java canonical representation of a rule base
➢
Automatically generated by Maven plugin or
Quarkus extension
●
Can be embedded in jar
●
Faster boot
➢
Improve Backward/Forward compatibility
➢
Allow for faster prototyping and experimentation of
new features
➢
Prerequisite to make Drools natively compilable on
GraalVM
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
throw new UnsupportedOperationException();
}
}
Drools on GraalVM – other refactors
Dynamic class definition
is no longer necessary
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
throw new UnsupportedOperationException();
}
}
Drools on GraalVM – other refactors
Dynamic class definition
is no longer necessary
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
<kbase name="simpleKB"
packages="org.drools.simple.project">
<ksession name="simpleKS" default="true"/>
</kbase>
</kmodule>
var m = KieServices.get().newKieModuleModel();
var kb = m.newKieBaseModel("simpleKB");
kb.setEventProcessingMode(CLOUD);
kb.addPackage("org.drools.simple.project");
var ks = kb.newKieSessionModel("simpleKS");
ks.setDefault(true);
ks.setType(STATEFUL);
ks.setClockType(ClockTypeOption.get("realtime"));
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
throw new UnsupportedOperationException();
}
}
Drools on GraalVM – other refactors
Dynamic class definition
is no longer necessary
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
<kbase name="simpleKB"
packages="org.drools.simple.project">
<ksession name="simpleKS" default="true"/>
</kbase>
</kmodule>
var m = KieServices.get().newKieModuleModel();
var kb = m.newKieBaseModel("simpleKB");
kb.setEventProcessingMode(CLOUD);
kb.addPackage("org.drools.simple.project");
var ks = kb.newKieSessionModel("simpleKS");
ks.setDefault(true);
ks.setType(STATEFUL);
ks.setClockType(ClockTypeOption.get("realtime"));
org.kie.api.io.KieResources =
org.drools.core.io.impl.ResourceFactoryServiceImpl
org.kie.api.marshalling.KieMarshallers =
org.drools.core.marshalling.MarshallerProviderImpl
org.kie.api.concurrent.KieExecutors =
org.drools.core.concurrent.ExecutorProviderImpl
Map<Class<?>, Object> serviceMap = new HashMap<>();
void wireServices() {
serviceMap.put( ServiceInterface.class,
Class.forName("org.drools.ServiceImpl")
.newInstance());
// … more services here
}
JVM vs.
Native
Introducing
➢
A Framework for writing (fast and
lightweight) Java applications
Introducing
➢
A Framework for writing (fast and
lightweight) Java applications
➢
(Optionally) allowing generation
of native executable via GraalVM
*.class
QUARKUS
optimized jar
native
executable
JVM
Maven/Gradle plugin
Introducing
➢
A Framework for writing (fast and
lightweight) Java applications
➢
(Optionally) allowing generation
of native executable via GraalVM
➢
Based on existing standard
●
Servlet
●
JAX-RS
●
JPA, JDBC
●
CDI
●
Bean Validation
●
Transactions
●
Logging
●
Microprofile
*.class
QUARKUS
optimized jar
native
executable
JVM
Maven/Gradle plugin
Introducing
➢
A Framework for writing (fast and
lightweight) Java applications
➢
(Optionally) allowing generation
of native executable via GraalVM
➢
Based on existing standard
●
Servlet
●
JAX-RS
●
JPA, JDBC
●
CDI
●
Bean Validation
●
Transactions
●
Logging
●
Microprofile
➢
Out-of-the-box integration with
libraries that you already know
*.class
QUARKUS
optimized jar
native
executable
JVM
Maven/Gradle plugin
Compile generate
Java sources in
memory
Integrating Quarkus and Kogito
Writing a Quarkus extension
public class KogitoAssetProcessor {
@BuildStep(providesCapabilities = "io.quarkus.kogito")
public void generateModel( ArchiveRootBuildItem root,
BuildProducer<GeneratedBeanBuildItem> generatedBeans,
LaunchModeBuildItem launchMode) throws IOException {
LaunchMode launchMode = launchModeItem.getLaunchMode();
if (hotReload(launchMode)) {
return;
}
ApplicationGenerator appGen = createApplicationGenerator(root, launchMode);
Collection<GeneratedFile> generatedFiles = appGen.generate();
if (!generatedFiles.isEmpty()) {
MemoryFileSystem trgMfs = new MemoryFileSystem();
CompilationResult result = compile( root, trgMfs, generatedFiles,
generatedBeans, launchMode );
register( trgMfs, generatedBeans, launchMode, result );
}
}
}
Avoid recompiling
everything during
an hot reload
Generate
executable model
source files
Register generated
classes into
Quarkus runtime
Kogito hot reload
public class KogitoCompilationProvider extends JavaCompilationProvider {
@Override
public final void compile(Set<File> filesToCompile, Context context) {
File outputDirectory = context.getOutputDirectory();
try {
ApplicationGenerator appGen = new ApplicationGenerator( appPackageName,
outputDirectory );
Generator generator = addGenerator(appGen, filesToCompile, context);
Collection<GeneratedFile> generatedFiles = generator.generate();
HashSet<File> generatedSourceFiles = new HashSet<>();
for (GeneratedFile file : generatedFiles) {
Path path = pathOf(outputDirectory.getPath(), file.relativePath());
Files.write(path, file.contents());
generatedSourceFiles.add(path.toFile());
}
super.compile(generatedSourceFiles, context);
} catch (IOException e) {
throw new KogitoCompilerException(e);
}
}
}
Write regenerated
source in the file
system
Extends Java hot
reload mechanism
provided by Quarkus
Regenerate executable
model only for changed
sources
Pass the list of
generated sources to
super in order to
recompile them
A simple Quarkus-based
REST endpoint using Kogito
@Path("/candrink/{name}/{age}")
public class CanDrinkResource {
@Inject @Named("canDrinkKS")
RuleUnit<SessionMemory> ruleUnit;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String canDrink( @PathParam("name") String name, @PathParam("age") int age ) {
SessionMemory memory = new SessionMemory();
Result result = new Result();
memory.add(result);
memory.add(new Person( name, age ));
ruleUnit.evaluate(memory);
return result.toString();
}
}
What’s next?
Don’t miss Maciej Swiderski’s DevNationLive talk on the 5th
of September:
Event-driven business automation powered by cloud native Java
➢
Rule bases modularization via
Rule Units
➢
Rule Units orchestration through
jBPM workflows
➢
Seamless integration with Camel
routes, Kafka streams, ...
➢
Automatic REST endpoint
generation returning result of DRL
queries
Mario Fusco
Red Hat – Principal Software Engineer
mario.fusco@gmail.com
twitter: @mariofusco
Q A
Thanks ... Questions?

Más contenido relacionado

La actualidad más candente

Rules Programming tutorial
Rules Programming tutorialRules Programming tutorial
Rules Programming tutorial
Srinath Perera
 
Effective Spring Transaction Management
Effective Spring Transaction ManagementEffective Spring Transaction Management
Effective Spring Transaction Management
UMA MAHESWARI
 
Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to Redis
Dvir Volk
 

La actualidad más candente (20)

Kafka Streams State Stores Being Persistent
Kafka Streams State Stores Being PersistentKafka Streams State Stores Being Persistent
Kafka Streams State Stores Being Persistent
 
Spring boot jpa
Spring boot jpaSpring boot jpa
Spring boot jpa
 
JDBC - JPA - Spring Data
JDBC - JPA - Spring DataJDBC - JPA - Spring Data
JDBC - JPA - Spring Data
 
Introduction to Kafka Streams
Introduction to Kafka StreamsIntroduction to Kafka Streams
Introduction to Kafka Streams
 
Spring Data JPA
Spring Data JPASpring Data JPA
Spring Data JPA
 
Rules Programming tutorial
Rules Programming tutorialRules Programming tutorial
Rules Programming tutorial
 
Spring Boot on Amazon Web Services with Spring Cloud AWS
Spring Boot on Amazon Web Services with Spring Cloud AWSSpring Boot on Amazon Web Services with Spring Cloud AWS
Spring Boot on Amazon Web Services with Spring Cloud AWS
 
Spring Security Framework
Spring Security FrameworkSpring Security Framework
Spring Security Framework
 
Messaging queue - Kafka
Messaging queue - KafkaMessaging queue - Kafka
Messaging queue - Kafka
 
On-boarding with JanusGraph Performance
On-boarding with JanusGraph PerformanceOn-boarding with JanusGraph Performance
On-boarding with JanusGraph Performance
 
Effective Spring Transaction Management
Effective Spring Transaction ManagementEffective Spring Transaction Management
Effective Spring Transaction Management
 
Java 11 to 17 : What's new !?
Java 11 to 17 : What's new !?Java 11 to 17 : What's new !?
Java 11 to 17 : What's new !?
 
Demystifying flink memory allocation and tuning - Roshan Naik, Uber
Demystifying flink memory allocation and tuning - Roshan Naik, UberDemystifying flink memory allocation and tuning - Roshan Naik, Uber
Demystifying flink memory allocation and tuning - Roshan Naik, Uber
 
Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to Redis
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
Spring Core
Spring CoreSpring Core
Spring Core
 
Drools rule Concepts
Drools rule ConceptsDrools rule Concepts
Drools rule Concepts
 
Flexible and Real-Time Stream Processing with Apache Flink
Flexible and Real-Time Stream Processing with Apache FlinkFlexible and Real-Time Stream Processing with Apache Flink
Flexible and Real-Time Stream Processing with Apache Flink
 
codecentric AG: CQRS and Event Sourcing Applications with Cassandra
codecentric AG: CQRS and Event Sourcing Applications with Cassandracodecentric AG: CQRS and Event Sourcing Applications with Cassandra
codecentric AG: CQRS and Event Sourcing Applications with Cassandra
 

Similar a Introducing Kogito

Clojure for Java developers - Stockholm
Clojure for Java developers - StockholmClojure for Java developers - Stockholm
Clojure for Java developers - Stockholm
Jan Kronquist
 
Unit testing JavaScript using Mocha and Node
Unit testing JavaScript using Mocha and NodeUnit testing JavaScript using Mocha and Node
Unit testing JavaScript using Mocha and Node
Josh Mock
 
Polyglot Programming @ Jax.de 2010
Polyglot Programming @ Jax.de 2010Polyglot Programming @ Jax.de 2010
Polyglot Programming @ Jax.de 2010
Andres Almiray
 

Similar a Introducing Kogito (20)

Scala in Places API
Scala in Places APIScala in Places API
Scala in Places API
 
Introduction to Scalding and Monoids
Introduction to Scalding and MonoidsIntroduction to Scalding and Monoids
Introduction to Scalding and Monoids
 
Clojure for Java developers - Stockholm
Clojure for Java developers - StockholmClojure for Java developers - Stockholm
Clojure for Java developers - Stockholm
 
JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the AST
 
Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)
 
Unit testing JavaScript using Mocha and Node
Unit testing JavaScript using Mocha and NodeUnit testing JavaScript using Mocha and Node
Unit testing JavaScript using Mocha and Node
 
Go 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX GoGo 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX Go
 
Clojure And Swing
Clojure And SwingClojure And Swing
Clojure And Swing
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
DataMapper
DataMapperDataMapper
DataMapper
 
Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)
 
Polyglot Programming @ Jax.de 2010
Polyglot Programming @ Jax.de 2010Polyglot Programming @ Jax.de 2010
Polyglot Programming @ Jax.de 2010
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008
 
JavaScript Basics - GameCraft Training
JavaScript Basics - GameCraft TrainingJavaScript Basics - GameCraft Training
JavaScript Basics - GameCraft Training
 
Node.js - async for the rest of us.
Node.js - async for the rest of us.Node.js - async for the rest of us.
Node.js - async for the rest of us.
 
2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws
 
TDC2018SP | Trilha Go - Processando analise genetica em background com Go
TDC2018SP | Trilha Go - Processando analise genetica em background com GoTDC2018SP | Trilha Go - Processando analise genetica em background com Go
TDC2018SP | Trilha Go - Processando analise genetica em background com Go
 
Groovy
GroovyGroovy
Groovy
 
Griffon @ Svwjug
Griffon @ SvwjugGriffon @ Svwjug
Griffon @ Svwjug
 
Riak at The NYC Cloud Computing Meetup Group
Riak at The NYC Cloud Computing Meetup GroupRiak at The NYC Cloud Computing Meetup Group
Riak at The NYC Cloud Computing Meetup Group
 

Más de Red Hat Developers

Más de Red Hat Developers (20)

DevNation Tech Talk: Getting GitOps
DevNation Tech Talk: Getting GitOpsDevNation Tech Talk: Getting GitOps
DevNation Tech Talk: Getting GitOps
 
Exploring the power of OpenTelemetry on Kubernetes
Exploring the power of OpenTelemetry on KubernetesExploring the power of OpenTelemetry on Kubernetes
Exploring the power of OpenTelemetry on Kubernetes
 
GitHub Makeover | DevNation Tech Talk
GitHub Makeover | DevNation Tech TalkGitHub Makeover | DevNation Tech Talk
GitHub Makeover | DevNation Tech Talk
 
Quinoa: A modern Quarkus UI with no hassles | DevNation tech Talk
Quinoa: A modern Quarkus UI with no hassles | DevNation tech TalkQuinoa: A modern Quarkus UI with no hassles | DevNation tech Talk
Quinoa: A modern Quarkus UI with no hassles | DevNation tech Talk
 
Extra micrometer practices with Quarkus | DevNation Tech Talk
Extra micrometer practices with Quarkus | DevNation Tech TalkExtra micrometer practices with Quarkus | DevNation Tech Talk
Extra micrometer practices with Quarkus | DevNation Tech Talk
 
Event-driven autoscaling through KEDA and Knative Integration | DevNation Tec...
Event-driven autoscaling through KEDA and Knative Integration | DevNation Tec...Event-driven autoscaling through KEDA and Knative Integration | DevNation Tec...
Event-driven autoscaling through KEDA and Knative Integration | DevNation Tec...
 
Integrating Loom in Quarkus | DevNation Tech Talk
Integrating Loom in Quarkus | DevNation Tech TalkIntegrating Loom in Quarkus | DevNation Tech Talk
Integrating Loom in Quarkus | DevNation Tech Talk
 
Quarkus Renarde 🦊♥: an old-school Web framework with today's touch | DevNatio...
Quarkus Renarde 🦊♥: an old-school Web framework with today's touch | DevNatio...Quarkus Renarde 🦊♥: an old-school Web framework with today's touch | DevNatio...
Quarkus Renarde 🦊♥: an old-school Web framework with today's touch | DevNatio...
 
Containers without docker | DevNation Tech Talk
Containers without docker | DevNation Tech TalkContainers without docker | DevNation Tech Talk
Containers without docker | DevNation Tech Talk
 
Distributed deployment of microservices across multiple OpenShift clusters | ...
Distributed deployment of microservices across multiple OpenShift clusters | ...Distributed deployment of microservices across multiple OpenShift clusters | ...
Distributed deployment of microservices across multiple OpenShift clusters | ...
 
DevNation Workshop: Object detection with Red Hat OpenShift Data Science [Mar...
DevNation Workshop: Object detection with Red Hat OpenShift Data Science [Mar...DevNation Workshop: Object detection with Red Hat OpenShift Data Science [Mar...
DevNation Workshop: Object detection with Red Hat OpenShift Data Science [Mar...
 
Dear security, compliance, and auditing: We’re sorry. Love, DevOps | DevNatio...
Dear security, compliance, and auditing: We’re sorry. Love, DevOps | DevNatio...Dear security, compliance, and auditing: We’re sorry. Love, DevOps | DevNatio...
Dear security, compliance, and auditing: We’re sorry. Love, DevOps | DevNatio...
 
11 CLI tools every developer should know | DevNation Tech Talk
11 CLI tools every developer should know | DevNation Tech Talk11 CLI tools every developer should know | DevNation Tech Talk
11 CLI tools every developer should know | DevNation Tech Talk
 
A Microservices approach with Cassandra and Quarkus | DevNation Tech Talk
A Microservices approach with Cassandra and Quarkus | DevNation Tech TalkA Microservices approach with Cassandra and Quarkus | DevNation Tech Talk
A Microservices approach with Cassandra and Quarkus | DevNation Tech Talk
 
GitHub Actions and OpenShift: ​​Supercharging your software development loops...
GitHub Actions and OpenShift: ​​Supercharging your software development loops...GitHub Actions and OpenShift: ​​Supercharging your software development loops...
GitHub Actions and OpenShift: ​​Supercharging your software development loops...
 
To the moon and beyond with Java 17 APIs! | DevNation Tech Talk
To the moon and beyond with Java 17 APIs! | DevNation Tech TalkTo the moon and beyond with Java 17 APIs! | DevNation Tech Talk
To the moon and beyond with Java 17 APIs! | DevNation Tech Talk
 
Profile your Java apps in production on Red Hat OpenShift with Cryostat | Dev...
Profile your Java apps in production on Red Hat OpenShift with Cryostat | Dev...Profile your Java apps in production on Red Hat OpenShift with Cryostat | Dev...
Profile your Java apps in production on Red Hat OpenShift with Cryostat | Dev...
 
Kafka at the Edge: an IoT scenario with OpenShift Streams for Apache Kafka | ...
Kafka at the Edge: an IoT scenario with OpenShift Streams for Apache Kafka | ...Kafka at the Edge: an IoT scenario with OpenShift Streams for Apache Kafka | ...
Kafka at the Edge: an IoT scenario with OpenShift Streams for Apache Kafka | ...
 
Kubernetes configuration and security policies with KubeLinter | DevNation Te...
Kubernetes configuration and security policies with KubeLinter | DevNation Te...Kubernetes configuration and security policies with KubeLinter | DevNation Te...
Kubernetes configuration and security policies with KubeLinter | DevNation Te...
 
Level-up your gaming telemetry using Kafka Streams | DevNation Tech Talk
Level-up your gaming telemetry using Kafka Streams | DevNation Tech TalkLevel-up your gaming telemetry using Kafka Streams | DevNation Tech Talk
Level-up your gaming telemetry using Kafka Streams | DevNation Tech Talk
 

Último

%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
masabamasaba
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
masabamasaba
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 

Último (20)

%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 

Introducing Kogito

  • 1. How and why I turned my old Java projects into a first-class serverless component by Mario Fusco Red Hat – Principal Software Engineer @mariofusco
  • 2. ● A cloud-native development, deployment and execution platform for business automation: ○ Rules and Decisions (Drools) ○ Processes and Cases (jBPM) ● ... under the covers ○ the backbone is code generation based on business assets ○ executable model for the process/rule/decision definitions ○ type safe data model that encapsulates variables ○ REST api for each public business process/decision/rule Introducing
  • 4. Cool, but ... how did we get there? A minimal agenda ⮚GraalVM features and limitations ⮚How (and why) we made Drools natively compilable on GraalVM ⮚How we integrated Kogito with Quarkus: creating a Quarkus extension ⮚Enabling hot reload of rules, decision tables and processes ⮚One last demo
  • 5. What is used by Quarkus ➢ A polyglot VM with cross-language JIT supporting ● Java Bytecode and JVM languages ● Interop with different languages ● Dynamic languages through Truffle API ➢ Cross-language interop out of the box ● Simple AST-based interpreter ● JIT across language boundaries ➢ Support for native binary compilation (SubstrateVM) ● faster boot-up ● lower memory footprint
  • 6. AoT compilation with GraalVM ➢ Static analysis ➢ Closed world assumption ➢ Dead code elimination:      classes, fields, methods, branches
  • 7. AoT compilation with GraalVM ➢ Static analysis ➢ Closed world assumption ➢ Dead code elimination:      classes, fields, methods, branches 🚀 Fast process start 🔬 Less memory 💾 Small size on disk
  • 8. GraalVM Limitations Dynaminc Classloading Deloying jars, wars, etc. at runtime impossible public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { return defineClass( name, bytecode, 0, bytecode.length ); } }
  • 9. GraalVM Limitations Dynaminc Classloading Deloying jars, wars, etc. at runtime impossible public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { return defineClass( name, bytecode, 0, bytecode.length ); } }
  • 10. GraalVM Limitations Dynaminc Classloading Deloying jars, wars, etc. at runtime impossible public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { return defineClass( name, bytecode, 0, bytecode.length ); } } JVMTI, JMX + other native VM interfaces No agents → No JRebel, Byteman, profilers, tracers Miscellaneous ➢ Security Manager ➢ finalize() (depreceated anyway) ➢ InvokeDynamic and MethodHandle
  • 11. GraalVM Limitations Dynaminc Classloading Deloying jars, wars, etc. at runtime impossible public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { return defineClass( name, bytecode, 0, bytecode.length ); } } JVMTI, JMX + other native VM interfaces No agents → No JRebel, Byteman, profilers, tracers Miscellaneous ➢ Security Manager ➢ finalize() (depreceated anyway) ➢ InvokeDynamic and MethodHandle
  • 12. GraalVM Limitations Dynaminc Classloading Deloying jars, wars, etc. at runtime impossible public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { return defineClass( name, bytecode, 0, bytecode.length ); } } JVMTI, JMX + other native VM interfaces No agents → No JRebel, Byteman, profilers, tracers Miscellaneous ➢ Security Manager ➢ finalize() (depreceated anyway) ➢ InvokeDynamic and MethodHandle Reflection Requires registration (closed world assumption)
  • 13. GraalVM Limitations Dynaminc Classloading Deloying jars, wars, etc. at runtime impossible public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { return defineClass( name, bytecode, 0, bytecode.length ); } } JVMTI, JMX + other native VM interfaces No agents → No JRebel, Byteman, profilers, tracers Miscellaneous ➢ Security Manager ➢ finalize() (depreceated anyway) ➢ InvokeDynamic and MethodHandle [ { "name" : "org.domain.model.Person", "allPublicConstructors" : true, "allPublicMethods" : true } ] Reflection Requires registration (closed world assumption) -H:ReflectionConfigurationFiles=src/main/resources/reflection.json
  • 14. Drools on GraalVM - Executable Model rule "Older than Mark" when $p1: Person( name == "Mark" ) $p2: Person( name != "Mark", age > $p1.age ) then System.out.println( $p1.getName() + " is older than " + $p2.getName() ); end Variable<Person> markV = declarationOf( Person.class ); Variable<Person> olderV = declarationOf( Person.class ); Rule rule = rule( "Older than Mark" ) .build( pattern(markV) .expr("exprA", p -> p.getName().equals( "Mark" ), alphaIndexedBy( String.class, ConstraintType.EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name", "age" )), pattern(olderV) .expr("exprB", p -> !p.getName().equals("Mark"), alphaIndexedBy( String.class, ConstraintType.NOT_EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name" )) .expr("exprC", markV, (p1, p2) -> p1.getAge() > p2.getAge(), betaIndexedBy( int.class, ConstraintType.GREATER_THAN, 0, p -> p.getAge(), p -> p.getAge() ), reactOn( "age" )), on(olderV, markV).execute((p1, p2) -> System.out.println( p1.getName() + " is older than " + p2.getName() )) )
  • 15. Drools on GraalVM - Executable Model rule "Older than Mark" when $p1: Person( name == "Mark" ) $p2: Person( name != "Mark", age > $p1.age ) then System.out.println( $p1.getName() + " is older than " + $p2.getName() ); end Variable<Person> markV = declarationOf( Person.class ); Variable<Person> olderV = declarationOf( Person.class ); Rule rule = rule( "Older than Mark" ) .build( pattern(markV) .expr("exprA", p -> p.getName().equals( "Mark" ), alphaIndexedBy( String.class, ConstraintType.EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name", "age" )), pattern(olderV) .expr("exprB", p -> !p.getName().equals("Mark"), alphaIndexedBy( String.class, ConstraintType.NOT_EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name" )) .expr("exprC", markV, (p1, p2) -> p1.getAge() > p2.getAge(), betaIndexedBy( int.class, ConstraintType.GREATER_THAN, 0, p -> p.getAge(), p -> p.getAge() ), reactOn( "age" )), on(olderV, markV).execute((p1, p2) -> System.out.println( p1.getName() + " is older than " + p2.getName() )) )
  • 16. Drools on GraalVM - Executable Model rule "Older than Mark" when $p1: Person( name == "Mark" ) $p2: Person( name != "Mark", age > $p1.age ) then System.out.println( $p1.getName() + " is older than " + $p2.getName() ); end Variable<Person> markV = declarationOf( Person.class ); Variable<Person> olderV = declarationOf( Person.class ); Rule rule = rule( "Older than Mark" ) .build( pattern(markV) .expr("exprA", p -> p.getName().equals( "Mark" ), alphaIndexedBy( String.class, ConstraintType.EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name", "age" )), pattern(olderV) .expr("exprB", p -> !p.getName().equals("Mark"), alphaIndexedBy( String.class, ConstraintType.NOT_EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name" )) .expr("exprC", markV, (p1, p2) -> p1.getAge() > p2.getAge(), betaIndexedBy( int.class, ConstraintType.GREATER_THAN, 0, p -> p.getAge(), p -> p.getAge() ), reactOn( "age" )), on(olderV, markV).execute((p1, p2) -> System.out.println( p1.getName() + " is older than " + p2.getName() )) ) Executable model Indexes and reactivity explicitly defined
  • 17. Executable Model at a glance ➢ A pure Java DSL for Drools rules authoring ➢ A pure Java canonical representation of a rule base ➢ Automatically generated by Maven plugin or Quarkus extension ● Can be embedded in jar ● Faster boot ➢ Improve Backward/Forward compatibility ➢ Allow for faster prototyping and experimentation of new features ➢ Prerequisite to make Drools natively compilable on GraalVM
  • 18. public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { throw new UnsupportedOperationException(); } } Drools on GraalVM – other refactors Dynamic class definition is no longer necessary
  • 19. public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { throw new UnsupportedOperationException(); } } Drools on GraalVM – other refactors Dynamic class definition is no longer necessary <?xml version="1.0" encoding="UTF-8"?> <kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"> <kbase name="simpleKB" packages="org.drools.simple.project"> <ksession name="simpleKS" default="true"/> </kbase> </kmodule> var m = KieServices.get().newKieModuleModel(); var kb = m.newKieBaseModel("simpleKB"); kb.setEventProcessingMode(CLOUD); kb.addPackage("org.drools.simple.project"); var ks = kb.newKieSessionModel("simpleKS"); ks.setDefault(true); ks.setType(STATEFUL); ks.setClockType(ClockTypeOption.get("realtime"));
  • 20. public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { throw new UnsupportedOperationException(); } } Drools on GraalVM – other refactors Dynamic class definition is no longer necessary <?xml version="1.0" encoding="UTF-8"?> <kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"> <kbase name="simpleKB" packages="org.drools.simple.project"> <ksession name="simpleKS" default="true"/> </kbase> </kmodule> var m = KieServices.get().newKieModuleModel(); var kb = m.newKieBaseModel("simpleKB"); kb.setEventProcessingMode(CLOUD); kb.addPackage("org.drools.simple.project"); var ks = kb.newKieSessionModel("simpleKS"); ks.setDefault(true); ks.setType(STATEFUL); ks.setClockType(ClockTypeOption.get("realtime")); org.kie.api.io.KieResources = org.drools.core.io.impl.ResourceFactoryServiceImpl org.kie.api.marshalling.KieMarshallers = org.drools.core.marshalling.MarshallerProviderImpl org.kie.api.concurrent.KieExecutors = org.drools.core.concurrent.ExecutorProviderImpl Map<Class<?>, Object> serviceMap = new HashMap<>(); void wireServices() { serviceMap.put( ServiceInterface.class, Class.forName("org.drools.ServiceImpl") .newInstance()); // … more services here }
  • 22. Introducing ➢ A Framework for writing (fast and lightweight) Java applications
  • 23. Introducing ➢ A Framework for writing (fast and lightweight) Java applications ➢ (Optionally) allowing generation of native executable via GraalVM *.class QUARKUS optimized jar native executable JVM Maven/Gradle plugin
  • 24. Introducing ➢ A Framework for writing (fast and lightweight) Java applications ➢ (Optionally) allowing generation of native executable via GraalVM ➢ Based on existing standard ● Servlet ● JAX-RS ● JPA, JDBC ● CDI ● Bean Validation ● Transactions ● Logging ● Microprofile *.class QUARKUS optimized jar native executable JVM Maven/Gradle plugin
  • 25. Introducing ➢ A Framework for writing (fast and lightweight) Java applications ➢ (Optionally) allowing generation of native executable via GraalVM ➢ Based on existing standard ● Servlet ● JAX-RS ● JPA, JDBC ● CDI ● Bean Validation ● Transactions ● Logging ● Microprofile ➢ Out-of-the-box integration with libraries that you already know *.class QUARKUS optimized jar native executable JVM Maven/Gradle plugin
  • 26. Compile generate Java sources in memory Integrating Quarkus and Kogito Writing a Quarkus extension public class KogitoAssetProcessor { @BuildStep(providesCapabilities = "io.quarkus.kogito") public void generateModel( ArchiveRootBuildItem root, BuildProducer<GeneratedBeanBuildItem> generatedBeans, LaunchModeBuildItem launchMode) throws IOException { LaunchMode launchMode = launchModeItem.getLaunchMode(); if (hotReload(launchMode)) { return; } ApplicationGenerator appGen = createApplicationGenerator(root, launchMode); Collection<GeneratedFile> generatedFiles = appGen.generate(); if (!generatedFiles.isEmpty()) { MemoryFileSystem trgMfs = new MemoryFileSystem(); CompilationResult result = compile( root, trgMfs, generatedFiles, generatedBeans, launchMode ); register( trgMfs, generatedBeans, launchMode, result ); } } } Avoid recompiling everything during an hot reload Generate executable model source files Register generated classes into Quarkus runtime
  • 27. Kogito hot reload public class KogitoCompilationProvider extends JavaCompilationProvider { @Override public final void compile(Set<File> filesToCompile, Context context) { File outputDirectory = context.getOutputDirectory(); try { ApplicationGenerator appGen = new ApplicationGenerator( appPackageName, outputDirectory ); Generator generator = addGenerator(appGen, filesToCompile, context); Collection<GeneratedFile> generatedFiles = generator.generate(); HashSet<File> generatedSourceFiles = new HashSet<>(); for (GeneratedFile file : generatedFiles) { Path path = pathOf(outputDirectory.getPath(), file.relativePath()); Files.write(path, file.contents()); generatedSourceFiles.add(path.toFile()); } super.compile(generatedSourceFiles, context); } catch (IOException e) { throw new KogitoCompilerException(e); } } } Write regenerated source in the file system Extends Java hot reload mechanism provided by Quarkus Regenerate executable model only for changed sources Pass the list of generated sources to super in order to recompile them
  • 28. A simple Quarkus-based REST endpoint using Kogito @Path("/candrink/{name}/{age}") public class CanDrinkResource { @Inject @Named("canDrinkKS") RuleUnit<SessionMemory> ruleUnit; @GET @Produces(MediaType.TEXT_PLAIN) public String canDrink( @PathParam("name") String name, @PathParam("age") int age ) { SessionMemory memory = new SessionMemory(); Result result = new Result(); memory.add(result); memory.add(new Person( name, age )); ruleUnit.evaluate(memory); return result.toString(); } }
  • 29. What’s next? Don’t miss Maciej Swiderski’s DevNationLive talk on the 5th of September: Event-driven business automation powered by cloud native Java ➢ Rule bases modularization via Rule Units ➢ Rule Units orchestration through jBPM workflows ➢ Seamless integration with Camel routes, Kafka streams, ... ➢ Automatic REST endpoint generation returning result of DRL queries
  • 30. Mario Fusco Red Hat – Principal Software Engineer mario.fusco@gmail.com twitter: @mariofusco Q A Thanks ... Questions?