Skip to content

Commit

Permalink
Send notification events to openhab when rule runs (#152)
Browse files Browse the repository at this point in the history
  • Loading branch information
querdenker2k authored Apr 25, 2023
1 parent 7bb4b64 commit 9d69d80
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ private void invokeRuleInternal(JRuleExecutionContext context, JRuleEvent event)
final Method method = context.getMethod();

try {
ruleProvider.runRule(rule, method);
JRule.JRULE_EXECUTION_CONTEXT.set(context);
JRuleLog.debug(logger, context.getMethod().getName(), "setting mdc tags: {}", context.getLoggingTags());
MDC.put(MDC_KEY_RULE, context.getMethod().getName());
Expand All @@ -539,6 +540,7 @@ private void invokeRuleInternal(JRuleExecutionContext context, JRuleEvent event)
Arrays.stream(context.getLoggingTags()).forEach(MDC::remove);
MDC.remove(MDC_KEY_RULE);
JRule.JRULE_EXECUTION_CONTEXT.remove();
ruleProvider.stopRule(rule, method);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.automation.jrule.internal.module;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.automation.RuleStatusInfo;
import org.openhab.core.automation.events.RuleStatusInfoEvent;
import org.openhab.core.events.AbstractEventFactory;
import org.openhab.core.events.Event;
import org.openhab.core.events.EventFactory;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Cloned from openhab Core
*
* @author Robert Delbrück - Initial contribution
* @see org.openhab.core.automation.internal.RuleEventFactory
*/
@NonNullByDefault
@Component(service = EventFactory.class, immediate = true)
public class JRuleEventFactory extends AbstractEventFactory {

private final Logger logger = LoggerFactory.getLogger(JRuleEventFactory.class);

private static final String RULE_STATE_EVENT_TOPIC = "openhab/rules/{ruleID}/state";

private static final Set<String> SUPPORTED_TYPES = new HashSet<>();

static {
SUPPORTED_TYPES.add(RuleStatusInfoEvent.TYPE);
}

public JRuleEventFactory() {
super(SUPPORTED_TYPES);
}

@Override
protected Event createEventByType(String eventType, String topic, String payload, @Nullable String source) {
logger.trace("creating ruleEvent of type: {}", eventType);
if (RuleStatusInfoEvent.TYPE.equals(eventType)) {
return createRuleStatusInfoEvent(topic, payload, source);
}
throw new IllegalArgumentException("The event type '" + eventType + "' is not supported by this factory.");
}

@SuppressWarnings("null")
private Event createRuleStatusInfoEvent(String topic, String payload, @Nullable String source) {
RuleStatusInfo statusInfo = deserializePayload(payload, RuleStatusInfo.class);
return new RuleStatusInfoEvent(topic, payload, source, statusInfo, getRuleId(topic));
}

private String getRuleId(String topic) {
String[] topicElements = getTopicElements(topic);
if (topicElements.length != 4) {
throw new IllegalArgumentException("Event creation failed, invalid topic: " + topic);
}
return topicElements[2];
}

/**
* Creates a rule status info event.
*
* @param statusInfo the status info of the event.
* @param ruleUID the UID of the rule for which the event is created.
* @param source the source of the event.
* @return {@link RuleStatusInfoEvent} instance.
*/
public static RuleStatusInfoEvent createRuleStatusInfoEvent(RuleStatusInfo statusInfo, String ruleUID,
String source) {
String topic = buildTopic(RULE_STATE_EVENT_TOPIC, ruleUID);
String payload = serializePayload(statusInfo);
return new RuleStatusInfoEvent(topic, payload, source, statusInfo, ruleUID);
}

private static String buildTopic(String topic, String ruleUID) {
return topic.replace("{ruleID}", ruleUID);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ public class JRuleModuleEntry extends SimpleRule {
boolean enabled = false;

public JRuleModuleEntry(JRule jRule, Method method, String ruleName) {
this.uid = jRule.getClass().getCanonicalName().replace("org.openhab.automation.jrule.rules.user.", "") + "."
+ method.getName();
this.uid = createUid(jRule, method);
tags.add("JRule");
setTriggers(ruleTriggers);
setConditions(List.of());
Expand All @@ -71,6 +70,11 @@ public JRuleModuleEntry(JRule jRule, Method method, String ruleName) {
setTags(tags);
}

public static String createUid(JRule jRule, Method method) {
return jRule.getClass().getCanonicalName().replace("org.openhab.automation.jrule.rules.user.", "") + "."
+ method.getName();
}

public void dispose() {
executionContextList.clear();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
package org.openhab.automation.jrule.internal.module;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
Expand All @@ -20,11 +21,18 @@

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.automation.jrule.rules.JRule;
import org.openhab.core.automation.Rule;
import org.openhab.core.automation.RuleProvider;
import org.openhab.core.automation.RuleStatus;
import org.openhab.core.automation.RuleStatusDetail;
import org.openhab.core.automation.RuleStatusInfo;
import org.openhab.core.automation.events.RuleStatusInfoEvent;
import org.openhab.core.common.registry.ProviderChangeListener;
import org.openhab.core.events.EventPublisher;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;

/**
* The {@link JRuleRuleProvider} provides rules into openhab ecosystem
Expand All @@ -41,6 +49,9 @@ public class JRuleRuleProvider implements RuleProvider {

private final Map<String, JRuleModuleEntry> rules = new ConcurrentHashMap<>();

@Nullable
private EventPublisher eventPublisher;

@Override
public Collection<Rule> getAll() {
return rules.values().stream().map(e -> (Rule) e).collect(Collectors.toList());
Expand All @@ -56,6 +67,11 @@ public void removeProviderChangeListener(ProviderChangeListener<Rule> listener)
listeners.remove(listener);
}

@Reference
public void setEventPublisher(final EventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}

@Deactivate
protected void deactivate() {
rules.clear();
Expand All @@ -78,4 +94,18 @@ public void add(JRuleModuleEntry entry) {
public JRuleModuleEntry getRule(String ruleUid) {
return rules.get(ruleUid);
}

public void runRule(JRule rule, Method method) {
RuleStatusInfoEvent ruleStatusInfoEvent = JRuleEventFactory.createRuleStatusInfoEvent(
new RuleStatusInfo(RuleStatus.RUNNING, RuleStatusDetail.NONE, null),
JRuleModuleEntry.createUid(rule, method), "jRule");
eventPublisher.post(ruleStatusInfoEvent);
}

public void stopRule(JRule rule, Method method) {
RuleStatusInfoEvent ruleStatusInfoEvent = JRuleEventFactory.createRuleStatusInfoEvent(
new RuleStatusInfo(RuleStatus.IDLE, RuleStatusDetail.NONE, null),
JRuleModuleEntry.createUid(rule, method), "jRule");
eventPublisher.post(ruleStatusInfoEvent);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.openhab.automation.jrule.items.JRuleItemRegistry;
import org.openhab.automation.jrule.rules.JRule;
import org.openhab.core.events.Event;
import org.openhab.core.events.EventPublisher;
import org.openhab.core.items.GenericItem;
import org.openhab.core.items.ItemNotFoundException;
import org.openhab.core.items.ItemRegistry;
Expand Down Expand Up @@ -67,7 +68,9 @@ protected void initEngine() {
itemRegistry = Mockito.mock(ItemRegistry.class);
JRuleEventHandler.get().setItemRegistry(itemRegistry);
JRuleEngine.get().setItemRegistry(itemRegistry);
JRuleEngine.get().setRuleProvider(new JRuleRuleProvider());
JRuleRuleProvider ruleProvider = new JRuleRuleProvider();
ruleProvider.setEventPublisher(Mockito.mock(EventPublisher.class));
JRuleEngine.get().setRuleProvider(ruleProvider);

JRuleItemRegistry.setMetadataRegistry(Mockito.mock(MetadataRegistry.class));

Expand Down

0 comments on commit 9d69d80

Please sign in to comment.