What's Kogito

Kogito is a cloud-native business automation toolkit that's here to make your life easier. Think of it as the love child of business process management (BPM) and decision management, raised in the cloud by its doting parent, Quarkus.

But why should you, a seasoned developer, give Kogito the time of day? Here's the TL;DR:

  • It's cloud-native and Kubernetes-ready out of the box
  • It plays nice with Quarkus, giving you supersonic, subatomic Java powers
  • It turns your business processes and decisions into first-class citizens in your codebase
  • It's open-source and backed by the Apache Software Foundation (currently in incubation)

Diving into the Kogito Examples Repository

Now that we've piqued your interest, let's take a tour of the apache/incubator-kie-kogito-examples repository. This treasure trove of examples is your ticket to Kogito mastery.

Setting Up Your Kogito Playground

Before we dive in, let's make sure you have everything you need to run these examples:

  • Java 11+ (because we're not savages)
  • Maven 3.8.1+
  • Docker (for those containerization cravings)
  • Quarkus CLI (optional, but highly recommended for that extra productivity boost)

Got all that? Great! Now let's get our hands dirty.

Quarkus: Kogito's Partner in Crime

You might be wondering, "What's Quarkus got to do with it?" Well, everything. Quarkus is the supersonic, subatomic Java framework that gives Kogito its cloud-native superpowers. It's like Red Bull for your Java applications, but without the caffeine jitters.

Kogito leverages Quarkus to:

  • Achieve lightning-fast startup times
  • Reduce memory footprint (your wallet will thank you)
  • Provide hot reload capabilities (because who has time for restarts?)
  • Offer seamless integration with cloud-native technologies

Exploring the Kogito Examples: A Whirlwind Tour

Let's take a look at some of the juiciest examples in the repository:

1. Process + Rules: The Dynamic Duo

Navigate to the kogito-quarkus-examples/process-business-rules-quarkus directory. This example showcases how Kogito combines processes and rules to create a powerful decision-making engine.

Key takeaways:

  • Integration of BPMN2 processes with DMN decision tables
  • Automatic REST endpoint generation for your processes
  • Seamless rule execution within process contexts

2. Serverless Workflow: Because Servers are So Last Decade

Check out the serverless-workflow-examples/serverless-workflow-greeting-quarkus example. This one's for all you serverless enthusiasts out there.

Highlights:

  • YAML-defined workflows (because who doesn't love YAML?)
  • Event-driven architectures made easy
  • Integrations with AWS Lambda and Knative

3. DMN: Making Decisions Great Again

Head over to kogito-quarkus-examples/dmn-quarkus-example for a deep dive into Decision Model and Notation (DMN) with Kogito.

What you'll learn:

  • Modeling complex decision logic visually
  • Automatic REST API generation for your decision services
  • Testing and debugging DMN models like a pro

Running Your First Kogito Example: A Step-by-Step Guide

Enough theory, let's get our hands dirty! We'll use the process-business-rules-quarkus example to get you started.

Once it's running, test the API:

curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"person": {"name":"John Doe", "age": 25}}' http://localhost:8080/persons

Build and run the example:

./mvnw clean compile quarkus:dev

Clone the repository:

git clone https://github.com/apache/incubator-kie-kogito-examples.git
cd incubator-kie-kogito-examples/kogito-quarkus-examples/process-business-rules-quarkus

Voilà! You've just executed a business process with embedded rules using Kogito. Feel the power coursing through your veins?

Implementing Business Processes: BPMN and DMN, Oh My!

Kogito brings BPMN (Business Process Model and Notation) and DMN (Decision Model and Notation) into the 21st century. Gone are the days of clunky, heavyweight BPM engines. With Kogito, your processes and decisions are first-class citizens in your codebase.

BPMN: Flowcharts on Steroids

Let's look at a simple BPMN process:

<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" id="_6063f3a1-5ba3-4f0e-b1f2-ad49e8e6f2a7" targetNamespace="http://www.omg.org/bpmn20">
  <bpmn2:process id="greeting" name="Greeting Process" isExecutable="true">
    <bpmn2:startEvent id="_1" name="StartProcess">
      <bpmn2:outgoing>_1-_2</bpmn2:outgoing>
    </bpmn2:startEvent>
    <bpmn2:scriptTask id="_2" name="Hello" scriptFormat="http://www.java.com/java">
      <bpmn2:incoming>_1-_2</bpmn2:incoming>
      <bpmn2:outgoing>_2-_3</bpmn2:outgoing>
      <bpmn2:script>System.out.println("Hello World");</bpmn2:script>
    </bpmn2:scriptTask>
    <bpmn2:endEvent id="_3" name="EndProcess">
      <bpmn2:incoming>_2-_3</bpmn2:incoming>
    </bpmn2:endEvent>
    <bpmn2:sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2"/>
    <bpmn2:sequenceFlow id="_2-_3" sourceRef="_2" targetRef="_3"/>
  </bpmn2:process>
</bpmn2:definitions>

This simple process just prints "Hello World", but imagine the possibilities when you start integrating with your business logic and external systems!

DMN: Decisions, Decisions

Now, let's take a peek at a DMN model:

<?xml version="1.0" encoding="UTF-8"?>
<dmn:definitions xmlns:dmn="http://www.omg.org/spec/DMN/20180521/MODEL/" xmlns="https://kiegroup.org/dmn/_52CEF9FD-9943-4A89-96D5-6F66810CA4C1" xmlns:di="http://www.omg.org/spec/DMN/20180521/DI/" xmlns:kie="http://www.drools.org/kie/dmn/1.2" xmlns:dmndi="http://www.omg.org/spec/DMN/20180521/DMNDI/" xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/" id="_4F7C97F9-EA35-4CB5-8E4C-C40C91B5F729" name="Greeting" typeLanguage="http://www.omg.org/spec/DMN/20180521/FEEL/" namespace="https://kiegroup.org/dmn/_52CEF9FD-9943-4A89-96D5-6F66810CA4C1">
  <dmn:decision id="_23B84E59-33C6-4D3A-9314-CF0724714606" name="Greeting Message">
    <dmn:extensionElements/>
    <dmn:variable id="_078A6F79-1861-47A1-8921-C9E7F2B728D1" name="Greeting Message" typeRef="string"/>
    <dmn:informationRequirement id="_2066A270-2A88-4B77-9F90-1F683FDF852C">
      <dmn:requiredInput href="#_C7ED7EFC-9F7F-4FBE-81DB-57A32A56502C"/>
    </dmn:informationRequirement>
    <dmn:decisionTable id="_5A25D948-34E0-4527-9EE2-7A9C0DC663A5" hitPolicy="UNIQUE" preferredOrientation="Rule-as-Row">
      <dmn:input id="_79ECD1F2-E11E-4F6D-9038-C47AE6EC1C9C">
        <dmn:inputExpression id="_E17A0C1D-A0F0-4C5F-8A0E-8B5F9A1BAB08" typeRef="number">
          <dmn:text>Age</dmn:text>
        </dmn:inputExpression>
      </dmn:input>
      <dmn:output id="_EC6A4902-BD03-4D48-AA45-9AD2AEB83E8B"/>
      <dmn:annotation name="annotation-1"/>
      <dmn:rule id="_C3F28427-2608-4ACE-98EE-C5C2F0AEF7A7">
        <dmn:inputEntry id="_0FBE3F3C-5F3A-4A21-A4A5-D207B2BA7808">
          <dmn:text>< 18</dmn:text>
        </dmn:inputEntry>
        <dmn:outputEntry id="_C05BE7BB-BDA0-4C45-9ED1-4F5B17B2A3E6">
          <dmn:text>"Hello young person!"</dmn:text>
        </dmn:outputEntry>
        <dmn:annotationEntry>
          <dmn:text/>
        </dmn:annotationEntry>
      </dmn:rule>
      <dmn:rule id="_C3B07D74-0354-4C44-9587-9B44C67F5AE0">
        <dmn:inputEntry id="_8A9B0EEC-5CB9-4D31-BB56-0A723CEABFBC">
          <dmn:text>>= 18</dmn:text>
        </dmn:inputEntry>
        <dmn:outputEntry id="_42C4EB7F-3F00-4A19-9F43-D2E246F378F9">
          <dmn:text>"Hello adult!"</dmn:text>
        </dmn:outputEntry>
        <dmn:annotationEntry>
          <dmn:text/>
        </dmn:annotationEntry>
      </dmn:rule>
    </dmn:decisionTable>
  </dmn:decision>
  <dmn:inputData id="_C7ED7EFC-9F7F-4FBE-81DB-57A32A56502C" name="Age">
    <dmn:extensionElements/>
    <dmn:variable id="_F0B70F13-94CB-4FB9-BD89-4AB84F8BDB07" name="Age" typeRef="number"/>
  </dmn:inputData>
  <dmndi:DMNDI>
    <dmndi:DMNDiagram>
      <di:extension>
        <kie:ComponentsWidthsExtension>
          <kie:ComponentWidths dmnElementRef="_5A25D948-34E0-4527-9EE2-7A9C0DC663A5">
            <kie:width>50</kie:width>
            <kie:width>100</kie:width>
            <kie:width>100</kie:width>
            <kie:width>100</kie:width>
          </kie:ComponentWidths>
        </kie:ComponentsWidthsExtension>
      </di:extension>
      <dmndi:DMNShape id="dmnshape-_23B84E59-33C6-4D3A-9314-CF0724714606" dmnElementRef="_23B84E59-33C6-4D3A-9314-CF0724714606" isCollapsed="false">
        <dmndi:DMNStyle>
          <dmndi:FillColor red="255" green="255" blue="255"/>
          <dmndi:StrokeColor red="0" green="0" blue="0"/>
          <dmndi:FontColor red="0" green="0" blue="0"/>
        </dmndi:DMNStyle>
        <dc:Bounds x="364" y="227" width="100" height="50"/>
        <dmndi:DMNLabel/>
      </dmndi:DMNShape>
      <dmndi:DMNShape id="dmnshape-_C7ED7EFC-9F7F-4FBE-81DB-57A32A56502C" dmnElementRef="_C7ED7EFC-9F7F-4FBE-81DB-57A32A56502C" isCollapsed="false">
        <dmndi:DMNStyle>
          <dmndi:FillColor red="255" green="255" blue="255"/>
          <dmndi:StrokeColor red="0" green="0" blue="0"/>
          <dmndi:FontColor red="0" green="0" blue="0"/>
        </dmndi:DMNStyle>
        <dc:Bounds x="365" y="94" width="100" height="50"/>
        <dmndi:DMNLabel/>
      </dmndi:DMNShape>
      <dmndi:DMNEdge id="dmnedge-_2066A270-2A88-4B77-9F90-1F683FDF852C" dmnElementRef="_2066A270-2A88-4B77-9F90-1F683FDF852C">
        <di:waypoint x="415" y="119"/>
        <di:waypoint x="414" y="252"/>
      </dmndi:DMNEdge>
    </dmndi:DMNDiagram>
  </dmndi:DMNDI>
</dmn:definitions>

This DMN model decides on a greeting based on a person's age. It's a simple example, but imagine scaling this to complex business rules and decision-making processes!

Customizing Rules and Decisions: Your Way or the Highway

Kogito doesn't just give you out-of-the-box rules and decisions. It lets you customize them to fit your unique business needs. Here are a few ways to flex those customization muscles:

1. Drools Rule Language (DRL)

For those times when visual models just won't cut it, you can use good old DRL:

package org.acme.rules

import org.acme.model.Person

rule "Greet adults"
when
    $person: Person(age >= 18)
then
    System.out.println("Hello, responsible adult!");
end

rule "Greet children"
when
    $person: Person(age < 18)
then
    System.out.println("Hi, youngster! Where are your parents?");
end

2. Decision Tables

For business users who break out in hives at the sight of code, decision tables are a godsend:

RuleSet,org.acme.rules
RuleSetName,Greeting Rules

RuleTable Greeting
CONDITION,ACTION
Person.age,System.out.println
>=18,"Hello, responsible adult!"
<18,"Hi, youngster! Where are your parents?"

3. Extending DMN with Custom Functions

Need some extra oomph in your DMN models? Extend them with custom Java functions:

@DMNFunction(name = "toUpperCase")
public static String toUpperCase(String input) {
    return input.toUpperCase();
}

Now you can use toUpperCase() in your DMN expressions. Neat, huh?

Integrating Kogito with the Outside World

Kogito plays well with others. Let's look at how to integrate it with some popular external systems:

REST APIs: Because SOAP is for Washing

Kogito automatically generates REST endpoints for your processes and decisions. But what if you need to call an external REST API? Easy peasy:

@Inject
RestClient myExternalService;

@POST
@Path("/process")
public Response startProcess(ProcessPayload payload) {
    // Start your Kogito process
    ProcessInstance<?> processInstance = processService.createProcessInstance(...);
    
    // Call external REST API
    ExternalData data = myExternalService.getData(payload.getId());
    
    // Update process variables
    processInstance.updateVariables(Collections.singletonMap("externalData", data));
    
    return Response.ok(processInstance).build();
}

Kafka: For Those Event-Driven Moments

Kogito and Kafka go together like peanut butter and jelly. Here's a taste:

@Inject
Emitter<PersonEvent> personEventEmitter;

@POST
@Path("/persons")
public Response createPerson(Person person) {
    // Your Kogito process logic here
    
    // Emit an event to Kafka
    personEventEmitter.send(new PersonEvent(person));
    
    return Response.ok(person).build();
}

Don't forget to configure your Kafka connection in application.properties:

mp.messaging.outgoing.person-events.connector=smallrye-kafka
mp.messaging.outgoing.person-events.topic=person-events
mp.messaging.outgoing.person-events.value.serializer=io.quarkus.kafka.client.serialization.JsonbSerializer

Debugging Kogito: When Things Go Sideways

Even the best developers sometimes find themselves in a debugging pickle. Here are some tips to keep you sane:

1. Enable Debug Logging

First things first, crank up that logging:

quarkus.log.category."org.kie".level=DEBUG
quarkus.log.category."org.drools".level=DEBUG
quarkus.log.category."org.jbpm".level=DEBUG

2. Use the Kogito Dev UI

Kogito comes with a slick Dev UI. Just add this dependency:

<dependency>
    <groupId>org.kie.kogito</groupId>
    <artifactId>kogito-addons-quarkus-process-management</artifactId>
</dependency>

Now you can access http://localhost:8080/q/dev to see your processes and decisions in action.

3. Test, Test, Test

Unit tests are your friends. Here's a quick example:

@QuarkusTest
public class GreetingProcessTest {

    @Inject
    ProcessService processService;

    @Test
    public void testGreetingProcess() {
        ProcessInstance<?> processInstance = processService.createProcessInstance(
            "greeting",
            Collections.singletonMap("name", "John")
        );
        
        assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED);
        assertThat(processInstance.variables()).containsEntry("greeting", "Hello, John!");
    }
}

Performance Tuning: Make It Go Vroom

Kogito is fast, but with these tips, you can make it break the sound barrier:

1. Native Compilation

Quarkus offers native compilation, which can significantly reduce startup time and memory usage:

./mvnw package -Pnative

2. Reactive Programming

Embrace the reactive paradigm for better scalability:

@Inject
ReactiveProcessService processService;

@POST
@Path("/process")
public Uni<ProcessInstance<?>> startProcess(ProcessPayload payload) {
    return processService.createProcessInstance("myProcess", payload.toMap());
}

3. Caching

Use Quarkus' built-in caching capabilities to speed up frequent operations:

@CacheResult(cacheName = "greeting-cache")
public String getGreeting(String name) {
    // Expensive operation here
    return "Hello, " + name + "!";
}

Best Practices: Do's and Don'ts

Let's wrap up with some golden rules for Kogito development:

Do:

  • Keep your processes and decisions simple and modular
  • Use meaningful names for your BPMN and DMN elements
  • Leverage Quarkus' hot reload for rapid development
  • Document your processes and decisions (your future self will thank you)
  • Use version control for your BPMN and DMN files

Don't:

  • Put business logic in your process diagrams (use service tasks instead)
  • Neglect error handling in your processes
  • Forget about monitoring and observability
  • Ignore security best practices (Kogito isn't magical security pixie dust)

Real-World Kogito: Not Just a Pretty Face

Kogito isn't just for toy examples. It's being used in the wild for some serious business automation. Here are a few real-world applications:

  • Financial Services: Automating loan approval processes and fraud detection
  • Healthcare: Managing patient workflows and insurance claim processing
  • E-commerce: Orchestrating order fulfillment and returns processes
  • Manufacturing: Optimizing supply chain decisions and quality control processes

Contributing to Kogito: Join the Cool Kids' Club

Feeling inspired? Want to give back to the community? Here's how you can contribute to Kogito:

  1. Fork the Kogito Examples repository
  2. Pick an issue from the issue tracker
  3. Make your changes and submit a pull request
  4. Engage with the community on the mailing list

Remember, no contribution is too small. Even fixing a typo in the documentation is appreciated!

The Final Countdown: Wrapping It Up

And there you have it, folks! A whirlwind tour of Kogito and its superpowers. We've covered everything from setting up your first Kogito project to contributing to the open-source community.

Kogito, powered by Quarkus, is changing the game in business automation. It brings the power of cloud-native technologies to the world of business processes and decisions. Whether you're building a simple workflow or a complex decision-making system, Kogito has got your back.

So, what are you waiting for? Dive in, start experimenting, and join the Kogito revolution. Your future self (and your ops team) will thank you.

Remember: with great power comes great responsibility. Use Kogito wisely, and may your business processes be ever in your favor!