2 * Copyright (c) 2010-2024 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.nibeuplink.internal.callback;
15 import java.net.SocketTimeoutException;
16 import java.net.UnknownHostException;
17 import java.nio.ByteBuffer;
18 import java.util.concurrent.TimeUnit;
19 import java.util.concurrent.TimeoutException;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.eclipse.jetty.client.HttpClient;
24 import org.eclipse.jetty.client.api.Request;
25 import org.eclipse.jetty.client.api.Response;
26 import org.eclipse.jetty.client.util.BufferingResponseListener;
27 import org.eclipse.jetty.http.HttpStatus;
28 import org.eclipse.jetty.http.HttpStatus.Code;
29 import org.openhab.binding.nibeuplink.internal.command.NibeUplinkCommand;
30 import org.openhab.binding.nibeuplink.internal.config.NibeUplinkConfiguration;
31 import org.openhab.binding.nibeuplink.internal.connector.CommunicationStatus;
32 import org.openhab.binding.nibeuplink.internal.connector.StatusUpdateListener;
33 import org.openhab.binding.nibeuplink.internal.model.GenericDataResponse;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
37 import com.google.gson.Gson;
40 * base class for all commands. common logic should be implemented here
42 * @author Alexander Friese - initial contribution
45 public abstract class AbstractUplinkCommandCallback extends BufferingResponseListener implements NibeUplinkCommand {
50 protected final Logger logger = LoggerFactory.getLogger(AbstractUplinkCommandCallback.class);
55 protected final NibeUplinkConfiguration config;
58 * status code of fulfilled request
60 private CommunicationStatus communicationStatus;
63 * listener to provide updates to the WebInterface class
65 private @Nullable StatusUpdateListener listener;
70 private final Gson gson;
77 public AbstractUplinkCommandCallback(NibeUplinkConfiguration config) {
78 this.communicationStatus = new CommunicationStatus();
80 this.gson = new Gson();
88 public AbstractUplinkCommandCallback(NibeUplinkConfiguration config, StatusUpdateListener listener) {
90 this.listener = listener;
97 public final void onSuccess(Response response) {
98 super.onSuccess(response);
99 if (response != null) {
100 communicationStatus.setHttpCode(HttpStatus.getCode(response.getStatus()));
101 logger.debug("HTTP response {}", response.getStatus());
106 * Log request failure
109 public final void onFailure(@Nullable Response response, @Nullable Throwable failure) {
110 if (response != null && failure != null) {
111 super.onFailure(response, failure);
113 if (failure != null) {
114 logger.debug("Request failed: {}", failure.toString());
115 communicationStatus.setError((Exception) failure);
117 if (failure instanceof SocketTimeoutException || failure instanceof TimeoutException) {
118 communicationStatus.setHttpCode(Code.REQUEST_TIMEOUT);
119 } else if (failure instanceof UnknownHostException) {
120 communicationStatus.setHttpCode(Code.BAD_GATEWAY);
122 communicationStatus.setHttpCode(Code.INTERNAL_SERVER_ERROR);
128 public void onContent(Response response, ByteBuffer content) {
129 super.onContent(response, content);
130 String contentAsString = getContentAsString();
131 logger.debug("received content, length: {}", contentAsString != null ? getContentAsString().length() : 0);
135 public void performAction(HttpClient asyncclient) {
136 Request request = asyncclient.newRequest(getURL()).timeout(config.getAsyncTimeout(), TimeUnit.SECONDS);
137 prepareRequest(request).send(this);
141 * {@code @Nullable} wrapper of gson which does not 'understand' nonnull annotations
146 protected @Nullable GenericDataResponse fromJson(String json) {
147 // gson is not able to handle @NonNull annotation, thus the return value can be null.
148 return gson.fromJson(json, GenericDataResponse.class);
152 * returns Http Status Code
154 public CommunicationStatus getCommunicationStatus() {
155 return communicationStatus;
159 * concrete implementation has to prepare the requests with additional parameters, etc
163 protected abstract Request prepareRequest(Request requestToPrepare);
166 * concrete implementation has to provide the URL
170 protected abstract String getURL();
173 public final void updateListenerStatus() {
174 StatusUpdateListener listener = this.listener;
175 if (listener != null) {
176 listener.update(communicationStatus);
181 public final void setListener(StatusUpdateListener listener) {
182 this.listener = listener;