/*
* Copyright 2015 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.
*
* 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.integrationtests;
import java.lang.reflect.Field;
import org.drools.compiler.CommonTestMethodBase;
import org.drools.compiler.Message;
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.Resource;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.internal.io.ResourceFactory;
public class DynamicRuleLoadTest extends CommonTestMethodBase {
private final String drl1 =
"package org.drools.compiler\n" +
"rule R1 when\n" +
" Message( $m : message )\n" +
"then\n" +
" System.out.println($m);\n" +
"end\n";
private final String drl2_1 =
"package org.drools.compiler\n" +
"global " + DynamicRuleLoadTest.class.getCanonicalName() + " test;\n" +
"rule R2_1 when\n" +
" $m : Message( message == \"Hi Universe\" )\n" +
"then\n" +
" test.updateToVersion();" +
"end\n";
private final String drl2_2 =
"package org.drools.compiler\n" +
"global " + DynamicRuleLoadTest.class.getCanonicalName() + " test;\n" +
"rule R2_2 when\n" +
" $m : Message( message == \"Hello World\" )\n" +
"then\n" +
" test.done();" +
"end\n";
private final String javaSrc =
"package org.drools.compiler.test;\n" +
"public class PersonObject {\n" +
" private String id;\n" +
" public String getId() {\n" +
" return id;\n" +
" }\n" +
" public void setId(String id) {\n" +
" this.id = id;\n" +
" }\n" +
" public void updateId() {\n" +
" this.id = \"Person from version 1\";\n" +
" }\n" +
"}";
private final String javaSrc_2 =
"package org.drools.compiler.test;\n" +
"public class PersonObject {\n" +
" private String id;\n" +
" public String getId() {\n" +
" return id;\n" +
" }\n" +
" public void setId(String id) {\n" +
" this.id = id;\n" +
" }\n" +
" public void updateId() {\n" +
" this.id = \"Person from version 2\";\n" +
" }\n" +
"}";
private final String person_drl =
"package org.drools.compiler.test\n" +
"import org.drools.compiler.test.PersonObject;\n" +
"\n" +
"rule \"Update person's id\"\n" +
"when\n" +
" $person : PersonObject()\n" +
"then\n" +
" $person.updateId();\n" +
" delete($person);\n" +
"end";
private KieContainer kieContainer;
private KieSession ksession;
private boolean done = false;
@Test
public void testKJarUpgrade() throws Exception {
// DROOLS-919
KieServices ks = KieServices.Factory.get();
// Create an in-memory jar for version 1.0.0
ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" );
KieModule km = createAndDeployJar( ks, releaseId1, drl1, drl2_1 );
// Create a session and fire rules
kieContainer = ks.newKieContainer( km.getReleaseId() );
ksession = kieContainer.newKieSession();
ksession.setGlobal( "test", this );
ksession.insert( new Message( "Hi Universe" ) );
ksession.fireAllRules();
assertTrue( done );
}
@Test
public void testKJarUpgradeWithJavaClass() throws Exception {
KieServices ks = KieServices.Factory.get();
String kmodule = "<kmodule xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n" +
" xmlns=\"http://www.drools.org/xsd/kmodule\">\n" +
" <kbase name=\"kbase1\">\n" +
" <ksession name=\"ksession1\" default=\"true\"/>\n" +
" </kbase>\n" +
"</kmodule>";
// Create an in-memory jar for version 1.0.0
ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade-java", "1.0.0" );
Resource javaResource = ResourceFactory.newByteArrayResource(javaSrc.getBytes()).setResourceType( ResourceType.JAVA )
.setSourcePath( "org/drools/compiler/test/PersonObject.java" );
Resource drlResource = ResourceFactory.newByteArrayResource( person_drl.getBytes() ).setResourceType( ResourceType.DRL )
.setSourcePath( "kbase1/person.drl" );
KieModule km = createAndDeployJar( ks, kmodule, releaseId1, javaResource, drlResource );
// Create a session and fire rules
kieContainer = ks.newKieContainer( km.getReleaseId() );
ksession = kieContainer.newKieSession();
Class<?> clazz = kieContainer.getClassLoader().loadClass("org.drools.compiler.test.PersonObject");
Object person = clazz.newInstance();
ksession.insert( person );
ksession.fireAllRules();
assertNotNull(person);
Object personId = valueOf(person, "id");
assertNotNull(personId);
assertEquals("Person from version 1", personId);
ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade-java", "1.1.0" );
Resource javaResource2 = ResourceFactory.newByteArrayResource(javaSrc_2.getBytes()).setResourceType( ResourceType.JAVA )
.setSourcePath( "org/drools/compiler/test/PersonObject.java" );
Resource drlResource2 = ResourceFactory.newByteArrayResource( person_drl.getBytes() ).setResourceType( ResourceType.DRL )
.setSourcePath( "kbase1/person.drl" );
createAndDeployJar( ks, kmodule, releaseId2, javaResource2, drlResource2 );
// update container
kieContainer.updateToVersion(releaseId2);
assertEquals(releaseId2, kieContainer.getReleaseId());
// now let's run the rules
ksession = kieContainer.newKieSession();
person = kieContainer.getClassLoader().loadClass("org.drools.compiler.test.PersonObject").newInstance();
ksession.insert( person );
ksession.fireAllRules();
assertNotNull(person);
personId = valueOf(person, "id");
assertNotNull(personId);
assertEquals("Person from version 2", personId);
}
public void updateToVersion() {
KieServices ks = KieServices.Factory.get();
// Create a new jar for version 1.1.0
ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" );
KieModule km = createAndDeployJar( ks, releaseId2, drl1, drl2_2 );
// try to update the container to version 1.1.0
kieContainer.updateToVersion( releaseId2 );
// create and use a new session
ksession.insert( new Message( "Hello World" ) );
}
public void done() {
done = true;
}
protected Object valueOf(Object object, String fieldName) {
try {
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(object);
} catch (Exception e) {
return null;
}
}
}