第18章 Decision Server capabilities and extensions
The capabilities in Decision Server are determined by plug-in extensions that you can enable, disable, or further extend to meet your business needs. Decision Server supports the following default capabilities and extensions:
| Capability name | Extension name | Description |
|---|---|---|
|
|
| Provides the core capabilities of Decision Server, such as creating and disposing KIE containers on your server instance |
|
|
| Provides the Business Rule Management (BRM) capabilities, such as inserting facts and executing business rules |
|
|
| Provides the Business Resource Planning (BRP) capabilities, such as implementing solvers |
|
|
| Provides the Decision Model and Notation (DMN) capabilities, such as managing DMN data types and executing DMN models |
|
|
| Provides the Swagger web-interface capabilities for interacting with the Decision Server REST API |
To view the supported extensions of a running Decision Server instance, send a GET request to the following REST API endpoint and review the XML or JSON server response:
Base URL for GET request for Decision Server information
http://SERVER:PORT/kie-server/services/rest/server
Example JSON response with Decision Server information
{
"type": "SUCCESS",
"msg": "Kie Server info",
"result": {
"kie-server-info": {
"id": "test-kie-server",
"version": "7.26.0.20190818-050814",
"name": "test-kie-server",
"location": "http://localhost:8080/kie-server/services/rest/server",
"capabilities": [
"KieServer",
"BRM",
"BRP",
"DMN",
"Swagger"
],
"messages": [
{
"severity": "INFO",
"timestamp": {
"java.util.Date": 1566169865791
},
"content": [
"Server KieServerInfo{serverId='test-kie-server', version='7.26.0.20190818-050814', name='test-kie-server', location='http:/localhost:8080/kie-server/services/rest/server', capabilities=[KieServer, BRM, BRP, DMN, Swagger]', messages=null', mode=DEVELOPMENT}started successfully at Sun Aug 18 23:11:05 UTC 2019"
]
}
],
"mode": "DEVELOPMENT"
}
}
}
To enable or disable Decision Server extensions, configure the related *.server.ext.disabled Decision Server system property. For example, to disable the BRM capability, set the system property org.drools.server.ext.disabled=true. For all Decision Server system properties, see 17章Decision Server system properties.
By default, Decision Server extensions are exposed through REST or JMS data transports and use predefined client APIs. You can extend existing Decision Server capabilities with additional REST endpoints, extend supported transport methods beyond REST or JMS, or extend functionality in the Decision Server client.
This flexibility in Decision Server functionality enables you to adapt your Decision Server instances to your business needs, instead of adapting your business needs to the default Decision Server capabilities.
If you extend Decision Server functionality, Red Hat does not support the custom code that you use as part of your custom implementations and extensions.
18.1. Extending an existing Decision Server capability with a custom REST API endpoint リンクのコピーリンクがクリップボードにコピーされました!
The Decision Server REST API enables you to interact with your KIE containers and business assets (such as business rules, processes, and solvers) in Red Hat Decision Manager without using the Business Central user interface. The available REST endpoints are determined by the capabilities enabled in your Decision Server system properties (for example, org.drools.server.ext.disabled=false for the BRM capability). You can extend an existing Decision Server capability with a custom REST API endpoint to further adapt the Decision Server REST API to your business needs.
As an example, this procedure extends the Drools Decision Server extension (for the BRM capability) with the following custom REST API endpoint:
Example custom REST API endpoint
/server/containers/instances/{containerId}/ksession/{ksessionId}
This example custom endpoint accepts a list of facts to be inserted into the working memory of the decision engine, automatically executes all rules, and retrieves all objects from the KIE session in the specified KIE container.
Procedure
Create an empty Maven project and define the following packaging type and dependencies in the
pom.xmlfile for the project:Example pom.xml file in the sample project
<packaging>jar</packaging> <properties> <version.org.kie>7.26.0.Final-redhat-00005</version.org.kie> </properties> <dependencies> <dependency> <groupId>org.kie</groupId> <artifactId>kie-api</artifactId> <version>${version.org.kie}</version> </dependency> <dependency> <groupId>org.kie</groupId> <artifactId>kie-internal</artifactId> <version>${version.org.kie}</version> </dependency> <dependency> <groupId>org.kie.server</groupId> <artifactId>kie-server-api</artifactId> <version>${version.org.kie}</version> </dependency> <dependency> <groupId>org.kie.server</groupId> <artifactId>kie-server-services-common</artifactId> <version>${version.org.kie}</version> </dependency> <dependency> <groupId>org.kie.server</groupId> <artifactId>kie-server-services-drools</artifactId> <version>${version.org.kie}</version> </dependency> <dependency> <groupId>org.kie.server</groupId> <artifactId>kie-server-rest-common</artifactId> <version>${version.org.kie}</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-core</artifactId> <version>${version.org.kie}</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-compiler</artifactId> <version>${version.org.kie}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> </dependencies>Implement the
org.kie.server.services.api.KieServerApplicationComponentsServiceinterface in a Java class in your project, as shown in the following example:Sample implementation of the
KieServerApplicationComponentsServiceinterfacepublic class CusomtDroolsKieServerApplicationComponentsService implements KieServerApplicationComponentsService {1 private static final String OWNER_EXTENSION = "Drools";2 public Collection<Object> getAppComponents(String extension, SupportedTransports type, Object... services) {3 // Do not accept calls from extensions other than the owner extension: if ( !OWNER_EXTENSION.equals(extension) ) { return Collections.emptyList(); } RulesExecutionService rulesExecutionService = null;4 KieServerRegistry context = null; for( Object object : services ) { if( RulesExecutionService.class.isAssignableFrom(object.getClass()) ) { rulesExecutionService = (RulesExecutionService) object; continue; } else if( KieServerRegistry.class.isAssignableFrom(object.getClass()) ) { context = (KieServerRegistry) object; continue; } } List<Object> components = new ArrayList<Object>(1); if( SupportedTransports.REST.equals(type) ) { components.add(new CustomResource(rulesExecutionService, context));5 } return components; } }- 1
- Delivers REST endpoints to the Decision Server infrastructure that is deployed when the application starts.
- 2
- Specifies the extension that you are extending, such as the
Droolsextension in this example. - 3
- Returns all resources that the REST container must deploy. Each extension that is enabled in your Decision Server instance calls the
getAppComponentsmethod, so theif ( !OWNER_EXTENSION.equals(extension) )call returns an empty collection for any extensions other than the specifiedOWNER_EXTENSIONextension. - 4
- Lists the services from the specified extension that you want to use, such as the
RulesExecutionServiceandKieServerRegistryservices from theDroolsextension in this example. - 5
- Specifies the transport type for the extension, either
RESTorJMS(RESTin this example), and theCustomResourceclass that returns the resource as part of thecomponentslist.
Implement the
CustomResourceclass that the Decision Server can use to provide the additional functionality for the new REST resource, as shown in the following example:Sample implementation of the
CustomResourceclass// Custom base endpoint: @Path("server/containers/instances/{containerId}/ksession") public class CustomResource { private static final Logger logger = LoggerFactory.getLogger(CustomResource.class); private KieCommands commandsFactory = KieServices.Factory.get().getCommands(); private RulesExecutionService rulesExecutionService; private KieServerRegistry registry; public CustomResource() { } public CustomResource(RulesExecutionService rulesExecutionService, KieServerRegistry registry) { this.rulesExecutionService = rulesExecutionService; this.registry = registry; } // Supported HTTP method, path parameters, and data formats: @POST @Path("/{ksessionId}") @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public Response insertFireReturn(@Context HttpHeaders headers, @PathParam("containerId") String id, @PathParam("ksessionId") String ksessionId, String cmdPayload) { Variant v = getVariant(headers); String contentType = getContentType(headers); // Marshalling behavior and supported actions: MarshallingFormat format = MarshallingFormat.fromType(contentType); if (format == null) { format = MarshallingFormat.valueOf(contentType); } try { KieContainerInstance kci = registry.getContainer(id); Marshaller marshaller = kci.getMarshaller(format); List<?> listOfFacts = marshaller.unmarshall(cmdPayload, List.class); List<Command<?>> commands = new ArrayList<Command<?>>(); BatchExecutionCommand executionCommand = commandsFactory.newBatchExecution(commands, ksessionId); for (Object fact : listOfFacts) { commands.add(commandsFactory.newInsert(fact, fact.toString())); } commands.add(commandsFactory.newFireAllRules()); commands.add(commandsFactory.newGetObjects()); ExecutionResults results = rulesExecutionService.call(kci, executionCommand); String result = marshaller.marshall(results); logger.debug("Returning OK response with content '{}'", result); return createResponse(result, v, Response.Status.OK); } catch (Exception e) { // If marshalling fails, return the `call-container` response to maintain backward compatibility: String response = "Execution failed with error : " + e.getMessage(); logger.debug("Returning Failure response with content '{}'", response); return createResponse(response, v, Response.Status.INTERNAL_SERVER_ERROR); } } }In this example, the
CustomResourceclass for the custom endpoint specifies the following data and behavior:-
Uses the base endpoint
server/containers/instances/{containerId}/ksession -
Uses
POSTHTTP method Expects the following data to be given in REST requests:
-
The
containerIdas a path argument -
The
ksessionIdas a path argument - List of facts as a message payload
-
The
Supports all Decision Server data formats:
- XML (JAXB, XStream)
- JSON
-
Unmarshals the payload into a
List<?>collection and, for each item in the list, creates anInsertCommandinstance followed byFireAllRulesandGetObjectcommands. -
Adds all commands to the
BatchExecutionCommandinstance that calls to the decision engine.
-
Uses the base endpoint
-
To make the new endpoint discoverable for Decision Server, create a
META-INF/services/org.kie.server.services.api.KieServerApplicationComponentsServicefile in your Maven project and add the fully qualified class name of theKieServerApplicationComponentsServiceimplementation class within the file. For this example, the file contains the single lineorg.kie.server.ext.drools.rest.CusomtDroolsKieServerApplicationComponentsService. -
Build your project and copy the resulting JAR file into the
~/kie-server.war/WEB-INF/libdirectory of your project. For example, on Red Hat JBoss EAP, the path to this directory isEAP_HOME/standalone/deployments/kie-server.war/WEB-INF/lib. Start the Decision Server and deploy the built project to the running Decision Server. You can deploy the project using either the Business Central interface or the Decision Server REST API (a
PUTrequest tohttp://SERVER:PORT/kie-server/services/rest/server/containers/{containerId}).After your project is deployed on a running Decision Server, you can start interacting with your new REST endpoint.
For this example, you can use the following information to invoke the new endpoint:
-
Example request URL:
http://localhost:8080/kie-server/services/rest/server/containers/instances/demo/ksession/defaultKieSession -
HTTP method:
POST HTTP headers:
-
Content-Type: application/json -
Accept: application/json
-
Example message payload:
[ { "org.jbpm.test.Person": { "name": "john", "age": 25 } }, { "org.jbpm.test.Person": { "name": "mary", "age": 22 } } ]-
Example server response:
200(success) Example server log output:
13:37:20,347 INFO [stdout] (default task-24) Hello mary 13:37:20,348 INFO [stdout] (default task-24) Hello john
-
Example request URL: