Retire/remove version scan

Remove version scan dead code and unnecessary classLoaderMatcher methods in instrumentations. Depends on #572
This commit is contained in:
Gary 2018-11-09 17:09:24 -05:00 committed by Gary Huang
parent 5bbc76f7b9
commit 90777f4b39
No known key found for this signature in database
GPG Key ID: 0CB168EE6C6844B7
6 changed files with 0 additions and 323 deletions

View File

@ -1,11 +0,0 @@
class VersionScanExtension {
String group
String module
String versions
boolean scanMethods = false
boolean scanDependencies = false
String legacyGroup
String legacyModule
Map<String, String> verifyPresent = Collections.emptyMap()
List<String> verifyMissing = Collections.emptyList()
}

View File

@ -1,291 +0,0 @@
import com.google.common.collect.Sets
import org.apache.maven.repository.internal.MavenRepositorySystemUtils
import org.eclipse.aether.DefaultRepositorySystemSession
import org.eclipse.aether.RepositorySystem
import org.eclipse.aether.RepositorySystemSession
import org.eclipse.aether.artifact.Artifact
import org.eclipse.aether.artifact.DefaultArtifact
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory
import org.eclipse.aether.impl.DefaultServiceLocator
import org.eclipse.aether.repository.LocalRepository
import org.eclipse.aether.repository.RemoteRepository
import org.eclipse.aether.resolution.VersionRangeRequest
import org.eclipse.aether.resolution.VersionRangeResult
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory
import org.eclipse.aether.spi.connector.transport.TransporterFactory
import org.eclipse.aether.transport.http.HttpTransporterFactory
import org.eclipse.aether.version.Version
import org.gradle.api.GradleException
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.objectweb.asm.ClassReader
import org.objectweb.asm.tree.ClassNode
import java.util.concurrent.atomic.AtomicReference
import java.util.jar.JarEntry
import java.util.jar.JarFile
/**
* Version syntax: https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html
*/
class VersionScanPlugin implements Plugin<Project> {
void apply(Project project) {
RepositorySystem system = newRepositorySystem()
RepositorySystemSession session = newRepositorySystemSession(system)
project.extensions.create("versionScan", VersionScanExtension)
def scanVersions = project.task('scanVersions') {
group = 'VersionScan'
description = "Verify instrumentation against runtime classpaths."
}
def hasRelevantTask = project.gradle.startParameter.taskNames.any { it.contains('scanVersions') }
hasRelevantTask |= project.gradle.startParameter.taskNames.any { it.contains('scanVersionsReport') }
hasRelevantTask |= project.gradle.startParameter.taskNames.any { it.contains('verifyVersionScan') }
if (!hasRelevantTask) {
return
}
if (!project.rootProject.version.toString().endsWith("-SNAPSHOT")) {
println "Skipping verifyVersionScan for release build."
project.task('verifyVersionScan').onlyIf { false }
return
}
// println "Adding scan tasks for $project"
Set<String> allInclude = Sets.newConcurrentHashSet()
Set<String> allExclude = Sets.newConcurrentHashSet()
AtomicReference<Set<String>> keyPresent = new AtomicReference(Collections.emptySet())
AtomicReference<Set<String>> keyMissing = new AtomicReference(Collections.emptySet())
def scanVersionsReport = project.task('scanVersionsReport') {
description = "Prints the result of the scanVersions task"
doLast {
def inCommonPresent = keyPresent.get().size()
def inCommonMissing = keyMissing.get().size()
keyPresent.get().removeAll(allExclude)
keyMissing.get().removeAll(allInclude)
def exclusivePresent = keyPresent.get().size()
def exclusiveMissing = keyMissing.get().size()
if (project.hasProperty("showClasses")) {
println "keyPresent: ${allInclude.size()}->$inCommonPresent->$exclusivePresent - ${keyPresent.get()}"
println "+++++++++++++++++++++"
println "keyMissing: ${allExclude.size()}->$inCommonMissing->$exclusiveMissing - ${keyMissing.get()}"
} else {
println "keyPresent: $inCommonPresent->$exclusivePresent"
println "keyMissing: $inCommonMissing->$exclusiveMissing"
}
}
}
if (project.gradle.startParameter.taskNames.any { it.contains('scanVersions') }) {
scanVersions.finalizedBy(scanVersionsReport)
}
project.repositories {
mavenCentral()
jcenter()
}
project.afterEvaluate {
String group = project.versionScan.group
String module = project.versionScan.module
String versions = project.versionScan.versions
Artifact artifact = new DefaultArtifact(group, module, "jar", versions)
Artifact allVersions = new DefaultArtifact(group, module, "jar", "(,)")
String legacyGroup = project.versionScan.legacyGroup == null ? group : project.versionScan.legacyGroup
String legacyModule = project.versionScan.legacyModule == null ? module : project.versionScan.legacyModule
Artifact allLegacyVersions = new DefaultArtifact(legacyGroup, legacyModule, "jar", "(,)")
VersionRangeRequest rangeRequest = new VersionRangeRequest()
rangeRequest.setRepositories(newRepositories(system, session))
rangeRequest.setArtifact(artifact)
VersionRangeResult rangeResult = system.resolveVersionRange(session, rangeRequest)
rangeRequest.setArtifact(allVersions)
VersionRangeResult allResult = system.resolveVersionRange(session, rangeRequest)
def includeVersionSet = Sets.newHashSet(filter(rangeResult.versions).collect {
new DefaultArtifact(group, module, "jar", it.toString())
})
def excludeVersionSet = Sets.newHashSet(filter(allResult.versions).collect {
new DefaultArtifact(group, module, "jar", it.toString())
})
excludeVersionSet.removeAll(includeVersionSet)
if (allVersions != allLegacyVersions) {
// println "Adding legacy versions $allLegacyVersions"
rangeRequest.setArtifact(allLegacyVersions)
VersionRangeResult allLegacyResult = system.resolveVersionRange(session, rangeRequest)
def legacyVersions = filter(allLegacyResult.versions)
// println "Found ${legacyVersions.size()} legacy versions for $legacyGroup:$legacyModule"
excludeVersionSet.addAll(legacyVersions.collect {
new DefaultArtifact(legacyGroup, legacyModule, "jar", it.toString())
})
}
if (excludeVersionSet.empty) {
println "Found ${includeVersionSet.size()} versions, but none to exclude. Skipping..."
scanVersionsReport.enabled = false
return
}
Map<String, String> verifyPresent = project.versionScan.verifyPresent
List<String> verifyMissing = project.versionScan.verifyMissing
if (!verifyPresent.isEmpty() || !verifyMissing.isEmpty()) {
def verifyVersionScan = project.task('verifyVersionScan') {
description = "Validates that the configured classes and methods are only present where expected."
}
verifyVersionScan.doLast {
// This may already be done by the report task, but repeating for good measure.
keyPresent.get().removeAll(allExclude)
keyMissing.get().removeAll(allInclude)
assert keyPresent.get() != [] || keyMissing.get() != []
def errors = []
for (String className : verifyPresent.keySet()) {
if (project.versionScan.scanMethods && verifyPresent.get(className) == null) {
throw new AssertionError("When 'scanMethods' is enabled, a method must be configured for '$className'")
} else if (!project.versionScan.scanMethods && verifyPresent.get(className) != null) {
throw new AssertionError("When 'scanMethods' is not enabled, configured method must be null for '$className'")
}
String identifier = project.versionScan.scanMethods ? "$className|${verifyPresent.get(className)}" : className
if (!keyPresent.get().contains(identifier)) {
errors << "not a 'keyPresent' identifier: $identifier"
}
}
for (String className : verifyMissing) {
if (!keyMissing.get().contains(className)) {
errors << "not a 'keyMissing' identifier: $className"
}
}
errors.each {
logger.error "Error for $group:$module - $it"
}
if (!errors.isEmpty()) {
throw new GradleException("Version scan verification failed.\n" +
"Errors listed above are likely the result of a new module " +
"being published to Maven, not a code change in this repo.")
}
}
if (project.gradle.startParameter.taskNames.any { it.contains('scanVersions') }) {
scanVersions.finalizedBy(verifyVersionScan)
}
}
// println "Scanning ${includeVersionSet.size()} included and ${excludeVersionSet.size()} excluded versions."
// println "Included: ${includeVersionSet.collect { it.version }}}"
// println "Excluded: ${excludeVersionSet.collect { it.version }}}"
includeVersionSet.each { version ->
addScanTask("Include", new DefaultArtifact(version.groupId, version.artifactId, "jar", version.version), keyPresent, allInclude, project)
}
excludeVersionSet.each { version ->
addScanTask("Exclude", new DefaultArtifact(version.groupId, version.artifactId, "jar", version.version), keyMissing, allExclude, project)
}
}
}
def addScanTask(String label, Artifact artifact, AtomicReference<Set<String>> keyIdentifiers, Set<String> allIdentifiers, Project project) {
def name = "scanVersion$label-$artifact.groupId-$artifact.artifactId-$artifact.version"
def config = project.configurations.create(name)
config.dependencies.add(project.dependencies.create("$artifact.groupId:$artifact.artifactId:$artifact.version") {
transitive = project.versionScan.scanDependencies
})
def task = project.task(name) {
doLast {
Set<String> contentSet = Sets.newConcurrentHashSet()
project.configurations.getByName(name).resolvedConfiguration.files.each { jarFile ->
def jar = new JarFile(jarFile)
for (jarEntry in jar.entries()) {
if (jarEntry.name.endsWith(".class")) {
def className = jarEntry.name
className = className.replaceAll("/", ".")
className = className.replace(".class", "")
if (project.versionScan.scanMethods) {
findMethodNames(jar, jarEntry).each {
contentSet.add("$className|$it".toString())
}
} else {
contentSet.add(className)
}
}
}
}
allIdentifiers.addAll(contentSet)
if (!keyIdentifiers.compareAndSet(Collections.emptySet(), contentSet)) {
def intersection = Sets.intersection(keyIdentifiers.get(), contentSet)
keyIdentifiers.get().retainAll(intersection)
}
}
}
project.tasks.scanVersions.finalizedBy(task)
project.tasks.scanVersionsReport.dependsOn(task)
if (project.tasks.hasProperty("verifyVersionScan")) {
project.tasks.verifyVersionScan.dependsOn(task)
}
}
def filter(List<Version> list) {
list.removeIf {
def version = it.toString().toLowerCase()
return version.contains("rc") ||
version.contains(".cr") ||
version.contains("alpha") ||
version.contains("beta") ||
version.contains("-b") ||
version.contains(".m") ||
version.contains("-dev") ||
version.contains("public_draft")
}
return list
}
def findMethodNames(JarFile jar, JarEntry entry) {
def stream = jar.getInputStream(entry)
def classNode = new ClassNode()
def cr = new ClassReader(stream)
cr.accept(classNode, 0)
return classNode.methods.collect { it.name }
}
RepositorySystem newRepositorySystem() {
DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator()
locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class)
locator.addService(TransporterFactory.class, HttpTransporterFactory.class)
return locator.getService(RepositorySystem.class)
}
DefaultRepositorySystemSession newRepositorySystemSession(RepositorySystem system) {
DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession()
def tempDir = File.createTempDir()
tempDir.deleteOnExit()
LocalRepository localRepo = new LocalRepository(tempDir)
session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo))
return session
}
static List<RemoteRepository> newRepositories(RepositorySystem system, RepositorySystemSession session) {
return new ArrayList<RemoteRepository>(Arrays.asList(newCentralRepository()))
}
private static RemoteRepository newCentralRepository() {
return new RemoteRepository.Builder("central", "default", "http://central.maven.org/maven2/").build()
}
}

View File

@ -1,6 +1,5 @@
package datadog.trace.instrumentation.elasticsearch5_3;
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
import static io.opentracing.log.Fields.ERROR_OBJECT;
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
@ -42,11 +41,6 @@ public class Elasticsearch53TransportClientInstrumentation extends Instrumenter.
return not(isInterface()).and(named("org.elasticsearch.client.support.AbstractClient"));
}
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
return classLoaderHasClasses("org.elasticsearch.percolator.TransportMultiPercolateAction");
}
@Override
public String[] helperClassNames() {
return new String[] {

View File

@ -1,6 +1,5 @@
package datadog.trace.instrumentation.elasticsearch5;
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
import static io.opentracing.log.Fields.ERROR_OBJECT;
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
@ -41,11 +40,6 @@ public class Elasticsearch5TransportClientInstrumentation extends Instrumenter.D
return not(isInterface()).and(named("org.elasticsearch.client.support.AbstractClient"));
}
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
return classLoaderHasClasses("org.elasticsearch.percolator.TransportMultiPercolateAction");
}
@Override
public String[] helperClassNames() {
return new String[] {

View File

@ -1,6 +1,5 @@
package datadog.trace.instrumentation.kafka_streams;
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
import static io.opentracing.log.Fields.ERROR_OBJECT;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.isPackagePrivate;
@ -103,12 +102,6 @@ public class KafkaStreamsProcessorInstrumentation {
return named("org.apache.kafka.streams.processor.internals.StreamTask");
}
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
return classLoaderHasClasses(
"org.apache.kafka.common.header.Header", "org.apache.kafka.common.header.Headers");
}
@Override
public String[] helperClassNames() {
return HELPER_CLASS_NAMES;

View File

@ -4,8 +4,6 @@ ext {
maxJavaVersionForTests = JavaVersion.VERSION_1_8
}
apply plugin: 'version-scan'
muzzle {
pass {
group = "io.lettuce"