Updated Branches: refs/heads/trunk db991df50 -> 3f2a76b1e
AMBARI-4549. Remove /api/v1 from Pass Through API.(vbrodetskyi) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/3f2a76b1 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/3f2a76b1 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/3f2a76b1 Branch: refs/heads/trunk Commit: 3f2a76b1e02dfc123488e98a240580c695849733 Parents: db991df Author: Vitaly Brodetskyi <[email protected]> Authored: Fri Feb 7 10:37:09 2014 +0200 Committer: Vitaly Brodetskyi <[email protected]> Committed: Fri Feb 7 10:37:09 2014 +0200 ---------------------------------------------------------------------- .../server/api/services/ProxyService.java | 108 ---------- .../ambari/server/controller/AmbariServer.java | 22 +- .../ambari/server/proxy/ProxyService.java | 108 ++++++++++ .../server/api/services/ProxyServiceTest.java | 214 ------------------ .../ambari/server/proxy/ProxyServiceTest.java | 215 +++++++++++++++++++ 5 files changed, 341 insertions(+), 326 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/3f2a76b1/ambari-server/src/main/java/org/apache/ambari/server/api/services/ProxyService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ProxyService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ProxyService.java deleted file mode 100644 index 9e457c6..0000000 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ProxyService.java +++ /dev/null @@ -1,108 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ambari.server.api.services; - -import com.google.gson.Gson; -import org.apache.ambari.server.controller.internal.URLStreamProvider; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED; -import static javax.ws.rs.core.MediaType.APPLICATION_JSON; -import javax.ws.rs.Path; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.DELETE; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriInfo; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.util.List; -import java.util.Map; - -@Path("/proxy/") -public class ProxyService { - - private static final int REPO_URL_CONNECT_TIMEOUT = 3000; - private static final int REPO_URL_READ_TIMEOUT = 1000; - private static final int HTTP_ERROR_RANGE_START = 400; - - private static final String REQUEST_TYPE_GET = "GET"; - private static final String REQUEST_TYPE_POST = "POST"; - private static final String REQUEST_TYPE_PUT = "PUT"; - private static final String REQUEST_TYPE_DELETE = "DELETE"; - private static final String QUERY_PARAMETER_URL = "url"; - private static final String ERROR_PROCESSING_URL = "Error occurred during processing URL "; - - private final static Logger LOG = LoggerFactory.getLogger(ProxyService.class); - - @GET - public Response processGetRequestForwarding(@Context HttpHeaders headers, @Context UriInfo ui) { - return handleRequest(REQUEST_TYPE_GET, ui, null, APPLICATION_FORM_URLENCODED); - } - - @POST - public Response processPostRequestForwarding(Object body, @Context HttpHeaders headers, @Context UriInfo ui) { - return handleRequest(REQUEST_TYPE_POST, ui, body, headers.getMediaType().toString()); - } - - @PUT - public Response processPutRequestForwarding(Object body, @Context HttpHeaders headers, @Context UriInfo ui) { - return handleRequest(REQUEST_TYPE_PUT, ui, body, headers.getMediaType().toString()); - } - - @DELETE - public Response processDeleteRequestForwarding(@Context HttpHeaders headers, @Context UriInfo ui) { - return handleRequest(REQUEST_TYPE_DELETE, ui, null, APPLICATION_FORM_URLENCODED); - } - - private Response handleRequest(String requestType, UriInfo ui, Object body, String mediaType) { - URLStreamProvider urlStreamProvider = new URLStreamProvider(REPO_URL_CONNECT_TIMEOUT, - REPO_URL_READ_TIMEOUT, null, null, null); - List<String> urlsToForward = ui.getQueryParameters().get(QUERY_PARAMETER_URL); - if (!urlsToForward.isEmpty()) { - String url = urlsToForward.get(0); - try { - HttpURLConnection connection = urlStreamProvider.processURL(url, requestType, body, mediaType); - int responseCode = connection.getResponseCode(); - if (responseCode >= HTTP_ERROR_RANGE_START) { - throw new WebApplicationException(connection.getResponseCode()); - } - String contentType = connection.getContentType(); - Response.ResponseBuilder rb = Response.status(responseCode); - if (contentType.indexOf(APPLICATION_JSON) != -1) { - rb.entity(new Gson().fromJson(new InputStreamReader(connection.getInputStream()), Map.class)); - } else { - rb.entity(connection.getInputStream()); - } - return rb.type(contentType).build(); - } catch (IOException e) { - LOG.error(ERROR_PROCESSING_URL + url, e); - } - } - return null; - } - -} http://git-wip-us.apache.org/repos/asf/ambari/blob/3f2a76b1/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java index faaf0ee..d480aee 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java @@ -203,12 +203,14 @@ public class AmbariServer { //session-per-request strategy for api and agents root.addFilter(new FilterHolder(injector.getInstance(AmbariPersistFilter.class)), "/api/*", 1); + root.addFilter(new FilterHolder(injector.getInstance(AmbariPersistFilter.class)), "/proxy/*", 1); agentroot.addFilter(new FilterHolder(injector.getInstance(AmbariPersistFilter.class)), "/agent/*", 1); agentroot.addFilter(SecurityFilter.class, "/*", 1); if (configs.getApiAuthentication()) { root.addFilter(new FilterHolder(springSecurityFilter), "/api/*", 1); + root.addFilter(new FilterHolder(springSecurityFilter), "/proxy/*", 1); } @@ -272,10 +274,6 @@ public class AmbariServer { "org.apache.ambari.server.api"); sh.setInitParameter("com.sun.jersey.api.json.POJOMappingFeature", "true"); - if (configs.csrfProtectionEnabled()) { - sh.setInitParameter("com.sun.jersey.spi.container.ContainerRequestFilters", - "com.sun.jersey.api.container.filter.CsrfProtectionFilter"); - } root.addServlet(sh, "/api/v1/*"); sh.setInitOrder(2); @@ -301,6 +299,15 @@ public class AmbariServer { agentroot.addServlet(cert, "/*"); cert.setInitOrder(4); + ServletHolder proxy = new ServletHolder(ServletContainer.class); + proxy.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", + "com.sun.jersey.api.core.PackagesResourceConfig"); + proxy.setInitParameter("com.sun.jersey.config.property.packages", + "org.apache.ambari.server.proxy"); + proxy.setInitParameter("com.sun.jersey.api.json.POJOMappingFeature", "true"); + root.addServlet(proxy, "/proxy/*"); + proxy.setInitOrder(5); + ServletHolder resources = new ServletHolder(ServletContainer.class); resources.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", "com.sun.jersey.api.core.PackagesResourceConfig"); @@ -311,6 +318,13 @@ public class AmbariServer { root.addServlet(resources, "/resources/*"); resources.setInitOrder(6); + if (configs.csrfProtectionEnabled()) { + sh.setInitParameter("com.sun.jersey.spi.container.ContainerRequestFilters", + "com.sun.jersey.api.container.filter.CsrfProtectionFilter"); + proxy.setInitParameter("com.sun.jersey.spi.container.ContainerRequestFilters", + "com.sun.jersey.api.container.filter.CsrfProtectionFilter"); + } + //Set jetty thread pool serverForAgent.setThreadPool(new QueuedThreadPool(25)); server.setThreadPool(new QueuedThreadPool(25)); http://git-wip-us.apache.org/repos/asf/ambari/blob/3f2a76b1/ambari-server/src/main/java/org/apache/ambari/server/proxy/ProxyService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/proxy/ProxyService.java b/ambari-server/src/main/java/org/apache/ambari/server/proxy/ProxyService.java new file mode 100644 index 0000000..9f7f108 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/proxy/ProxyService.java @@ -0,0 +1,108 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ambari.server.proxy; + +import com.google.gson.Gson; +import org.apache.ambari.server.controller.internal.URLStreamProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED; +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; +import javax.ws.rs.Path; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.DELETE; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.util.List; +import java.util.Map; + +@Path("/") +public class ProxyService { + + private static final int REPO_URL_CONNECT_TIMEOUT = 3000; + private static final int REPO_URL_READ_TIMEOUT = 1000; + private static final int HTTP_ERROR_RANGE_START = 400; + + private static final String REQUEST_TYPE_GET = "GET"; + private static final String REQUEST_TYPE_POST = "POST"; + private static final String REQUEST_TYPE_PUT = "PUT"; + private static final String REQUEST_TYPE_DELETE = "DELETE"; + private static final String QUERY_PARAMETER_URL = "url"; + private static final String ERROR_PROCESSING_URL = "Error occurred during processing URL "; + + private final static Logger LOG = LoggerFactory.getLogger(ProxyService.class); + + @GET + public Response processGetRequestForwarding(@Context HttpHeaders headers, @Context UriInfo ui) { + return handleRequest(REQUEST_TYPE_GET, ui, null, APPLICATION_FORM_URLENCODED); + } + + @POST + public Response processPostRequestForwarding(Object body, @Context HttpHeaders headers, @Context UriInfo ui) { + return handleRequest(REQUEST_TYPE_POST, ui, body, headers.getMediaType().toString()); + } + + @PUT + public Response processPutRequestForwarding(Object body, @Context HttpHeaders headers, @Context UriInfo ui) { + return handleRequest(REQUEST_TYPE_PUT, ui, body, headers.getMediaType().toString()); + } + + @DELETE + public Response processDeleteRequestForwarding(@Context HttpHeaders headers, @Context UriInfo ui) { + return handleRequest(REQUEST_TYPE_DELETE, ui, null, APPLICATION_FORM_URLENCODED); + } + + private Response handleRequest(String requestType, UriInfo ui, Object body, String mediaType) { + URLStreamProvider urlStreamProvider = new URLStreamProvider(REPO_URL_CONNECT_TIMEOUT, + REPO_URL_READ_TIMEOUT, null, null, null); + List<String> urlsToForward = ui.getQueryParameters().get(QUERY_PARAMETER_URL); + if (!urlsToForward.isEmpty()) { + String url = urlsToForward.get(0); + try { + HttpURLConnection connection = urlStreamProvider.processURL(url, requestType, body, mediaType); + int responseCode = connection.getResponseCode(); + if (responseCode >= HTTP_ERROR_RANGE_START) { + throw new WebApplicationException(connection.getResponseCode()); + } + String contentType = connection.getContentType(); + Response.ResponseBuilder rb = Response.status(responseCode); + if (contentType.indexOf(APPLICATION_JSON) != -1) { + rb.entity(new Gson().fromJson(new InputStreamReader(connection.getInputStream()), Map.class)); + } else { + rb.entity(connection.getInputStream()); + } + return rb.type(contentType).build(); + } catch (IOException e) { + LOG.error(ERROR_PROCESSING_URL + url, e); + } + } + return null; + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/3f2a76b1/ambari-server/src/test/java/org/apache/ambari/server/api/services/ProxyServiceTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/ProxyServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/ProxyServiceTest.java deleted file mode 100644 index 3f219dd..0000000 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/ProxyServiceTest.java +++ /dev/null @@ -1,214 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ambari.server.api.services; - -import com.google.gson.Gson; -import com.sun.jersey.core.spi.factory.ResponseBuilderImpl; -import com.sun.jersey.core.spi.factory.ResponseImpl; -import com.sun.jersey.core.util.MultivaluedMapImpl; - -import org.apache.ambari.server.controller.internal.URLStreamProvider; -import org.junit.Test; -import org.junit.runner.RunWith; -import static org.junit.Assert.assertSame; -import org.powermock.api.easymock.PowerMock; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED; -import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED_TYPE; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.core.Response; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.util.Map; -import java.util.List; -import java.util.Collections; - -import static org.easymock.EasyMock.createMock; -import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.replay; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({ ProxyServiceTest.class, ProxyService.class, URLStreamProvider.class, Response.class, ResponseBuilderImpl.class }) -class ProxyServiceTest extends BaseServiceTest { - - @Test - public void testProxyGetRequest() throws Exception { - ProxyService ps = new ProxyService(); - URLStreamProvider streamProviderMock = PowerMock.createNiceMock(URLStreamProvider.class); - HttpURLConnection urlConnectionMock = createMock(HttpURLConnection.class); - MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); - Response.ResponseBuilder responseBuilderMock = PowerMock.createMock(ResponseBuilderImpl.class); - Response responseMock = createMock(ResponseImpl.class); - queryParams.add("url","testurl"); - InputStream is = new ByteArrayInputStream("test".getBytes()); - PowerMock.mockStatic(Response.class); - expect(getUriInfo().getQueryParameters()).andReturn(queryParams); - expect(streamProviderMock.processURL("testurl", "GET", null, APPLICATION_FORM_URLENCODED)).andReturn(urlConnectionMock); - expect(urlConnectionMock.getResponseCode()).andReturn(200); - expect(urlConnectionMock.getContentType()).andReturn("text/plain"); - expect(urlConnectionMock.getInputStream()).andReturn(is); - PowerMock.expectNew(URLStreamProvider.class, 3000, 1000, null, null, null).andReturn(streamProviderMock); - expect(Response.status(200)).andReturn(responseBuilderMock); - expect(responseBuilderMock.entity(is)).andReturn(responseBuilderMock); - expect(responseBuilderMock.type("text/plain")).andReturn(responseBuilderMock); - expect(responseBuilderMock.build()).andReturn(responseMock); - PowerMock.replay(streamProviderMock, URLStreamProvider.class, Response.class, responseBuilderMock); - replay(getUriInfo(), urlConnectionMock); - Response resultForGetRequest = ps.processGetRequestForwarding(getHttpHeaders(),getUriInfo()); - assertSame(resultForGetRequest, responseMock); - } - - @Test - public void testProxyPostRequest() throws Exception { - ProxyService ps = new ProxyService(); - URLStreamProvider streamProviderMock = PowerMock.createNiceMock(URLStreamProvider.class); - HttpURLConnection urlConnectionMock = createMock(HttpURLConnection.class); - MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); - Response.ResponseBuilder responseBuilderMock = PowerMock.createMock(ResponseBuilderImpl.class); - Response responseMock = createMock(ResponseImpl.class); - queryParams.add("url","testurl"); - InputStream is = new ByteArrayInputStream("test".getBytes()); - PowerMock.mockStatic(Response.class); - expect(getUriInfo().getQueryParameters()).andReturn(queryParams); - expect(getHttpHeaders().getMediaType()).andReturn(APPLICATION_FORM_URLENCODED_TYPE); - expect(streamProviderMock.processURL("testurl", "POST", "testbody", APPLICATION_FORM_URLENCODED)).andReturn(urlConnectionMock); - expect(urlConnectionMock.getResponseCode()).andReturn(200); - expect(urlConnectionMock.getContentType()).andReturn("text/plain"); - expect(urlConnectionMock.getInputStream()).andReturn(is); - PowerMock.expectNew(URLStreamProvider.class, 3000, 1000, null, null, null).andReturn(streamProviderMock); - expect(Response.status(200)).andReturn(responseBuilderMock); - expect(responseBuilderMock.entity(is)).andReturn(responseBuilderMock); - expect(responseBuilderMock.type("text/plain")).andReturn(responseBuilderMock); - expect(responseBuilderMock.build()).andReturn(responseMock); - PowerMock.replay(streamProviderMock, URLStreamProvider.class, Response.class, responseBuilderMock); - replay(getUriInfo(), urlConnectionMock, getHttpHeaders()); - Response resultForPostRequest = ps.processPostRequestForwarding("testbody", getHttpHeaders(), getUriInfo()); - assertSame(resultForPostRequest, responseMock); - } - - @Test - public void testProxyPutRequest() throws Exception { - ProxyService ps = new ProxyService(); - URLStreamProvider streamProviderMock = PowerMock.createNiceMock(URLStreamProvider.class); - HttpURLConnection urlConnectionMock = createMock(HttpURLConnection.class); - MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); - Response.ResponseBuilder responseBuilderMock = PowerMock.createMock(ResponseBuilderImpl.class); - Response responseMock = createMock(ResponseImpl.class); - queryParams.add("url","testurl"); - InputStream is = new ByteArrayInputStream("test".getBytes()); - PowerMock.mockStatic(Response.class); - expect(getUriInfo().getQueryParameters()).andReturn(queryParams); - expect(getHttpHeaders().getMediaType()).andReturn(APPLICATION_FORM_URLENCODED_TYPE); - expect(streamProviderMock.processURL("testurl", "PUT", "testbody", APPLICATION_FORM_URLENCODED)).andReturn(urlConnectionMock); - expect(urlConnectionMock.getResponseCode()).andReturn(200); - expect(urlConnectionMock.getContentType()).andReturn("text/plain"); - expect(urlConnectionMock.getInputStream()).andReturn(is); - PowerMock.expectNew(URLStreamProvider.class, 3000, 1000, null, null, null).andReturn(streamProviderMock); - expect(Response.status(200)).andReturn(responseBuilderMock); - expect(responseBuilderMock.entity(is)).andReturn(responseBuilderMock); - expect(responseBuilderMock.type("text/plain")).andReturn(responseBuilderMock); - expect(responseBuilderMock.build()).andReturn(responseMock); - PowerMock.replay(streamProviderMock, URLStreamProvider.class, Response.class, responseBuilderMock); - replay(getUriInfo(), urlConnectionMock, getHttpHeaders()); - Response resultForPutRequest = ps.processPutRequestForwarding("testbody", getHttpHeaders(), getUriInfo()); - assertSame(resultForPutRequest, responseMock); - } - - @Test - public void testProxyDeleteRequest() throws Exception { - ProxyService ps = new ProxyService(); - URLStreamProvider streamProviderMock = PowerMock.createNiceMock(URLStreamProvider.class); - HttpURLConnection urlConnectionMock = createMock(HttpURLConnection.class); - MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); - Response.ResponseBuilder responseBuilderMock = PowerMock.createMock(ResponseBuilderImpl.class); - Response responseMock = createMock(ResponseImpl.class); - queryParams.add("url","testurl"); - InputStream is = new ByteArrayInputStream("test".getBytes()); - PowerMock.mockStatic(Response.class); - expect(getUriInfo().getQueryParameters()).andReturn(queryParams); - expect(streamProviderMock.processURL("testurl", "DELETE", null, APPLICATION_FORM_URLENCODED)).andReturn(urlConnectionMock); - expect(urlConnectionMock.getResponseCode()).andReturn(200); - expect(urlConnectionMock.getContentType()).andReturn("text/plain"); - expect(urlConnectionMock.getInputStream()).andReturn(is); - PowerMock.expectNew(URLStreamProvider.class, 3000, 1000, null, null, null).andReturn(streamProviderMock); - expect(Response.status(200)).andReturn(responseBuilderMock); - expect(responseBuilderMock.entity(is)).andReturn(responseBuilderMock); - expect(responseBuilderMock.type("text/plain")).andReturn(responseBuilderMock); - expect(responseBuilderMock.build()).andReturn(responseMock); - PowerMock.replay(streamProviderMock, URLStreamProvider.class, Response.class, responseBuilderMock); - replay(getUriInfo(), urlConnectionMock); - Response resultForDeleteRequest = ps.processDeleteRequestForwarding(getHttpHeaders(), getUriInfo()); - assertSame(resultForDeleteRequest, responseMock); - } - - @Test(expected = WebApplicationException.class) - public void testResponseWithError() throws Exception { - ProxyService ps = new ProxyService(); - URLStreamProvider streamProviderMock = PowerMock.createNiceMock(URLStreamProvider.class); - HttpURLConnection urlConnectionMock = createMock(HttpURLConnection.class); - MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); - queryParams.add("url","testurl"); - expect(getUriInfo().getQueryParameters()).andReturn(queryParams); - expect(streamProviderMock.processURL("testurl", "GET", null, APPLICATION_FORM_URLENCODED)).andReturn(urlConnectionMock); - expect(urlConnectionMock.getResponseCode()).andReturn(405).times(2); - PowerMock.expectNew(URLStreamProvider.class, 3000, 1000, null, null, null).andReturn(streamProviderMock); - PowerMock.replay(streamProviderMock, URLStreamProvider.class); - replay(getUriInfo(), urlConnectionMock); - ps.processGetRequestForwarding(getHttpHeaders(),getUriInfo()); - } - - @Test - public void testProxyWithJSONResponse() throws Exception { - ProxyService ps = new ProxyService(); - URLStreamProvider streamProviderMock = PowerMock.createNiceMock(URLStreamProvider.class); - HttpURLConnection urlConnectionMock = createMock(HttpURLConnection.class); - MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); - Response.ResponseBuilder responseBuilderMock = PowerMock.createMock(ResponseBuilderImpl.class); - Response responseMock = createMock(ResponseImpl.class); - queryParams.add("url","testurl"); - Map map = new Gson().fromJson(new InputStreamReader(new ByteArrayInputStream("{ \"test\":\"test\" }".getBytes())), Map.class); - PowerMock.mockStatic(Response.class); - expect(getUriInfo().getQueryParameters()).andReturn(queryParams); - expect(streamProviderMock.processURL("testurl", "GET", null, APPLICATION_FORM_URLENCODED)).andReturn(urlConnectionMock); - expect(urlConnectionMock.getResponseCode()).andReturn(200); - expect(urlConnectionMock.getContentType()).andReturn("application/json"); - expect(urlConnectionMock.getInputStream()).andReturn(new ByteArrayInputStream("{ \"test\":\"test\" }".getBytes())); - PowerMock.expectNew(URLStreamProvider.class, 3000, 1000, null, null, null).andReturn(streamProviderMock); - expect(Response.status(200)).andReturn(responseBuilderMock); - expect(responseBuilderMock.entity(map)).andReturn(responseBuilderMock); - expect(responseBuilderMock.type("application/json")).andReturn(responseBuilderMock); - expect(responseBuilderMock.build()).andReturn(responseMock); - PowerMock.replay(streamProviderMock, URLStreamProvider.class, Response.class, responseBuilderMock); - replay(getUriInfo(), urlConnectionMock); - Response resultForGetRequest = ps.processGetRequestForwarding(getHttpHeaders(),getUriInfo()); - assertSame(resultForGetRequest, responseMock); - } - - @Override - public List<ServiceTestInvocation> getTestInvocations() throws Exception { - return Collections.emptyList(); - } - -} http://git-wip-us.apache.org/repos/asf/ambari/blob/3f2a76b1/ambari-server/src/test/java/org/apache/ambari/server/proxy/ProxyServiceTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/proxy/ProxyServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/proxy/ProxyServiceTest.java new file mode 100644 index 0000000..80c5c7d --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/proxy/ProxyServiceTest.java @@ -0,0 +1,215 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ambari.server.proxy; + +import com.google.gson.Gson; +import com.sun.jersey.core.spi.factory.ResponseBuilderImpl; +import com.sun.jersey.core.spi.factory.ResponseImpl; +import com.sun.jersey.core.util.MultivaluedMapImpl; + +import org.apache.ambari.server.api.services.BaseServiceTest; +import org.apache.ambari.server.controller.internal.URLStreamProvider; +import org.junit.Test; +import org.junit.runner.RunWith; +import static org.junit.Assert.assertSame; +import org.powermock.api.easymock.PowerMock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED; +import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED_TYPE; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.util.Map; +import java.util.List; +import java.util.Collections; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ ProxyServiceTest.class, ProxyService.class, URLStreamProvider.class, Response.class, ResponseBuilderImpl.class }) +class ProxyServiceTest extends BaseServiceTest { + + @Test + public void testProxyGetRequest() throws Exception { + ProxyService ps = new ProxyService(); + URLStreamProvider streamProviderMock = PowerMock.createNiceMock(URLStreamProvider.class); + HttpURLConnection urlConnectionMock = createMock(HttpURLConnection.class); + MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); + Response.ResponseBuilder responseBuilderMock = PowerMock.createMock(ResponseBuilderImpl.class); + Response responseMock = createMock(ResponseImpl.class); + queryParams.add("url","testurl"); + InputStream is = new ByteArrayInputStream("test".getBytes()); + PowerMock.mockStatic(Response.class); + expect(getUriInfo().getQueryParameters()).andReturn(queryParams); + expect(streamProviderMock.processURL("testurl", "GET", null, APPLICATION_FORM_URLENCODED)).andReturn(urlConnectionMock); + expect(urlConnectionMock.getResponseCode()).andReturn(200); + expect(urlConnectionMock.getContentType()).andReturn("text/plain"); + expect(urlConnectionMock.getInputStream()).andReturn(is); + PowerMock.expectNew(URLStreamProvider.class, 3000, 1000, null, null, null).andReturn(streamProviderMock); + expect(Response.status(200)).andReturn(responseBuilderMock); + expect(responseBuilderMock.entity(is)).andReturn(responseBuilderMock); + expect(responseBuilderMock.type("text/plain")).andReturn(responseBuilderMock); + expect(responseBuilderMock.build()).andReturn(responseMock); + PowerMock.replay(streamProviderMock, URLStreamProvider.class, Response.class, responseBuilderMock); + replay(getUriInfo(), urlConnectionMock); + Response resultForGetRequest = ps.processGetRequestForwarding(getHttpHeaders(),getUriInfo()); + assertSame(resultForGetRequest, responseMock); + } + + @Test + public void testProxyPostRequest() throws Exception { + ProxyService ps = new ProxyService(); + URLStreamProvider streamProviderMock = PowerMock.createNiceMock(URLStreamProvider.class); + HttpURLConnection urlConnectionMock = createMock(HttpURLConnection.class); + MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); + Response.ResponseBuilder responseBuilderMock = PowerMock.createMock(ResponseBuilderImpl.class); + Response responseMock = createMock(ResponseImpl.class); + queryParams.add("url","testurl"); + InputStream is = new ByteArrayInputStream("test".getBytes()); + PowerMock.mockStatic(Response.class); + expect(getUriInfo().getQueryParameters()).andReturn(queryParams); + expect(getHttpHeaders().getMediaType()).andReturn(APPLICATION_FORM_URLENCODED_TYPE); + expect(streamProviderMock.processURL("testurl", "POST", "testbody", APPLICATION_FORM_URLENCODED)).andReturn(urlConnectionMock); + expect(urlConnectionMock.getResponseCode()).andReturn(200); + expect(urlConnectionMock.getContentType()).andReturn("text/plain"); + expect(urlConnectionMock.getInputStream()).andReturn(is); + PowerMock.expectNew(URLStreamProvider.class, 3000, 1000, null, null, null).andReturn(streamProviderMock); + expect(Response.status(200)).andReturn(responseBuilderMock); + expect(responseBuilderMock.entity(is)).andReturn(responseBuilderMock); + expect(responseBuilderMock.type("text/plain")).andReturn(responseBuilderMock); + expect(responseBuilderMock.build()).andReturn(responseMock); + PowerMock.replay(streamProviderMock, URLStreamProvider.class, Response.class, responseBuilderMock); + replay(getUriInfo(), urlConnectionMock, getHttpHeaders()); + Response resultForPostRequest = ps.processPostRequestForwarding("testbody", getHttpHeaders(), getUriInfo()); + assertSame(resultForPostRequest, responseMock); + } + + @Test + public void testProxyPutRequest() throws Exception { + ProxyService ps = new ProxyService(); + URLStreamProvider streamProviderMock = PowerMock.createNiceMock(URLStreamProvider.class); + HttpURLConnection urlConnectionMock = createMock(HttpURLConnection.class); + MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); + Response.ResponseBuilder responseBuilderMock = PowerMock.createMock(ResponseBuilderImpl.class); + Response responseMock = createMock(ResponseImpl.class); + queryParams.add("url","testurl"); + InputStream is = new ByteArrayInputStream("test".getBytes()); + PowerMock.mockStatic(Response.class); + expect(getUriInfo().getQueryParameters()).andReturn(queryParams); + expect(getHttpHeaders().getMediaType()).andReturn(APPLICATION_FORM_URLENCODED_TYPE); + expect(streamProviderMock.processURL("testurl", "PUT", "testbody", APPLICATION_FORM_URLENCODED)).andReturn(urlConnectionMock); + expect(urlConnectionMock.getResponseCode()).andReturn(200); + expect(urlConnectionMock.getContentType()).andReturn("text/plain"); + expect(urlConnectionMock.getInputStream()).andReturn(is); + PowerMock.expectNew(URLStreamProvider.class, 3000, 1000, null, null, null).andReturn(streamProviderMock); + expect(Response.status(200)).andReturn(responseBuilderMock); + expect(responseBuilderMock.entity(is)).andReturn(responseBuilderMock); + expect(responseBuilderMock.type("text/plain")).andReturn(responseBuilderMock); + expect(responseBuilderMock.build()).andReturn(responseMock); + PowerMock.replay(streamProviderMock, URLStreamProvider.class, Response.class, responseBuilderMock); + replay(getUriInfo(), urlConnectionMock, getHttpHeaders()); + Response resultForPutRequest = ps.processPutRequestForwarding("testbody", getHttpHeaders(), getUriInfo()); + assertSame(resultForPutRequest, responseMock); + } + + @Test + public void testProxyDeleteRequest() throws Exception { + ProxyService ps = new ProxyService(); + URLStreamProvider streamProviderMock = PowerMock.createNiceMock(URLStreamProvider.class); + HttpURLConnection urlConnectionMock = createMock(HttpURLConnection.class); + MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); + Response.ResponseBuilder responseBuilderMock = PowerMock.createMock(ResponseBuilderImpl.class); + Response responseMock = createMock(ResponseImpl.class); + queryParams.add("url","testurl"); + InputStream is = new ByteArrayInputStream("test".getBytes()); + PowerMock.mockStatic(Response.class); + expect(getUriInfo().getQueryParameters()).andReturn(queryParams); + expect(streamProviderMock.processURL("testurl", "DELETE", null, APPLICATION_FORM_URLENCODED)).andReturn(urlConnectionMock); + expect(urlConnectionMock.getResponseCode()).andReturn(200); + expect(urlConnectionMock.getContentType()).andReturn("text/plain"); + expect(urlConnectionMock.getInputStream()).andReturn(is); + PowerMock.expectNew(URLStreamProvider.class, 3000, 1000, null, null, null).andReturn(streamProviderMock); + expect(Response.status(200)).andReturn(responseBuilderMock); + expect(responseBuilderMock.entity(is)).andReturn(responseBuilderMock); + expect(responseBuilderMock.type("text/plain")).andReturn(responseBuilderMock); + expect(responseBuilderMock.build()).andReturn(responseMock); + PowerMock.replay(streamProviderMock, URLStreamProvider.class, Response.class, responseBuilderMock); + replay(getUriInfo(), urlConnectionMock); + Response resultForDeleteRequest = ps.processDeleteRequestForwarding(getHttpHeaders(), getUriInfo()); + assertSame(resultForDeleteRequest, responseMock); + } + + @Test(expected = WebApplicationException.class) + public void testResponseWithError() throws Exception { + ProxyService ps = new ProxyService(); + URLStreamProvider streamProviderMock = PowerMock.createNiceMock(URLStreamProvider.class); + HttpURLConnection urlConnectionMock = createMock(HttpURLConnection.class); + MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); + queryParams.add("url","testurl"); + expect(getUriInfo().getQueryParameters()).andReturn(queryParams); + expect(streamProviderMock.processURL("testurl", "GET", null, APPLICATION_FORM_URLENCODED)).andReturn(urlConnectionMock); + expect(urlConnectionMock.getResponseCode()).andReturn(405).times(2); + PowerMock.expectNew(URLStreamProvider.class, 3000, 1000, null, null, null).andReturn(streamProviderMock); + PowerMock.replay(streamProviderMock, URLStreamProvider.class); + replay(getUriInfo(), urlConnectionMock); + ps.processGetRequestForwarding(getHttpHeaders(),getUriInfo()); + } + + @Test + public void testProxyWithJSONResponse() throws Exception { + ProxyService ps = new ProxyService(); + URLStreamProvider streamProviderMock = PowerMock.createNiceMock(URLStreamProvider.class); + HttpURLConnection urlConnectionMock = createMock(HttpURLConnection.class); + MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); + Response.ResponseBuilder responseBuilderMock = PowerMock.createMock(ResponseBuilderImpl.class); + Response responseMock = createMock(ResponseImpl.class); + queryParams.add("url","testurl"); + Map map = new Gson().fromJson(new InputStreamReader(new ByteArrayInputStream("{ \"test\":\"test\" }".getBytes())), Map.class); + PowerMock.mockStatic(Response.class); + expect(getUriInfo().getQueryParameters()).andReturn(queryParams); + expect(streamProviderMock.processURL("testurl", "GET", null, APPLICATION_FORM_URLENCODED)).andReturn(urlConnectionMock); + expect(urlConnectionMock.getResponseCode()).andReturn(200); + expect(urlConnectionMock.getContentType()).andReturn("application/json"); + expect(urlConnectionMock.getInputStream()).andReturn(new ByteArrayInputStream("{ \"test\":\"test\" }".getBytes())); + PowerMock.expectNew(URLStreamProvider.class, 3000, 1000, null, null, null).andReturn(streamProviderMock); + expect(Response.status(200)).andReturn(responseBuilderMock); + expect(responseBuilderMock.entity(map)).andReturn(responseBuilderMock); + expect(responseBuilderMock.type("application/json")).andReturn(responseBuilderMock); + expect(responseBuilderMock.build()).andReturn(responseMock); + PowerMock.replay(streamProviderMock, URLStreamProvider.class, Response.class, responseBuilderMock); + replay(getUriInfo(), urlConnectionMock); + Response resultForGetRequest = ps.processGetRequestForwarding(getHttpHeaders(),getUriInfo()); + assertSame(resultForGetRequest, responseMock); + } + + @Override + public List<ServiceTestInvocation> getTestInvocations() throws Exception { + return Collections.emptyList(); + } + +}
