From 2a9dc737946743a5103ff295e7c23ac4df70cc2e Mon Sep 17 00:00:00 2001 From: Nakul Sabharwal Date: Tue, 16 Apr 2019 00:37:06 +0530 Subject: [PATCH 1/2] Telemetry handler and its tests --- .../graph/httpcore/AuthenticationHandler.java | 6 ++ .../microsoft/graph/httpcore/HttpClients.java | 17 ++++++ .../graph/httpcore/RedirectHandler.java | 6 ++ .../graph/httpcore/RetryHandler.java | 6 ++ .../graph/httpcore/TelemetryHandler.java | 38 ++++++++++++ .../middlewareoption/TelemetryOptions.java | 38 ++++++++++++ .../graph/httpcore/HttpClientsTest.java | 14 +++++ .../graph/httpcore/TelemetryHandlerTest.java | 59 +++++++++++++++++++ .../graph/httpcore/TelemetryOptionsTest.java | 53 +++++++++++++++++ 9 files changed, 237 insertions(+) create mode 100644 src/main/java/com/microsoft/graph/httpcore/TelemetryHandler.java create mode 100644 src/main/java/com/microsoft/graph/httpcore/middlewareoption/TelemetryOptions.java create mode 100644 src/test/java/com/microsoft/graph/httpcore/TelemetryHandlerTest.java create mode 100644 src/test/java/com/microsoft/graph/httpcore/TelemetryOptionsTest.java diff --git a/src/main/java/com/microsoft/graph/httpcore/AuthenticationHandler.java b/src/main/java/com/microsoft/graph/httpcore/AuthenticationHandler.java index 42e9fe304..b48b8b337 100644 --- a/src/main/java/com/microsoft/graph/httpcore/AuthenticationHandler.java +++ b/src/main/java/com/microsoft/graph/httpcore/AuthenticationHandler.java @@ -3,6 +3,7 @@ import java.io.IOException; import com.microsoft.graph.httpcore.middlewareoption.MiddlewareType; +import com.microsoft.graph.httpcore.middlewareoption.TelemetryOptions; import okhttp3.Interceptor; import okhttp3.Request; @@ -21,6 +22,11 @@ public AuthenticationHandler(ICoreAuthenticationProvider authProvider) { @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); + + if(originalRequest.tag(TelemetryOptions.class) == null) + originalRequest = originalRequest.newBuilder().tag(TelemetryOptions.class, new TelemetryOptions()).build(); + originalRequest.tag(TelemetryOptions.class).setFeatureUsage(TelemetryOptions.AUTH_HANDLER_ENABLED_FLAG); + Request authenticatedRequest = authProvider.authenticateRequest(originalRequest); return chain.proceed(authenticatedRequest); } diff --git a/src/main/java/com/microsoft/graph/httpcore/HttpClients.java b/src/main/java/com/microsoft/graph/httpcore/HttpClients.java index 4084ae91d..144173609 100644 --- a/src/main/java/com/microsoft/graph/httpcore/HttpClients.java +++ b/src/main/java/com/microsoft/graph/httpcore/HttpClients.java @@ -1,5 +1,6 @@ package com.microsoft.graph.httpcore; +import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.OkHttpClient.Builder; @@ -30,6 +31,22 @@ public static OkHttpClient createDefault(ICoreAuthenticationProvider auth) { .followRedirects(false) .addInterceptor(new RetryHandler()) .addInterceptor(new RedirectHandler()) + .addInterceptor(new TelemetryHandler()) .build(); } + + /** + * Creates {@link OkHttpClient} instance with interceptors + * + * @param interceptors Use interceptors provided while constructing http client + * @return OkHttpClient build with interceptors provided + */ + public static OkHttpClient createFromInterceptors(Interceptor[] interceptors) { + OkHttpClient.Builder builder = new OkHttpClient.Builder(); + for(Interceptor interceptor : interceptors) { + builder.addInterceptor(interceptor); + } + builder.addInterceptor(new TelemetryHandler()); + return builder.build(); + } } diff --git a/src/main/java/com/microsoft/graph/httpcore/RedirectHandler.java b/src/main/java/com/microsoft/graph/httpcore/RedirectHandler.java index dbc866990..78c3aa787 100644 --- a/src/main/java/com/microsoft/graph/httpcore/RedirectHandler.java +++ b/src/main/java/com/microsoft/graph/httpcore/RedirectHandler.java @@ -11,6 +11,7 @@ import com.microsoft.graph.httpcore.middlewareoption.MiddlewareType; import com.microsoft.graph.httpcore.middlewareoption.RedirectOptions; +import com.microsoft.graph.httpcore.middlewareoption.TelemetryOptions; import okhttp3.HttpUrl; import okhttp3.Interceptor; @@ -100,6 +101,11 @@ Request getRedirect( @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); + + if(request.tag(TelemetryOptions.class) == null) + request = request.newBuilder().tag(TelemetryOptions.class, new TelemetryOptions()).build(); + request.tag(TelemetryOptions.class).setFeatureUsage(TelemetryOptions.REDIRECT_HANDLER_ENABLED_FLAG); + Response response = null; int requestsCount = 1; diff --git a/src/main/java/com/microsoft/graph/httpcore/RetryHandler.java b/src/main/java/com/microsoft/graph/httpcore/RetryHandler.java index 5d8b18fc8..a8f542398 100644 --- a/src/main/java/com/microsoft/graph/httpcore/RetryHandler.java +++ b/src/main/java/com/microsoft/graph/httpcore/RetryHandler.java @@ -5,6 +5,7 @@ import com.microsoft.graph.httpcore.middlewareoption.IShouldRetry; import com.microsoft.graph.httpcore.middlewareoption.MiddlewareType; import com.microsoft.graph.httpcore.middlewareoption.RetryOptions; +import com.microsoft.graph.httpcore.middlewareoption.TelemetryOptions; import okhttp3.Interceptor; import okhttp3.Request; @@ -124,6 +125,11 @@ boolean isBuffered(Response response, Request request) { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); + + if(request.tag(TelemetryOptions.class) == null) + request = request.newBuilder().tag(TelemetryOptions.class, new TelemetryOptions()).build(); + request.tag(TelemetryOptions.class).setFeatureUsage(TelemetryOptions.RETRY_HANDLER_ENABLED_FLAG); + Response response = chain.proceed(request); // Use should retry pass along with this request diff --git a/src/main/java/com/microsoft/graph/httpcore/TelemetryHandler.java b/src/main/java/com/microsoft/graph/httpcore/TelemetryHandler.java new file mode 100644 index 000000000..9bcd75d3f --- /dev/null +++ b/src/main/java/com/microsoft/graph/httpcore/TelemetryHandler.java @@ -0,0 +1,38 @@ +package com.microsoft.graph.httpcore; + +import java.io.IOException; + +import com.microsoft.graph.httpcore.middlewareoption.TelemetryOptions; + +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; + +public class TelemetryHandler implements Interceptor{ + + public static final String SDK_VERSION = "SdkVersion"; + public static final String VERSION = "v0.1.0-SNAPSHOT"; + public static final String GRAPH_VERSION_PREFIX = "graph-java-core"; + public static final String CLIENT_REQUEST_ID = "client-request-id"; + + @Override + public Response intercept(Chain chain) throws IOException { + Request request = chain.request(); + Request.Builder telemetryAddedBuilder = request.newBuilder(); + + TelemetryOptions telemetryOptions = request.tag(TelemetryOptions.class); + + if(telemetryOptions != null) { + String featureUsage = "(featureUsage=" + telemetryOptions.getFeatureUsage() + ")"; + String sdkversion_value = GRAPH_VERSION_PREFIX + "/" + VERSION + " " + featureUsage; + telemetryAddedBuilder.addHeader(SDK_VERSION, sdkversion_value); + + if(request.header(CLIENT_REQUEST_ID) == null) { + telemetryAddedBuilder.addHeader(CLIENT_REQUEST_ID, telemetryOptions.getClientRequestId()); + } + } + + return chain.proceed(telemetryAddedBuilder.build()); + } + +} diff --git a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/TelemetryOptions.java b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/TelemetryOptions.java new file mode 100644 index 000000000..0e7848323 --- /dev/null +++ b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/TelemetryOptions.java @@ -0,0 +1,38 @@ +package com.microsoft.graph.httpcore.middlewareoption; + +import java.math.BigInteger; +import java.util.UUID; + +public class TelemetryOptions { + + public static final String NONE_FLAG = "0x00000000"; + public static final String REDIRECT_HANDLER_ENABLED_FLAG = "0x00000001"; + public static final String RETRY_HANDLER_ENABLED_FLAG = "0x00000002"; + public static final String AUTH_HANDLER_ENABLED_FLAG = "0x00000004"; + public static final String DEFAULT_HTTPROVIDER_ENABLED_FLAG = "0x00000008"; + public static final String LOGGING_HANDLER_ENABLED_FLAG = "0x00000010"; + + private static final int RADIX = 16; + private BigInteger featureUsage = new BigInteger(NONE_FLAG.substring(2), RADIX); + private String clientRequestId; + + public void setFeatureUsage(String flag) { + featureUsage = featureUsage.or(new BigInteger(flag.substring(2), RADIX)); + } + + public String getFeatureUsage() { + return featureUsage.toString(RADIX); + } + + public void setClientRequestId(String clientRequestId) { + this.clientRequestId = clientRequestId; + } + + public String getClientRequestId() { + if(clientRequestId == null) { + clientRequestId = UUID.randomUUID().toString(); + } + return clientRequestId; + } + +} diff --git a/src/test/java/com/microsoft/graph/httpcore/HttpClientsTest.java b/src/test/java/com/microsoft/graph/httpcore/HttpClientsTest.java index 85bb76fd5..6043c432d 100644 --- a/src/test/java/com/microsoft/graph/httpcore/HttpClientsTest.java +++ b/src/test/java/com/microsoft/graph/httpcore/HttpClientsTest.java @@ -4,6 +4,7 @@ import org.junit.Test; +import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -21,5 +22,18 @@ public Request authenticateRequest(Request request) { OkHttpClient httpclient = HttpClients.createDefault(authprovider); assertTrue(httpclient != null); } + + @Test + public void arrayInterceptorsTest() { + AuthenticationHandler authenticationHandler = new AuthenticationHandler(new ICoreAuthenticationProvider() { + @Override + public Request authenticateRequest(Request request) { + return request; + } + }); + Interceptor[] interceptors = {new RetryHandler(), new RedirectHandler(), authenticationHandler}; + OkHttpClient client = HttpClients.createFromInterceptors(interceptors); + assertTrue(client.interceptors().size()==4); + } } diff --git a/src/test/java/com/microsoft/graph/httpcore/TelemetryHandlerTest.java b/src/test/java/com/microsoft/graph/httpcore/TelemetryHandlerTest.java new file mode 100644 index 000000000..8f49b8126 --- /dev/null +++ b/src/test/java/com/microsoft/graph/httpcore/TelemetryHandlerTest.java @@ -0,0 +1,59 @@ +package com.microsoft.graph.httpcore; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import org.junit.Ignore; +import org.junit.Test; + +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +@Ignore +public class TelemetryHandlerTest { + @Test + public void telemetryInitTest() { + TelemetryHandler telemetryHandler = new TelemetryHandler(); + assertNotNull(telemetryHandler); + } + + @Test + public void interceptTest() throws IOException { + String expectedHeader = TelemetryHandler.SDK_VERSION + TelemetryHandler.GRAPH_VERSION_PREFIX +"/" + +TelemetryHandler.VERSION; + OkHttpClient client = HttpClients.createDefault(new ICoreAuthenticationProvider() { + @Override + public Request authenticateRequest(Request request) { + return request; + } + }); + Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/users/").build(); + Response response = client.newCall(request).execute(); + assertNotNull(response); + assertTrue(response.request().header("SdkVersion").contains(expectedHeader)); + } + + @Test + public void arrayInterceptorsTest() throws IOException { + + AuthenticationHandler authenticationHandler = new AuthenticationHandler(new ICoreAuthenticationProvider() { + + @Override + public Request authenticateRequest(Request request) { + return request; + } + }); + Interceptor[] interceptors = {new RetryHandler(), new RedirectHandler(), authenticationHandler}; + OkHttpClient client = HttpClients.createFromInterceptors(interceptors); + String expectedHeader = TelemetryHandler.SDK_VERSION + TelemetryHandler.GRAPH_VERSION_PREFIX +"/" + +TelemetryHandler.VERSION; + Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/users/").build(); + Response response = client.newCall(request).execute(); + assertNotNull(response); + assertTrue(response.request().header("SdkVersion").contains(expectedHeader)); + } +} diff --git a/src/test/java/com/microsoft/graph/httpcore/TelemetryOptionsTest.java b/src/test/java/com/microsoft/graph/httpcore/TelemetryOptionsTest.java new file mode 100644 index 000000000..dece2ef55 --- /dev/null +++ b/src/test/java/com/microsoft/graph/httpcore/TelemetryOptionsTest.java @@ -0,0 +1,53 @@ +package com.microsoft.graph.httpcore; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.microsoft.graph.httpcore.middlewareoption.TelemetryOptions; + +public class TelemetryOptionsTest { + + @Test + public void createTelemetryOptionsTest() { + TelemetryOptions telemetryOptions = new TelemetryOptions(); + assertNotNull(telemetryOptions); + assertNotNull(telemetryOptions.getClientRequestId()); + } + + @Test + public void setFeatureUsageTest() { + TelemetryOptions telemetryOptions = new TelemetryOptions(); + telemetryOptions.setFeatureUsage(TelemetryOptions.AUTH_HANDLER_ENABLED_FLAG); + telemetryOptions.setFeatureUsage(TelemetryOptions.REDIRECT_HANDLER_ENABLED_FLAG); + assertTrue(telemetryOptions.getFeatureUsage().compareTo("5")==0); + } + + @Test + public void getFeatureUsageTest() { + TelemetryOptions telemetryOptions = new TelemetryOptions(); + telemetryOptions.setFeatureUsage(TelemetryOptions.AUTH_HANDLER_ENABLED_FLAG); + telemetryOptions.setFeatureUsage(TelemetryOptions.REDIRECT_HANDLER_ENABLED_FLAG); + telemetryOptions.setFeatureUsage(TelemetryOptions.RETRY_HANDLER_ENABLED_FLAG); + assertTrue(telemetryOptions.getFeatureUsage().compareTo("7")==0); + } + + @Test + public void setClientRequestIdTest() { + TelemetryOptions telemetryOptions = new TelemetryOptions(); + telemetryOptions.setClientRequestId("test id"); + assertTrue(telemetryOptions.getClientRequestId().compareTo("test id")==0); + } + + @Test + public void getClientRequestIdTest() { + TelemetryOptions telemetryOptions = new TelemetryOptions(); + assertNotNull(telemetryOptions.getClientRequestId()); + telemetryOptions.setClientRequestId("test id 1"); + assertTrue(telemetryOptions.getClientRequestId().compareTo("test id 1")==0); + telemetryOptions.setClientRequestId("test id 2"); + assertTrue(telemetryOptions.getClientRequestId().compareTo("test id 2")==0); + } + +} From c42ccb996faab7c0b3b264b970ab14468e73bbbb Mon Sep 17 00:00:00 2001 From: Nakul Sabharwal Date: Wed, 17 Apr 2019 12:14:59 +0530 Subject: [PATCH 2/2] Changed flags from String to int --- .../middlewareoption/TelemetryOptions.java | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/TelemetryOptions.java b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/TelemetryOptions.java index 0e7848323..60def57d8 100644 --- a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/TelemetryOptions.java +++ b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/TelemetryOptions.java @@ -1,27 +1,25 @@ package com.microsoft.graph.httpcore.middlewareoption; -import java.math.BigInteger; import java.util.UUID; public class TelemetryOptions { - public static final String NONE_FLAG = "0x00000000"; - public static final String REDIRECT_HANDLER_ENABLED_FLAG = "0x00000001"; - public static final String RETRY_HANDLER_ENABLED_FLAG = "0x00000002"; - public static final String AUTH_HANDLER_ENABLED_FLAG = "0x00000004"; - public static final String DEFAULT_HTTPROVIDER_ENABLED_FLAG = "0x00000008"; - public static final String LOGGING_HANDLER_ENABLED_FLAG = "0x00000010"; + public static final int NONE_FLAG = 0; + public static final int REDIRECT_HANDLER_ENABLED_FLAG = 1; + public static final int RETRY_HANDLER_ENABLED_FLAG = 2; + public static final int AUTH_HANDLER_ENABLED_FLAG = 4; + public static final int DEFAULT_HTTPROVIDER_ENABLED_FLAG = 8; + public static final int LOGGING_HANDLER_ENABLED_FLAG = 16; - private static final int RADIX = 16; - private BigInteger featureUsage = new BigInteger(NONE_FLAG.substring(2), RADIX); + private int featureUsage = NONE_FLAG; private String clientRequestId; - public void setFeatureUsage(String flag) { - featureUsage = featureUsage.or(new BigInteger(flag.substring(2), RADIX)); + public void setFeatureUsage(int flag) { + featureUsage = featureUsage | flag; } public String getFeatureUsage() { - return featureUsage.toString(RADIX); + return Integer.toHexString(featureUsage); } public void setClientRequestId(String clientRequestId) {