2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.evohome.internal.api;
15 import java.util.HashMap;
17 import java.util.concurrent.ExecutionException;
18 import java.util.concurrent.TimeUnit;
19 import java.util.concurrent.TimeoutException;
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;
31 import com.google.gson.Gson;
32 import com.google.gson.GsonBuilder;
35 * Provides access to (an optionally OAUTH based) API. Makes sure that all the necessary headers are set.
37 * @author Jasper van Zuijlen - Initial contribution
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;
46 private Authentication authenticationData;
47 private String applicationId;
49 public ApiAccess(HttpClient httpClient) {
50 this.gson = new GsonBuilder().create();
51 this.httpClient = httpClient;
55 * Sets the authentication details on the type
57 * @param authentication The authentication details to apply
59 public void setAuthentication(Authentication authentication) {
60 authenticationData = authentication;
64 * Gets the current authentication details of the type
66 * @return The current authentication details
68 public Authentication getAuthentication() {
69 return authenticationData;
73 * Sets the application id on the type
75 * @param applicationId The application id to apply
77 public void setApplicationId(String applicationId) {
78 this.applicationId = applicationId;
82 * Issues an HTTP request on the API's URL. Makes sure that the request is correctly formatted.
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
92 public <TOut> TOut doRequest(HttpMethod method, String url, Map<String, String> headers, String requestData,
93 String contentType, Class<TOut> outClass) throws TimeoutException {
95 logger.debug("Requesting: [{}]", url);
98 Request request = httpClient.newRequest(url).method(method);
100 if (headers != null) {
101 for (Map.Entry<String, String> header : headers.entrySet()) {
102 request.header(header.getKey(), header.getValue());
106 if (requestData != null) {
107 request.content(new StringContentProvider(requestData), contentType);
110 ContentResponse response = request.timeout(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS).send();
112 logger.debug("Response: {}", response);
113 logger.debug("\n{}\n{}", response.getHeaders(), response.getContentAsString());
115 if ((response.getStatus() == HttpStatus.OK_200) || (response.getStatus() == HttpStatus.ACCEPTED_202)) {
116 String reply = response.getContentAsString();
118 if (outClass != null) {
119 retVal = new Gson().fromJson(reply, outClass);
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();
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.*
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
141 public <TOut> TOut doAuthenticatedGet(String url, Class<TOut> outClass) throws TimeoutException {
142 return doAuthenticatedRequest(HttpMethod.GET, url, null, outClass);
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.*
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
153 public void doAuthenticatedPut(String url, Object requestContainer) throws TimeoutException {
154 doAuthenticatedRequest(HttpMethod.PUT, url, requestContainer, null);
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.*
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
169 private <TOut> TOut doRequest(HttpMethod method, String url, Map<String, String> headers, Object requestContainer,
170 Class<TOut> outClass) throws TimeoutException {
172 if (requestContainer != null) {
173 json = this.gson.toJson(requestContainer);
176 return doRequest(method, url, headers, json, "application/json", outClass);
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.*
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
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<>();
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");
203 return doRequest(method, url, headers, requestContainer, outClass);