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

notify for rule runs #152

Merged
merged 4 commits into from
Apr 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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