]> git.basschouten.com Git - openhab-addons.git/blob
6ffc29cc9e8cff586d4f5cbb9ae12e221b1be0a3
[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.mielecloud.internal.webservice;
14
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.eclipse.jetty.client.api.ContentResponse;
17 import org.eclipse.jetty.client.api.Response;
18 import org.openhab.binding.mielecloud.internal.webservice.api.json.ErrorMessage;
19 import org.openhab.binding.mielecloud.internal.webservice.api.json.MieleSyntaxException;
20 import org.openhab.binding.mielecloud.internal.webservice.exception.AuthorizationFailedException;
21 import org.openhab.binding.mielecloud.internal.webservice.exception.MieleWebserviceException;
22 import org.openhab.binding.mielecloud.internal.webservice.exception.MieleWebserviceTransientException;
23 import org.openhab.binding.mielecloud.internal.webservice.exception.TooManyRequestsException;
24
25 /**
26  * Holds utility functions for working with HTTP.
27  *
28  * @author Björn Lange - Initial Contribution
29  */
30 @NonNullByDefault
31 public final class HttpUtil {
32     private static final String RETRY_AFTER_HEADER_FIELD_NAME = "Retry-After";
33
34     private HttpUtil() {
35         throw new IllegalStateException("This class must not be instantiated");
36     }
37
38     /**
39      * Checks whether the HTTP status given in {@code response} is a success state. In case an error state is obtained,
40      * exceptions are thrown.
41      *
42      * @param response The response to check.
43      * @throws MieleWebserviceTransientException if the status indicates a transient HTTP error.
44      * @throws MieleWebserviceException if the status indicates another HTTP error.
45      * @throws AuthorizationFailedException if the status indicates an authorization failure.
46      * @throws TooManyRequestsException if the status indicates that too many requests have been made against the remote
47      *             endpoint.
48      */
49     public static void checkHttpSuccess(Response response) {
50         if (isHttpSuccessStatus(response.getStatus())) {
51             return;
52         }
53
54         String exceptionMessage = getHttpErrorMessageFromCloudResponse(response);
55
56         switch (response.getStatus()) {
57             case 401:
58                 throw new AuthorizationFailedException(exceptionMessage);
59             case 429:
60                 String retryAfter = null;
61                 if (response.getHeaders().containsKey(RETRY_AFTER_HEADER_FIELD_NAME)) {
62                     retryAfter = response.getHeaders().get(RETRY_AFTER_HEADER_FIELD_NAME);
63                 }
64                 throw new TooManyRequestsException(exceptionMessage, retryAfter);
65             case 500:
66                 throw new MieleWebserviceTransientException(exceptionMessage, ConnectionError.SERVER_ERROR);
67             case 503:
68                 throw new MieleWebserviceTransientException(exceptionMessage, ConnectionError.SERVICE_UNAVAILABLE);
69             default:
70                 throw new MieleWebserviceException(exceptionMessage, ConnectionError.OTHER_HTTP_ERROR);
71         }
72     }
73
74     /**
75      * Gets whether {@code httpStatus} is a HTTP error code from the 200 range (success).
76      */
77     private static boolean isHttpSuccessStatus(int httpStatus) {
78         return httpStatus / 100 == 2;
79     }
80
81     private static String getHttpErrorMessageFromCloudResponse(Response response) {
82         String exceptionMessage = "HTTP error " + response.getStatus() + ": " + response.getReason();
83
84         if (response instanceof ContentResponse) {
85             try {
86                 ErrorMessage errorMessage = ErrorMessage.fromJson(((ContentResponse) response).getContentAsString());
87                 exceptionMessage += "\nCloud returned message: " + errorMessage.getMessage();
88             } catch (MieleSyntaxException e) {
89                 exceptionMessage += "\nCloud returned invalid message.";
90             }
91         }
92         return exceptionMessage;
93     }
94 }