/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * 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.kie.server.router.handlers; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.Deque; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange; import io.undertow.server.handlers.ResponseCodeHandler; import io.undertow.util.HeaderValues; import io.undertow.util.Headers; import io.undertow.util.HttpString; import org.kie.server.router.proxy.aggragate.ResponseAggregator; public class QueriesDataHttpHandler extends AbstractAggregateHttpHandler { public QueriesDataHttpHandler(HttpHandler httpHandler, AdminHttpHandler adminHandler) { super(httpHandler, adminHandler); } @Override public void handleRequest(HttpServerExchange exchange) throws Exception { if (exchange.getRequestMethod().equals(HttpString.tryFromString("POST"))) { Map<String, Deque<String>> queryParams = exchange.getQueryParameters(); // collect and alter paging Integer page = 0; Integer pageSize = 10; Deque<String> originalPage = queryParams.get("page"); if (originalPage != null && !originalPage.isEmpty()) { page = Integer.parseInt(originalPage.getFirst()); } Deque<String> originalPageSize = queryParams.remove("pageSize"); if (originalPageSize != null && !originalPageSize.isEmpty()) { pageSize = Integer.parseInt(originalPageSize.getFirst()); } boolean useAdvanced = pageSize.intValue() != -1; final String routerPage = "0"; // need to add 1 to page for proper size of page final String routerPageSize = String.valueOf((1 + page) * pageSize); // collect sorting String sortBy = null; boolean sortOder = true; Deque<String> originalSortBy = queryParams.get("sort"); if (originalSortBy != null && !originalSortBy.isEmpty()) { sortBy = originalSortBy.getFirst(); } Deque<String> originalSortOrder = queryParams.get("sortOrder"); if (originalSortOrder != null && !originalSortOrder.isEmpty()) { sortOder = Boolean.parseBoolean(originalSortOrder.getFirst()); } StringBuilder requestBody = new StringBuilder(); // collect body of the request exchange.getRequestReceiver().receiveFullString((ex, data) -> { requestBody.append(data); }); final String body = requestBody.toString(); final Map<String,List<String>> responseHeaders = new ConcurrentHashMap<>(); List<String> returnResponses = getServerHosts().parallelStream().map(url -> { String response = null; try { response = sendPostRequest(url, body, exchange, responseHeaders, routerPage, routerPageSize); } catch (Exception e) { log.error("Error when forwarding request to server", e); } return response; }) .filter(msg -> msg != null && !msg.trim().isEmpty()) .collect(Collectors.toList()); HeaderValues accept = exchange.getRequestHeaders().get(Headers.ACCEPT); HeaderValues kieContentType = exchange.getRequestHeaders().get("X-KIE-ContentType"); String response = ""; if (returnResponses.size() > 0) { ResponseAggregator responseAggregator = adminHandler.getAggregators().stream().filter(a -> a.supports(kieContentType, accept, DEFAULT_ACCEPT)).findFirst().orElseThrow(() -> new RuntimeException("not possible to find response aggregator for " + responseHeaders.get(Headers.ACCEPT)) ); if (supportAdvancedAggregate() && useAdvanced) { response = responseAggregator.aggregate(returnResponses, sortBy, sortOder, page, pageSize); } else { response = responseAggregator.aggregate(returnResponses); } } responseHeaders.forEach((name, value) -> { exchange.getResponseHeaders().putAll(HttpString.tryFromString(name), value); }); exchange.getResponseHeaders().put(Headers.CONTENT_LENGTH, response.getBytes("UTF-8").length); exchange.getResponseSender().send(response); } else if (exchange.getRequestMethod().equals(HttpString.tryFromString("PUT"))) { StringBuilder requestBody = new StringBuilder(); // collect body of the request exchange.getRequestReceiver().receiveFullString((ex, data) -> { requestBody.append(data); }); final String body = requestBody.toString(); final Map<String,List<String>> responseHeaders = new ConcurrentHashMap<>(); List<String> returnResponses = getServerHosts().parallelStream().map(url -> { String response = null; try { response = sendPutRequest(url, body, exchange, responseHeaders); } catch (Exception e) { log.error("Error when forwarding request to server", e); } return response; }) .filter(msg -> msg != null) .collect(Collectors.toList()); responseHeaders.forEach((name, value) -> { exchange.getResponseHeaders().putAll(HttpString.tryFromString(name), value); }); if (returnResponses.size() == 0) { ResponseCodeHandler.HANDLE_404.handleRequest(exchange); return; } new ResponseCodeHandler(201).handleRequest(exchange); } else if (exchange.getRequestMethod().equals(HttpString.tryFromString("DELETE"))) { final Map<String,List<String>> responseHeaders = new ConcurrentHashMap<>(); getServerHosts().parallelStream().forEach(url -> { try { sendDeleteRequest(url, exchange, responseHeaders); } catch (Exception e) { log.error("Error when forwarding request to server", e); } }); responseHeaders.forEach((name, value) -> { exchange.getResponseHeaders().putAll(HttpString.tryFromString(name), value); }); new ResponseCodeHandler(204).handleRequest(exchange); return; } else { super.handleRequest(exchange); } } protected String sendPostRequest(String url, String body, HttpServerExchange exchange, Map<String,List<String>> responseHeaders, String page, String pageSize) throws Exception { URL obj = new URL(url + exchange.getRequestPath() + "?" + exchange.getQueryString().replaceAll(REPLACE_PAGE, "page=" + page).replaceAll(REPLACE_PAGE_SIZE, "pageSize=" + pageSize)); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); con.setRequestMethod("POST"); //add request headers exchange.getRequestHeaders().forEach(h -> { con.setRequestProperty(h.getHeaderName().toString(), h.getFirst()); }); con.setDoOutput(true); if (body != null) { con.getOutputStream().write(body.getBytes("UTF-8")); } log.debugf("Sending 'POST' request to URL : %s", obj); int responseCode = con.getResponseCode(); log.debugf("Response Code : %s", responseCode); Map<String, List<String>> headers = con.getHeaderFields(); headers.forEach((k, v) -> { if (k != null) { responseHeaders.put(k, v); } }); BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); return response.toString(); } protected String sendPutRequest(String url, String body, HttpServerExchange exchange, Map<String,List<String>> responseHeaders) throws Exception { URL obj = new URL(url + exchange.getRequestPath() + "?" + exchange.getQueryString()); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); con.setRequestMethod("PUT"); //add request headers exchange.getRequestHeaders().forEach(h -> { con.setRequestProperty(h.getHeaderName().toString(), h.getFirst()); }); con.setDoOutput(true); if (body != null) { con.getOutputStream().write(body.getBytes("UTF-8")); } log.debugf("Sending 'PUT' request to URL : %s", obj); int responseCode = con.getResponseCode(); log.debugf("Response Code : %s", responseCode); Map<String, List<String>> headers = con.getHeaderFields(); headers.forEach((k, v) -> { if (k != null) { responseHeaders.put(k, v); } }); BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); return response.toString(); } protected String sendDeleteRequest(String url, HttpServerExchange exchange, Map<String,List<String>> responseHeaders) throws Exception { URL obj = new URL(url + exchange.getRequestPath() + "?" + exchange.getQueryString()); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); con.setRequestMethod("DELETE"); //add request headers exchange.getRequestHeaders().forEach(h -> { con.setRequestProperty(h.getHeaderName().toString(), h.getFirst()); }); con.setDoOutput(true); log.debugf("Sending 'DELETE' request to URL : %s", obj); int responseCode = con.getResponseCode(); log.debugf("Response Code : %s", responseCode); Map<String, List<String>> headers = con.getHeaderFields(); headers.forEach((k, v) -> { if (k != null) { responseHeaders.put(k, v); } }); BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); return response.toString(); } }