Passing tests. Modify escaping of spaces in urls

This commit is contained in:
Laplie Anderson 2019-07-09 15:08:08 -04:00
parent d97b1c2d53
commit caa7e4426a
3 changed files with 77 additions and 5 deletions

View File

@ -16,7 +16,11 @@ public class GoogleHttpClientDecorator extends HttpClientDecorator<HttpRequest,
@Override @Override
protected URI url(final HttpRequest httpRequest) throws URISyntaxException { protected URI url(final HttpRequest httpRequest) throws URISyntaxException {
return httpRequest.getUrl().toURI(); // Google uses %20 (space) instead of "+" for spaces in the fragment
// Add "+" back for consistency with the other http client instrumentations
final String url = httpRequest.getUrl().build();
final String fixedUrl = url.replaceAll("%20", "+");
return new URI(fixedUrl);
} }
@Override @Override

View File

@ -19,12 +19,12 @@ import io.opentracing.propagation.Format;
import io.opentracing.propagation.TextMap; import io.opentracing.propagation.TextMap;
import io.opentracing.tag.Tags; import io.opentracing.tag.Tags;
import io.opentracing.util.GlobalTracer; import io.opentracing.util.GlobalTracer;
import java.util.Iterator;
import java.util.Map;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
import java.util.Iterator;
import java.util.Map;
@AutoService(Instrumenter.class) @AutoService(Instrumenter.class)
public class GoogleHttpClientInstrumentation extends Instrumenter.Default { public class GoogleHttpClientInstrumentation extends Instrumenter.Default {
@ -44,7 +44,7 @@ public class GoogleHttpClientInstrumentation extends Instrumenter.Default {
"datadog.trace.agent.decorator.BaseDecorator", "datadog.trace.agent.decorator.BaseDecorator",
"datadog.trace.agent.decorator.ClientDecorator", "datadog.trace.agent.decorator.ClientDecorator",
"datadog.trace.agent.decorator.HttpClientDecorator", "datadog.trace.agent.decorator.HttpClientDecorator",
packageName + ".GoogleHttpClientClientDecorator", packageName + ".GoogleHttpClientDecorator",
getClass().getName() + "$GoogleHttpClientAdvice", getClass().getName() + "$GoogleHttpClientAdvice",
getClass().getName() + "$HeadersInjectAdapter" getClass().getName() + "$HeadersInjectAdapter"
}; };
@ -87,13 +87,14 @@ public class GoogleHttpClientInstrumentation extends Instrumenter.Default {
// If HttpRequest.setThrowExceptionOnExecuteError is set to false, there are no exceptions // If HttpRequest.setThrowExceptionOnExecuteError is set to false, there are no exceptions
// for a failed request. Thus, check the response code // for a failed request. Thus, check the response code
if (!response.isSuccessStatusCode()) { if (response != null && !response.isSuccessStatusCode()) {
Tags.ERROR.set(span, true); Tags.ERROR.set(span, true);
span.log(singletonMap(Fields.MESSAGE, response.getStatusMessage())); span.log(singletonMap(Fields.MESSAGE, response.getStatusMessage()));
} }
DECORATE.onError(span, throwable); DECORATE.onError(span, throwable);
DECORATE.beforeFinish(span); DECORATE.beforeFinish(span);
span.finish();
} finally { } finally {
scope.close(); scope.close();
CallDepthThreadLocalMap.reset(HttpRequest.class); CallDepthThreadLocalMap.reset(HttpRequest.class);

View File

@ -0,0 +1,67 @@
import com.google.api.client.http.GenericUrl
import com.google.api.client.http.HttpRequest
import com.google.api.client.http.HttpResponse
import com.google.api.client.http.javanet.NetHttpTransport
import datadog.trace.agent.test.base.HttpClientTest
import datadog.trace.api.DDSpanTypes
import datadog.trace.instrumentation.googlehttpclient.GoogleHttpClientDecorator
import spock.lang.Shared
class GoogleHttpClientTest extends HttpClientTest<GoogleHttpClientDecorator> {
@Shared
def requestFactory = new NetHttpTransport().createRequestFactory();
@Override
int doRequest(String method, URI uri, Map<String, String> headers, Closure callback) {
doRequest(method, uri, headers, callback, false);
}
int doRequest(String method, URI uri, Map<String, String> headers, Closure callback, boolean throwExceptionOnError) {
GenericUrl genericUrl = new GenericUrl(uri)
HttpRequest request = requestFactory.buildRequest(method, genericUrl, null)
request.getHeaders().putAll(headers)
request.setThrowExceptionOnExecuteError(throwExceptionOnError)
HttpResponse response = request.execute()
callback?.call()
return response.getStatusCode()
}
@Override
GoogleHttpClientDecorator decorator() {
return GoogleHttpClientDecorator.DECORATE
}
@Override
boolean testRedirects() {
// Circular redirects don't throw an exception with Google Http Client
return false
}
def "error traces when exception is not thrown"() {
given:
def uri = server.address.resolve("/error")
when:
def status = doRequest(method, uri)
then:
status == 500
assertTraces(2) {
server.distributedRequestTrace(it, 0, trace(1).last())
trace(1, size(1)) {
span(0) {
resourceName "$method $uri.path"
spanType DDSpanTypes.HTTP_CLIENT
errored true
}
}
}
where:
method = "GET"
}
}