From 1c76abf134141cdc889ca7a05240d45605868deb Mon Sep 17 00:00:00 2001 From: Alex Bogdanovski Date: Fri, 16 Feb 2018 12:24:04 +0200 Subject: [PATCH] fixed RestClient not being initialized properly in ProxyResourceHandler, leading to OOME --- .../para/rest/ProxyResourceHandler.java | 38 +++++++++++++------ .../para/rest/ProxyResourceHandlerIT.java | 13 ++++--- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/erudika/para/rest/ProxyResourceHandler.java b/src/main/java/com/erudika/para/rest/ProxyResourceHandler.java index 655603a..5583211 100644 --- a/src/main/java/com/erudika/para/rest/ProxyResourceHandler.java +++ b/src/main/java/com/erudika/para/rest/ProxyResourceHandler.java @@ -71,6 +71,7 @@ public class ProxyResourceHandler implements CustomResourceHandler { private final String esHost = Config.getConfigParam("es.restclient_host", Config.getConfigParam("es.transportclient_host", "localhost")); private final int esPort = Config.getConfigInt("es.restclient_port", 9200); + private RestClient lowLevelClient; /** * Resource path. Defaults to '_elasticsearch'. @@ -112,18 +113,18 @@ Response proxyRequest(String method, ContainerRequestContext ctx) { return Response.status(Response.Status.FORBIDDEN.getStatusCode(), "This feature is disabled.").build(); } String appid = ParaObjectUtils.getAppidFromAuthHeader(ctx.getHeaders().getFirst(HttpHeaders.AUTHORIZATION)); - String path = getCleanPath(getPath(ctx)); if (StringUtils.isBlank(appid)) { return Response.status(Response.Status.BAD_REQUEST).build(); } + String path = getCleanPath(appid, getPath(ctx)); try { - if ("reindex".equals(path) && POST.equals(method)) { + if (path.endsWith("/reindex") && POST.equals(method)) { return handleReindexTask(appid); } Header[] headers = getHeaders(ctx.getHeaders()); HttpEntity resp; - RestClient client = getClient(appid); + RestClient client = getClient(); if (client != null) { if (ctx.getEntityStream() != null && ctx.getEntityStream().available() > 0) { HttpEntity body = new InputStreamEntity(ctx.getEntityStream(), ContentType.APPLICATION_JSON); @@ -143,16 +144,27 @@ Response proxyRequest(String method, ContainerRequestContext ctx) { return Response.status(Response.Status.BAD_REQUEST).build(); } - private RestClient getClient(String appid) { + private RestClient getClient() { + if (lowLevelClient != null) { + return lowLevelClient; + } try { - return RestClient.builder(new HttpHost(esHost, esPort, esScheme)). - // We prefix path with appid in order to route request to the correct index - // for a particular app. Also, append '/' to prevent other mishap. - setPathPrefix(appid.concat("/")).build(); + lowLevelClient = RestClient.builder(new HttpHost(esHost, esPort, esScheme)).build(); + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { + if (lowLevelClient != null) { + try { + lowLevelClient.close(); + } catch (IOException ex) { + logger.error(null, ex); + } + } + } + }); } catch (Exception e) { - logger.error("Failed to build Elasticsearch client for app '{}': {}", appid, e.getMessage()); - return null; + logger.error("Failed to initialize Elasticsearch low-level client: {}", e.getMessage()); } + return lowLevelClient; } private Header[] getHeaders(MultivaluedMap headers) { @@ -174,7 +186,7 @@ private String getPath(ContainerRequestContext ctx) { return StringUtils.isBlank(path) ? "_search" : path; } - String getCleanPath(String path) { + String getCleanPath(String appid, String path) { if (StringUtils.containsIgnoreCase(path, "getRawResponse")) { try { URIBuilder uri = new URIBuilder(path); @@ -191,7 +203,9 @@ String getCleanPath(String path) { logger.warn(null, ex); } } - return StringUtils.isBlank(path) ? "_search" : path; + // We prefix path with appid (alias) in order to route request to the correct index + // for a particular app. Also, append '/' to prevent other mishap. + return appid.concat("/").concat(StringUtils.isBlank(path) ? "_search" : path); } private Response handleReindexTask(String appid) { diff --git a/src/test/java/com/erudika/para/rest/ProxyResourceHandlerIT.java b/src/test/java/com/erudika/para/rest/ProxyResourceHandlerIT.java index e6803e3..6afd12e 100644 --- a/src/test/java/com/erudika/para/rest/ProxyResourceHandlerIT.java +++ b/src/test/java/com/erudika/para/rest/ProxyResourceHandlerIT.java @@ -97,12 +97,13 @@ protected Application configure() { @Test public void testGetCleanPath() { ProxyResourceHandler prh = new ProxyResourceHandler(); - assertEquals(prh.getCleanPath(""), "_search"); - assertEquals(prh.getCleanPath("_search?param=123"), "_search?param=123"); - assertEquals(prh.getCleanPath("_search?param=123¶m2=345"), "_search?param=123¶m2=345"); - assertEquals(prh.getCleanPath("_search?getRawResponse=true¶m2=345"), "_search?param2=345"); - assertEquals(prh.getCleanPath("_search?getRawResponse=1¶m2=345"), "_search?param2=345"); - assertEquals(prh.getCleanPath("_search?getrawresponse=1¶m2=345"), "_search?param2=345"); + String appid = "app"; + assertEquals(prh.getCleanPath(appid, ""), appid + "/_search"); + assertEquals(prh.getCleanPath(appid, "_search?param=123"), appid + "/_search?param=123"); + assertEquals(prh.getCleanPath(appid, "_search?param=123¶m2=345"), appid + "/_search?param=123¶m2=345"); + assertEquals(prh.getCleanPath(appid, "_search?getRawResponse=true¶m2=345"), appid + "/_search?param2=345"); + assertEquals(prh.getCleanPath(appid, "_search?getRawResponse=1¶m2=345"), appid + "/_search?param2=345"); + assertEquals(prh.getCleanPath(appid, "_search?getrawresponse=1¶m2=345"), appid + "/_search?param2=345"); } @Test