884708d039137e486568e2f300aeefb75f95ffa9
[policy/apex-pdp.git] / examples / examples-onap-bbs / src / main / java / org / onap / policy / apex / examples / bbs / WebClient.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2019 Huawei. All rights reserved.
4  *  Modifications Copyright (C) 2019-2020 Nordix Foundation.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.apex.examples.bbs;
23
24 import java.io.BufferedReader;
25 import java.io.ByteArrayInputStream;
26 import java.io.InputStreamReader;
27 import java.io.OutputStream;
28 import java.io.StringWriter;
29 import java.net.HttpURLConnection;
30 import java.net.URL;
31 import java.nio.charset.StandardCharsets;
32 import java.util.Base64;
33 import javax.net.ssl.HttpsURLConnection;
34 import javax.net.ssl.SSLContext;
35 import javax.net.ssl.SSLSession;
36 import javax.net.ssl.TrustManager;
37 import javax.xml.parsers.DocumentBuilderFactory;
38 import javax.xml.transform.OutputKeys;
39 import javax.xml.transform.Transformer;
40 import javax.xml.transform.TransformerFactory;
41 import javax.xml.transform.dom.DOMSource;
42 import javax.xml.transform.stream.StreamResult;
43 import javax.xml.xpath.XPath;
44 import javax.xml.xpath.XPathConstants;
45 import javax.xml.xpath.XPathFactory;
46
47 import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException;
48 import org.onap.policy.common.utils.network.NetworkUtil;
49 import org.slf4j.ext.XLogger;
50 import org.slf4j.ext.XLoggerFactory;
51 import org.w3c.dom.Document;
52 import org.w3c.dom.Node;
53 import org.w3c.dom.NodeList;
54 import org.xml.sax.InputSource;
55
56 /**
57  * The Class WebClient act as rest client for BBS usecase.
58  */
59 public class WebClient {
60
61     private static final XLogger LOGGER = XLoggerFactory.getXLogger(WebClient.class);
62
63     // Duplicated string constants
64     private static final String BBS_POLICY = "BBS Policy";
65
66     //Features to prevent XXE injection
67     private static final String XML_DISALLOW_DOCTYPE_FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
68     private static final String XML_EXTERNAL_ENTITY_FEATURE = "http://xml.org/sax/features/external-general-entities";
69
70     /**
71      * Send simple https rest request.
72      *
73      * @param requestUrl    url
74      * @param requestMethod method eg POST/GET/PUT
75      * @param outputStr     Data
76      * @param username      Simple Username
77      * @param pass          Simple password
78      * @param contentType   http content type
79      * @return String response message
80      */
81     public String httpRequest(String requestUrl, String requestMethod, String outputStr, String username, String pass,
82         String contentType) {
83         String result = "";
84         StringBuilder builder = new StringBuilder();
85         try {
86             LOGGER.info("httpsRequest starts {} method {}", requestUrl, requestMethod);
87             disableCertificateValidation();
88
89             URL url = new URL(requestUrl);
90             HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();
91
92             httpUrlConn.setDoOutput(true);
93             httpUrlConn.setDoInput(true);
94             httpUrlConn.setUseCaches(false);
95
96             if ((username != null) && (pass != null)) {
97                 httpUrlConn.setRequestProperty("Authorization", getAuth(username, pass));
98             } else {
99                 LOGGER.warn("Authorization information missing");
100             }
101
102             httpUrlConn.setRequestProperty("Content-Type", contentType);
103             httpUrlConn.setRequestProperty("Accept", contentType);
104             httpUrlConn.setRequestProperty("X-FromAppId", BBS_POLICY);
105             httpUrlConn.setRequestProperty("X-TransactionId", BBS_POLICY);
106             httpUrlConn.setRequestMethod(requestMethod);
107
108             if ("GET".equalsIgnoreCase(requestMethod)) {
109                 httpUrlConn.connect();
110             }
111
112             if (null != outputStr) {
113                 OutputStream outputStream = httpUrlConn.getOutputStream();
114                 outputStream.write(outputStr.getBytes(StandardCharsets.UTF_8));
115                 outputStream.close();
116             }
117
118             try (BufferedReader bufferedReader = new BufferedReader(
119                 new InputStreamReader(httpUrlConn.getInputStream(), StandardCharsets.UTF_8))) {
120                 String str;
121                 while ((str = bufferedReader.readLine()) != null) {
122                     builder.append(str);
123                 }
124                 httpUrlConn.disconnect();
125                 result = builder.toString();
126             }
127             LOGGER.info("httpsRequest success");
128         } catch (Exception ce) {
129             LOGGER.error("httpsRequest Exception", ce);
130         }
131         return result;
132     }
133
134     /**
135      * Pretty print xml string.
136      *
137      * @param xml    Input string
138      * @param indent Indent number
139      * @return Indented xml string
140      */
141     public String toPrettyString(String xml, int indent) {
142         try {
143             try (ByteArrayInputStream br = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))) {
144
145                 DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
146                 df.setFeature(XML_DISALLOW_DOCTYPE_FEATURE, true);
147                 df.setFeature(XML_EXTERNAL_ENTITY_FEATURE, false);
148                 Document document = df.newDocumentBuilder().parse(new InputSource(br));
149
150                 document.normalize();
151                 XPath path = XPathFactory.newInstance().newXPath();
152                 NodeList nodeList = (NodeList) path
153                     .evaluate("//text()[normalize-space()='']", document, XPathConstants.NODESET);
154
155                 for (int i = 0; i < nodeList.getLength(); ++i) {
156                     Node node = nodeList.item(i);
157                     node.getParentNode().removeChild(node);
158                 }
159
160                 TransformerFactory transformerFactory = TransformerFactory.newInstance();
161                 transformerFactory.setAttribute("indent-number", indent);
162                 Transformer transformer = transformerFactory.newTransformer();
163                 transformer.setOutputProperty(OutputKeys.ENCODING, StandardCharsets.UTF_8.name());
164                 transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
165                 transformer.setOutputProperty(OutputKeys.INDENT, "yes");
166
167                 StringWriter stringWriter = new StringWriter();
168                 transformer.transform(new DOMSource(document), new StreamResult(stringWriter));
169                 return stringWriter.toString();
170             }
171         } catch (Exception e) {
172             throw new ApexRuntimeException("Convert to Pretty string failed", e);
173         }
174     }
175
176     /**
177      * Disable ssl verification.
178      */
179     private static void disableCertificateValidation() {
180         try {
181             TrustManager[] trustAllCerts = NetworkUtil.getAlwaysTrustingManager();
182
183             SSLContext sc = SSLContext.getInstance("TLS");
184             sc.init(null, trustAllCerts, new java.security.SecureRandom());
185             HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
186             HttpsURLConnection.setDefaultHostnameVerifier((String hostname, SSLSession session) -> {
187                 if (!hostname.equalsIgnoreCase(session.getPeerHost())) {
188                     LOGGER.warn("Warning: URL host \"{}\" is different to SSLSession host \"{}\".", hostname,
189                         session.getPeerHost());
190                     return false;
191                 }
192                 return true;
193             });
194         } catch (Exception e) {
195             LOGGER.error("certificate validation Exception", e);
196         }
197     }
198
199     /**
200      * Return Basic Authentication String.
201      *
202      * @param userName UserName
203      * @param password PassWord
204      * @return Basic Authentication
205      */
206     private String getAuth(String userName, String password) {
207         String userCredentials = userName + ":" + password;
208         return ("Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes(StandardCharsets.UTF_8)));
209     }
210 }