[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:
committed by
GitHub
parent
d2efe69a73
commit
ee34d92c17
@@ -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)'
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user