]> git.basschouten.com Git - openhab-addons.git/blob
c770a617789beb5dab93a2589049d25873aca146
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.nibeuplink.internal.callback;
14
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;
20
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;
36
37 import com.google.gson.Gson;
38
39 /**
40  * base class for all commands. common logic should be implemented here
41  *
42  * @author Alexander Friese - initial contribution
43  */
44 @NonNullByDefault
45 public abstract class AbstractUplinkCommandCallback extends BufferingResponseListener implements NibeUplinkCommand {
46
47     /**
48      * logger
49      */
50     protected final Logger logger = LoggerFactory.getLogger(AbstractUplinkCommandCallback.class);
51
52     /**
53      * the configuration
54      */
55     protected final NibeUplinkConfiguration config;
56
57     /**
58      * status code of fulfilled request
59      */
60     private CommunicationStatus communicationStatus;
61
62     /**
63      * listener to provide updates to the WebInterface class
64      */
65     private @Nullable StatusUpdateListener listener;
66
67     /**
68      * JSON deserializer
69      */
70     private final Gson gson;
71
72     /**
73      * the constructor
74      *
75      * @param config
76      */
77     public AbstractUplinkCommandCallback(NibeUplinkConfiguration config) {
78         this.communicationStatus = new CommunicationStatus();
79         this.config = config;
80         this.gson = new Gson();
81     }
82
83     /**
84      * the constructor
85      *
86      * @param config
87      */
88     public AbstractUplinkCommandCallback(NibeUplinkConfiguration config, StatusUpdateListener listener) {
89         this(config);
90         this.listener = listener;
91     }
92
93     /**
94      * Log request success
95      */
96     @Override
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());
102         }
103     }
104
105     /**
106      * Log request failure
107      */
108     @Override
109     public final void onFailure(@Nullable Response response, @Nullable Throwable failure) {
110         if (response != null && failure != null) {
111             super.onFailure(response, failure);
112         }
113         if (failure != null) {
114             logger.debug("Request failed: {}", failure.toString());
115             communicationStatus.setError((Exception) failure);
116
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);
121             } else {
122                 communicationStatus.setHttpCode(Code.INTERNAL_SERVER_ERROR);
123             }
124         }
125     }
126
127     @Override
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);
132     }
133
134     @Override
135     public void performAction(HttpClient asyncclient) {
136         Request request = asyncclient.newRequest(getURL()).timeout(config.getAsyncTimeout(), TimeUnit.SECONDS);
137         prepareRequest(request).send(this);
138     }
139
140     /**
141      * {@code @Nullable} wrapper of gson which does not 'understand' nonnull annotations
142      *
143      * @param json
144      * @return
145      */
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);
149     }
150
151     /**
152      * returns Http Status Code
153      */
154     public CommunicationStatus getCommunicationStatus() {
155         return communicationStatus;
156     }
157
158     /**
159      * concrete implementation has to prepare the requests with additional parameters, etc
160      *
161      * @return
162      */
163     protected abstract Request prepareRequest(Request requestToPrepare);
164
165     /**
166      * concrete implementation has to provide the URL
167      *
168      * @return
169      */
170     protected abstract String getURL();
171
172     @Override
173     public final void updateListenerStatus() {
174         StatusUpdateListener listener = this.listener;
175         if (listener != null) {
176             listener.update(communicationStatus);
177         }
178     }
179
180     @Override
181     public final void setListener(StatusUpdateListener listener) {
182         this.listener = listener;
183     }
184 }