/* * (C) Copyright 2016 Nuxeo SA (http://nuxeo.com/) and others. * * Licensed 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. * * Contributors: * Ricardo Dias */ package org.nuxeo.ecm.automation.core.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockserver.integration.ClientAndProxy.startClientAndProxy; import static org.mockserver.integration.ClientAndServer.startClientAndServer; import static org.mockserver.model.HttpRequest.request; import static org.mockserver.model.HttpResponse.response; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import javax.inject.Inject; import javax.ws.rs.core.HttpHeaders; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.codehaus.jackson.map.ObjectMapper; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockserver.client.server.MockServerClient; import org.mockserver.integration.ClientAndProxy; import org.mockserver.integration.ClientAndServer; import org.mockserver.matchers.Times; import org.mockserver.model.BinaryBody; import org.mockserver.model.Body; import org.mockserver.model.Delay; import org.mockserver.model.Header; import org.mockserver.model.JsonBody; import org.nuxeo.ecm.automation.OperationContext; import org.nuxeo.ecm.automation.context.ContextHelper; import org.nuxeo.ecm.automation.context.ContextService; import org.nuxeo.ecm.automation.core.scripting.Scripting; import org.nuxeo.ecm.automation.features.HTTPHelper; import org.nuxeo.ecm.core.api.Blob; import org.nuxeo.ecm.core.api.CoreSession; import org.nuxeo.ecm.platform.test.PlatformFeature; import org.nuxeo.runtime.test.runner.Deploy; import org.nuxeo.runtime.test.runner.Features; import org.nuxeo.runtime.test.runner.FeaturesRunner; /** * @since 8.4 */ @RunWith(FeaturesRunner.class) @Features(PlatformFeature.class) @Deploy({ "org.nuxeo.ecm.automation.core", "org.nuxeo.ecm.automation.features" }) public class HTTPHelperTest { @Inject CoreSession session; @Inject ContextService ctxService; OperationContext ctx; protected ClientAndProxy proxy; protected ClientAndServer mockServer; protected final static String SERVER_HOST = "localhost"; protected final static String SERVER_PATH = "/ws/path/"; protected final static int SERVER_PORT = 1080; protected final static String SERVER_URL = "http://" + SERVER_HOST + ":" + String.valueOf(SERVER_PORT) + SERVER_PATH; protected final static String IMAGE_FILENAME = "sample.jpeg"; private final JsonBody DEFAULT_HTTP_RESPONSE = new JsonBody("{\"message\": \"Default answer to requests.\"}"); @Before public void setUp() throws Exception { mockServer = startClientAndServer(1080); proxy = startClientAndProxy(1090); ctx = new OperationContext(session); // assert that the helper is available Map<String, ContextHelper> contextHelperList = ctxService.getHelperFunctions(); Object httpHelper = contextHelperList.get("HTTP"); assertNotNull(httpHelper); assertTrue(httpHelper instanceof HTTPHelper); } @After public void tearDown() throws Exception { proxy.stop(); mockServer.stop(); } @Test public void testHTTPHelperGet() { createMockServer("GET", SERVER_PATH, DEFAULT_HTTP_RESPONSE); try { String expr = String.format( "HTTP.get(\'%s\', {'auth' : { 'method' : 'basic', 'username' : 'test', 'password' : 'test' }})", SERVER_URL); Blob resultBlob = (Blob) Scripting.newExpression(expr).eval(ctx); String result = IOUtils.toString(resultBlob.getStream(), "utf-8"); ObjectMapper mapper = new ObjectMapper(); Map<String, String> jsonResult = mapper.readValue(result, Map.class); String message = jsonResult.get("message"); assertEquals("Default answer to requests.", message); } catch (IOException exception) { fail("Problem parsing the result. " + exception); } } @Test public void testHTTPHelperGetWithParams() { createMockServer("GET", SERVER_PATH, DEFAULT_HTTP_RESPONSE); try { String expr = String.format( "HTTP.get(\'%s\', " + "{'auth' : { 'method' : 'basic', 'username' : 'test', 'password' : 'test' }, " + "'params' : { 'param1' : [ 'value1' ] , 'param2' : [ 'value2' ] }})", SERVER_URL); Blob resultBlob = (Blob) Scripting.newExpression(expr).eval(ctx); String result = IOUtils.toString(resultBlob.getStream(), "utf-8"); ObjectMapper mapper = new ObjectMapper(); Map<String, String> jsonResult = mapper.readValue(result, Map.class); String message = jsonResult.get("message"); assertEquals("Default answer to requests.", message); } catch (IOException exception) { fail("Problem parsing the result. " + exception.getMessage()); } } @Test public void testHTTPHelperGetWithHeaders() { createMockServer("GET", SERVER_PATH, DEFAULT_HTTP_RESPONSE); try { String expr = String.format( "HTTP.get(\'%s\', " + "{'auth' : { 'method' : 'basic', 'username' : 'test', 'password' : 'test' }, " + "'headers' : { 'Accept' : 'application/json' , 'User-Agent' : 'Mozilla/5.0' }})", SERVER_URL); Blob resultBlob = (Blob) Scripting.newExpression(expr).eval(ctx); String result = IOUtils.toString(resultBlob.getStream(), "utf-8"); ObjectMapper mapper = new ObjectMapper(); Map<String, String> jsonResult = mapper.readValue(result, Map.class); String message = jsonResult.get("message"); assertEquals("Default answer to requests.", message); } catch (IOException exception) { fail("Problem parsing the result. " + exception.getMessage()); } } @Test public void testHTTPHelperPost() { createMockServer("POST", SERVER_PATH, DEFAULT_HTTP_RESPONSE); try { String expr = String.format( "HTTP.post(\'%s\', 'Test', {'auth' : { 'method' : 'basic', 'username' : 'test', 'password' : 'test' }})", SERVER_URL); Blob resultBlob = (Blob) Scripting.newExpression(expr).eval(ctx); String result = IOUtils.toString(resultBlob.getStream(), "utf-8"); ObjectMapper mapper = new ObjectMapper(); Map<String, String> jsonResult = mapper.readValue(result, Map.class); String message = jsonResult.get("message"); assertEquals("Default answer to requests.", message); } catch (IOException exception) { fail("Problem parsing the result. " + exception); } } @Test public void testHTTPHelperPut() { createMockServer("PUT", SERVER_PATH, DEFAULT_HTTP_RESPONSE); try { String expr = String.format( "HTTP.put(\'%s\', 'Test', {'auth' : { 'method' : 'basic', 'username' : 'test', 'password' : 'test' }})", SERVER_URL); Blob resultBlob = (Blob) Scripting.newExpression(expr).eval(ctx); String result = IOUtils.toString(resultBlob.getStream(), "utf-8"); ObjectMapper mapper = new ObjectMapper(); Map<String, String> jsonResult = mapper.readValue(result, Map.class); String message = jsonResult.get("message"); assertEquals("Default answer to requests.", message); } catch (IOException exception) { fail("Problem parsing the result. " + exception); } } @Test public void testHTTPHelperDelete() { createMockServer("DELETE", SERVER_PATH, DEFAULT_HTTP_RESPONSE); try { String expr = String.format( "HTTP.delete(\'%s\', 'Test', {'auth' : { 'method' : 'basic', 'username' : 'test', 'password' : 'test' }})", SERVER_URL); Blob resultBlob = (Blob) Scripting.newExpression(expr).eval(ctx); String result = IOUtils.toString(resultBlob.getStream(), "utf-8"); ObjectMapper mapper = new ObjectMapper(); Map<String, String> jsonResult = mapper.readValue(result, Map.class); String message = jsonResult.get("message"); assertEquals("Default answer to requests.", message); } catch (IOException exception) { fail("Problem parsing the result. " + exception); } } @Test public void testHTTPHelperGetDownloadFile() { try { File file = org.nuxeo.common.utils.FileUtils.getResourceFileFromContext("test-data/sample.jpeg"); byte[] answer = FileUtils.readFileToByteArray(file); Body responseBody = new BinaryBody(answer); createMockServer("GET", SERVER_PATH + IMAGE_FILENAME, responseBody); } catch (IOException e) { fail("Error reading the image file." + e.getMessage()); } String expr = String.format( "HTTP.get(\'%s\', {'auth' : { 'method' : 'basic', 'username' : 'test', 'password' : 'test' }})", SERVER_URL + IMAGE_FILENAME); Blob httpResult = (Blob) Scripting.newExpression(expr).eval(ctx); assertTrue(httpResult.getLength() > 0); assertEquals(httpResult.getFilename(), IMAGE_FILENAME); } /** * Create a mock server that answers http requests with a certain set of headers and a body answer. * * @param method the HTTP request (GET, POST, PUT, DELETE) * @param path the path of the requests * @param answer the body of the http response */ public void createMockServer(String method, String path, Body answer) { List<Header> requestHeaders = new ArrayList<>(); requestHeaders.add(new Header(HttpHeaders.AUTHORIZATION, "Basic dGVzdDp0ZXN0")); List<Header> responseHeaders = new ArrayList<>(); responseHeaders.add(new Header(HttpHeaders.CONTENT_TYPE, "application/json; charset=utf-8")); responseHeaders.add(new Header(HttpHeaders.CACHE_CONTROL, "public, max-age=86400")); new MockServerClient(SERVER_HOST, SERVER_PORT) .when(request().withHeaders(requestHeaders) .withMethod(method) .withPath(path), Times.exactly(2)) .respond(response().withStatusCode(200) .withHeaders(responseHeaders) .withBody(answer) .withDelay(new Delay(TimeUnit.SECONDS, 1))); } }