Slide 1

Slide 1 text

Event-driven business automation powered by cloud native Java Mario Fusco, Maciej Swiderski, Edoardo Vacchi

Slide 2

Slide 2 text

Agenda ● What is business automation: introduction to Drools and jBPM ● Event-Driven Business Automation with Kogito ● Cloud-native business automation on Openshift + ● Quarkus: an open source stack to write cloud native Java apps

Slide 3

Slide 3 text

What is Business Automation ● Processes Set of activities and tasks that, once completed following a specific workflow, will accomplish an organizational goal ● Rules Encapsulate domain and define business-specific constraints and behaviors, keeping them separated from the main application flow

Slide 4

Slide 4 text

Drools A Rule Engine

Slide 5

Slide 5 text

What is a Rule ● A business rule is a piece of logic that captures "what to do" depending on a context (Facts) ● Usually captured in natural language first WHEN THEN

Slide 6

Slide 6 text

Introducing Drools ● 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 life cycles ● Complex Event Processing → Facts can be handled like timestamped events allowing temporal reasoning on them RULES

Slide 7

Slide 7 text

How a Rule Engine 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 session ● The engine matches the fact in the working memory against the rules set ● When a match is found it creates an activation and puts 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 first ● The elected activation is passed to the execution engine and then fired

Slide 8

Slide 8 text

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 fired

Slide 9

Slide 9 text

jBPM A Workflow Engine

Slide 10

Slide 10 text

Almost anything in any domain can be expressed as process or rule. It’s a matter of recognizing patterns to be able to avoid repetition and mistakes, and by that automating business.

Slide 11

Slide 11 text

jBPM provides various capabilities that simplify and externalize business logic into reusable assets such as cases, processes, decision tables and more. It consists of: ● business processes (BPMN2) ● case management (BPMN2 and CMMN) ● decision management (DMN) ● business rules (DRL) A toolkit for building business applications to help automate business processes and decisions

Slide 12

Slide 12 text

jBPM … a business process

Slide 13

Slide 13 text

Orchestration vs Choreography

Slide 14

Slide 14 text

Orchestration vs Choreography Conductor vs Reactor pattern

Slide 15

Slide 15 text

Orchestration vs Choreography Conductor vs Reactor pattern Why not use whatever fits the use case?

Slide 16

Slide 16 text

Kogito Business Automation in the Cloud

Slide 17

Slide 17 text

● World around us has changed ● New deployment techniques ● Better usage of machine and cluster resources ● Fat application servers vs lean serverless/FaaS architectures The reasons for a change

Slide 18

Slide 18 text

● If you think about business automation think about the cloud as this is where your business logic lives these days ● Achieves amazingly fast boot time and low memory footprint by leveraging latest technology ○ Quarkus ○ Kubernetes ○ OpenShift ○ KNative The reasons for a change

Slide 19

Slide 19 text

Cogito, ergo sum Pronunciation /ˈko.d ͡ ʒi.to/, [ˈkoː.d ͡ ʒi.to] (Don't worry, nobody in the team gets it right, anyway) see also: http://kverlaen.blogspot.com/2019/09/etymology-of-kogito.html René Descartes

Slide 20

Slide 20 text

Kogito, ergo automate ● BTW, this is not Mario ● Not a pirate ● It is a viking ● Odin, who sacrificed his eye for knowledge

Slide 21

Slide 21 text

● A cloud-native development, deployment and execution platform for business automation: ○ Rules and Decisions ○ Processes and Cases ● ... 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 Kogito

Slide 22

Slide 22 text

Kogito ergo domain

Slide 23

Slide 23 text

● Adapts to your business domain instead of the other way around ● No more leaking of abstractions of the platform into your client applications ● Stay focused on business requirements instead of implementation technology Focus on business domain instead of technology

Slide 24

Slide 24 text

Kogito ergo power

Slide 25

Slide 25 text

● Achieve instant developer efficiency by having ○ Tooling embeddable wherever you need it ○ Code generation taking care of 80% of the work ○ Flexibility to customize, only use what you need ○ Simplified local development with live reload Offers a powerful developer experience

Slide 26

Slide 26 text

Kogito ergo cloud

Slide 27

Slide 27 text

● If you think about business automation think about the cloud as this is where your business logic lives these days ● Achieves amazingly fast boot time and low memory footprint by leveraging newest technology ○ Quarkus ○ Kubernetes/OpenShift/KNative Designed from ground up to run at scale

Slide 28

Slide 28 text

Quarkus Supersonic Subatomic Java

Slide 29

Slide 29 text

Introducing Quarkus ● A Framework for writing (fast and lightweight) Java applications

Slide 30

Slide 30 text

● A Framework for writing (fast and lightweight) Java applications ● Code generation reduces startup time and memory footprint (bonus: GraalVM native image) Introducing Quarkus

Slide 31

Slide 31 text

● A Framework for writing (fast and lightweight) Java applications ● Code generation reduces startup time and memory footprint (bonus: GraalVM native image) ● Exposes existing standard ○ Servlet ○ JAX-RS ○ JPA, JDBC ○ CDI ○ Bean Validation ○ Transactions ○ Logging ○ Microprofile Introducing Quarkus

Slide 32

Slide 32 text

Quarkus Extensions

Slide 33

Slide 33 text

Why Quarkus

Slide 34

Slide 34 text

Hot Reload ● ./mvn compile quarkus:dev makes Quarkus run in dev mode and provide hot-reload capabilities ● Changes made to source and configuration files are automatically re-compiled once the browser is refreshed ● Thanks to Kogito’s Quarkus extension, also Drools and jBPM files are recognized as hot reloadable artifacts and the corresponding rules and processes are regenerated

Slide 35

Slide 35 text

Demo Kogito Travel Agency.. the beginning ● Travel request handling service ○ deals with Travel requests submitted by travellers ○ assesses if there is a need for visa ○ books hotel and flights ○ awaits confirmation from traveller ● Single service that ○ exposes REST api ○ provides simple UI

Slide 36

Slide 36 text

Demo Instructions ● install VSCode ● install Kogito extension $ curl -L http://bit.ly/get-kogito-ext | sh ● You can also install manually - download vsix from https://github.com/kiegroup/kogito-tooling/releases/tag/0.2.0 - install from vsix in VSCode

Slide 37

Slide 37 text

Demo Instructions $ git clone https://github.com/mswiderski/devoxx-be-2019 $ cd devoxx-be-2019/1-kogito-travel-agency $ code . $ mvn compile quarkus:dev point your browser to http://localhost:8080

Slide 38

Slide 38 text

Startup Time Optimization

Slide 39

Slide 39 text

Startup Time Optimization ● Quarkus and Kogito philosophy is to move as much as possible at build-time of what formerly was done at compile-time ● Ahead-of-time optimizations ○ Dead code elimination ○ Code generation instead of reflection + dynamic class loading ● Starts key parts of application ahead-of-time

Slide 40

Slide 40 text

Executable Model at a Glance ● A pure Java DSL for rules and processes 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

Slide 41

Slide 41 text

Executable Model at a Glance ● Avoid: ○ unnecessary reflection ○ unnecessary dynamic class loading ○ process as much info at compile time ● Benefits ○ faster startup-time ○ enable ahead-of-time native compilation

Slide 42

Slide 42 text

Executable Model at a Glance ● Avoid: ○ unnecessary reflection ○ unnecessary dynamic class loading ○ process as much info at compile time ● Benefits ○ faster startup-time ○ enable ahead-of-time native compilation Shameless Plug: Your Program as a Transpiler: Applying Compiler Design to Everyday Programming Wednesday @ 12:00 -- Room 9 (Edoardo)

Slide 43

Slide 43 text

Native Mode ● Quarkus allows to generate an operating system specific (aka native) executable from your Java code ● Trade-offs: lack of build-once-run-anywhere and hot reload capabilities VS. lower on-disk footprint and quicker startup time ● Perfect fit for serverless/event-driven environments where we need to spin up a service in real time to react to an event ● Statically compiled executables benefit from closed-world optimizations, such as fine-grained dead-code elimination, where only the portions of frameworks (including the JDK itself) actually in use by the service are included in the resulting image

Slide 44

Slide 44 text

Demo Native Mode

Slide 45

Slide 45 text

JVM vs. Native

Slide 46

Slide 46 text

JVM vs. Native - Startup time

Slide 47

Slide 47 text

JVM vs. Native - Response time

Slide 48

Slide 48 text

Kogito Architecture

Slide 49

Slide 49 text

Architecture

Slide 50

Slide 50 text

● Responsible for building with selected runtime ○ Quarkus ○ Spring Boot ● Provision services on demand and remove them when no longer needed ● Manage deployed services including their dependencies ● Service discovery based on labels ● Guarding services of losing their dependants ● Security provisioning and propagation Operator

Slide 51

Slide 51 text

● Deploy and manage your services with operator and intuitive CLI tool ○ kogito new-app travel-agency Create new OpenShift project with default services provisioned ○ kogito deploy travel-agency https://github.com/.../travelapp Deploys given application from source and attaches to required infrastructure ○ kogito deploy visas https://github.com/.../visasapp Deploys given application from source and attaches to required infrastructure Designed from ground up to run at scale

Slide 52

Slide 52 text

Demo Travel Agency on OpenShift

Slide 53

Slide 53 text

Runtime Service ● Exposes business logic as service ○ processes ○ rules ○ decisions ● Lightweight and fast ● Allows to build on top of ○ Quarkus ○ Spring Boot ● Extendable

Slide 54

Slide 54 text

Persistence ● Backed by key value storage - string -> byte[] ● Infinispan used as default persistent store ● Stores ○ Process Instance and Node Instance information ○ Process Instance variables ■ Marshalling of both process/node instance and variables is done by protobuf ● Each process definition is stored in its own cache to improve management and concurrency

Slide 55

Slide 55 text

Demo Travel Agency on OpenShift with persistence

Slide 56

Slide 56 text

Data Index ● Captures all events related to runtime processing ○ processes ○ user tasks ○ decision and rules ● Indexes it in domain specific way ● Exposes GraphQL based API ● Provides unified view on technical aspects of the running services

Slide 57

Slide 57 text

Demo Travel Agency on OpenShift with data index

Slide 58

Slide 58 text

● Messaging (Kafka and AMQ) ● Optionally equipped with monitoring and tracing capabilities ● Monitoring (Prometheus) ● Visualization (Grafana) Uses existing and well known tools

Slide 59

Slide 59 text

Demo Complete Kogito Travel Agency

Slide 60

Slide 60 text

Kogito Travel Agency

Slide 61

Slide 61 text

Questions?

Slide 62

Slide 62 text

Get started http://kogito.kie.org

Slide 63

Slide 63 text

Bonus track GraalVM

Slide 64

Slide 64 text

What is GraalVM 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

Slide 65

Slide 65 text

AoT compilation with GraalVM ● Static analysis ● Closed world assumption ● Dead code elimination: classes, fields, methods, branches

Slide 66

Slide 66 text

Fast process start Less memory Small size on disk AoT compilation with GraalVM ● Static analysis ● Closed world assumption ● Dead code elimination: classes, fields, methods, branches

Slide 67

Slide 67 text

GraalVM Limitations Dynamic Classloading Deploying 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 ); } }

Slide 68

Slide 68 text

GraalVM Limitations Dynamic Classloading Deploying 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 ); } }

Slide 69

Slide 69 text

public class InternalClassLoader extends ClassLoader { public Class> defineClass( String name, byte[] bytecode ) { return defineClass( name, bytecode, 0, bytecode.length ); } } GraalVM Limitations JVMTI, JMX + other native VM interfaces No agents → No JRebel, Byteman, profilers, tracers Dynamic Classloading Deploying jars, wars, etc. at runtime impossible Miscellaneous ● Security Manager ● finalize() (deprecated anyway) ● InvokeDynamic and MethodHandle

Slide 70

Slide 70 text

public class InternalClassLoader extends ClassLoader { public Class> defineClass( String name, byte[] bytecode ) { return defineClass( name, bytecode, 0, bytecode.length ); } } GraalVM Limitations JVMTI, JMX + other native VM interfaces No agents → No JRebel, Byteman, profilers, tracers Miscellaneous ● Security Manager ● finalize() (deprecated anyway) ● InvokeDynamic and MethodHandle Dynamic Classloading Deploying jars, wars, etc. at runtime impossible

Slide 71

Slide 71 text

public class InternalClassLoader extends ClassLoader { public Class> defineClass( String name, byte[] bytecode ) { return defineClass( name, bytecode, 0, bytecode.length ); } } GraalVM Limitations JVMTI, JMX + other native VM interfaces No agents → No JRebel, Byteman, profilers, tracers Reflection Requires registration (closed world assumption) Miscellaneous ● Security Manager ● finalize() (deprecated anyway) ● InvokeDynamic and MethodHandle Dynamic Classloading Deploying jars, wars, etc. at runtime impossible

Slide 72

Slide 72 text

public class InternalClassLoader extends ClassLoader { public Class> defineClass( String name, byte[] bytecode ) { return defineClass( name, bytecode, 0, bytecode.length ); } } GraalVM Limitations JVMTI, JMX + other native VM interfaces No agents → No JRebel, Byteman, profilers, tracers [ { "name" : "org.domain.model.Person", "allPublicConstructors" : true, "allPublicMethods" : true } ] Reflection Requires registration (closed world assumption) -H:ReflectionConfigurationFiles=src/main/resources/reflection.json Miscellaneous ● Security Manager ● finalize() (deprecated anyway) ● InvokeDynamic and MethodHandle Dynamic Classloading Deploying jars, wars, etc. at runtime impossible

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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 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"));

Slide 75

Slide 75 text

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 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, Object> serviceMap = new HashMap<>(); void wireServices() { serviceMap.put( ServiceInterface.class, Class.forName("org.drools.ServiceImpl") .newInstance()); // … more services here }

Slide 76

Slide 76 text

Get started http://kogito.kie.org