SlideShare a Scribd company logo
How and why I turned my old
Java projects into a first-class
serverless component
by Mario Fusco
Red Hat – Principal Software Engineer
@mariofusco
c
Agenda
➢
Declarative vs. Imperative programming
➢
What is a rule engine and how it works
➢
A simple example
➢
From drl to Java: the executable model
Agenda
➢
Declarative vs. Imperative programming
➢
What is a rule engine and how it works
➢
A simple example
➢
From drl to Java: the executable model
➢
What is GraalVM
➢
AoT compilation
➢
Limitations
➢
Refactoring Drools to (natively) compile on GraalVM
Agenda
c
➢
Declarative vs. Imperative programming
➢
What is a rule engine and how it works
➢
A simple example
➢
From drl to Java: the executable model
➢
What is GraalVM
➢
AoT compilation
➢
Limitations
➢
Refactoring Drools to (natively) compile on GraalVM
➢
What is Quarkus
➢
Quarkus features
➢
Integrating Drools with Quarkus
➢
Writing a Quarkus extension for Drools
What a rule-based program is
➢
A rule-based program is made up of discrete rules, each of which applies to a subset of the problem
➢
It is simpler, because you can concentrate on the rules for one situation at a time
➢
It can be more flexible in the face of fragmentary or poorly conditioned inputs
➢
Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in
short, all problems without clear algorithmic solutions
What a rule-based program is
➢
A rule-based program is made up of discrete rules, each of which applies to a subset of the problem
➢
It is simpler, because you can concentrate on the rules for one situation at a time
➢
It can be more flexible in the face of fragmentary or poorly conditioned inputs
➢
Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in
short, all problems without clear algorithmic solutions
Declarative
(What to do)
Imperative
(How to do it) Vs.
public void helloMark(Person person) {
if ( person.getName().equals( “Mark” ) {
System.out.println( “Hello Mark” );
}
}
rule “Hello Mark”
when
Person( name == “Mark” )
then
System.out.println( “Hello Mark” );
end
What a rule-based program is
➢
A rule-based program is made up of discrete rules, each of which applies to a subset of the problem
➢
It is simpler, because you can concentrate on the rules for one situation at a time
➢
It can be more flexible in the face of fragmentary or poorly conditioned inputs
➢
Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in
short, all problems without clear algorithmic solutions
Declarative
(What to do)
Imperative
(How to do it) Vs.
public void helloMark(Person person) {
if ( person.getName().equals( “Mark” ) {
System.out.println( “Hello Mark” );
}
}
rule “Hello Mark”
when
Person( name == “Mark” )
then
System.out.println( “Hello Mark” );
end
A method must
be called directly
Rules can never
be called directly
What a rule-based program is
➢
A rule-based program is made up of discrete rules, each of which applies to a subset of the problem
➢
It is simpler, because you can concentrate on the rules for one situation at a time
➢
It can be more flexible in the face of fragmentary or poorly conditioned inputs
➢
Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in
short, all problems without clear algorithmic solutions
Declarative
(What to do)
Imperative
(How to do it) Vs.
public void helloMark(Person person) {
if ( person.getName().equals( “Mark” ) {
System.out.println( “Hello Mark” );
}
}
rule “Hello Mark”
when
Person( name == “Mark” )
then
System.out.println( “Hello Mark” );
end
A method must
be called directly
Specific passing
of arguments
Rules can never
be called directly
Specific instances cannot
be passed but are
automatically selected
with pattern-matching
Introducing
➢
Easier to understand → Requirements can be more naturally translated into
rules. It is more likely for a technically skilled business analyst to verify, validate
or even change a rule than a piece of Java code
➢
Improved maintainability → We don't care about how to implement a solution
only what needs to be done to solve a problem
➢
Deals with evolving complexity → It's easier to modify a rule than a Java
program and to determine the impact of this change on the rest of the application
➢
Modularity → Each rule models an isolated and small portion of your business
logic and is not part of a monolithic program
➢
Clear separation of business logic from the rest of the system → Business
and infrastructural code have very different lifecycles
➢
Complex Event Processing → Facts can be handled like timestamped events
allowing temporal reasoning on them
RULES
How a rule-based system works
➢
The Rule Base contains a computation efficient
representation of the set of the defined rules
➢
The Working Memory contains the set of facts
inserted into sessions
➢
The engine matches the fact in the working
memory against the rules set
➢
When a match is found it creates an activation
and put it into the agenda
➢
An activation is the tuple of facts matching the
conditions of a rule plus the rule itself
➢
When all activations have been created the
agenda elects through a conflict resolution
strategy the one to be executed
➢
The elected activation is passed to the execution
engine and the fired
A simple rule set
rule RaiseAlarm when
exists Fire()
then
insert( new Alarm( "house1" ) );
System.out.println( "Raise the Alarm");
end
rule CancelAlarm when
not Fire()
a : Alarm()
then
delete( a );
System.out.println( "Cancel the Alarm");
end
rule TurnSprinklerOn when
s : Sprinkler( on == false )
f : Fire( room == s.room )
then
modify( s ) { setOn( true ) }
System.out.println( "Turn on the sprinkler for room " +
f.getRoom().getName() );
end
rule TurnSprinklerOff when
s : Sprinkler( on == true )
not Fire( room == s.room )
then
modify( s ) { setOn( false ) }
System.out.println( "Turn off the sprinkler for room " +
s.getRoom().getName() );
end
rule OK when
not Alarm()
not Sprinkler( on == true )
then
System.out.println( "Everything is ok" );
end
Pattern-matching
against objects in the
Working Memory
Code executed when
a match is found
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
}
Demo 1
Drools on GraalVM
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
Why Quarkus
Lower
memory
usage
Faster
startup
Optimized for
short-lived
processes
Kubernetes
Native
Live
reload
Microservices
Why Quarkus
Lower
memory
usage
Faster
startup
Optimized for
short-lived
processes
Kubernetes
Native
Live
reload
Microservices
Fast, lightweight Drools = Submarine
The question of whether a
computer can think is no
more interesting than the
question of whether a
submarine can swim
- Edsger W. Dijkstra
Integrating Quarkus and Drools
Writing a Quarkus extension
public class ExecutableModelGenerator {
private static final String PRODUCER_SOURCE = "package io.quarkus.drools.runtime;n" +
"import org.drools.modelcompiler.KieRuntimeBuilder;n" +
"n" +
"@javax.inject.Singletonn" +
"public class RuntimeProducer {n" +
" public static final KieRuntimeBuilder INSTANCE = new org.drools.project.model.ProjectRuntime();n" +
"n" +
" @javax.enterprise.inject.Producesn" +
" public KieRuntimeBuilder produce() { return INSTANCE; }n" +
"}";
@BuildStep(providesCapabilities = "io.quarkus.drools") @Record(STATIC_INIT)
public void generateModel( ArchiveRootBuildItem root,
BuildProducer<GeneratedBeanBuildItem> generatedBeans, BuildProducer<GeneratedClassBuildItem> generatedClasses) {
MemoryFileSystem srcMfs = new MemoryFileSystem();
String[] sources = generateSources(root, srcMfs);
srcMfs.write(toRuntimeSource(PRODUCER_CLASSNAME), PRODUCER_SOURCE.getBytes());
sources[sources.length - 1] = toRuntimeSource(PRODUCER_CLASSNAME);
registerGeneratedClasses(generatedBeans, generatedClasses, compileSources(srcMfs, sources));
}
private void registerGeneratedClasses( BuildProducer<GeneratedBeanBuildItem> generatedBeans,
BuildProducer<GeneratedClassBuildItem> generatedClasses, MemoryFileSystem trgMfs) {
for (String fileName : trgMfs.getFileNames()) {
String className = toClassName(fileName);
if (className.equals(PRODUCER_CLASSNAME)) {
generatedBeans.produce(new GeneratedBeanBuildItem(className, trgMfs.getBytes(fileName)));
} else {
generatedClasses.produce(new GeneratedClassBuildItem(true, className, trgMfs.getBytes(fileName)));
}
}
}
}
A simple Quarkus-based
REST endopint using Drools
@Path("/candrink/{name}/{age}")
public class CanDrinkResource {
@Inject
KieRuntimeBuilder runtimeBuilder;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String canDrink( @PathParam("name") String name, @PathParam("age") int age ) {
KieSession ksession = runtimeBuilder.newKieSession("canDrinkKS");
Result result = new Result();
ksession.insert(result);
ksession.insert(new Person( name, age ));
ksession.fireAllRules();
return result.toString();
}
}
Demo 2
Drools on Quarkus
Mario Fusco
Red Hat – Principal Software Engineer
mario.fusco@gmail.com
twitter: @mariofusco
Q A
Thanks ... Questions?

More Related Content

What's hot (20)

PDF
The... Wonderful? World of Lambdas
Esther Lozano
 
PDF
Advanced Java Practical File
Soumya Behera
 
PDF
Currying and Partial Function Application (PFA)
Dhaval Dalal
 
DOC
CS2309 JAVA LAB MANUAL
Lavanya Arunachalam A
 
PDF
Java 8 Workshop
Mario Fusco
 
PDF
Java Lab Manual
Naveen Sagayaselvaraj
 
ODP
Software Transactioneel Geheugen
Devnology
 
PDF
Java Class Design
Ganesh Samarthyam
 
PDF
Parallel streams in java 8
David Gómez García
 
PDF
Java9 Beyond Modularity - Java 9 más allá de la modularidad
David Gómez García
 
DOCX
Parallel Programming With Dot Net
Neeraj Kaushik
 
PDF
Java 8 Stream API. A different way to process collections.
David Gómez García
 
PDF
DRYing to Monad in Java8
Dhaval Dalal
 
PDF
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Chris Richardson
 
PDF
Creating Lazy stream in CSharp
Dhaval Dalal
 
PDF
Harnessing the Power of Java 8 Streams
IndicThreads
 
PDF
Concurrency Utilities in Java 8
Martin Toshev
 
PPT
Functional Programming Past Present Future
IndicThreads
 
PDF
Java programming lab manual
sameer farooq
 
PDF
Java Concurrency Idioms
Alex Miller
 
The... Wonderful? World of Lambdas
Esther Lozano
 
Advanced Java Practical File
Soumya Behera
 
Currying and Partial Function Application (PFA)
Dhaval Dalal
 
CS2309 JAVA LAB MANUAL
Lavanya Arunachalam A
 
Java 8 Workshop
Mario Fusco
 
Java Lab Manual
Naveen Sagayaselvaraj
 
Software Transactioneel Geheugen
Devnology
 
Java Class Design
Ganesh Samarthyam
 
Parallel streams in java 8
David Gómez García
 
Java9 Beyond Modularity - Java 9 más allá de la modularidad
David Gómez García
 
Parallel Programming With Dot Net
Neeraj Kaushik
 
Java 8 Stream API. A different way to process collections.
David Gómez García
 
DRYing to Monad in Java8
Dhaval Dalal
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Chris Richardson
 
Creating Lazy stream in CSharp
Dhaval Dalal
 
Harnessing the Power of Java 8 Streams
IndicThreads
 
Concurrency Utilities in Java 8
Martin Toshev
 
Functional Programming Past Present Future
IndicThreads
 
Java programming lab manual
sameer farooq
 
Java Concurrency Idioms
Alex Miller
 

Similar to How and why I turned my old Java projects into a first-class serverless component (20)

PDF
Introducing Kogito
Red Hat Developers
 
PPTX
Jboss drools 3 key drools functionalities
Zoran Hristov
 
PDF
Hotspot & AOT
Dmitry Chuyko
 
PDF
Drools
John Paulett
 
PPTX
Jboss drools 4 scope - benefits, shortfalls
Zoran Hristov
 
PPTX
GOTO Night with Charles Nutter Slides
Alexandra Masterson
 
PPTX
Does Java Have a Future After Version 8? (Belfast JUG April 2014)
Garth Gilmour
 
PDF
Typesafe stack - Scala, Akka and Play
Luka Zakrajšek
 
PDF
Drools, jBPM OptaPlanner presentation
Mark Proctor
 
PPTX
Java Modularity with OSGi
Ilya Rybak
 
PPTX
Indic threads pune12-typesafe stack software development on the jvm
IndicThreads
 
PDF
How the HotSpot and Graal JVMs execute Java Code
Jim Gough
 
PDF
Intro to Drools - St Louis Gateway JUG
Ray Ploski
 
PPTX
Discover Quarkus and GraalVM
Romain Schlick
 
PDF
Kogito: cloud native business automation
Mario Fusco
 
PDF
Ola Bini Evolving The Java Platform
deimos
 
PPTX
Process Orchestration with Flowable and Spring Boot
Chavdar Baikov
 
PPTX
Simple tweaks to get the most out of your JVM
Jamie Coleman
 
PDF
Introduction to OSGi (Tokyo JUG)
njbartlett
 
PDF
Class 1
Dario Pilozo
 
Introducing Kogito
Red Hat Developers
 
Jboss drools 3 key drools functionalities
Zoran Hristov
 
Hotspot & AOT
Dmitry Chuyko
 
Drools
John Paulett
 
Jboss drools 4 scope - benefits, shortfalls
Zoran Hristov
 
GOTO Night with Charles Nutter Slides
Alexandra Masterson
 
Does Java Have a Future After Version 8? (Belfast JUG April 2014)
Garth Gilmour
 
Typesafe stack - Scala, Akka and Play
Luka Zakrajšek
 
Drools, jBPM OptaPlanner presentation
Mark Proctor
 
Java Modularity with OSGi
Ilya Rybak
 
Indic threads pune12-typesafe stack software development on the jvm
IndicThreads
 
How the HotSpot and Graal JVMs execute Java Code
Jim Gough
 
Intro to Drools - St Louis Gateway JUG
Ray Ploski
 
Discover Quarkus and GraalVM
Romain Schlick
 
Kogito: cloud native business automation
Mario Fusco
 
Ola Bini Evolving The Java Platform
deimos
 
Process Orchestration with Flowable and Spring Boot
Chavdar Baikov
 
Simple tweaks to get the most out of your JVM
Jamie Coleman
 
Introduction to OSGi (Tokyo JUG)
njbartlett
 
Class 1
Dario Pilozo
 
Ad

More from Mario Fusco (16)

PDF
Let's make a contract: the art of designing a Java API
Mario Fusco
 
PDF
OOP and FP
Mario Fusco
 
PDF
Lazy java
Mario Fusco
 
PDF
From object oriented to functional domain modeling
Mario Fusco
 
ODP
Drools 6 deep dive
Mario Fusco
 
PDF
OOP and FP - Become a Better Programmer
Mario Fusco
 
PDF
Monadic Java
Mario Fusco
 
PDF
FP in Java - Project Lambda and beyond
Mario Fusco
 
PPTX
Real world DSL - making technical and business people speaking the same language
Mario Fusco
 
PDF
Introducing Drools
Mario Fusco
 
PPTX
Java 7, 8 & 9 - Moving the language forward
Mario Fusco
 
PDF
Hammurabi
Mario Fusco
 
PPT
Swiss army knife Spring
Mario Fusco
 
PDF
No more loops with lambdaj
Mario Fusco
 
PPTX
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Mario Fusco
 
PPTX
Scala - where objects and functions meet
Mario Fusco
 
Let's make a contract: the art of designing a Java API
Mario Fusco
 
OOP and FP
Mario Fusco
 
Lazy java
Mario Fusco
 
From object oriented to functional domain modeling
Mario Fusco
 
Drools 6 deep dive
Mario Fusco
 
OOP and FP - Become a Better Programmer
Mario Fusco
 
Monadic Java
Mario Fusco
 
FP in Java - Project Lambda and beyond
Mario Fusco
 
Real world DSL - making technical and business people speaking the same language
Mario Fusco
 
Introducing Drools
Mario Fusco
 
Java 7, 8 & 9 - Moving the language forward
Mario Fusco
 
Hammurabi
Mario Fusco
 
Swiss army knife Spring
Mario Fusco
 
No more loops with lambdaj
Mario Fusco
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Mario Fusco
 
Scala - where objects and functions meet
Mario Fusco
 
Ad

Recently uploaded (20)

PDF
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
 
PDF
Online Queue Management System for Public Service Offices in Nepal [Focused i...
Rishab Acharya
 
PDF
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
PDF
IDM Crack with Internet Download Manager 6.42 Build 43 with Patch Latest 2025
bashirkhan333g
 
PDF
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
PPTX
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
PDF
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
PDF
AI + DevOps = Smart Automation with devseccops.ai.pdf
Devseccops.ai
 
PDF
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
PDF
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
PPTX
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
PPTX
Empowering Asian Contributions: The Rise of Regional User Groups in Open Sour...
Shane Coughlan
 
PPTX
Tally software_Introduction_Presentation
AditiBansal54083
 
PPTX
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
PDF
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
PDF
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
PDF
Revenue streams of the Wazirx clone script.pdf
aaronjeffray
 
PPTX
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
PDF
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
 
Online Queue Management System for Public Service Offices in Nepal [Focused i...
Rishab Acharya
 
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
IDM Crack with Internet Download Manager 6.42 Build 43 with Patch Latest 2025
bashirkhan333g
 
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
AI + DevOps = Smart Automation with devseccops.ai.pdf
Devseccops.ai
 
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
Empowering Asian Contributions: The Rise of Regional User Groups in Open Sour...
Shane Coughlan
 
Tally software_Introduction_Presentation
AditiBansal54083
 
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
Revenue streams of the Wazirx clone script.pdf
aaronjeffray
 
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 

How and why I turned my old Java projects into a first-class serverless component

  • 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 c
  • 2. Agenda ➢ Declarative vs. Imperative programming ➢ What is a rule engine and how it works ➢ A simple example ➢ From drl to Java: the executable model
  • 3. Agenda ➢ Declarative vs. Imperative programming ➢ What is a rule engine and how it works ➢ A simple example ➢ From drl to Java: the executable model ➢ What is GraalVM ➢ AoT compilation ➢ Limitations ➢ Refactoring Drools to (natively) compile on GraalVM
  • 4. Agenda c ➢ Declarative vs. Imperative programming ➢ What is a rule engine and how it works ➢ A simple example ➢ From drl to Java: the executable model ➢ What is GraalVM ➢ AoT compilation ➢ Limitations ➢ Refactoring Drools to (natively) compile on GraalVM ➢ What is Quarkus ➢ Quarkus features ➢ Integrating Drools with Quarkus ➢ Writing a Quarkus extension for Drools
  • 5. What a rule-based program is ➢ A rule-based program is made up of discrete rules, each of which applies to a subset of the problem ➢ It is simpler, because you can concentrate on the rules for one situation at a time ➢ It can be more flexible in the face of fragmentary or poorly conditioned inputs ➢ Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in short, all problems without clear algorithmic solutions
  • 6. What a rule-based program is ➢ A rule-based program is made up of discrete rules, each of which applies to a subset of the problem ➢ It is simpler, because you can concentrate on the rules for one situation at a time ➢ It can be more flexible in the face of fragmentary or poorly conditioned inputs ➢ Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in short, all problems without clear algorithmic solutions Declarative (What to do) Imperative (How to do it) Vs. public void helloMark(Person person) { if ( person.getName().equals( “Mark” ) { System.out.println( “Hello Mark” ); } } rule “Hello Mark” when Person( name == “Mark” ) then System.out.println( “Hello Mark” ); end
  • 7. What a rule-based program is ➢ A rule-based program is made up of discrete rules, each of which applies to a subset of the problem ➢ It is simpler, because you can concentrate on the rules for one situation at a time ➢ It can be more flexible in the face of fragmentary or poorly conditioned inputs ➢ Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in short, all problems without clear algorithmic solutions Declarative (What to do) Imperative (How to do it) Vs. public void helloMark(Person person) { if ( person.getName().equals( “Mark” ) { System.out.println( “Hello Mark” ); } } rule “Hello Mark” when Person( name == “Mark” ) then System.out.println( “Hello Mark” ); end A method must be called directly Rules can never be called directly
  • 8. What a rule-based program is ➢ A rule-based program is made up of discrete rules, each of which applies to a subset of the problem ➢ It is simpler, because you can concentrate on the rules for one situation at a time ➢ It can be more flexible in the face of fragmentary or poorly conditioned inputs ➢ Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in short, all problems without clear algorithmic solutions Declarative (What to do) Imperative (How to do it) Vs. public void helloMark(Person person) { if ( person.getName().equals( “Mark” ) { System.out.println( “Hello Mark” ); } } rule “Hello Mark” when Person( name == “Mark” ) then System.out.println( “Hello Mark” ); end A method must be called directly Specific passing of arguments Rules can never be called directly Specific instances cannot be passed but are automatically selected with pattern-matching
  • 9. Introducing ➢ Easier to understand → Requirements can be more naturally translated into rules. It is more likely for a technically skilled business analyst to verify, validate or even change a rule than a piece of Java code ➢ Improved maintainability → We don't care about how to implement a solution only what needs to be done to solve a problem ➢ Deals with evolving complexity → It's easier to modify a rule than a Java program and to determine the impact of this change on the rest of the application ➢ Modularity → Each rule models an isolated and small portion of your business logic and is not part of a monolithic program ➢ Clear separation of business logic from the rest of the system → Business and infrastructural code have very different lifecycles ➢ Complex Event Processing → Facts can be handled like timestamped events allowing temporal reasoning on them RULES
  • 10. How a rule-based system works ➢ The Rule Base contains a computation efficient representation of the set of the defined rules ➢ The Working Memory contains the set of facts inserted into sessions ➢ The engine matches the fact in the working memory against the rules set ➢ When a match is found it creates an activation and put it into the agenda ➢ An activation is the tuple of facts matching the conditions of a rule plus the rule itself ➢ When all activations have been created the agenda elects through a conflict resolution strategy the one to be executed ➢ The elected activation is passed to the execution engine and the fired
  • 11. A simple rule set rule RaiseAlarm when exists Fire() then insert( new Alarm( "house1" ) ); System.out.println( "Raise the Alarm"); end rule CancelAlarm when not Fire() a : Alarm() then delete( a ); System.out.println( "Cancel the Alarm"); end rule TurnSprinklerOn when s : Sprinkler( on == false ) f : Fire( room == s.room ) then modify( s ) { setOn( true ) } System.out.println( "Turn on the sprinkler for room " + f.getRoom().getName() ); end rule TurnSprinklerOff when s : Sprinkler( on == true ) not Fire( room == s.room ) then modify( s ) { setOn( false ) } System.out.println( "Turn off the sprinkler for room " + s.getRoom().getName() ); end rule OK when not Alarm() not Sprinkler( on == true ) then System.out.println( "Everything is ok" ); end Pattern-matching against objects in the Working Memory Code executed when a match is found
  • 12. 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
  • 13. AoT compilation with GraalVM ➢ Static analysis ➢ Closed world assumption ➢ Dead code elimination:      classes, fields, methods, branches
  • 14. 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
  • 15. 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 ); } }
  • 16. 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 ); } }
  • 17. 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
  • 18. 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
  • 19. 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)
  • 20. 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
  • 21. 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() )) )
  • 22. 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() )) )
  • 23. 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
  • 24. 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
  • 25. 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
  • 26. 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"));
  • 27. 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 }
  • 28. Demo 1 Drools on GraalVM
  • 29. Introducing ➢ A Framework for writing (fast and lightweight) Java applications
  • 30. 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
  • 31. 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
  • 32. 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
  • 35. Fast, lightweight Drools = Submarine The question of whether a computer can think is no more interesting than the question of whether a submarine can swim - Edsger W. Dijkstra
  • 36. Integrating Quarkus and Drools Writing a Quarkus extension public class ExecutableModelGenerator { private static final String PRODUCER_SOURCE = "package io.quarkus.drools.runtime;n" + "import org.drools.modelcompiler.KieRuntimeBuilder;n" + "n" + "@javax.inject.Singletonn" + "public class RuntimeProducer {n" + " public static final KieRuntimeBuilder INSTANCE = new org.drools.project.model.ProjectRuntime();n" + "n" + " @javax.enterprise.inject.Producesn" + " public KieRuntimeBuilder produce() { return INSTANCE; }n" + "}"; @BuildStep(providesCapabilities = "io.quarkus.drools") @Record(STATIC_INIT) public void generateModel( ArchiveRootBuildItem root, BuildProducer<GeneratedBeanBuildItem> generatedBeans, BuildProducer<GeneratedClassBuildItem> generatedClasses) { MemoryFileSystem srcMfs = new MemoryFileSystem(); String[] sources = generateSources(root, srcMfs); srcMfs.write(toRuntimeSource(PRODUCER_CLASSNAME), PRODUCER_SOURCE.getBytes()); sources[sources.length - 1] = toRuntimeSource(PRODUCER_CLASSNAME); registerGeneratedClasses(generatedBeans, generatedClasses, compileSources(srcMfs, sources)); } private void registerGeneratedClasses( BuildProducer<GeneratedBeanBuildItem> generatedBeans, BuildProducer<GeneratedClassBuildItem> generatedClasses, MemoryFileSystem trgMfs) { for (String fileName : trgMfs.getFileNames()) { String className = toClassName(fileName); if (className.equals(PRODUCER_CLASSNAME)) { generatedBeans.produce(new GeneratedBeanBuildItem(className, trgMfs.getBytes(fileName))); } else { generatedClasses.produce(new GeneratedClassBuildItem(true, className, trgMfs.getBytes(fileName))); } } } }
  • 37. A simple Quarkus-based REST endopint using Drools @Path("/candrink/{name}/{age}") public class CanDrinkResource { @Inject KieRuntimeBuilder runtimeBuilder; @GET @Produces(MediaType.TEXT_PLAIN) public String canDrink( @PathParam("name") String name, @PathParam("age") int age ) { KieSession ksession = runtimeBuilder.newKieSession("canDrinkKS"); Result result = new Result(); ksession.insert(result); ksession.insert(new Person( name, age )); ksession.fireAllRules(); return result.toString(); } }
  • 38. Demo 2 Drools on Quarkus
  • 39. Mario Fusco Red Hat – Principal Software Engineer [email protected] twitter: @mariofusco Q A Thanks ... Questions?