Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rework GenericEventTrigger and GenericEventCondition #3299

Merged
merged 4 commits into from
Feb 14, 2023

Conversation

ccutrer
Copy link
Contributor

@ccutrer ccutrer commented Jan 3, 2023

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

fixes #3234

@ccutrer ccutrer requested a review from a team as a code owner January 3, 2023 17:13
@ccutrer
Copy link
Contributor Author

ccutrer commented Jan 3, 2023

This is very much a breaking change - filtering behavior and names of configuration items. I don't think GenerictEventTrigger and GenericEventCondition are used too much though, so the impact shouldn't be huge. I'm still open to walking back, or having a back-compat mode (depending on which configuration params are used) any particular breaking change.

In light of that pending discussion, I haven't ensured all the integration tests pass yet, and don't plan on solidifying them until the direction I'm going here is confirmed.

fixes openhab#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>
Copy link
Member

@J-N-K J-N-K left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not compare with the old implementation, just checked what I would expect. What exactly makes it incompatible with the old implementation (except that the topic filtering was not working at all for the trigger, which is clearly a bug)?

}
this.source = (String) module.getConfiguration().get(CFG_SOURCE);
String topic = (String) module.getConfiguration().get(CFG_TOPIC);
if (!topic.isEmpty()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest to use .isBlank here, only whitespace characters don't make sense in the topic, too.

} else {
topicFilter = null;
}
if (module.getConfiguration().get(CFG_TOPIC) != null) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be CFG_TYPES?

} else {
return true;
payloadPattern = null;
}
}

@Override
public boolean isSatisfied(Map<String, Object> inputs) {
Event event = inputs.get("event") != null ? (Event) inputs.get("event") : null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Event event = inputs.get("event") != null ? (Event) inputs.get("event") : null;
Event event = inputs.get("event") instanceof Event ? (Event) inputs.get("event") : null;

Just to make sure we don't run into a ClassCastException here.

if (!types.isEmpty() && !types.contains(event.getType())) {
return false;
}
TopicGlobEventFilter localTopicFilter = topicFilter;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was think about that in your previous PR. Wouldn't it be better to have a MatchAllEventFilter that always returns true? That way we could omit a lot of null checks and also make .getFilter return a non-null value.

In general since EventFilter gets the Event, a filter could also filter not only on topic but also on source or type. That brings me again to the EventFilterBuilder that builds an EventFilter .withTopicGlob(String glob), .withTopicRegex(String regex), .withType(Class<? extends Event>), .withTypes(Set<Class<? extends Event>> or .withSource(String source). The implementation than collects all those filters in a List<EventFilter> filterChain, and does a filterChain.stream().allMatch(filter -> filter.apply(event) in .apply. But this is out of scope here. Just an idea :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually really like this idea. But yeah... out of scope here.

} else {
topicFilter = null;
}
if (module.getConfiguration().get(CFG_TOPIC) != null) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above

@ccutrer
Copy link
Contributor Author

ccutrer commented Jan 3, 2023

I did not compare with the old implementation, just checked what I would expect. What exactly makes it incompatible with the old implementation (except that the topic filtering was not working at all for the trigger, which is clearly a bug)?

Behavior changes (whether it's a bug or not):

  • Config param names for GenericEventTrigger changed (from eventTopic => topic, eventSource => source, eventType => types
  • Config param names for GenericEventCondition changed (from eventType => types)
  • GenericEventTrigger topic param now enforced (as a glob)
  • GenericEventTrigger source param is now checked against event source, exact match, not against the event topic as a substring
  • GenericEventCondition topic param is now a glob, instead of a regex (though it was never documented that I could find that it was a regex)
  • GenericEventCondition source param is now an exact match, instead of a regex (again, never really documented)
  • GenericEventCondition payload param is now a simple regex, without implicit start/end anchors (using find() instead of matches()). There are also weirdness here because the old code checked if the payload config value started with * it would leave it alone, and then process as a regex, which then is a syntax error since regexes can't start with *.

I'm mostly concerned about the GenericEventTrigger topic now being enforced. Before switching some of the internal triggers to use the TopicPrefixEventFilter, they were attempting to set a filter like openhab/*, which wouldn't match an event like openhab/items/myMotionItem1/command anymore, since the glob would need to be ** in order to match multiple levels. And itests definitely had several cases where the source param was being set to things like myMotionItem1 which definitely won't match the event source anymore. Maybe I'm just being too conservative though, and these are things that didn't work at all in the past, so shouldn't really be considered breaking.

 * use isBlank() instead of isEmpty()
 * fix copy/paste error using wrong config param for event types

Signed-off-by: Cody Cutrer <cody@cutrer.us>
* Glob</a>
*/
public TopicGlobEventFilter(String topicGlob) {
this.topicMatcher = FileSystems.getDefault().getPathMatcher("glob:" + topicGlob);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did verify that this still works on Windows, even though this is technically a file system interface, and file systems on windows use backslash not forward slash

Copy link
Member

@J-N-K J-N-K Jan 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it works because internally it is converted to a regex and the conversion code is the same for Windows and Unix. To make sure that this is always the case in the future, please add a test that checks it, we'll have Windows and Mac builds for CI, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already there, as a unit test: TopicGlobEventFilterTest.

@J-N-K
Copy link
Member

J-N-K commented Jan 3, 2023

To me these changes make perfectly sense and I agree that most of this was probably never used. We need to add a breaking notice to openhab-distro.

I would like to hear comments from other @openhab/core-maintainers.

ccutrer added a commit to ccutrer/openhab-docs that referenced this pull request Jan 3, 2023
see openhab/openhab-core#3299

Signed-off-by: Cody Cutrer <cody@cutrer.us>
ccutrer added a commit to ccutrer/openhab-distro that referenced this pull request Jan 3, 2023
Signed-off-by: Cody Cutrer <cody@cutrer.us>
ccutrer added a commit to ccutrer/openhab-docs that referenced this pull request Jan 3, 2023
see openhab/openhab-core#3299

Signed-off-by: Cody Cutrer <cody@cutrer.us>
@openhab-bot
Copy link
Collaborator

This pull request has been mentioned on openHAB Community. There might be relevant details there:

https://community.openhab.org/t/thing-status-reporting-4-0-0/143180/2

@ccutrer
Copy link
Contributor Author

ccutrer commented Jan 13, 2023

Ping @openhab/core-maintainers

@J-N-K
Copy link
Member

J-N-K commented Jan 20, 2023

Since nobody objects, I would say we are good to go. I'll have a last look this evening.

Copy link
Member

@J-N-K J-N-K left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for letting you wait so long. One last point: can you re-generate the i18n-files? Otherwise LGTM.

apparently this wasn't run when the timeOnly option was added to
timer.DateTimeTrigger either. I just left it.

Signed-off-by: Cody Cutrer <cody@cutrer.us>
Copy link
Member

@J-N-K J-N-K left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

@J-N-K J-N-K added the enhancement An enhancement or new feature of the Core label Feb 14, 2023
@J-N-K J-N-K added this to the 4.0 milestone Feb 14, 2023
@J-N-K J-N-K merged commit 474d24c into openhab:main Feb 14, 2023
wborn pushed a commit to openhab/openhab-distro that referenced this pull request Feb 18, 2023
ccutrer added a commit to ccutrer/openhab-docs that referenced this pull request Mar 6, 2023
see openhab/openhab-core#3299

Signed-off-by: Cody Cutrer <cody@cutrer.us>
stefan-hoehn pushed a commit to openhab/openhab-docs that referenced this pull request Mar 18, 2023
* update docs for core.GenericEventTrigger

see openhab/openhab-core#3299

Signed-off-by: Cody Cutrer <cody@cutrer.us>

* link to javadocs for mostly-complete list of event types

Signed-off-by: Cody Cutrer <cody@cutrer.us>

---------

Signed-off-by: Cody Cutrer <cody@cutrer.us>
splatch pushed a commit to ConnectorIO/copybara-hab-core that referenced this pull request Jul 12, 2023
* rework GenericEventTrigger and GenericEventCondition

fixes openhab#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>
GitOrigin-RevId: 474d24c
@openhab-bot
Copy link
Collaborator

This pull request has been mentioned on openHAB Community. There might be relevant details there:

https://community.openhab.org/t/openhab-4-migration-faq/148144/18

@openhab-bot
Copy link
Collaborator

This pull request has been mentioned on openHAB Community. There might be relevant details there:

https://community.openhab.org/t/openhab-4-0-release-discussion/147957/111

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement An enhancement or new feature of the Core
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RFC: Implement event topic filtering directly in EventHandler
3 participants