]> git.basschouten.com Git - openhab-addons.git/blob
1bcc711d02202d1797370f41e128113c4537bfcf
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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 (InterruptedException | ExecutionException e) {
123             logger.debug("Error in handling request: ", e);
124         }
125
126         return retVal;
127     }
128
129     /**
130      * Issues an HTTP GET request on the API's URL, using an object that is serialized to JSON as input.
131      * Makes sure that the request is correctly formatted.*
132      *
133      * @param url The URL to query
134      * @param outClass The type of the requested result
135      * @return The result of the request or null
136      * @throws TimeoutException Thrown when a request times out
137      */
138     public <TOut> TOut doAuthenticatedGet(String url, Class<TOut> outClass) throws TimeoutException {
139         return doAuthenticatedRequest(HttpMethod.GET, url, null, outClass);
140     }
141
142     /**
143      * Issues an HTTP request on the API's URL, using an object that is serialized to JSON as input.
144      * Makes sure that the request is correctly formatted.*
145      *
146      * @param url The URL to query
147      * @param requestContainer The object to use as JSON data for the request
148      * @throws TimeoutException Thrown when a request times out
149      */
150     public void doAuthenticatedPut(String url, Object requestContainer) throws TimeoutException {
151         doAuthenticatedRequest(HttpMethod.PUT, url, requestContainer, null);
152     }
153
154     /**
155      * Issues an HTTP request on the API's URL, using an object that is serialized to JSON as input.
156      * Makes sure that the request is correctly formatted.*
157      *
158      * @param method The HTTP method to use (POST, GET, ...)
159      * @param url The URL to query
160      * @param headers The optional additional headers to apply, can be null
161      * @param requestContainer The object to use as JSON data for the request
162      * @param outClass The type of the requested result
163      * @return The result of the request or null
164      * @throws TimeoutException Thrown when a request times out
165      */
166     private <TOut> TOut doRequest(HttpMethod method, String url, Map<String, String> headers, Object requestContainer,
167             Class<TOut> outClass) throws TimeoutException {
168         String json = null;
169         if (requestContainer != null) {
170             json = this.gson.toJson(requestContainer);
171         }
172
173         return doRequest(method, url, headers, json, "application/json", outClass);
174     }
175
176     /**
177      * Issues an HTTP request on the API's URL, using an object that is serialized to JSON as input and
178      * using the authentication applied to the type.
179      * Makes sure that the request is correctly formatted.*
180      *
181      * @param method The HTTP method to use (POST, GET, ...)
182      * @param url The URL to query
183      * @param requestContainer The object to use as JSON data for the request
184      * @param outClass The type of the requested result
185      * @return The result of the request or null
186      * @throws TimeoutException Thrown when a request times out
187      */
188     private <TOut> TOut doAuthenticatedRequest(HttpMethod method, String url, Object requestContainer,
189             Class<TOut> outClass) throws TimeoutException {
190         Map<String, String> headers = null;
191         if (authenticationData != null) {
192             headers = new HashMap<>();
193
194             headers.put("Authorization", "Bearer " + authenticationData.getAccessToken());
195             headers.put("applicationId", applicationId);
196             headers.put("Accept",
197                     "application/json, application/xml, text/json, text/x-json, text/javascript, text/xml");
198         }
199
200         return doRequest(method, url, headers, requestContainer, outClass);
201     }
202 }