KIE Server execution using Java API - drools

I have simple Business process with rule executed before and after RestService WorkItem
BPM Process
I also defined the Rest Work Handler definition in the settings.
Rest Work Handler Definition Install Rest Work Item Handler.
Using Java KIE API calling RuleServicesClient to execute Rules and BPM Process.
KieServices kieServices = KieServices.Factory.get();
CredentialsProvider credentialsProvider = new EnteredCredentialsProvider(USERNAME, PASSWORD);
KieServicesConfiguration kieServicesConfig = KieServicesFactory.newRestConfiguration(KIE_SERVER_URL, credentialsProvider);
// Set the Marshaling Format to JSON. Other options are JAXB and XSTREAM
kieServicesConfig.setMarshallingFormat(MarshallingFormat.JSON);
KieServicesClient kieServicesClient = KieServicesFactory.newKieServicesClient(kieServicesConfig);
// Retrieve the RuleServices Client.
RuleServicesClient rulesClient = kieServicesClient.getServicesClient(RuleServicesClient.class);
List<Command<?>> commands = new ArrayList<>();
KieCommands commandFactory = kieServices.getCommands();
commands.add(commandFactory.newInsert(new RestFlowRequest("Sample"), "SampleRequest"));
commands.add(commandFactory.newStartProcess("RuleFlowSample.DecisionRestBPM"));
//commands.add(commandFactory.newFireAllRules("numberOfFiredRules"));
//ProcessServicesClient processService
// = kieServicesClient.getServicesClient(ProcessServicesClient.class);
//processService.startProcess(CONTAINER_ID,"RuleFlowSample.DecisionRestBPM");
BatchExecutionCommand batchExecutionCommand = commandFactory.newBatchExecution(commands);
ServiceResponse<ExecutionResults> response = rulesClient.executeCommandsWithResults(CONTAINER_ID, batchExecutionCommand);
It fails to execute the Rest Service Task with following error
Error Thrown By KIE Server
If change the code to start process using ProcessServicesClient then Business Process executes without any issue but rules don't execute.

You are using the correct approach using commands.add(commandFactory.newStartProcess("RuleFlowSample.DecisionRestBPM"));"
I tried it using below code(https://github.com/jbossdemocentral/kie-server-client-examples/blob/master/src/main/java/com/redhat/demo/qlb/loan_application/Main.java) and it works fine :
KieServices kieServices = KieServices.Factory.get();
CredentialsProvider credentialsProvider = new EnteredCredentialsProvider(USERNAME, PASSWORD);
KieServicesConfiguration kieServicesConfig = KieServicesFactory.newRestConfiguration(KIE_SERVER_URL, credentialsProvider);
// Set the Marshaling Format to JSON. Other options are JAXB and XSTREAM
kieServicesConfig.setMarshallingFormat(MarshallingFormat.JSON);
KieServicesClient kieServicesClient = KieServicesFactory.newKieServicesClient(kieServicesConfig);
// Retrieve the RuleServices Client.
RuleServicesClient rulesClient = kieServicesClient.getServicesClient(RuleServicesClient.class);
/*
* Create the list of commands that we want to fire against the rule engine. In this case we insert 2 objects, applicant and loan,
* and we trigger a ruleflow (with the StartProcess command).
*/
List<Command<?>> commands = new ArrayList<>();
KieCommands commandFactory = kieServices.getCommands();
//The identifiers that we provide in the insert commands can later be used to retrieve the object from the response.
commands.add(commandFactory.newInsert(getApplicant(), "applicant"));
commands.add(commandFactory.newInsert(getLoan(), "loan"));
commands.add(commandFactory.newStartProcess("loan-application.loan-application-decision-flow"));
For testing purpose please remove rest handler and try with script task and see the result.

Related

Drools Kie Server ignoring AgendaFilter

I've two guided decision tables in one project. My requirement is to execute only those rules which belong to one decision table at any given point of time. I tried to use RuleNameEndsWithAgendaFilter("some suffix") with FireAllRulesCommand class but Kie server is not filtering the rules based on the passed AgendaFilter. It runs all the rules every time.
Drools Workbench version 7.2.0.Final and Drools Kie Server version 7.2.0.Final.
Below is the code snippet for the same:
KieServicesConfiguration configuration = KieServicesFactory.newRestConfiguration(serverUrl, user, password);
Set<Class<?>> allClasses = new HashSet<Class<?>>();
allClasses.add(OrderItem.class);
configuration.addExtraClasses(allClasses);
configuration.setMarshallingFormat(MarshallingFormat.JAXB);
OrderItem oi = new OrderItem("Mobile", 7000.00, 0.00, "");
KieServicesClient client = KieServicesFactory.newKieServicesClient(configuration);
// work with rules
List<ExecutableCommand<?>> commands = new ArrayList<ExecutableCommand<?>>();
BatchExecutionCommandImpl executionCommand = new BatchExecutionCommandImpl(commands, "defaultKieSession");
InsertObjectCommand insertObjectCommand = new InsertObjectCommand();
insertObjectCommand.setOutIdentifier("orderItem");
insertObjectCommand.setObject(oi);
FireAllRulesCommand fireAllRulesCommand = new FireAllRulesCommand();
fireAllRulesCommand.setAgendaFilter(new RuleNameEndsWithAgendaFilter("MyRuleSuffix", true));
commands.add(insertObjectCommand);
commands.add(fireAllRulesCommand);
RuleServicesClient ruleClient = client.getServicesClient(RuleServicesClient.class);
ServiceResponse<String> response = ruleClient.executeCommands(containerId, executionCommand);
System.out.println(response.getResult());
You cannot use the standard class RuleNameEndsWithAgendaFilter for filtering the rules of a decision table because rules from one table don't have equal endings.
Try RuleNameStartsWithAgendaFilter, possibly after renaming your tables.

Trying to retrieve JBPM process results from KIE Remote REST API

I am trying to retrieve the result objects created by a business process via the KIE remote API:
if (baseURL != null) {
System.out.println("[GlobalFlow]-Creating Engine");
engine = RemoteRuntimeEngineFactory.newRestBuilder().addUrl(baseURL).addUserName(user).add Password(password)
.addDeploymentId(deploymentId).addTimeout(10)
.addExtraJaxbClasses(ClaimRequest.class, EvaluateLabClaimResponse.class, SecondaryCodes.class,
ResponseHeaderData.class, ResponseLineData.class, EvaluateLabClaim.class)
.build();
KieSession ksession = engine.getKieSession();
Map<String, Object> params = new HashMap<String, Object>();
[create and store a bunch of params...]
ProcessInstance processInstance = ksession.startProcess("defaultPackage.GlobalFlow", params);
}
Now I want to get the return values that were created by the remote JBPM process. We have the objects sitting over there, all I need to do is get access to them.
How do I do that?

Is RESTEasy RegisterBuiltin.register necessary when using ClientResponse<T>

I am developing a REST client using JBOSS app server and RESTEasy 2.3.6. I've included the following line at the beginning of my code:
RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
Here's the rest of the snippet:
RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(host, port, AuthScope.ANY_REALM), new UsernamePasswordCredentials(userid,password));
ClientExecutor executor = createAuthenticatingExecutor(httpclient, host, port);
String uriTemplate = "http://myhost:8080/webapp/rest/MySearch";
ClientRequest request = new ClientRequest(uriTemplate, executor);
request.accept("application/json").queryParameter("query", searchArg);
ClientResponse<SearchResponse> response = null;
List<MyClass> values = null;
try
{
response = request.get(SearchResponse.class);
if (response.getResponseStatus().getStatusCode() != 200)
{
throw new Exception("REST GET failed");
}
SearchResponse searchResp = response.getEntity();
values = searchResp.getValue();
}
catch (ClientResponseFailure e)
{
log.error("REST call failed", e);
}
finally
{
response.releaseConnection();
}
private ClientExecutor createAuthenticatingExecutor(DefaultHttpClient client, String server, int port)
{
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
HttpHost targetHost = new HttpHost(server, port);
authCache.put(targetHost, basicAuth);
// Add AuthCache to the execution context
BasicHttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.AUTH_CACHE, authCache);
// Create ClientExecutor.
ApacheHttpClient4Executor executor = new ApacheHttpClient4Executor(client, localContext);
return executor;
}
The above is a fairly simple client that employs the ClientRequest/ClientResponse<T> technique. This is documented here. The above code does work (only left out some trivial variable declarations like host and port). It is unclear to me from the JBOSS documentation as to whether I need to run RegisterBuiltin.register first. If I remove the line completely - my code still functions. Do I really need to include the register method call given the approach I have taken? The Docs say I need to run this once per VM. Secondly, if I am required to call it, is it safe to call more than one time in the same VM?
NOTE: I do understand there are newer versions of RESTEasy for JBOSS, we are not there yet.

Understanding Esper IO Http example

What is Trigger Event here ?
How to plug this to the EsperEngine for getting events ?
What URI should be passed ? how should engineURI look like ?
Is it the remote location of the esper engine ?
ConfigurationHTTPAdapter adapterConfig = new ConfigurationHTTPAdapter();
// add additional configuration
Request request = new Request();
request.setStream("TriggerEvent");
request.setUri("http://localhost:8077/root");
adapterConfig.getRequests().add(request);
// start adapter
EsperIOHTTPAdapter httpAdapter = new EsperIOHTTPAdapter(adapterConfig, "engineURI");
httpAdapter.start();
// destroy the adapter when done
httpAdapter.destroy();
Changed the stream from TriggerEvents to HttpEvents and I get this exception given below
ConfigurationException: Event type by name 'HttpEvents' not found
The "engineURI" is a name for the CEP engine instance and has nothing to do with the EsperIO http transport. Its a name for looking up what engines exists and finding the engine by name. So any text can be used here and the default CEP engine is named "default" when you allocate the default one.
You should define the event type of the event you expect to receive via http. A sample code is in http://svn.codehaus.org/esper/esper/trunk/esperio-socket/src/test/java/com/espertech/esperio/socket/TestSocketAdapterCSV.java
You need to declare your event type(s) in either Java, or through Esper's EPL statements.
The reason why you are getting exception is because your type is not defined.
Then you can start sending events by specifying type you are sending in HTTP request. For example, here is a bit of code in python:
import urllib
cepurl = "http://localhost:8084"
param = urllib.urlencode({'stream':'DataEvent',
'date': datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"),
'src':data["ipsrc"],
'dst':data["ipdst"],
'type':data["type"]})
# sending event:
f = urllib.urlopen(cepurl + "/sendevent?" + param);
rez = f.read()
in java this probably would be something like this:
SupportHTTPClient client = new SupportHTTPClient();
client.request(8084, "sendevent", "stream", "DataEvent", "date", "mydate");

How to code with websphere commerce inventory facade client

I'm finding this incredibly frustrating. I'm trying to use the InventoryFacadeClient to call either the Change or Sync web services to update product availability. The issue I'm facing is that I can't seem to instantiate all of the required DataTypes to populate the request.
It's quite confusing, I wanted to call ChangeInventory but can't compose the request, and started down SyncProductAvailability but again, can't compose the request.
The problem below is that the ProductIdentifierType is null, and there's no corresponding "createProductIdentifierType" on the Factory....I'm not sure what I"m missing here, the factory seems to be half baked...
If someone can help me complete this code, it would be great?
public void setUp() throws Exception {
String METHOD_NAME = "setUp";
logger.info("{} entering", METHOD_NAME);
super.setUp();
InventoryFacadeClient iClient = super.initializeInventoryClient(false);
InventoryFactory f = com.ibm.commerce.inventory.datatypes.InventoryFactory.eINSTANCE;
com.ibm.commerce.inventory.facade.datatypes.InventoryFactory cf = iClient.getInventoryFactory();
CommerceFoundationFactory fd = iClient.getCommerceFoundationFactory();
// we must have customised the SyncProductAvailability web service to
// handle ATP inventory model.
SyncProductAvailabilityDataAreaType dataArea = f.createSyncProductAvailabilityDataAreaType();
SyncProductAvailabilityType sat = f.createSyncProductAvailabilityType();
sat.setDataArea(dataArea);
DocumentRoot root = cf.createDocumentRoot();
sat.setVersionID(root.getInventoryAvailabilityBODVersion());
ProductAvailabilityType pat = f.createProductAvailabilityType();
ProductIdentifierType pid = pat.getProductIdentifier();
I found the answer to this on another forum. I was missing the right CommerceFoundationFactory - the class the ProductIdentifierType is created from is:
com.ibm.commerce.foundation.datatypes.CommerceFoundationFactory fd2 = com.ibm.commerce.foundation.datatypes.CommerceFoundationFactory.eINSTANCE;
fd2.createProductIdentifierType