Regenerate rules from templates (#4718)
* Rule template regeneration support Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>pull/4829/head
parent
fb62bf33cd
commit
5b12280f5b
|
@ -118,4 +118,9 @@ public class RuleSupportRuleRegistryDelegate implements RuleRegistry {
|
|||
public Collection<Rule> getByTags(String... tags) {
|
||||
return ruleRegistry.getByTags(tags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void regenerateFromTemplate(String ruleUID) {
|
||||
ruleRegistry.regenerateFromTemplate(ruleUID);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
"conditions": [
|
||||
{
|
||||
"uid": "jsr223.ScriptedCondition",
|
||||
"label": "Scripted condition",
|
||||
"description": "allows the definition of a condition by a script",
|
||||
"label": "Opaque Condition",
|
||||
"description": "Evaluates a condition using external code. See the rule source for details.",
|
||||
"visibility": "EXPERT",
|
||||
"configDescriptions": [
|
||||
{
|
||||
"name": "privId",
|
||||
"type": "TEXT",
|
||||
"description": "the identifier of the private method",
|
||||
"description": "The identifier of the private method",
|
||||
"required": true
|
||||
}
|
||||
]
|
||||
|
@ -18,14 +18,14 @@
|
|||
"actions": [
|
||||
{
|
||||
"uid": "jsr223.ScriptedAction",
|
||||
"label": "Scripted action",
|
||||
"description": "allows the execution of a method defined by a script",
|
||||
"label": "Opaque Action",
|
||||
"description": "Executes external code. See the rule source for details.",
|
||||
"visibility": "EXPERT",
|
||||
"configDescriptions": [
|
||||
{
|
||||
"name": "privId",
|
||||
"type": "TEXT",
|
||||
"description": "the identifier of the private method",
|
||||
"description": "The identifier of the private method",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
|
@ -33,8 +33,8 @@
|
|||
{
|
||||
"name": "result",
|
||||
"type": "java.lang.Object",
|
||||
"label": "result",
|
||||
"description": "the script result.",
|
||||
"label": "Result",
|
||||
"description": "The script result",
|
||||
"reference": ""
|
||||
}
|
||||
]
|
||||
|
@ -43,14 +43,14 @@
|
|||
"triggers": [
|
||||
{
|
||||
"uid": "jsr223.ScriptedTrigger",
|
||||
"label": "Scripted trigger",
|
||||
"description": "allows the execution of a method defined by a script",
|
||||
"label": "Opaque Trigger",
|
||||
"description": "A trigger controlled by external code. See the rule source for details.",
|
||||
"visibility": "EXPERT",
|
||||
"configDescriptions": [
|
||||
{
|
||||
"name": "privId",
|
||||
"type": "TEXT",
|
||||
"description": "the identifier of the private method",
|
||||
"description": "The identifier of the private method",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
|
@ -58,8 +58,8 @@
|
|||
{
|
||||
"name": "triggerOutput",
|
||||
"type": "java.lang.String",
|
||||
"label": "TriggerOutput label",
|
||||
"description": "Text from the trigger",
|
||||
"label": "Trigger Output",
|
||||
"description": "The text from the trigger",
|
||||
"reference": "consoleInput",
|
||||
"defaultValue": "dtag"
|
||||
}
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
# jsr223.ScriptedAction
|
||||
|
||||
module-type.jsr223.ScriptedAction.label = Scripted action
|
||||
module-type.jsr223.ScriptedAction.description = allows the execution of a method defined by a script
|
||||
module-type.jsr223.ScriptedAction.config.privId.description = the identifier of the private method
|
||||
module-type.jsr223.ScriptedAction.output.result.label = result
|
||||
module-type.jsr223.ScriptedAction.output.result.description = the script result.
|
||||
module-type.jsr223.ScriptedAction.label = Opaque Action
|
||||
module-type.jsr223.ScriptedAction.description = Executes external code. See the rule source for details.
|
||||
module-type.jsr223.ScriptedAction.config.privId.description = The identifier of the private method
|
||||
module-type.jsr223.ScriptedAction.output.result.label = Result
|
||||
module-type.jsr223.ScriptedAction.output.result.description = The script result
|
||||
|
||||
# jsr223.ScriptedCondition
|
||||
|
||||
module-type.jsr223.ScriptedCondition.label = Scripted condition
|
||||
module-type.jsr223.ScriptedCondition.description = allows the definition of a condition by a script
|
||||
module-type.jsr223.ScriptedCondition.config.privId.description = the identifier of the private method
|
||||
module-type.jsr223.ScriptedCondition.label = Opaque Condition
|
||||
module-type.jsr223.ScriptedCondition.description = Evaluates a condition using external code. See the rule source for details.
|
||||
module-type.jsr223.ScriptedCondition.config.privId.description = The identifier of the private method
|
||||
|
||||
# jsr223.ScriptedTrigger
|
||||
|
||||
module-type.jsr223.ScriptedTrigger.label = Scripted trigger
|
||||
module-type.jsr223.ScriptedTrigger.description = allows the execution of a method defined by a script
|
||||
module-type.jsr223.ScriptedTrigger.config.privId.description = the identifier of the private method
|
||||
module-type.jsr223.ScriptedTrigger.output.triggerOutput.label = TriggerOutput label
|
||||
module-type.jsr223.ScriptedTrigger.output.triggerOutput.description = Text from the trigger
|
||||
module-type.jsr223.ScriptedTrigger.label = Opaque Trigger
|
||||
module-type.jsr223.ScriptedTrigger.description = A trigger controlled by external code. See the rule source for details.
|
||||
module-type.jsr223.ScriptedTrigger.config.privId.description = The identifier of the private method
|
||||
module-type.jsr223.ScriptedTrigger.output.triggerOutput.label = Trigger Output
|
||||
module-type.jsr223.ScriptedTrigger.output.triggerOutput.description = The text from the trigger
|
||||
|
|
|
@ -84,13 +84,13 @@ public class ScriptModuleTypeProvider extends AbstractProvider<ModuleType> imple
|
|||
List<Output> outputs = new ArrayList<>();
|
||||
Output result = new Output("result", "java.lang.Object", "result", "the script result", null, null, null);
|
||||
outputs.add(result);
|
||||
return new ActionType(ScriptActionHandler.TYPE_ID, getConfigDescriptions(locale), "execute an inline script",
|
||||
"Allows the execution of a user-defined script.", null, Visibility.VISIBLE, null, outputs);
|
||||
return new ActionType(ScriptActionHandler.TYPE_ID, getConfigDescriptions(locale), "Execute an inline script",
|
||||
"Executes a user-defined script", null, Visibility.VISIBLE, null, outputs);
|
||||
}
|
||||
|
||||
private ModuleType getScriptConditionType(@Nullable Locale locale) {
|
||||
return new ConditionType(ScriptConditionHandler.TYPE_ID, getConfigDescriptions(locale),
|
||||
"an inline script evaluates to true", "Allows the definition of a condition through a script.", null,
|
||||
"An inline script evaluates to true", "Allows the definition of a condition through a script", null,
|
||||
Visibility.VISIBLE, null);
|
||||
}
|
||||
|
||||
|
@ -111,11 +111,11 @@ public class ScriptModuleTypeProvider extends AbstractProvider<ModuleType> imple
|
|||
}
|
||||
final ConfigDescriptionParameter scriptType = ConfigDescriptionParameterBuilder.create("type", Type.TEXT)
|
||||
.withRequired(true).withMultiple(false).withLabel("Script Type")
|
||||
.withDescription("the scripting language used").withOptions(parameterOptionsList)
|
||||
.withDescription("The scripting language used").withOptions(parameterOptionsList)
|
||||
.withLimitToOptions(true).build();
|
||||
final ConfigDescriptionParameter script = ConfigDescriptionParameterBuilder.create("script", Type.TEXT)
|
||||
.withRequired(true).withReadOnly(false).withMultiple(false).withLabel("Script").withContext("script")
|
||||
.withDescription("the script to execute").build();
|
||||
.withDescription("The script to execute").build();
|
||||
return List.of(scriptType, script);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,8 +13,10 @@
|
|||
package org.openhab.core.automation.rest.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.HeaderParam;
|
||||
|
@ -100,21 +102,43 @@ public class ModuleTypeResource implements RESTResource {
|
|||
public Response getAll(
|
||||
@HeaderParam("Accept-Language") @Parameter(description = "language") @Nullable String language,
|
||||
@QueryParam("tags") @Parameter(description = "tags for filtering") @Nullable String tagList,
|
||||
@QueryParam("type") @Parameter(description = "filtering by action, condition or trigger") @Nullable String type) {
|
||||
@QueryParam("type") @Parameter(description = "filtering by action, condition or trigger") @Nullable String type,
|
||||
@QueryParam("asMap") @Parameter(description = "returns an object of arrays by type instead of a mixed array") @Nullable Boolean asMap) {
|
||||
final Locale locale = localeService.getLocale(language);
|
||||
final String[] tags = tagList != null ? tagList.split(",") : new String[0];
|
||||
final List<ModuleTypeDTO> modules = new ArrayList<>();
|
||||
Map<String, List<ModuleTypeDTO>> modulesMap = null;
|
||||
List<ModuleTypeDTO> modules = null;
|
||||
if (asMap == null || !asMap.booleanValue()) {
|
||||
modules = new ArrayList<>();
|
||||
} else {
|
||||
modulesMap = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
if (type == null || "trigger".equals(type)) {
|
||||
modules.addAll(TriggerTypeDTOMapper.map(moduleTypeRegistry.getTriggers(locale, tags)));
|
||||
if (modules != null) {
|
||||
modules.addAll(TriggerTypeDTOMapper.map(moduleTypeRegistry.getTriggers(locale, tags)));
|
||||
} else if (modulesMap != null) {
|
||||
modulesMap.put("triggers", new ArrayList<ModuleTypeDTO>(
|
||||
TriggerTypeDTOMapper.map(moduleTypeRegistry.getTriggers(locale, tags))));
|
||||
}
|
||||
}
|
||||
if (type == null || "condition".equals(type)) {
|
||||
modules.addAll(ConditionTypeDTOMapper.map(moduleTypeRegistry.getConditions(locale, tags)));
|
||||
if (modules != null) {
|
||||
modules.addAll(ConditionTypeDTOMapper.map(moduleTypeRegistry.getConditions(locale, tags)));
|
||||
} else if (modulesMap != null) {
|
||||
modulesMap.put("conditions", new ArrayList<ModuleTypeDTO>(
|
||||
ConditionTypeDTOMapper.map(moduleTypeRegistry.getConditions(locale, tags))));
|
||||
}
|
||||
}
|
||||
if (type == null || "action".equals(type)) {
|
||||
modules.addAll(ActionTypeDTOMapper.map(moduleTypeRegistry.getActions(locale, tags)));
|
||||
if (modules != null) {
|
||||
modules.addAll(ActionTypeDTOMapper.map(moduleTypeRegistry.getActions(locale, tags)));
|
||||
} else if (modulesMap != null) {
|
||||
modulesMap.put("actions", new ArrayList<ModuleTypeDTO>(
|
||||
ActionTypeDTOMapper.map(moduleTypeRegistry.getActions(locale, tags))));
|
||||
}
|
||||
}
|
||||
return Response.ok(modules).build();
|
||||
return Response.ok(modules != null ? modules : modulesMap).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
|
|
|
@ -212,7 +212,8 @@ public class RuleResource implements RESTResource {
|
|||
Stream<EnrichedRuleDTO> rules = ruleRegistry.stream().filter(p) // filter according to Predicates
|
||||
.map(rule -> EnrichedRuleDTOMapper.map(rule, ruleManager, managedRuleProvider)); // map matching rules
|
||||
if (summary != null && summary) {
|
||||
rules = dtoMapper.limitToFields(rules, "uid,templateUID,name,visibility,description,status,tags,editable");
|
||||
rules = dtoMapper.limitToFields(rules,
|
||||
"uid,templateUID,templateState,name,visibility,description,status,tags,editable");
|
||||
}
|
||||
|
||||
return Response.ok(new Stream2JSONInputStream(rules)).build();
|
||||
|
@ -344,12 +345,12 @@ public class RuleResource implements RESTResource {
|
|||
@Consumes(MediaType.TEXT_PLAIN)
|
||||
@Operation(operationId = "enableRule", summary = "Sets the rule enabled status.", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK"),
|
||||
@ApiResponse(responseCode = "404", description = "Rule corresponding to the given UID does not found.") })
|
||||
@ApiResponse(responseCode = "404", description = "Rule corresponding to the given UID was not found.") })
|
||||
public Response enableRule(@PathParam("ruleUID") @Parameter(description = "ruleUID") String ruleUID,
|
||||
@Parameter(description = "enable", required = true) String enabled) throws IOException {
|
||||
Rule rule = ruleRegistry.get(ruleUID);
|
||||
if (rule == null) {
|
||||
logger.info("Received HTTP PUT request for set enabled at '{}' for the unknown rule '{}'.",
|
||||
logger.info("Received HTTP POST request for set enabled at '{}' for the unknown rule '{}'.",
|
||||
uriInfo.getPath(), ruleUID);
|
||||
return Response.status(Status.NOT_FOUND).build();
|
||||
} else {
|
||||
|
@ -358,13 +359,32 @@ public class RuleResource implements RESTResource {
|
|||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/{ruleUID}/regenerate")
|
||||
@Consumes(MediaType.TEXT_PLAIN)
|
||||
@Operation(operationId = "regenerateRule", summary = "Regenerates the rule from its template.", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK"),
|
||||
@ApiResponse(responseCode = "404", description = "A template-based rule with the given UID was not found.") })
|
||||
public Response regenerateRule(@PathParam("ruleUID") @Parameter(description = "ruleUID") String ruleUID)
|
||||
throws IOException {
|
||||
try {
|
||||
ruleRegistry.regenerateFromTemplate(ruleUID);
|
||||
return Response.ok(null, MediaType.TEXT_PLAIN).build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.info(
|
||||
"Received HTTP POST request for regenerating rule from template at '{}' for an invalid rule UID '{}'.",
|
||||
uriInfo.getPath(), ruleUID);
|
||||
return Response.status(Status.NOT_FOUND).build();
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@RolesAllowed({ Role.USER, Role.ADMIN })
|
||||
@Path("/{ruleUID}/runnow")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Operation(operationId = "runRuleNow", summary = "Executes actions of the rule.", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK"),
|
||||
@ApiResponse(responseCode = "404", description = "Rule corresponding to the given UID does not found.") })
|
||||
@ApiResponse(responseCode = "404", description = "Rule corresponding to the given UID was not found.") })
|
||||
public Response runNow(@PathParam("ruleUID") @Parameter(description = "ruleUID") String ruleUID,
|
||||
@Nullable @Parameter(description = "the context for running this rule", allowEmptyValue = true) Map<String, Object> context)
|
||||
throws IOException {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
package org.openhab.core.automation;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
@ -40,6 +41,7 @@ import org.openhab.core.config.core.Configuration;
|
|||
* They can help the user to classify or label the Rules, and to filter and search them.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
* @author Ravi Nadahar - Added TemplateState
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface Rule extends Identifiable<String> {
|
||||
|
@ -66,6 +68,17 @@ public interface Rule extends Identifiable<String> {
|
|||
@Nullable
|
||||
String getTemplateUID();
|
||||
|
||||
/**
|
||||
* This method is used to track the template processing state by the {@link RuleRegistry}. The default
|
||||
* implementation doesn't support templates and must be overridden if the {@link Rule} implementation
|
||||
* supports templates.
|
||||
*
|
||||
* @return the current template processing state.
|
||||
*/
|
||||
default TemplateState getTemplateState() {
|
||||
return TemplateState.NO_TEMPLATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to obtain the {@link Rule}'s human-readable name.
|
||||
*
|
||||
|
@ -154,4 +167,61 @@ public interface Rule extends Identifiable<String> {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This enum represent the different states a rule can have in respect to rule templates.
|
||||
*/
|
||||
public enum TemplateState {
|
||||
|
||||
/** This {@link Rule} isn't associated with a template */
|
||||
NO_TEMPLATE,
|
||||
|
||||
/** This {@link Rule} is associated with a template and it has yet to be instantiated */
|
||||
PENDING,
|
||||
|
||||
/** This {@link Rule} is associated with a template that wasn't found */
|
||||
TEMPLATE_MISSING,
|
||||
|
||||
/** This {@link Rule} is associated with a template and has been instantiated */
|
||||
INSTANTIATED;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch (this) {
|
||||
case INSTANTIATED:
|
||||
return "instantiated";
|
||||
case PENDING:
|
||||
return "pending";
|
||||
case TEMPLATE_MISSING:
|
||||
return "template-missing";
|
||||
case NO_TEMPLATE:
|
||||
default:
|
||||
return "no-template";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link TemplateState} that best represents the specified string. If no match is found,
|
||||
* {@link TemplateState#NO_TEMPLATE} is returned.
|
||||
*
|
||||
* @param templateState the string to convert.
|
||||
* @return The resulting {@link TemplateState}.
|
||||
*/
|
||||
public static TemplateState typeOf(@Nullable String templateState) {
|
||||
if (templateState == null) {
|
||||
return NO_TEMPLATE;
|
||||
}
|
||||
String s = templateState.trim().toLowerCase(Locale.ROOT);
|
||||
switch (s) {
|
||||
case "instantiated":
|
||||
return INSTANTIATED;
|
||||
case "pending":
|
||||
return PENDING;
|
||||
case "template-missing":
|
||||
return TEMPLATE_MISSING;
|
||||
default:
|
||||
return NO_TEMPLATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,4 +85,13 @@ public interface RuleRegistry extends Registry<Rule, String> {
|
|||
* @return collection of {@link Rule}s having specified tags.
|
||||
*/
|
||||
Collection<Rule> getByTags(String... tags);
|
||||
|
||||
/**
|
||||
* This method triggers a new generation of the rule from its template by reverting the rule to its
|
||||
* "rule stub" state only containing the template configuration.
|
||||
*
|
||||
* @param ruleUID the UID of the {@link Rule}.
|
||||
* @throws IllegalArgumentException if the rule doesn't exist or isn't linked to a template.
|
||||
*/
|
||||
void regenerateFromTemplate(String ruleUID);
|
||||
}
|
||||
|
|
|
@ -64,6 +64,13 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
|||
* <td><b>N/A</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>{@link #TEMPLATE_PENDING}</b></td>
|
||||
* <td>Template processing pending</td>
|
||||
* <td>Template processing pending</td>
|
||||
* <td>Template processing pending</td>
|
||||
* <td><b>N/A</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>{@link #INVALID_RULE}</b></td>
|
||||
* <td>Resolving failed</td>
|
||||
* <td><b>N/A</b></td>
|
||||
|
@ -82,6 +89,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
|||
* @author Yordan Mihaylov - Initial contribution
|
||||
* @author Kai Kreuzer - Refactored to match ThingStatusDetail implementation
|
||||
* @author Ana Dimova - add java doc
|
||||
* @author Ravi Nadahar - added {@link #TEMPLATE_PENDING}
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum RuleStatusDetail {
|
||||
|
@ -90,8 +98,9 @@ public enum RuleStatusDetail {
|
|||
HANDLER_INITIALIZING_ERROR(2),
|
||||
CONFIGURATION_ERROR(3),
|
||||
TEMPLATE_MISSING_ERROR(4),
|
||||
INVALID_RULE(5),
|
||||
DISABLED(6);
|
||||
TEMPLATE_PENDING(5),
|
||||
INVALID_RULE(6),
|
||||
DISABLED(7);
|
||||
|
||||
private final int value;
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.openhab.core.automation.Visibility;
|
||||
import org.openhab.core.config.core.dto.ConfigDescriptionParameterDTO;
|
||||
|
||||
|
@ -26,15 +27,16 @@ import org.openhab.core.config.core.dto.ConfigDescriptionParameterDTO;
|
|||
*/
|
||||
public class RuleDTO {
|
||||
|
||||
public List<TriggerDTO> triggers;
|
||||
public List<ConditionDTO> conditions;
|
||||
public List<ActionDTO> actions;
|
||||
public Map<String, Object> configuration;
|
||||
public List<ConfigDescriptionParameterDTO> configDescriptions;
|
||||
public List<@NonNull TriggerDTO> triggers;
|
||||
public List<@NonNull ConditionDTO> conditions;
|
||||
public List<@NonNull ActionDTO> actions;
|
||||
public Map<@NonNull String, @NonNull Object> configuration;
|
||||
public List<@NonNull ConfigDescriptionParameterDTO> configDescriptions;
|
||||
public String templateUID;
|
||||
public String templateState;
|
||||
public String uid;
|
||||
public String name;
|
||||
public Set<String> tags;
|
||||
public Set<@NonNull String> tags;
|
||||
public Visibility visibility;
|
||||
public String description;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ package org.openhab.core.automation.dto;
|
|||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.automation.Rule;
|
||||
import org.openhab.core.automation.Rule.TemplateState;
|
||||
import org.openhab.core.automation.util.RuleBuilder;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.config.core.dto.ConfigDescriptionDTOMapper;
|
||||
|
@ -34,13 +35,19 @@ public class RuleDTOMapper {
|
|||
}
|
||||
|
||||
public static Rule map(final RuleDTO ruleDto) {
|
||||
return RuleBuilder.create(ruleDto.uid).withActions(ActionDTOMapper.mapDto(ruleDto.actions))
|
||||
RuleBuilder builder = RuleBuilder.create(ruleDto.uid).withActions(ActionDTOMapper.mapDto(ruleDto.actions))
|
||||
.withConditions(ConditionDTOMapper.mapDto(ruleDto.conditions))
|
||||
.withTriggers(TriggerDTOMapper.mapDto(ruleDto.triggers))
|
||||
.withConfiguration(new Configuration(ruleDto.configuration))
|
||||
.withConfigurationDescriptions(ConfigDescriptionDTOMapper.map(ruleDto.configDescriptions))
|
||||
.withTemplateUID(ruleDto.templateUID).withVisibility(ruleDto.visibility).withTags(ruleDto.tags)
|
||||
.withName(ruleDto.name).withDescription(ruleDto.description).build();
|
||||
.withName(ruleDto.name).withDescription(ruleDto.description);
|
||||
if (ruleDto.templateState == null) {
|
||||
builder.withTemplateState(ruleDto.templateUID == null ? TemplateState.NO_TEMPLATE : TemplateState.PENDING);
|
||||
} else {
|
||||
builder.withTemplateState(TemplateState.typeOf(ruleDto.templateState));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
protected static void fillProperties(final Rule from, final RuleDTO to) {
|
||||
|
@ -50,6 +57,7 @@ public class RuleDTOMapper {
|
|||
to.configuration = from.getConfiguration().getProperties();
|
||||
to.configDescriptions = ConfigDescriptionDTOMapper.mapParameters(from.getConfigurationDescriptions());
|
||||
to.templateUID = from.getTemplateUID();
|
||||
to.templateState = from.getTemplateState().toString();
|
||||
to.uid = from.getUID();
|
||||
to.name = from.getName();
|
||||
to.tags = from.getTags();
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.openhab.core.automation.Condition;
|
|||
import org.openhab.core.automation.Module;
|
||||
import org.openhab.core.automation.ModuleHandlerCallback;
|
||||
import org.openhab.core.automation.Rule;
|
||||
import org.openhab.core.automation.Rule.TemplateState;
|
||||
import org.openhab.core.automation.RuleExecution;
|
||||
import org.openhab.core.automation.RuleManager;
|
||||
import org.openhab.core.automation.RuleRegistry;
|
||||
|
@ -838,8 +839,17 @@ public class RuleEngineImpl implements RuleManager, RegistryChangeListener<Modul
|
|||
return false;
|
||||
}
|
||||
|
||||
// Set the module handlers and so check if all handlers are available.
|
||||
final String ruleUID = rule.getUID();
|
||||
TemplateState templateState = rule.unwrap().getTemplateState();
|
||||
if (templateState == TemplateState.TEMPLATE_MISSING || templateState == TemplateState.PENDING) {
|
||||
setStatus(ruleUID,
|
||||
new RuleStatusInfo(RuleStatus.UNINITIALIZED,
|
||||
templateState == TemplateState.TEMPLATE_MISSING ? RuleStatusDetail.TEMPLATE_MISSING_ERROR
|
||||
: RuleStatusDetail.TEMPLATE_PENDING));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the module handlers and so check if all handlers are available.
|
||||
final String errMsgs = setModuleHandlers(ruleUID, rule.getModules());
|
||||
if (errMsgs != null) {
|
||||
setStatus(ruleUID,
|
||||
|
@ -1562,7 +1572,7 @@ public class RuleEngineImpl implements RuleManager, RegistryChangeListener<Modul
|
|||
*/
|
||||
private void compileRules() {
|
||||
getScheduledExecutor().submit(() -> {
|
||||
ruleRegistry.getAll().stream() //
|
||||
ruleRegistry.stream() //
|
||||
.filter(r -> isEnabled(r.getUID())) //
|
||||
.forEach(r -> compileRule(r.getUID()));
|
||||
executeRulesWithStartLevel();
|
||||
|
@ -1571,7 +1581,7 @@ public class RuleEngineImpl implements RuleManager, RegistryChangeListener<Modul
|
|||
|
||||
private void executeRulesWithStartLevel() {
|
||||
getScheduledExecutor().submit(() -> {
|
||||
ruleRegistry.getAll().stream() //
|
||||
ruleRegistry.stream() //
|
||||
.filter(this::mustTrigger) //
|
||||
.forEach(r -> runNow(r.getUID(), true,
|
||||
Map.of(SystemTriggerHandler.OUT_STARTLEVEL, StartLevelService.STARTLEVEL_RULES, "event",
|
||||
|
|
|
@ -15,6 +15,7 @@ package org.openhab.core.automation.internal;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -48,6 +49,7 @@ public class RuleImpl implements Rule {
|
|||
protected Configuration configuration;
|
||||
protected List<ConfigDescriptionParameter> configDescriptions;
|
||||
protected @Nullable String templateUID;
|
||||
protected TemplateState templateStatus;
|
||||
protected String uid;
|
||||
protected @Nullable String name;
|
||||
protected Set<String> tags;
|
||||
|
@ -62,7 +64,7 @@ public class RuleImpl implements Rule {
|
|||
* @param uid the rule's identifier, or {@code null} if a random identifier should be generated.
|
||||
*/
|
||||
public RuleImpl(@Nullable String uid) {
|
||||
this(uid, null, null, null, null, null, null, null, null, null, null);
|
||||
this(uid, null, null, null, null, null, null, null, null, null, TemplateState.NO_TEMPLATE, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -90,7 +92,8 @@ public class RuleImpl implements Rule {
|
|||
public RuleImpl(@Nullable String uid, final @Nullable String name, final @Nullable String description,
|
||||
final @Nullable Set<String> tags, @Nullable List<Trigger> triggers, @Nullable List<Condition> conditions,
|
||||
@Nullable List<Action> actions, @Nullable List<ConfigDescriptionParameter> configDescriptions,
|
||||
@Nullable Configuration configuration, @Nullable String templateUID, @Nullable Visibility visibility) {
|
||||
@Nullable Configuration configuration, @Nullable String templateUID, TemplateState templateStatus,
|
||||
@Nullable Visibility visibility) {
|
||||
this.uid = uid == null ? UUID.randomUUID().toString() : uid;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
|
@ -102,6 +105,7 @@ public class RuleImpl implements Rule {
|
|||
this.configuration = configuration == null ? new Configuration()
|
||||
: new Configuration(configuration.getProperties());
|
||||
this.templateUID = templateUID;
|
||||
this.templateStatus = templateStatus;
|
||||
this.visibility = visibility == null ? Visibility.VISIBLE : visibility;
|
||||
}
|
||||
|
||||
|
@ -124,6 +128,20 @@ public class RuleImpl implements Rule {
|
|||
this.templateUID = templateUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateState getTemplateState() {
|
||||
return templateStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to specify the current rule template state.
|
||||
*
|
||||
* @param templateState the {@link TemplateState} to set.
|
||||
*/
|
||||
public void setTemplateStatus(TemplateState templateState) {
|
||||
this.templateStatus = Objects.requireNonNull(templateState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String getName() {
|
||||
return name;
|
||||
|
|
|
@ -20,18 +20,21 @@ import java.util.HashSet;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.automation.Action;
|
||||
import org.openhab.core.automation.Condition;
|
||||
import org.openhab.core.automation.ManagedRuleProvider;
|
||||
import org.openhab.core.automation.Module;
|
||||
import org.openhab.core.automation.Rule;
|
||||
import org.openhab.core.automation.Rule.TemplateState;
|
||||
import org.openhab.core.automation.RuleProvider;
|
||||
import org.openhab.core.automation.RuleRegistry;
|
||||
import org.openhab.core.automation.RuleStatus;
|
||||
import org.openhab.core.automation.RuleStatusInfo;
|
||||
import org.openhab.core.automation.Trigger;
|
||||
import org.openhab.core.automation.internal.template.RuleTemplateRegistry;
|
||||
import org.openhab.core.automation.template.RuleTemplate;
|
||||
import org.openhab.core.automation.template.TemplateRegistry;
|
||||
|
@ -101,6 +104,7 @@ import org.slf4j.LoggerFactory;
|
|||
* @author Kai Kreuzer - refactored (managed) provider and registry implementation and other fixes
|
||||
* @author Benedikt Niehues - added events for rules
|
||||
* @author Victor Toni - return only copies of {@link Rule}s
|
||||
* @author Ravi Nadahar - added support for regenerating {@link Rule}s from {@link RuleTemplate}s.
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(service = RuleRegistry.class, immediate = true)
|
||||
|
@ -108,17 +112,14 @@ public class RuleRegistryImpl extends AbstractRegistry<Rule, String, RuleProvide
|
|||
implements RuleRegistry, RegistryChangeListener<RuleTemplate> {
|
||||
|
||||
private static final String SOURCE = RuleRegistryImpl.class.getSimpleName();
|
||||
private static final Set<TemplateState> PROCESSABLE_TEMPLATE_STATES = Set.of(TemplateState.PENDING,
|
||||
TemplateState.TEMPLATE_MISSING);
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(RuleRegistryImpl.class.getName());
|
||||
|
||||
private @NonNullByDefault({}) ModuleTypeRegistry moduleTypeRegistry;
|
||||
private @NonNullByDefault({}) RuleTemplateRegistry templateRegistry;
|
||||
|
||||
/**
|
||||
* {@link Map} of template UIDs to rules where these templates participated.
|
||||
*/
|
||||
private final Map<String, Set<String>> mapTemplateToRules = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Constructor that is responsible to invoke the super constructor with appropriate providerClazz
|
||||
* {@link RuleProvider} - the class of the providers that should be tracked automatically after activation.
|
||||
|
@ -290,15 +291,6 @@ public class RuleRegistryImpl extends AbstractRegistry<Rule, String, RuleProvide
|
|||
postEvent(RuleEventFactory.createRuleStatusInfoEvent(statusInfo, ruleUID, SOURCE));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRemoveElement(Rule rule) {
|
||||
String uid = rule.getUID();
|
||||
String templateUID = rule.getTemplateUID();
|
||||
if (templateUID != null) {
|
||||
updateRuleTemplateMapping(templateUID, uid, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyListenersAboutRemovedElement(Rule element) {
|
||||
super.notifyListenersAboutRemovedElement(element);
|
||||
|
@ -336,6 +328,44 @@ public class RuleRegistryImpl extends AbstractRegistry<Rule, String, RuleProvide
|
|||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void regenerateFromTemplate(String ruleUID) {
|
||||
Rule rule = get(ruleUID);
|
||||
if (rule == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't regenerate rule from template because no rule with UID \"" + ruleUID + "\" exists");
|
||||
}
|
||||
if (rule.getTemplateUID() == null || rule.getTemplateState() == TemplateState.NO_TEMPLATE) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't regenerate rule from template because the rule isn't linked to a template");
|
||||
}
|
||||
try {
|
||||
Rule resolvedRule = resolveRuleByTemplate(
|
||||
RuleBuilder.create(rule).withActions((List<Action>) null).withConditions((List<Condition>) null)
|
||||
.withTriggers((List<Trigger>) null).withTemplateState(TemplateState.PENDING).build());
|
||||
Provider<Rule> provider = getProvider(rule.getUID());
|
||||
if (provider == null) {
|
||||
logger.error("Regenerating rule '{}' from template failed because the provider is unknown",
|
||||
rule.getUID());
|
||||
return;
|
||||
}
|
||||
if (provider instanceof ManagedRuleProvider) {
|
||||
update(resolvedRule);
|
||||
} else {
|
||||
updated(provider, rule, resolvedRule);
|
||||
}
|
||||
if (resolvedRule.getTemplateState() == TemplateState.TEMPLATE_MISSING) {
|
||||
logger.warn("Failed to regenerate rule '{}' from template since the template is missing",
|
||||
rule.getUID());
|
||||
} else {
|
||||
logger.info("Rule '{}' was regenerated from template '{}'", rule.getUID(), rule.getTemplateUID());
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.error("Regenerating rule '{}' from template failed: {}", rule.getUID(), e.getMessage(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The method checks if the rule has to be resolved by template or not. If the rule does not contain tempateUID it
|
||||
* returns same rule, otherwise it tries to resolve the rule created from template. If the template is available
|
||||
|
@ -347,46 +377,30 @@ public class RuleRegistryImpl extends AbstractRegistry<Rule, String, RuleProvide
|
|||
* missing.
|
||||
*/
|
||||
private Rule resolveRuleByTemplate(Rule rule) {
|
||||
TemplateState templateState = rule.getTemplateState();
|
||||
if (templateState == TemplateState.NO_TEMPLATE || templateState == TemplateState.INSTANTIATED) {
|
||||
return rule;
|
||||
}
|
||||
String templateUID = rule.getTemplateUID();
|
||||
if (templateUID == null) {
|
||||
return rule;
|
||||
}
|
||||
RuleTemplate template = templateRegistry.get(templateUID);
|
||||
String uid = rule.getUID();
|
||||
if (template == null) {
|
||||
updateRuleTemplateMapping(templateUID, uid, false);
|
||||
if (templateState == TemplateState.TEMPLATE_MISSING) {
|
||||
return rule;
|
||||
}
|
||||
logger.debug("Rule template {} does not exist.", templateUID);
|
||||
return rule;
|
||||
return RuleBuilder.create(rule).withTemplateState(TemplateState.TEMPLATE_MISSING).build();
|
||||
} else {
|
||||
RuleImpl resolvedRule = (RuleImpl) RuleBuilder
|
||||
.create(template, rule.getUID(), rule.getName(), rule.getConfiguration(), rule.getVisibility())
|
||||
.build();
|
||||
resolveConfigurations(resolvedRule);
|
||||
updateRuleTemplateMapping(templateUID, uid, true);
|
||||
return resolvedRule;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the content of the {@link Map} that maps the template to rules, using it to complete their definitions.
|
||||
*
|
||||
* @param templateUID the {@link RuleTemplate}'s UID specifying the template.
|
||||
* @param ruleUID the {@link Rule}'s UID specifying a rule created by the specified template.
|
||||
* @param resolved specifies if the {@link Map} should be updated by adding or removing the specified rule
|
||||
* accordingly if the rule is resolved or not.
|
||||
*/
|
||||
private void updateRuleTemplateMapping(String templateUID, String ruleUID, boolean resolved) {
|
||||
synchronized (this) {
|
||||
Set<String> ruleUIDs = Objects
|
||||
.requireNonNull(mapTemplateToRules.computeIfAbsent(templateUID, k -> new HashSet<>()));
|
||||
if (resolved) {
|
||||
ruleUIDs.remove(ruleUID);
|
||||
} else {
|
||||
ruleUIDs.add(ruleUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addProvider(Provider<Rule> provider) {
|
||||
super.addProvider(provider);
|
||||
|
@ -474,7 +488,8 @@ public class RuleRegistryImpl extends AbstractRegistry<Rule, String, RuleProvide
|
|||
ConfigurationNormalizer.normalizeConfiguration(configuration,
|
||||
ConfigurationNormalizer.getConfigDescriptionMap(configDescriptions));
|
||||
Map<String, Object> configurationProperties = configuration.getProperties();
|
||||
if (rule.getTemplateUID() == null) {
|
||||
TemplateState templateState = rule.getTemplateState();
|
||||
if (templateState == TemplateState.INSTANTIATED || templateState == TemplateState.NO_TEMPLATE) {
|
||||
String uid = rule.getUID();
|
||||
try {
|
||||
validateConfiguration(configDescriptions, new HashMap<>(configurationProperties));
|
||||
|
@ -622,38 +637,7 @@ public class RuleRegistryImpl extends AbstractRegistry<Rule, String, RuleProvide
|
|||
|
||||
@Override
|
||||
public void added(RuleTemplate element) {
|
||||
String templateUID = element.getUID();
|
||||
Set<String> rules = new HashSet<>();
|
||||
synchronized (this) {
|
||||
Set<String> rulesForResolving = mapTemplateToRules.get(templateUID);
|
||||
if (rulesForResolving != null) {
|
||||
rules.addAll(rulesForResolving);
|
||||
}
|
||||
}
|
||||
for (String rUID : rules) {
|
||||
try {
|
||||
Rule unresolvedRule = get(rUID);
|
||||
if (unresolvedRule != null) {
|
||||
Rule resolvedRule = resolveRuleByTemplate(unresolvedRule);
|
||||
Provider<Rule> provider = getProvider(rUID);
|
||||
if (provider instanceof ManagedRuleProvider) {
|
||||
update(resolvedRule);
|
||||
} else if (provider != null) {
|
||||
updated(provider, unresolvedRule, unresolvedRule);
|
||||
} else {
|
||||
logger.error(
|
||||
"Resolving the rule '{}' by template '{}' failed because the provider is not known",
|
||||
rUID, templateUID);
|
||||
}
|
||||
} else {
|
||||
logger.error(
|
||||
"Resolving the rule '{}' by template '{}' failed because it is not known to the registry",
|
||||
rUID, templateUID);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.error("Resolving the rule '{}' by template '{}' failed", rUID, templateUID, e);
|
||||
}
|
||||
}
|
||||
processRuleStubs(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -663,6 +647,34 @@ public class RuleRegistryImpl extends AbstractRegistry<Rule, String, RuleProvide
|
|||
|
||||
@Override
|
||||
public void updated(RuleTemplate oldElement, RuleTemplate element) {
|
||||
// Do nothing - resolved rules are independent from templates
|
||||
processRuleStubs(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes any existing rule stubs (rules with a template specified that haven't yet been converted into "proper
|
||||
* rules") that references the specified rule template using the new or updated rule template.
|
||||
*
|
||||
* @param template the {@link RuleTemplate} to use for processing matching rule stubs.
|
||||
*/
|
||||
protected void processRuleStubs(RuleTemplate template) {
|
||||
String templateUID = template.getUID();
|
||||
List<Rule> rules = stream().filter((r) -> PROCESSABLE_TEMPLATE_STATES.contains(r.getTemplateState())).toList();
|
||||
for (Rule unresolvedRule : rules) {
|
||||
try {
|
||||
Rule resolvedRule = resolveRuleByTemplate(unresolvedRule);
|
||||
Provider<Rule> provider = getProvider(unresolvedRule.getUID());
|
||||
if (provider instanceof ManagedRuleProvider) {
|
||||
update(resolvedRule);
|
||||
} else if (provider != null) {
|
||||
updated(provider, unresolvedRule, resolvedRule);
|
||||
} else {
|
||||
logger.error("Resolving the rule '{}' by template '{}' failed because the provider is not known",
|
||||
unresolvedRule.getUID(), templateUID);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.error("Resolving the rule '{}' by template '{}' failed", unresolvedRule.getUID(), templateUID,
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.eclipse.jdt.annotation.Nullable;
|
|||
import org.openhab.core.automation.Action;
|
||||
import org.openhab.core.automation.Condition;
|
||||
import org.openhab.core.automation.Rule;
|
||||
import org.openhab.core.automation.Rule.TemplateState;
|
||||
import org.openhab.core.automation.Trigger;
|
||||
import org.openhab.core.automation.Visibility;
|
||||
import org.openhab.core.automation.internal.RuleImpl;
|
||||
|
@ -45,6 +46,7 @@ public class RuleBuilder {
|
|||
private Configuration configuration;
|
||||
private List<ConfigDescriptionParameter> configDescriptions;
|
||||
private @Nullable String templateUID;
|
||||
private TemplateState templateState;
|
||||
private final String uid;
|
||||
private @Nullable String name;
|
||||
private Set<String> tags;
|
||||
|
@ -58,6 +60,7 @@ public class RuleBuilder {
|
|||
this.configuration = new Configuration(rule.getConfiguration());
|
||||
this.configDescriptions = new LinkedList<>(rule.getConfigurationDescriptions());
|
||||
this.templateUID = rule.getTemplateUID();
|
||||
this.templateState = TemplateState.NO_TEMPLATE;
|
||||
this.uid = rule.getUID();
|
||||
this.name = rule.getName();
|
||||
this.tags = new HashSet<>(rule.getTags());
|
||||
|
@ -74,7 +77,8 @@ public class RuleBuilder {
|
|||
return create(r.getUID()).withActions(r.getActions()).withConditions(r.getConditions())
|
||||
.withTriggers(r.getTriggers()).withConfiguration(r.getConfiguration())
|
||||
.withConfigurationDescriptions(r.getConfigurationDescriptions()).withDescription(r.getDescription())
|
||||
.withName(r.getName()).withTags(r.getTags());
|
||||
.withName(r.getName()).withTags(r.getTags()).withTemplateUID(r.getTemplateUID())
|
||||
.withTemplateState(r.getTemplateState());
|
||||
}
|
||||
|
||||
public static RuleBuilder create(RuleTemplate template, String uid, @Nullable String name,
|
||||
|
@ -82,7 +86,8 @@ public class RuleBuilder {
|
|||
return create(uid).withActions(template.getActions()).withConditions(template.getConditions())
|
||||
.withTriggers(template.getTriggers()).withConfiguration(configuration)
|
||||
.withConfigurationDescriptions(template.getConfigurationDescriptions())
|
||||
.withDescription(template.getDescription()).withName(name).withTags(template.getTags());
|
||||
.withDescription(template.getDescription()).withName(name).withTags(template.getTags())
|
||||
.withTemplateState(TemplateState.INSTANTIATED).withTemplateUID(template.getUID());
|
||||
}
|
||||
|
||||
public RuleBuilder withName(@Nullable String name) {
|
||||
|
@ -100,6 +105,11 @@ public class RuleBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public RuleBuilder withTemplateState(TemplateState templateState) {
|
||||
this.templateState = templateState;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RuleBuilder withVisibility(@Nullable Visibility visibility) {
|
||||
this.visibility = visibility;
|
||||
return this;
|
||||
|
@ -166,6 +176,6 @@ public class RuleBuilder {
|
|||
|
||||
public Rule build() {
|
||||
return new RuleImpl(uid, name, description, tags, triggers, conditions, actions, configDescriptions,
|
||||
configuration, templateUID, visibility);
|
||||
configuration, templateUID, templateState, visibility);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.openhab.core.automation.Action;
|
|||
import org.openhab.core.automation.Condition;
|
||||
import org.openhab.core.automation.ManagedRuleProvider;
|
||||
import org.openhab.core.automation.Rule;
|
||||
import org.openhab.core.automation.Rule.TemplateState;
|
||||
import org.openhab.core.automation.RuleManager;
|
||||
import org.openhab.core.automation.RuleProvider;
|
||||
import org.openhab.core.automation.RuleRegistry;
|
||||
|
@ -678,7 +679,7 @@ public class AutomationIntegrationTest extends JavaOSGiTest {
|
|||
configs.put("updateItem", "templ_LampItem");
|
||||
configs.put("updateCommand", "ON");
|
||||
Rule templateRule = RuleBuilder.create("templateRuleUID").withTemplateUID("SimpleTestTemplate")
|
||||
.withConfiguration(new Configuration(configs)).build();
|
||||
.withTemplateState(TemplateState.PENDING).withConfiguration(new Configuration(configs)).build();
|
||||
ruleRegistry.add(templateRule);
|
||||
assertThat(ruleRegistry.get(templateRule.getUID()), is(notNullValue()));
|
||||
|
||||
|
@ -727,7 +728,7 @@ public class AutomationIntegrationTest extends JavaOSGiTest {
|
|||
configs.put("updateCommand", "ON");
|
||||
Configuration config = new Configuration(configs);
|
||||
Rule templateRule = RuleBuilder.create("xtemplateRuleUID").withTemplateUID("TestTemplateWithCompositeModules")
|
||||
.withConfiguration(config).build();
|
||||
.withTemplateState(TemplateState.PENDING).withConfiguration(config).build();
|
||||
|
||||
ruleRegistry.add(templateRule);
|
||||
assertThat(ruleRegistry.get(templateRule.getUID()), is(notNullValue()));
|
||||
|
|
Loading…
Reference in New Issue