[CCSDK-1985]GR Toolkit Refactor
[ccsdk/sli/plugins.git] / grToolkit / provider / src / main / java / org / onap / ccsdk / sli / plugins / grtoolkit / connection / ConnectionManager.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : SDN-C
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights
6  *                      reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.ccsdk.sli.plugins.grtoolkit.connection;
23
24 import org.apache.commons.lang.StringUtils;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 import java.io.BufferedReader;
29 import java.io.IOException;
30 import java.io.InputStreamReader;
31 import java.io.OutputStream;
32 import java.net.HttpURLConnection;
33 import java.net.URL;
34 import java.nio.charset.StandardCharsets;
35
36 /**
37  * Handles the process for getting HTTP connections to resources. Has the
38  * ability to send JSON payloads. Only supports basic authorization when
39  * sending credentials.
40  *
41  * @author Anthony Haddox
42  * @see ConnectionResponse
43  */
44 public interface ConnectionManager {
45     Logger log = LoggerFactory.getLogger(ConnectionManager.class);
46     int CONNECTION_TIMEOUT = 5000; // 5 second timeout
47     enum HttpMethod {
48         GET("GET"),
49         POST("POST");
50
51         private final String method;
52         HttpMethod(String method) {
53             this.method = method;
54         }
55         String getMethod() {
56             return method;
57         }
58     }
59
60     /**
61      * Writes a JSON payload to an {@code HTTPURLConnection OutputStream}.
62      *
63      * @param input the JSON payload to send
64      * @param connection the {@code HTTPURLConnection} to write to
65      * @throws IOException if there is a problem writing to the output stream
66      */
67     static void sendPayload(String input, HttpURLConnection connection) throws IOException {
68         byte[] out = input.getBytes(StandardCharsets.UTF_8);
69         int length = out.length;
70
71         connection.setFixedLengthStreamingMode(length);
72         connection.setRequestProperty("Content-Type", "application/json");
73         connection.setDoOutput(true);
74         connection.connect();
75         try(OutputStream os = connection.getOutputStream()) {
76             os.write(out);
77         }
78     }
79
80     /**
81      * Gets an {@code HTTPURLConnection} to a {@code host}.
82      *
83      * @param host the host to connect to
84      * @return an {@code HTTPURLConnection}
85      * @throws IOException if a connection cannot be opened
86      */
87     static HttpURLConnection getConnection(String host) throws IOException {
88         log.info("getConnection(): Getting connection to: {}", host);
89         URL url = new URL(host);
90         HttpURLConnection connection = (HttpURLConnection) url.openConnection();
91         connection.setRequestProperty("Connection", "keep-alive");
92         connection.setRequestProperty("Proxy-Connection", "keep-alive");
93         connection.setConnectTimeout(CONNECTION_TIMEOUT);
94         connection.setReadTimeout(CONNECTION_TIMEOUT);
95         return connection;
96     }
97
98     /**
99      * Gets an {@code HTTPURLConnection} to a {@code host} and sets the
100      * Authorization header with the supplied credentials. Only supports basic
101      * authentication.
102      *
103      * @param host the host to connect to
104      * @param credentials the authorization credentials
105      * @return an {@code HTTPURLConnection} with Authorization header set
106      * @throws IOException if a connection cannot be opened
107      */
108     static HttpURLConnection getConnection(String host, String credentials) throws IOException {
109         String auth = "Basic " + javax.xml.bind.DatatypeConverter.printBase64Binary(credentials.getBytes());
110         HttpURLConnection connection = getConnection(host);
111         connection.addRequestProperty("Authorization", auth);
112         credentials = null;
113         auth = null;
114         return connection;
115     }
116
117     /**
118      * Opens a connection to a path, sends a payload (if supplied with one),
119      * and returns the response.
120      * @param path the host to connect to
121      * @param method the {@code HttpMethod} to use
122      * @param input the payload to send
123      * @param credentials the credentials to use
124      * @return a {@code ConnectionResponse} containing the response body and
125      *         status code of the operation
126      * @throws IOException if a connection cannot be opened or if the payload
127      *                     cannot be sent
128      * @see HttpMethod
129      */
130     static ConnectionResponse getConnectionResponse(String path, HttpMethod method, String input, String credentials) throws IOException {
131         HttpURLConnection connection = (StringUtils.isEmpty(credentials)) ? getConnection(path) : getConnection(path, credentials);
132         credentials = null;
133         connection.setRequestMethod(method.getMethod());
134         connection.setDoInput(true);
135
136         if(!StringUtils.isEmpty(input)) {
137             sendPayload(input, connection);
138         }
139
140         StringBuilder content = new StringBuilder();
141         try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
142             String inputLine;
143             while((inputLine = bufferedReader.readLine()) != null) {
144                 content.append(inputLine);
145             }
146         } finally {
147             connection.disconnect();
148         }
149
150         ConnectionResponse connectionResponse = new ConnectionResponse();
151         connectionResponse.content = content.toString();
152         connectionResponse.statusCode = connection.getResponseCode();
153         log.info("getConnectionResponse(): {} response code from {}", connectionResponse.statusCode, path);
154         log.debug("getConnectionResponse(): Response:\n{}", connectionResponse.content);
155         return connectionResponse;
156     }
157 }