Event-driven business automation powered by cloud native Java

Event-driven business automation powered by cloud native Java

2020/01/30 JJUG x JJBUG共催ナイトセミナー「cloud native business automation for Java」のスライドです。

Db3a590d9699ed3687641c46ee14b023?s=128

Toshiya Kobayashi

January 31, 2020
Tweet

Transcript

  1. Event-driven business automation powered by cloud native Java Mario Fusco,

    Maciej Swiderski, Edoardo Vacchi
  2. 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
  3. 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
  4. Drools A Rule Engine

  5. 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 <CONDITIONS> THEN <ACTIONS>
  6. 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
  7. 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
  8. 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
  9. jBPM A Workflow Engine

  10. 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.
  11. 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
  12. jBPM … a business process

  13. Orchestration vs Choreography

  14. Orchestration vs Choreography Conductor vs Reactor pattern

  15. Orchestration vs Choreography Conductor vs Reactor pattern Why not use

    whatever fits the use case?
  16. Kogito Business Automation in the Cloud

  17. • 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
  18. • 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
  19. 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
  20. Kogito, ergo automate • BTW, this is not Mario •

    Not a pirate • It is a viking • Odin, who sacrificed his eye for knowledge
  21. • 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
  22. Kogito ergo domain

  23. • 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
  24. Kogito ergo power

  25. • 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
  26. Kogito ergo cloud

  27. • 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
  28. Quarkus Supersonic Subatomic Java

  29. Introducing Quarkus • A Framework for writing (fast and lightweight)

    Java applications
  30. • A Framework for writing (fast and lightweight) Java applications

    • Code generation reduces startup time and memory footprint (bonus: GraalVM native image) Introducing Quarkus
  31. • 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
  32. Quarkus Extensions

  33. Why Quarkus

  34. 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
  35. 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
  36. 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
  37. 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
  38. Startup Time Optimization

  39. 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
  40. 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
  41. 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
  42. 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)
  43. 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
  44. Demo Native Mode

  45. JVM vs. Native

  46. JVM vs. Native - Startup time

  47. JVM vs. Native - Response time

  48. Kogito Architecture

  49. Architecture

  50. • 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
  51. • 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
  52. Demo Travel Agency on OpenShift

  53. Runtime Service • Exposes business logic as service ◦ processes

    ◦ rules ◦ decisions • Lightweight and fast • Allows to build on top of ◦ Quarkus ◦ Spring Boot • Extendable
  54. 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
  55. Demo Travel Agency on OpenShift with persistence

  56. 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
  57. Demo Travel Agency on OpenShift with data index

  58. • Messaging (Kafka and AMQ) • Optionally equipped with monitoring

    and tracing capabilities • Monitoring (Prometheus) • Visualization (Grafana) Uses existing and well known tools
  59. Demo Complete Kogito Travel Agency

  60. Kogito Travel Agency

  61. Questions?

  62. Get started http://kogito.kie.org

  63. Bonus track GraalVM

  64. 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
  65. AoT compilation with GraalVM • Static analysis • Closed world

    assumption • Dead code elimination: classes, fields, methods, branches
  66. 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
  67. 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 ); } }
  68. 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 ); } }
  69. 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
  70. 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
  71. 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
  72. 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
  73. 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
  74. 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"));
  75. 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 }
  76. Get started http://kogito.kie.org