| // *************************************************************************************************************************** |
| // * 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.juneau.rest.test; |
| |
| import java.io.*; |
| import java.net.*; |
| import java.security.*; |
| import java.util.*; |
| |
| import javax.net.ssl.*; |
| |
| import org.apache.http.*; |
| import org.apache.http.client.*; |
| import org.apache.http.conn.ssl.*; |
| import org.apache.http.impl.client.*; |
| import org.apache.http.protocol.*; |
| import org.apache.juneau.internal.*; |
| import org.apache.juneau.microservice.*; |
| import org.apache.juneau.parser.*; |
| import org.apache.juneau.plaintext.*; |
| import org.apache.juneau.rest.client.*; |
| import org.apache.juneau.serializer.*; |
| |
| /** |
| * Utility class for starting up the tests microservice. |
| * @author james.bognar |
| */ |
| public class TestMicroservice { |
| |
| static RestMicroservice microservice; |
| static URI microserviceURI; |
| |
| // Reusable HTTP clients that get created and shut down with the microservice. |
| public static RestClient DEFAULT_CLIENT, DEFAULT_CLIENT_DEBUG; |
| public static RestClient DEFAULT_CLIENT_PLAINTEXT; |
| |
| /** |
| * Starts the microservice. |
| * @return <jk>true</jk> if the service started, <jk>false</jk> if it's already started. |
| * If this returns <jk>false</jk> then don't call stopMicroservice()!. |
| */ |
| public static boolean startMicroservice() { |
| if (microservice != null) |
| return false; |
| try { |
| Locale.setDefault(Locale.US); |
| microservice = new RestMicroservice() |
| .setConfig("juneau-microservice-test.cfg", false) |
| .setManifestContents( |
| "Test-Entry: test-value" |
| ); |
| microserviceURI = microservice.start().getURI(); |
| DEFAULT_CLIENT = client().build(); |
| DEFAULT_CLIENT_DEBUG = client().debug().build(); |
| DEFAULT_CLIENT_PLAINTEXT = client(PlainTextSerializer.class, PlainTextParser.class).build(); |
| return true; |
| } catch (Throwable e) { |
| System.err.println(e); // NOT DEBUG |
| return false; |
| } |
| } |
| |
| /** |
| * Returns the URI of the microservice. |
| * @return The URI of the microservice. |
| */ |
| public static URI getURI() { |
| if (microservice == null) |
| startMicroservice(); |
| return microserviceURI; |
| } |
| |
| /** |
| * Stops the microservice. |
| */ |
| public static void stopMicroservice() { |
| try { |
| microservice.stop(); |
| microservice = null; |
| DEFAULT_CLIENT.closeQuietly(); |
| DEFAULT_CLIENT_PLAINTEXT.closeQuietly(); |
| |
| } catch (Exception e) { |
| System.err.println(e); // NOT DEBUG |
| } |
| } |
| |
| /** |
| * Create a new HTTP client. |
| */ |
| public static RestClientBuilder client() { |
| try { |
| final RequestLine[] currentRequest = new RequestLine[1]; |
| final StatusLine[] currentResponse = new StatusLine[1]; |
| return new RestClientBuilder() |
| .rootUrl(microserviceURI) |
| .setRetryHandler( |
| new HttpRequestRetryHandler() { |
| @Override |
| public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { |
| System.err.println("*** ERROR ***"); |
| TestMicroservice.jettyDump(currentRequest[0], currentResponse[0]); |
| return (executionCount < 3); |
| } |
| } |
| ) |
| .addInterceptorFirst(new org.apache.http.HttpRequestInterceptor() { |
| @Override |
| public void process(HttpRequest r, HttpContext c) throws HttpException, IOException { |
| currentRequest[0] = r.getRequestLine(); |
| } |
| }) |
| .addInterceptorFirst(new org.apache.http.HttpResponseInterceptor() { |
| @Override |
| public void process(HttpResponse r, HttpContext c) throws HttpException, IOException { |
| currentResponse[0] = r.getStatusLine(); |
| } |
| }) |
| .noTrace() |
| ; |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| /** |
| * Create a new HTTP client using the specified serializer and parser. |
| */ |
| public static RestClientBuilder client(Serializer s, Parser p) { |
| return client().serializer(s).parser(p); |
| } |
| |
| /** |
| * Create a new HTTP client using the specified serializer and parser. |
| */ |
| public static RestClientBuilder client(Class<? extends Serializer> s, Class<? extends Parser> p) { |
| return client().serializer(s).parser(p); |
| } |
| |
| // TODO - Why is this needed? |
| static SSLConnectionSocketFactory getSSLSocketFactory() throws Exception { |
| SSLContext sslContext = SSLContext.getInstance("SSL"); |
| TrustManager tm = new SimpleX509TrustManager(true); |
| sslContext.init(null, new TrustManager[]{tm}, new SecureRandom()); |
| return new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier()); |
| } |
| |
| public static CloseableHttpClient createHttpClient() { |
| try { |
| return HttpClients.custom().setSSLSocketFactory(getSSLSocketFactory()).setRedirectStrategy(new LaxRedirectStrategy()).build(); |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| private static int dumpCount = 0; |
| |
| public static void jettyDump(RequestLine rl, StatusLine sl) { |
| try { |
| String dump = microservice.getServer().dump(); |
| FileWriter fw = new FileWriter(microservice.getConfig().getString("Logging/logDir") + "/jetty-thread-dump-"+(dumpCount++)+".log"); |
| fw.append("RequestLine = [" + rl + "]\n"); |
| fw.append("StatusLine = [" + sl + "]\n"); |
| IOUtils.pipe(dump, fw); |
| fw.flush(); |
| fw.close(); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| } |