[hue] Changed discovery to mDNS; added HTTPS handling; refactor HTTPClient to use jetty shared client (#11842)

* Changed discovery to MDNS; added HTTPS handling; refactor HTTPClient to use jetty shared client

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
This commit is contained in:
Christoph Weitkamp
2022-10-22 23:39:51 +02:00
committed by GitHub
parent d2efe69a73
commit ee34d92c17
90 changed files with 1158 additions and 1618 deletions

View File

@@ -26,8 +26,6 @@ Fragment-Host: org.openhab.binding.hue
jakarta.xml.bind-api;version='[2.3.3,2.3.4)',\
org.apache.servicemix.specs.activation-api-1.2.1;version='[1.2.1,1.2.2)',\
org.glassfish.hk2.osgi-resource-locator;version='[1.0.3,1.0.4)',\
org.objectweb.asm.commons;version='[9.0.0,9.0.1)',\
org.objectweb.asm.tree;version='[9.0.0,9.0.1)',\
jakarta.annotation-api;version='[2.0.0,2.0.1)',\
jakarta.inject.jakarta.inject-api;version='[2.0.0,2.0.1)',\
javax.measure.unit-api;version='[2.1.2,2.1.3)',\
@@ -45,12 +43,21 @@ Fragment-Host: org.openhab.binding.hue
org.apache.felix.scr;version='[2.1.30,2.1.31)',\
org.osgi.util.function;version='[1.2.0,1.2.1)',\
org.osgi.util.promise;version='[1.2.0,1.2.1)',\
org.openhab.binding.hue;version='[3.4.0,3.4.1)',\
org.openhab.binding.hue.tests;version='[3.4.0,3.4.1)',\
org.openhab.core;version='[3.4.0,3.4.1)',\
org.openhab.core.binding.xml;version='[3.4.0,3.4.1)',\
org.openhab.core.config.core;version='[3.4.0,3.4.1)',\
org.openhab.core.config.discovery;version='[3.4.0,3.4.1)',\
org.openhab.core.config.xml;version='[3.4.0,3.4.1)',\
org.openhab.core.io.console;version='[3.4.0,3.4.1)',\
org.openhab.core.io.net;version='[3.4.0,3.4.1)',\
org.openhab.core.test;version='[3.4.0,3.4.1)',\
org.openhab.core.thing;version='[3.4.0,3.4.1)',\
org.openhab.core.thing.xml;version='[3.4.0,3.4.1)',\
xstream;version='[1.4.19,1.4.20)',\
com.google.gson;version='[2.8.9,2.8.10)',\
org.objectweb.asm;version='[9.2.0,9.2.1)',\
org.apache.felix.configadmin;version='[1.9.24,1.9.25)',\
org.apache.xbean.bundleutils;version='[4.21.0,4.21.1)',\
org.apache.xbean.finder;version='[4.21.0,4.21.1)',\
org.eclipse.jetty.client;version='[9.4.46,9.4.47)',\
org.eclipse.jetty.http;version='[9.4.46,9.4.47)',\
org.eclipse.jetty.io;version='[9.4.46,9.4.47)',\
@@ -63,22 +70,14 @@ Fragment-Host: org.openhab.binding.hue
org.eclipse.jetty.websocket.client;version='[9.4.46,9.4.47)',\
org.eclipse.jetty.websocket.common;version='[9.4.46,9.4.47)',\
org.ops4j.pax.logging.pax-logging-api;version='[2.0.16,2.0.17)',\
org.ops4j.pax.web.pax-web-api;version='[7.3.25,7.3.26)',\
org.jupnp;version='[2.6.1,2.6.2)',\
ch.qos.logback.classic;version='[1.2.11,1.2.12)',\
ch.qos.logback.core;version='[1.2.11,1.2.12)',\
org.eclipse.jdt.annotation;version='[2.2.100,2.2.101)',\
javax.jmdns;version='[3.5.8,3.5.9)',\
net.bytebuddy.byte-buddy;version='[1.12.1,1.12.2)',\
net.bytebuddy.byte-buddy-agent;version='[1.12.1,1.12.2)',\
org.mockito.mockito-core;version='[4.1.0,4.1.1)',\
org.objenesis;version='[3.2.0,3.2.1)',\
org.openhab.core.config.discovery.mdns;version='[3.4.0,3.4.1)',\
org.openhab.core.io.transport.mdns;version='[3.4.0,3.4.1)',\
biz.aQute.tester.junit-platform;version='[6.3.0,6.3.1)',\
org.openhab.binding.hue;version='[3.4.0,3.4.1)',\
org.openhab.binding.hue.tests;version='[3.4.0,3.4.1)',\
org.openhab.core;version='[3.4.0,3.4.1)',\
org.openhab.core.binding.xml;version='[3.4.0,3.4.1)',\
org.openhab.core.config.core;version='[3.4.0,3.4.1)',\
org.openhab.core.config.discovery;version='[3.4.0,3.4.1)',\
org.openhab.core.config.discovery.upnp;version='[3.4.0,3.4.1)',\
org.openhab.core.config.xml;version='[3.4.0,3.4.1)',\
org.openhab.core.io.console;version='[3.4.0,3.4.1)',\
org.openhab.core.io.net;version='[3.4.0,3.4.1)',\
org.openhab.core.test;version='[3.4.0,3.4.1)',\
org.openhab.core.thing;version='[3.4.0,3.4.1)',\
org.openhab.core.thing.xml;version='[3.4.0,3.4.1)'
ch.qos.logback.classic;version='[1.2.11,1.2.12)',\
ch.qos.logback.core;version='[1.2.11,1.2.12)'

View File

@@ -15,26 +15,35 @@ package org.openhab.binding.hue.internal;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.mock;
import static org.openhab.binding.hue.internal.HueBindingConstants.*;
import static org.openhab.core.thing.Thing.PROPERTY_SERIAL_NUMBER;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.http.HttpStatus;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openhab.binding.hue.internal.config.HueBridgeConfig;
import org.openhab.binding.hue.internal.connection.HueBridge;
import org.openhab.binding.hue.internal.discovery.HueDeviceDiscoveryService;
import org.openhab.binding.hue.internal.dto.FullLight;
import org.openhab.binding.hue.internal.exceptions.ApiException;
import org.openhab.binding.hue.internal.handler.HueBridgeHandler;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.config.discovery.DiscoveryListener;
import org.openhab.core.config.discovery.DiscoveryResult;
import org.openhab.core.config.discovery.DiscoveryResultFlag;
import org.openhab.core.config.discovery.DiscoveryService;
import org.openhab.core.i18n.CommunicationException;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingRegistry;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
@@ -54,7 +63,6 @@ import org.openhab.core.thing.binding.builder.ThingStatusInfoBuilder;
*/
public class HueDeviceDiscoveryServiceOSGiTest extends AbstractHueOSGiTestParent {
protected HueThingHandlerFactory hueThingHandlerFactory;
protected DiscoveryListener discoveryListener;
protected ThingRegistry thingRegistry;
protected Bridge hueBridge;
@@ -74,7 +82,8 @@ public class HueDeviceDiscoveryServiceOSGiTest extends AbstractHueOSGiTestParent
Configuration configuration = new Configuration();
configuration.put(HOST, "1.2.3.4");
configuration.put(USER_NAME, "testUserName");
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
configuration.put(Thing.PROPERTY_SERIAL_NUMBER, "testSerialNumber");
configuration.put("useSelfSignedCertificate", false);
hueBridge = (Bridge) thingRegistry.createThingOfType(BRIDGE_THING_TYPE_UID, BRIDGE_THING_UID, null, "Bridge",
configuration);
@@ -150,45 +159,45 @@ public class HueDeviceDiscoveryServiceOSGiTest extends AbstractHueOSGiTestParent
}
@Test
public void startSearchIsCalled() {
public void startSearchIsCalled() throws IOException, ApiException {
final AtomicBoolean searchHasBeenTriggered = new AtomicBoolean(false);
MockedHttpClient mockedHttpClient = new MockedHttpClient() {
HueBridge mockedHueBridge = new HueBridge(mock(HttpClient.class), "ip", 443, HueBridgeConfig.HTTPS, "username",
Executors.newScheduledThreadPool(1)) {
@Override
public Result put(String address, String body) throws IOException {
return new Result("", 200);
}
@Override
public Result get(String address) throws IOException {
public HueResult get(String address) throws CommunicationException {
if (address.endsWith("testUserName")) {
String body = "{\"lights\":{}}";
return new Result(body, 200);
return new HueResult(body, HttpStatus.OK_200);
} else if (address.endsWith("lights") || address.endsWith("sensors") || address.endsWith("groups")) {
String body = "{}";
return new Result(body, 200);
return new HueResult(body, HttpStatus.OK_200);
} else if (address.endsWith("testUserName/config")) {
String body = "{ \"apiversion\": \"1.26.0\"}";
return new Result(body, 200);
String body = "{\"apiversion\": \"1.26.0\"}";
return new HueResult(body, HttpStatus.OK_200);
} else {
return new Result("", 404);
return new HueResult("", HttpStatus.NOT_FOUND_404);
}
}
@Override
public Result post(String address, String body) throws IOException {
public HueResult post(String address, String body) throws CommunicationException {
if (address.endsWith("lights")) {
String bodyReturn = "{\"success\": {\"/lights\": \"Searching for new devices\"}}";
searchHasBeenTriggered.set(true);
return new Result(bodyReturn, 200);
return new HueResult(bodyReturn, HttpStatus.OK_200);
} else {
return new Result("", 404);
return new HueResult("", HttpStatus.NOT_FOUND_404);
}
}
@Override
public HueResult put(String address, String body) throws CommunicationException {
return new HueResult("", HttpStatus.OK_200);
}
};
installHttpClientMock(hueBridgeHandler, mockedHttpClient);
installHttpClientMock(hueBridgeHandler, mockedHueBridge);
ThingStatusInfo online = ThingStatusInfoBuilder.create(ThingStatus.ONLINE, ThingStatusDetail.NONE).build();
waitForAssert(() -> {
@@ -201,19 +210,17 @@ public class HueDeviceDiscoveryServiceOSGiTest extends AbstractHueOSGiTestParent
});
}
private void installHttpClientMock(HueBridgeHandler hueBridgeHandler, MockedHttpClient mockedHttpClient) {
private void installHttpClientMock(HueBridgeHandler hueBridgeHandler, HueBridge mockedHueBridge) {
waitForAssert(() -> {
try {
// mock HttpClient
final Field hueBridgeField = HueBridgeHandler.class.getDeclaredField("hueBridge");
hueBridgeField.setAccessible(true);
hueBridgeField.set(hueBridgeHandler, mockedHueBridge);
final Object hueBridgeValue = hueBridgeField.get(hueBridgeHandler);
assertThat(hueBridgeValue, is(notNullValue()));
final Field httpClientField = HueBridge.class.getDeclaredField("http");
httpClientField.setAccessible(true);
httpClientField.set(hueBridgeValue, mockedHttpClient);
final Field usernameField = HueBridge.class.getDeclaredField("username");
usernameField.setAccessible(true);
usernameField.set(hueBridgeValue, hueBridgeHandler.getThing().getConfiguration().get(USER_NAME));

View File

@@ -1,20 +0,0 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.hue.internal;
/**
* @author Denis Dudnik - Initial contribution
*/
public class MockedHttpClient extends HttpClient {
}

View File

@@ -1,117 +0,0 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.hue.internal.discovery;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.fail;
import static org.openhab.binding.hue.internal.HueBindingConstants.*;
import static org.openhab.core.thing.Thing.PROPERTY_SERIAL_NUMBER;
import java.net.MalformedURLException;
import java.net.URL;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.jupnp.model.ValidationException;
import org.jupnp.model.meta.DeviceDetails;
import org.jupnp.model.meta.ManufacturerDetails;
import org.jupnp.model.meta.ModelDetails;
import org.jupnp.model.meta.RemoteDevice;
import org.jupnp.model.meta.RemoteDeviceIdentity;
import org.jupnp.model.meta.RemoteService;
import org.jupnp.model.types.DeviceType;
import org.jupnp.model.types.UDN;
import org.openhab.core.config.discovery.DiscoveryResult;
import org.openhab.core.config.discovery.DiscoveryResultFlag;
import org.openhab.core.config.discovery.upnp.UpnpDiscoveryParticipant;
import org.openhab.core.test.java.JavaOSGiTest;
import org.openhab.core.thing.ThingUID;
/**
* Tests for {@link org.openhab.binding.hue.internal.discovery.HueBridgeDiscoveryParticipant}.
*
* @author Kai Kreuzer - Initial contribution
* @author Thomas Höfer - Added representation
* @author Markus Rathgeb - migrated to plain Java test
*/
public class HueBridgeDiscoveryParticipantOSGITest extends JavaOSGiTest {
UpnpDiscoveryParticipant discoveryParticipant;
RemoteDevice hueDevice;
RemoteDevice otherDevice;
@BeforeEach
public void setUp() {
discoveryParticipant = getService(UpnpDiscoveryParticipant.class, HueBridgeDiscoveryParticipant.class);
assertThat(discoveryParticipant, is(notNullValue()));
try {
final RemoteService remoteService = null;
hueDevice = new RemoteDevice(
new RemoteDeviceIdentity(new UDN("123"), 60, new URL("http://hue"), null, null),
new DeviceType("namespace", "type"),
new DeviceDetails(new URL("http://1.2.3.4/"), "Hue Bridge", new ManufacturerDetails("Philips"),
new ModelDetails("Philips hue bridge"), "serial123", "upc", null),
remoteService);
otherDevice = new RemoteDevice(
new RemoteDeviceIdentity(new UDN("567"), 60, new URL("http://acme"), null, null),
new DeviceType("namespace", "type"), new DeviceDetails("Some Device",
new ManufacturerDetails("Taiwan"), new ModelDetails("$%&/"), "serial567", "upc"),
remoteService);
} catch (final ValidationException | MalformedURLException ex) {
fail("Internal test error.");
}
}
@AfterEach
public void cleanUp() {
}
@Test
public void correctSupportedTypes() {
assertThat(discoveryParticipant.getSupportedThingTypeUIDs().size(), is(1));
assertThat(discoveryParticipant.getSupportedThingTypeUIDs().iterator().next(), is(THING_TYPE_BRIDGE));
}
@Test
public void correctThingUID() {
assertThat(discoveryParticipant.getThingUID(hueDevice), is(new ThingUID("hue:bridge:serial123")));
}
@Test
public void validDiscoveryResult() {
final DiscoveryResult result = discoveryParticipant.createResult(hueDevice);
assertThat(result.getFlag(), is(DiscoveryResultFlag.NEW));
assertThat(result.getThingUID(), is(new ThingUID("hue:bridge:serial123")));
assertThat(result.getThingTypeUID(), is(THING_TYPE_BRIDGE));
assertThat(result.getBridgeUID(), is(nullValue()));
assertThat(result.getProperties().get(HOST), is("1.2.3.4"));
assertThat(result.getProperties().get(PROPERTY_SERIAL_NUMBER), is("serial123"));
assertThat(result.getRepresentationProperty(), is(PROPERTY_SERIAL_NUMBER));
}
@Test
public void noThingUIDForUnknownDevice() {
assertThat(discoveryParticipant.getThingUID(otherDevice), is(nullValue()));
}
@Test
public void noDiscoveryResultForUnknownDevice() {
assertThat(discoveryParticipant.createResult(otherDevice), is(nullValue()));
}
}

View File

@@ -37,7 +37,6 @@ import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.ThingUID;
/**
*
* @author Christoph Knauf - Initial contribution
* @author Markus Rathgeb - migrated to plain Java test
*/
@@ -51,64 +50,18 @@ public class HueBridgeNupnpDiscoveryOSGITest extends JavaOSGiTest {
final ThingTypeUID BRIDGE_THING_TYPE_UID = new ThingTypeUID("hue", "bridge");
final String ip1 = "192.168.31.17";
final String ip2 = "192.168.30.28";
final String sn1 = "00178820057f";
final String sn2 = "001788141b41";
final String sn1 = "001788fffe20057f";
final String sn2 = "001788fffe141b41";
final ThingUID BRIDGE_THING_UID_1 = new ThingUID(BRIDGE_THING_TYPE_UID, sn1);
final ThingUID BRIDGE_THING_UID_2 = new ThingUID(BRIDGE_THING_TYPE_UID, sn2);
final String validBridgeDiscoveryResult = "[{\"id\":\"001788fffe20057f\",\"internalipaddress\":" + ip1
+ "},{\"id\":\"001788fffe141b41\",\"internalipaddress\":" + ip2 + "}]";
final String validBridgeDiscoveryResult = "[{\"id\":\"" + sn1 + "\",\"internalipaddress\":" + ip1 + "},{\"id\":\""
+ sn2 + "\",\"internalipaddress\":" + ip2 + "}]";
String discoveryResult;
String expBridgeDescription = "" + //
"<?xml version=\"1.0\"?>" + //
"<root xmlns=\"urn:schemas-upnp-org:device-1-0\">" + //
" <specVersion>" + //
" <major>1</major>" + //
" <minor>0</minor>" + //
" </specVersion>" + //
" <URLBase>http://$IP:80/</URLBase>" + //
" <device>" + //
" <deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>" + //
" <friendlyName>Philips hue ($IP)</friendlyName>" + //
" <manufacturer>Royal Philips Electronics</manufacturer>" + //
" <manufacturerURL>http://www.philips.com</manufacturerURL>" + //
"<modelDescription>Philips hue Personal Wireless Lighting</modelDescription>" + //
"<modelName>Philips hue bridge 2012</modelName>" + //
"<modelNumber>1000000000000</modelNumber>" + //
"<modelURL>http://www.meethue.com</modelURL>" + //
" <serialNumber>93eadbeef13</serialNumber>" + //
" <UDN>uuid:01234567-89ab-cdef-0123-456789abcdef</UDN>" + //
" <serviceList>" + //
" <service>" + //
" <serviceType>(null)</serviceType>" + //
" <serviceId>(null)</serviceId>" + //
" <controlURL>(null)</controlURL>" + //
" <eventSubURL>(null)</eventSubURL>" + //
" <SCPDURL>(null)</SCPDURL>" + //
" </service>" + //
" </serviceList>" + //
" <presentationURL>index.html</presentationURL>" + //
" <iconList>" + //
" <icon>" + //
" <mimetype>image/png</mimetype>" + //
" <height>48</height>" + //
" <width>48</width>" + //
" <depth>24</depth>" + //
" <url>hue_logo_0.png</url>" + //
" </icon>" + //
" <icon>" + //
" <mimetype>image/png</mimetype>" + //
" <height>120</height>" + //
" <width>120</width>" + //
" <depth>24</depth>" + //
" <url>hue_logo_3.png</url>" + //
" </icon>" + //
" </iconList>" + //
" </device>" + //
"</root>";
String expBridgeDescription = "{\"name\":\"Philips Hue\",\"datastoreversion\":\"113\",\"swversion\":\"1948086000\",\"apiversion\":\"1.48.0\",\"mac\":\"00:11:22:33:44\",\"bridgeid\":\"$SN\",\"factorynew\":false,\"replacesbridgeid\":null,\"modelid\":\"BSB002\",\"starterkitid\":\"\"}";
private void checkDiscoveryResult(DiscoveryResult result, String expIp, String expSn) {
assertThat(result.getBridgeUID(), nullValue());
assertThat(result.getLabel(), is(HueBridgeNupnpDiscovery.LABEL_PATTERN.replace("IP", expIp)));
assertThat(result.getLabel(), is(String.format(HueBridgeNupnpDiscovery.LABEL_PATTERN, expIp)));
assertThat(result.getProperties().get("ipAddress"), is(expIp));
assertThat(result.getProperties().get("serialNumber"), is(expSn));
}
@@ -132,9 +85,9 @@ public class HueBridgeNupnpDiscoveryOSGITest extends JavaOSGiTest {
if (url.contains("meethue")) {
return discoveryResult;
} else if (url.contains(ip1)) {
return expBridgeDescription.replaceAll("$IP", ip1);
return expBridgeDescription.replaceAll("$SN", sn1);
} else if (url.contains(ip2)) {
return expBridgeDescription.replaceAll("$IP", ip2);
return expBridgeDescription.replaceAll("$SN", sn2);
}
throw new IOException();
}

View File

@@ -16,19 +16,19 @@ import static org.eclipse.jdt.annotation.Checks.requireNonNull;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.mock;
import static org.openhab.binding.hue.internal.HueBindingConstants.*;
import static org.openhab.binding.hue.internal.config.HueBridgeConfig.HTTP;
import static org.openhab.core.thing.Thing.PROPERTY_SERIAL_NUMBER;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.concurrent.ScheduledExecutorService;
import org.eclipse.jetty.client.HttpClient;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openhab.binding.hue.internal.AbstractHueOSGiTestParent;
import org.openhab.binding.hue.internal.HueBridge;
import org.openhab.binding.hue.internal.HueConfigStatusMessage;
import org.openhab.binding.hue.internal.config.HueBridgeConfig;
import org.openhab.binding.hue.internal.connection.HueBridge;
import org.openhab.binding.hue.internal.exceptions.ApiException;
import org.openhab.binding.hue.internal.exceptions.LinkButtonException;
import org.openhab.binding.hue.internal.exceptions.UnauthorizedException;
@@ -36,6 +36,7 @@ import org.openhab.core.common.ThreadPoolManager;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.config.core.status.ConfigStatusMessage;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingRegistry;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
@@ -72,18 +73,19 @@ public class HueBridgeHandlerOSGiTest extends AbstractHueOSGiTestParent {
public void assertThatANewUserIsAddedToConfigIfNotExistingYet() {
Configuration configuration = new Configuration();
configuration.put(HOST, DUMMY_HOST);
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
configuration.put(Thing.PROPERTY_SERIAL_NUMBER, "testSerialNumber");
Bridge bridge = createBridgeThing(configuration);
HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
hueBridgeHandler.thingUpdated(bridge);
injectBridge(hueBridgeHandler, new HueBridge(DUMMY_HOST, 80, HTTP, scheduler) {
@Override
public String link(String deviceType) throws IOException, ApiException {
return TEST_USER_NAME;
}
});
injectBridge(hueBridgeHandler,
new HueBridge(mock(HttpClient.class), DUMMY_HOST, 80, HueBridgeConfig.HTTP, scheduler) {
@Override
public String link(String deviceType) throws IOException, ApiException {
return TEST_USER_NAME;
}
});
hueBridgeHandler.onNotAuthenticated();
@@ -95,17 +97,18 @@ public class HueBridgeHandlerOSGiTest extends AbstractHueOSGiTestParent {
Configuration configuration = new Configuration();
configuration.put(HOST, DUMMY_HOST);
configuration.put(USER_NAME, TEST_USER_NAME);
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
configuration.put(Thing.PROPERTY_SERIAL_NUMBER, "testSerialNumber");
Bridge bridge = createBridgeThing(configuration);
HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
hueBridgeHandler.thingUpdated(bridge);
injectBridge(hueBridgeHandler, new HueBridge(DUMMY_HOST, 80, HTTP, scheduler) {
@Override
public void authenticate(String userName) throws IOException, ApiException {
}
});
injectBridge(hueBridgeHandler,
new HueBridge(mock(HttpClient.class), DUMMY_HOST, 80, HueBridgeConfig.HTTP, scheduler) {
@Override
public void authenticate(String userName) throws IOException, ApiException {
}
});
hueBridgeHandler.onNotAuthenticated();
@@ -117,18 +120,19 @@ public class HueBridgeHandlerOSGiTest extends AbstractHueOSGiTestParent {
Configuration configuration = new Configuration();
configuration.put(HOST, DUMMY_HOST);
configuration.put(USER_NAME, "notAuthenticatedUser");
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
configuration.put(Thing.PROPERTY_SERIAL_NUMBER, "testSerialNumber");
Bridge bridge = createBridgeThing(configuration);
HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
hueBridgeHandler.thingUpdated(bridge);
injectBridge(hueBridgeHandler, new HueBridge(DUMMY_HOST, 80, HTTP, scheduler) {
@Override
public void authenticate(String userName) throws IOException, ApiException {
throw new UnauthorizedException();
}
});
injectBridge(hueBridgeHandler,
new HueBridge(mock(HttpClient.class), DUMMY_HOST, 80, HueBridgeConfig.HTTP, scheduler) {
@Override
public void authenticate(String userName) throws IOException, ApiException {
throw new UnauthorizedException();
}
});
hueBridgeHandler.onNotAuthenticated();
@@ -141,18 +145,19 @@ public class HueBridgeHandlerOSGiTest extends AbstractHueOSGiTestParent {
public void verifyStatusIfLinkButtonIsNotPressed() {
Configuration configuration = new Configuration();
configuration.put(HOST, DUMMY_HOST);
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
configuration.put(Thing.PROPERTY_SERIAL_NUMBER, "testSerialNumber");
Bridge bridge = createBridgeThing(configuration);
HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
hueBridgeHandler.thingUpdated(bridge);
injectBridge(hueBridgeHandler, new HueBridge(DUMMY_HOST, 80, HTTP, scheduler) {
@Override
public String link(String deviceType) throws IOException, ApiException {
throw new LinkButtonException();
}
});
injectBridge(hueBridgeHandler,
new HueBridge(mock(HttpClient.class), DUMMY_HOST, 80, HueBridgeConfig.HTTP, scheduler) {
@Override
public String link(String deviceType) throws IOException, ApiException {
throw new LinkButtonException();
}
});
hueBridgeHandler.onNotAuthenticated();
@@ -165,18 +170,19 @@ public class HueBridgeHandlerOSGiTest extends AbstractHueOSGiTestParent {
public void verifyStatusIfNewUserCannotBeCreated() {
Configuration configuration = new Configuration();
configuration.put(HOST, DUMMY_HOST);
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
configuration.put(Thing.PROPERTY_SERIAL_NUMBER, "testSerialNumber");
Bridge bridge = createBridgeThing(configuration);
HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
hueBridgeHandler.thingUpdated(bridge);
injectBridge(hueBridgeHandler, new HueBridge(DUMMY_HOST, 80, HTTP, scheduler) {
@Override
public String link(String deviceType) throws IOException, ApiException {
throw new ApiException();
}
});
injectBridge(hueBridgeHandler,
new HueBridge(mock(HttpClient.class), DUMMY_HOST, 80, HueBridgeConfig.HTTP, scheduler) {
@Override
public String link(String deviceType) throws IOException, ApiException {
throw new ApiException();
}
});
hueBridgeHandler.onNotAuthenticated();
@@ -190,7 +196,7 @@ public class HueBridgeHandlerOSGiTest extends AbstractHueOSGiTestParent {
public void verifyOfflineIsSetWithoutBridgeOfflineStatus() {
Configuration configuration = new Configuration();
configuration.put(HOST, DUMMY_HOST);
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
configuration.put(Thing.PROPERTY_SERIAL_NUMBER, "testSerialNumber");
Bridge bridge = createBridgeThing(configuration);
HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
@@ -206,14 +212,13 @@ public class HueBridgeHandlerOSGiTest extends AbstractHueOSGiTestParent {
public void assertThatAStatusConfigurationMessageForMissingBridgeIPIsProperlyReturnedIPIsNull() {
Configuration configuration = new Configuration();
configuration.put(HOST, null);
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
configuration.put(Thing.PROPERTY_SERIAL_NUMBER, "testSerialNumber");
Bridge bridge = createBridgeThing(configuration);
HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
ConfigStatusMessage expected = ConfigStatusMessage.Builder.error(HOST)
.withMessageKeySuffix(HueConfigStatusMessage.IP_ADDRESS_MISSING).withArguments(HOST).build();
ConfigStatusMessage expected = ConfigStatusMessage.Builder.error(HOST).withMessageKeySuffix(IP_ADDRESS_MISSING)
.withArguments(HOST).build();
waitForAssert(() -> assertEquals(expected, hueBridgeHandler.getConfigStatus().iterator().next()));
}
@@ -222,19 +227,19 @@ public class HueBridgeHandlerOSGiTest extends AbstractHueOSGiTestParent {
public void assertThatAStatusConfigurationMessageForMissingBridgeIPIsProperlyReturnedIPIsAnEmptyString() {
Configuration configuration = new Configuration();
configuration.put(HOST, "");
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
configuration.put(Thing.PROPERTY_SERIAL_NUMBER, "testSerialNumber");
Bridge bridge = createBridgeThing(configuration);
HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
ConfigStatusMessage expected = ConfigStatusMessage.Builder.error(HOST)
.withMessageKeySuffix(HueConfigStatusMessage.IP_ADDRESS_MISSING).withArguments(HOST).build();
ConfigStatusMessage expected = ConfigStatusMessage.Builder.error(HOST).withMessageKeySuffix(IP_ADDRESS_MISSING)
.withArguments(HOST).build();
waitForAssert(() -> assertEquals(expected, hueBridgeHandler.getConfigStatus().iterator().next()));
}
private Bridge createBridgeThing(Configuration configuration) {
configuration.put("useSelfSignedCertificate", false);
Bridge bridge = (Bridge) thingRegistry.createThingOfType(BRIDGE_THING_TYPE_UID,
new ThingUID(BRIDGE_THING_TYPE_UID, "testBridge"), null, "Bridge", configuration);