mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-02 19:45:51 +01:00
Integrate trace api with AdvancedHttpClient
This commit is contained in:
@@ -26,18 +26,16 @@ package sonia.scm.net.ahc;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import org.apache.shiro.codec.Base64;
|
||||
|
||||
import sonia.scm.util.HttpUtil;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Base class for http requests.
|
||||
@@ -102,7 +100,7 @@ public abstract class BaseHttpRequest<T extends BaseHttpRequest>
|
||||
String auth = Strings.nullToEmpty(username).concat(":").concat(
|
||||
Strings.nullToEmpty(password));
|
||||
|
||||
auth = Base64.encodeToString(auth.getBytes(Charsets.ISO_8859_1));
|
||||
auth = Base64.encodeToString(auth.getBytes(StandardCharsets.ISO_8859_1));
|
||||
headers.put("Authorization", "Basic ".concat(auth));
|
||||
|
||||
return self();
|
||||
@@ -246,6 +244,19 @@ public abstract class BaseHttpRequest<T extends BaseHttpRequest>
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the kind of span for tracing api.
|
||||
*
|
||||
* @param spanKind kind of span
|
||||
* @return request instance
|
||||
*
|
||||
* @since 2.9.0
|
||||
*/
|
||||
public T spanKind(String spanKind) {
|
||||
this.spanKind = spanKind;
|
||||
return self();
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -281,6 +292,17 @@ public abstract class BaseHttpRequest<T extends BaseHttpRequest>
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the kind of span which is used for the trace api.
|
||||
*
|
||||
* @return kind of span
|
||||
*
|
||||
* @since 2.9.0
|
||||
*/
|
||||
public String getSpanKind() {
|
||||
return spanKind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the request decodes gzip compression.
|
||||
*
|
||||
@@ -398,4 +420,7 @@ public abstract class BaseHttpRequest<T extends BaseHttpRequest>
|
||||
|
||||
/** url of request */
|
||||
private String url;
|
||||
|
||||
/** kind of span for trace api */
|
||||
private String spanKind = "http-request";
|
||||
}
|
||||
|
||||
@@ -38,8 +38,11 @@ import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.net.Proxies;
|
||||
import sonia.scm.net.TrustAllHostnameVerifier;
|
||||
import sonia.scm.net.TrustAllTrustManager;
|
||||
import sonia.scm.trace.Span;
|
||||
import sonia.scm.trace.Tracer;
|
||||
import sonia.scm.util.HttpUtil;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.inject.Provider;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
@@ -99,9 +102,10 @@ public class DefaultAdvancedHttpClient extends AdvancedHttpClient
|
||||
*/
|
||||
@Inject
|
||||
public DefaultAdvancedHttpClient(ScmConfiguration configuration,
|
||||
Set<ContentTransformer> contentTransformers, Provider<SSLContext> sslContextProvider)
|
||||
Tracer tracer, Set<ContentTransformer> contentTransformers, Provider<SSLContext> sslContextProvider)
|
||||
{
|
||||
this.configuration = configuration;
|
||||
this.tracer = tracer;
|
||||
this.contentTransformers = contentTransformers;
|
||||
this.sslContextProvider = sslContextProvider;
|
||||
}
|
||||
@@ -185,45 +189,48 @@ public class DefaultAdvancedHttpClient extends AdvancedHttpClient
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
protected AdvancedHttpResponse request(BaseHttpRequest<?> request)
|
||||
throws IOException
|
||||
{
|
||||
HttpURLConnection connection = openConnection(request,
|
||||
new URL(request.getUrl()));
|
||||
protected AdvancedHttpResponse request(BaseHttpRequest<?> request) throws IOException {
|
||||
try (Span span = tracer.span(request.getSpanKind())) {
|
||||
span.label("url", request.getUrl());
|
||||
span.label("method", request.getMethod());
|
||||
DefaultAdvancedHttpResponse response = doRequest(request);
|
||||
span.label("status", response.getStatus());
|
||||
if (!response.isSuccessful()) {
|
||||
span.failed();
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private DefaultAdvancedHttpResponse doRequest(BaseHttpRequest<?> request) throws IOException {
|
||||
HttpURLConnection connection = openConnection(request, new URL(request.getUrl()));
|
||||
|
||||
applyBaseSettings(request, connection);
|
||||
|
||||
if (connection instanceof HttpsURLConnection)
|
||||
{
|
||||
if (connection instanceof HttpsURLConnection) {
|
||||
applySSLSettings(request, (HttpsURLConnection) connection);
|
||||
}
|
||||
|
||||
Content content = null;
|
||||
|
||||
if (request instanceof AdvancedHttpRequestWithBody)
|
||||
{
|
||||
if (request instanceof AdvancedHttpRequestWithBody) {
|
||||
AdvancedHttpRequestWithBody ahrwb = (AdvancedHttpRequestWithBody) request;
|
||||
|
||||
content = ahrwb.getContent();
|
||||
|
||||
if (content != null)
|
||||
{
|
||||
if (content != null) {
|
||||
content.prepare(ahrwb);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
request.header(HttpUtil.HEADER_CONTENT_LENGTH, "0");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
request.header(HttpUtil.HEADER_CONTENT_LENGTH, "0");
|
||||
}
|
||||
|
||||
applyHeaders(request, connection);
|
||||
|
||||
if (content != null)
|
||||
{
|
||||
if (content != null) {
|
||||
applyContent(connection, content);
|
||||
}
|
||||
|
||||
@@ -383,4 +390,7 @@ public class DefaultAdvancedHttpClient extends AdvancedHttpClient
|
||||
|
||||
/** ssl context provider */
|
||||
private final Provider<SSLContext> sslContextProvider;
|
||||
|
||||
/** tracer used for request tracing */
|
||||
private Tracer tracer;
|
||||
}
|
||||
|
||||
@@ -30,11 +30,14 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.net.TrustAllHostnameVerifier;
|
||||
import sonia.scm.trace.Span;
|
||||
import sonia.scm.trace.Tracer;
|
||||
import sonia.scm.util.HttpUtil;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
@@ -265,6 +268,32 @@ public class DefaultAdvancedHttpClientTest
|
||||
"Basic dHJpY2lhOnRyaWNpYXMgc2VjcmV0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateTracingSpan() throws IOException {
|
||||
when(connection.getResponseCode()).thenReturn(200);
|
||||
|
||||
new AdvancedHttpRequest(client, HttpMethod.GET, "https://www.scm-manager.org").spanKind("spaceships").request();
|
||||
verify(tracer).span("spaceships");
|
||||
verify(span).label("url", "https://www.scm-manager.org");
|
||||
verify(span).label("method", "GET");
|
||||
verify(span).label("status", 200);
|
||||
verify(span, never()).failed();
|
||||
verify(span).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateFailedTracingSpan() throws IOException {
|
||||
when(connection.getResponseCode()).thenReturn(500);
|
||||
|
||||
new AdvancedHttpRequest(client, HttpMethod.GET, "https://www.scm-manager.org").request();
|
||||
verify(tracer).span("http-request");
|
||||
verify(span).label("url", "https://www.scm-manager.org");
|
||||
verify(span).label("method", "GET");
|
||||
verify(span).label("status", 500);
|
||||
verify(span).failed();
|
||||
verify(span).close();
|
||||
}
|
||||
|
||||
//~--- set methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -277,6 +306,7 @@ public class DefaultAdvancedHttpClientTest
|
||||
configuration = new ScmConfiguration();
|
||||
transformers = new HashSet<ContentTransformer>();
|
||||
client = new TestingAdvacedHttpClient(configuration, transformers);
|
||||
when(tracer.span(anyString())).thenReturn(span);
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
@@ -298,10 +328,9 @@ public class DefaultAdvancedHttpClientTest
|
||||
* @param configuration
|
||||
* @param transformers
|
||||
*/
|
||||
public TestingAdvacedHttpClient(ScmConfiguration configuration,
|
||||
Set<ContentTransformer> transformers)
|
||||
public TestingAdvacedHttpClient(ScmConfiguration configuration, Set<ContentTransformer> transformers)
|
||||
{
|
||||
super(configuration, transformers, new SSLContextProvider());
|
||||
super(configuration, tracer, transformers, new SSLContextProvider());
|
||||
}
|
||||
|
||||
//~--- methods ------------------------------------------------------------
|
||||
@@ -364,4 +393,10 @@ public class DefaultAdvancedHttpClientTest
|
||||
|
||||
/** Field description */
|
||||
private Set<ContentTransformer> transformers;
|
||||
|
||||
@Mock
|
||||
private Tracer tracer;
|
||||
|
||||
@Mock
|
||||
private Span span;
|
||||
}
|
||||
|
||||
@@ -33,9 +33,11 @@ import com.google.common.collect.Multimap;
|
||||
import com.google.common.io.ByteSource;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@@ -56,6 +58,7 @@ import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import sonia.scm.net.SSLContextProvider;
|
||||
import sonia.scm.trace.Tracer;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -65,6 +68,13 @@ import sonia.scm.net.SSLContextProvider;
|
||||
public class DefaultAdvancedHttpResponseTest
|
||||
{
|
||||
|
||||
private DefaultAdvancedHttpClient client;
|
||||
|
||||
@Before
|
||||
public void setUpClient() {
|
||||
client = new DefaultAdvancedHttpClient(new ScmConfiguration(), tracer, new HashSet<>(), new SSLContextProvider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
@@ -130,13 +140,10 @@ public class DefaultAdvancedHttpResponseTest
|
||||
assertTrue(headers.get("Test-2").isEmpty());
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private final DefaultAdvancedHttpClient client =
|
||||
new DefaultAdvancedHttpClient(new ScmConfiguration(), new HashSet<>(), new SSLContextProvider());
|
||||
|
||||
/** Field description */
|
||||
@Mock
|
||||
private HttpURLConnection connection;
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private Tracer tracer;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user