*/
package org.openhab.binding.miele.internal;
-import java.io.BufferedInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
import java.io.StringReader;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Collections;
-import java.util.Map;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.Random;
-import java.util.zip.GZIPInputStream;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.client.api.Request;
+import org.eclipse.jetty.client.util.StringContentProvider;
+import org.eclipse.jetty.http.HttpMethod;
import org.openhab.binding.miele.internal.exceptions.MieleRpcException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@NonNullByDefault
public class MieleGatewayCommunicationController {
- private final URL url;
+ private final URI uri;
private final Random rand = new Random();
private final Gson gson = new Gson();
private final Logger logger = LoggerFactory.getLogger(MieleGatewayCommunicationController.class);
+ private final HttpClient httpClient;
- public MieleGatewayCommunicationController(String host) throws MalformedURLException {
- url = new URL("http://" + host + "/remote/json-rpc");
+ public MieleGatewayCommunicationController(HttpClient httpClient, String host) throws URISyntaxException {
+ uri = new URI("http://" + host + "/remote/json-rpc");
+ this.httpClient = httpClient;
}
public JsonElement invokeOperation(FullyQualifiedApplianceIdentifier applianceIdentifier, String modelID,
public JsonElement invokeRPC(String methodName, Object[] args) throws MieleRpcException {
JsonElement result = null;
- JsonObject req = new JsonObject();
+ JsonObject requestBodyAsJson = new JsonObject();
int id = rand.nextInt(Integer.MAX_VALUE);
- req.addProperty("jsonrpc", "2.0");
- req.addProperty("id", id);
- req.addProperty("method", methodName);
+ requestBodyAsJson.addProperty("jsonrpc", "2.0");
+ requestBodyAsJson.addProperty("id", id);
+ requestBodyAsJson.addProperty("method", methodName);
JsonArray params = new JsonArray();
for (Object o : args) {
params.add(gson.toJsonTree(o));
}
- req.add("params", params);
+ requestBodyAsJson.add("params", params);
+
+ String requestBody = requestBodyAsJson.toString();
+ Request request = httpClient.newRequest(uri).method(HttpMethod.POST)
+ .content(new StringContentProvider(requestBody), "application/json");
- String requestData = req.toString();
String responseData = null;
try {
- responseData = post(url, Collections.emptyMap(), requestData);
- } catch (IOException e) {
- throw new MieleRpcException("Exception occurred while posting data", e);
+ final ContentResponse contentResponse = request.send();
+ final int httpStatus = contentResponse.getStatus();
+ if (httpStatus != 200) {
+ if (httpStatus == 503) {
+ throw new MieleRpcException("Gateway is temporarily unavailable");
+ }
+ throw new MieleRpcException("Unexpected HTTP status code " + httpStatus);
+ }
+ responseData = contentResponse.getContentAsString();
+ } catch (TimeoutException e) {
+ throw new MieleRpcException("Timeout when calling gateway", e);
+ } catch (ExecutionException e) {
+ throw new MieleRpcException("Failure when calling gateway", e);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new MieleRpcException("Interrupted while calling gateway", e);
}
- logger.trace("The request '{}' yields '{}'", requestData, responseData);
+ logger.trace("The request '{}' yields '{}'", requestBody, responseData);
JsonObject parsedResponse = null;
try {
parsedResponse = (JsonObject) JsonParser.parseReader(new StringReader(responseData));
String message = (o.has("message") ? o.get("message").getAsString() : null);
String data = (o.has("data")
? (o.get("data") instanceof JsonObject ? o.get("data").toString() : o.get("data").getAsString())
- : null);
+ : "");
throw new MieleRpcException(
"Remote exception occurred: '" + code + "':'" + message + "':'" + data + "'");
} else {
return result;
}
-
- private String post(URL url, Map<String, String> headers, String data) throws IOException {
- HttpURLConnection connection = (HttpURLConnection) url.openConnection();
-
- for (Map.Entry<String, String> entry : headers.entrySet()) {
- connection.addRequestProperty(entry.getKey(), entry.getValue());
- }
-
- connection.addRequestProperty("Accept-Encoding", "gzip");
- connection.setRequestMethod("POST");
- connection.setDoOutput(true);
- connection.connect();
-
- OutputStream out = null;
-
- try {
- out = connection.getOutputStream();
-
- out.write(data.getBytes());
- out.flush();
-
- int statusCode = connection.getResponseCode();
- if (statusCode != HttpURLConnection.HTTP_OK) {
- logger.debug("An unexpected status code was returned: '{}'", statusCode);
- }
- } finally {
- if (out != null) {
- out.close();
- }
- }
-
- String responseEncoding = connection.getHeaderField("Content-Encoding");
- responseEncoding = (responseEncoding == null ? "" : responseEncoding.trim());
-
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
-
- InputStream in = connection.getInputStream();
- try {
- in = connection.getInputStream();
- if ("gzip".equalsIgnoreCase(responseEncoding)) {
- in = new GZIPInputStream(in);
- }
- in = new BufferedInputStream(in);
-
- byte[] buff = new byte[1024];
- int n;
- while ((n = in.read(buff)) > 0) {
- bos.write(buff, 0, n);
- }
- bos.flush();
- bos.close();
- } finally {
- if (in != null) {
- in.close();
- }
- }
-
- return bos.toString();
- }
}
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.miele.internal.discovery.MieleApplianceDiscoveryService;
import org.openhab.binding.miele.internal.handler.CoffeeMachineHandler;
import org.openhab.binding.miele.internal.handler.DishWasherHandler;
import org.openhab.core.config.discovery.DiscoveryService;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
+import org.openhab.core.io.net.http.HttpClientFactory;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
* handlers.
*
* @author Karel Goderis - Initial contribution
+ * @author Jacob Laursen - Refactored to use framework's HTTP client
*/
@NonNullByDefault
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.miele")
MieleApplianceHandler.SUPPORTED_THING_TYPES.stream())
.collect(Collectors.toSet());
+ private final HttpClient httpClient;
private final TranslationProvider i18nProvider;
private final LocaleProvider localeProvider;
private Map<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>();
@Activate
- public MieleHandlerFactory(final @Reference TranslationProvider i18nProvider,
- final @Reference LocaleProvider localeProvider, ComponentContext componentContext) {
+ public MieleHandlerFactory(@Reference final HttpClientFactory httpClientFactory,
+ final @Reference TranslationProvider i18nProvider, final @Reference LocaleProvider localeProvider,
+ ComponentContext componentContext) {
+ this.httpClient = httpClientFactory.getCommonHttpClient();
this.i18nProvider = i18nProvider;
this.localeProvider = localeProvider;
}
@Override
protected @Nullable ThingHandler createHandler(Thing thing) {
if (MieleBridgeHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
- MieleBridgeHandler handler = new MieleBridgeHandler((Bridge) thing);
+ MieleBridgeHandler handler = new MieleBridgeHandler((Bridge) thing, httpClient);
registerApplianceDiscoveryService(handler);
return handler;
} else if (MieleApplianceHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
-import java.net.MalformedURLException;
import java.net.MulticastSocket;
import java.net.SocketTimeoutException;
+import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.IllformedLocaleException;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.miele.internal.FullyQualifiedApplianceIdentifier;
import org.openhab.binding.miele.internal.MieleGatewayCommunicationController;
import org.openhab.binding.miele.internal.api.dto.DeviceClassObject;
private boolean lastBridgeConnectionState = false;
- private Gson gson = new Gson();
+ private final HttpClient httpClient;
+ private final Gson gson = new Gson();
private @NonNullByDefault({}) MieleGatewayCommunicationController gatewayCommunication;
private Set<DiscoveryListener> discoveryListeners = ConcurrentHashMap.newKeySet();
private Map<String, HomeDevice> cachedHomeDevicesByApplianceId = new ConcurrentHashMap<>();
private Map<String, HomeDevice> cachedHomeDevicesByRemoteUid = new ConcurrentHashMap<>();
- public MieleBridgeHandler(Bridge bridge) {
+ public MieleBridgeHandler(Bridge bridge, HttpClient httpClient) {
super(bridge);
+ this.httpClient = httpClient;
}
@Override
public void initialize() {
- logger.debug("Initializing the Miele bridge handler.");
+ logger.debug("Initializing handler for bridge {}", getThing().getUID());
if (!validateConfig(getConfig())) {
return;
}
try {
- gatewayCommunication = new MieleGatewayCommunicationController((String) getConfig().get(HOST));
- } catch (MalformedURLException e) {
+ gatewayCommunication = new MieleGatewayCommunicationController(httpClient, (String) getConfig().get(HOST));
+ } catch (URISyntaxException e) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR, e.getMessage());
return;
}