]> git.basschouten.com Git - openhab-addons.git/blob
cb2335e7473b9ff00814f463eaf4ac1238796fb4
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.evohome.internal.api;
14
15 import java.util.HashMap;
16 import java.util.Map;
17 import java.util.concurrent.ExecutionException;
18 import java.util.concurrent.TimeUnit;
19 import java.util.concurrent.TimeoutException;
20
21 import org.eclipse.jetty.client.HttpClient;
22 import org.eclipse.jetty.client.api.ContentResponse;
23 import org.eclipse.jetty.client.api.Request;
24 import org.eclipse.jetty.client.util.StringContentProvider;
25 import org.eclipse.jetty.http.HttpMethod;
26 import org.eclipse.jetty.http.HttpStatus;
27 import org.openhab.binding.evohome.internal.api.models.v2.response.Authentication;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 import com.google.gson.Gson;
32 import com.google.gson.GsonBuilder;
33
34 /**
35  * Provides access to (an optionally OAUTH based) API. Makes sure that all the necessary headers are set.
36  *
37  * @author Jasper van Zuijlen - Initial contribution
38  *
39  */
40 public class ApiAccess {
41     private static final int REQUEST_TIMEOUT_SECONDS = 5;
42     private final Logger logger = LoggerFactory.getLogger(ApiAccess.class);
43     private final HttpClient httpClient;
44     private final Gson gson;
45
46     private Authentication authenticationData;
47     private String applicationId;
48
49     public ApiAccess(HttpClient httpClient) {
50         this.gson = new GsonBuilder().create();
51         this.httpClient = httpClient;
52     }
53
54     /**
55      * Sets the authentication details on the type
56      *
57      * @param authentication The authentication details to apply
58      */
59     public void setAuthentication(Authentication authentication) {
60         authenticationData = authentication;
61     }
62
63     /**
64      * Gets the current authentication details of the type
65      *
66      * @return The current authentication details
67      */
68     public Authentication getAuthentication() {
69         return authenticationData;
70     }
71
72     /**
73      * Sets the application id on the type
74      *
75      * @param applicationId The application id to apply
76      */
77     public void setApplicationId(String applicationId) {
78         this.applicationId = applicationId;
79     }
80
81     /**
82      * Issues an HTTP request on the API's URL. Makes sure that the request is correctly formatted.
83      *
84      * @param method The HTTP method to use (POST, GET, ...)
85      * @param url The URL to query
86      * @param headers The optional additional headers to apply, can be null
87      * @param requestData The optional request data to use, can be null
88      * @param contentType The content type to use with the request data. Required when using requestData
89      * @return The result of the request or null
90      * @throws TimeoutException Thrown when a request times out
91      */
92     public <TOut> TOut doRequest(HttpMethod method, String url, Map<String, String> headers, String requestData,
93             String contentType, Class<TOut> outClass) throws TimeoutException {
94         TOut retVal = null;
95         logger.debug("Requesting: [{}]", url);
96
97         try {
98             Request request = httpClient.newRequest(url).method(method);
99
100             if (headers != null) {
101                 for (Map.Entry<String, String> header : headers.entrySet()) {
102                     request.header(header.getKey(), header.getValue());
103                 }
104             }
105
106             if (requestData != null) {
107                 request.content(new StringContentProvider(requestData), contentType);
108             }
109
110             ContentResponse response = request.timeout(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS).send();
111
112             logger.debug("Response: {}", response);
113             logger.debug("\n{}\n{}", response.getHeaders(), response.getContentAsString());
114
115             if ((response.getStatus() == HttpStatus.OK_200) || (response.getStatus() == HttpStatus.ACCEPTED_202)) {
116                 String reply = response.getContentAsString();
117
118                 if (outClass != null) {
119                     retVal = new Gson().fromJson(reply, outClass);
120                 }
121             }
122         } catch (ExecutionException e) {
123             logger.debug("Error in handling request: ", e);
124         } catch (InterruptedException e) {
125             logger.debug("Handling request interrupted: ", e);
126             Thread.currentThread().interrupt();
127         }
128
129         return retVal;
130     }
131
132     /**
133      * Issues an HTTP GET request on the API's URL, using an object that is serialized to JSON as input.
134      * Makes sure that the request is correctly formatted.*
135      *
136      * @param url The URL to query
137      * @param outClass The type of the requested result
138      * @return The result of the request or null
139      * @throws TimeoutException Thrown when a request times out
140      */
141     public <TOut> TOut doAuthenticatedGet(String url, Class<TOut> outClass) throws TimeoutException {
142         return doAuthenticatedRequest(HttpMethod.GET, url, null, outClass);
143     }
144
145     /**
146      * Issues an HTTP request on the API's URL, using an object that is serialized to JSON as input.
147      * Makes sure that the request is correctly formatted.*
148      *
149      * @param url The URL to query
150      * @param requestContainer The object to use as JSON data for the request
151      * @throws TimeoutException Thrown when a request times out
152      */
153     public void doAuthenticatedPut(String url, Object requestContainer) throws TimeoutException {
154         doAuthenticatedRequest(HttpMethod.PUT, url, requestContainer, null);
155     }
156
157     /**
158      * Issues an HTTP request on the API's URL, using an object that is serialized to JSON as input.
159      * Makes sure that the request is correctly formatted.*
160      *
161      * @param method The HTTP method to use (POST, GET, ...)
162      * @param url The URL to query
163      * @param headers The optional additional headers to apply, can be null
164      * @param requestContainer The object to use as JSON data for the request
165      * @param outClass The type of the requested result
166      * @return The result of the request or null
167      * @throws TimeoutException Thrown when a request times out
168      */
169     private <TOut> TOut doRequest(HttpMethod method, String url, Map<String, String> headers, Object requestContainer,
170             Class<TOut> outClass) throws TimeoutException {
171         String json = null;
172         if (requestContainer != null) {
173             json = this.gson.toJson(requestContainer);
174         }
175
176         return doRequest(method, url, headers, json, "application/json", outClass);
177     }
178
179     /**
180      * Issues an HTTP request on the API's URL, using an object that is serialized to JSON as input and
181      * using the authentication applied to the type.
182      * Makes sure that the request is correctly formatted.*
183      *
184      * @param method The HTTP method to use (POST, GET, ...)
185      * @param url The URL to query
186      * @param requestContainer The object to use as JSON data for the request
187      * @param outClass The type of the requested result
188      * @return The result of the request or null
189      * @throws TimeoutException Thrown when a request times out
190      */
191     private <TOut> TOut doAuthenticatedRequest(HttpMethod method, String url, Object requestContainer,
192             Class<TOut> outClass) throws TimeoutException {
193         Map<String, String> headers = null;
194         if (authenticationData != null) {
195             headers = new HashMap<>();
196
197             headers.put("Authorization", "Bearer " + authenticationData.getAccessToken());
198             headers.put("applicationId", applicationId);
199             headers.put("Accept",
200                     "application/json, application/xml, text/json, text/x-json, text/javascript, text/xml");
201         }
202
203         return doRequest(method, url, headers, requestContainer, outClass);
204     }
205 }