X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=restapi-call-node%2Fprovider%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Fccsdk%2Fsli%2Fplugins%2Frestapicall%2FRestapiCallNode.java;h=b4d7e1ba8950d81929b74ef0a1dc6b5eabb9bba8;hb=refs%2Fheads%2Fmaster;hp=adf723b8b219aae382cf90a79c244c10c2b9c85f;hpb=b43008aa2dce75efdf704d1a5e2529e58b4fbde1;p=ccsdk%2Fsli%2Fplugins.git diff --git a/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/RestapiCallNode.java b/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/RestapiCallNode.java index adf723b8..3d704249 100755 --- a/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/RestapiCallNode.java +++ b/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/RestapiCallNode.java @@ -25,15 +25,22 @@ package org.onap.ccsdk.sli.plugins.restapicall; import static java.lang.Boolean.valueOf; import static javax.ws.rs.client.Entity.entity; import static org.onap.ccsdk.sli.plugins.restapicall.AuthType.fromString; +import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.ProtocolException; import java.net.SocketException; import java.net.URI; +import java.net.URL; import java.nio.file.Files; import java.nio.file.Paths; import java.security.KeyStore; import java.util.ArrayList; +import java.util.Base64; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -43,6 +50,8 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; @@ -57,6 +66,7 @@ import javax.ws.rs.core.Feature; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriBuilder; import org.apache.commons.lang3.StringUtils; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; @@ -71,8 +81,13 @@ import org.glassfish.jersey.media.multipart.file.FileDataBodyPart; import org.onap.ccsdk.sli.core.sli.SvcLogicContext; import org.onap.ccsdk.sli.core.sli.SvcLogicException; import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; +import org.onap.logging.filter.base.HttpURLConnectionMetricUtil; +import org.onap.logging.filter.base.MetricLogClientFilter; +import org.onap.logging.filter.base.ONAPComponents; +import org.onap.logging.ref.slf4j.ONAPLogConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.slf4j.MDC; public class RestapiCallNode implements SvcLogicJavaPlugin { @@ -80,6 +95,8 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { protected static final String UEB_PROPERTIES_FILE_NAME = "ueb.properties"; protected static final String DEFAULT_PROPERTIES_DIR = "/opt/onap/ccsdk/data/properties"; protected static final String PROPERTIES_DIR_KEY = "SDNC_CONFIG_DIR"; + protected static final int DEFAULT_HTTP_CONNECT_TIMEOUT_MS = 30000; // 30 seconds + protected static final int DEFAULT_HTTP_READ_TIMEOUT_MS = 600000; // 10 minutes private static final Logger log = LoggerFactory.getLogger(RestapiCallNode.class); private String uebServers; @@ -93,8 +110,11 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { protected static final String restapiUrlString = "restapiUrl"; protected static final String restapiUserKey = "restapiUser"; protected static final String restapiPasswordKey = "restapiPassword"; + protected Integer httpConnectTimeout; + protected Integer httpReadTimeout; protected HashMap partnerStore; + private static final Pattern retryPattern = Pattern.compile(".*,(http|https):.*"); public RestapiCallNode() { String configDir = System.getProperty(PROPERTIES_DIR_KEY, DEFAULT_PROPERTIES_DIR); @@ -105,7 +125,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { loadPartners(partners); log.info("Partners support enabled"); } catch (Exception e) { - log.warn("Partners file could not be read, Partner support will not be enabled.", e); + log.warn("Partners file could not be read, Partner support will not be enabled. " + e.getMessage()); } try (FileInputStream in = new FileInputStream(configDir + "/" + UEB_PROPERTIES_FILE_NAME)) { @@ -114,10 +134,13 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { uebServers = props.getProperty("servers"); log.info("UEB support enabled"); } catch (Exception e) { - log.warn("UEB properties could not be read, UEB support will not be enabled.", e); + log.warn("UEB properties could not be read, UEB support will not be enabled. " + e.getMessage()); } + httpConnectTimeout = readOptionalInteger("HTTP_CONNECT_TIMEOUT_MS",DEFAULT_HTTP_CONNECT_TIMEOUT_MS); + httpReadTimeout = readOptionalInteger("HTTP_READ_TIMEOUT_MS",DEFAULT_HTTP_READ_TIMEOUT_MS); } + @SuppressWarnings("unchecked") protected void loadPartners(JSONObject partners) { Iterator keys = partners.keys(); String partnerUserKey = "user"; @@ -135,7 +158,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { } String userName = partnerObject.getString(partnerUserKey); String password = partnerObject.getString(partnerPasswordKey); - PartnerDetails details = new PartnerDetails(userName, password, url); + PartnerDetails details = new PartnerDetails(userName, getObfuscatedVal(password), url); partnerStore.put(partnerKey, details); log.info("mapped partner using partner key " + partnerKey); } else { @@ -147,6 +170,25 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { } } + /* Unobfuscate param value */ + private static String getObfuscatedVal(String paramValue) { + String resValue = paramValue; + if (paramValue != null && paramValue.startsWith("${") && paramValue.endsWith("}")) + { + String paramStr = paramValue.substring(2, paramValue.length()-1); + if (paramStr != null && paramStr.length() > 0) + { + String val = System.getenv(paramStr); + if (val != null && val.length() > 0) + { + resValue=val; + log.info("Obfuscated value RESET for param value:" + paramValue); + } + } + } + return resValue; + } + /** * Returns parameters from the parameter map. * @@ -160,14 +202,16 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { p.templateFileName = parseParam(paramMap, "templateFileName", false, null); p.requestBody = parseParam(paramMap, "requestBody", false, null); p.restapiUrl = parseParam(paramMap, restapiUrlString, true, null); - validateUrl(p.restapiUrl); p.restapiUrlSuffix = parseParam(paramMap, "restapiUrlSuffix", false, null); - p.restapiUser = parseParam(paramMap, restapiUserKey, false, null); - p.restapiPassword = parseParam(paramMap, restapiPasswordKey, false, null); if (p.restapiUrlSuffix != null) { p.restapiUrl = p.restapiUrl + p.restapiUrlSuffix; - validateUrl(p.restapiUrl); } + + p.restapiUrl = UriBuilder.fromUri(p.restapiUrl).toTemplate(); + validateUrl(p.restapiUrl); + + p.restapiUser = parseParam(paramMap, restapiUserKey, false, null); + p.restapiPassword = parseParam(paramMap, restapiPasswordKey, false, null); p.oAuthConsumerKey = parseParam(paramMap, "oAuthConsumerKey", false, null); p.oAuthConsumerSecret = parseParam(paramMap, "oAuthConsumerSecret", false, null); p.oAuthSignatureMethod = parseParam(paramMap, "oAuthSignatureMethod", false, null); @@ -181,12 +225,9 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { String skipSendingStr = paramMap.get(skipSendingMessage); p.skipSending = "true".equalsIgnoreCase(skipSendingStr); p.convertResponse = valueOf(parseParam(paramMap, "convertResponse", false, "true")); - p.trustStoreFileName = parseParam(paramMap, "trustStoreFileName", false, null); - p.trustStorePassword = parseParam(paramMap, "trustStorePassword", false, null); p.keyStoreFileName = parseParam(paramMap, "keyStoreFileName", false, null); p.keyStorePassword = parseParam(paramMap, "keyStorePassword", false, null); - p.ssl = p.trustStoreFileName != null && p.trustStorePassword != null && p.keyStoreFileName != null - && p.keyStorePassword != null; + p.ssl = p.keyStoreFileName != null && p.keyStorePassword != null; p.customHttpHeaders = parseParam(paramMap, "customHttpHeaders", false, null); p.partner = parseParam(paramMap, "partner", false, null); p.dumpHeaders = valueOf(parseParam(paramMap, "dumpHeaders", false, null)); @@ -194,6 +235,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { p.accept = parseParam(paramMap, "accept", false, null); p.multipartFormData = valueOf(parseParam(paramMap, "multipartFormData", false, "false")); p.multipartFile = parseParam(paramMap, "multipartFile", false, null); + p.targetEntity = parseParam(paramMap, "targetEntity", false, null); return p; } @@ -204,8 +246,8 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { * @throws SvcLogicException when URL validation fails */ private static void validateUrl(String restapiUrl) throws SvcLogicException { - if (restapiUrl.contains(",")) { - String[] urls = restapiUrl.split(","); + if (containsMultipleUrls(restapiUrl)) { + String[] urls = getMultipleUrls(restapiUrl); for (String url : urls) { validateUrl(url); } @@ -246,7 +288,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { * @throws SvcLogicException if required parameter value is empty */ public static String parseParam(Map paramMap, String name, boolean required, String def) - throws SvcLogicException { + throws SvcLogicException { String s = paramMap.get(name); if (s == null || s.trim().length() == 0) { @@ -432,14 +474,17 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { } protected void sendRequest(Map paramMap, SvcLogicContext ctx, RetryPolicy retryPolicy) - throws SvcLogicException { + throws SvcLogicException { - HttpResponse r = new HttpResponse(); + HttpResponse r = new HttpResponse(); try { handlePartner(paramMap); Parameters p = getParameters(paramMap, new Parameters()); - if (p.restapiUrl.contains(",") && retryPolicy == null) { - String[] urls = p.restapiUrl.split(","); + if(p.targetEntity != null && !p.targetEntity.isEmpty()) { + MDC.put(ONAPLogConstants.MDCs.TARGET_ENTITY, p.targetEntity); + } + if (containsMultipleUrls(p.restapiUrl) && retryPolicy == null) { + String[] urls = getMultipleUrls(p.restapiUrl); retryPolicy = new RetryPolicy(urls, urls.length * 2); p.restapiUrl = urls[0]; } @@ -501,7 +546,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { if (retryPolicy.shouldRetry()) { paramMap.put(restapiUrlString, retryString); log.debug("retry attempt {} will use the retry url {}", retryPolicy.getRetryCount(), - retryString); + retryString); sendRequest(paramMap, ctx, retryPolicy); } else { log.debug("Maximum retries reached, won't attempt to retry. Calling setFailureResponseStatus."); @@ -509,7 +554,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { } } catch (Exception ex) { String retryErrorMessage = "Retry attempt " + retryPolicy.getRetryCount() - + "has failed with error message " + ex.getMessage(); + + "has failed with error message " + ex.getMessage(); setFailureResponseStatus(ctx, prefix, retryErrorMessage, r); } } @@ -582,7 +627,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { } String req = format == Format.XML ? XmlJsonUtil.removeEmptyStructXml(ss.toString()) - : XmlJsonUtil.removeEmptyStructJson(originalTemplate, ss.toString()); + : XmlJsonUtil.removeEmptyStructJson(originalTemplate, ss.toString()); if (format == Format.JSON) { req = XmlJsonUtil.removeLastCommaJson(req); @@ -607,7 +652,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { int i2 = template.indexOf(':', i1 + 9); if (i2 < 0) { throw new SvcLogicException( - "Template error: Context variable name followed by : is required after repeat"); + "Template error: Context variable name followed by : is required after repeat"); } // Find the closing }, store in i3 @@ -691,8 +736,8 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { client.register(HttpAuthenticationFeature.basic(p.restapiUser, p.restapiPassword)); } else if (p.oAuthConsumerKey != null && p.oAuthConsumerSecret != null && p.oAuthSignatureMethod != null) { Feature oAuth1Feature = - OAuth1ClientSupport.builder(new ConsumerCredentials(p.oAuthConsumerKey, p.oAuthConsumerSecret)) - .version(p.oAuthVersion).signatureMethod(p.oAuthSignatureMethod).feature().build(); + OAuth1ClientSupport.builder(new ConsumerCredentials(p.oAuthConsumerKey, p.oAuthConsumerSecret)) + .version(p.oAuthVersion).signatureMethod(p.oAuthSignatureMethod).feature().build(); client.register(oAuth1Feature); } @@ -702,30 +747,30 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { client.register(HttpAuthenticationFeature.digest(p.restapiUser, p.restapiPassword)); } else { throw new SvcLogicException( - "oAUTH authentication type selected but all restapiUser and restapiPassword " - + "parameters doesn't exist", - new Throwable()); + "oAUTH authentication type selected but all restapiUser and restapiPassword " + + "parameters doesn't exist", + new Throwable()); } } else if (p.authtype == AuthType.BASIC) { if (p.restapiUser != null && p.restapiPassword != null) { client.register(HttpAuthenticationFeature.basic(p.restapiUser, p.restapiPassword)); } else { throw new SvcLogicException( - "oAUTH authentication type selected but all restapiUser and restapiPassword " - + "parameters doesn't exist", - new Throwable()); + "oAUTH authentication type selected but all restapiUser and restapiPassword " + + "parameters doesn't exist", + new Throwable()); } } else if (p.authtype == AuthType.OAUTH) { if (p.oAuthConsumerKey != null && p.oAuthConsumerSecret != null && p.oAuthSignatureMethod != null) { Feature oAuth1Feature = OAuth1ClientSupport - .builder(new ConsumerCredentials(p.oAuthConsumerKey, p.oAuthConsumerSecret)) - .version(p.oAuthVersion).signatureMethod(p.oAuthSignatureMethod).feature().build(); + .builder(new ConsumerCredentials(p.oAuthConsumerKey, p.oAuthConsumerSecret)) + .version(p.oAuthVersion).signatureMethod(p.oAuthSignatureMethod).feature().build(); client.register(oAuth1Feature); } else { throw new SvcLogicException( - "oAUTH authentication type selected but all oAuthConsumerKey, oAuthConsumerSecret " - + "and oAuthSignatureMethod parameters doesn't exist", - new Throwable()); + "oAUTH authentication type selected but all oAuthConsumerKey, oAuthConsumerSecret " + + "and oAuthSignatureMethod parameters doesn't exist", + new Throwable()); } } } @@ -747,21 +792,19 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { ssl = createSSLContext(p); } Client client; - if (ssl != null) { HttpsURLConnection.setDefaultSSLSocketFactory(ssl.getSocketFactory()); client = ClientBuilder.newBuilder().sslContext(ssl).hostnameVerifier((s, sslSession) -> true).build(); } else { client = ClientBuilder.newBuilder().hostnameVerifier((s, sslSession) -> true).build(); } - client.property(ClientProperties.CONNECT_TIMEOUT, 5000); + + setClientTimeouts(client); // Needed to support additional HTTP methods such as PATCH client.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true); - + client.register(new MetricLogClientFilter()); WebTarget webTarget = addAuthType(client, p).target(p.restapiUrl); - log.info("Sending request below to url " + p.restapiUrl); - log.info(request); long t1 = System.currentTimeMillis(); HttpResponse r = new HttpResponse(); @@ -789,18 +832,24 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { for (String singlePair : keyValuePairs) { int equalPosition = singlePair.indexOf('='); invocationBuilder.header(singlePair.substring(0, equalPosition), - singlePair.substring(equalPosition + 1, singlePair.length())); + singlePair.substring(equalPosition + 1, singlePair.length())); } } - invocationBuilder.header("X-ECOMP-RequestID", org.slf4j.MDC.get("X-ECOMP-RequestID")); - invocationBuilder.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true); Response response; try { - response = invocationBuilder.method(p.httpMethod.toString(), entity(request, contentType)); + // When the HTTP operation has no body do not set the content-type + //setting content-type has caused errors with some servers when no body is present + if (request == null) { + response = invocationBuilder.method(p.httpMethod.toString()); + } else { + log.info("Sending request below to url " + p.restapiUrl); + log.info(request); + response = invocationBuilder.method(p.httpMethod.toString(), entity(request, contentType)); + } } catch (ProcessingException | IllegalStateException e) { throw new SvcLogicException(requestPostingException + e.getLocalizedMessage(), e); } @@ -822,7 +871,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { multiPart.setMediaType(MediaType.MULTIPART_FORM_DATA_TYPE); FileDataBodyPart fileDataBodyPart = - new FileDataBodyPart("file", new File(p.multipartFile), MediaType.APPLICATION_OCTET_STREAM_TYPE); + new FileDataBodyPart("file", new File(p.multipartFile), MediaType.APPLICATION_OCTET_STREAM_TYPE); multiPart.bodyPart(fileDataBodyPart); @@ -837,17 +886,15 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { for (String singlePair : keyValuePairs) { int equalPosition = singlePair.indexOf('='); invocationBuilder.header(singlePair.substring(0, equalPosition), - singlePair.substring(equalPosition + 1, singlePair.length())); + singlePair.substring(equalPosition + 1, singlePair.length())); } } - invocationBuilder.header("X-ECOMP-RequestID", org.slf4j.MDC.get("X-ECOMP-RequestID")); - Response response; try { response = - invocationBuilder.method(p.httpMethod.toString(), entity(multiPart, multiPart.getMediaType())); + invocationBuilder.method(p.httpMethod.toString(), entity(multiPart, multiPart.getMediaType())); } catch (ProcessingException | IllegalStateException e) { throw new SvcLogicException(requestPostingException + e.getLocalizedMessage(), e); } @@ -876,18 +923,12 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { protected SSLContext createSSLContext(Parameters p) { try (FileInputStream in = new FileInputStream(p.keyStoreFileName)) { - System.setProperty("jsse.enableSNIExtension", "false"); - System.setProperty("javax.net.ssl.trustStore", p.trustStoreFileName); - System.setProperty("javax.net.ssl.trustStorePassword", p.trustStorePassword); - HttpsURLConnection.setDefaultHostnameVerifier((string, ssls) -> true); - KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); KeyStore ks = KeyStore.getInstance("PKCS12"); char[] pwd = p.keyStorePassword.toCharArray(); ks.load(in, pwd); kmf.init(ks, pwd); - SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(kmf.getKeyManagers(), null, null); return ctx; @@ -898,7 +939,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { } protected void setFailureResponseStatus(SvcLogicContext ctx, String prefix, String errorMessage, - HttpResponse resp) { + HttpResponse resp) { resp.code = 500; resp.message = errorMessage; String pp = prefix != null ? prefix + '.' : ""; @@ -919,6 +960,16 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { byte[] data = Files.readAllBytes(Paths.get(p.fileName)); r = sendHttpData(data, p); + + for (int i = 0; i < 10 && r.code == 301; i++) { + String newUrl = r.headers2.get("Location").get(0); + + log.info("Got response code 301. Sending same request to URL: " + newUrl); + + p.url = newUrl; + r = sendHttpData(data, p); + } + setResponseStatus(ctx, p.responsePrefix, r); } catch (SvcLogicException | IOException e) { @@ -993,12 +1044,27 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { } } - protected HttpResponse sendHttpData(byte[] data, FileParam p) throws SvcLogicException { + protected HttpResponse sendHttpData(byte[] data, FileParam p) throws IOException { + URL url = new URL(p.url); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); - Client client = ClientBuilder.newBuilder().build(); - client.property(ClientProperties.CONNECT_TIMEOUT, 5000); - client.property(ClientProperties.FOLLOW_REDIRECTS, true); - WebTarget webTarget = addAuthType(client, p).target(p.url); + log.info("Connection: " + con.getClass().getName()); + + con.setRequestMethod(p.httpMethod.toString()); + con.setRequestProperty("Content-Type", "application/octet-stream"); + con.setRequestProperty("Accept", "*/*"); + con.setRequestProperty("Expect", "100-continue"); + con.setFixedLengthStreamingMode(data.length); + con.setInstanceFollowRedirects(false); + + if (p.user != null && p.password != null) { + String authString = p.user + ":" + p.password; + String authStringEnc = Base64.getEncoder().encodeToString(authString.getBytes()); + con.setRequestProperty("Authorization", "Basic " + authStringEnc); + } + + con.setDoInput(true); + con.setDoOutput(true); log.info("Sending file"); long t1 = System.currentTimeMillis(); @@ -1007,69 +1073,46 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { r.code = 200; if (!p.skipSending) { - String tt = "application/octet-stream"; - Invocation.Builder invocationBuilder = webTarget.request(tt).accept(tt); + HttpURLConnectionMetricUtil util = new HttpURLConnectionMetricUtil(); + util.logBefore(con, ONAPComponents.DMAAP); - Response response; + con.connect(); + boolean continue100failed = false; try { - if (p.httpMethod == HttpMethod.POST) { - response = invocationBuilder.post(Entity.entity(data, tt)); - } else if (p.httpMethod == HttpMethod.PUT) { - response = invocationBuilder.put(Entity.entity(data, tt)); - } else { - throw new SvcLogicException("Http operation" + p.httpMethod + "not supported"); - } - } catch (ProcessingException e) { - throw new SvcLogicException(requestPostingException + e.getLocalizedMessage(), e); - } - - r.code = response.getStatus(); - r.headers = response.getStringHeaders(); - EntityTag etag = response.getEntityTag(); - if (etag != null) { - r.message = etag.getValue(); - } - if (response.hasEntity() && r.code != 204) { - r.body = response.readEntity(String.class); + OutputStream os = con.getOutputStream(); + os.write(data); + os.flush(); + os.close(); + } catch (ProtocolException e) { + continue100failed = true; } - if (r.code == 301) { - String newUrl = response.getStringHeaders().getFirst("Location"); - - log.info("Got response code 301. Sending same request to URL: {}", newUrl); + r.code = con.getResponseCode(); + r.headers2 = con.getHeaderFields(); - webTarget = client.target(newUrl); - invocationBuilder = webTarget.request(tt).accept(tt); - - try { - if (p.httpMethod == HttpMethod.POST) { - response = invocationBuilder.post(Entity.entity(data, tt)); - } else if (p.httpMethod == HttpMethod.PUT) { - response = invocationBuilder.put(Entity.entity(data, tt)); - } else { - throw new SvcLogicException("Http operation" + p.httpMethod + "not supported"); - } - } catch (ProcessingException e) { - throw new SvcLogicException(requestPostingException + e.getLocalizedMessage(), e); + if (r.code != 204 && !continue100failed) { + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuffer response = new StringBuffer(); + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); } + in.close(); - r.code = response.getStatus(); - etag = response.getEntityTag(); - if (etag != null) { - r.message = etag.getValue(); - } - if (response.hasEntity() && r.code != 204) { - r.body = response.readEntity(String.class); - } + r.body = response.toString(); } + + util.logAfter(con); + + con.disconnect(); } long t2 = System.currentTimeMillis(); - log.info(responseReceivedMessage, t2 - t1); - log.info(responseHttpCodeMessage, r.code); + log.info("Response received. Time: {}", t2 - t1); + log.info("HTTP response code: {}", r.code); log.info("HTTP response message: {}", r.message); - logHeaders(r.headers); + logHeaders(r.headers2); log.info("HTTP response: {}", r.body); return r; @@ -1117,6 +1160,26 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { } } + private void logHeaders(Map> mm) { + if (mm == null || mm.isEmpty()) { + return; + } + + List ll = new ArrayList<>(); + for (String s : mm.keySet()) { + if (s != null) { + ll.add(s); + } + } + Collections.sort(ll); + + for (String name : ll) { + List v = mm.get(name); + log.info("--- {}:{}", name, String.valueOf(mm.get(name))); + log.info("--- " + name + ": " + (v.size() == 1 ? v.get(0) : v)); + } + } + protected HttpResponse postOnUeb(String request, UebParam p) throws SvcLogicException { String[] urls = uebServers.split(" "); for (int i = 0; i < urls.length; i++) { @@ -1127,7 +1190,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { } Client client = ClientBuilder.newBuilder().build(); - client.property(ClientProperties.CONNECT_TIMEOUT, 5000); + setClientTimeouts(client); WebTarget webTarget = client.target(urls[0]); log.info("UEB URL: {}", urls[0]); @@ -1174,6 +1237,48 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { this.defaultUebTemplateFileName = defaultUebTemplateFileName; } + protected void setClientTimeouts(Client client) { + client.property(ClientProperties.CONNECT_TIMEOUT, httpConnectTimeout); + client.property(ClientProperties.READ_TIMEOUT, httpReadTimeout); + } + + protected Integer readOptionalInteger(String propertyName, Integer defaultValue) { + String stringValue = System.getProperty(propertyName); + if (stringValue != null && stringValue.length() > 0) { + try { + return Integer.valueOf(stringValue); + } catch (NumberFormatException e) { + log.warn("property " + propertyName + " had the value " + stringValue + " that could not be converted to an Integer, default " + defaultValue + " will be used instead", e); + } + } + return defaultValue; + } + + protected static String[] getMultipleUrls(String restapiUrl) { + List urls = new ArrayList<>(); + int start = 0; + for (int i = 0; i < restapiUrl.length(); i++) { + if (restapiUrl.charAt(i) == ',') { + if (i + 9 < restapiUrl.length()) { + String part = restapiUrl.substring(i + 1, i + 9); + if (part.equals("https://") || part.startsWith("http://")) { + urls.add(restapiUrl.substring(start, i)); + start = i + 1; + } + } + } else if (i == restapiUrl.length() - 1) { + urls.add(restapiUrl.substring(start, i + 1)); + } + } + String[] arr = new String[urls.size()]; + return urls.toArray(arr); + } + + protected static boolean containsMultipleUrls(String restapiUrl) { + Matcher m = retryPattern.matcher(restapiUrl); + return m.matches(); + } + private static class FileParam { public String fileName;