/*
* 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.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import org.drools.compiler.Message;
import org.drools.core.common.DroolsObjectInputStream;
import org.drools.core.common.DroolsObjectOutputStream;
import org.junit.Test;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieSession;
import org.kie.internal.KnowledgeBase;
import org.kie.internal.KnowledgeBaseFactory;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.definition.KnowledgePackage;
import org.kie.internal.io.ResourceFactory;
import org.kie.internal.runtime.StatelessKnowledgeSession;
import static org.junit.Assert.*;
public class SerializedPackageMergeTest {
private static final DateFormat DF = new SimpleDateFormat( "dd-MMM-yyyy", Locale.UK );
private static final String[] DRLs = {"HelloWorld.drl","test_Serialization1.drl"};
@Test
public void testRuleExecutionWithoutSerialization() {
try {
// without serialization, it works.
testRuleExecution( getSession( false ) );
} catch ( Exception e ) {
e.printStackTrace();
fail( "Should not have raised any exception. Message: " + e.getMessage() );
}
}
@Test
public void testRuleExecutionWithSerialization() throws Exception {
try {
// with serialized packages, NullPointerException
testRuleExecution( getSession( true ) );
} catch ( Exception e ) {
e.printStackTrace();
fail( "Should not have raised any exception. Message: " + e.getMessage() );
}
}
private void testRuleExecution(StatelessKnowledgeSession session) throws Exception {
List<Object> list = new ArrayList<Object>();
session.setGlobal( "list",
list );
session.execute( getObject() );
assertEquals( 2,
list.size() );
}
private Message getObject() throws ParseException {
Message message = new Message();
message.setMessage( "hola" );
message.setNumber( 50 );
message.getList().add( "hello" );
message.setBirthday( DF.parse( "10-Jul-1976" ) );
return message;
}
private StatelessKnowledgeSession getSession(boolean serialize) throws Exception {
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
for ( String drl : DRLs ) {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newInputStreamResource(getClass().getResourceAsStream(drl)),
ResourceType.DRL );
assertFalse( kbuilder.getErrors().toString(),
kbuilder.hasErrors() );
Collection<KnowledgePackage> kpkgs = kbuilder.getKnowledgePackages();
Collection<KnowledgePackage> newCollection = null;
if ( serialize ) {
newCollection = new ArrayList<KnowledgePackage>();
for( KnowledgePackage kpkg : kpkgs) {
kpkg = SerializationHelper.serializeObject(kpkg);
newCollection.add( kpkg );
}
} else {
newCollection = kpkgs;
}
kbase.addKnowledgePackages( newCollection );
}
return kbase.newStatelessKnowledgeSession();
}
@Test
public void testBuildAndSerializePackagesWithSamePackageName() throws IOException, ClassNotFoundException {
// RHBRMS-2773
String str1 =
"package com.sample\n" +
"import org.drools.compiler.Person\n" +
"global java.util.List list\n" +
"rule R1 when\n" +
" $p : Person( name == \"John\" )\n" +
"then\n" +
" list.add($p);" +
"end\n";
String str2 =
"package com.sample\n" +
"import org.drools.compiler.Person\n" +
"global java.util.List list\n" +
"rule R2 when\n" +
" $p : Person( name == \"Paul\" )\n" +
"then\n" +
" list.add($p);" +
"end\n";
// Create 2 knowledgePackages separately (but these rules have the same package name)
KnowledgeBuilder builder1 = KnowledgeBuilderFactory.newKnowledgeBuilder();
builder1.add( ResourceFactory.newByteArrayResource( str1.getBytes() ), ResourceType.DRL );
Collection<KnowledgePackage> knowledgePackages1 = builder1.getKnowledgePackages();
KnowledgeBuilder builder2 = KnowledgeBuilderFactory.newKnowledgeBuilder();
builder2.add( ResourceFactory.newByteArrayResource( str2.getBytes() ), ResourceType.DRL );
Collection<KnowledgePackage> knowledgePackages2 = builder2.getKnowledgePackages();
// Combine the knowledgePackages
KnowledgeBase knowledgeBase1 = KnowledgeBaseFactory.newKnowledgeBase();
knowledgeBase1.addKnowledgePackages( knowledgePackages1 );
knowledgeBase1.addKnowledgePackages( knowledgePackages2 );
Collection<KnowledgePackage> knowledgePackagesCombined = knowledgeBase1.getKnowledgePackages();
// serialize
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream out = new DroolsObjectOutputStream( baos );
out.writeObject( knowledgePackagesCombined );
out.flush();
out.close();
// deserialize
ObjectInputStream in = new DroolsObjectInputStream( new ByteArrayInputStream( baos.toByteArray() ) );
Collection<KnowledgePackage> deserializedPackages = (Collection<KnowledgePackage>) in.readObject();
// Use the deserialized knowledgePackages
KnowledgeBase knowledgeBase2 = KnowledgeBaseFactory.newKnowledgeBase();
knowledgeBase2.addKnowledgePackages(deserializedPackages);
KieSession ksession = knowledgeBase2.newKieSession();
List<String> list = new ArrayList<String>();
ksession.setGlobal( "list", list );
ksession.insert(new org.drools.compiler.Person("John"));
ksession.insert(new org.drools.compiler.Person("Paul"));
ksession.fireAllRules();
assertEquals(2, list.size());
ksession.dispose();
}
}