Kogito: Cloud-Native Business Automation¶
Introduction to Kogito¶
Kogito is a cloud-native business automation platform that combines business processes, decision management, and rules engines into a unified solution optimized for Kubernetes® environments. Built on the solid foundation of Drools, jBPM, and other Apache KIE™ technologies, Kogito brings business automation into the cloud era with a focus on scalability, developer productivity, and modern architecture patterns.
The name "Kogito" comes from the Latin "cogito, ergo sum" ("I think, therefore I am"), reflecting its intelligent decision-making capabilities.
Why Choose Kogito?¶
- Cloud-Native Design: Built from the ground up for Kubernetes and containerized environments
- Developer-First Approach: Integrates seamlessly with modern development tools and workflows
- Quarkusâ„¢ & Spring Bootâ„¢ Integration: Works with popular microservice frameworks
- Lightweight Runtime: Minimal footprint optimized for containers and serverless environments
- Event-Driven Architecture: First-class support for event-based communication
- DevOps Ready: CI/CD friendly with GitOps workflows
- Domain-Specific Workloads: Focused on business automation as a specialized workload
- Unified Platform: Combines processes, decisions, and rules in a consistent way
Core Concepts¶
Cloud-Native Design¶
Kogito is designed around cloud-native principles:
- Containerization: Everything runs in containers
- Microservices: Small, focused services with bounded contexts
- Kubernetes-Native: Optimized for orchestration with Kubernetes
- Scalability: Horizontal scaling for process and decision services
- Resilience: Fault-tolerant design
- Observability: Built-in monitoring and tracing
- Configuration: Externalized configuration
Domain-Driven Design¶
Kogito encourages domain-driven design (DDD) practices:
- Bounded Contexts: Clear boundaries between different business domains
- Ubiquitous Language: Consistent terminology between business and technical teams
- Aggregates: Business entities that ensure consistency
- Business Processes: Workflows that coordinate aggregates
- Business Rules: Decisions that operate on domain models
Development Model¶
Kogito uses a code-centric development approach:
- Source files (BPMNâ„¢, DMNâ„¢) generate code during build
- Business assets are treated as source code
- Domain models drive the implementation
- Lightweight runtime environment
- Framework integration (Quarkus, Spring Boot)
Getting Started¶
Prerequisites¶
- Javaâ„¢ Development Kit - JDK 17
- Apache Mavenâ„¢ 3.9.7 or later
- Docker® and other container platforms
- Kubernetes®/Red Hat OpenShift® (for deployment)
- IDE with Kogito extensions (Visual Studio Code®, IntelliJ®, etc.)
Create a Kogito Project¶
Project Structure¶
A typical Kogito project has the following structure:
src/
├── main/
│ ├── java/
│ │ └── org/acme/
│ │ ├── model/
│ │ │ └── MyModel.java
│ │ └── service/
│ │ └── MyService.java
│ └── resources/
│ ├── application.properties
│ ├── META-INF/
│ │ └── resources/
│ │ └── index.html
│ └── process.bpmn
└── test/
├── java/
│ └── org/acme/
│ └── ProcessTest.java
└── resources/
└── test-process.bpmn
Creating Business Logic¶
Business Processes¶
Create a file named orders.bpmn
in the src/main/resources
directory:
Domain Model¶
Create a Java class for your domain model:
package org.acme.model;
public class Order {
private String id;
private String customer;
private double amount;
private String status;
// Constructors, getters, and setters
public Order() {
}
public Order(String id, String customer, double amount) {
this.id = id;
this.customer = customer;
this.amount = amount;
this.status = "New";
}
// Getters and setters
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCustomer() {
return customer;
}
public void setCustomer(String customer) {
this.customer = customer;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
Service Implementation¶
Create a service class for your process tasks:
package org.acme.service;
import org.acme.model.Order;
import javax.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class OrderService {
public Order processOrder(Order order) {
// Business logic for processing an order
order.setStatus("Processed");
// Simulate some processing
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return order;
}
}
Building and Running¶
Build the Project¶
Run in Development Mode¶
Quarkus¶
Spring Boot¶
Test the Process Service¶
curl -X POST \
http://localhost:8080/orders \
-H 'Content-Type: application/json' \
-d '{
"id": "ORD-001",
"customer": "John Doe",
"amount": 100.0
}'
Business Decision Management¶
Creating Decision Models¶
Create a file named pricing.dmn
in the src/main/resources
directory:
Decision Integration¶
Using decisions in your service:
package org.acme.service;
import org.acme.model.Customer;
import org.acme.model.Order;
import org.kie.kogito.decision.DecisionModel;
import org.kie.kogito.decision.DecisionModels;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.util.HashMap;
import java.util.Map;
@ApplicationScoped
public class PricingService {
@Inject
DecisionModels decisionModels;
public double calculateDiscount(Customer customer, Order order) {
DecisionModel pricingModel = decisionModels.getDecisionModel("pricing", "Pricing Decision");
Map<String, Object> inputs = new HashMap<>();
inputs.put("Customer", customer);
inputs.put("Order", order);
Map<String, Object> outcome = pricingModel.evaluateAll(inputs);
return (double) outcome.get("PriceDiscount");
}
}
Containerization and Deployment¶
Creating a Container¶
Dockerfile for Quarkus¶
FROM registry.access.redhat.com/ #CHANGE IMAGE
WORKDIR /work/
COPY target/*-runner /work/application
RUN chmod 775 /work
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
Build and Run Container¶
Kubernetes Deployment¶
Kubernetes YAML¶
apiVersion: apps/v1
kind: Deployment
metadata:
name: kogito-app
spec:
replicas: 1
selector:
matchLabels:
app: kogito-app
template:
metadata:
labels:
app: kogito-app
spec:
containers:
- name: kogito-app
image: kogito-app:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: kogito-app
spec:
selector:
app: kogito-app
ports:
- port: 8080
targetPort: 8080
type: ClusterIP
Deploy to Kubernetes¶
Event-Driven Architecture¶
Adding Kafka Support¶
Maven Dependencies (Quarkus)¶
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-reactive-messaging-kafka</artifactId>
</dependency>
Cloud Events¶
@Incoming("orders-in")
@Outgoing("orders-processed")
public Order processOrder(Order order) {
// Process the order
order.setStatus("Processed");
return order;
}
Event-Driven Process¶
<bpmn2:startEvent id="start" name="Start">
<bpmn2:outgoing>Flow_1</bpmn2:outgoing>
<bpmn2:messageEventDefinition messageRef="newOrderMessage"/>
</bpmn2:startEvent>
Advanced Features¶
Process Persistence¶
Configuration (Quarkus)¶
# MongoDB persistence
quarkus.mongodb.connection-string=mongodb://localhost:27017
quarkus.mongodb.database=kogito
kogito.persistence.type=mongodb
Service Discovery¶
Configuration (Quarkus)¶
Monitoring and Observability¶
Maven Dependencies (Quarkus)¶
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-metrics</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-health</artifactId>
</dependency>
Security¶
# OIDC Configuration
quarkus.oidc.auth-server-url=https://auth-server/auth/realms/kogito
quarkus.oidc.client-id=kogito-app
quarkus.oidc.credentials.secret=secret
quarkus.http.auth.permission.authenticated.paths=/*
quarkus.http.auth.permission.authenticated.policy=authenticated
Kogito Tooling¶
VS Code Extensions¶
- BPMN Editor: Visual editing of business processes
- DMN Editor: Decision model creation and testing
- Test Scenario Editor: Define and run test scenarios
Web-Based Editors¶
# Enable Dev UI and editors
quarkus.kogito.devservices.enabled=true
quarkus.kogito.devui.enabled=true
Kogito Management Console¶
A web console for managing process instances:
Testing¶
Process Testing¶
package org.acme;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
import org.acme.model.Order;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
@QuarkusTest
public class OrderProcessTest {
@Test
public void testOrderProcess() {
Order order = new Order("ORD-TEST", "Test Customer", 150.0);
given()
.contentType("application/json")
.body(order)
.when()
.post("/orders")
.then()
.statusCode(201)
.body("id", is("ORD-TEST"))
.body("status", is("Processed"));
}
}
Decision Testing¶
package org.acme;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
import org.acme.model.Customer;
import org.acme.model.Order;
import org.acme.service.PricingService;
import javax.inject.Inject;
import static org.junit.jupiter.api.Assertions.assertEquals;
@QuarkusTest
public class PricingDecisionTest {
@Inject
PricingService pricingService;
@Test
public void testPremiumCustomerHighAmount() {
Customer customer = new Customer("CUST-001", "Premium");
Order order = new Order("ORD-001", customer.getId(), 200.0);
double discount = pricingService.calculateDiscount(customer, order);
assertEquals(0.15, discount, 0.001);
}
}
Integration Patterns¶
REST Integration¶
package org.acme.service;
import org.acme.model.ShippingInfo;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
@Path("/shipping")
@RegisterRestClient(configKey="shipping-api")
public interface ShippingService {
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
ShippingInfo createShipment(Order order);
}
Serverless Integration¶
package org.acme.service;
import org.acme.model.Order;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import org.eclipse.microprofile.reactive.messaging.Channel;
import org.eclipse.microprofile.reactive.messaging.Emitter;
@ApplicationScoped
public class NotificationService {
@Inject
@Channel("notifications")
Emitter<Order> notificationEmitter;
public void notifyOrderProcessed(Order order) {
notificationEmitter.send(order);
}
}
Best Practices¶
Process Design¶
- Keep processes simple and focused
- Use domain-driven design principles
- Leverage events for process communication
- Use compensation for error handling
- Break large processes into smaller subprocesses
Cloud Architecture¶
- Design for horizontal scaling
- Use stateless processes where possible
- Externalize configuration
- Implement proper health checks
- Plan for resilience and failures
Development Workflow¶
- Use source control for business assets
- Implement automated testing
- Adopt continuous integration and deployment
- Use feature branches for process changes
- Document API contracts
Comparison with Traditional jBPM¶
Feature | Traditional jBPM | Kogito |
---|---|---|
Architecture | Monolithic | Microservices |
Deployment | Application server | Containers/Kubernetes |
Development | Server-centric | Developer-centric |
Runtime | Heavy | Lightweight |
Scalability | Vertical | Horizontal |
Integration | EE-centric | Cloud-native |
Process State | Centralized | Distributed |
Generated Assets | Runtime assets | Build-time assets |
Next Steps¶
- Follow the Advanced Kogito Patterns tutorial
- Learn about Kogito Serverless Workflow
- Explore Event-Driven Processes
- Set up Kogito Operator for Kubernetes deployments
- Check out the Example Projects for more use cases