Repository: ambari Updated Branches: refs/heads/trunk 872c62457 -> db09f15f9
AMBARI-11489 - Views : URLStreamProvider & HttpImpersonator do not inject doAs param correctly (tbeerbower) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/db09f15f Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/db09f15f Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/db09f15f Branch: refs/heads/trunk Commit: db09f15f9eb9ea078c5b457af241fea11c3abed5 Parents: 872c624 Author: tbeerbower <tbeerbo...@hortonworks.com> Authored: Thu May 28 16:47:07 2015 -0400 Committer: tbeerbower <tbeerbo...@hortonworks.com> Committed: Thu May 28 16:47:21 2015 -0400 ---------------------------------------------------------------------- .../server/view/HttpImpersonatorImpl.java | 50 ++++---- .../server/view/ViewURLStreamProvider.java | 23 ++-- .../server/view/HttpImpersonatorImplTest.java | 123 ++++++++----------- .../server/view/ViewURLStreamProviderTest.java | 16 +-- 4 files changed, 86 insertions(+), 126 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/db09f15f/ambari-server/src/main/java/org/apache/ambari/server/view/HttpImpersonatorImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/HttpImpersonatorImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/view/HttpImpersonatorImpl.java index 7dd4947..f95c0e7 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/view/HttpImpersonatorImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/view/HttpImpersonatorImpl.java @@ -24,16 +24,15 @@ import org.apache.ambari.server.proxy.ProxyService; import org.apache.ambari.view.ImpersonatorSetting; import org.apache.ambari.view.ViewContext; import org.apache.ambari.view.HttpImpersonator; +import org.apache.http.client.utils.URIBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; -import java.util.Map; -import java.util.HashMap; -import java.util.List; -import java.util.ArrayList; /** @@ -44,25 +43,22 @@ import java.util.ArrayList; */ public class HttpImpersonatorImpl implements HttpImpersonator { private ViewContext context; - private FactoryHelper helper; + private final URLStreamProvider urlStreamProvider; - /** - * Helper class that is mocked during unit testing. - */ - static class FactoryHelper{ - BufferedReader makeBR(InputStreamReader in){ - return new BufferedReader(in); - } - } + private static Logger LOG = LoggerFactory.getLogger(HttpImpersonatorImpl.class); public HttpImpersonatorImpl(ViewContext c) { this.context = c; - this.helper = new FactoryHelper(); + + ComponentSSLConfiguration configuration = ComponentSSLConfiguration.instance(); + this.urlStreamProvider = new URLStreamProvider(ProxyService.URL_CONNECT_TIMEOUT, + ProxyService.URL_READ_TIMEOUT, configuration.getTruststorePath(), + configuration.getTruststorePassword(), configuration.getTruststoreType()); } - public HttpImpersonatorImpl(ViewContext c, FactoryHelper h) { + public HttpImpersonatorImpl(ViewContext c, URLStreamProvider urlStreamProvider) { this.context = c; - this.helper = h; + this.urlStreamProvider = urlStreamProvider; } public ViewContext getContext() { @@ -128,16 +124,14 @@ public class HttpImpersonatorImpl implements HttpImpersonator { } try { + String username = impersonatorSetting.getUsername(); + if (username != null) { + URIBuilder builder = new URIBuilder(url); + builder.addParameter(impersonatorSetting.getDoAsParamName(), username); + url = builder.build().toString(); + } - ComponentSSLConfiguration configuration = ComponentSSLConfiguration.instance(); - URLStreamProvider urlStreamProvider = new URLStreamProvider(ProxyService.URL_CONNECT_TIMEOUT, - ProxyService.URL_READ_TIMEOUT, configuration.getTruststorePath(), - configuration.getTruststorePassword(), configuration.getTruststoreType()); - - Map<String, List<String>> headers = new HashMap<String, List<String>>(); - headers.put(impersonatorSetting.getDoAsParamName(), new ArrayList<String>() {{add(impersonatorSetting.getUsername()); }} ); - - HttpURLConnection connection = urlStreamProvider.processURL(url, requestType, (String) null, headers); + HttpURLConnection connection = urlStreamProvider.processURL(url, requestType, (String) null, null); int responseCode = connection.getResponseCode(); InputStream resultInputStream; @@ -147,7 +141,7 @@ public class HttpImpersonatorImpl implements HttpImpersonator { resultInputStream = connection.getInputStream(); } - rd = this.helper.makeBR(new InputStreamReader(resultInputStream)); + rd = new BufferedReader(new InputStreamReader(resultInputStream)); if (rd != null) { line = rd.readLine(); @@ -157,10 +151,8 @@ public class HttpImpersonatorImpl implements HttpImpersonator { } rd.close(); } - } catch (IOException e) { - e.printStackTrace(); } catch (Exception e) { - e.printStackTrace(); + LOG.error("Exception caught processing impersonator request.", e); } return result; } http://git-wip-us.apache.org/repos/asf/ambari/blob/db09f15f/ambari-server/src/main/java/org/apache/ambari/server/view/ViewURLStreamProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewURLStreamProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewURLStreamProvider.java index 459cea1..bb3b8aa 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewURLStreamProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewURLStreamProvider.java @@ -23,9 +23,11 @@ import org.apache.ambari.server.proxy.ProxyService; import org.apache.ambari.view.ViewContext; import org.apache.commons.io.IOUtils; +import org.apache.http.client.utils.URIBuilder; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; +import java.net.URISyntaxException; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -86,13 +88,13 @@ public class ViewURLStreamProvider implements org.apache.ambari.view.URLStreamPr String userName) throws IOException { - return readFrom(spec, requestMethod, body, addDoAsHeader(spec, headers, userName)); + return readFrom(addDoAs(spec, userName), requestMethod, body, headers); } @Override public InputStream readAs(String spec, String requestMethod, InputStream body, Map<String, String> headers, String userName) throws IOException { - return readFrom(spec, requestMethod, body, addDoAsHeader(spec, headers, userName)); + return readFrom(addDoAs(spec, userName), requestMethod, body, headers); } @@ -113,20 +115,19 @@ public class ViewURLStreamProvider implements org.apache.ambari.view.URLStreamPr // ----- helper methods ---------------------------------------------------- - // add the "do as" header - private Map<String, String> addDoAsHeader(String spec, Map<String, String> headers, String userName) { + // add the "do as" query parameter + private String addDoAs(String spec, String userName) throws IOException { if (spec.toLowerCase().contains(DO_AS_PARAM)) { throw new IllegalArgumentException("URL cannot contain \"" + DO_AS_PARAM + "\" parameter."); } - if (headers == null) { - headers = new HashMap<String, String>(); - } else { - headers = new HashMap<String, String>(headers); + try { + URIBuilder builder = new URIBuilder(spec); + builder.addParameter(DO_AS_PARAM, userName); + return builder.build().toString(); + } catch (URISyntaxException e) { + throw new IOException(e); } - - headers.put(DO_AS_PARAM, userName); - return headers; } // get the input stream response from the underlying stream provider http://git-wip-us.apache.org/repos/asf/ambari/blob/db09f15f/ambari-server/src/test/java/org/apache/ambari/server/view/HttpImpersonatorImplTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/HttpImpersonatorImplTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/HttpImpersonatorImplTest.java index 935b488..e1df325 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/view/HttpImpersonatorImplTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/view/HttpImpersonatorImplTest.java @@ -18,6 +18,8 @@ package org.apache.ambari.server.view; +import org.apache.ambari.server.controller.internal.URLStreamProvider; +import org.apache.ambari.view.HttpImpersonator; import org.apache.ambari.view.ImpersonatorSetting; import org.apache.ambari.view.ViewContext; import org.apache.ambari.server.controller.internal.AppCookieManager; @@ -25,104 +27,77 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; +import sun.nio.cs.StandardCharsets; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; +import java.nio.charset.Charset; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.UUID; +import static org.easymock.EasyMock.aryEq; +import static org.easymock.EasyMock.createNiceMock; +import static org.easymock.EasyMock.eq; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; import static org.mockito.Matchers.*; import static org.mockito.Mockito.when; public class HttpImpersonatorImplTest { - String cookie; - String username; - ViewContext viewContext; - HttpImpersonatorImpl impersonator; - String expectedResult; - - @Before - public void setUp() throws Exception { - String uuid = UUID.randomUUID().toString().replace("-", ""); - this.cookie = uuid; - this.username = "admin" + uuid; + @Test + public void testRequestURL() throws Exception { - AppCookieManager mockAppCookieManager = Mockito.mock(AppCookieManager.class); - when(mockAppCookieManager.getAppCookie(anyString(), anyBoolean())).thenReturn(cookie); + URLStreamProvider streamProvider = createNiceMock(URLStreamProvider.class); + HttpURLConnection urlConnection = createNiceMock(HttpURLConnection.class); + ViewContext viewContext = createNiceMock(ViewContext.class); - this.expectedResult = "Dummy text from HTTP response"; - BufferedReader mockBufferedReader = Mockito.mock(BufferedReader.class); - when(mockBufferedReader.readLine()).thenReturn(expectedResult).thenReturn(null); + String responseBody = "Response body..."; + InputStream inputStream = new ByteArrayInputStream(responseBody.getBytes(Charset.forName("UTF-8"))); - HttpImpersonatorImpl.FactoryHelper mockFactory = Mockito.mock(HttpImpersonatorImpl.FactoryHelper.class); - when(mockFactory.makeBR(any(InputStreamReader.class))).thenReturn(mockBufferedReader); + expect(streamProvider.processURL(eq("spec?doAs=joe"), eq("requestMethod"), eq((String) null), eq((Map<String, List<String>>)null))).andReturn(urlConnection); + expect(urlConnection.getInputStream()).andReturn(inputStream); + expect(viewContext.getUsername()).andReturn("joe").anyTimes(); - this.viewContext = Mockito.mock(ViewContext.class); - when(this.viewContext.getUsername()).thenReturn(username); + replay(streamProvider, urlConnection, viewContext); - this.impersonator = new HttpImpersonatorImpl(this.viewContext, mockFactory); - when(this.viewContext.getHttpImpersonator()).thenReturn(this.impersonator); - } + HttpImpersonatorImpl impersonator = new HttpImpersonatorImpl(viewContext, streamProvider); + ImpersonatorSetting setting = new ImpersonatorSettingImpl(viewContext); - @Test - public void testBasic() throws Exception { - String urlToRead = "http://foo.com"; - String requestMethod = "GET"; - URL url = new URL(urlToRead); - - // Test default params - HttpURLConnection conn1 = (HttpURLConnection) url.openConnection(); - - conn1 = this.viewContext.getHttpImpersonator().doAs(conn1, requestMethod); - Assert.assertEquals(requestMethod, conn1.getRequestMethod()); - Assert.assertEquals(username, conn1.getRequestProperty("doAs")); - - // Test specific params - HttpURLConnection conn2 = (HttpURLConnection) url.openConnection(); - conn2 = this.viewContext.getHttpImpersonator().doAs(conn2, requestMethod, "admin", "username"); - Assert.assertEquals(requestMethod, conn2.getRequestMethod()); - Assert.assertEquals("admin", conn2.getRequestProperty("username")); - } + Assert.assertEquals(responseBody, impersonator.requestURL("spec", "requestMethod", setting)); - @Test - public void testRequestURL() throws Exception { - String urlToRead = "http://foo.com"; - String requestMethod = "GET"; - - // Test default params - ImpersonatorSetting impersonatorSetting = new ImpersonatorSettingImpl(this.viewContext); - when(this.viewContext.getImpersonatorSetting()).thenReturn(impersonatorSetting); - String actualResult = this.viewContext.getHttpImpersonator().requestURL(urlToRead, requestMethod, impersonatorSetting); - Assert.assertEquals(this.expectedResult, actualResult); + verify(streamProvider, urlConnection, viewContext); } @Test public void testRequestURLWithCustom() throws Exception { - String urlToRead = "http://foo.com"; - String requestMethod = "GET"; - - // Test custom params - ImpersonatorSetting impersonatorSetting = new ImpersonatorSettingImpl("hive", "impersonate"); - when(this.viewContext.getImpersonatorSetting()).thenReturn(impersonatorSetting); - String actualResult = this.viewContext.getHttpImpersonator().requestURL(urlToRead, requestMethod, impersonatorSetting); - Assert.assertEquals(this.expectedResult, actualResult); - } - @Test - public void testInvalidURL() throws Exception { - String urlToRead = "http://foo.com?" + "doAs" + "=hive"; - String requestMethod = "GET"; - URL url = new URL(urlToRead); - - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - try { - this.viewContext.getHttpImpersonator().doAs(conn, requestMethod); - Assert.fail("Expected an exception to be thrown."); - } catch(IllegalArgumentException e) { - //expected - } + URLStreamProvider streamProvider = createNiceMock(URLStreamProvider.class); + HttpURLConnection urlConnection = createNiceMock(HttpURLConnection.class); + ViewContext viewContext = createNiceMock(ViewContext.class); + + String responseBody = "Response body..."; + InputStream inputStream = new ByteArrayInputStream(responseBody.getBytes(Charset.forName("UTF-8"))); + + expect(streamProvider.processURL(eq("spec?impersonate=hive"), eq("requestMethod"), eq((String) null), eq((Map<String, List<String>>)null))).andReturn(urlConnection); + expect(urlConnection.getInputStream()).andReturn(inputStream); + + replay(streamProvider, urlConnection); + + HttpImpersonatorImpl impersonator = new HttpImpersonatorImpl(viewContext, streamProvider); + ImpersonatorSetting setting = new ImpersonatorSettingImpl("hive", "impersonate"); + + Assert.assertEquals(responseBody, impersonator.requestURL("spec", "requestMethod", setting)); + + verify(streamProvider, urlConnection); } } http://git-wip-us.apache.org/repos/asf/ambari/blob/db09f15f/ambari-server/src/test/java/org/apache/ambari/server/view/ViewURLStreamProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewURLStreamProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewURLStreamProviderTest.java index 267a605..e606820 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewURLStreamProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewURLStreamProviderTest.java @@ -104,13 +104,11 @@ public class ViewURLStreamProviderTest { Map<String, String> headers = new HashMap<String, String>(); headers.put("header", "headerValue"); - headers.put("doAs", "joe"); Map<String, List<String>> headerMap = new HashMap<String, List<String>>(); headerMap.put("header", Collections.singletonList("headerValue")); - headerMap.put("doAs", Collections.singletonList("joe")); - expect(streamProvider.processURL(eq("spec"), eq("requestMethod"), aryEq("params".getBytes()), eq(headerMap))).andReturn(urlConnection); + expect(streamProvider.processURL(eq("spec?doAs=joe"), eq("requestMethod"), aryEq("params".getBytes()), eq(headerMap))).andReturn(urlConnection); expect(urlConnection.getInputStream()).andReturn(inputStream); replay(streamProvider, urlConnection, inputStream); @@ -132,13 +130,11 @@ public class ViewURLStreamProviderTest { Map<String, String> headers = new HashMap<String, String>(); headers.put("header", "headerValue"); - headers.put("doAs", "joe"); Map<String, List<String>> headerMap = new HashMap<String, List<String>>(); headerMap.put("header", Collections.singletonList("headerValue")); - headerMap.put("doAs", Collections.singletonList("joe")); - expect(streamProvider.processURL(eq("spec"), eq("requestMethod"), aryEq("params".getBytes()), eq(headerMap))).andReturn(urlConnection); + expect(streamProvider.processURL(eq("spec?doAs=joe"), eq("requestMethod"), aryEq("params".getBytes()), eq(headerMap))).andReturn(urlConnection); expect(urlConnection.getInputStream()).andReturn(inputStream); expect(viewContext.getUsername()).andReturn("joe").anyTimes(); @@ -219,13 +215,11 @@ public class ViewURLStreamProviderTest { Map<String, String> headers = new HashMap<String, String>(); headers.put("header", "headerValue"); - headers.put("doAs", "joe"); Map<String, List<String>> headerMap = new HashMap<String, List<String>>(); headerMap.put("header", Collections.singletonList("headerValue")); - headerMap.put("doAs", Collections.singletonList("joe")); - expect(streamProvider.processURL(eq("spec"), eq("requestMethod"), aryEq("params".getBytes()), eq(headerMap))).andReturn(urlConnection); + expect(streamProvider.processURL(eq("spec?doAs=joe"), eq("requestMethod"), aryEq("params".getBytes()), eq(headerMap))).andReturn(urlConnection); expect(urlConnection.getInputStream()).andReturn(inputStream); replay(streamProvider, urlConnection, inputStream); @@ -249,13 +243,11 @@ public class ViewURLStreamProviderTest { Map<String, String> headers = new HashMap<String, String>(); headers.put("header", "headerValue"); - headers.put("doAs", "joe"); Map<String, List<String>> headerMap = new HashMap<String, List<String>>(); headerMap.put("header", Collections.singletonList("headerValue")); - headerMap.put("doAs", Collections.singletonList("joe")); - expect(streamProvider.processURL(eq("spec"), eq("requestMethod"), aryEq("params".getBytes()), eq(headerMap))).andReturn(urlConnection); + expect(streamProvider.processURL(eq("spec?doAs=joe"), eq("requestMethod"), aryEq("params".getBytes()), eq(headerMap))).andReturn(urlConnection); expect(urlConnection.getInputStream()).andReturn(inputStream); expect(viewContext.getUsername()).andReturn("joe").anyTimes();