/*
* 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.kie.scanner;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import org.drools.compiler.kie.builder.impl.InternalKieModule;
import org.drools.compiler.kproject.xml.DependencyFilter;
import org.drools.core.rule.TypeMetaInfo;
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.KieModule;
import org.kie.api.builder.Message;
import org.kie.api.builder.ReleaseId;
import org.kie.api.builder.model.KieModuleModel;
import org.kie.api.definition.type.Role;
import static java.util.Arrays.asList;
import static junit.framework.TestCase.assertFalse;
import static org.drools.compiler.kie.builder.impl.KieBuilderImpl.generatePomXml;
import static org.junit.Assert.*;
public class KieModuleMetaDataTest extends AbstractKieCiTest {
@Test
public void testKieModuleMetaData() throws Exception {
ReleaseId releaseId = KieServices.Factory.get().newReleaseId( "org.drools", "drools-core", "5.5.0.Final" );
KieModuleMetaData kieModuleMetaData = KieModuleMetaData.Factory.newKieModuleMetaData( releaseId );
checkDroolsCoreDep( kieModuleMetaData );
assertTrue( ("" + kieModuleMetaData.getPackages()).contains( "junit" ) );
}
@Test
public void testKieModuleMetaDataWithoutTestDependencies() throws Exception {
ReleaseId releaseId = KieServices.Factory.get().newReleaseId( "org.drools", "drools-core", "5.5.0.Final" );
KieModuleMetaData kieModuleMetaData = KieModuleMetaData.Factory.newKieModuleMetaData( releaseId, new DependencyFilter.ExcludeScopeFilter("test") );
checkDroolsCoreDep( kieModuleMetaData );
assertFalse( ( "" + kieModuleMetaData.getPackages() ).contains( "junit" ) );
}
@Test
public void testKieModuleMetaDataForNonExistingGAV() throws Exception {
// DROOLS-1562
ReleaseId releaseId = KieServices.Factory.get().newReleaseId( "org.drools", "drools-core", "5.7.0.Final" );
KieModuleMetaData kieModuleMetaData = KieModuleMetaData.Factory.newKieModuleMetaData( releaseId );
assertEquals( 0, kieModuleMetaData.getPackages().size() );
}
@Test
public void testKieModuleMetaDataInMemoryWithJavaClass() throws Exception {
testKieModuleMetaDataInMemory( false );
}
@Test
public void testKieModuleMetaDataInMemoryWithTypeDeclaration() throws Exception {
testKieModuleMetaDataInMemory( true );
}
@Test
public void testKieModuleMetaDataInMemoryUsingPOMWithTypeDeclaration() throws Exception {
testKieModuleMetaDataInMemoryUsingPOM( true );
}
@Test
public void testKieModuleMetaDataForDependenciesInMemory() throws Exception {
testKieModuleMetaDataForDependenciesInMemory( false );
}
@Test
public void testKieModuleMetaDataInMemoryWithJavaClassDefaultPackage() throws Exception {
final KieServices ks = KieServices.Factory.get();
final ReleaseId releaseId = ks.newReleaseId( "org.kie", "javaDefaultPackage", "1.0-SNAPSHOT" );
final KieModuleModel kproj = ks.newKieModuleModel();
final KieFileSystem kfs = ks.newKieFileSystem();
kfs.writeKModuleXML( kproj.toXML() )
.writePomXML( generatePomXml( releaseId ) )
.write( "src/main/java/test/Bean.java", createJavaSource() );
final KieBuilder kieBuilder = ks.newKieBuilder( kfs );
final List<Message> messages = kieBuilder.buildAll().getResults().getMessages();
assertTrue( messages.isEmpty() );
final KieModule kieModule = kieBuilder.getKieModule();
final KieModuleMetaData kieModuleMetaData = KieModuleMetaData.Factory.newKieModuleMetaData( kieModule );
//The call to kieModuleMetaData.getClass() assumes a Java file has an explicit package
final Class<?> beanClass = kieModuleMetaData.getClass( "", "test.Bean" );
assertNotNull( beanClass );
final TypeMetaInfo beanMetaInfo = kieModuleMetaData.getTypeMetaInfo( beanClass );
assertNotNull( beanMetaInfo );
}
@Test
public void testGetPackageNames() {
final KieServices ks = KieServices.Factory.get();
final KieFileSystem kfs = ks.newKieFileSystem();
kfs.write( "src/main/resources/test.drl",
"package org.test declare Bean end" );
final KieBuilder kieBuilder = ks.newKieBuilder( kfs );
final List<Message> messages = kieBuilder.buildAll().getResults().getMessages();
assertTrue( messages.isEmpty() );
final KieModule kieModule = kieBuilder.getKieModule();
final KieModuleMetaData kieModuleMetaData = KieModuleMetaData.Factory.newKieModuleMetaData( kieModule );
assertFalse( kieModuleMetaData.getPackages().isEmpty() );
assertTrue( kieModuleMetaData.getPackages().contains( "org.test" ) );
}
@Test
public void testIncludeAllDeps() {
final KieServices ks = KieServices.Factory.get();
final KieFileSystem kfs = ks.newKieFileSystem();
kfs.writePomXML( getPomWithTestDependency() );
final KieModule kieModule = ks.newKieBuilder( kfs ).getKieModule();
final KieModuleMetaData kieModuleMetaData = KieModuleMetaData.Factory.newKieModuleMetaData( kieModule );
assertTrue( ("" + kieModuleMetaData.getPackages()).contains( "junit" ) );
}
@Test
public void testExcludeTestDeps() {
final KieServices ks = KieServices.Factory.get();
final KieFileSystem kfs = ks.newKieFileSystem();
kfs.writePomXML( getPomWithTestDependency() );
final KieModule kieModule = ks.newKieBuilder( kfs ).getKieModule();
final KieModuleMetaData kieModuleMetaData = KieModuleMetaData.Factory.newKieModuleMetaData( kieModule, new DependencyFilter.ExcludeScopeFilter("test") );
assertFalse( ( "" + kieModuleMetaData.getPackages() ).contains( "junit" ) );
}
private String getPomWithTestDependency() {
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n" +
" <modelVersion>4.0.0</modelVersion>\n" +
"\n" +
" <groupId>org.kie</groupId>\n" +
" <artifactId>test</artifactId>\n" +
" <version>1.0</version>\n" +
"\n" +
" <dependencies>\n" +
" <dependency>\n" +
" <groupId>junit</groupId>\n" +
" <artifactId>junit</artifactId>\n" +
" <version>4.11</version>\n" +
" <scope>test</scope>\n" +
" </dependency>\n" +
" </dependencies>\n" +
"</project>";
}
@Test
public void testGetRuleNames() {
final KieServices ks = KieServices.Factory.get();
final KieFileSystem kfs = ks.newKieFileSystem();
kfs.write( "src/main/resources/test1.drl",
"package org.test\n" +
"rule A\n" +
" when\n" +
"then\n" +
"end\n" +
"rule B\n" +
" when\n" +
"then\n" +
"end\n" );
kfs.write( "src/main/resources/test2.drl",
"package org.test\n" +
"rule C\n" +
" when\n" +
"then\n" +
"end\n" );
final KieBuilder kieBuilder = ks.newKieBuilder( kfs );
final List<Message> messages = kieBuilder.buildAll().getResults().getMessages();
assertTrue( messages.isEmpty() );
final KieModule kieModule = kieBuilder.getKieModule();
final KieModuleMetaData kieModuleMetaData = KieModuleMetaData.Factory.newKieModuleMetaData( kieModule );
Collection<String> rules = kieModuleMetaData.getRuleNamesInPackage( "org.test" );
assertEquals( 3, rules.size() );
assertTrue( rules.containsAll( asList( "A", "B", "C" ) ) );
}
private String createJavaSource() {
return "package test;\n" +
"public class Bean {\n" +
" private int value;\n" +
" public int getValue() {\n" +
" return value;\n" +
" }\n" +
"}";
}
private void testKieModuleMetaDataInMemory( boolean useTypeDeclaration ) throws Exception {
KieServices ks = KieServices.Factory.get();
ReleaseId dependency = ks.newReleaseId( "org.drools", "drools-core", "5.5.0.Final" );
ReleaseId releaseId = ks.newReleaseId( "org.kie", "metadata-test", "1.0-SNAPSHOT" );
InternalKieModule kieModule = createKieJarWithClass( ks, releaseId, useTypeDeclaration, 2, 7, dependency );
KieModuleMetaData kieModuleMetaData = KieModuleMetaData.Factory.newKieModuleMetaData( kieModule );
checkDroolsCoreDep( kieModuleMetaData );
Collection<String> testClasses = kieModuleMetaData.getClasses( "org.kie.test" );
assertEquals( 1, testClasses.size() );
assertEquals( "Bean", testClasses.iterator().next() );
Class<?> beanClass = kieModuleMetaData.getClass( "org.kie.test", "Bean" );
assertNotNull( beanClass.getMethod( "getValue" ) );
TypeMetaInfo beanTypeInfo = kieModuleMetaData.getTypeMetaInfo( beanClass );
assertNotNull( beanTypeInfo );
assertTrue( beanTypeInfo.isEvent() );
Role role = beanClass.getAnnotation( Role.class );
assertNotNull( role );
assertEquals( Role.Type.EVENT, role.value() );
assertEquals( useTypeDeclaration, beanTypeInfo.isDeclaredType() );
}
private void testKieModuleMetaDataInMemoryUsingPOM( boolean useTypeDeclaration ) throws Exception {
//Build a KieModule jar, deploy it into local Maven repository
KieServices ks = KieServices.Factory.get();
ReleaseId dependency = ks.newReleaseId( "org.drools", "drools-core", "5.5.0.Final" );
ReleaseId releaseId = ks.newReleaseId( "org.kie", "metadata-test", "1.0-SNAPSHOT" );
InternalKieModule kieModule = createKieJarWithClass( ks, releaseId, useTypeDeclaration, 2, 7, dependency );
String pomText = getPom( dependency );
File pomFile = new File( System.getProperty( "java.io.tmpdir" ), MavenRepository.toFileName( releaseId, null ) + ".pom" );
try {
FileOutputStream fos = new FileOutputStream( pomFile );
fos.write( pomText.getBytes() );
fos.flush();
fos.close();
} catch ( IOException e ) {
throw new RuntimeException( e );
}
MavenRepository.getMavenRepository().installArtifact( releaseId, kieModule, pomFile );
//Build a second KieModule, depends on the first KieModule jar which we have deployed into Maven
ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "metadata-test-using-pom", "1.0-SNAPSHOT" );
String pomText2 = getPom( releaseId2, releaseId );
File pomFile2 = new File( System.getProperty( "java.io.tmpdir" ), MavenRepository.toFileName( releaseId2, null ) + ".pom" );
try {
FileOutputStream fos = new FileOutputStream( pomFile2 );
fos.write( pomText2.getBytes() );
fos.flush();
fos.close();
} catch ( IOException e ) {
throw new RuntimeException( e );
}
KieModuleMetaData kieModuleMetaData = KieModuleMetaData.Factory.newKieModuleMetaData( pomFile2 );
//checkDroolsCoreDep(kieModuleMetaData);
Collection<String> testClasses = kieModuleMetaData.getClasses( "org.kie.test" );
assertEquals( 1, testClasses.size() );
assertEquals( "Bean", testClasses.iterator().next() );
Class<?> beanClass = kieModuleMetaData.getClass( "org.kie.test", "Bean" );
assertNotNull( beanClass.getMethod( "getValue" ) );
if ( useTypeDeclaration ) {
assertTrue( kieModuleMetaData.getTypeMetaInfo( beanClass ).isEvent() );
}
}
private void checkDroolsCoreDep( KieModuleMetaData kieModuleMetaData ) {
assertEquals( 17, kieModuleMetaData.getClasses( "org.drools.runtime" ).size() );
Class<?> statefulKnowledgeSessionClass = kieModuleMetaData.getClass( "org.drools.runtime", "StatefulKnowledgeSession" );
assertTrue( statefulKnowledgeSessionClass.isInterface() );
assertEquals( 2, statefulKnowledgeSessionClass.getDeclaredMethods().length );
}
private void testKieModuleMetaDataForDependenciesInMemory( boolean useTypeDeclaration ) throws Exception {
KieServices ks = KieServices.Factory.get();
ReleaseId dependency = ks.newReleaseId( "org.drools", "drools-core", "5.5.0.Final" );
ReleaseId releaseId = ks.newReleaseId( "org.kie", "metadata-test", "1.0-SNAPSHOT" );
InternalKieModule kieModule = createKieJarWithClass( ks, releaseId, useTypeDeclaration, 2, 7, dependency );
KieModuleMetaData kieModuleMetaData = KieModuleMetaData.Factory.newKieModuleMetaData( kieModule );
checkDroolsCoreDep( kieModuleMetaData );
Collection<String> testClasses = kieModuleMetaData.getClasses( "org.drools" );
assertEquals( 55, testClasses.size() );
Class<?> beanClass = kieModuleMetaData.getClass( "org.drools", "QueryResult" );
assertNotNull( beanClass );
//Classes in dependencies should have TypeMetaInfo
TypeMetaInfo beanTypeInfo = kieModuleMetaData.getTypeMetaInfo( beanClass );
assertNotNull( beanTypeInfo );
if ( useTypeDeclaration ) {
assertTrue( beanTypeInfo.isEvent() );
}
assertEquals( useTypeDeclaration, beanTypeInfo.isDeclaredType() );
}
@Test
public void testKieMavenPluginEmptyProject() {
// According to https://bugzilla.redhat.com/show_bug.cgi?id=1049674#c2 the below is the minimal POM required to use KieMavenPlugin.
final KieServices ks = KieServices.Factory.get();
final KieFileSystem kfs = ks.newKieFileSystem();
kfs.write( "pom.xml",
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<project xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\" xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+ " <modelVersion>4.0.0</modelVersion>"
+ " <groupId>org.kie</groupId>"
+ " <artifactId>plugin-test</artifactId>"
+ " <version>1.0</version>"
+ " <packaging>kjar</packaging>"
+ " <build>"
+ " <plugins>"
+ " <plugin>"
+ " <groupId>org.kie</groupId>"
+ " <artifactId>kie-maven-plugin</artifactId>"
+ " <version>the-test-does-not-need-proper-version-here</version>"
+ " <extensions>true</extensions>"
+ " </plugin>"
+ " </plugins>"
+ " </build>"
+ "</project>" );
kfs.write("/src/main/resources/META-INF/kmodule.xml",
"<kmodule xmlns=\"http://www.drools.org/xsd/kmodule\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>");
final KieBuilder kieBuilder = ks.newKieBuilder( kfs );
final List<Message> messages = kieBuilder.buildAll().getResults().getMessages();
assertTrue( messages.isEmpty() );
final KieModule kieModule = kieBuilder.getKieModule();
final KieModuleMetaData kieModuleMetaData = KieModuleMetaData.Factory.newKieModuleMetaData( kieModule );
boolean fail = false;
for ( final String packageName : kieModuleMetaData.getPackages() ) {
for ( final String className : kieModuleMetaData.getClasses( packageName ) ) {
try {
kieModuleMetaData.getClass( packageName, className );
} catch ( Throwable e ) {
fail = true;
System.out.println( e );
}
}
}
if ( fail ) {
fail( "See console for details." );
}
}
}