Changes for checkstyle 8.32
[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 import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException;
47 import org.onap.policy.common.utils.network.NetworkUtil;
48 import org.slf4j.ext.XLogger;
49 import org.slf4j.ext.XLoggerFactory;
50 import org.w3c.dom.Document;
51 import org.w3c.dom.Node;
52 import org.w3c.dom.NodeList;
53 import org.xml.sax.InputSource;
54
55 /**
56  * The Class WebClient act as rest client for BBS usecase.
57  */
58 public class WebClient {
59
60     private static final XLogger LOGGER = XLoggerFactory.getXLogger(WebClient.class);
61
62     // Duplicated string constants
63     private static final String BBS_POLICY = "BBS Policy";
64
65     //Features to prevent XXE injection
66     private static final String XML_DISALLOW_DOCTYPE_FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
67     private static final String XML_EXTERNAL_ENTITY_FEATURE = "http://xml.org/sax/features/external-general-entities";
68
69     /**
70      * Send simple https rest request.
71      *
72      * @param requestUrl    url
73      * @param requestMethod method eg POST/GET/PUT
74      * @param outputStr     Data
75      * @param username      Simple Username
76      * @param pass          Simple password
77      * @param contentType   http content type
78      * @return String response message
79      */
80     public String httpRequest(String requestUrl, String requestMethod, String outputStr, String username, String pass,
81         String contentType) {
82         String result = "";
83         StringBuilder builder = new StringBuilder();
84         try {
85             LOGGER.info("httpsRequest starts {} method {}", requestUrl, requestMethod);
86             disableCertificateValidation();
87
88             URL url = new URL(requestUrl);
89             HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();
90
91             httpUrlConn.setDoOutput(true);
92             httpUrlConn.setDoInput(true);
93             httpUrlConn.setUseCaches(false);
94
95             if ((username != null) && (pass != null)) {
96                 httpUrlConn.setRequestProperty("Authorization", getAuth(username, pass));
97             } else {
98                 LOGGER.warn("Authorization information missing");
99             }
100
101             httpUrlConn.setRequestProperty("Content-Type", contentType);
102             httpUrlConn.setRequestProperty("Accept", contentType);
103             httpUrlConn.setRequestProperty("X-FromAppId", BBS_POLICY);
104             httpUrlConn.setRequestProperty("X-TransactionId", BBS_POLICY);
105             httpUrlConn.setRequestMethod(requestMethod);
106
107             if ("GET".equalsIgnoreCase(requestMethod)) {
108                 httpUrlConn.connect();
109             }
110
111             if (null != outputStr) {
112                 OutputStream outputStream = httpUrlConn.getOutputStream();
113                 outputStream.write(outputStr.getBytes(StandardCharsets.UTF_8));
114                 outputStream.close();
115             }
116
117             try (BufferedReader bufferedReader = new BufferedReader(
118                 new InputStreamReader(httpUrlConn.getInputStream(), StandardCharsets.UTF_8))) {
119                 String str;
120                 while ((str = bufferedReader.readLine()) != null) {
121                     builder.append(str);
122                 }
123                 httpUrlConn.disconnect();
124                 result = builder.toString();
125             }
126             LOGGER.info("httpsRequest success");
127         } catch (Exception ce) {
128             LOGGER.error("httpsRequest Exception", ce);
129         }
130         return result;
131     }
132
133     /**
134      * Pretty print xml string.
135      *
136      * @param xml    Input string
137      * @param indent Indent number
138      * @return Indented xml string
139      */
140     public String toPrettyString(String xml, int indent) {
141         try {
142             try (ByteArrayInputStream br = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))) {
143
144                 DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
145                 df.setFeature(XML_DISALLOW_DOCTYPE_FEATURE, true);
146                 df.setFeature(XML_EXTERNAL_ENTITY_FEATURE, false);
147                 Document document = df.newDocumentBuilder().parse(new InputSource(br));
148
149                 document.normalize();
150                 XPath path = XPathFactory.newInstance().newXPath();
151                 NodeList nodeList = (NodeList) path
152                     .evaluate("//text()[normalize-space()='']", document, XPathConstants.NODESET);
153
154                 for (int i = 0; i < nodeList.getLength(); ++i) {
155                     Node node = nodeList.item(i);
156                     node.getParentNode().removeChild(node);
157                 }
158
159                 TransformerFactory transformerFactory = TransformerFactory.newInstance();
160                 transformerFactory.setAttribute("indent-number", indent);
161                 Transformer transformer = transformerFactory.newTransformer();
162                 transformer.setOutputProperty(OutputKeys.ENCODING, StandardCharsets.UTF_8.name());
163                 transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
164                 transformer.setOutputProperty(OutputKeys.INDENT, "yes");
165
166                 StringWriter stringWriter = new StringWriter();
167                 transformer.transform(new DOMSource(document), new StreamResult(stringWriter));
168                 return stringWriter.toString();
169             }
170         } catch (Exception e) {
171             throw new ApexRuntimeException("Convert to Pretty string failed", e);
172         }
173     }
174
175     /**
176      * Disable ssl verification.
177      */
178     private static void disableCertificateValidation() {
179         try {
180             TrustManager[] trustAllCerts = NetworkUtil.getAlwaysTrustingManager();
181
182             SSLContext sc = SSLContext.getInstance("TLS");
183             sc.init(null, trustAllCerts, new java.security.SecureRandom());
184             HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
185             HttpsURLConnection.setDefaultHostnameVerifier((String hostname, SSLSession session) -> {
186                 if (!hostname.equalsIgnoreCase(session.getPeerHost())) {
187                     LOGGER.warn("Warning: URL host \"{}\" is different to SSLSession host \"{}\".", hostname,
188                         session.getPeerHost());
189                     return false;
190                 }
191                 return true;
192             });
193         } catch (Exception e) {
194             LOGGER.error("certificate validation Exception", e);
195         }
196     }
197
198     /**
199      * Return Basic Authentication String.
200      *
201      * @param userName UserName
202      * @param password PassWord
203      * @return Basic Authentication
204      */
205     private String getAuth(String userName, String password) {
206         String userCredentials = userName + ":" + password;
207         return ("Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes(StandardCharsets.UTF_8)));
208     }
209 }