/*
* Copyright 2014 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.jbpm.kie.services.test;
import static org.junit.Assert.*;
import static org.kie.scanner.MavenRepository.getMavenRepository;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonAnyGetter;
import org.drools.compiler.kie.builder.impl.InternalKieModule;
import org.jbpm.kie.services.impl.KModuleDeploymentUnit;
import org.jbpm.kie.test.objects.Building;
import org.jbpm.kie.test.objects.House;
import org.jbpm.kie.test.objects.OtherPerson;
import org.jbpm.kie.test.objects.Person;
import org.jbpm.kie.test.objects.Thing;
import org.jbpm.kie.test.util.AbstractKieServicesBaseTest;
import org.jbpm.runtime.manager.impl.deploy.DeploymentDescriptorImpl;
import org.jbpm.services.api.model.DeployedUnit;
import org.jbpm.services.api.model.DeploymentUnit;
import org.jbpm.services.api.model.ProcessDefinition;
import org.junit.After;
import org.junit.Test;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.Message;
import org.kie.api.builder.ReleaseId;
import org.kie.api.builder.helper.FluentKieModuleDeploymentHelper;
import org.kie.api.builder.model.KieBaseModel;
import org.kie.api.builder.model.KieModuleModel;
import org.kie.api.builder.model.KieSessionModel;
import org.kie.api.conf.EqualityBehaviorOption;
import org.kie.api.conf.EventProcessingOption;
import org.kie.api.remote.Remotable;
import org.kie.api.runtime.conf.ClockTypeOption;
import org.kie.api.runtime.query.QueryContext;
import org.kie.internal.io.ResourceFactory;
import org.kie.internal.runtime.conf.DeploymentDescriptor;
import org.kie.scanner.MavenRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FilteredKModuleDeploymentServiceTest extends AbstractKieServicesBaseTest {
private static final Logger logger = LoggerFactory.getLogger(FilteredKModuleDeploymentServiceTest.class);
private List<DeploymentUnit> units = new ArrayList<DeploymentUnit>();
public void prepare(String packages) {
configureServices();
logger.debug("Preparing kjar");
KieServices ks = KieServices.Factory.get();
ReleaseId releaseId = ks.newReleaseId(GROUP_ID, ARTIFACT_ID, VERSION);
List<String> processes = new ArrayList<String>();
processes.add("repo/processes/general/customtask.bpmn");
processes.add("repo/processes/general/humanTask.bpmn");
List<String> processes2 = new ArrayList<String>();
processes2.add("repo/processes/general/import.bpmn");
InternalKieModule kJar1 = createKieJar(ks, releaseId, processes, processes2, packages);
File pom = new File("target/kmodule", "pom.xml");
pom.getParentFile().mkdir();
try {
FileOutputStream fs = new FileOutputStream(pom);
fs.write(getPom(releaseId).getBytes());
fs.close();
} catch (Exception e) {
}
MavenRepository repository = getMavenRepository();
repository.deployArtifact(releaseId, kJar1, pom);
}
@After
public void cleanup() {
cleanupSingletonSessionId();
if (units != null && !units.isEmpty()) {
for (DeploymentUnit unit : units) {
deploymentService.undeploy(unit);
}
units.clear();
}
close();
}
@Test
public void testDeploymentOfProcessesFromCustomerPackageDeafultKBase() {
prepare("customer.repo.processes.general");
assertNotNull(deploymentService);
DeploymentUnit deploymentUnit = new KModuleDeploymentUnit(GROUP_ID, ARTIFACT_ID, VERSION);
deploymentService.deploy(deploymentUnit);
units.add(deploymentUnit);
DeployedUnit deployed = deploymentService.getDeployedUnit(deploymentUnit.getIdentifier());
assertNotNull(deployed);
assertNotNull(deployed.getDeploymentUnit());
assertNotNull(deployed.getRuntimeManager());
assertEquals(GROUP_ID+":"+ARTIFACT_ID+":"+VERSION,
deployed.getDeploymentUnit().getIdentifier());
assertNotNull(runtimeDataService);
Collection<ProcessDefinition> processes = runtimeDataService.getProcesses(new QueryContext());
assertNotNull(processes);
assertEquals(2, processes.size());
processes = runtimeDataService.getProcessesByFilter("custom", new QueryContext());
assertNotNull(processes);
assertEquals(1, processes.size());
processes = runtimeDataService.getProcessesByDeploymentId(deploymentUnit.getIdentifier(), new QueryContext());
assertNotNull(processes);
assertEquals(2, processes.size());
ProcessDefinition process = runtimeDataService.getProcessesByDeploymentIdProcessId(deploymentUnit.getIdentifier(), "customtask");
assertNotNull(process);
}
@Test
public void testDeploymentOfProcessesFromCustomerPackage() {
prepare("customer.repo.processes.general");
assertNotNull(deploymentService);
DeploymentUnit deploymentUnit = new KModuleDeploymentUnit(GROUP_ID, ARTIFACT_ID, VERSION, "KBase-test", "ksession-test");
deploymentService.deploy(deploymentUnit);
units.add(deploymentUnit);
DeployedUnit deployed = deploymentService.getDeployedUnit(deploymentUnit.getIdentifier());
assertNotNull(deployed);
assertNotNull(deployed.getDeploymentUnit());
assertNotNull(deployed.getRuntimeManager());
assertEquals(GROUP_ID+":"+ARTIFACT_ID+":"+VERSION+":"+"KBase-test"+":"+"ksession-test",
deployed.getDeploymentUnit().getIdentifier());
assertNotNull(runtimeDataService);
Collection<ProcessDefinition> processes = runtimeDataService.getProcesses(new QueryContext());
assertNotNull(processes);
assertEquals(2, processes.size());
processes = runtimeDataService.getProcessesByFilter("custom", new QueryContext());
assertNotNull(processes);
assertEquals(1, processes.size());
processes = runtimeDataService.getProcessesByDeploymentId(deploymentUnit.getIdentifier(), new QueryContext());
assertNotNull(processes);
assertEquals(2, processes.size());
ProcessDefinition process = runtimeDataService.getProcessesByDeploymentIdProcessId(deploymentUnit.getIdentifier(), "customtask");
assertNotNull(process);
}
@Test
public void testDeploymentOfProcessesFromOrderPackage() {
prepare("order.repo.processes.general");
assertNotNull(deploymentService);
DeploymentUnit deploymentUnit = new KModuleDeploymentUnit(GROUP_ID, ARTIFACT_ID, VERSION, "KBase-test", "ksession-test");
deploymentService.deploy(deploymentUnit);
units.add(deploymentUnit);
DeployedUnit deployed = deploymentService.getDeployedUnit(deploymentUnit.getIdentifier());
assertNotNull(deployed);
assertNotNull(deployed.getDeploymentUnit());
assertNotNull(deployed.getRuntimeManager());
assertEquals(GROUP_ID+":"+ARTIFACT_ID+":"+VERSION+":"+"KBase-test"+":"+"ksession-test",
deployed.getDeploymentUnit().getIdentifier());
assertNotNull(runtimeDataService);
Collection<ProcessDefinition> processes = runtimeDataService.getProcesses(new QueryContext());
assertNotNull(processes);
assertEquals(1, processes.size());
processes = runtimeDataService.getProcessesByDeploymentId(deploymentUnit.getIdentifier(), new QueryContext());
assertNotNull(processes);
assertEquals(1, processes.size());
ProcessDefinition process = runtimeDataService.getProcessesByDeploymentIdProcessId(deploymentUnit.getIdentifier(), "Import");
assertNotNull(process);
}
@Test
public void testDeploymentOfProcessesWildcardPackage() {
prepare("customer.*");
assertNotNull(deploymentService);
DeploymentUnit deploymentUnit = new KModuleDeploymentUnit(GROUP_ID, ARTIFACT_ID, VERSION, "KBase-test", "ksession-test");
deploymentService.deploy(deploymentUnit);
units.add(deploymentUnit);
DeployedUnit deployed = deploymentService.getDeployedUnit(deploymentUnit.getIdentifier());
assertNotNull(deployed);
assertNotNull(deployed.getDeploymentUnit());
assertNotNull(deployed.getRuntimeManager());
assertEquals(GROUP_ID+":"+ARTIFACT_ID+":"+VERSION+":"+"KBase-test"+":"+"ksession-test",
deployed.getDeploymentUnit().getIdentifier());
assertNotNull(runtimeDataService);
Collection<ProcessDefinition> processes = runtimeDataService.getProcesses(new QueryContext());
assertNotNull(processes);
assertEquals(2, processes.size());
processes = runtimeDataService.getProcessesByFilter("custom", new QueryContext());
assertNotNull(processes);
assertEquals(1, processes.size());
processes = runtimeDataService.getProcessesByDeploymentId(deploymentUnit.getIdentifier(), new QueryContext());
assertNotNull(processes);
assertEquals(2, processes.size());
ProcessDefinition process = runtimeDataService.getProcessesByDeploymentIdProcessId(deploymentUnit.getIdentifier(), "customtask");
assertNotNull(process);
}
protected InternalKieModule createKieJar(KieServices ks, ReleaseId releaseId, List<String> resources, List<String> resources2, String packages ) {
KieFileSystem kfs = createKieFileSystemWithKProject(ks, packages);
kfs.writePomXML( getPom(releaseId) );
for (String resource : resources) {
kfs.write("src/main/resources/customer/" + resource, ResourceFactory.newClassPathResource(resource));
}
for (String resource : resources2) {
kfs.write("src/main/resources/order/" + resource, ResourceFactory.newClassPathResource(resource));
}
KieBuilder kieBuilder = ks.newKieBuilder(kfs);
if (!kieBuilder.buildAll().getResults().getMessages().isEmpty()) {
for (Message message : kieBuilder.buildAll().getResults().getMessages()) {
logger.error("Error Message: ({}) {}", message.getPath(), message.getText());
}
throw new RuntimeException(
"There are errors builing the package, please check your knowledge assets!");
}
return ( InternalKieModule ) kieBuilder.getKieModule();
}
protected KieFileSystem createKieFileSystemWithKProject(KieServices ks, String packages) {
KieModuleModel kproj = ks.newKieModuleModel();
KieBaseModel kieBaseModel1 = kproj.newKieBaseModel("KBase-test").setDefault(true).addPackage(packages)
.setEqualsBehavior( EqualityBehaviorOption.EQUALITY )
.setEventProcessingMode( EventProcessingOption.STREAM );
kieBaseModel1.newKieSessionModel("ksession-test").setDefault(true)
.setType(KieSessionModel.KieSessionType.STATEFUL)
.setClockType( ClockTypeOption.get("realtime") )
.newWorkItemHandlerModel("Log", "new org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler()");
KieFileSystem kfs = ks.newKieFileSystem();
kfs.writeKModuleXML(kproj.toXML());
return kfs;
}
private void verifyDeployedUnitContainsCorrectClasses(DeploymentUnit deploymentUnit) {
DeployedUnit deployedUnit = deploymentService.getDeployedUnit(deploymentUnit.getIdentifier());
DeploymentDescriptor descriptor = ((KModuleDeploymentUnit) deployedUnit.getDeploymentUnit()).getDeploymentDescriptor();
boolean limitClasses = descriptor.getLimitSerializationClasses();
boolean unAnnotatedClassesFound = false;
for( Class<?> depdClass : deployedUnit.getDeployedClasses() ) {
Annotation [] declAnnos = depdClass.getDeclaredAnnotations();
boolean xmlOrRemotAnnoFound = false;
for( Annotation depdClassAnno : declAnnos ) {
Class annoType = depdClassAnno.annotationType();
if( XmlRootElement.class.equals(annoType)
|| Remotable.class.equals(annoType) ) {
xmlOrRemotAnnoFound = true;
break;
}
}
assertTrue( "Expected to find annotations on " + depdClass.getSimpleName(),
(xmlOrRemotAnnoFound && limitClasses) || ! limitClasses );
if( ! xmlOrRemotAnnoFound ) {
unAnnotatedClassesFound = true;
}
}
assertTrue( "Expected to find unannotated classes in " + deployedUnit.getDeploymentUnit().getIdentifier(),
( limitClasses && ! unAnnotatedClassesFound ) || (! limitClasses && unAnnotatedClassesFound) );
if( limitClasses ) {
try {
JAXBContext.newInstance(deployedUnit.getDeployedClasses().toArray(new Class[0]));
} catch( JAXBException e ) {
e.printStackTrace();
fail("JAXBContext creation with deployed unit classes failed: " + e.getMessage());
}
}
}
@Test
public void testSerializationClassesLimitedInDeploymentItself() {
String groupId = "org.test";
String artifactId = "jbpm-kie-services-filter-test";
String version = VERSION;
FluentKieModuleDeploymentHelper.newFluentInstance()
.setGroupId(groupId)
.setArtifactId(artifactId)
.setVersion(version)
.addClass(Building.class, House.class, Person.class, OtherPerson.class, Thing.class)
.createKieJarAndDeployToMaven();
KModuleDeploymentUnit limitDeploymentUnit = new KModuleDeploymentUnit(groupId, artifactId, version);
FluentKieModuleDeploymentHelper.newFluentInstance()
.setGroupId(groupId)
.setArtifactId(artifactId + "-all")
.setVersion(version)
.addClass(Building.class, House.class, Person.class, OtherPerson.class, Thing.class)
.createKieJarAndDeployToMaven();
KModuleDeploymentUnit allDeploymentUnit = new KModuleDeploymentUnit(groupId, artifactId + "-all", version);
configureServices();
DeploymentDescriptor depDesc = new DeploymentDescriptorImpl().getBuilder()
.setLimitSerializationClasses(true)
.get();
limitDeploymentUnit.setDeploymentDescriptor(depDesc);
deploymentService.deploy(limitDeploymentUnit);
verifyDeployedUnitContainsCorrectClasses(limitDeploymentUnit);
depDesc = new DeploymentDescriptorImpl().getBuilder()
.setLimitSerializationClasses(false)
.get();
allDeploymentUnit.setDeploymentDescriptor(depDesc);
deploymentService.deploy(allDeploymentUnit);
verifyDeployedUnitContainsCorrectClasses(allDeploymentUnit);
}
@Test
public void testSerializationClassesLimitedInDeploymentDescriptor() {
String groupId = "org.test";
String artifactId = "jbpm-kie-services-filter-test-desc";
String version = VERSION;
FluentKieModuleDeploymentHelper.newFluentInstance()
.setGroupId(groupId)
.setArtifactId(artifactId)
.setVersion(version)
.createKieJarAndDeployToMaven();
configureServices();
KModuleDeploymentUnit deploymentUnit = new KModuleDeploymentUnit(groupId, artifactId, version);
DeploymentDescriptor depDesc = new DeploymentDescriptorImpl().getBuilder()
.setLimitSerializationClasses(true)
.addClass(Building.class.getName()) // interface, no annotations!
.addClass(House.class.getName()) // @XmlRootElement
.addClass(Person.class.getName()) // @XmlRootElement
.addClass(OtherPerson.class.getName()) // inherits from Person
.addClass(Thing.class.getName()) // @Remotable
.get();
deploymentUnit.setDeploymentDescriptor(depDesc);
deploymentService.deploy(deploymentUnit);
units.add(deploymentUnit);
verifyDeployedUnitContainsCorrectClasses(deploymentUnit);
}
@Test
public void testSerializationClassesLimitedInDeploymentDependencies() {
String groupId = "org.test";
String childArtifactId = "jbpm-kie-services-filter-test-dep";
String parentArtifactId = "jbpm-kie-services-filter-test-parent";
String version = VERSION;
FluentKieModuleDeploymentHelper.newFluentInstance()
.setGroupId(groupId)
.setArtifactId(childArtifactId)
.setVersion(version)
.addClass(Building.class, House.class, Person.class, OtherPerson.class, Thing.class)
.createKieJarAndDeployToMaven();
FluentKieModuleDeploymentHelper.newFluentInstance()
.setGroupId(groupId)
.setArtifactId(parentArtifactId)
.setVersion(version)
.addDependencies(groupId +":" + childArtifactId + ":" + version)
.createKieJarAndDeployToMaven();
configureServices();
KModuleDeploymentUnit childDeploymentUnit = new KModuleDeploymentUnit(groupId, childArtifactId, version);
DeploymentDescriptor depDesc = new DeploymentDescriptorImpl().getBuilder()
.setLimitSerializationClasses(false) // parent dictates behavior
.get();
childDeploymentUnit.setDeploymentDescriptor(depDesc);
deploymentService.deploy(childDeploymentUnit);
KModuleDeploymentUnit parentDeploymentUnit = new KModuleDeploymentUnit(groupId, parentArtifactId, version);
DeploymentDescriptor parentDepDesc = new DeploymentDescriptorImpl().getBuilder()
.setLimitSerializationClasses(true)
.get();
parentDeploymentUnit.setDeploymentDescriptor(parentDepDesc);
deploymentService.deploy(parentDeploymentUnit);
verifyDeployedUnitContainsCorrectClasses(parentDeploymentUnit);
}
@Test
public void testMultipleRemotableInPojoJar() {
String groupId = "org.test";
String pojoArtifactId = "jbpm-kie-services-filter-test-pojo";
String projectArtifactId = "jbpm-kie-services-filter-test-project";
String version = VERSION;
KieServices ks = KieServices.Factory.get();
ReleaseId pojoReleaseId = ks.newReleaseId( groupId, pojoArtifactId, VERSION );
File pojojar = new File( "src/test/resources/multi-remotable/pojo.jar" ); // contains two @Remotable classes MyPojo, MyPojo2
File pojopom = new File( this.getClass().getResource("/multi-remotable/pojo-pom.xml").getFile());
MavenRepository.getMavenRepository().installArtifact( pojoReleaseId, pojojar, pojopom );
FluentKieModuleDeploymentHelper.newFluentInstance()
.setGroupId( groupId )
.setArtifactId( projectArtifactId )
.setVersion( version )
.addDependencies( groupId + ":" + pojoArtifactId + ":" + version )
.createKieJarAndDeployToMaven();
configureServices();
KModuleDeploymentUnit deploymentUnit = new KModuleDeploymentUnit( groupId, projectArtifactId, version );
DeploymentDescriptor depDesc = new DeploymentDescriptorImpl().getBuilder().setLimitSerializationClasses( true ).get();
deploymentUnit.setDeploymentDescriptor( depDesc );
deploymentService.deploy( deploymentUnit );
DeployedUnit deployedUnit = deploymentService.getDeployedUnit( deploymentUnit.getIdentifier() );
Collection<Class<?>> deployedClasses = deployedUnit.getDeployedClasses();
ClassLoader classLoader = deploymentUnit.getKieContainer().getClassLoader();
try {
assertTrue( "MyPojo is not added", deployedClasses.contains( classLoader.loadClass( "com.sample.MyPojo" ) ) );
assertTrue( "MyPojo2 is not added", deployedClasses.contains( classLoader.loadClass( "com.sample.MyPojo2" ) ) );
} catch ( ClassNotFoundException e ) {
fail( e.getMessage() );
}
}
}