This is an automated email from the ASF dual-hosted git repository.

gwenshap pushed a commit to branch 2.0
in repository https://gitbox.apache.org/repos/asf/kafka.git


The following commit(s) were added to refs/heads/2.0 by this push:
     new 436bd77  KAFKA-7799; Use httpcomponents-client in RestServerTest.
436bd77 is described below

commit 436bd779a4039d0b33834a091b4d9de9ee702947
Author: Alex Diachenko <sansanic...@gmail.com>
AuthorDate: Tue Feb 19 11:52:07 2019 -0800

    KAFKA-7799; Use httpcomponents-client in RestServerTest.
    
    The test 
`org.apache.kafka.connect.runtime.rest.RestServerTest#testCORSEnabled` assumes 
Jersey client can send restricted HTTP headers(`Origin`).
    
    Jersey client uses `sun.net.www.protocol.http.HttpURLConnection`.
    `sun.net.www.protocol.http.HttpURLConnection` drops restricted 
headers(`Host`, `Keep-Alive`, `Origin`, etc) based on static property 
`allowRestrictedHeaders`.
    This property is initialized in a static block by reading Java system 
property `sun.net.http.allowRestrictedHeaders`.
    
    So, if classloader loads `HttpURLConnection` before we set 
`sun.net.http.allowRestrictedHeaders=true`, then all subsequent changes of this 
system property won't take any effect(which happens if 
`org.apache.kafka.connect.integration.ExampleConnectIntegrationTest` is 
executed before `RestServerTest`).
    To prevent this, we have to either make sure we set 
`sun.net.http.allowRestrictedHeaders=true` as early as possible or do not rely 
on this system property at all.
    
    This PR adds test dependency on `httpcomponents-client` which doesn't 
depend on `sun.net.http.allowRestrictedHeaders` system property. Thus none of 
existing tests should interfere with `RestServerTest`.
    
    Author: Alex Diachenko <sansanic...@gmail.com>
    
    Reviewers: Gwen Shapira
    
    Closes #6276 from avocader/KAFKA-7799_2.0
---
 build.gradle                                       |   1 +
 checkstyle/import-control.xml                      |   1 +
 .../kafka/connect/runtime/rest/RestServerTest.java | 138 +++++++++------------
 gradle/dependencies.gradle                         |   4 +-
 4 files changed, 63 insertions(+), 81 deletions(-)

diff --git a/build.gradle b/build.gradle
index 95d2df1..42aabea 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1378,6 +1378,7 @@ project(':connect:runtime') {
     testCompile libs.junit
     testCompile libs.powermockJunit4
     testCompile libs.powermockEasymock
+    testCompile libs.httpclient
 
     testCompile project(':clients').sourceSets.test.output
     testCompile project(':core')
diff --git a/checkstyle/import-control.xml b/checkstyle/import-control.xml
index 933dcbc..526f17f 100644
--- a/checkstyle/import-control.xml
+++ b/checkstyle/import-control.xml
@@ -330,6 +330,7 @@
         <allow pkg="javax.servlet" />
         <allow pkg="org.glassfish.jersey" />
         <allow pkg="com.fasterxml.jackson" />
+        <allow pkg="org.apache.http"/>
       </subpackage>
 
       <subpackage name="isolation">
diff --git 
a/connect/runtime/src/test/java/org/apache/kafka/connect/runtime/rest/RestServerTest.java
 
b/connect/runtime/src/test/java/org/apache/kafka/connect/runtime/rest/RestServerTest.java
index d084e4c..8824d77 100644
--- 
a/connect/runtime/src/test/java/org/apache/kafka/connect/runtime/rest/RestServerTest.java
+++ 
b/connect/runtime/src/test/java/org/apache/kafka/connect/runtime/rest/RestServerTest.java
@@ -16,6 +16,13 @@
  */
 package org.apache.kafka.connect.runtime.rest;
 
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpOptions;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
 import org.apache.kafka.clients.CommonClientConfigs;
 import org.apache.kafka.connect.rest.ConnectRestExtension;
 import org.apache.kafka.connect.runtime.Herder;
@@ -28,30 +35,25 @@ import org.easymock.Capture;
 import org.easymock.EasyMock;
 import org.junit.After;
 import org.junit.Assert;
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.powermock.api.easymock.PowerMock;
 import org.powermock.api.easymock.annotation.MockStrict;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
 import org.powermock.modules.junit4.PowerMockRunner;
 
-import java.net.URI;
-import java.net.URISyntaxException;
+import javax.ws.rs.core.MediaType;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.Invocation;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import static org.junit.Assert.assertEquals;
 
 @RunWith(PowerMockRunner.class)
+@PowerMockIgnore({"javax.net.ssl.*", "javax.security.*"})
 public class RestServerTest {
 
     @MockStrict
@@ -60,12 +62,6 @@ public class RestServerTest {
     private Plugins plugins;
     private RestServer server;
 
-    @Before
-    public void setUp() {
-        // To be able to set the Origin, we need to toggle this flag
-        System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
-    }
-
     @After
     public void tearDown() {
         server.stop();
@@ -87,12 +83,12 @@ public class RestServerTest {
     }
 
     @Test
-    public void testCORSEnabled() {
+    public void testCORSEnabled() throws IOException {
         checkCORSRequest("*", "http://bar.com";, "http://bar.com";, "PUT");
     }
 
     @Test
-    public void testCORSDisabled() {
+    public void testCORSDisabled() throws IOException {
         checkCORSRequest("", "http://bar.com";, null, null);
     }
 
@@ -163,7 +159,7 @@ public class RestServerTest {
     }
 
     @Test
-    public void testOptionsDoesNotIncludeWadlOutput() {
+    public void testOptionsDoesNotIncludeWadlOutput() throws IOException {
         Map<String, String> configMap = new HashMap<>(baseWorkerProps());
         DistributedConfig workerConfig = new DistributedConfig(configMap);
 
@@ -177,19 +173,26 @@ public class RestServerTest {
         server = new RestServer(workerConfig);
         server.start(new HerderProvider(herder), herder.plugins());
 
-        Response response = request("/connectors")
-            .accept(MediaType.WILDCARD)
-            .options();
-        Assert.assertEquals(MediaType.TEXT_PLAIN_TYPE, 
response.getMediaType());
+        HttpOptions request = new HttpOptions("/connectors");
+        request.addHeader("Content-Type", MediaType.WILDCARD);
+        CloseableHttpClient httpClient = HttpClients.createMinimal();
+        HttpHost httpHost = new HttpHost(
+            server.advertisedUrl().getHost(),
+            server.advertisedUrl().getPort()
+        );
+        CloseableHttpResponse response = httpClient.execute(httpHost, request);
+        Assert.assertEquals(MediaType.TEXT_PLAIN, 
response.getEntity().getContentType().getValue());
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        response.getEntity().writeTo(baos);
         Assert.assertArrayEquals(
-            response.getAllowedMethods().toArray(new String[0]),
-            response.readEntity(String.class).split(", ")
+            request.getAllowedMethods(response).toArray(),
+            new String(baos.toByteArray(), StandardCharsets.UTF_8).split(", ")
         );
-
         PowerMock.verifyAll();
     }
 
-    public void checkCORSRequest(String corsDomain, String origin, String 
expectedHeader, String method) {
+    public void checkCORSRequest(String corsDomain, String origin, String 
expectedHeader, String method)
+        throws IOException {
         Map<String, String> workerProps = baseWorkerProps();
         workerProps.put(WorkerConfig.ACCESS_CONTROL_ALLOW_ORIGIN_CONFIG, 
corsDomain);
         workerProps.put(WorkerConfig.ACCESS_CONTROL_ALLOW_METHODS_CONFIG, 
method);
@@ -210,64 +213,39 @@ public class RestServerTest {
 
         PowerMock.replayAll();
 
-
         server = new RestServer(workerConfig);
         server.start(new HerderProvider(herder), herder.plugins());
+        HttpRequest request = new HttpGet("/connectors");
+        request.addHeader("Referer", origin + "/page");
+        request.addHeader("Origin", origin);
+        CloseableHttpClient httpClient = HttpClients.createMinimal();
+        HttpHost httpHost = new HttpHost(
+            server.advertisedUrl().getHost(),
+            server.advertisedUrl().getPort()
+        );
+        CloseableHttpResponse response = httpClient.execute(httpHost, request);
 
-        Response response = request("/connectors")
-                .header("Referer", origin + "/page")
-                .header("Origin", origin)
-                .get();
-        assertEquals(200, response.getStatus());
-
-        assertEquals(expectedHeader, 
response.getHeaderString("Access-Control-Allow-Origin"));
-
-        response = request("/connector-plugins/FileStreamSource/validate")
-            .header("Referer", origin + "/page")
-            .header("Origin", origin)
-            .header("Access-Control-Request-Method", method)
-            .options();
-        assertEquals(404, response.getStatus());
-        assertEquals(expectedHeader, 
response.getHeaderString("Access-Control-Allow-Origin"));
-        assertEquals(method, 
response.getHeaderString("Access-Control-Allow-Methods"));
-        PowerMock.verifyAll();
-    }
-
-    protected Invocation.Builder request(String path) {
-        return request(path, null, null, null);
-    }
-
-    protected Invocation.Builder request(String path, Map<String, String> 
queryParams) {
-        return request(path, null, null, queryParams);
-    }
-
-    protected Invocation.Builder request(String path, String templateName, 
Object templateValue) {
-        return request(path, templateName, templateValue, null);
-    }
+        Assert.assertEquals(200, response.getStatusLine().getStatusCode());
 
-    protected Invocation.Builder request(String path, String templateName, 
Object templateValue,
-                                         Map<String, String> queryParams) {
-        Client client = ClientBuilder.newClient();
-        WebTarget target;
-        URI pathUri = null;
-        try {
-            pathUri = new URI(path);
-        } catch (URISyntaxException e) {
-            // Ignore, use restConnect and assume this is a valid path part
-        }
-        if (pathUri != null && pathUri.isAbsolute()) {
-            target = client.target(path);
-        } else {
-            target = client.target(server.advertisedUrl()).path(path);
+        if (expectedHeader != null) {
+            Assert.assertEquals(expectedHeader,
+                
response.getFirstHeader("Access-Control-Allow-Origin").getValue());
         }
-        if (templateName != null && templateValue != null) {
-            target = target.resolveTemplate(templateName, templateValue);
+
+        request = new 
HttpOptions("/connector-plugins/FileStreamSource/validate");
+        request.addHeader("Referer", origin + "/page");
+        request.addHeader("Origin", origin);
+        request.addHeader("Access-Control-Request-Method", method);
+        response = httpClient.execute(httpHost, request);
+        Assert.assertEquals(404, response.getStatusLine().getStatusCode());
+        if (expectedHeader != null) {
+            Assert.assertEquals(expectedHeader,
+                
response.getFirstHeader("Access-Control-Allow-Origin").getValue());
         }
-        if (queryParams != null) {
-            for (Map.Entry<String, String> queryParam : 
queryParams.entrySet()) {
-                target = target.queryParam(queryParam.getKey(), 
queryParam.getValue());
-            }
+        if (method != null) {
+            Assert.assertEquals(method,
+                
response.getFirstHeader("Access-Control-Allow-Methods").getValue());
         }
-        return target.request();
+        PowerMock.verifyAll();
     }
 }
diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle
index 08d8bf7..d3f70d1 100644
--- a/gradle/dependencies.gradle
+++ b/gradle/dependencies.gradle
@@ -52,6 +52,7 @@ versions += [
   apacheds: "2.0.0-M24",
   argparse4j: "0.7.0",
   bcpkix: "1.59",
+  httpclient: "4.5.7",
   easymock: "3.6",
   jackson: "2.9.7",
   jetty: "9.4.11.v20180605",
@@ -140,5 +141,6 @@ libs += [
   zkclient: "com.101tec:zkclient:$versions.zkclient",
   zookeeper: "org.apache.zookeeper:zookeeper:$versions.zookeeper",
   jfreechart: "jfreechart:jfreechart:$versions.jfreechart",
-  mavenArtifact: "org.apache.maven:maven-artifact:$versions.mavenArtifact"
+  mavenArtifact: "org.apache.maven:maven-artifact:$versions.mavenArtifact",
+  httpclient: "org.apache.httpcomponents:httpclient:$versions.httpclient"
 ]

Reply via email to