Merge pull request #113 from DataDog/tyler/jetty

Add version checking via class/method for jetty
This commit is contained in:
Tyler Benson 2017-08-24 17:41:13 -07:00 committed by GitHub
commit 10faa9ab89
7 changed files with 103 additions and 56 deletions

View File

@ -139,6 +139,12 @@ class VersionScanPlugin implements Plugin<Project> {
def errors = [] def errors = []
for (String className : verifyPresent.keySet()) { 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 String identifier = project.versionScan.scanMethods ? "$className|${verifyPresent.get(className)}" : className
if (!keyPresent.get().contains(identifier)) { if (!keyPresent.get().contains(identifier)) {
errors << "not a 'keyPresent' identifier: $identifier" errors << "not a 'keyPresent' identifier: $identifier"

View File

@ -0,0 +1,13 @@
apply plugin: 'version-scan'
versionScan {
group = "org.eclipse.jetty"
module = "jetty-server"
versions = "[8.0,)"
legacyGroup = "org.mortbay.jetty"
legacyModule = "jetty"
scanMethods = true
verifyPresent = [
"org.eclipse.jetty.server.ServletRequestHttpWrapper": "getPart",
]
}

View File

@ -4,6 +4,7 @@ import com.datadoghq.trace.resolver.FactoryUtils;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import java.io.File; import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -131,11 +132,33 @@ public class InstrumentationChecker {
log.debug("Checking rule {}", check); log.debug("Checking rule {}", check);
boolean matched = true; boolean matched = true;
for (final String identifyingClass : check.identifyingPresentClasses) { for (final Map.Entry<String, String> identifier :
final boolean classPresent = isClassPresent(identifyingClass); check.identifyingPresentClasses.entrySet()) {
final boolean classPresent = isClassPresent(identifier.getKey());
if (!classPresent) { if (!classPresent) {
log.debug( log.debug("Instrumentation {} not applied due to missing class {}.", rule, identifier);
"Instrumentation {} not applied due to missing class {}.", rule, identifyingClass); } else {
String identifyingMethod = identifier.getValue();
if (identifyingMethod != null && !identifyingMethod.isEmpty()) {
Class clazz = getClassIfPresent(identifier.getKey(), classLoader);
// already confirmed above the class is there.
Method[] declaredMethods = clazz.getDeclaredMethods();
boolean methodFound = false;
for (Method m : declaredMethods) {
if (m.getName().equals(identifyingMethod)) {
methodFound = true;
break;
}
}
if (!methodFound) {
log.debug(
"Instrumentation {} not applied due to missing method {}.{}",
rule,
identifier.getKey(),
identifyingMethod);
matched = false;
}
}
} }
matched &= classPresent; matched &= classPresent;
} }
@ -183,11 +206,14 @@ public class InstrumentationChecker {
} }
static boolean isClassPresent(final String identifyingPresentClass, ClassLoader classLoader) { static boolean isClassPresent(final String identifyingPresentClass, ClassLoader classLoader) {
return getClassIfPresent(identifyingPresentClass, classLoader) != null;
}
static Class getClassIfPresent(final String identifyingPresentClass, ClassLoader classLoader) {
try { try {
return identifyingPresentClass != null return Class.forName(identifyingPresentClass, false, classLoader);
&& Class.forName(identifyingPresentClass, false, classLoader) != null; } catch (final Exception e) {
} catch (final ClassNotFoundException e) { return null;
return false;
} }
} }
@ -199,7 +225,7 @@ public class InstrumentationChecker {
private String supportedVersion; private String supportedVersion;
@JsonProperty("identifying_present_classes") @JsonProperty("identifying_present_classes")
private List<String> identifyingPresentClasses = Collections.emptyList(); private Map<String, String> identifyingPresentClasses = Collections.emptyMap();
@JsonProperty("identifying_missing_classes") @JsonProperty("identifying_missing_classes")
private List<String> identifyingMissingClasses = Collections.emptyList(); private List<String> identifyingMissingClasses = Collections.emptyList();

View File

@ -1,18 +1,18 @@
### This file define all supported libraries ### This file define all supported libraries
### Syntax: ### Syntax:
### <rulename>: # the rule name defined in the otarules.btm ### <rulename>: # the rule name defined in the otarules.btm
### - artifact: <artifactId> # the artifact name to be tested ### - artifact: <artifactId> # the artifact name to be tested
### supported_version: # a regex expression to express the version required by the rule ### supported_version: # a regex expression to express the version required by the rule
### identifying_present_classes: # a list of classes that distinctly identify the range of supported libraries ### identifying_present_classes: # a list of classes that distinctly identify the range of supported libraries
### - some.key.FrameworkClass # only if missing, supported_version regex is used. ### some.key.FrameworkClass: orMethod # only if missing, supported_version regex is used.
### - ... ### - ...
opentracing-apache-httpclient: opentracing-apache-httpclient:
- artifact: httpclient - artifact: httpclient
supported_version: 4\.[3|4|5]\..* supported_version: 4\.[3|4|5]\..*
identifying_present_classes: identifying_present_classes:
- org.apache.http.conn.SchemePortResolver org.apache.http.conn.SchemePortResolver:
- org.apache.http.conn.ssl.SSLContexts org.apache.http.conn.ssl.SSLContexts:
- artifact: commons-httpclient - artifact: commons-httpclient
supported_version: none supported_version: none
@ -21,82 +21,83 @@ opentracing-aws-sdk:
- artifact: aws-java-sdk - artifact: aws-java-sdk
supported_version: 1\.11\..* supported_version: 1\.11\..*
identifying_present_classes: identifying_present_classes:
- com.amazonaws.http.client.HttpClientFactory com.amazonaws.http.client.HttpClientFactory:
- com.amazonaws.http.apache.utils.ApacheUtils com.amazonaws.http.apache.utils.ApacheUtils:
- com.amazonaws.http.request.HttpRequestFactory com.amazonaws.http.request.HttpRequestFactory:
opentracing-cassandra-driver: opentracing-cassandra-driver:
- artifact: cassandra-driver-core - artifact: cassandra-driver-core
supported_version: 3\.2.* supported_version: 3\.2.*
identifying_present_classes: identifying_present_classes:
- com.datastax.driver.core.utils.MoreObjects com.datastax.driver.core.utils.MoreObjects:
- com.datastax.driver.core.RemoteEndpointAwareNettySSLOptions com.datastax.driver.core.RemoteEndpointAwareNettySSLOptions:
- com.datastax.driver.core.GuavaCompatibility com.datastax.driver.core.GuavaCompatibility:
opentracing-jms-2_producer: opentracing-jms-2_producer:
- artifact: javax.jms-api - artifact: javax.jms-api
supported_version: 2\..* supported_version: 2\..*
identifying_present_classes: identifying_present_classes:
- javax.jms.JMSContext javax.jms.JMSContext:
- javax.jms.CompletionListener javax.jms.CompletionListener:
opentracing-jms-2_consumer: opentracing-jms-2_consumer:
- artifact: javax.jms-api - artifact: javax.jms-api
supported_version: 2\..* supported_version: 2\..*
identifying_present_classes: identifying_present_classes:
- javax.jms.JMSContext javax.jms.JMSContext:
- javax.jms.CompletionListener javax.jms.CompletionListener:
opentracing-mongo-driver: opentracing-mongo-driver:
- artifact: mongo-java-driver - artifact: mongo-java-driver
supported_version: 3\..* supported_version: 3\..*
identifying_present_classes: identifying_present_classes:
- com.mongodb.operation.AsyncReadOperation com.mongodb.operation.AsyncReadOperation:
- com.mongodb.client.model.MapReduceAction com.mongodb.client.model.MapReduceAction:
- artifact: mongodb-driver-async - artifact: mongodb-driver-async
supported_version: 3\..* supported_version: 3\..*
identifying_present_classes: identifying_present_classes:
- com.mongodb.operation.AsyncReadOperation com.mongodb.operation.AsyncReadOperation:
- com.mongodb.client.model.MapReduceAction com.mongodb.client.model.MapReduceAction:
opentracing-mongo-driver-helper: opentracing-mongo-driver-helper:
- artifact: mongo-java-driver - artifact: mongo-java-driver
supported_version: 3\..* supported_version: 3\..*
identifying_present_classes: identifying_present_classes:
- com.mongodb.operation.AsyncReadOperation com.mongodb.operation.AsyncReadOperation:
- com.mongodb.client.model.MapReduceAction com.mongodb.client.model.MapReduceAction:
- artifact: mongodb-driver-async - artifact: mongodb-driver-async
supported_version: 3\..* supported_version: 3\..*
identifying_present_classes: identifying_present_classes:
- com.mongodb.operation.AsyncReadOperation com.mongodb.operation.AsyncReadOperation:
- com.mongodb.client.model.MapReduceAction com.mongodb.client.model.MapReduceAction:
opentracing-okhttp3: opentracing-okhttp3:
- artifact: okhttp - artifact: okhttp
supported_version: 3\..* supported_version: 3\..*
identifying_present_classes: identifying_present_classes:
- okhttp3.Cookie okhttp3.Cookie:
- okhttp3.ConnectionPool okhttp3.ConnectionPool:
- okhttp3.Headers okhttp3.Headers:
opentracing-web-servlet-filter_jetty: opentracing-web-servlet-filter_jetty:
- artifact: jetty-server - artifact: jetty-server
supported_version: (8\.|9\.).* supported_version: (8\.|9\.).*
# identifying_present_classes: identifying_present_classes:
org.eclipse.jetty.server.ServletRequestHttpWrapper: getPart
opentracing-web-servlet-filter_tomcat: opentracing-web-servlet-filter_tomcat:
- artifact: opentracing-web-servlet-filter_tomcat - artifact: opentracing-web-servlet-filter_tomcat
supported_version: (8\.|9\.).* supported_version: (8\.|9\.).*
identifying_present_classes: identifying_present_classes:
- org.apache.catalina.WebResource org.apache.catalina.WebResource:
- org.apache.catalina.webresources.TrackedInputStream org.apache.catalina.webresources.TrackedInputStream:
- org.apache.catalina.webresources.AbstractArchiveResource org.apache.catalina.webresources.AbstractArchiveResource:
- artifact: opentracing-web-servlet-filter_tomcat - artifact: opentracing-web-servlet-filter_tomcat
supported_version: (8\.|9\.).* supported_version: (8\.|9\.).*
identifying_present_classes: identifying_present_classes:
- org.apache.catalina.WebResource org.apache.catalina.WebResource:
- org.apache.catalina.webresources.TrackedInputStream org.apache.catalina.webresources.TrackedInputStream:
- org.apache.catalina.webresources.AbstractArchiveResource org.apache.catalina.webresources.AbstractArchiveResource:

View File

@ -24,7 +24,9 @@ class InstrumentationCheckerTest extends Specification {
rules.sort() == ["unsupportedRuleOne", "unsupportedRuleThree", "unsupportedRuleTwo"] rules.sort() == ["unsupportedRuleOne", "unsupportedRuleThree", "unsupportedRuleTwo"]
} }
static class DemoClass1 {} static class DemoClass1 {
void testMethod(String arg) {}
}
static class DemoClass2 {} static class DemoClass2 {}

View File

@ -4,38 +4,36 @@ unsupportedRuleOne:
- artifact: artifact-2 - artifact: artifact-2
supported_version: none supported_version: none
identifying_present_classes:
-
unsupportedRuleTwo: unsupportedRuleTwo:
- artifact: artifact-1 - artifact: artifact-1
supported_version: 2\.3\. supported_version: 2\.3\.
identifying_present_classes: identifying_present_classes:
- com.datadoghq.trace.agent.InstrumentationCheckerTest$MissingClass com.datadoghq.trace.agent.InstrumentationCheckerTest$DemoClass1: missingMethod
supportedRuleOne: supportedRuleOne:
- artifact: artifact-3 - artifact: artifact-3
supported_version: 5\..* supported_version: 5\..*
identifying_present_classes: identifying_present_classes:
- com.datadoghq.trace.agent.InstrumentationCheckerTest$DemoClass1 com.datadoghq.trace.agent.InstrumentationCheckerTest$DemoClass1:
- com.datadoghq.trace.agent.InstrumentationCheckerTest$DemoClass2 com.datadoghq.trace.agent.InstrumentationCheckerTest$DemoClass2:
- com.datadoghq.trace.agent.InstrumentationCheckerTest$DemoClass3 com.datadoghq.trace.agent.InstrumentationCheckerTest$DemoClass3:
supportedRuleTwo: supportedRuleTwo:
- artifact: artifact-1 - artifact: artifact-1
supported_version: 1\.2\.3\..* supported_version: 1\.2\.3\..*
identifying_present_classes: identifying_present_classes:
- com.datadoghq.trace.agent.InstrumentationCheckerTest$DemoClass1 com.datadoghq.trace.agent.InstrumentationCheckerTest$DemoClass1: testMethod
- com.datadoghq.trace.agent.InstrumentationCheckerTest$DemoClass2 com.datadoghq.trace.agent.InstrumentationCheckerTest$DemoClass2:
- artifact: artifact-2 - artifact: artifact-2
supported_version: 4\..* supported_version: 4\..*
identifying_present_classes: identifying_present_classes:
- com.datadoghq.trace.agent.InstrumentationCheckerTest$DemoClass3 com.datadoghq.trace.agent.InstrumentationCheckerTest$DemoClass3: missingMethod
unsupportedRuleThree: unsupportedRuleThree:
- artifact: foo - artifact: foo
supported_version: 1 supported_version: 1
identifying_present_classes: identifying_present_classes:
- com.datadoghq.trace.agent.InstrumentationCheckerTest$DemoClass1 com.datadoghq.trace.agent.InstrumentationCheckerTest$DemoClass1:
- com.datadoghq.trace.agent.InstrumentationCheckerTest$MissingClass com.datadoghq.trace.agent.InstrumentationCheckerTest$MissingClass:

View File

@ -14,6 +14,7 @@ include ':dd-trace-annotations'
include ':dd-java-agent:integrations:apache-httpclient' include ':dd-java-agent:integrations:apache-httpclient'
include ':dd-java-agent:integrations:aws-sdk' include ':dd-java-agent:integrations:aws-sdk'
include ':dd-java-agent:integrations:cassandra' include ':dd-java-agent:integrations:cassandra'
include ':dd-java-agent:integrations:jetty'
include ':dd-java-agent:integrations:jms' include ':dd-java-agent:integrations:jms'
include ':dd-java-agent:integrations:mongo' include ':dd-java-agent:integrations:mongo'
include ':dd-java-agent:integrations:mongo-async' include ':dd-java-agent:integrations:mongo-async'