]> git.basschouten.com Git - openhab-addons.git/blob
7e84dc05c36f15e32b2f79c44f26d5b812e00718
[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.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(@Nullable 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         super.onFailure(response, failure);
111         if (failure != null) {
112             logger.debug("Request failed: {}", failure.toString());
113             communicationStatus.setError((Exception) failure);
114
115             if (failure instanceof SocketTimeoutException || failure instanceof TimeoutException) {
116                 communicationStatus.setHttpCode(Code.REQUEST_TIMEOUT);
117             } else if (failure instanceof UnknownHostException) {
118                 communicationStatus.setHttpCode(Code.BAD_GATEWAY);
119             } else {
120                 communicationStatus.setHttpCode(Code.INTERNAL_SERVER_ERROR);
121             }
122         }
123     }
124
125     @Override
126     public void onContent(@Nullable Response response, @Nullable ByteBuffer content) {
127         super.onContent(response, content);
128         logger.debug("received content, length: {}", getContentAsString().length());
129     }
130
131     @Override
132     public void performAction(HttpClient asyncclient) {
133         Request request = asyncclient.newRequest(getURL()).timeout(config.getAsyncTimeout(), TimeUnit.SECONDS);
134         prepareRequest(request).send(this);
135     }
136
137     /**
138      * @Nullable wrapper of gson which does not 'understand' nonnull annotations
139      *
140      * @param json
141      * @return
142      */
143     protected @Nullable GenericDataResponse fromJson(String json) {
144         // gson is not able to handle @NonNull annotation, thus the return value can be null.
145         return gson.fromJson(json, GenericDataResponse.class);
146     }
147
148     /**
149      * returns Http Status Code
150      */
151     public CommunicationStatus getCommunicationStatus() {
152         return communicationStatus;
153     }
154
155     /**
156      * concrete implementation has to prepare the requests with additional parameters, etc
157      *
158      * @return
159      */
160     protected abstract Request prepareRequest(Request requestToPrepare);
161
162     /**
163      * concrete implementation has to provide the URL
164      *
165      * @return
166      */
167     protected abstract String getURL();
168
169     @Override
170     public final void updateListenerStatus() {
171         StatusUpdateListener listener = this.listener;
172         if (listener != null) {
173             listener.update(communicationStatus);
174         }
175     }
176
177     @Override
178     public final void setListener(StatusUpdateListener listener) {
179         this.listener = listener;
180     }
181 }