From b6732f10327e26e3c4ee3baba601e7af0ec517b4 Mon Sep 17 00:00:00 2001 From: J-N-K Date: Mon, 1 Jan 2024 13:06:46 +0100 Subject: [PATCH] [commons] Remove UpdatingBaseThing/BridgeHandler (#556) ... as channel updates are now available in core Signed-off-by: Jan N. Klug (cherry picked from commit 50269fc51e5eb0ec6ca6ee4cc6e7457beccd42b3) --- .../commons/UpdatingBaseBridgeHandler.java | 53 ---- .../commons/UpdatingBaseThingHandler.java | 52 ---- .../smarthomej/commons/impl/ThingUpdater.java | 188 -------------- .../UpdatingBaseBridgeHandlerTest.java | 228 ----------------- .../commons/UpdatingBaseThingHandlerTest.java | 229 ------------------ .../resources/update/testThingTypeAdd.update | 5 - .../update/testThingTypeMultiple.update | 3 - .../update/testThingTypeRemove.update | 1 - .../update/testThingTypeUpdate.update | 1 - 9 files changed, 760 deletions(-) delete mode 100644 bundles/org.smarthomej.commons/src/main/java/org/smarthomej/commons/UpdatingBaseBridgeHandler.java delete mode 100644 bundles/org.smarthomej.commons/src/main/java/org/smarthomej/commons/UpdatingBaseThingHandler.java delete mode 100644 bundles/org.smarthomej.commons/src/main/java/org/smarthomej/commons/impl/ThingUpdater.java delete mode 100644 bundles/org.smarthomej.commons/src/test/java/org/smarthomej/commons/UpdatingBaseBridgeHandlerTest.java delete mode 100644 bundles/org.smarthomej.commons/src/test/java/org/smarthomej/commons/UpdatingBaseThingHandlerTest.java delete mode 100644 bundles/org.smarthomej.commons/src/test/resources/update/testThingTypeAdd.update delete mode 100644 bundles/org.smarthomej.commons/src/test/resources/update/testThingTypeMultiple.update delete mode 100644 bundles/org.smarthomej.commons/src/test/resources/update/testThingTypeRemove.update delete mode 100644 bundles/org.smarthomej.commons/src/test/resources/update/testThingTypeUpdate.update diff --git a/bundles/org.smarthomej.commons/src/main/java/org/smarthomej/commons/UpdatingBaseBridgeHandler.java b/bundles/org.smarthomej.commons/src/main/java/org/smarthomej/commons/UpdatingBaseBridgeHandler.java deleted file mode 100644 index 4febd4f871..0000000000 --- a/bundles/org.smarthomej.commons/src/main/java/org/smarthomej/commons/UpdatingBaseBridgeHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.commons; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.openhab.core.thing.Bridge; -import org.openhab.core.thing.Thing; -import org.openhab.core.thing.binding.BaseBridgeHandler; -import org.openhab.core.thing.binding.ThingHandlerCallback; -import org.smarthomej.commons.impl.ThingUpdater; - -/** - * The {@link UpdatingBaseBridgeHandler} is an extension to the {@link BaseBridgeHandler} which allows updating thing - * channels on bundle upgrade - * - * @author Jan N. Klug - Initial contribution - */ -@NonNullByDefault -public abstract class UpdatingBaseBridgeHandler extends BaseBridgeHandler { - public static final String PROPERTY_THING_TYPE_VERSION = "thingTypeVersion"; - - private final ThingUpdater thingUpdater; - - /** - * Creates a new instance of this class for the {@link Thing}. - * - * @param bridge the bridge that should be handled, not null - */ - public UpdatingBaseBridgeHandler(Bridge bridge) { - super(bridge); - - thingUpdater = new ThingUpdater(bridge, this.getClass()); - } - - @Override - public void setCallback(@Nullable ThingHandlerCallback thingHandlerCallback) { - super.setCallback(thingHandlerCallback); - if (thingHandlerCallback != null && thingUpdater.thingNeedsUpdate()) { - thingUpdater.update(this::editThing, thingHandlerCallback, this::isInitialized, this::updateThing); - } - } -} diff --git a/bundles/org.smarthomej.commons/src/main/java/org/smarthomej/commons/UpdatingBaseThingHandler.java b/bundles/org.smarthomej.commons/src/main/java/org/smarthomej/commons/UpdatingBaseThingHandler.java deleted file mode 100644 index ccbb3e1119..0000000000 --- a/bundles/org.smarthomej.commons/src/main/java/org/smarthomej/commons/UpdatingBaseThingHandler.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.commons; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.openhab.core.thing.Thing; -import org.openhab.core.thing.binding.BaseThingHandler; -import org.openhab.core.thing.binding.ThingHandlerCallback; -import org.smarthomej.commons.impl.ThingUpdater; - -/** - * The {@link UpdatingBaseThingHandler} is an extension to the {@link BaseThingHandler} which allows updating thing - * channels on bundle upgrade - * - * @author Jan N. Klug - Initial contribution - */ -@NonNullByDefault -public abstract class UpdatingBaseThingHandler extends BaseThingHandler { - public static final String PROPERTY_THING_TYPE_VERSION = "thingTypeVersion"; - - private final ThingUpdater thingUpdater; - - /** - * Creates a new instance of this class for the {@link Thing}. - * - * @param thing the thing that should be handled, not null - */ - public UpdatingBaseThingHandler(Thing thing) { - super(thing); - - thingUpdater = new ThingUpdater(thing, this.getClass()); - } - - @Override - public void setCallback(@Nullable ThingHandlerCallback thingHandlerCallback) { - super.setCallback(thingHandlerCallback); - if (thingHandlerCallback != null && thingUpdater.thingNeedsUpdate()) { - thingUpdater.update(this::editThing, thingHandlerCallback, this::isInitialized, this::updateThing); - } - } -} diff --git a/bundles/org.smarthomej.commons/src/main/java/org/smarthomej/commons/impl/ThingUpdater.java b/bundles/org.smarthomej.commons/src/main/java/org/smarthomej/commons/impl/ThingUpdater.java deleted file mode 100644 index 04a01aab85..0000000000 --- a/bundles/org.smarthomej.commons/src/main/java/org/smarthomej/commons/impl/ThingUpdater.java +++ /dev/null @@ -1,188 +0,0 @@ -/** - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.commons.impl; - -import static org.smarthomej.commons.UpdatingBaseThingHandler.PROPERTY_THING_TYPE_VERSION; - -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Scanner; -import java.util.TreeMap; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.core.common.ThreadPoolManager; -import org.openhab.core.thing.ChannelUID; -import org.openhab.core.thing.Thing; -import org.openhab.core.thing.ThingUID; -import org.openhab.core.thing.binding.ThingHandlerCallback; -import org.openhab.core.thing.binding.builder.ChannelBuilder; -import org.openhab.core.thing.binding.builder.ThingBuilder; -import org.openhab.core.thing.type.ChannelTypeUID; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.smarthomej.commons.util.ResourceUtil; - -/** - * The {@link ThingUpdater} is responsible for processing thing updates - * - * @author Jan N. Klug - Initial contribution - */ -@NonNullByDefault -public class ThingUpdater { - private static final Pattern UPDATE_INSTRUCTION = Pattern - .compile("(?\\d+);(?ADD_CHANNEL|UPDATE_CHANNEL|REMOVE_CHANNEL);(?.*)"); - - private final Logger logger = LoggerFactory.getLogger(ThingUpdater.class); - private final TreeMap> updateInstructions = new TreeMap<>(); - private final ThingUID thingUid; - private int currentThingTypeVersion; - private final ScheduledExecutorService scheduler = ThreadPoolManager - .getScheduledPool(ThreadPoolManager.THREAD_POOL_NAME_COMMON); - - public ThingUpdater(Thing thing, Class clazz) { - currentThingTypeVersion = Integer - .parseInt(thing.getProperties().getOrDefault(PROPERTY_THING_TYPE_VERSION, "0")); - thingUid = thing.getUID(); - String thingType = thing.getThingTypeUID().getId(); - - String fileName = "update/" + thingType + ".update"; - Optional inputStream = ResourceUtil.getResourceStream(clazz, fileName); - if (inputStream.isEmpty()) { - logger.trace("No update instructions found for thing type '{}'", thingType); - return; - } - - try (Scanner scanner = new Scanner(inputStream.get(), StandardCharsets.UTF_8)) { - scanner.useDelimiter(Pattern.compile("\\r|\\n|\\r\\n")); - while (scanner.hasNext()) { - String line = scanner.next().trim(); - if (line.startsWith("#") || line.isEmpty()) { - continue; - } - Matcher matcher = UPDATE_INSTRUCTION.matcher(line); - if (!matcher.matches()) { - logger.warn("Line '{}' did not match format for instruction. Ignoring.", line); - continue; - } - - // create update instruction: version;command;parameter(s) - int targetThingTypeVersion = Integer.parseInt(matcher.group("version")); - if (targetThingTypeVersion > currentThingTypeVersion) { - try { - updateInstructions.compute(targetThingTypeVersion, (k, v) -> { - List list = Objects.requireNonNullElse(v, new ArrayList<>()); - list.add(new UpdateInstruction(matcher.group("action"), matcher.group("parameters"))); - return list; - }); - } catch (IllegalArgumentException e) { - logger.warn("Illegal thing update instruction '{}' found: {}", line, e.getMessage()); - } - } - } - } - } - - public boolean thingNeedsUpdate() { - return !updateInstructions.isEmpty(); - } - - public void update(Supplier thingBuilderSupplier, ThingHandlerCallback callback, - Supplier isInitialized, Consumer update) { - if (!isInitialized.get()) { - logger.trace("Thing {} is not yet initialized, deferring update for 500ms.", thingUid); - scheduler.schedule(() -> update(thingBuilderSupplier, callback, isInitialized, update), 500, - TimeUnit.MILLISECONDS); - return; - } - ThingBuilder thingBuilder = thingBuilderSupplier.get(); - updateInstructions.forEach((targetThingTypeVersion, updateInstruction) -> { - logger.info("Updating {} from version {} to {}", thingUid, currentThingTypeVersion, targetThingTypeVersion); - updateInstruction.forEach(instruction -> processUpdateInstruction(instruction, thingBuilder, callback)); - currentThingTypeVersion = targetThingTypeVersion; - }); - thingBuilder.withProperties(Map.of(PROPERTY_THING_TYPE_VERSION, String.valueOf(updateInstructions.lastKey()))); - update.accept(thingBuilder.build()); - } - - private void processUpdateInstruction(UpdateInstruction instruction, ThingBuilder thingBuilder, - ThingHandlerCallback callback) { - ChannelUID affectedChannelUid = new ChannelUID(thingUid, instruction.channelId); - switch (instruction.updateCommand) { - case UPDATE_CHANNEL: - thingBuilder.withoutChannel(affectedChannelUid); - // fall-through to add channel - case ADD_CHANNEL: - ChannelBuilder channelBuilder = callback.createChannelBuilder(affectedChannelUid, - new ChannelTypeUID(instruction.parameters.get(1))); - if (instruction.parameters.size() >= 3) { - // label is optional (could be inherited from thing-type) - channelBuilder.withLabel(instruction.parameters.get(2)); - } - if (instruction.parameters.size() == 4) { - // label is optional (could be inherited from thing-type) - channelBuilder.withDescription(instruction.parameters.get(3)); - } - thingBuilder.withChannel(channelBuilder.build()); - break; - case REMOVE_CHANNEL: - thingBuilder.withoutChannel(affectedChannelUid); - break; - } - } - - private static class UpdateInstruction { - public final UpdateCommand updateCommand; - public final String channelId; - public final List parameters; - - public UpdateInstruction(String updateCommand, String parameters) { - this.updateCommand = UpdateCommand.valueOf(updateCommand); - this.parameters = new ArrayList<>(List.of(parameters.split(","))); - // first is always channelId - this.channelId = this.parameters.remove(0); - - if (!this.updateCommand.checkParameterCount(this.parameters.size())) { - throw new IllegalArgumentException("Wrong number of parameters: " + this.parameters.size()); - } - } - } - - private enum UpdateCommand { - ADD_CHANNEL(2, 4), - REMOVE_CHANNEL(0, 0), - UPDATE_CHANNEL(2, 4); - - private final int minParameterCount; - private final int maxParameterCount; - - UpdateCommand(int minParameterCount, int maxParameterCount) { - this.minParameterCount = minParameterCount; - this.maxParameterCount = maxParameterCount; - } - - public boolean checkParameterCount(int parameterCount) { - return parameterCount >= minParameterCount && parameterCount <= maxParameterCount; - } - } -} diff --git a/bundles/org.smarthomej.commons/src/test/java/org/smarthomej/commons/UpdatingBaseBridgeHandlerTest.java b/bundles/org.smarthomej.commons/src/test/java/org/smarthomej/commons/UpdatingBaseBridgeHandlerTest.java deleted file mode 100644 index c0b88b7edb..0000000000 --- a/bundles/org.smarthomej.commons/src/test/java/org/smarthomej/commons/UpdatingBaseBridgeHandlerTest.java +++ /dev/null @@ -1,228 +0,0 @@ -/** - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.commons; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.timeout; -import static org.smarthomej.commons.UpdatingBaseThingHandler.PROPERTY_THING_TYPE_VERSION; - -import java.util.Map; -import java.util.Objects; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.openhab.core.thing.Bridge; -import org.openhab.core.thing.Channel; -import org.openhab.core.thing.ChannelUID; -import org.openhab.core.thing.ThingTypeUID; -import org.openhab.core.thing.ThingUID; -import org.openhab.core.thing.binding.ThingHandlerCallback; -import org.openhab.core.thing.binding.builder.BridgeBuilder; -import org.openhab.core.thing.binding.builder.ChannelBuilder; -import org.openhab.core.thing.type.ChannelTypeUID; -import org.openhab.core.types.Command; - -/** - * The {@link UpdatingBaseBridgeHandlerTest} contains test cases for the {@link UpdatingBaseBridgeHandler} - * - * @author Jan N. Klug - Initial contribution - */ -@NonNullByDefault -public class UpdatingBaseBridgeHandlerTest { - private static final ThingTypeUID THING_TYPE_ADD_UID = new ThingTypeUID("testBinding", "testThingTypeAdd"); - private static final ThingTypeUID THING_TYPE_REMOVE_UID = new ThingTypeUID("testBinding", "testThingTypeRemove"); - private static final ThingTypeUID THING_TYPE_UPDATE_UID = new ThingTypeUID("testBinding", "testThingTypeUpdate"); - private static final ThingTypeUID THING_TYPE_MULTIPLE_UID = new ThingTypeUID("testBinding", - "testThingTypeMultiple"); - - private static final ChannelTypeUID CHANNEL_TYPE_UID = new ChannelTypeUID("testBinding", "testChannelId"); - private static final ChannelTypeUID UPDATED_CHANNEL_TYPE_UID = new ChannelTypeUID("testBinding", - "testChannelNewId"); - - @Mock - private @NonNullByDefault({}) ThingHandlerCallback callback; - - @Captor - private @NonNullByDefault({}) ArgumentCaptor thingCaptor; - - private @NonNullByDefault({}) AutoCloseable closeable; - - @BeforeEach - public void init() { - closeable = MockitoAnnotations.openMocks(this); - Mockito.when(callback.createChannelBuilder(any(), any())).thenAnswer(invocation -> { - ChannelUID channelUID = (ChannelUID) invocation.getArguments()[0]; - ChannelTypeUID channelTypeUID = (ChannelTypeUID) invocation.getArguments()[1]; - - return ChannelBuilder.create(channelUID).withType(channelTypeUID); - }); - } - - @AfterEach - public void close() throws Exception { - closeable.close(); - } - - @Test - public void addChannelTest() { - Bridge bridge = BridgeBuilder.create(THING_TYPE_ADD_UID, "testThingId").build(); - - TestBridgeHandler testBridgeHandler = new TestBridgeHandler(bridge); - testBridgeHandler.setCallback(callback); - - Mockito.verify(callback, timeout(2000)).thingUpdated(thingCaptor.capture()); - Assertions.assertEquals(2, testBridgeHandler.initializeCounter); - Bridge newBridge = thingCaptor.getValue(); - - Channel newChannel = newBridge.getChannel("testChannel1"); - Assertions.assertNotNull(newChannel); - Objects.requireNonNull(newChannel); - Assertions.assertNull(newChannel.getLabel()); - Assertions.assertNull(newChannel.getDescription()); - Assertions.assertEquals(CHANNEL_TYPE_UID, newChannel.getChannelTypeUID()); - - newChannel = newBridge.getChannel("testChannel2"); - Assertions.assertNotNull(newChannel); - Objects.requireNonNull(newChannel); - Assertions.assertEquals("Test Label", newChannel.getLabel()); - Assertions.assertNull(newChannel.getDescription()); - Assertions.assertEquals(CHANNEL_TYPE_UID, newChannel.getChannelTypeUID()); - - newChannel = newBridge.getChannel("testChannel3"); - Assertions.assertNotNull(newChannel); - Objects.requireNonNull(newChannel); - Assertions.assertEquals("Test Label", newChannel.getLabel()); - Assertions.assertEquals("Test Description", newChannel.getDescription()); - Assertions.assertEquals(CHANNEL_TYPE_UID, newChannel.getChannelTypeUID()); - Assertions.assertEquals("1", newBridge.getProperties().get(PROPERTY_THING_TYPE_VERSION)); - } - - @Test - public void removeChannelTest() { - ThingUID thingUID = new ThingUID(THING_TYPE_REMOVE_UID, "testThingId"); - Bridge bridge = BridgeBuilder.create(THING_TYPE_REMOVE_UID, thingUID) - .withChannel(ChannelBuilder.create(new ChannelUID(thingUID, "testChannel"), "String").build()).build(); - - TestBridgeHandler testBridgeHandler = new TestBridgeHandler(bridge); - testBridgeHandler.setCallback(callback); - - Mockito.verify(callback, timeout(2000)).thingUpdated(thingCaptor.capture()); - Assertions.assertEquals(2, testBridgeHandler.initializeCounter); - Bridge newBridge = thingCaptor.getValue(); - - Assertions.assertEquals(0, newBridge.getChannels().size()); - - Assertions.assertEquals("1", newBridge.getProperties().get(PROPERTY_THING_TYPE_VERSION)); - } - - @Test - public void updateChannelTest() { - ThingUID thingUID = new ThingUID(THING_TYPE_UPDATE_UID, "testThingId"); - Bridge bridge = BridgeBuilder.create(THING_TYPE_UPDATE_UID, thingUID) - .withChannel(ChannelBuilder.create(new ChannelUID(thingUID, "testChannel"), "Number").build()).build(); - - TestBridgeHandler testBridgeHandler = new TestBridgeHandler(bridge); - testBridgeHandler.setCallback(callback); - - Mockito.verify(callback, timeout(2000)).thingUpdated(thingCaptor.capture()); - Assertions.assertEquals(2, testBridgeHandler.initializeCounter); - Bridge newBridge = thingCaptor.getValue(); - - Channel newChannel = newBridge.getChannel("testChannel"); - Assertions.assertNotNull(newChannel); - Objects.requireNonNull(newChannel); - - Assertions.assertEquals("Test Label", newChannel.getLabel()); - Assertions.assertEquals(UPDATED_CHANNEL_TYPE_UID, newChannel.getChannelTypeUID()); - - Assertions.assertEquals("1", newBridge.getProperties().get(PROPERTY_THING_TYPE_VERSION)); - } - - @Test - public void multipleChannelTest() { - ThingUID thingUID = new ThingUID(THING_TYPE_UPDATE_UID, "testThingId"); - Bridge bridge = BridgeBuilder.create(THING_TYPE_MULTIPLE_UID, thingUID) - .withChannel(ChannelBuilder.create(new ChannelUID(thingUID, "testChannel0"), "Number").build()) - .withChannel(ChannelBuilder.create(new ChannelUID(thingUID, "testChannel1"), "Number").build()).build(); - - TestBridgeHandler testBridgeHandler = new TestBridgeHandler(bridge); - testBridgeHandler.setCallback(callback); - - Mockito.verify(callback, timeout(2000)).thingUpdated(thingCaptor.capture()); - Assertions.assertEquals(2, testBridgeHandler.initializeCounter); - Bridge newBridge = thingCaptor.getValue(); - - // added channel - Channel newChannel = newBridge.getChannel("testChannel2"); - Assertions.assertNotNull(newChannel); - Objects.requireNonNull(newChannel); - Assertions.assertEquals("TestLabel", newChannel.getLabel()); - Assertions.assertEquals(CHANNEL_TYPE_UID, newChannel.getChannelTypeUID()); - - // updated channel - Channel updatedChannel = newBridge.getChannel("testChannel1"); - Assertions.assertNotNull(updatedChannel); - Objects.requireNonNull(updatedChannel); - Assertions.assertEquals("Test Label", updatedChannel.getLabel()); - Assertions.assertEquals(UPDATED_CHANNEL_TYPE_UID, updatedChannel.getChannelTypeUID()); - - // removed channel - Channel removedChannel = newBridge.getChannel("testChannel0"); - Assertions.assertNull(removedChannel); - - Assertions.assertEquals("3", newBridge.getProperties().get(PROPERTY_THING_TYPE_VERSION)); - } - - @Test - public void noUpdateIfHigherVersionTest() { - ThingUID thingUID = new ThingUID(THING_TYPE_UPDATE_UID, "testThingId"); - Bridge bridge = BridgeBuilder.create(THING_TYPE_UPDATE_UID, thingUID) - .withProperties(Map.of(PROPERTY_THING_TYPE_VERSION, "2")) - .withChannel(ChannelBuilder.create(new ChannelUID(thingUID, "testChannel"), "Number").build()).build(); - - TestBridgeHandler testBridgeHandler = new TestBridgeHandler(bridge); - testBridgeHandler.setCallback(callback); - - Mockito.verify(callback, never()).thingUpdated(any()); - } - - private static class TestBridgeHandler extends UpdatingBaseBridgeHandler { - public TestBridgeHandler(Bridge bridge) { - super(bridge); - } - - private int initializeCounter = 0; - - @Override - protected boolean isInitialized() { - return ++initializeCounter > 1; - } - - @Override - public void initialize() { - } - - @Override - public void handleCommand(ChannelUID channelUID, Command command) { - } - } -} diff --git a/bundles/org.smarthomej.commons/src/test/java/org/smarthomej/commons/UpdatingBaseThingHandlerTest.java b/bundles/org.smarthomej.commons/src/test/java/org/smarthomej/commons/UpdatingBaseThingHandlerTest.java deleted file mode 100644 index 04b8cd1308..0000000000 --- a/bundles/org.smarthomej.commons/src/test/java/org/smarthomej/commons/UpdatingBaseThingHandlerTest.java +++ /dev/null @@ -1,229 +0,0 @@ -/** - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.commons; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.timeout; -import static org.smarthomej.commons.UpdatingBaseThingHandler.PROPERTY_THING_TYPE_VERSION; - -import java.util.Map; -import java.util.Objects; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.openhab.core.thing.Channel; -import org.openhab.core.thing.ChannelUID; -import org.openhab.core.thing.Thing; -import org.openhab.core.thing.ThingTypeUID; -import org.openhab.core.thing.ThingUID; -import org.openhab.core.thing.binding.ThingHandlerCallback; -import org.openhab.core.thing.binding.builder.ChannelBuilder; -import org.openhab.core.thing.binding.builder.ThingBuilder; -import org.openhab.core.thing.type.ChannelTypeUID; -import org.openhab.core.types.Command; - -/** - * The {@link UpdatingBaseThingHandlerTest} contains test cases for the {@link UpdatingBaseThingHandler} - * - * @author Jan N. Klug - Initial contribution - */ -@NonNullByDefault -public class UpdatingBaseThingHandlerTest { - private static final ThingTypeUID THING_TYPE_ADD_UID = new ThingTypeUID("testBinding", "testThingTypeAdd"); - private static final ThingTypeUID THING_TYPE_REMOVE_UID = new ThingTypeUID("testBinding", "testThingTypeRemove"); - private static final ThingTypeUID THING_TYPE_UPDATE_UID = new ThingTypeUID("testBinding", "testThingTypeUpdate"); - private static final ThingTypeUID THING_TYPE_MULTIPLE_UID = new ThingTypeUID("testBinding", - "testThingTypeMultiple"); - - private static final ChannelTypeUID CHANNEL_TYPE_UID = new ChannelTypeUID("testBinding", "testChannelId"); - private static final ChannelTypeUID UPDATED_CHANNEL_TYPE_UID = new ChannelTypeUID("testBinding", - "testChannelNewId"); - - @Mock - private @NonNullByDefault({}) ThingHandlerCallback callback; - - @Captor - private @NonNullByDefault({}) ArgumentCaptor thingCaptor; - - private @NonNullByDefault({}) AutoCloseable closeable; - - @BeforeEach - public void init() { - closeable = MockitoAnnotations.openMocks(this); - Mockito.when(callback.createChannelBuilder(any(), any())).thenAnswer(invocation -> { - ChannelUID channelUID = (ChannelUID) invocation.getArguments()[0]; - ChannelTypeUID channelTypeUID = (ChannelTypeUID) invocation.getArguments()[1]; - - return ChannelBuilder.create(channelUID).withType(channelTypeUID); - }); - } - - @AfterEach - public void close() throws Exception { - closeable.close(); - } - - @Test - public void addChannelTest() { - Thing thing = ThingBuilder.create(THING_TYPE_ADD_UID, "testThingId").build(); - - TestThingHandler testThingHandler = new TestThingHandler(thing); - testThingHandler.setCallback(callback); - - Mockito.verify(callback, timeout(2000)).thingUpdated(thingCaptor.capture()); - Assertions.assertEquals(2, testThingHandler.initializeCounter); - Thing newThing = thingCaptor.getValue(); - - Channel newChannel = newThing.getChannel("testChannel1"); - Assertions.assertNotNull(newChannel); - Objects.requireNonNull(newChannel); - Assertions.assertNull(newChannel.getLabel()); - Assertions.assertNull(newChannel.getDescription()); - Assertions.assertEquals(CHANNEL_TYPE_UID, newChannel.getChannelTypeUID()); - - newChannel = newThing.getChannel("testChannel2"); - Assertions.assertNotNull(newChannel); - Objects.requireNonNull(newChannel); - Assertions.assertEquals("Test Label", newChannel.getLabel()); - Assertions.assertNull(newChannel.getDescription()); - Assertions.assertEquals(CHANNEL_TYPE_UID, newChannel.getChannelTypeUID()); - - newChannel = newThing.getChannel("testChannel3"); - Assertions.assertNotNull(newChannel); - Objects.requireNonNull(newChannel); - Assertions.assertEquals("Test Label", newChannel.getLabel()); - Assertions.assertEquals("Test Description", newChannel.getDescription()); - Assertions.assertEquals(CHANNEL_TYPE_UID, newChannel.getChannelTypeUID()); - - Assertions.assertEquals("1", newThing.getProperties().get(PROPERTY_THING_TYPE_VERSION)); - } - - @Test - public void removeChannelTest() { - ThingUID thingUID = new ThingUID(THING_TYPE_REMOVE_UID, "testThingId"); - Thing thing = ThingBuilder.create(THING_TYPE_REMOVE_UID, thingUID) - .withChannel(ChannelBuilder.create(new ChannelUID(thingUID, "testChannel"), "String").build()).build(); - - TestThingHandler testThingHandler = new TestThingHandler(thing); - testThingHandler.setCallback(callback); - - Mockito.verify(callback, timeout(2000)).thingUpdated(thingCaptor.capture()); - Assertions.assertEquals(2, testThingHandler.initializeCounter); - Thing newThing = thingCaptor.getValue(); - - Assertions.assertEquals(0, newThing.getChannels().size()); - - Assertions.assertEquals("1", newThing.getProperties().get(PROPERTY_THING_TYPE_VERSION)); - } - - @Test - public void updateChannelTest() { - ThingUID thingUID = new ThingUID(THING_TYPE_UPDATE_UID, "testThingId"); - Thing thing = ThingBuilder.create(THING_TYPE_UPDATE_UID, thingUID) - .withChannel(ChannelBuilder.create(new ChannelUID(thingUID, "testChannel"), "Number").build()).build(); - - TestThingHandler testThingHandler = new TestThingHandler(thing); - testThingHandler.setCallback(callback); - - Mockito.verify(callback, timeout(2000)).thingUpdated(thingCaptor.capture()); - Assertions.assertEquals(2, testThingHandler.initializeCounter); - Thing newThing = thingCaptor.getValue(); - - Channel newChannel = newThing.getChannel("testChannel"); - Assertions.assertNotNull(newChannel); - Objects.requireNonNull(newChannel); - - Assertions.assertEquals("Test Label", newChannel.getLabel()); - Assertions.assertEquals(UPDATED_CHANNEL_TYPE_UID, newChannel.getChannelTypeUID()); - - Assertions.assertEquals("1", newThing.getProperties().get(PROPERTY_THING_TYPE_VERSION)); - } - - @Test - public void multipleChannelTest() { - ThingUID thingUID = new ThingUID(THING_TYPE_UPDATE_UID, "testThingId"); - Thing thing = ThingBuilder.create(THING_TYPE_MULTIPLE_UID, thingUID) - .withChannel(ChannelBuilder.create(new ChannelUID(thingUID, "testChannel0"), "Number").build()) - .withChannel(ChannelBuilder.create(new ChannelUID(thingUID, "testChannel1"), "Number").build()).build(); - - TestThingHandler testThingHandler = new TestThingHandler(thing); - testThingHandler.setCallback(callback); - - Mockito.verify(callback, timeout(2000)).thingUpdated(thingCaptor.capture()); - Assertions.assertEquals(2, testThingHandler.initializeCounter); - Thing newThing = thingCaptor.getValue(); - - // added channel - Channel newChannel = newThing.getChannel("testChannel2"); - Assertions.assertNotNull(newChannel); - Objects.requireNonNull(newChannel); - Assertions.assertEquals("TestLabel", newChannel.getLabel()); - Assertions.assertEquals(CHANNEL_TYPE_UID, newChannel.getChannelTypeUID()); - - // updated channel - Channel updatedChannel = newThing.getChannel("testChannel1"); - Assertions.assertNotNull(updatedChannel); - Objects.requireNonNull(updatedChannel); - Assertions.assertEquals("Test Label", updatedChannel.getLabel()); - Assertions.assertEquals(UPDATED_CHANNEL_TYPE_UID, updatedChannel.getChannelTypeUID()); - - // removed channel - Channel removedChannel = newThing.getChannel("testChannel0"); - Assertions.assertNull(removedChannel); - - Assertions.assertEquals("3", newThing.getProperties().get(PROPERTY_THING_TYPE_VERSION)); - } - - @Test - public void noUpdateIfHigherVersionTest() { - ThingUID thingUID = new ThingUID(THING_TYPE_UPDATE_UID, "testThingId"); - Thing thing = ThingBuilder.create(THING_TYPE_UPDATE_UID, thingUID) - .withProperties(Map.of(PROPERTY_THING_TYPE_VERSION, "2")) - .withChannel(ChannelBuilder.create(new ChannelUID(thingUID, "testChannel"), "Number").build()).build(); - - TestThingHandler testThingHandler = new TestThingHandler(thing); - testThingHandler.setCallback(callback); - - Mockito.verify(callback, never()).thingUpdated(any()); - } - - private static class TestThingHandler extends UpdatingBaseThingHandler { - public TestThingHandler(Thing thing) { - super(thing); - } - - private int initializeCounter = 0; - - @Override - protected boolean isInitialized() { - return ++initializeCounter > 1; - } - - @Override - public void initialize() { - } - - @Override - public void handleCommand(ChannelUID channelUID, Command command) { - } - } -} diff --git a/bundles/org.smarthomej.commons/src/test/resources/update/testThingTypeAdd.update b/bundles/org.smarthomej.commons/src/test/resources/update/testThingTypeAdd.update deleted file mode 100644 index 2c92099723..0000000000 --- a/bundles/org.smarthomej.commons/src/test/resources/update/testThingTypeAdd.update +++ /dev/null @@ -1,5 +0,0 @@ -# simple instruction to add a channel, without label and description, with label and without description and with both -1;ADD_CHANNEL;testChannel1,String,testBinding:testChannelId -1;ADD_CHANNEL;testChannel2,String,testBinding:testChannelId,Test Label -1;ADD_CHANNEL;testChannel3,String,testBinding:testChannelId,Test Label,Test Description - diff --git a/bundles/org.smarthomej.commons/src/test/resources/update/testThingTypeMultiple.update b/bundles/org.smarthomej.commons/src/test/resources/update/testThingTypeMultiple.update deleted file mode 100644 index e436015096..0000000000 --- a/bundles/org.smarthomej.commons/src/test/resources/update/testThingTypeMultiple.update +++ /dev/null @@ -1,3 +0,0 @@ -1;UPDATE_CHANNEL;testChannel1,String,testBinding:testChannelNewId,Test Label -2;ADD_CHANNEL;testChannel2,Switch,testBinding:testChannelId,TestLabel -3;REMOVE_CHANNEL;testChannel0 diff --git a/bundles/org.smarthomej.commons/src/test/resources/update/testThingTypeRemove.update b/bundles/org.smarthomej.commons/src/test/resources/update/testThingTypeRemove.update deleted file mode 100644 index e5fa1856dd..0000000000 --- a/bundles/org.smarthomej.commons/src/test/resources/update/testThingTypeRemove.update +++ /dev/null @@ -1 +0,0 @@ -1;REMOVE_CHANNEL;testChannel diff --git a/bundles/org.smarthomej.commons/src/test/resources/update/testThingTypeUpdate.update b/bundles/org.smarthomej.commons/src/test/resources/update/testThingTypeUpdate.update deleted file mode 100644 index 60597ef6fd..0000000000 --- a/bundles/org.smarthomej.commons/src/test/resources/update/testThingTypeUpdate.update +++ /dev/null @@ -1 +0,0 @@ -1;UPDATE_CHANNEL;testChannel,String,testBinding:testChannelNewId,Test Label