Refactor GenericEventTrigger and GenericEventCondition (#3299)

* rework GenericEventTrigger and GenericEventCondition

fixes #3234

to make their interfaces and semantics match, as well as having a
well defined (and useful) way of defining topic filters

Signed-off-by: Cody Cutrer <cody@cutrer.us>
pull/3369/head
Cody Cutrer 2023-02-14 01:07:23 -07:00 committed by GitHub
parent fd6e161d21
commit 474d24c62d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 374 additions and 137 deletions

View File

@ -13,12 +13,15 @@
package org.openhab.core.automation.internal.module.handler;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.automation.Condition;
import org.openhab.core.automation.handler.BaseConditionModuleHandler;
import org.openhab.core.events.Event;
import org.openhab.core.events.TopicGlobEventFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -27,50 +30,69 @@ import org.slf4j.LoggerFactory;
*
* @author Benedikt Niehues - Initial contribution
* @author Kai Kreuzer - refactored and simplified customized module handling
* @author Cody Cutrer - refactored to match configuration and semantics of GenericEventTriggerHandler
*/
@NonNullByDefault
public class GenericEventConditionHandler extends BaseConditionModuleHandler {
public static final String MODULETYPE_ID = "core.GenericEventCondition";
private static final String TOPIC = "topic";
private static final String EVENTTYPE = "eventType";
private static final String SOURCE = "source";
private static final String PAYLOAD = "payload";
public static final String CFG_TOPIC = "topic";
public static final String CFG_TYPES = "types";
public static final String CFG_SOURCE = "source";
public static final String CFG_PAYLOAD = "payload";
public final Logger logger = LoggerFactory.getLogger(GenericEventConditionHandler.class);
private final String source;
private final @Nullable TopicGlobEventFilter topicFilter;
private final Set<String> types;
private final @Nullable Pattern payloadPattern;
public GenericEventConditionHandler(Condition module) {
super(module);
}
private boolean isConfiguredAndMatches(String keyParam, @Nullable String value) {
Object mo = module.getConfiguration().get(keyParam);
String configValue = mo != null && mo instanceof String ? (String) mo : null;
if (configValue != null) {
if (PAYLOAD.equals(keyParam)) {
// automatically adding wildcards only for payload matching
configValue = configValue.startsWith("*") ? configValue : ".*" + configValue;
configValue = configValue.endsWith("*") ? configValue : configValue + ".*";
}
if (value != null) {
return value.matches(configValue);
} else {
return false;
}
this.source = (String) module.getConfiguration().get(CFG_SOURCE);
String topic = (String) module.getConfiguration().get(CFG_TOPIC);
if (!topic.isBlank()) {
topicFilter = new TopicGlobEventFilter(topic);
} else {
return true;
topicFilter = null;
}
if (module.getConfiguration().get(CFG_TYPES) != null) {
this.types = Set.of(((String) module.getConfiguration().get(CFG_TYPES)).split(","));
} else {
this.types = Set.of();
}
String payload = (String) module.getConfiguration().get(CFG_PAYLOAD);
if (!payload.isBlank()) {
payloadPattern = Pattern.compile(payload);
} else {
payloadPattern = null;
}
}
@Override
public boolean isSatisfied(Map<String, Object> inputs) {
Event event = inputs.get("event") != null ? (Event) inputs.get("event") : null;
if (event != null) {
return isConfiguredAndMatches(TOPIC, event.getTopic()) && isConfiguredAndMatches(SOURCE, event.getSource())
&& isConfiguredAndMatches(PAYLOAD, event.getPayload())
&& isConfiguredAndMatches(EVENTTYPE, event.getType());
Event event = inputs.get("event") instanceof Event ? (Event) inputs.get("event") : null;
if (event == null) {
return false;
}
return false;
if (!types.isEmpty() && !types.contains(event.getType())) {
return false;
}
TopicGlobEventFilter localTopicFilter = topicFilter;
if (localTopicFilter != null && !localTopicFilter.apply(event)) {
return false;
}
if (!source.isEmpty() && !source.equals(event.getSource())) {
return false;
}
Pattern localPayloadPattern = payloadPattern;
if (localPayloadPattern != null && !localPayloadPattern.matcher(event.getPayload()).find()) {
return false;
}
return true;
}
}

View File

@ -15,6 +15,7 @@ package org.openhab.core.automation.internal.module.handler;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
@ -25,6 +26,7 @@ import org.openhab.core.automation.handler.TriggerHandlerCallback;
import org.openhab.core.events.Event;
import org.openhab.core.events.EventFilter;
import org.openhab.core.events.EventSubscriber;
import org.openhab.core.events.TopicGlobEventFilter;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
@ -41,37 +43,51 @@ import org.slf4j.LoggerFactory;
*
* @author Benedikt Niehues - Initial contribution
* @author Kai Kreuzer - refactored and simplified customized module handling
* @author Cody Cutrer - refactored to match configuration and semantics of GenericConditionTriggerHandler
*/
@NonNullByDefault
public class GenericEventTriggerHandler extends BaseTriggerModuleHandler implements EventSubscriber, EventFilter {
public static final String MODULE_TYPE_ID = "core.GenericEventTrigger";
private static final String CFG_EVENT_TOPIC = "eventTopic";
private static final String CFG_EVENT_SOURCE = "eventSource";
private static final String CFG_EVENT_TYPES = "eventTypes";
public static final String CFG_TOPIC = "topic";
public static final String CFG_SOURCE = "source";
public static final String CFG_TYPES = "types";
public static final String CFG_PAYLOAD = "payload";
private final Logger logger = LoggerFactory.getLogger(GenericEventTriggerHandler.class);
private final String source;
private String topic;
private final @Nullable TopicGlobEventFilter topicFilter;
private final Set<String> types;
private final BundleContext bundleContext;
private final @Nullable Pattern payloadPattern;
private @Nullable ServiceRegistration<?> eventSubscriberRegistration;
public GenericEventTriggerHandler(Trigger module, BundleContext bundleContext) {
super(module);
this.source = (String) module.getConfiguration().get(CFG_EVENT_SOURCE);
this.topic = (String) module.getConfiguration().get(CFG_EVENT_TOPIC);
if (module.getConfiguration().get(CFG_EVENT_TYPES) != null) {
this.types = Set.of(((String) module.getConfiguration().get(CFG_EVENT_TYPES)).split(","));
this.source = (String) module.getConfiguration().get(CFG_SOURCE);
String topic = (String) module.getConfiguration().get(CFG_TOPIC);
if (!topic.isBlank()) {
topicFilter = new TopicGlobEventFilter(topic);
} else {
topicFilter = null;
}
if (module.getConfiguration().get(CFG_TYPES) != null) {
this.types = Set.of(((String) module.getConfiguration().get(CFG_TYPES)).split(","));
} else {
this.types = Set.of();
}
this.bundleContext = bundleContext;
eventSubscriberRegistration = this.bundleContext.registerService(EventSubscriber.class.getName(), this, null);
logger.trace("Registered EventSubscriber: Topic: {} Type: {} Source: {}", topic, types, source);
String payload = (String) module.getConfiguration().get(CFG_PAYLOAD);
if (!payload.isBlank()) {
payloadPattern = Pattern.compile(payload);
} else {
payloadPattern = null;
}
eventSubscriberRegistration = bundleContext.registerService(EventSubscriber.class.getName(), this, null);
logger.trace("Registered EventSubscriber: Topic: {} Type: {} Source: {} Payload: {}", topic, types, source,
payload);
}
@Override
@ -100,21 +116,6 @@ public class GenericEventTriggerHandler extends BaseTriggerModuleHandler impleme
}
}
/**
* @return the topic
*/
public String getTopic() {
return topic;
}
/**
* @param topic
* the topic to set
*/
public void setTopic(String topic) {
this.topic = topic;
}
/**
* do the cleanup: unregistering eventSubscriber...
*/
@ -129,7 +130,20 @@ public class GenericEventTriggerHandler extends BaseTriggerModuleHandler impleme
@Override
public boolean apply(Event event) {
logger.trace("->FILTER: {}:{}", event.getTopic(), source);
return event.getTopic().contains(source);
logger.trace("->FILTER: {}: {}", event.getTopic(), source);
TopicGlobEventFilter localTopicFilter = topicFilter;
if (localTopicFilter != null && !topicFilter.apply(event)) {
return false;
}
if (!source.isEmpty() && !source.equals(event.getSource())) {
return false;
}
Pattern localPayloadPattern = payloadPattern;
if (localPayloadPattern != null && !localPayloadPattern.matcher(event.getPayload()).find()) {
return false;
}
return true;
}
}

View File

@ -9,26 +9,34 @@
{
"name": "topic",
"type": "TEXT",
"description": "topic should match",
"required": false
},
{
"name": "eventType",
"type": "TEXT",
"description": "eventType should match",
"required": false
"label": "Topic",
"description": "the topic, as a file-system style glob (*, ** and {} operators). will match all events if empty",
"required": true,
"default": ""
},
{
"name": "source",
"type": "TEXT",
"description": "source should match",
"required": false
"label": "Source",
"description": "the source of the event (e.g. org.openhab.core.expire, etc.). will match all events if empty",
"required": true,
"default": ""
},
{
"name": "types",
"type": "TEXT",
"label": "Event Type",
"description": "the event type the trigger should listen to. multiple types can be specified comma-separated. will match all events if empty",
"required": true,
"default": ""
},
{
"name": "payload",
"type": "TEXT",
"description": "payload should match",
"required": false
"label": "Event Payload",
"description": "A regex to match the event's serialized payload. will match all events if empty",
"required": true,
"default": ""
}
],
"inputs": [
@ -36,7 +44,7 @@
"name": "event",
"type": "org.openhab.core.events.Event",
"label": "Event",
"description": "The events which was sent.",
"description": "The event which was sent.",
"required": true
}
]

View File

@ -7,26 +7,34 @@
"visibility": "HIDDEN",
"configDescriptions": [
{
"name": "eventTopic",
"name": "topic",
"type": "TEXT",
"label": "Topic",
"description": "This is the topic, the trigger will listen to: >>openhab/*<<",
"required": true,
"default": "openhab/*"
},
{
"name": "eventSource",
"type": "TEXT",
"label": "Source",
"description": "This is the source of the event (eg. item name)",
"description": "the topic, as a file-system style glob (*, ** and {} operators). will match all events if empty",
"required": true,
"default": ""
},
{
"name": "eventTypes",
"name": "source",
"type": "TEXT",
"label": "Source",
"description": "the source of the event (e.g. org.openhab.core.expire, etc.). will match all events if empty",
"required": true,
"default": ""
},
{
"name": "types",
"type": "TEXT",
"label": "Event Type",
"description": "the event type, the trigger should listen to. Multiple types can be specified comma-separated",
"description": "the event type the trigger should listen to. multiple types can be specified comma-separated. will match all events if empty",
"required": true,
"default": ""
},
{
"name": "payload",
"type": "TEXT",
"label": "Event Payload",
"description": "A regex to match the event's serialized payload. will match all events if empty",
"required": true,
"default": ""
}

View File

@ -26,23 +26,29 @@ module-type.core.GenericCompareCondition.input.input.description = The input whi
module-type.core.GenericEventCondition.label = Event Condition
module-type.core.GenericEventCondition.description = Condition for events
module-type.core.GenericEventCondition.config.topic.description = topic should match
module-type.core.GenericEventCondition.config.eventType.description = eventType should match
module-type.core.GenericEventCondition.config.source.description = source should match
module-type.core.GenericEventCondition.config.payload.description = payload should match
module-type.core.GenericEventCondition.config.topic.label = Topic
module-type.core.GenericEventCondition.config.topic.description = the topic, as a file-system style glob (*, ** and {} operators). will match all events if empty
module-type.core.GenericEventCondition.config.source.label = Source
module-type.core.GenericEventCondition.config.source.description = the source of the event (e.g. org.openhab.core.expire, etc.). will match all events if empty
module-type.core.GenericEventCondition.config.types.label = Event Type
module-type.core.GenericEventCondition.config.types.description = the event type the trigger should listen to. multiple types can be specified comma-separated. will match all events if empty
module-type.core.GenericEventCondition.config.payload.label = Event Payload
module-type.core.GenericEventCondition.config.payload.description = A regex to match the event's serialized payload. will match all events if empty
module-type.core.GenericEventCondition.input.event.label = Event
module-type.core.GenericEventCondition.input.event.description = The events which was sent.
module-type.core.GenericEventCondition.input.event.description = The event which was sent.
# core.GenericEventTrigger
module-type.core.GenericEventTrigger.label = Basic Event Trigger
module-type.core.GenericEventTrigger.description = Triggers Rules on Events
module-type.core.GenericEventTrigger.config.eventTopic.label = Topic
module-type.core.GenericEventTrigger.config.eventTopic.description = This is the topic, the trigger will listen to: >>openhab/*<<
module-type.core.GenericEventTrigger.config.eventSource.label = Source
module-type.core.GenericEventTrigger.config.eventSource.description = This is the source of the event (eg. item name)
module-type.core.GenericEventTrigger.config.eventTypes.label = Event Type
module-type.core.GenericEventTrigger.config.eventTypes.description = the event type, the trigger should listen to. Multiple types can be specified comma-separated
module-type.core.GenericEventTrigger.config.topic.label = Topic
module-type.core.GenericEventTrigger.config.topic.description = the topic, as a file-system style glob (*, ** and {} operators). will match all events if empty
module-type.core.GenericEventTrigger.config.source.label = Source
module-type.core.GenericEventTrigger.config.source.description = the source of the event (e.g. org.openhab.core.expire, etc.). will match all events if empty
module-type.core.GenericEventTrigger.config.types.label = Event Type
module-type.core.GenericEventTrigger.config.types.description = the event type the trigger should listen to. multiple types can be specified comma-separated. will match all events if empty
module-type.core.GenericEventTrigger.config.payload.label = Event Payload
module-type.core.GenericEventTrigger.config.payload.description = A regex to match the event's serialized payload. will match all events if empty
module-type.core.GenericEventTrigger.output.event.label = Event
module-type.core.GenericEventTrigger.output.event.description = The events which was sent.
@ -382,6 +388,10 @@ module-type.timer.DateTimeTrigger.label = it is a date and time specified in an
module-type.timer.DateTimeTrigger.description = Triggers at a time specified in an item
module-type.timer.DateTimeTrigger.config.itemName.label = Item
module-type.timer.DateTimeTrigger.config.itemName.description = the name of the item
module-type.timer.DateTimeTrigger.config.timeOnly.label = Time only
module-type.timer.DateTimeTrigger.config.timeOnly.description = Specifies whether only the time of the item should be compared or the date and time.
module-type.timer.DateTimeTrigger.config.timeOnly.option.true = Yes
module-type.timer.DateTimeTrigger.config.timeOnly.option.false = No
# timer.DayOfWeekCondition

View File

@ -0,0 +1,82 @@
/**
* Copyright (c) 2010-2023 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.automation.internal.module.handler;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Map;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openhab.core.automation.Trigger;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.events.Event;
import org.osgi.framework.BundleContext;
/**
* Basic test cases for {@link GenericEventTriggerHandler}
*
* @author Cody Cutrer - Initial contribution
*/
@NonNullByDefault
class GenericEventTriggerHandlerTest {
private @NonNullByDefault({}) GenericEventTriggerHandler handler;
private @NonNullByDefault({}) Trigger moduleMock;
private @NonNullByDefault({}) BundleContext contextMock;
public Event createEvent(String topic, String source) {
Event event = mock(Event.class);
when(event.getTopic()).thenReturn(topic);
when(event.getSource()).thenReturn(source);
return event;
}
@BeforeEach
public void setUp() {
moduleMock = mock(Trigger.class);
contextMock = mock(BundleContext.class);
}
@Test
public void testTopicFilterIsGlobbed() {
when(moduleMock.getConfiguration()).thenReturn(new Configuration(Map.of(GenericEventTriggerHandler.CFG_TOPIC,
"openhab/items/*/command", GenericEventTriggerHandler.CFG_SOURCE, "",
GenericEventTriggerHandler.CFG_TYPES, "", GenericEventTriggerHandler.CFG_PAYLOAD, "")));
handler = new GenericEventTriggerHandler(moduleMock, contextMock);
assertTrue(handler.apply(createEvent("openhab/items/myMotion1/command", "Source")));
}
@Test
public void testsSourceFilterIsExactMatch() {
when(moduleMock.getConfiguration()).thenReturn(new Configuration(
Map.of(GenericEventTriggerHandler.CFG_TOPIC, "", GenericEventTriggerHandler.CFG_SOURCE, "ExactSource",
GenericEventTriggerHandler.CFG_TYPES, "", GenericEventTriggerHandler.CFG_PAYLOAD, "")));
handler = new GenericEventTriggerHandler(moduleMock, contextMock);
assertTrue(handler.apply(createEvent("openhab/items/myMotion1/command", "ExactSource")));
}
@Test
public void testsSourceFilterDoesntMatchSubstring() {
when(moduleMock.getConfiguration()).thenReturn(new Configuration(
Map.of(GenericEventTriggerHandler.CFG_TOPIC, "", GenericEventTriggerHandler.CFG_SOURCE, "Source",
GenericEventTriggerHandler.CFG_TYPES, "", GenericEventTriggerHandler.CFG_PAYLOAD, "")));
handler = new GenericEventTriggerHandler(moduleMock, contextMock);
assertFalse(handler.apply(createEvent("openhab/items/myMotion1/command", "ExactSource")));
}
}

View File

@ -0,0 +1,51 @@
/**
* Copyright (c) 2010-2023 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.events;
import java.nio.file.FileSystems;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
* The {@link TopicGlobalEventFilter} is a default openHAB {@link EventFilter} implementation that ensures filtering
* of events based on an event topic.
*
* The syntax for the filter is the glob syntax documented at
* https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/nio/file/FileSystem.html#getPathMatcher(java.lang.String)
*
* @author Cody Cutrer - Initial contribution
*/
@NonNullByDefault
public class TopicGlobEventFilter implements EventFilter {
private final PathMatcher topicMatcher;
/**
* Constructs a new topic event filter.
*
* @param topicGlob the glob
* @see <a href=
* "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/nio/file/FileSystem.html#getPathMatcher(java.lang.String)">Java
* Glob</a>
*/
public TopicGlobEventFilter(String topicGlob) {
this.topicMatcher = FileSystems.getDefault().getPathMatcher("glob:" + topicGlob);
}
@Override
public boolean apply(Event event) {
return topicMatcher.matches(Paths.get(event.getTopic()));
}
}

View File

@ -0,0 +1,50 @@
/**
* Copyright (c) 2010-2023 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.events;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test;
/**
* {@link TopicGlobEventFilterTest} tests the {@link org.openhab.core.events.TopicGlobEventFilter}.
*
* @author Cody Cutrer - Initial contribution
*/
@NonNullByDefault
public class TopicGlobEventFilterTest {
public Event createEvent(String topic) {
Event event = mock(Event.class);
when(event.getTopic()).thenReturn(topic);
return event;
}
@Test
public void testBasic() throws Exception {
var filter = new TopicGlobEventFilter("openhab/**");
assertTrue(filter.apply(createEvent("openhab/items/a")));
assertFalse(filter.apply(createEvent("somewhereElse")));
assertFalse(filter.apply(createEvent("preopenhab/items/apost")));
// * does not match multiple sub-directories
filter = new TopicGlobEventFilter("openhab/*");
assertFalse(filter.apply(createEvent("openhab/items/a")));
// * can be used in the middle of a path component
filter = new TopicGlobEventFilter("openhab/it*s/*");
assertTrue(filter.apply(createEvent("openhab/items/a")));
assertFalse(filter.apply(createEvent("openhab/things/a")));
}
}

View File

@ -247,9 +247,10 @@ public class AutomationIntegrationJsonTest extends JavaOSGiTest {
.filter(t -> "ItemStateChangeTriggerID".equals(t.getId())).findFirst();
assertThat(trigger.isPresent(), is(true));
assertThat(trigger.get().getTypeUID(), is("core.GenericEventTrigger"));
assertThat(trigger.get().getConfiguration().get("eventSource"), is("myMotionItem"));
assertThat(trigger.get().getConfiguration().get("eventTopic"), is("openhab/items/*"));
assertThat(trigger.get().getConfiguration().get("eventTypes"), is("ItemStateEvent"));
assertThat(trigger.get().getConfiguration().get("source"), is(""));
assertThat(trigger.get().getConfiguration().get("topic"), is("openhab/items/myMotionItem/*"));
assertThat(trigger.get().getConfiguration().get("types"), is("ItemStateEvent"));
assertThat(trigger.get().getConfiguration().get("payload"), is(""));
Optional<? extends Action> action = rule.getActions().stream()
.filter(a -> "ItemPostCommandActionID".equals(a.getId())).findFirst();
assertThat(action.isPresent(), is(true));
@ -287,8 +288,10 @@ public class AutomationIntegrationJsonTest extends JavaOSGiTest {
.filter(t -> "ItemStateChangeTriggerID".equals(t.getId())).findFirst();
assertThat(trigger.isPresent(), is(true));
assertThat(trigger.get().getTypeUID(), is("core.GenericEventTrigger"));
assertThat(trigger.get().getConfiguration().get("eventTopic"), is("openhab/items/*"));
assertThat(trigger.get().getConfiguration().get("eventTypes"), is("ItemStateEvent"));
assertThat(trigger.get().getConfiguration().get("source"), is(""));
assertThat(trigger.get().getConfiguration().get("topic"), is("openhab/items/myMotionItem/*"));
assertThat(trigger.get().getConfiguration().get("types"), is("ItemStateEvent"));
assertThat(trigger.get().getConfiguration().get("payload"), is(""));
Optional<? extends Action> action = rule.getActions().stream()
.filter(a -> "ItemPostCommandActionID".equals(a.getId())).findFirst();
assertThat(action.isPresent(), is(true));

View File

@ -254,12 +254,11 @@ public class AutomationIntegrationTest extends JavaOSGiTest {
public void assertThatARuleWithConnectionsIsExecuted() {
logger.info("assert that a rule with connections is executed");
Map<String, Object> params = new HashMap<>();
params.put("eventSource", "myMotionItem3");
params.put("eventTopic", "openhab/*");
params.put("eventTypes", "ItemStateEvent");
params.put("topic", "openhab/items/myMotionItem3/*");
params.put("types", "ItemStateEvent");
Configuration triggerConfig = new Configuration(params);
params = new HashMap<>();
params.put("eventTopic", "openhab/*");
params.put("topic", "openhab/**");
Configuration condition1Config = new Configuration(params);
params = new HashMap<>();
params.put("itemName", "myLampItem3");
@ -321,7 +320,7 @@ public class AutomationIntegrationTest extends JavaOSGiTest {
params.put("eventTypes", "ItemStateEvent");
Configuration triggerConfig = new Configuration(params);
params = new HashMap<>();
params.put("topic", "openhab/*");
params.put("topic", "openhab/**");
Configuration condition1Config = new Configuration(params);
params = new HashMap<>();
params.put("itemName", "myLampItem3");
@ -404,7 +403,7 @@ public class AutomationIntegrationTest extends JavaOSGiTest {
@Test
public void assertThatRuleNowMethodExecutesActionsOfTheRule() throws ItemNotFoundException {
Configuration triggerConfig = new Configuration(Map.of("eventTopic", "runNowEventTopic/*"));
Configuration triggerConfig = new Configuration(Map.of("topic", "runNowEventTopic/*"));
Map<String, Object> params = new HashMap<>();
params.put("itemName", "myLampItem3");
params.put("command", "TOGGLE");
@ -467,7 +466,7 @@ public class AutomationIntegrationTest extends JavaOSGiTest {
@Test
public void assertThatRuleCanBeUpdated() throws ItemNotFoundException {
Configuration triggerConfig = new Configuration(Map.of("eventTopic", "runNowEventTopic/*"));
Configuration triggerConfig = new Configuration(Map.of("topic", "runNowEventTopic/*"));
Map<String, Object> params = new HashMap<>();
params.put("itemName", "myLampItem3");
params.put("command", "ON");
@ -594,9 +593,8 @@ public class AutomationIntegrationTest extends JavaOSGiTest {
logger.info("assert a rule added by api is executed as expected");
// Creation of RULE
Map<String, Object> params = new HashMap<>();
params.put("eventSource", "myMotionItem2");
params.put("eventTopic", "openhab/*");
params.put("eventTypes", "ItemStateEvent");
params.put("topic", "openhab/items/myMotionItem2/*");
params.put("types", "ItemStateEvent");
Configuration triggerConfig = new Configuration(params);
params = new HashMap<>();
params.put("itemName", "myLampItem2");
@ -854,9 +852,8 @@ public class AutomationIntegrationTest extends JavaOSGiTest {
int rand = new Random().nextInt();
Map<String, Object> configs = new HashMap<>();
configs.put("eventSource", "myMotionItem2");
configs.put("eventTopic", "openhab/*");
configs.put("eventTypes", "ItemStateEvent");
configs.put("topic", "openhab/items/myMotionItem2/*");
configs.put("types", "ItemStateEvent");
Configuration triggerConfig = new Configuration(configs);
configs = new HashMap<>();
configs.put("itemName", "myLampItem2");
@ -880,9 +877,8 @@ public class AutomationIntegrationTest extends JavaOSGiTest {
logger.info("assert a rule with generic condition works");
// Creation of RULE
Map<String, Object> configs = new HashMap<>();
configs.put("eventSource", "myMotionItem5");
configs.put("eventTopic", "openhab/*");
configs.put("eventTypes", "ItemStateEvent");
configs.put("topic", "openhab/items/myMotionItem5/*");
configs.put("types", "ItemStateEvent");
Configuration triggerConfig = new Configuration(configs);
configs = new HashMap<>();
configs.put("operator", "matches");

View File

@ -17,9 +17,8 @@
"id": "ItemStateChangeTriggerID",
"type": "core.GenericEventTrigger",
"configuration": {
"eventSource": "myMotionItem",
"eventTopic": "openhab/items/*",
"eventTypes": "ItemStateEvent"
"topic": "openhab/items/myMotionItem/*",
"types": "ItemStateEvent"
}
}
],

View File

@ -39,9 +39,8 @@
"id": "ItemUpdateTrigger_1",
"type": "core.GenericEventTrigger",
"configuration": {
"eventSource": "{{onItem}}",
"eventTopic": "openhab/items/*",
"eventTypes": "ItemStateEvent"
"topic": "openhab/items/{{onItem}}/*",
"types": "ItemStateEvent"
}
}
],

View File

@ -29,9 +29,8 @@
"id": "ItemStateChangeTriggerID",
"type": "core.GenericEventTrigger",
"configuration": {
"eventSource": "{{triggerItem}}",
"eventTopic": "openhab/items/*",
"eventTypes": "ItemStateEvent"
"topic": "openhab/items/{{triggerItem}}/*",
"types": "ItemStateEvent"
}
}
],
@ -41,7 +40,7 @@
"type": "core.GenericEventCondition",
"configuration": {
"topic": "openhab/items/{{triggerItem}}/state",
"payload": ".*ON.*"
"payload": "ON"
},
"inputs": {
"event": "ItemStateChangeTriggerID.event"

View File

@ -113,8 +113,7 @@ public class RunRuleModuleTest extends JavaOSGiTest {
private Rule createOuterRule() {
final Configuration outerRuleTriggerConfig = new Configuration(
Map.ofEntries(entry("eventSource", "ruleTrigger"), entry("eventTopic", "openhab/*"),
entry("eventTypes", "ItemStateEvent")));
Map.ofEntries(entry("topic", "openhab/items/ruleTrigger/*"), entry("types", "ItemStateEvent")));
final List<String> ruleUIDs = new ArrayList<>();
ruleUIDs.add("exampleSceneRule");

View File

@ -142,8 +142,8 @@ public class RuntimeRuleTest extends JavaOSGiTest {
@Test
public void itemStateUpdatedBySimpleRule() throws ItemNotFoundException, InterruptedException {
final Configuration triggerConfig = new Configuration(Map.ofEntries(entry("eventSource", "myMotionItem2"),
entry("eventTopic", "openhab/*"), entry("eventTypes", "ItemStateEvent")));
final Configuration triggerConfig = new Configuration(
Map.ofEntries(entry("topic", "openhab/items/myMotionItem2/*"), entry("types", "ItemStateEvent")));
final Configuration actionConfig = new Configuration(
Map.ofEntries(entry("itemName", "myLampItem2"), entry("command", "ON")));
final Rule rule = RuleBuilder.create("myRule21" + new Random().nextInt())

View File

@ -8,9 +8,8 @@
"id": "trigger",
"type": "core.GenericEventTrigger",
"configuration": {
"eventSource": "MyTrigger",
"eventTopic": "openhab/items/MyTrigger/state",
"eventTypes": "ItemStateEvent"
"topic": "openhab/items/MyTrigger/state",
"types": "ItemStateEvent"
}
}
],

View File

@ -118,9 +118,8 @@ public class ScriptRuleOSGiTest extends JavaOSGiTest {
.findFirst();
assertThat(trigger.isPresent(), is(true));
assertThat(trigger.get().getTypeUID(), is("core.GenericEventTrigger"));
assertThat(trigger.get().getConfiguration().get("eventSource"), is("MyTrigger"));
assertThat(trigger.get().getConfiguration().get("eventTopic"), is("openhab/items/MyTrigger/state"));
assertThat(trigger.get().getConfiguration().get("eventTypes"), is("ItemStateEvent"));
assertThat(trigger.get().getConfiguration().get("topic"), is("openhab/items/MyTrigger/state"));
assertThat(trigger.get().getConfiguration().get("types"), is("ItemStateEvent"));
Optional<? extends Condition> condition1 = rule.getConditions().stream()
.filter(c -> "condition".equals(c.getId())).findFirst();
assertThat(condition1.isPresent(), is(true));

View File

@ -8,9 +8,8 @@
"id": "trigger",
"type": "core.GenericEventTrigger",
"configuration": {
"eventSource": "MyTrigger",
"eventTopic": "openhab/items/MyTrigger/state",
"eventTypes": "ItemStateEvent"
"topic": "openhab/items/MyTrigger/state",
"types": "ItemStateEvent"
}
}
],

View File

@ -127,8 +127,8 @@ public class RuleEventTest extends JavaOSGiTest {
registerService(ruleEventHandler);
// Creation of RULE
Configuration triggerConfig = new Configuration(Map.ofEntries(entry("eventSource", "myMotionItem2"),
entry("eventTopic", "openhab/*"), entry("eventTypes", "ItemStateEvent")));
Configuration triggerConfig = new Configuration(
Map.ofEntries(entry("topic", "openhab/items/myMotionItem2/*"), entry("types", "ItemStateEvent")));
Configuration actionConfig = new Configuration(
Map.ofEntries(entry("itemName", "myLampItem2"), entry("command", "ON")));