mirror of
https://github.com/danieldemus/openhab-core.git
synced 2026-07-29 12:34:22 +02:00
Removed ChannelItemProvider (#1643)
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
-411
@@ -1,411 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.thing.internal;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.common.registry.ProviderChangeListener;
|
||||
import org.openhab.core.common.registry.RegistryChangeListener;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.items.GenericItem;
|
||||
import org.openhab.core.items.Item;
|
||||
import org.openhab.core.items.ItemFactory;
|
||||
import org.openhab.core.items.ItemProvider;
|
||||
import org.openhab.core.items.ItemRegistry;
|
||||
import org.openhab.core.items.RegistryHook;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingRegistry;
|
||||
import org.openhab.core.thing.link.ItemChannelLink;
|
||||
import org.openhab.core.thing.link.ItemChannelLinkRegistry;
|
||||
import org.openhab.core.thing.type.ChannelKind;
|
||||
import org.openhab.core.thing.type.ChannelType;
|
||||
import org.openhab.core.thing.type.ChannelTypeRegistry;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Deactivate;
|
||||
import org.osgi.service.component.annotations.Modified;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.osgi.service.component.annotations.ReferenceCardinality;
|
||||
import org.osgi.service.component.annotations.ReferencePolicy;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This class dynamically provides items for all links that point to non-existing items.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
* @author Markus Rathgeb - Add locale provider support
|
||||
* @author Thomas Höfer - Added modified operation
|
||||
*/
|
||||
@Component(configurationPid = "org.openhab.channelitemprovider", immediate = true)
|
||||
@NonNullByDefault
|
||||
public class ChannelItemProvider implements ItemProvider {
|
||||
|
||||
private static final long INITIALIZATION_DELAY_NANOS = TimeUnit.SECONDS.toNanos(2);
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ChannelItemProvider.class);
|
||||
|
||||
private final Set<ProviderChangeListener<Item>> listeners = new HashSet<>();
|
||||
private final Set<ItemFactory> itemFactories = new HashSet<>();
|
||||
private @Nullable Map<String, Item> items;
|
||||
|
||||
private final LocaleProvider localeProvider;
|
||||
private final ChannelTypeRegistry channelTypeRegistry;
|
||||
private final ThingRegistry thingRegistry;
|
||||
private final ItemRegistry itemRegistry;
|
||||
private final ItemChannelLinkRegistry linkRegistry;
|
||||
|
||||
private boolean enabled = true;
|
||||
private volatile boolean initialized = false;
|
||||
private volatile long lastUpdate = System.nanoTime();
|
||||
private @Nullable ScheduledExecutorService executor;
|
||||
|
||||
@Activate
|
||||
public ChannelItemProvider(final @Reference LocaleProvider localeProvider,
|
||||
final @Reference ChannelTypeRegistry channelTypeRegistry, final @Reference ThingRegistry thingRegistry,
|
||||
final @Reference ItemRegistry itemRegistry, final @Reference ItemChannelLinkRegistry linkRegistry) {
|
||||
this.localeProvider = localeProvider;
|
||||
this.channelTypeRegistry = channelTypeRegistry;
|
||||
this.thingRegistry = thingRegistry;
|
||||
this.itemRegistry = itemRegistry;
|
||||
this.linkRegistry = linkRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Item> getAll() {
|
||||
if (!enabled || !initialized) {
|
||||
return Collections.emptySet();
|
||||
} else {
|
||||
initializeItems();
|
||||
return new HashSet<>(items.values());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProviderChangeListener(ProviderChangeListener<Item> listener) {
|
||||
listeners.add(listener);
|
||||
for (Item item : getAll()) {
|
||||
listener.added(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeProviderChangeListener(ProviderChangeListener<Item> listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Reference(cardinality = ReferenceCardinality.AT_LEAST_ONE, policy = ReferencePolicy.DYNAMIC)
|
||||
protected void addItemFactory(ItemFactory itemFactory) {
|
||||
this.itemFactories.add(itemFactory);
|
||||
}
|
||||
|
||||
protected void removeItemFactory(ItemFactory itemFactory) {
|
||||
this.itemFactories.remove(itemFactory);
|
||||
}
|
||||
|
||||
@Activate
|
||||
protected void activate(Map<String, Object> properties) {
|
||||
modified(properties);
|
||||
}
|
||||
|
||||
@Modified
|
||||
protected synchronized void modified(Map<String, Object> properties) {
|
||||
if (properties != null) {
|
||||
String enabled = (String) properties.get("enabled");
|
||||
if ("false".equalsIgnoreCase(enabled)) {
|
||||
this.enabled = false;
|
||||
} else {
|
||||
this.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
addRegistryChangeListeners();
|
||||
|
||||
boolean initialDelay = properties == null
|
||||
|| !"false".equalsIgnoreCase((String) properties.get("initialDelay"));
|
||||
if (initialDelay) {
|
||||
executor = Executors.newSingleThreadScheduledExecutor();
|
||||
delayedInitialize();
|
||||
} else {
|
||||
initialize();
|
||||
}
|
||||
} else {
|
||||
logger.debug("Disabling channel item provider.");
|
||||
disableChannelItemProvider();
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void disableChannelItemProvider() {
|
||||
if (executor != null) {
|
||||
executor.shutdownNow();
|
||||
executor = null;
|
||||
}
|
||||
|
||||
for (ProviderChangeListener<Item> listener : listeners) {
|
||||
for (Item item : getAll()) {
|
||||
listener.removed(this, item);
|
||||
}
|
||||
}
|
||||
removeRegistryChangeListeners();
|
||||
|
||||
initialized = false;
|
||||
items = null;
|
||||
}
|
||||
|
||||
private synchronized void delayedInitialize() {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
return;
|
||||
}
|
||||
// we wait until no further new links or items are announced in order to avoid creation of
|
||||
// items which then must be removed again immediately.
|
||||
final long diff = System.nanoTime() - lastUpdate - INITIALIZATION_DELAY_NANOS;
|
||||
if (diff < 0) {
|
||||
executor.schedule(() -> delayedInitialize(), -diff, TimeUnit.NANOSECONDS);
|
||||
} else {
|
||||
executor.shutdown();
|
||||
executor = null;
|
||||
|
||||
initialize();
|
||||
}
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
initializeItems();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
private synchronized void initializeItems() {
|
||||
if (items != null) {
|
||||
return;
|
||||
}
|
||||
items = new ConcurrentHashMap<>();
|
||||
for (ItemChannelLink link : linkRegistry.getAll()) {
|
||||
createItemForLink(link);
|
||||
}
|
||||
}
|
||||
|
||||
@Deactivate
|
||||
protected void deactivate() {
|
||||
disableChannelItemProvider();
|
||||
}
|
||||
|
||||
private void addRegistryChangeListeners() {
|
||||
linkRegistry.addRegistryChangeListener(linkRegistryListener);
|
||||
itemRegistry.addRegistryHook(itemRegistryListener);
|
||||
thingRegistry.addRegistryChangeListener(thingRegistryListener);
|
||||
}
|
||||
|
||||
private void removeRegistryChangeListeners() {
|
||||
itemRegistry.removeRegistryHook(itemRegistryListener);
|
||||
linkRegistry.removeRegistryChangeListener(linkRegistryListener);
|
||||
thingRegistry.removeRegistryChangeListener(thingRegistryListener);
|
||||
}
|
||||
|
||||
private void createItemForLink(ItemChannelLink link) {
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
if (itemRegistry.get(link.getItemName()) != null) {
|
||||
// there is already an item, we do not need to create one
|
||||
return;
|
||||
}
|
||||
Channel channel = thingRegistry.getChannel(link.getLinkedUID());
|
||||
if (channel != null) {
|
||||
Item item = null;
|
||||
// Only create an item for state channels
|
||||
if (channel.getKind() == ChannelKind.STATE) {
|
||||
for (ItemFactory itemFactory : itemFactories) {
|
||||
item = itemFactory.createItem(channel.getAcceptedItemType(), link.getItemName());
|
||||
if (item != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (item instanceof GenericItem) {
|
||||
GenericItem gItem = (GenericItem) item;
|
||||
gItem.setLabel(getLabel(channel));
|
||||
gItem.setCategory(getCategory(channel));
|
||||
gItem.addTags(channel.getDefaultTags());
|
||||
}
|
||||
if (item != null) {
|
||||
logger.trace("Created virtual item '{}'", item.getName());
|
||||
items.put(item.getName(), item);
|
||||
for (ProviderChangeListener<Item> listener : listeners) {
|
||||
listener.added(this, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable String getCategory(Channel channel) {
|
||||
if (channel.getChannelTypeUID() != null) {
|
||||
ChannelType channelType = channelTypeRegistry.getChannelType(channel.getChannelTypeUID(),
|
||||
localeProvider.getLocale());
|
||||
if (channelType != null) {
|
||||
return channelType.getCategory();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private @Nullable String getLabel(Channel channel) {
|
||||
if (channel.getLabel() != null) {
|
||||
return channel.getLabel();
|
||||
} else {
|
||||
if (channel.getChannelTypeUID() != null) {
|
||||
final ChannelType channelType = channelTypeRegistry.getChannelType(channel.getChannelTypeUID(),
|
||||
localeProvider.getLocale());
|
||||
if (channelType != null) {
|
||||
return channelType.getLabel();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void removeItem(String key) {
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
Item item = items.get(key);
|
||||
if (item != null) {
|
||||
for (ProviderChangeListener<Item> listener : listeners) {
|
||||
listener.removed(this, item);
|
||||
}
|
||||
items.remove(key);
|
||||
logger.trace("Removed virtual item '{}'", item.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
final RegistryChangeListener<Thing> thingRegistryListener = new RegistryChangeListener<Thing>() {
|
||||
|
||||
@Override
|
||||
public void added(Thing element) {
|
||||
if (!initialized) {
|
||||
return;
|
||||
}
|
||||
for (Channel channel : element.getChannels()) {
|
||||
for (ItemChannelLink link : linkRegistry.getLinks(channel.getUID())) {
|
||||
createItemForLink(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed(Thing element) {
|
||||
if (!initialized) {
|
||||
return;
|
||||
}
|
||||
for (Channel channel : element.getChannels()) {
|
||||
for (ItemChannelLink link : linkRegistry.getLinks(channel.getUID())) {
|
||||
removeItem(link.getItemName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updated(Thing oldElement, Thing element) {
|
||||
removed(oldElement);
|
||||
added(element);
|
||||
}
|
||||
};
|
||||
|
||||
final RegistryChangeListener<ItemChannelLink> linkRegistryListener = new RegistryChangeListener<ItemChannelLink>() {
|
||||
|
||||
@Override
|
||||
public void added(ItemChannelLink element) {
|
||||
if (!initialized) {
|
||||
lastUpdate = System.nanoTime();
|
||||
return;
|
||||
}
|
||||
createItemForLink(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed(ItemChannelLink element) {
|
||||
if (!initialized) {
|
||||
return;
|
||||
}
|
||||
removeItem(element.getItemName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updated(ItemChannelLink oldElement, ItemChannelLink element) {
|
||||
removed(oldElement);
|
||||
added(element);
|
||||
}
|
||||
};
|
||||
|
||||
final RegistryHook<Item> itemRegistryListener = new RegistryHook<Item>() {
|
||||
|
||||
@Override
|
||||
public void beforeAdding(Item element) {
|
||||
if (!initialized) {
|
||||
lastUpdate = System.nanoTime();
|
||||
return;
|
||||
}
|
||||
// check, if it is our own item
|
||||
for (Item item : items.values()) {
|
||||
if (item == element) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// it is from some other provider, so remove ours, if we have one
|
||||
Item oldElement = items.get(element.getName());
|
||||
if (oldElement != null) {
|
||||
for (ProviderChangeListener<Item> listener : listeners) {
|
||||
listener.removed(ChannelItemProvider.this, oldElement);
|
||||
}
|
||||
items.remove(element.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterRemoving(Item element) {
|
||||
if (!initialized) {
|
||||
return;
|
||||
}
|
||||
// check, if it is our own item
|
||||
for (Item item : items.values()) {
|
||||
if (item == element) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// it is from some other provider, so create one ourselves if needed
|
||||
for (ChannelUID uid : linkRegistry.getBoundChannels(element.getName())) {
|
||||
for (ItemChannelLink link : linkRegistry.getLinks(uid)) {
|
||||
if (itemRegistry.get(link.getItemName()) == null) {
|
||||
createItemForLink(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
-211
@@ -1,211 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.thing.internal;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
import org.openhab.core.common.registry.ProviderChangeListener;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.items.Item;
|
||||
import org.openhab.core.items.ItemFactory;
|
||||
import org.openhab.core.items.ItemRegistry;
|
||||
import org.openhab.core.library.CoreItemFactory;
|
||||
import org.openhab.core.library.items.NumberItem;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingRegistry;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.builder.ChannelBuilder;
|
||||
import org.openhab.core.thing.binding.builder.ThingBuilder;
|
||||
import org.openhab.core.thing.link.ItemChannelLink;
|
||||
import org.openhab.core.thing.link.ItemChannelLinkRegistry;
|
||||
import org.openhab.core.thing.type.ChannelTypeRegistry;
|
||||
|
||||
/**
|
||||
* @author Simon Kaufmann - Initial contribution
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.WARN)
|
||||
public class ChannelItemProviderTest {
|
||||
|
||||
private static final ChannelUID CHANNEL_UID = new ChannelUID("test:test:test:test");
|
||||
private static final Channel CHANNEL = ChannelBuilder.create(CHANNEL_UID, CoreItemFactory.NUMBER).build();
|
||||
|
||||
private static final ThingTypeUID THING_TYPE_UID = new ThingTypeUID("test:test");
|
||||
private static final Thing THING = ThingBuilder.create(THING_TYPE_UID, "test").withChannel(CHANNEL).build();
|
||||
|
||||
private static final String ITEM_NAME = "test";
|
||||
private static final NumberItem ITEM = new NumberItem(ITEM_NAME);
|
||||
private static final ItemChannelLink LINK = new ItemChannelLink(ITEM_NAME, CHANNEL_UID);
|
||||
|
||||
private @Mock ItemFactory itemFactoryMock;
|
||||
private @Mock ItemRegistry itemRegistryMock;
|
||||
private @Mock ItemChannelLinkRegistry linkRegistryMock;
|
||||
private @Mock ProviderChangeListener<@NonNull Item> listenerMock;
|
||||
private @Mock LocaleProvider localeProviderMock;
|
||||
private @Mock ThingRegistry thingRegistryMock;
|
||||
|
||||
private ChannelItemProvider provider;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
provider = createProvider();
|
||||
|
||||
provider.activate(Map.ofEntries(entry("enabled", "true"), entry("initialDelay", "false")));
|
||||
|
||||
when(thingRegistryMock.getChannel(same(CHANNEL_UID))).thenReturn(CHANNEL);
|
||||
when(itemFactoryMock.createItem(CoreItemFactory.NUMBER, ITEM_NAME)).thenReturn(ITEM);
|
||||
when(localeProviderMock.getLocale()).thenReturn(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemCreationFromThingNotThere() {
|
||||
resetAndPrepareListener();
|
||||
|
||||
provider.thingRegistryListener.added(THING);
|
||||
verify(listenerMock, only()).added(same(provider), same(ITEM));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemCreationFromThingAlreadyExists() {
|
||||
when(itemRegistryMock.get(eq(ITEM_NAME))).thenReturn(ITEM);
|
||||
|
||||
resetAndPrepareListener();
|
||||
|
||||
provider.thingRegistryListener.added(THING);
|
||||
verify(listenerMock, never()).added(same(provider), same(ITEM));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemRemovalFromThingLinkRemoved() {
|
||||
provider.linkRegistryListener.added(LINK);
|
||||
|
||||
resetAndPrepareListener();
|
||||
|
||||
provider.thingRegistryListener.removed(THING);
|
||||
verify(listenerMock, never()).added(same(provider), same(ITEM));
|
||||
verify(listenerMock, only()).removed(same(provider), same(ITEM));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemCreationFromLinkNotThere() {
|
||||
provider.linkRegistryListener.added(LINK);
|
||||
verify(listenerMock, only()).added(same(provider), same(ITEM));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemCreationFromLinkAlreadyExists() {
|
||||
when(itemRegistryMock.get(eq(ITEM_NAME))).thenReturn(ITEM);
|
||||
|
||||
provider.linkRegistryListener.added(LINK);
|
||||
verify(listenerMock, never()).added(same(provider), same(ITEM));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemRemovalFromLinkLinkRemoved() {
|
||||
provider.linkRegistryListener.added(LINK);
|
||||
|
||||
resetAndPrepareListener();
|
||||
|
||||
provider.linkRegistryListener.removed(LINK);
|
||||
verify(listenerMock, never()).added(same(provider), same(ITEM));
|
||||
verify(listenerMock, only()).removed(same(provider), same(ITEM));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemRemovalItemFromOtherProvider() {
|
||||
provider.linkRegistryListener.added(LINK);
|
||||
|
||||
resetAndPrepareListener();
|
||||
|
||||
provider.itemRegistryListener.beforeAdding(new NumberItem(ITEM_NAME));
|
||||
verify(listenerMock, only()).removed(same(provider), same(ITEM));
|
||||
verify(listenerMock, never()).added(same(provider), same(ITEM));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisableBeforeDelayedInitialization() throws Exception {
|
||||
provider = createProvider();
|
||||
reset(linkRegistryMock);
|
||||
|
||||
// Set the initialization delay to 40ms so we don't have to wait 2000ms to do the assertion
|
||||
Field field = ChannelItemProvider.class.getDeclaredField("INITIALIZATION_DELAY_NANOS");
|
||||
field.setAccessible(true);
|
||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
modifiersField.setAccessible(true);
|
||||
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
|
||||
field.set(provider, TimeUnit.MILLISECONDS.toNanos(40));
|
||||
|
||||
Map<String, Object> props = new HashMap<>();
|
||||
props.put("enabled", "true");
|
||||
provider.activate(props);
|
||||
|
||||
provider.linkRegistryListener.added(LINK);
|
||||
verify(listenerMock, never()).added(same(provider), same(ITEM));
|
||||
verify(linkRegistryMock, never()).getAll();
|
||||
|
||||
props = new HashMap<>();
|
||||
props.put("enabled", "false");
|
||||
provider.modified(props);
|
||||
|
||||
Thread.sleep(100);
|
||||
|
||||
provider.linkRegistryListener.added(LINK);
|
||||
verify(listenerMock, never()).added(same(provider), same(ITEM));
|
||||
verify(linkRegistryMock, never()).getAll();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void resetAndPrepareListener() {
|
||||
reset(listenerMock);
|
||||
doAnswer(invocation -> {
|
||||
// this is crucial as it mimics the real ItemRegistry's behavior
|
||||
provider.itemRegistryListener.afterRemoving((Item) invocation.getArguments()[1]);
|
||||
return null;
|
||||
}).when(listenerMock).removed(same(provider), any(Item.class));
|
||||
doAnswer(invocation -> {
|
||||
// this is crucial as it mimics the real ItemRegistry's behavior
|
||||
provider.itemRegistryListener.beforeAdding((Item) invocation.getArguments()[1]);
|
||||
return null;
|
||||
}).when(listenerMock).added(same(provider), any(Item.class));
|
||||
when(linkRegistryMock.getBoundChannels(eq(ITEM_NAME))).thenReturn(Set.of(CHANNEL_UID));
|
||||
when(linkRegistryMock.getLinks(eq(CHANNEL_UID))).thenReturn(Set.of(LINK));
|
||||
}
|
||||
|
||||
private ChannelItemProvider createProvider() {
|
||||
ChannelItemProvider provider = new ChannelItemProvider(localeProviderMock, mock(ChannelTypeRegistry.class),
|
||||
thingRegistryMock, itemRegistryMock, linkRegistryMock);
|
||||
provider.addItemFactory(itemFactoryMock);
|
||||
provider.addProviderChangeListener(listenerMock);
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
-7
@@ -173,13 +173,6 @@ public class ThingManagerOSGiJavaTest extends JavaOSGiTest {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
waitForAssert(() -> {
|
||||
try {
|
||||
assertThat(bundleContext.getServiceReferences(ChannelItemProvider.class, null), is(notNullValue()));
|
||||
} catch (InvalidSyntaxException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
||||
+9
-12
@@ -168,13 +168,6 @@ public class ThingManagerOSGiTest extends JavaOSGiTest {
|
||||
fail("Failed to get service reference: " + e.getMessage());
|
||||
}
|
||||
});
|
||||
waitForAssert(() -> {
|
||||
try {
|
||||
assertThat(bundleContext.getServiceReferences(ChannelItemProvider.class, null), is(notNullValue()));
|
||||
} catch (InvalidSyntaxException e) {
|
||||
fail("Failed to get service reference: " + e.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
Bundle bundle = mock(Bundle.class);
|
||||
when(bundle.getSymbolicName()).thenReturn("org.openhab.core.thing");
|
||||
@@ -794,6 +787,8 @@ public class ThingManagerOSGiTest extends JavaOSGiTest {
|
||||
managedItemChannelLinkProvider.add(new ItemChannelLink(itemName, CHANNEL_UID));
|
||||
|
||||
registerService(thingHandlerFactory);
|
||||
Item item = new StringItem(itemName);
|
||||
itemRegistry.add(item);
|
||||
waitForAssert(() -> assertThat(itemRegistry.get(itemName), is(notNullValue())));
|
||||
|
||||
state.callback.statusUpdated(thing, ThingStatusInfoBuilder.create(ThingStatus.ONLINE).build());
|
||||
@@ -1954,11 +1949,13 @@ public class ThingManagerOSGiTest extends JavaOSGiTest {
|
||||
when(thingHandlerFactory.registerHandler(any(Thing.class))).thenReturn(thingHandler);
|
||||
|
||||
registerService(thingHandlerFactory);
|
||||
String itemName = "testItem";
|
||||
Item item = new StringItem(itemName);
|
||||
itemRegistry.add(item);
|
||||
itemChannelLinkRegistry.add(new ItemChannelLink(itemName, new ChannelUID(thing.getUID(), "channel")));
|
||||
waitForAssert(() -> assertThat(itemRegistry.get(itemName), is(notNullValue())));
|
||||
|
||||
itemChannelLinkRegistry.add(new ItemChannelLink("testItem", new ChannelUID(thing.getUID(), "channel")));
|
||||
waitForAssert(() -> assertThat(itemRegistry.get("testItem"), is(notNullValue())));
|
||||
|
||||
eventPublisher.post(ItemEventFactory.createCommandEvent("testItem", OnOffType.ON));
|
||||
eventPublisher.post(ItemEventFactory.createCommandEvent(itemName, OnOffType.ON));
|
||||
|
||||
assertThat(state.handleCommandCalled, is(false));
|
||||
|
||||
@@ -1967,7 +1964,7 @@ public class ThingManagerOSGiTest extends JavaOSGiTest {
|
||||
state.callback.statusUpdated(thing, unknownNone);
|
||||
assertThat(thing.getStatusInfo(), is(unknownNone));
|
||||
|
||||
eventPublisher.post(ItemEventFactory.createCommandEvent("testItem", OnOffType.ON));
|
||||
eventPublisher.post(ItemEventFactory.createCommandEvent(itemName, OnOffType.ON));
|
||||
|
||||
waitForAssert(() -> {
|
||||
assertThat(state.handleCommandCalled, is(true));
|
||||
|
||||
Reference in New Issue
Block a user