From 64aef943514f2badaeb91744d1004c35a57adf4c Mon Sep 17 00:00:00 2001 From: Vidyashree Rama Date: Thu, 25 Oct 2018 09:31:30 +0530 Subject: Add authorization header in SSE request Add authorization header in SSE request to support https Issue-ID: DCAEGEN2-918 Change-Id: I64e1caf98dab34040b58454f656d65b9245c2021 Signed-off-by: Vidyashree Rama --- etc/access-token.json | 4 + etc/collector.properties | 6 + etc/establish-subscription-input-template.json | 4 +- pom.xml | 10 ++ .../restconf/common/AdditionalHeaderWebTarget.java | 157 ++++++++++++++++++ .../dcae/collectors/restconf/common/Constants.java | 6 + .../restconf/common/RestConfCollector.java | 12 +- .../collectors/restconf/common/RestConfProc.java | 112 +++++++++++-- .../restconf/common/RestapiCallNode.java | 95 +---------- .../restconf/common/RestapiCallNodeUtil.java | 178 +++++++++++++++++++++ .../restconf/restconftest/RestConfProcTest.java | 4 + 11 files changed, 482 insertions(+), 106 deletions(-) create mode 100755 etc/access-token.json create mode 100644 src/main/java/org/onap/dcae/collectors/restconf/common/AdditionalHeaderWebTarget.java create mode 100755 src/main/java/org/onap/dcae/collectors/restconf/common/RestapiCallNodeUtil.java diff --git a/etc/access-token.json b/etc/access-token.json new file mode 100755 index 0000000..6fc9fbb --- /dev/null +++ b/etc/access-token.json @@ -0,0 +1,4 @@ +{ + "userName" : "test123", + "password" : "Changeme_123" +} diff --git a/etc/collector.properties b/etc/collector.properties index a013578..6907e88 100755 --- a/etc/collector.properties +++ b/etc/collector.properties @@ -20,3 +20,9 @@ responsePrefix=restapi-result skipSending=false sseConnectURL=http://10.0.4.1:8080/RestConfServer/rest/ssevents; http://10.0.4.2:8080/RestConfServer/rest/ssevents format=json +restapiUser=access +restapiPassword=Huawei@123 +trustStoreFileName=./etc/truststore1.openecomp.client.jks;./etc/truststore2.openecomp.client.jks +trustStorePassword=adminadmin +keyStoreFileName=./etc/sotn1.p12;./etc/ctrl2.p12 +keyStorePassword=adminadmin diff --git a/etc/establish-subscription-input-template.json b/etc/establish-subscription-input-template.json index c47ba01..5273683 100755 --- a/etc/establish-subscription-input-template.json +++ b/etc/establish-subscription-input-template.json @@ -1,5 +1,5 @@ { - "ietf-subscribed-notification:input": { - "encoding": "encoding-json" + "ietf-subscribed-notifications:input": { + "encoding": "encode-json" } } diff --git a/pom.xml b/pom.xml index f0efa8f..9a78d0f 100755 --- a/pom.xml +++ b/pom.xml @@ -322,6 +322,16 @@ 3.8.0 test + + org.glassfish.jersey.security + oauth1-client + 2.27 + + + org.glassfish.jersey.security + oauth1-signature + 2.27 + diff --git a/src/main/java/org/onap/dcae/collectors/restconf/common/AdditionalHeaderWebTarget.java b/src/main/java/org/onap/dcae/collectors/restconf/common/AdditionalHeaderWebTarget.java new file mode 100644 index 0000000..81a658d --- /dev/null +++ b/src/main/java/org/onap/dcae/collectors/restconf/common/AdditionalHeaderWebTarget.java @@ -0,0 +1,157 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Huawei. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.dcae.collectors.restconf.common; + +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Configuration; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriBuilder; +import java.net.URI; +import java.util.Map; + +class AdditionalHeaderWebTarget implements WebTarget { + private WebTarget base; + private String token; + + public AdditionalHeaderWebTarget(WebTarget target, String token) { + base = target; + this.token = token; + } + + @Override + public Invocation.Builder request() { + return base.request().header("X-ACCESS-TOKEN", token); + } + + @Override + public Invocation.Builder request(String... acceptedResponseTypes) { + return base.request().header("X-ACCESS-TOKEN", token); + } + + @Override + public Invocation.Builder request(MediaType... acceptedResponseTypes) { + return base.request().header("X-ACCESS-TOKEN", token); + } + + @Override + public Configuration getConfiguration() { + return base.getConfiguration(); + } + + @Override + public URI getUri() { + return base.getUri(); + } + + @Override + public UriBuilder getUriBuilder() { + return base.getUriBuilder(); + } + + @Override + public WebTarget path(String path) { + return base.path(path); + } + + @Override + public WebTarget resolveTemplate(String name, Object value) { + return base.resolveTemplate(name, value); + } + + @Override + public WebTarget resolveTemplate(String name, Object value, boolean encodeSlashInPath) { + return base.resolveTemplate(name, value, encodeSlashInPath); + } + + @Override + public WebTarget resolveTemplateFromEncoded(String name, Object value) { + return base.resolveTemplateFromEncoded(name, value); + } + + @Override + public WebTarget resolveTemplates(Map templateValues) { + return base.resolveTemplates(templateValues); + } + + @Override + public WebTarget resolveTemplates(Map templateValues, boolean encodeSlashInPath) { + return base.resolveTemplates(templateValues, encodeSlashInPath); + } + + @Override + public WebTarget resolveTemplatesFromEncoded(Map templateValues) { + return base.resolveTemplatesFromEncoded(templateValues); + } + + @Override + public WebTarget matrixParam(String name, Object... values) { + return base.matrixParam(name, values); + } + + @Override + public WebTarget queryParam(String name, Object... values) { + return base.queryParam(name, values); + } + + @Override + public WebTarget property(String name, Object value) { + return base.property(name, value); + } + + @Override + public WebTarget register(Class componentClass) { + return base.register(componentClass); + } + + @Override + public WebTarget register(Class componentClass, int priority) { + return base.register(componentClass, priority); + } + + @Override + public WebTarget register(Class componentClass, Class... contracts) { + return base.register(componentClass, contracts); + } + + @Override + public WebTarget register(Class componentClass, Map, Integer> contracts) { + return base.register(componentClass, contracts); + } + + @Override + public WebTarget register(Object component) { + return base.register(component); + } + + @Override + public WebTarget register(Object component, int priority) { + return base.register(component, priority); + } + + @Override + public WebTarget register(Object component, Class... contracts) { + return base.register(component, contracts); + } + + @Override + public WebTarget register(Object component, Map, Integer> contracts) { + return base.register(component, contracts); + } +} diff --git a/src/main/java/org/onap/dcae/collectors/restconf/common/Constants.java b/src/main/java/org/onap/dcae/collectors/restconf/common/Constants.java index 92266b3..5f8925d 100755 --- a/src/main/java/org/onap/dcae/collectors/restconf/common/Constants.java +++ b/src/main/java/org/onap/dcae/collectors/restconf/common/Constants.java @@ -35,4 +35,10 @@ public class Constants { public static final String OUTPUT_IDENTIFIER = "restapi-result.ietf-subscribed-notifications:output.identifier"; public static final String RESPONSE_CODE_200 = "200"; public static final String KCONFIG = "c"; + public static final String KSETTING_UNAME = "restapiUser"; + public static final String KSETTING_PASSWORD = "restapiPassword"; + public static final String KSETTING_TRUST_STORE_FILENAME = "trustStoreFileName"; + public static final String KSETTING_TRUST_STORE_PASSWORD = "trustStorePassword"; + public static final String KSETTING_KEY_STORE_FILENAME = "keyStoreFileName"; + public static final String KSETTING_KEY_STORE_PASSWORD = "keyStorePassword"; } diff --git a/src/main/java/org/onap/dcae/collectors/restconf/common/RestConfCollector.java b/src/main/java/org/onap/dcae/collectors/restconf/common/RestConfCollector.java index 4d380e6..508cf66 100755 --- a/src/main/java/org/onap/dcae/collectors/restconf/common/RestConfCollector.java +++ b/src/main/java/org/onap/dcae/collectors/restconf/common/RestConfCollector.java @@ -49,13 +49,19 @@ public class RestConfCollector { Map paraMap = restConfProc.getParaMap(); String restApiURL = paraMap.get(Constants.KSETTING_REST_API_URL); String sseEventsURL = paraMap.get(Constants.KSETTING_SSE_CONNECT_URL); + String trustStoreFileName = paraMap.get(Constants.KSETTING_TRUST_STORE_FILENAME); + String keyStoreFileName = paraMap.get(Constants.KSETTING_KEY_STORE_FILENAME); String[] listRestApiURL = restApiURL.split(";"); String[] listSseEventsURL = sseEventsURL.split(";"); + String[] listTrustStoreFileName = trustStoreFileName.split(";"); + String[] listKeyStoreFileName = keyStoreFileName.split(";"); for (int i = 0; i < listRestApiURL.length; i++) { - paraMap.put(Constants.KSETTING_REST_API_URL, "http://" + listRestApiURL[i] + - "/RestConfServer/rest/operations/establish-subscription"); + paraMap.put(Constants.KSETTING_REST_API_URL, "https://" + listRestApiURL[i] + + "/restconf/operations/ietf-subscribed-notifications:establish-subscription"); paraMap.put(Constants.KSETTING_SSE_CONNECT_URL, listSseEventsURL[i]); - restConfProc.establishSubscription(paraMap, restConfProc.getCtx()); + paraMap.put(Constants.KSETTING_TRUST_STORE_FILENAME, listTrustStoreFileName[i]); + paraMap.put(Constants.KSETTING_KEY_STORE_FILENAME, listKeyStoreFileName[i]); + restConfProc.establishSubscription(paraMap, restConfProc.getCtx(), listRestApiURL[i]); } } catch (Exception e) { diff --git a/src/main/java/org/onap/dcae/collectors/restconf/common/RestConfProc.java b/src/main/java/org/onap/dcae/collectors/restconf/common/RestConfProc.java index 0e2c73e..4b3154c 100755 --- a/src/main/java/org/onap/dcae/collectors/restconf/common/RestConfProc.java +++ b/src/main/java/org/onap/dcae/collectors/restconf/common/RestConfProc.java @@ -30,10 +30,17 @@ import org.onap.dcae.collectors.restconf.common.event.publishing.EventPublisher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.WebTarget; import java.nio.file.Paths; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -41,6 +48,8 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; +import static org.onap.dcae.collectors.restconf.common.RestapiCallNodeUtil.addAuthType; +import static org.onap.dcae.collectors.restconf.common.RestapiCallNodeUtil.getParameters; public class RestConfProc { @@ -72,6 +81,12 @@ public class RestConfProc { String respPrefix; String skipSending; String sseConnectUrl; + String restapiUser; + String restapiPassword; + String trustStoreFileName; + String trustStorePassword; + String keyStoreFileName; + String keyStorePassword; String[] currentConfigFile; currentConfigFile = settings.getStrings(Constants.KSETTING_DMAAPCONFIGS, Constants.KDEFAULT_DMAAPCONFIGS); @@ -83,6 +98,12 @@ public class RestConfProc { respPrefix = settings.getString(Constants.KSETTING_RESP_PREFIX, null); skipSending = settings.getString(Constants.KSETTING_SKIP_SENDING, null); sseConnectUrl = settings.getString(Constants.KSETTING_SSE_CONNECT_URL, null); + restapiUser = settings.getString(Constants.KSETTING_UNAME, null); + restapiPassword = settings.getString(Constants.KSETTING_PASSWORD, null); + trustStoreFileName = settings.getString(Constants.KSETTING_TRUST_STORE_FILENAME, null); + trustStorePassword = settings.getString(Constants.KSETTING_TRUST_STORE_PASSWORD, null); + keyStoreFileName = settings.getString(Constants.KSETTING_KEY_STORE_FILENAME, null); + keyStorePassword = settings.getString(Constants.KSETTING_KEY_STORE_PASSWORD, null); format = settings.getString(Constants.KSETTING_FORMAT, null); streamID = "route=route_failure"; @@ -93,6 +114,12 @@ public class RestConfProc { paraMap.put(Constants.KSETTING_SKIP_SENDING, skipSending); paraMap.put(Constants.KSETTING_SSE_CONNECT_URL, sseConnectUrl); paraMap.put(Constants.KSETTING_FORMAT, format); + paraMap.put(Constants.KSETTING_UNAME, restapiUser); + paraMap.put(Constants.KSETTING_PASSWORD, restapiPassword); + paraMap.put(Constants.KSETTING_TRUST_STORE_FILENAME, trustStoreFileName); + paraMap.put(Constants.KSETTING_TRUST_STORE_PASSWORD, trustStorePassword); + paraMap.put(Constants.KSETTING_KEY_STORE_FILENAME, keyStoreFileName); + paraMap.put(Constants.KSETTING_KEY_STORE_PASSWORD, keyStorePassword); ctx.setAttribute("prop.encoding-json", "encoding-json"); ctx.setAttribute("restapi-result.response-code", "200"); @@ -120,12 +147,41 @@ public class RestConfProc { * * @param paramMap holds the input configuration * @param ctx restconf context + * @param url url to send subscription request * @throws Exception exception */ - public void establishSubscription(Map paramMap, RestConfContext ctx) throws Exception { + public void establishSubscription(Map paramMap, + RestConfContext ctx, + String url) throws Exception { RestapiCallNode restApiCallNode = new RestapiCallNode(); + Map params = new HashMap<>(); + params.put("restapiUrl", "https://" + url + "/controller/v2/tokens"); + params.put("httpMethod", "post"); + params.put("templateFileName", "./etc/access-token.json"); + params.put("skipSending", "false"); + params.put("format", "json"); + params.put("restapiUser", "test123"); + params.put("restapiPassword", "Changeme_123"); + params.put(Constants.KSETTING_TRUST_STORE_FILENAME, + paramMap.get(Constants.KSETTING_TRUST_STORE_FILENAME)); + params.put(Constants.KSETTING_TRUST_STORE_PASSWORD, "adminadmin"); + params.put(Constants.KSETTING_KEY_STORE_FILENAME, + paramMap.get(Constants.KSETTING_KEY_STORE_FILENAME)); + params.put(Constants.KSETTING_KEY_STORE_PASSWORD, "adminadmin"); + + restApiCallNode.sendRequest(params, ctx, null); + log.debug("ctx response" + ctx); + String httpResponse = ctx.getAttribute("httpResponse"); + JSONObject jsonObj = new JSONObject(httpResponse); + log.debug("http response" + httpResponse); + JSONObject data = jsonObj.getJSONObject("data"); + String tokenId = data.get("token_id").toString(); + + paramMap.put("customHttpHeaders", "X-ACCESS-TOKEN=" + tokenId); + paramMap.put("TokenId", tokenId); + restApiCallNode.sendRequest(paramMap, ctx, null); establishPersistentConnection(paramMap, ctx); @@ -146,7 +202,7 @@ public class RestConfProc { String url = paramMap.get(Constants.KSETTING_SSE_CONNECT_URL); - PersistentConnection connection = new PersistentConnection(url, ctx); + PersistentConnection connection = new PersistentConnection(url, ctx, paramMap); runnableInfo.put(id, connection); executor.execute(connection); } else { @@ -177,27 +233,39 @@ public class RestConfProc { public class PersistentConnection implements Runnable { private String url; private RestConfContext ctx; + private Map paramMap; private volatile boolean running = true; - public PersistentConnection(String url, RestConfContext ctx) { + public PersistentConnection(String url, RestConfContext ctx, Map paramMap) { this.url = url; this.ctx = ctx; + this.paramMap = paramMap; } @Override public void run() { - Client client = ClientBuilder.newBuilder() - .register(SseFeature.class).build(); - WebTarget target = client.target(url); - EventSource eventSource = EventSource.target(target).build(); + Parameters p = null; + try { + p = getParameters(paramMap); + } catch (Exception e) { + log.error("Exception occured!", e); + Thread.currentThread().interrupt(); + } + + Client client = ignoreSslClient().register(SseFeature.class); + WebTarget target = addAuthType(client, p).target(url); + AdditionalHeaderWebTarget newTarget = new AdditionalHeaderWebTarget(target, paramMap.get("TokenId")); + EventSource eventSource = EventSource.target(newTarget).build(); eventSource.register(new DataChangeEventListener(ctx)); eventSource.open(); - log.info("Connected to SSE source"); + log.debug("Connected to SSE source"); while (running) { try { + log.debug("SSE state " + eventSource.isOpen()); Thread.sleep(5000); } catch (InterruptedException ie) { - log.info("Exception: " + ie.getMessage()); + log.debug("Exception: " + ie.getMessage()); + Thread.currentThread().interrupt(); } } eventSource.close(); @@ -219,6 +287,32 @@ public class RestConfProc { } log.debug("RestConfCollector.handleEvents:EVENTS has been published successfully!"); } + + private Client ignoreSslClient() { + SSLContext sslcontext = null; + + try { + sslcontext = SSLContext.getInstance("TLS"); + sslcontext.init(null, new TrustManager[]{new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { + } + + @Override + public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + } }, new java.security.SecureRandom()); + } catch (NoSuchAlgorithmException | KeyManagementException e) { + throw new IllegalStateException(e); + } + + return ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier((s1, s2) -> true).build(); + } } diff --git a/src/main/java/org/onap/dcae/collectors/restconf/common/RestapiCallNode.java b/src/main/java/org/onap/dcae/collectors/restconf/common/RestapiCallNode.java index 82acc0c..c7310d4 100755 --- a/src/main/java/org/onap/dcae/collectors/restconf/common/RestapiCallNode.java +++ b/src/main/java/org/onap/dcae/collectors/restconf/common/RestapiCallNode.java @@ -54,10 +54,11 @@ import java.security.KeyStore; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; + +import static org.onap.dcae.collectors.restconf.common.RestapiCallNodeUtil.getParameters; +import static org.onap.dcae.collectors.restconf.common.RestapiCallNodeUtil.parseParam; public class RestapiCallNode { private static final Logger log = LoggerFactory.getLogger(RestapiCallNode.class); @@ -157,96 +158,6 @@ public class RestapiCallNode { } } - protected Parameters getParameters(Map paramMap) throws Exception { - Parameters p = new Parameters(); - p.templateFileName = parseParam(paramMap, "templateFileName", false, null); - p.requestBody = parseParam(paramMap, "requestBody", false, null); - p.restapiUrl = parseParam(paramMap, "restapiUrl", true, null); - validateUrl(p.restapiUrl); - p.restapiUser = parseParam(paramMap, "restapiUser", false, null); - p.restapiPassword = parseParam(paramMap, "restapiPassword", false, null); - p.oAuthConsumerKey = parseParam(paramMap, "oAuthConsumerKey", false, null); - p.oAuthConsumerSecret = parseParam(paramMap, "oAuthConsumerSecret", false, null); - p.oAuthSignatureMethod = parseParam(paramMap, "oAuthSignatureMethod", false, null); - p.oAuthVersion = parseParam(paramMap, "oAuthVersion", false, null); - p.contentType = parseParam(paramMap, "contentType", false, null); - p.format = Format.fromString(parseParam(paramMap, "format", false, "json")); - p.authtype = AuthType.fromString(parseParam(paramMap, "authType", false, "unspecified")); - p.httpMethod = HttpMethod.fromString(parseParam(paramMap, "httpMethod", false, "post")); - p.responsePrefix = parseParam(paramMap, "responsePrefix", false, null); - p.listNameList = getListNameList(paramMap); - String skipSendingStr = paramMap.get("skipSending"); - p.skipSending = "true".equalsIgnoreCase(skipSendingStr); - p.convertResponse = Boolean.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.customHttpHeaders = parseParam(paramMap, "customHttpHeaders", false, null); - p.partner = parseParam(paramMap, "partner", false, null); - p.dumpHeaders = Boolean.valueOf(parseParam(paramMap, "dumpHeaders", false, null)); - p.returnRequestPayload = Boolean.valueOf(parseParam(paramMap, "returnRequestPayload", false, null)); - return p; - } - - private void validateUrl(String restapiUrl) throws Exception { - try { - URI.create(restapiUrl); - } catch (IllegalArgumentException e) { - throw new Exception("Invalid input of url " + e.getLocalizedMessage(), e); - } - } - - protected Set getListNameList(Map paramMap) { - Set ll = new HashSet<>(); - for (Map.Entry entry : paramMap.entrySet()) - if (entry.getKey().startsWith("listName")) { - ll.add(entry.getValue()); - } - return ll; - } - - protected String parseParam(Map paramMap, String name, boolean required, String def) - throws Exception { - String s = paramMap.get(name); - - if (s == null || s.trim().length() == 0) { - if (!required) { - return def; - } - throw new Exception("Parameter " + name + " is required in RestapiCallNode"); - } - - s = s.trim(); - StringBuilder value = new StringBuilder(); - int i = 0; - int i1 = s.indexOf('%'); - while (i1 >= 0) { - int i2 = s.indexOf('%', i1 + 1); - if (i2 < 0) { - break; - } - - String varName = s.substring(i1 + 1, i2); - String varValue = System.getenv(varName); - if (varValue == null) { - varValue = "%" + varName + "%"; - } - - value.append(s.substring(i, i1)); - value.append(varValue); - - i = i2 + 1; - i1 = s.indexOf('%', i); - } - value.append(s.substring(i)); - - log.info("Parameter {}: [{}]", name, value); - return value.toString(); - } - protected String buildXmlJsonRequest(RestConfContext ctx, String template, Format format) throws Exception { log.info("Building {} started", format); long t1 = System.currentTimeMillis(); diff --git a/src/main/java/org/onap/dcae/collectors/restconf/common/RestapiCallNodeUtil.java b/src/main/java/org/onap/dcae/collectors/restconf/common/RestapiCallNodeUtil.java new file mode 100755 index 0000000..0e1d03b --- /dev/null +++ b/src/main/java/org/onap/dcae/collectors/restconf/common/RestapiCallNodeUtil.java @@ -0,0 +1,178 @@ +/*- + * ============LICENSE_START======================================================= + * org.onap.dcaegen2.collectors.restconf + * ================================================================================ + * Copyright (C) 2018 Huawei. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.dcae.collectors.restconf.common; + +import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; +import org.glassfish.jersey.client.oauth1.ConsumerCredentials; +import org.glassfish.jersey.client.oauth1.OAuth1ClientSupport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ws.rs.client.Client; +import javax.ws.rs.core.Feature; +import java.net.URI; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class RestapiCallNodeUtil { + + private static final Logger log = LoggerFactory.getLogger(RestapiCallNodeUtil.class); + + private RestapiCallNodeUtil() { + // Preventing instantiation of the same. + } + + public static Parameters getParameters(Map paramMap) throws Exception { + Parameters p = new Parameters(); + p.templateFileName = parseParam(paramMap, "templateFileName", false, null); + p.requestBody = parseParam(paramMap, "requestBody", false, null); + p.restapiUrl = parseParam(paramMap, "restapiUrl", true, null); + validateUrl(p.restapiUrl); + p.restapiUser = parseParam(paramMap, "restapiUser", false, null); + p.restapiPassword = parseParam(paramMap, "restapiPassword", false, null); + p.oAuthConsumerKey = parseParam(paramMap, "oAuthConsumerKey", false, null); + p.oAuthConsumerSecret = parseParam(paramMap, "oAuthConsumerSecret", false, null); + p.oAuthSignatureMethod = parseParam(paramMap, "oAuthSignatureMethod", false, null); + p.oAuthVersion = parseParam(paramMap, "oAuthVersion", false, null); + p.contentType = parseParam(paramMap, "contentType", false, null); + p.format = Format.fromString(parseParam(paramMap, "format", false, "json")); + p.authtype = AuthType.fromString(parseParam(paramMap, "authType", false, "unspecified")); + p.httpMethod = HttpMethod.fromString(parseParam(paramMap, "httpMethod", false, "post")); + p.responsePrefix = parseParam(paramMap, "responsePrefix", false, null); + p.listNameList = getListNameList(paramMap); + String skipSendingStr = paramMap.get("skipSending"); + p.skipSending = "true".equalsIgnoreCase(skipSendingStr); + p.convertResponse = Boolean.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.customHttpHeaders = parseParam(paramMap, "customHttpHeaders", false, null); + p.partner = parseParam(paramMap, "partner", false, null); + p.dumpHeaders = Boolean.valueOf(parseParam(paramMap, "dumpHeaders", false, null)); + p.returnRequestPayload = Boolean.valueOf(parseParam(paramMap, "returnRequestPayload", false, null)); + return p; + } + + public static String parseParam(Map paramMap, String name, boolean required, String def) + throws Exception { + String s = paramMap.get(name); + + if (s == null || s.trim().length() == 0) { + if (!required) { + return def; + } + throw new Exception("Parameter " + name + " is required in RestapiCallNode"); + } + + s = s.trim(); + StringBuilder value = new StringBuilder(); + int i = 0; + int i1 = s.indexOf('%'); + while (i1 >= 0) { + int i2 = s.indexOf('%', i1 + 1); + if (i2 < 0) { + break; + } + + String varName = s.substring(i1 + 1, i2); + String varValue = System.getenv(varName); + if (varValue == null) { + varValue = "%" + varName + "%"; + } + + value.append(s.substring(i, i1)); + value.append(varValue); + + i = i2 + 1; + i1 = s.indexOf('%', i); + } + value.append(s.substring(i)); + + log.info("Parameter {}: [{}]", name, value); + return value.toString(); + } + + private static void validateUrl(String restapiUrl) throws Exception { + try { + URI.create(restapiUrl); + } catch (IllegalArgumentException e) { + throw new Exception("Invalid input of url " + e.getLocalizedMessage(), e); + } + } + + private static Set getListNameList(Map paramMap) { + Set ll = new HashSet<>(); + for (Map.Entry entry : paramMap.entrySet()) + if (entry.getKey().startsWith("listName")) { + ll.add(entry.getValue()); + } + return ll; + } + + public static Client addAuthType(Client client, Parameters p) { + if (p.authtype == AuthType.Unspecified) { + if (p.restapiUser != null && p.restapiPassword != null) { + 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(); + client.register(oAuth1Feature); + } + } else { + if (p.authtype == AuthType.DIGEST) { + if (p.restapiUser != null && p.restapiPassword != null) { + client.register(HttpAuthenticationFeature.digest(p.restapiUser, p.restapiPassword)); + } else { + throw new IllegalArgumentException( + "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 IllegalArgumentException( + "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(); + client.register(oAuth1Feature); + } else { + throw new IllegalArgumentException( + "oAUTH authentication type selected but all oAuthConsumerKey, oAuthConsumerSecret " + + "and oAuthSignatureMethod parameters doesn't exist", new Throwable()); + } + } + } + return client; + } +} + diff --git a/src/test/java/org/onap/dcae/collectors/restconf/restconftest/RestConfProcTest.java b/src/test/java/org/onap/dcae/collectors/restconf/restconftest/RestConfProcTest.java index c86206a..3c55618 100755 --- a/src/test/java/org/onap/dcae/collectors/restconf/restconftest/RestConfProcTest.java +++ b/src/test/java/org/onap/dcae/collectors/restconf/restconftest/RestConfProcTest.java @@ -68,6 +68,10 @@ public class RestConfProcTest { p.put("sseConnectURL", "http://localhost:8080/ssevents"); p.put("subscriberId", "networkId"); p.put("responsePrefix", "restapi-result"); + p.put("restapiUrl", "https://localhost:8080/restconf/operations/" + + "ietf-subscribed-notifications:establish-subscription"); + p.put("restapiUser", "access"); + p.put("restapiPassword", "abc@123"); restConfProc.establishPersistentConnection(p, ctx); Thread.sleep(1000); -- cgit 1.2.3-korg