/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.drools.compiler.simulation;
import org.drools.compiler.CommonTestMethodBase;
import org.drools.compiler.Message;
import org.drools.core.command.RequestContextImpl;
import org.drools.core.fluent.impl.ExecutableBuilderImpl;
import org.junit.Test;
import org.kie.api.KieServices;
import org.kie.api.builder.KieModule;
import org.kie.api.builder.ReleaseId;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.ExecutableRunner;
import org.kie.api.runtime.RequestContext;
import org.kie.api.runtime.builder.Scope;
import org.kie.api.runtime.builder.ExecutableBuilder;
import org.kie.api.runtime.builder.KieSessionFluent;
public class BatchRunFluentTest extends CommonTestMethodBase {
String header = "package org.drools.compiler\n" +
"import " + Message.class.getCanonicalName() + "\n";
String drl1 = "global String outS;\n" +
"global Long timeNow;\n" +
"rule R1 when\n" +
" s : String()\n" +
"then\n" +
" kcontext.getKnowledgeRuntime().setGlobal(\"outS\", s);\n" +
" kcontext.getKnowledgeRuntime().setGlobal(\"timeNow\", kcontext.getKnowledgeRuntime().getSessionClock().getCurrentTime() );\n" +
"end\n";
ReleaseId releaseId = SimulateTestBase.createKJarWithMultipleResources("org.kie", new String[]{header + drl1}, new ResourceType[] {ResourceType.DRL});
@Test
public void testOutName() {
ExecutableBuilder f = ExecutableBuilder.create();
f.newApplicationContext("app1")
.getKieContainer(releaseId).newSession()
.insert("h1")
.fireAllRules()
.getGlobal("outS").out("outS")
.dispose();
RequestContext requestContext = ExecutableRunner.create().execute( f.getExecutable() );
assertEquals("h1", requestContext.get("outS"));
}
@Test
public void testOutWithPriorSetAndNoName() {
ExecutableBuilder f = ExecutableBuilder.create();
f.newApplicationContext("app1")
.getKieContainer(releaseId).newSession()
.insert("h1")
.fireAllRules()
.getGlobal("outS").set("outS").out()
.dispose();
RequestContext requestContext = ExecutableRunner.create().execute(f.getExecutable());
assertEquals("h1", requestContext.get("outS"));
assertEquals("h1", requestContext.get("outS"));
}
@Test
public void testOutWithoutPriorSetAndNoName() {
ExecutableBuilder f = ExecutableBuilder.create();
f.newApplicationContext("app1")
.getKieContainer(releaseId).newSession()
.insert("h1")
.fireAllRules()
.getGlobal("outS").out()
.dispose();
try {
RequestContext requestContext = ExecutableRunner.create().execute(f.getExecutable());
assertEquals("h1", requestContext.get("out1"));
fail("Must throw Exception, as no prior set was called and no name given to out");
} catch ( Exception e ) {
}
}
@Test
public void testSetAndGetWithCommandRegisterWithEnds() {
ExecutableBuilder f = ExecutableBuilder.create();
f.newApplicationContext("app1")
// create two sessions, and assign names
.getKieContainer(releaseId).newSession().set("s1").end()
.getKieContainer(releaseId).newSession().set("s2").end()
// initialise s1 with data
.get("s1", KieSessionFluent.class)
.insert("h1").fireAllRules().end()
// initialise s2 with data
.get("s2", KieSessionFluent.class)
.insert("h2").fireAllRules().end()
// assign s1 to out
.get("s1", KieSessionFluent.class)
.getGlobal("outS").out("outS1").dispose()
.get("s2", KieSessionFluent.class)
.getGlobal("outS").out("outS2").dispose();
RequestContext requestContext = ExecutableRunner.create().execute(f.getExecutable());
// Check that nothing went to the 'out'
assertEquals("h1", requestContext.get("outS1"));
assertEquals("h2", requestContext.get("outS2"));
}
@Test
public void testSetAndGetWithCommandRegisterWithoutEnds() {
ExecutableBuilder f = ExecutableBuilder.create();
f.newApplicationContext("app1")
// create two sessions, and assign names
.getKieContainer(releaseId).newSession().set("s1").end() // this end is needed, it's the get(String, Class) we are checking to see if it auto ends
.getKieContainer(releaseId).newSession().set("s2")
// initialise s1 with data
.get("s1", KieSessionFluent.class)
.insert("h1").fireAllRules()
// initialise s2 with data
.get("s2", KieSessionFluent.class)
.insert("h2").fireAllRules()
// assign s1 to out
.get("s1", KieSessionFluent.class)
.getGlobal("outS").out("outS1").dispose()
.get("s2", KieSessionFluent.class)
.getGlobal("outS").out("outS2").dispose();
RequestContext requestContext = ExecutableRunner.create().execute(f.getExecutable());
// Check that nothing went to the 'out'
assertEquals("h1", requestContext.get("outS1"));
assertEquals("h2", requestContext.get("outS2"));
}
@Test
public void testDifferentConversationIds() {
ExecutableRunner<RequestContext> runner = ExecutableRunner.create();
RequestContext requestContext = runner.createContext();
ExecutableBuilder f = ExecutableBuilder.create();
f.newApplicationContext("app1").startConversation()
.getKieContainer(releaseId).newSession()
.insert("h1")
.fireAllRules()
.dispose();
runner.execute(f.getExecutable(), requestContext);
String conversationId = requestContext.getConversationContext().getName();
runner.execute(f.getExecutable(), requestContext);
assertNotEquals(conversationId, requestContext.getConversationContext().getName());
}
@Test
public void testRequestScope() {
ExecutableBuilder f = ExecutableBuilder.create();
f.newApplicationContext("app1")
.getKieContainer(releaseId).newSession()
.insert("h1")
.fireAllRules()
.getGlobal("outS").set("outS1") // Request is default
.dispose();
RequestContext requestContext = ExecutableRunner.create().execute(f.getExecutable());
// Check that nothing went to the 'out'
assertNull(requestContext.get("outS"));
assertNull(requestContext.getApplicationContext().get("outS1") );
assertNull(requestContext.getConversationContext() );
assertEquals("h1", requestContext.get("outS1") );
}
@Test
public void testApplicationScope() {
ExecutableRunner<RequestContext> runner = ExecutableRunner.create();
ExecutableBuilder f = ExecutableBuilder.create();
f.newApplicationContext("app1")
.getKieContainer(releaseId).newSession()
.insert("h1")
.fireAllRules()
.getGlobal("outS").set("outS1", Scope.APPLICATION)
.dispose();
RequestContext requestContext = runner.execute(f.getExecutable());
// Check that nothing went to the 'out'
assertEquals(null, requestContext.get("outS"));
assertEquals("h1", requestContext.getApplicationContext().get("outS1") );
// Make another request, add to application context, assert old and new values are there.
f = new ExecutableBuilderImpl();
f.getApplicationContext("app1")
.getKieContainer(releaseId).newSession()
.insert("h2")
.fireAllRules()
.getGlobal("outS").set("outS2", Scope.APPLICATION)
.dispose();
requestContext = (RequestContextImpl) runner.execute(f.getExecutable());
assertEquals("h1", requestContext.getApplicationContext().get("outS1") );
assertEquals("h2", requestContext.getApplicationContext().get("outS2") );
}
@Test
public void testConversationScope() {
ExecutableRunner<RequestContext> runner = ExecutableRunner.create();
ExecutableBuilder f = ExecutableBuilder.create();
f.newApplicationContext("app1").startConversation()
.getKieContainer(releaseId).newSession()
.insert("h1")
.fireAllRules()
.getGlobal("outS").set("outS1", Scope.CONVERSATION)
.dispose();
RequestContextImpl requestContext = (RequestContextImpl) runner.execute(f.getExecutable());
// check that nothing went to the 'out'
assertEquals(null, requestContext.get("outS"));
String conversationId = requestContext.getConversationContext().getName();
assertEquals("h1", requestContext.getConversationContext().get("outS1") );
// Make another request, add to conversation context, assert old and new values are there.
f = new ExecutableBuilderImpl();
f.getApplicationContext("app1").joinConversation(conversationId)
.getKieContainer(releaseId).newSession()
.insert("h2")
.fireAllRules()
.getGlobal("outS").set("outS2", Scope.CONVERSATION)
.dispose();
requestContext = (RequestContextImpl) runner.execute(f.getExecutable());
assertEquals("h1", requestContext.getConversationContext().get("outS1") );
assertEquals("h2", requestContext.getConversationContext().get("outS2") );
// End the conversation, check it's now null
f = new ExecutableBuilderImpl();
f.endConversation(conversationId);
requestContext = (RequestContextImpl) runner.execute(f.getExecutable());
assertNull(requestContext.getConversationContext());
}
@Test
public void testContextScopeSearching() {
ExecutableRunner<RequestContext> runner = ExecutableRunner.create();
ExecutableBuilder f = ExecutableBuilder.create();
// Check that get() will search up to Application, when no request or conversation values
f.newApplicationContext("app1")
.getKieContainer(releaseId).newSession()
.insert("h1")
.fireAllRules()
.getGlobal("outS").set("outS1", Scope.APPLICATION)
.get("outS1").out()
.dispose();
RequestContext requestContext = runner.execute(f.getExecutable());
assertEquals("h1", requestContext.get("outS1"));
assertEquals("h1", requestContext.getApplicationContext().get("outS1") );
assertEquals("h1", requestContext.get("outS1") );
// Check that get() will search up to Conversation, thus over-riding Application scope and ignoring Request when it has no value
f = new ExecutableBuilderImpl();
f.getApplicationContext("app1").startConversation()
.getKieContainer(releaseId).newSession()
.insert("h2")
.fireAllRules()
.getGlobal("outS").set("outS1", Scope.CONVERSATION)
.get("outS1").out()
.dispose();
requestContext = runner.execute(f.getExecutable());
assertEquals("h2", requestContext.get("outS1"));
assertEquals("h1", requestContext.getApplicationContext().get("outS1") );
assertEquals("h2", requestContext.getConversationContext().get("outS1") );
assertEquals("h2", requestContext.get("outS1") );
// Check that get() will search directly to Request, thus over-riding Application and Conversation scoped values
f = new ExecutableBuilderImpl();
f.getApplicationContext("app1").joinConversation(requestContext.getConversationContext().getName())
.getKieContainer(releaseId).newSession()
.insert("h3")
.fireAllRules()
.getGlobal("outS").set("outS1", Scope.REQUEST)
.get("outS1").out()
.dispose();
requestContext = runner.execute(f.getExecutable());
assertEquals("h3", requestContext.get("outS1"));
assertEquals("h1", requestContext.getApplicationContext().get("outS1") );
assertEquals("h2", requestContext.getConversationContext().get("outS1") );
assertEquals("h3", requestContext.get("outS1") );
}
@Test
public void testAfter() {
ExecutableRunner<RequestContext> runner = ExecutableRunner.create(0L);
ExecutableBuilder f = ExecutableBuilder.create();
// Check that get() will search up to Application, when no request or conversation values
f.after(1000).newApplicationContext("app1")
.getKieContainer(releaseId).newSession()
.insert("h1")
.fireAllRules()
.getGlobal("outS").out("outS1")
.getGlobal("timeNow").out("timeNow1")
.dispose()
.after(2000).newApplicationContext("app1")
.getKieContainer(releaseId).newSession()
.insert("h1")
.fireAllRules()
.getGlobal("outS").out("outS2")
.getGlobal("timeNow").out("timeNow2")
.dispose();
RequestContext requestContext = runner.execute(f.getExecutable());
assertEquals(1000l, requestContext.get("timeNow1"));
assertEquals(2000l, requestContext.get("timeNow2"));
}
public static KieModule createAndDeployJar( KieServices ks,
ReleaseId releaseId,
String... drls ) {
byte[] jar = createKJar( ks, releaseId, null, drls );
return deployJar( ks, jar );
}
}