HHH-9699 - Re-work the hibernate-osgi integration tests using managed Karaf

This commit is contained in:
Steve Ebersole 2015-05-01 08:54:47 -05:00
parent 1b468d06a3
commit fde734e828
3 changed files with 55 additions and 236 deletions

View File

@ -23,6 +23,7 @@ buildscript {
classpath 'org.hibernate.build.gradle:hibernate-matrix-testing:1.0.0-SNAPSHOT'
classpath 'org.hibernate.build.gradle:version-injection-plugin:1.0.0'
classpath 'org.hibernate.build.gradle:gradle-xjc-plugin:1.0.2.Final'
classpath 'com.github.lburgazzoli:lb-karaf-features-gen:1.0.0.SNAPSHOT'
}
}

View File

@ -1,6 +1,4 @@
import java.util.jar.JarFile
import groovy.xml.MarkupBuilder
apply plugin: 'karaf-featuresgen'
ext {
paxExamVersion = '4.0.0'
@ -8,6 +6,9 @@ ext {
}
configurations {
aries {
description = 'Runtime dependencies for Aries for the hibernate-jpa-aries Karaf feature'
}
osgiRuntime {
// Ignore the transitive dependencies.
transitive = false
@ -74,6 +75,7 @@ dependencies {
testCompile "org.ops4j.pax.exam:pax-exam-junit4:${paxExamVersion}"
testCompile 'org.ops4j.pax.url:pax-url-aether:1.6.0'
karafFeaturesBundles "org.apache.logging.log4j:log4j-api:2.0"
//
//
//
@ -101,9 +103,9 @@ dependencies {
// testRuntime( "org.jboss.arquillian.container:arquillian-osgi-felix:2.0.0.CR4" )
// testRuntime( "org.apache.felix:org.apache.felix.framework:4.0.3" )
// testRuntime( "org.apache.felix:org.apache.felix.main:4.0.3" )
// testRuntime( libraries.slf4j_api );
// testRuntime( libraries.slf4j_log4j );
// testRuntime( "org.jboss.logmanager:jboss-logmanager:2.0.0.Beta1" )
testRuntime( libraries.slf4j_api );
testRuntime( libraries.slf4j_log4j );
testRuntime( "org.jboss.logmanager:jboss-logmanager:2.0.0.Beta1" )
//
// // Local copies of all jars needed fur the OSGi runtime. Ignore the transitive dependencies.
// // ORDER DEPENDENT!!!
@ -300,238 +302,54 @@ task generateDependsFile {
}
}
Project[] karafFeatureProjects = [
project.rootProject.project( "hibernate-core" ),
project.rootProject.project( "hibernate-entitymanager" ),
project.rootProject.project( "hibernate-envers" ),
project.rootProject.project( "hibernate-spatial" ),
project.rootProject.project( "hibernate-ehcache" ),
project.rootProject.project( "hibernate-infinispan" ),
project.rootProject.project( "hibernate-osgi" )
]
task generateKarafFeaturesXml(dependsOn: jar) {
File outputFileDir = project.libsDir
String fileName = "${project.name}-${project.version}-karaf.xml"
File outputFile = new File( outputFileDir, fileName )
outputs.file outputFile
inputs.files karafFeatureProjects*.configurations.runtime
// outputs.upToDateWhen(Specs.satisfyNone());
doFirst {
outputFileDir.mkdirs()
def writer = new BufferedWriter( new FileWriter( outputFile ) )
def builder = new MarkupBuilder( writer )
builder.features(xmlns:'http://karaf.apache.org/xmlns/features/v1.0.0') {
// extension.projects.each { project ->
karafFeatureProjects.each { selectedProject ->
// The LinkedHashSet here will hold the dependencies in order, transitivity depth first
LinkedHashSet<ResolvedComponentResult> orderedDependencies = new LinkedHashSet<ResolvedComponentResult>()
collectOrderedDependencies( orderedDependencies, selectedProject.configurations.runtime.incoming.resolutionResult.root )
builder.feature(name:"${selectedProject.name}", version:"${selectedProject.version}") {
generateBundles( selectedProject, builder, orderedDependencies )
// add bundle for this project
// generateBundles( builder, orderedDependencies, extension )
// extension.extraBundles.each { extraBundle ->
// builder.bundle( extraBundle )
// }
}
}
karafFeatures {
features {
// NOTE : would like to include spatial as well, but we need to wait for
// it to not define dependency on postgresql driver
hibernateNative {
name = 'hibernate-native'
projects = [
rootProject.childProjects.'hibernate-core',
rootProject.childProjects.'hibernate-envers',
project
]
}
hibernateJpa {
name = 'hibernate-jpa'
projects = [
rootProject.childProjects.'hibernate-entitymanager',
rootProject.childProjects.'hibernate-envers',
project
]
}
hibernateJpaAries {
name = 'hibernate-jpa-aries'
projects = [
rootProject.childProjects.'hibernate-entitymanager',
rootProject.childProjects.'hibernate-envers',
project
]
extraBundleDependencies = [project.configurations.aries]
}
hibernateInfinispan {
name = 'hibernate-infinispan'
projects = [
rootProject.childProjects.'hibernate-infinispan',
project
]
}
hibernateEhcache {
name = 'hibernate-ehcache'
projects = [
rootProject.childProjects.'hibernate-ehcache',
project
]
}
writer.close()
// if(project.karafFeatures.outputFile != null) {
// def out = new BufferedWriter(new FileWriter(project.karafFeatures.outputFile))
// out.write(writer.toString())
// out.close()
// } else {
// println writer.toString()
// }
}
}
test.dependsOn felixProperties
//test.dependsOn testClientBundleJar
test.dependsOn jar
test.dependsOn( [generateDependsFile, generateVersionFile, generateKarafFeaturesXml] )
karafFeatureProjects.each {
generateKarafFeaturesXml.dependsOn it.tasks.jar
}
/**
* Recursive method walking the dependency graph depth first in order to build a a set of
* dependencies ordered by their transitivity depth.
*
* @param orderedDependencies The ordered set of dependencies being built
* @param resolvedComponentResult The dependency to process
* @param extension The karafFeatures extension
*/
static void collectOrderedDependencies(
LinkedHashSet<ResolvedComponentResult> orderedDependencies,
ResolvedComponentResult resolvedComponentResult) {
// if ( shouldExclude( resolvedComponentResult, extension ) ) {
// return;
// }
// add dependencies first
resolvedComponentResult.dependencies.each {
if ( it instanceof UnresolvedDependencyResult ) {
// skip it
logger.debug( "Skipping dependency [%s] as it is unresolved", it.requested.displayName )
return;
}
collectOrderedDependencies( orderedDependencies, ( (ResolvedDependencyResult) it ).selected )
// collectOrderedDependencies( orderedDependencies, ( (ResolvedDependencyResult) it ).selected, extension )
}
// then add this one
orderedDependencies.add( resolvedComponentResult )
}
/**
* Using the passed MarkupBuilder, generate {@code <bundle/>} element for each dependency.
*
* @param builder The MarkupBuilder to use.
* @param orderedDependencies The ordered set of dependencies
* @param extension The karafFeatures extension
*/
void generateBundles(
Project selectedProject,
MarkupBuilder builder,
LinkedHashSet<ResolvedComponentResult> orderedDependencies) {
// The determination of whether to wrap partially involves seeing if the
// artifact (file) resolved from the dependency defined OSGi metadata. So we need a Map
// of the ResolvedArtifacts by their identifier (GAV)
def Map<ModuleVersionIdentifier,ResolvedArtifact> resolvedArtifactMap = new HashMap<ModuleVersionIdentifier,ResolvedArtifact>()
selectedProject.configurations.runtime.resolvedConfiguration.resolvedArtifacts.each {
resolvedArtifactMap.put( it.moduleVersion.id, it );
}
orderedDependencies.each { dep ->
logger.lifecycle( " >> ($selectedProject.name) Starting dependency bundle generation : ${dep.moduleVersion}" )
def mavenUrl = "mvn:${dep.moduleVersion.group}/${dep.moduleVersion.name}/${dep.moduleVersion.version}"
if ( shouldWrap( dep, selectedProject, resolvedArtifactMap ) ) {
mavenUrl = "wrap:${mavenUrl}"
}
def startLevel = getBundleStartLevel(dep)
if ( startLevel == null ) {
builder.bundle(mavenUrl)
}
else {
builder.bundle("start-level": startLevel, mavenUrl)
}
}
}
/**
* Should the bundle generated from this dependency use the {@code wrap:} url scheme?
*
* @param dep The dependency to check
* @param extension The karafFeatures extension
* @param resolvedArtifactMap The map of GAV->ResolvedArtifact
*
* @return {@code true} to indicate that the dependency should be wrapped; {@code false} indicates it should not.
*/
boolean shouldWrap(
ResolvedComponentResult dep,
Project selectedProject,
Map<ModuleVersionIdentifier,ResolvedArtifact> resolvedArtifactMap) {
// if ( matchedPattern( dep, extension.wraps ) ) {
// return true;
// }
if ( matchesPattern( dep, "${selectedProject.group}/${selectedProject.name}/${selectedProject.version}") ) {
boolean hasHeader = hasOsgiManifestHeaders( ( selectedProject.tasks.jar as Jar ).archivePath )
logger.lifecycle( " >> project artifact -> isOsgi = ${hasHeader}" )
return !hasHeader;
}
ResolvedArtifact resolvedArtifact = resolvedArtifactMap.get( dep.moduleVersion )
if ( resolvedArtifact != null ) {
boolean hasHeader = hasOsgiManifestHeaders( resolvedArtifact.file )
logger.lifecycle( " >> dependency artifact -> isOsgi = ${hasHeader}" )
return !hasHeader;
}
return true
}
public boolean hasOsgiManifestHeaders(File file) {
JarFile jarFile = new JarFile( file );
java.util.jar.Manifest manifest = jarFile.getManifest();
if ( manifest != null ) {
logger.lifecycle( "Found manifest [${file.absolutePath}], checking for OSGi metadata" )
if ( hasAttribute( manifest, "Bundle-SymbolicName" ) ) {
logger.lifecycle( " >> Found Bundle-SymbolicName" )
return true;
}
if ( hasAttribute( manifest, "Bundle-Name" ) ) {
logger.lifecycle( " >> Found Bundle-Name" )
return true;
}
}
return false;
}
public boolean hasAttribute(java.util.jar.Manifest manifest, String attributeName) {
String value = manifest.mainAttributes.getValue( attributeName )
return value != null && !value.trim().isEmpty()
}
/**
* Method to determine if a given jar file is am OSGi bundle.
* This is useful for determining if we need to wrap it, determined by the existence
* of a Bundle-SymbolicName manifest attribute..
*
* @param dep The dependency to check.
* @param resolvedArtifactMap Map of dependency ids (GAV) to ResolvedArtifact
*
* @return True if this dependency resolved to a jar with an OSGi bundle
*/
public boolean isOsgi(ResolvedComponentResult dep, Map<ModuleVersionIdentifier,ResolvedArtifact> resolvedArtifactMap) {
JarFile jarFile = new JarFile( resolvedArtifact.file );
java.util.jar.Manifest manifest = jarFile.getManifest();
if ( manifest != null ) {
Object value = manifest.getMainAttributes().getValue( "Bundle-SymbolicName" )
logger.lifecycle( "Manifest Bundle-SymbolicName (${dep.moduleVersion}) : ${value}" )
if ( value != null && !value.toString().isEmpty() ) {
return true;
}
}
else {
logger.lifecycle( "No manifest found ${dep.moduleVersion}" )
}
return false;
}
static def getBundleStartLevel(ResolvedComponentResult dep) {
return null;
}
static boolean matchesPattern(ResolvedComponentResult dep, String... patterns) {
for(String pattern : patterns) {
if("${dep.moduleVersion.group}/${dep.moduleVersion.name}/${dep.moduleVersion.version}".matches(pattern)) {
return true;
}
}
return false
}
test.dependsOn( [generateDependsFile, generateVersionFile, generateKarafFeatures] )

View File

@ -160,8 +160,8 @@ public class OsgiIntegrationTest {
// dir now points to the root classes output dir, go up one more...
dir = dir.getParentFile();
// go to the `libs` dir...
dir = new File( dir, "libs" );
// go to the `karafFeatures` dir...
dir = new File( dir, "karafFeatures" );
// and look for the feature file there...
final String featureFileName = String.format(