OSGi extensions & BPM/EIP integration
When the standard apps and scripts aren't enough, you can add advanced extensions as OSGi bundles. The BPM and EIP runtimes also publish events to OSGi EventAdmin, which bundles, scripts and Camel routes can integrate with.
How an OSGi bundle is structured
A bundle looks like this:
com.example.myfeature/
├── META-INF/MANIFEST.MF # OSGi bundle metadata
├── OSGI-INF/*.xml # Declarative Services (DS) component descriptors
├── src/... # Java source
└── build.properties
In MANIFEST.MF you declare the symbolic name, version, dependencies (Import-Package / Require-Bundle), public API (Export-Package) and DS components (Service-Component). A DS component (OSGI-INF/*.xml) receives the services it needs via <reference> and activates automatically once they are all available.
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.3.0"
immediate="true" name="com.example.myfeature.MyService">
<reference cardinality="1..1" field="fRepository"
interface="javax.jcr.Repository" name="fRepository" policy="static"/>
<implementation class="com.example.myfeature.internal.MyService"/>
</scr:component>
Felix loads bundles at startup. Manage and inspect them at runtime from the OSGi Console (/en/docs/user-guide/osgi-console/).
BPM / EIP EventAdmin integration
Both engines publish their runtime lifecycle to OSGi EventAdmin. The topic and property conventions are shared, and every event carries a workspace property (for the operational overview, see "BPM & EIP configuration").
- Topic:
<fully/qualified/Type>/<ACTION>(the fully-qualified type name with.→/, suffixed with an upper-case action) - Examples:
org/camunda/bpm/engine/task/Task/CREATED,org/apache/camel/Exchange/FAILED - Delivery is asynchronous (
postEvent); BPM publishes only on transaction commit
The eventadmin: Camel component
Camel routes can consume and produce EventAdmin events.
Consume events:
from("eventadmin:org/camunda/bpm/engine/runtime/ProcessInstance/*?filter=(workspace=web)")
.to("log:bpm-notifications");
The endpoint is eventadmin:<topic>?filter=<ldap-filter> — the topic supports wildcards and the filter narrows by, for example, workspace. Internally it registers an OSGi EventHandler.
Produce events:
from("...")
.to("eventadmin:org/my/custom/Event/TRIGGERED");
If the message body is a Map, it becomes the event properties, and a TOPIC header can override the topic.
Integrating with processes & routes
- Start a process — the GraphQL
startProcessmutation, or theProcessEngineAPI - Send to a route —
CamelContext'sProducerTemplate#sendBody(endpointUri, body), or the GraphQLsendToEndpoint - React to activity — subscribe to EventAdmin topics (an OSGi
EventHandler, a Camelfrom("eventadmin:..."), or a GraphQL subscription)
Run automation as a service account
It's safest to give an integration the permissions of a passwordless service account. Create it via provisioning and grant ACLs through a group.
users:
- id: myapp-service
service: true
displayName: MyApp Integration
memberOf: [myapp-service-group]
groups:
- id: myapp-service-group
displayName: MyApp Service Users
nodes:
- path: /content/myapp
primaryType: nt:folder
acl:
- group: myapp-service-group
privileges: jcr:read, jcr:write
effect: allow
See "Provisioning" and "Users, roles & permissions".