mirror of
https://github.com/danieldemus/openhab-core.git
synced 2025-01-10 13:21:53 +01:00
Wait for thing-type available in PersistentInbox (#2981)
Signed-off-by: Jan N. Klug <github@klug.nrw>
This commit is contained in:
parent
603988a963
commit
836ae89489
@ -13,6 +13,7 @@
|
||||
package org.openhab.core.config.discovery.inbox;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
@ -57,7 +58,7 @@ public interface Inbox {
|
||||
* @param result the discovery result to be added to this inbox (could be null)
|
||||
* @return true if the specified discovery result could be added or updated, otherwise false
|
||||
*/
|
||||
boolean add(@Nullable DiscoveryResult result);
|
||||
CompletableFuture<Boolean> add(@Nullable DiscoveryResult result);
|
||||
|
||||
/**
|
||||
* Removes the {@link DiscoveryResult} associated with the specified {@code Thing} ID from
|
||||
|
@ -26,9 +26,11 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
@ -140,6 +142,8 @@ public final class PersistentInbox implements Inbox, DiscoveryListener, ThingReg
|
||||
private final Storage<DiscoveryResult> discoveryResultStorage;
|
||||
private final Map<DiscoveryResult, Class<?>> resultDiscovererMap = new ConcurrentHashMap<>();
|
||||
private @NonNullByDefault({}) ScheduledFuture<?> timeToLiveChecker;
|
||||
private @NonNullByDefault({}) ScheduledFuture<?> delayedDiscoveryResultProcessor;
|
||||
|
||||
private @Nullable EventPublisher eventPublisher;
|
||||
private final List<ThingHandlerFactory> thingHandlerFactories = new CopyOnWriteArrayList<>();
|
||||
|
||||
@ -163,8 +167,11 @@ public final class PersistentInbox implements Inbox, DiscoveryListener, ThingReg
|
||||
protected void activate() {
|
||||
discoveryServiceRegistry.addDiscoveryListener(this);
|
||||
thingRegistry.addRegistryChangeListener(this);
|
||||
timeToLiveChecker = ThreadPoolManager.getScheduledPool("discovery")
|
||||
.scheduleWithFixedDelay(new TimeToLiveCheckingThread(this), 0, 30, TimeUnit.SECONDS);
|
||||
ScheduledExecutorService scheduler = ThreadPoolManager.getScheduledPool("discovery");
|
||||
timeToLiveChecker = scheduler.scheduleWithFixedDelay(new TimeToLiveCheckingThread(this), 0, 30,
|
||||
TimeUnit.SECONDS);
|
||||
delayedDiscoveryResultProcessor = scheduler.scheduleWithFixedDelay(
|
||||
() -> Set.copyOf(delayedDiscoveryResults.values()).forEach(this::internalAdd), 0, 15, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Deactivate
|
||||
@ -173,6 +180,8 @@ public final class PersistentInbox implements Inbox, DiscoveryListener, ThingReg
|
||||
discoveryServiceRegistry.removeDiscoveryListener(this);
|
||||
listeners.clear();
|
||||
timeToLiveChecker.cancel(true);
|
||||
delayedDiscoveryResultProcessor.cancel(true);
|
||||
delayedDiscoveryResults.values().forEach(dr -> dr.future.complete(false));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -219,14 +228,47 @@ public final class PersistentInbox implements Inbox, DiscoveryListener, ThingReg
|
||||
return newThing;
|
||||
}
|
||||
|
||||
private Map<ThingUID, DiscoveryResultWrapper> delayedDiscoveryResults = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public synchronized boolean add(final @Nullable DiscoveryResult discoveryResult) throws IllegalStateException {
|
||||
public synchronized CompletableFuture<Boolean> add(final @Nullable DiscoveryResult discoveryResult)
|
||||
throws IllegalStateException {
|
||||
if (discoveryResult == null) {
|
||||
return false;
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
|
||||
CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
internalAdd(new DiscoveryResultWrapper(discoveryResult, future));
|
||||
return future;
|
||||
}
|
||||
|
||||
private void internalAdd(DiscoveryResultWrapper discoveryResultWrapper) {
|
||||
DiscoveryResult discoveryResult = discoveryResultWrapper.discoveryResult;
|
||||
|
||||
// if we already have a result for the same ThingUID that is not added yet, delete it from the delayed map
|
||||
delayedDiscoveryResults.remove(discoveryResult.getThingUID());
|
||||
|
||||
ThingType thingType = thingTypeRegistry.getThingType(discoveryResult.getThingTypeUID());
|
||||
List<String> configurationParameters = thingType != null ? getConfigDescParams(thingType).stream()
|
||||
.map(ConfigDescriptionParameter::getName).collect(Collectors.toList()) : List.of();
|
||||
if (thingType == null) {
|
||||
discoveryResultWrapper.retryCount++;
|
||||
|
||||
if (discoveryResultWrapper.retryCount >= 20) {
|
||||
logger.info(
|
||||
"ThingTypeUID {} for discovery result with ThingUID {} not found, retried 20 times, aborting",
|
||||
discoveryResult.getThingTypeUID(), discoveryResult.getThingUID());
|
||||
discoveryResultWrapper.future.complete(false);
|
||||
} else {
|
||||
logger.trace(
|
||||
"ThingTypeUID {} for discovery result with ThingUID {} not found, delaying add, retry {}/20",
|
||||
discoveryResult.getThingTypeUID(), discoveryResult.getThingUID(),
|
||||
discoveryResultWrapper.retryCount);
|
||||
delayedDiscoveryResults.put(discoveryResult.getThingUID(), discoveryResultWrapper);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> configurationParameters = getConfigDescParams(thingType).stream()
|
||||
.map(ConfigDescriptionParameter::getName).collect(Collectors.toList());
|
||||
|
||||
discoveryResult.normalizePropertiesOnConfigDescription(configurationParameters);
|
||||
|
||||
@ -240,7 +282,7 @@ public final class PersistentInbox implements Inbox, DiscoveryListener, ThingReg
|
||||
discoveryResultStorage.put(discoveryResult.getThingUID().toString(), discoveryResult);
|
||||
notifyListeners(discoveryResult, EventType.ADDED);
|
||||
logger.info("Added new thing '{}' to inbox.", thingUID);
|
||||
return true;
|
||||
discoveryResultWrapper.future.complete(true);
|
||||
} else {
|
||||
if (inboxResult instanceof DiscoveryResultImpl) {
|
||||
DiscoveryResultImpl resultImpl = (DiscoveryResultImpl) inboxResult;
|
||||
@ -248,7 +290,7 @@ public final class PersistentInbox implements Inbox, DiscoveryListener, ThingReg
|
||||
discoveryResultStorage.put(discoveryResult.getThingUID().toString(), resultImpl);
|
||||
notifyListeners(resultImpl, EventType.UPDATED);
|
||||
logger.debug("Updated discovery result for '{}'.", thingUID);
|
||||
return true;
|
||||
discoveryResultWrapper.future.complete(true);
|
||||
} else {
|
||||
logger.warn("Cannot synchronize result with implementation class '{}'.",
|
||||
inboxResult.getClass().getName());
|
||||
@ -269,7 +311,7 @@ public final class PersistentInbox implements Inbox, DiscoveryListener, ThingReg
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
discoveryResultWrapper.future.complete(false);
|
||||
}
|
||||
|
||||
private boolean synchronizeConfiguration(ThingTypeUID thingTypeUID, Map<String, Object> properties,
|
||||
@ -377,9 +419,11 @@ public final class PersistentInbox implements Inbox, DiscoveryListener, ThingReg
|
||||
|
||||
@Override
|
||||
public void thingDiscovered(DiscoveryService source, DiscoveryResult result) {
|
||||
if (add(result)) {
|
||||
resultDiscovererMap.put(result, source.getClass());
|
||||
}
|
||||
add(result).thenAccept(success -> {
|
||||
if (success) {
|
||||
resultDiscovererMap.put(result, source.getClass());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -606,6 +650,13 @@ public final class PersistentInbox implements Inbox, DiscoveryListener, ThingReg
|
||||
.scheduleWithFixedDelay(new TimeToLiveCheckingThread(this), 0, interval, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
void setDiscoveryResultAddRetryInterval(int interval) {
|
||||
delayedDiscoveryResultProcessor.cancel(true);
|
||||
delayedDiscoveryResultProcessor = ThreadPoolManager.getScheduledPool("discovery").scheduleWithFixedDelay(
|
||||
() -> Set.copyOf(delayedDiscoveryResults.values()).forEach(this::internalAdd), 0, interval,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC)
|
||||
protected void setEventPublisher(EventPublisher eventPublisher) {
|
||||
this.eventPublisher = eventPublisher;
|
||||
@ -623,4 +674,15 @@ public final class PersistentInbox implements Inbox, DiscoveryListener, ThingReg
|
||||
protected void removeThingHandlerFactory(ThingHandlerFactory thingHandlerFactory) {
|
||||
this.thingHandlerFactories.remove(thingHandlerFactory);
|
||||
}
|
||||
|
||||
private static class DiscoveryResultWrapper {
|
||||
public final CompletableFuture<Boolean> future;
|
||||
public final DiscoveryResult discoveryResult;
|
||||
public int retryCount = 0;
|
||||
|
||||
public DiscoveryResultWrapper(DiscoveryResult discoveryResult, CompletableFuture<Boolean> future) {
|
||||
this.discoveryResult = discoveryResult;
|
||||
this.future = future;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,9 +84,12 @@ public class PersistentInboxTest {
|
||||
private @Mock @NonNullByDefault({}) ThingTypeRegistry thingTypeRegistryMock;
|
||||
private @Mock @NonNullByDefault({}) ConfigDescriptionRegistry configDescriptionRegistryMock;
|
||||
private @Mock @NonNullByDefault({}) ThingHandlerFactory thingHandlerFactoryMock;
|
||||
private @Mock @NonNullByDefault({}) ThingType thingTypeMock;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(thingTypeMock.getConfigDescriptionURI()).thenReturn(null);
|
||||
when(thingTypeRegistryMock.getThingType(any())).thenReturn(thingTypeMock);
|
||||
when(storageServiceMock.getStorage(any(String.class), any(ClassLoader.class))).thenReturn(storageMock);
|
||||
doAnswer(invocation -> lastAddedThing = (Thing) invocation.getArguments()[0]).when(thingRegistryMock)
|
||||
.add(any(Thing.class));
|
||||
|
@ -29,10 +29,12 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.openhab.core.config.discovery.inbox.Inbox;
|
||||
import org.openhab.core.config.discovery.test.DummyThingTypeProvider;
|
||||
import org.openhab.core.test.java.JavaOSGiTest;
|
||||
import org.openhab.core.thing.ThingRegistry;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.type.ThingTypeBuilder;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
|
||||
/**
|
||||
@ -56,12 +58,18 @@ public class DiscoveryServiceRegistryOSGiTest extends JavaOSGiTest {
|
||||
|
||||
private static final String ANY_BINDING_ID_1 = "any2BindingId1";
|
||||
private static final String ANY_THING_TYPE_1 = "any2ThingType1";
|
||||
private static final ThingTypeUID ANY_BINDING_ID_1_ANY_THING_TYPE_1_UID = new ThingTypeUID(ANY_BINDING_ID_1,
|
||||
ANY_THING_TYPE_1);
|
||||
|
||||
private static final String ANY_BINDING_ID_2 = "any2BindingId2";
|
||||
private static final String ANY_THING_TYPE_2 = "any2ThingType2";
|
||||
private static final ThingTypeUID ANY_BINDING_ID_2_ANY_THING_TYPE_2_UID = new ThingTypeUID(ANY_BINDING_ID_2,
|
||||
ANY_THING_TYPE_2);
|
||||
|
||||
private static final String ANY_BINDING_ID_3 = "any2BindingId3";
|
||||
private static final String ANY_THING_TYPE_3 = "any2ThingType3";
|
||||
private static final ThingTypeUID ANY_BINDING_ID_3_ANY_THING_TYPE_3_UID = new ThingTypeUID(ANY_BINDING_ID_3,
|
||||
ANY_THING_TYPE_3);
|
||||
|
||||
private static final ThingUID BRIDGE_UID_1 = new ThingUID(ANY_BINDING_ID_3, "bridge", "1");
|
||||
private static final ThingUID BRIDGE_UID_2 = new ThingUID(ANY_BINDING_ID_3, "bridge", "2");
|
||||
@ -88,20 +96,30 @@ public class DiscoveryServiceRegistryOSGiTest extends JavaOSGiTest {
|
||||
|
||||
private @Mock @NonNullByDefault({}) DiscoveryListener discoveryListenerMock;
|
||||
|
||||
private @NonNullByDefault({}) DummyThingTypeProvider dummyThingTypeProvider;
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach() {
|
||||
registerVolatileStorageService();
|
||||
|
||||
dummyThingTypeProvider = new DummyThingTypeProvider();
|
||||
registerService(dummyThingTypeProvider);
|
||||
|
||||
dummyThingTypeProvider.add(ANY_BINDING_ID_1_ANY_THING_TYPE_1_UID,
|
||||
ThingTypeBuilder.instance(ANY_BINDING_ID_1_ANY_THING_TYPE_1_UID, "label1").build());
|
||||
dummyThingTypeProvider.add(ANY_BINDING_ID_2_ANY_THING_TYPE_2_UID,
|
||||
ThingTypeBuilder.instance(ANY_BINDING_ID_2_ANY_THING_TYPE_2_UID, "label2").build());
|
||||
dummyThingTypeProvider.add(ANY_BINDING_ID_3_ANY_THING_TYPE_3_UID,
|
||||
ThingTypeBuilder.instance(ANY_BINDING_ID_3_ANY_THING_TYPE_3_UID, "label3").build());
|
||||
|
||||
thingRegistry = getService(ThingRegistry.class);
|
||||
assertNotNull(thingRegistry);
|
||||
|
||||
inbox = getService(Inbox.class);
|
||||
assertNotNull(inbox);
|
||||
|
||||
discoveryServiceMockForBinding1 = new DiscoveryServiceMock(new ThingTypeUID(ANY_BINDING_ID_1, ANY_THING_TYPE_1),
|
||||
1);
|
||||
discoveryServiceMockForBinding2 = new DiscoveryServiceMock(new ThingTypeUID(ANY_BINDING_ID_2, ANY_THING_TYPE_2),
|
||||
3);
|
||||
discoveryServiceMockForBinding1 = new DiscoveryServiceMock(ANY_BINDING_ID_1_ANY_THING_TYPE_1_UID, 1);
|
||||
discoveryServiceMockForBinding2 = new DiscoveryServiceMock(ANY_BINDING_ID_2_ANY_THING_TYPE_2_UID, 3);
|
||||
|
||||
discoveryServiceMockForBinding3Bridge1 = new DiscoveryServiceMockOfBridge(
|
||||
new ThingTypeUID(ANY_BINDING_ID_3, ANY_THING_TYPE_3), 1, BRIDGE_UID_1);
|
||||
@ -270,7 +288,7 @@ public class DiscoveryServiceRegistryOSGiTest extends JavaOSGiTest {
|
||||
ScanListener mockScanListener1 = mock(ScanListener.class);
|
||||
|
||||
discoveryServiceRegistry.addDiscoveryListener(discoveryListenerMock);
|
||||
discoveryServiceRegistry.startScan(new ThingTypeUID(ANY_BINDING_ID_3, ANY_THING_TYPE_3), mockScanListener1);
|
||||
discoveryServiceRegistry.startScan(ANY_BINDING_ID_3_ANY_THING_TYPE_3_UID, mockScanListener1);
|
||||
|
||||
waitForAssert(() -> verify(mockScanListener1, times(1)).onFinished());
|
||||
verify(discoveryListenerMock, times(2)).thingDiscovered(any(), any());
|
||||
|
@ -31,6 +31,8 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
@ -54,6 +56,7 @@ import org.openhab.core.config.discovery.inbox.InboxListener;
|
||||
import org.openhab.core.config.discovery.inbox.events.InboxAddedEvent;
|
||||
import org.openhab.core.config.discovery.inbox.events.InboxRemovedEvent;
|
||||
import org.openhab.core.config.discovery.inbox.events.InboxUpdatedEvent;
|
||||
import org.openhab.core.config.discovery.test.DummyThingTypeProvider;
|
||||
import org.openhab.core.events.Event;
|
||||
import org.openhab.core.events.EventFilter;
|
||||
import org.openhab.core.events.EventSubscriber;
|
||||
@ -140,7 +143,7 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
private final String discoveryResultLabel = "MyLabel";
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private final Map<String, Object> discoveryResultProperties = new LinkedHashMap<String, Object>() {
|
||||
private final Map<String, Object> discoveryResultProperties = new LinkedHashMap<>() {
|
||||
{
|
||||
put("ip", "192.168.3.99");
|
||||
put("pnr", 1234455);
|
||||
@ -172,6 +175,10 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
private @NonNullByDefault({}) ManagedThingProvider managedThingProvider;
|
||||
private @NonNullByDefault({}) ThingRegistry registry;
|
||||
|
||||
private @NonNullByDefault({}) ThingTypeRegistry thingTypeRegistry;
|
||||
|
||||
private @NonNullByDefault({}) DummyThingTypeProvider dummyThingTypeProvider;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
registerVolatileStorageService();
|
||||
@ -179,6 +186,16 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
discoveryResults.clear();
|
||||
inboxListeners.clear();
|
||||
|
||||
dummyThingTypeProvider = new DummyThingTypeProvider();
|
||||
registerService(dummyThingTypeProvider);
|
||||
|
||||
dummyThingTypeProvider.add(testTypeUID, testThingType);
|
||||
dummyThingTypeProvider.add(THING_TYPE_UID, testThingType);
|
||||
dummyThingTypeProvider.add(BRIDGE_THING_TYPE_UID, testThingType);
|
||||
|
||||
thingTypeRegistry = getService(ThingTypeRegistry.class);
|
||||
assertThat(thingTypeRegistry, is(notNullValue()));
|
||||
|
||||
inbox = (PersistentInbox) getService(Inbox.class);
|
||||
assertThat(inbox, is(notNullValue()));
|
||||
|
||||
@ -237,11 +254,15 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
}
|
||||
|
||||
private boolean addDiscoveryResult(DiscoveryResult discoveryResult) {
|
||||
boolean result = inbox.add(discoveryResult);
|
||||
if (result) {
|
||||
discoveryResults.put(discoveryResult.getThingUID(), discoveryResult);
|
||||
CompletableFuture<Boolean> future = inbox.add(discoveryResult);
|
||||
waitForAssert(() -> assertThat(future.isDone(), is(true)));
|
||||
|
||||
try {
|
||||
return future.get();
|
||||
} catch (ExecutionException | InterruptedException ignored) {
|
||||
}
|
||||
return result;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean removeDiscoveryResult(ThingUID thingUID) {
|
||||
@ -261,6 +282,7 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
@Test
|
||||
public void assertThatGetAllIncludesPreviouslyAddedDiscoveryResult() {
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID("dummyBindingId", "dummyThingType");
|
||||
dummyThingTypeProvider.add(thingTypeUID, testThingType);
|
||||
ThingUID thingUID = new ThingUID(thingTypeUID, "thingId");
|
||||
|
||||
List<DiscoveryResult> allDiscoveryResults = inbox.getAll();
|
||||
@ -294,6 +316,8 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
@Test
|
||||
public void assertThatGetAllIncludesPreviouslyUpdatedDiscoveryResult() {
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID("dummyBindingId", "dummyThingType");
|
||||
dummyThingTypeProvider.add(thingTypeUID, testThingType);
|
||||
|
||||
ThingUID thingUID = new ThingUID(thingTypeUID, "dummyThingId");
|
||||
|
||||
List<DiscoveryResult> allDiscoveryResults = inbox.getAll();
|
||||
@ -335,6 +359,8 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
@Test
|
||||
public void assertThatGetAllIncludesTwoPreviouslyAddedDiscoveryResults() {
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID("dummyBindingId", "dummyThingType");
|
||||
dummyThingTypeProvider.add(thingTypeUID, testThingType);
|
||||
|
||||
ThingUID thingUID = new ThingUID(thingTypeUID, "dummyThingId");
|
||||
|
||||
List<DiscoveryResult> allDiscoveryResults = inbox.getAll();
|
||||
@ -358,6 +384,8 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
@Test
|
||||
public void assertThatGetAllNotIncludesRemovedDiscoveryResult() {
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID("dummyBindingId", "dummyThingType");
|
||||
dummyThingTypeProvider.add(thingTypeUID, testThingType);
|
||||
|
||||
ThingUID thingUID = new ThingUID(thingTypeUID, "dummyThingId");
|
||||
|
||||
List<DiscoveryResult> allDiscoveryResults = inbox.getAll();
|
||||
@ -384,6 +412,8 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
@Test
|
||||
public void assertThatGetAllIncludesRemovedUpdatedDiscoveryResult() {
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID("dummyBindingId", "dummyThingType");
|
||||
dummyThingTypeProvider.add(thingTypeUID, testThingType);
|
||||
|
||||
ThingUID thingUID = new ThingUID(thingTypeUID, "dummyThingId");
|
||||
|
||||
List<DiscoveryResult> allDiscoveryResults = inbox.getAll();
|
||||
@ -423,6 +453,8 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
@Test
|
||||
public void assertThatInboxListenerIsNotifiedAboutPreviouslyAddedDiscoveryResult() {
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID("dummyBindingId", "dummyThingType");
|
||||
dummyThingTypeProvider.add(thingTypeUID, testThingType);
|
||||
|
||||
ThingUID thingUID = new ThingUID(thingTypeUID, "dummyThingId");
|
||||
|
||||
List<DiscoveryResult> allDiscoveryResults = inbox.getAll();
|
||||
@ -488,6 +520,8 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
@Test
|
||||
public void assertThatInboxListenerIsNotifiedAboutPreviouslyUpdatedDiscoveryResult() {
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID("dummyBindingId", "dummyThingType");
|
||||
dummyThingTypeProvider.add(thingTypeUID, testThingType);
|
||||
|
||||
ThingUID thingUID = new ThingUID(thingTypeUID, "dummyThingId");
|
||||
|
||||
List<DiscoveryResult> allDiscoveryResults = inbox.getAll();
|
||||
@ -560,6 +594,8 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
@Test
|
||||
public void assertThatInboxListenerIsNotifiedAboutPreviouslyRemovedDiscoveryResult() {
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID("dummyBindingId", "dummyThingType");
|
||||
dummyThingTypeProvider.add(thingTypeUID, testThingType);
|
||||
|
||||
ThingUID thingUID = new ThingUID(thingTypeUID, "dummyThingId");
|
||||
|
||||
List<DiscoveryResult> allDiscoveryResults = inbox.getAll();
|
||||
@ -628,6 +664,8 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
assertThat(inbox.getAll().size(), is(0));
|
||||
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID("dummyBindingId", "dummyThingType");
|
||||
dummyThingTypeProvider.add(thingTypeUID, testThingType);
|
||||
|
||||
ThingUID thingUID = new ThingUID(thingTypeUID, "dummyThingId");
|
||||
|
||||
Map<String, Object> props = new HashMap<>();
|
||||
@ -653,6 +691,7 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID("dummyBindingId", "dummyThingType");
|
||||
ThingUID thingUID = new ThingUID(thingTypeUID, "dummyThingId");
|
||||
dummyThingTypeProvider.add(thingTypeUID, testThingType);
|
||||
|
||||
managedThingProvider.add(ThingBuilder.create(thingTypeUID, "dummyThingId").build());
|
||||
|
||||
@ -673,6 +712,8 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
assertThat(inbox.getAll().size(), is(0));
|
||||
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID("dummyBindingId2", "dummyThingType");
|
||||
dummyThingTypeProvider.add(thingTypeUID, testThingType);
|
||||
|
||||
ThingUID thingUID = new ThingUID(thingTypeUID, "dummyThingId");
|
||||
|
||||
managedThingProvider.add(ThingBuilder.create(thingTypeUID, "dummyThingId").build());
|
||||
@ -699,6 +740,8 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
@Test
|
||||
public void assertThatInboxEventSubscribersReceiveEventsAboutDiscoveryResultChanges() {
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID("some", "thing");
|
||||
dummyThingTypeProvider.add(thingTypeUID, testThingType);
|
||||
|
||||
ThingUID thingUID = new ThingUID(thingTypeUID, "uid");
|
||||
final AsyncResultWrapper<Event> receivedEvent = new AsyncResultWrapper<>();
|
||||
|
||||
@ -914,6 +957,7 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
@Test
|
||||
@SuppressWarnings("null")
|
||||
public void assertThatApproveSetsTheDiscoveredLabelIfNoOtherIsGiven() {
|
||||
|
||||
inbox.add(testDiscoveryResult);
|
||||
Thing approvedThing = inbox.approve(testThing.getUID(), null, null);
|
||||
Thing addedThing = registry.get(testThing.getUID());
|
||||
@ -1025,6 +1069,40 @@ public class InboxOSGiTest extends JavaOSGiTest {
|
||||
assertThat(inbox.getAll().size(), is(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertThatResultWithMissingThingTypeNotAdded() throws ExecutionException, InterruptedException {
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID("bindingId", "missingThingType");
|
||||
ThingUID thingUID = new ThingUID("bindingId", "missingThingType", "thingId");
|
||||
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withThingType(thingTypeUID).build();
|
||||
|
||||
// reduce time between retries to ensure the test does not time out
|
||||
inbox.setDiscoveryResultAddRetryInterval(1);
|
||||
|
||||
CompletableFuture future = inbox.add(discoveryResult);
|
||||
|
||||
waitForAssert(() -> future.isDone(), 30, 5);
|
||||
|
||||
assertThat(future.get(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertThatResultWithLaterAddedThingTypeIsAdded() throws ExecutionException, InterruptedException {
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID("bindingId", "missingThingType");
|
||||
ThingUID thingUID = new ThingUID("bindingId", "missingThingType", "thingId");
|
||||
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withThingType(thingTypeUID).build();
|
||||
|
||||
// reduce time between retries to ensure the test does not time out
|
||||
inbox.setDiscoveryResultAddRetryInterval(1);
|
||||
|
||||
CompletableFuture future = inbox.add(discoveryResult);
|
||||
|
||||
dummyThingTypeProvider.add(thingTypeUID, ThingTypeBuilder.instance(thingTypeUID, "label").build());
|
||||
|
||||
waitForAssert(() -> future.isDone(), 30, 5);
|
||||
|
||||
assertThat(future.get(), is(true));
|
||||
}
|
||||
|
||||
class DummyThingHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
public DummyThingHandlerFactory(ComponentContext context) {
|
||||
|
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* 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.core.config.discovery.test;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.ThingTypeProvider;
|
||||
import org.openhab.core.thing.type.ThingType;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
||||
/**
|
||||
* The {@link DummyThingTypeProvider} is used in tests to provide thing types
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true)
|
||||
public class DummyThingTypeProvider implements ThingTypeProvider {
|
||||
|
||||
private final Map<ThingTypeUID, ThingType> thingTypeMap = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public Collection<ThingType> getThingTypes(@Nullable Locale locale) {
|
||||
return thingTypeMap.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ThingType getThingType(ThingTypeUID thingTypeUID, @Nullable Locale locale) {
|
||||
return thingTypeMap.get(thingTypeUID);
|
||||
}
|
||||
|
||||
public void add(ThingTypeUID thingTypeUID, ThingType thingType) {
|
||||
thingTypeMap.put(thingTypeUID, thingType);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user