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.mielecloud.internal.webservice;
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;
26 * Holds utility functions for working with HTTP.
28 * @author Björn Lange - Initial Contribution
31 public final class HttpUtil {
32 private static final String RETRY_AFTER_HEADER_FIELD_NAME = "Retry-After";
35 throw new IllegalStateException("This class must not be instantiated");
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.
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
49 public static void checkHttpSuccess(Response response) {
50 if (isHttpSuccessStatus(response.getStatus())) {
54 String exceptionMessage = getHttpErrorMessageFromCloudResponse(response);
56 switch (response.getStatus()) {
58 throw new AuthorizationFailedException(exceptionMessage);
60 String retryAfter = null;
61 if (response.getHeaders().containsKey(RETRY_AFTER_HEADER_FIELD_NAME)) {
62 retryAfter = response.getHeaders().get(RETRY_AFTER_HEADER_FIELD_NAME);
64 throw new TooManyRequestsException(exceptionMessage, retryAfter);
66 throw new MieleWebserviceTransientException(exceptionMessage, ConnectionError.SERVER_ERROR);
68 throw new MieleWebserviceTransientException(exceptionMessage, ConnectionError.SERVICE_UNAVAILABLE);
70 throw new MieleWebserviceException(exceptionMessage, ConnectionError.OTHER_HTTP_ERROR);
75 * Gets whether {@code httpStatus} is a HTTP error code from the 200 range (success).
77 private static boolean isHttpSuccessStatus(int httpStatus) {
78 return httpStatus / 100 == 2;
81 private static String getHttpErrorMessageFromCloudResponse(Response response) {
82 String exceptionMessage = "HTTP error " + response.getStatus() + ": " + response.getReason();
84 if (response instanceof ContentResponse) {
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.";
92 return exceptionMessage;