diff options
Diffstat (limited to 'dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor')
25 files changed, 1127 insertions, 0 deletions
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/ConditionTypeEnum.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/ConditionTypeEnum.java new file mode 100644 index 0000000..e4921e2 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/ConditionTypeEnum.java @@ -0,0 +1,22 @@ +package org.onap.sdc.dcae.rule.editor.enums; + +import java.util.Arrays; + +public enum ConditionTypeEnum { + ALL("And"), ANY("Or"); + + public String getFilterClass() { + return filterClass; + } + + private String filterClass; + + ConditionTypeEnum(String filterClass) { + + this.filterClass = filterClass; + } + + public static ConditionTypeEnum getTypeByName(String name) { + return Arrays.stream(ConditionTypeEnum.values()).filter(type -> name.equalsIgnoreCase(type.name())).findAny().orElse(null); + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/OperatorTypeEnum.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/OperatorTypeEnum.java new file mode 100644 index 0000000..2cd03a7 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/OperatorTypeEnum.java @@ -0,0 +1,32 @@ +package org.onap.sdc.dcae.rule.editor.enums; + +import java.util.Arrays; + +public enum OperatorTypeEnum { + EQUALS("Equals", "OneOf"), + NOT_EQUAL("NotEqual", "NotOneOf"), + CONTAINS("Contains", null), + ENDS_WITH("EndsWith", null), + STARTS_WITH("StartsWith", null); + + private String type; + private String modifiedType; + + OperatorTypeEnum(String type, String modifiedType) { + this.type = type; + this.modifiedType = modifiedType; + } + + public String getType() { + return type; + } + + public String getModifiedType() { + return modifiedType; + } + + public static OperatorTypeEnum getTypeByName(String name) { + return Arrays.stream(OperatorTypeEnum.values()).filter(type -> name.replaceAll(" ", "").equalsIgnoreCase(type.getType())).findAny().orElse(null); + } + +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/RuleEditorElementType.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/RuleEditorElementType.java new file mode 100644 index 0000000..0bec7d8 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/RuleEditorElementType.java @@ -0,0 +1,58 @@ +package org.onap.sdc.dcae.rule.editor.enums; + +import java.util.Arrays; + +import org.onap.sdc.dcae.rule.editor.translators.ConditionGroupTranslator; +import org.onap.sdc.dcae.rule.editor.translators.ConditionTranslator; +import org.onap.sdc.dcae.rule.editor.translators.CopyActionTranslator; +import org.onap.sdc.dcae.rule.editor.translators.DateFormatterTranslator; +import org.onap.sdc.dcae.rule.editor.translators.FieldConditionTranslator; +import org.onap.sdc.dcae.rule.editor.translators.IRuleElementTranslator; +import org.onap.sdc.dcae.rule.editor.translators.MapActionTranslator; +import org.onap.sdc.dcae.rule.editor.translators.MappingRulesTranslator; +import org.onap.sdc.dcae.rule.editor.translators.RegexActionTranslator; +import org.onap.sdc.dcae.rule.editor.translators.RuleTranslator; +import org.onap.sdc.dcae.rule.editor.validators.ActionValidator; +import org.onap.sdc.dcae.rule.editor.validators.ConcatActionValidator; +import org.onap.sdc.dcae.rule.editor.validators.ConditionGroupValidator; +import org.onap.sdc.dcae.rule.editor.validators.ConditionValidator; +import org.onap.sdc.dcae.rule.editor.validators.DateFormatterValidator; +import org.onap.sdc.dcae.rule.editor.validators.IRuleElementValidator; +import org.onap.sdc.dcae.rule.editor.validators.MapActionValidator; +import org.onap.sdc.dcae.rule.editor.validators.RuleValidator; + +public enum RuleEditorElementType { + COPY("Copy", ActionValidator.getInstance(), CopyActionTranslator.getInstance()), + CONCAT("Concat", ConcatActionValidator.getInstance(), CopyActionTranslator.getInstance()), + MAP("Map", MapActionValidator.getInstance(), MapActionTranslator.getInstance()), + REGEX("Regex", ActionValidator.getInstance(), RegexActionTranslator.getInstance()), + DATE_FORMATTER("DateFormatter", DateFormatterValidator.getInstance(), DateFormatterTranslator.getInstance()), + CONDITION("Condition", ConditionValidator.getInstance(), ConditionTranslator.getInstance()), + FIELD_CONDITION("FieldCondition", ConditionValidator.getInstance(), FieldConditionTranslator.getInstance()), + CONDITION_GROUP("ConditionGroup", ConditionGroupValidator.getInstance(), ConditionGroupTranslator.getInstance()), + RULE("Rule", RuleValidator.getInstance(), RuleTranslator.getInstance()), + MAPPING_RULES("MappingRules", null, MappingRulesTranslator.getInstance()); + + private String elementType; + private IRuleElementValidator validator; + private IRuleElementTranslator translator; + + public IRuleElementValidator getValidator() { + return validator; + } + + public IRuleElementTranslator getTranslator() { + return translator; + } + + RuleEditorElementType(String elementType, IRuleElementValidator validator, IRuleElementTranslator translator) { + this.elementType = elementType; + this.validator = validator; + this.translator = translator; + } + + public static RuleEditorElementType getElementTypeByName(String name) { + return Arrays.stream(RuleEditorElementType.values()).filter(p -> p.elementType.equalsIgnoreCase(name)) + .findAny().orElse(null); + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogic.java new file mode 100644 index 0000000..849ad42 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogic.java @@ -0,0 +1,149 @@ +package org.onap.sdc.dcae.rule.editor.impl; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.apache.commons.lang3.StringUtils; +import org.onap.sdc.common.onaplog.OnapLoggerDebug; +import org.onap.sdc.common.onaplog.Enums.LogLevel; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.*; +import org.onap.sdc.dcae.errormng.ActionStatus; +import org.onap.sdc.dcae.errormng.ErrConfMgr; +import org.onap.sdc.dcae.errormng.ResponseFormat; +import org.onap.sdc.dcae.errormng.ServiceException; +import org.onap.sdc.dcae.rule.editor.translators.MappingRulesTranslator; +import org.onap.sdc.dcae.rule.editor.utils.EmptyStringTranslationSerializer; +import org.onap.sdc.dcae.rule.editor.validators.RuleValidator; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Component +public class RulesBusinessLogic { + + protected OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); + private RuleValidator ruleValidator = RuleValidator.getInstance(); + private MappingRulesTranslator mappingRulesTranslator = MappingRulesTranslator.getInstance(); + private static Gson gsonTranslator = new GsonBuilder().registerTypeAdapter(String.class, new EmptyStringTranslationSerializer()).enableComplexMapKeySerialization().create(); + + public List<ServiceException> validateRule(Rule rule) { + List<ResponseFormat> errors = new ArrayList<>(); + if(ruleValidator.validate(rule, errors)) + detectAndResolveActionDependencies(rule, errors); + return errors.stream().map(r -> r.getRequestError().getServiceException()).collect(Collectors.toList()); + } + + public List<ServiceException> validateRules(MappingRules rules) { + List<ResponseFormat> errors = new ArrayList<>(); + detectAndResolveRuleDependencies(rules, errors); + return errors.stream().map(r -> r.getRequestError().getServiceException()).collect(Collectors.toList()); + } + + public String translateRules(MappingRules rules, String entryPointPhase, String lastPhase, String runPhase) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Start translating mapping rules"); + return gsonTranslator.toJson(mappingRulesTranslator.translateToHpJson(rules, entryPointPhase, lastPhase, runPhase)); + } + + public boolean addOrEditRule(MappingRules rules, Rule rule) { + // in case the rule id is passed but the rule doesn't exist on the mapping rule file: + if(StringUtils.isNotBlank(rule.getUid()) && !rules.ruleExists(rule)) + return false; + rules.addOrReplaceRule(rule); + return true; + } + + public Rule deleteRule(MappingRules rules, String ruleUid) { + return rules.removeRule(ruleUid); + } + + private <T> List<T> detectDependentItemsByDependencyDefinition(Collection<T> allItems, BiFunction<T, Collection<T>, Boolean> dependencyDefinition) { + return allItems.stream().filter(i -> dependencyDefinition.apply(i, allItems)).collect(Collectors.toList()); + } + + // if all dependencies are resolvable returns empty list + // else returns list of non resolvable items (circular dependent items) + // iterate through all dependentItems removing resolvable items each iteration. + + private <T> List<T> detectCircularDependenciesByDependencyDefinition(List<T> dependentItems, BiFunction<T, Collection<T>, Boolean> dependencyDetector) { + while(!CollectionUtils.isEmpty(dependentItems)) { + List<T> resolvable = dependentItems.stream() + .filter(i -> !dependencyDetector.apply(i, dependentItems)) + .collect(Collectors.toList()); + if(CollectionUtils.isEmpty(resolvable)) + break; + dependentItems.removeAll(resolvable); + } + return dependentItems; + } + + private <T> List<T> reorderItemsByDependencyDefinition(Collection<T> allItems, BiFunction<T, T, Boolean> dependencyDetector) { + List<T> ordered = new ArrayList<>(allItems); + allItems.forEach(i -> { + List<T> dependencies = allItems.stream().filter(o -> dependencyDetector.apply(i, o)).collect(Collectors.toList()); + dependencies.forEach(d -> { + if(ordered.indexOf(d) > ordered.indexOf(i)) { + ordered.remove(d); + ordered.add(ordered.indexOf(i), d); + } + }); + }); + return ordered; + } + + private void detectAndResolveActionDependencies(Rule rule, List<ResponseFormat> errors) { + List<BaseAction> dependentActions = detectDependentItemsByDependencyDefinition(rule.getActions(), BaseAction::hasDependencies); + if(!CollectionUtils.isEmpty(dependentActions)) { + List<BaseAction> nonResolvable = detectCircularDependenciesByDependencyDefinition(dependentActions, BaseAction::hasDependencies); + if (!CollectionUtils.isEmpty(nonResolvable)) { + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.ACTION_DEPENDENCY, null, nonResolvable.stream().map(BaseAction::getTarget).collect(Collectors.joining(", ")))); + return; + } + List<BaseAction> actions = reorderItemsByDependencyDefinition(rule.getActions(), BaseAction::referencesTarget); + rule.setActions(actions); + } + } + + // first identify dependent rules + // if no dependencies found return true + // if non resolvable dependencies found return false + // else reorder and return true + + private void detectAndResolveRuleDependencies(MappingRules rules, List<ResponseFormat> errors) { + List<Rule> dependentRules = detectDependentItemsByDependencyDefinition(rules.getRules().values(), Rule::referencesOtherRules); + if(!CollectionUtils.isEmpty(dependentRules)) { + List<Rule> nonResolvable = detectCircularDependenciesByDependencyDefinition(dependentRules, Rule::referencesOtherRules); + if (!CollectionUtils.isEmpty(nonResolvable)) { + String nonResolvableRuleIds = nonResolvable.stream().map(Rule::getUid).collect(Collectors.joining(", ")); + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.RULE_DEPENDENCY, null, nonResolvableRuleIds, extractDependentActionTargetsFromRules(nonResolvable))); + return; + } + reorderRulesByDependency(rules); + } + } + + private String extractDependentActionTargetsFromRules(List<Rule> dependentRules) { + List<BaseAction> allActions = dependentRules.stream().map(Rule::getActions).flatMap(List::stream).collect(Collectors.toList()); + // option 1: circular dependency between actions + List<BaseAction> nonResolvable = detectCircularDependenciesByDependencyDefinition(allActions, BaseAction::hasDependencies); + if(CollectionUtils.isEmpty(nonResolvable)) + // option 2: circular dependency between rules - collect dependent actions and condition dependencies + nonResolvable = dependentRules.stream() + .map(r -> r.findDependencies(dependentRules)) + .flatMap(List::stream) + .collect(Collectors.toList()); + return nonResolvable.stream() + .map(BaseAction::getTarget) + .collect(Collectors.joining(", ")); + } + + private void reorderRulesByDependency(MappingRules rules) { + List<Rule> ordered = reorderItemsByDependencyDefinition(rules.getRules().values(), Rule::referencesOtherRule); + Map<String, Rule> rulesMap = ordered.stream().collect(Collectors.toMap(Rule::getUid, Function.identity(), (u, v) -> { + throw new IllegalStateException(String.format("Duplicate key %s", u)); + }, LinkedHashMap::new)); + rules.setRules(rulesMap); + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionGroupTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionGroupTranslator.java new file mode 100644 index 0000000..093c239 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionGroupTranslator.java @@ -0,0 +1,47 @@ +package org.onap.sdc.dcae.rule.editor.translators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.*; +import org.onap.sdc.dcae.rule.editor.enums.ConditionTypeEnum; +import org.onap.sdc.dcae.rule.editor.enums.OperatorTypeEnum; +import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class ConditionGroupTranslator implements IRuleElementTranslator<ConditionGroup> { + + private static ConditionGroupTranslator conditionGroupTranslator = new ConditionGroupTranslator(); + + public static ConditionGroupTranslator getInstance() { + return conditionGroupTranslator; + } + + private ConditionGroupTranslator(){} + + public Translation translateToHpJson(ConditionGroup conditionGroup) { + String clazz = ConditionTypeEnum.getTypeByName(conditionGroup.getType()).getFilterClass(); + FiltersTranslation translation = new FiltersTranslation(clazz, conditionGroup.getChildren().stream() + .map(this::getTranslation) + .collect(Collectors.toList())); + flattenNestedFilters(translation, clazz); + return translation; + } + + + private IRuleElementTranslator getConditionTranslator(BaseCondition condition){ + return condition instanceof ConditionGroup ? ConditionGroupTranslator.getInstance() : + ValidationUtils.validateNotEmpty(OperatorTypeEnum.getTypeByName(((Condition)condition).getOperator()).getModifiedType()) ? FieldConditionTranslator.getInstance() : ConditionTranslator.getInstance(); + } + + private Translation getTranslation(BaseCondition condition) { + return getConditionTranslator(condition).translateToHpJson(condition); + } + + private void flattenNestedFilters(FiltersTranslation filtersTranslation, String clazz) { + Map<Boolean, List<Translation>> partitioned = filtersTranslation.filters.stream().collect(Collectors.partitioningBy(f -> clazz.equals(((ProcessorTranslation) f).clazz))); + filtersTranslation.filters.removeAll(partitioned.get(Boolean.TRUE)); + filtersTranslation.filters.addAll(partitioned.get(Boolean.TRUE).stream().map(f -> ((FiltersTranslation) f).filters).flatMap(List::stream).collect(Collectors.toList())); + } + +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionTranslator.java new file mode 100644 index 0000000..f93101b --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionTranslator.java @@ -0,0 +1,40 @@ +package org.onap.sdc.dcae.rule.editor.translators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.Condition; +import org.onap.sdc.dcae.rule.editor.enums.ConditionTypeEnum; +import org.onap.sdc.dcae.rule.editor.enums.OperatorTypeEnum; + +import java.util.stream.Collectors; + +public class ConditionTranslator implements IRuleElementTranslator<Condition> { + + private static ConditionTranslator conditionTranslator = new ConditionTranslator(); + + public static ConditionTranslator getInstance() { + return conditionTranslator; + } + + private ConditionTranslator(){} + + private class StringFilterTranslation extends ProcessorTranslation { + private String string; + private String value; + + private StringFilterTranslation(Condition condition, String value){ + this.clazz = OperatorTypeEnum.getTypeByName(condition.getOperator()).getType(); + this.string = condition.getLeft(); + this.value = value; + } + + private StringFilterTranslation(Condition condition){ + this(condition, condition.getRight().get(0)); + } + } + + public Translation translateToHpJson(Condition condition) { + return 1 == condition.getRight().size() ? new StringFilterTranslation(condition) : new FiltersTranslation(ConditionTypeEnum.ANY.getFilterClass(), condition.getRight().stream() + .map(r -> new StringFilterTranslation(condition, r)).collect(Collectors.toList())); + } + + +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/CopyActionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/CopyActionTranslator.java new file mode 100644 index 0000000..9d02c8e --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/CopyActionTranslator.java @@ -0,0 +1,47 @@ +package org.onap.sdc.dcae.rule.editor.translators; + +import org.onap.sdc.common.onaplog.Enums.LogLevel; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction; + +public class CopyActionTranslator<A extends BaseAction> implements IRuleElementTranslator<A>{ + + private static CopyActionTranslator copyActionTranslator = new CopyActionTranslator(); + + public static CopyActionTranslator getInstance() { + return copyActionTranslator; + } + + CopyActionTranslator(){} + + public Translation translateToHpJson(A action) { + return new CopyActionSetTranslation(action.getTarget(), action.getFromValue()); + } + + void addToHpJsonProcessors(A action, List<Translation> processors) { + processors.add(translateToHpJson(action)); + } + + public boolean addToHpJsonProcessors(A action, List<Translation> processors, boolean asNewProcessor) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translating {} action. New Processor: {}", action.getActionType(), asNewProcessor); + if(asNewProcessor) + addToHpJsonProcessors(action, processors); + else + ((CopyActionSetTranslation) processors.get(processors.size()-1)).updates.put(action.getTarget(), action.getFromValue()); + return false; + } + + class CopyActionSetTranslation extends ProcessorTranslation { + Map<String, String> updates = new LinkedHashMap<>(); + CopyActionSetTranslation(String target, String from) { + clazz = "Set"; + updates.put(target, from); + } + } + +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/DateFormatterTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/DateFormatterTranslator.java new file mode 100644 index 0000000..89f0def --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/DateFormatterTranslator.java @@ -0,0 +1,49 @@ +package org.onap.sdc.dcae.rule.editor.translators; + +import org.onap.sdc.common.onaplog.Enums.LogLevel; +import java.util.List; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.DateFormatterAction; + +public class DateFormatterTranslator extends CopyActionTranslator<DateFormatterAction> { + + private static DateFormatterTranslator dateFormatterTranslator = new DateFormatterTranslator(); + + public static DateFormatterTranslator getInstance() { + return dateFormatterTranslator; + } + + private DateFormatterTranslator(){} + + private class DateFormatterTranslation extends ProcessorTranslation { + private String fromFormat; + private String fromTz; + private String toField; + private String toFormat; + private String toTz; + private String value; + + private DateFormatterTranslation(DateFormatterAction action){ + clazz = "DateFormatter"; + fromFormat = action.getFromFormat(); + fromTz = action.getFromTz(); + toField = action.getTarget(); + toFormat = action.getToFormat(); + toTz = action.getToTz(); + value = action.getFromValue(); + } + } + + @Override + public boolean addToHpJsonProcessors(DateFormatterAction action, List<Translation> processors, boolean asNewProcessor) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translating date formatter action"); + addToHpJsonProcessors(action, processors); + return true; + } + + @Override + public Translation translateToHpJson(DateFormatterAction action){ + return new DateFormatterTranslation(action); + } + +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/FieldConditionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/FieldConditionTranslator.java new file mode 100644 index 0000000..ef2949e --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/FieldConditionTranslator.java @@ -0,0 +1,43 @@ +package org.onap.sdc.dcae.rule.editor.translators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.Condition; +import org.onap.sdc.dcae.rule.editor.enums.OperatorTypeEnum; + +import java.util.List; + +public class FieldConditionTranslator implements IRuleElementTranslator<Condition> { + + private static FieldConditionTranslator fieldConditionTranslator = new FieldConditionTranslator(); + + public static FieldConditionTranslator getInstance() { + return fieldConditionTranslator; + } + + private FieldConditionTranslator(){} + + private class FieldFilterTranslation extends ProcessorTranslation { + private String field; + private String value; + + private FieldFilterTranslation(Condition condition) { + clazz = OperatorTypeEnum.getTypeByName(condition.getOperator()).getType(); + field = condition.getLeft(); + value = condition.getRight().get(0); + } + } + + private class MultiFieldFilterTranslation extends ProcessorTranslation { + private String field; + private List<String> values; + + private MultiFieldFilterTranslation(Condition condition) { + field = condition.getLeft(); + values = condition.getRight(); + clazz = OperatorTypeEnum.getTypeByName(condition.getOperator()).getModifiedType(); + } + } + + public Translation translateToHpJson(Condition condition) { + return 1 == condition.getRight().size() ? new FieldFilterTranslation(condition) : new MultiFieldFilterTranslation(condition); + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/IRuleElementTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/IRuleElementTranslator.java new file mode 100644 index 0000000..dac818d --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/IRuleElementTranslator.java @@ -0,0 +1,50 @@ +package org.onap.sdc.dcae.rule.editor.translators; + +import com.google.gson.annotations.SerializedName; +import org.onap.sdc.common.onaplog.OnapLoggerDebug; +import org.onap.sdc.common.onaplog.OnapLoggerError; + +import java.util.ArrayList; +import java.util.List; + +public interface IRuleElementTranslator<T> { + + OnapLoggerError errLogger = OnapLoggerError.getInstance(); + OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); + + Translation translateToHpJson(T element); + + abstract class Translation { + } + + class ProcessorTranslation extends Translation { + @SerializedName("class") + protected String clazz; + } + + + class FiltersTranslation extends ProcessorTranslation { + protected List<Translation> filters; + + protected FiltersTranslation(String clazz, List<Translation> filters) { + this.clazz = clazz; + this.filters = filters; + } + } + + class RuleTranslation extends Translation { + protected String phase; + protected Translation filter; + protected List<Translation> processors = new ArrayList<>(); + } + + class RunPhaseProcessorsTranslation extends ProcessorTranslation { + protected String phase; + + protected RunPhaseProcessorsTranslation(String runPhase){ + clazz ="RunPhase"; + phase = runPhase; + } + } + +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MapActionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MapActionTranslator.java new file mode 100644 index 0000000..922312e --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MapActionTranslator.java @@ -0,0 +1,50 @@ +package org.onap.sdc.dcae.rule.editor.translators; + +import com.google.gson.annotations.SerializedName; + +import org.onap.sdc.common.onaplog.Enums.LogLevel; + +import java.util.List; +import java.util.Map; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.MapAction; + +public class MapActionTranslator extends CopyActionTranslator<MapAction> { + + private static MapActionTranslator mapActionTranslator = new MapActionTranslator(); + + public static MapActionTranslator getInstance() { + return mapActionTranslator; + } + + private MapActionTranslator(){} + + private class MapActionTranslation extends ProcessorTranslation { + + private Map<String, String> map; + private String field; + private String toField; + @SerializedName("default") + private String Default; + + private MapActionTranslation(MapAction action) { + clazz = "MapAlarmValues"; + Default = action.getMapDefaultValue(); + field = action.getFromValue(); + toField = action.getTarget(); + map = action.transformToMap(); + } + } + + @Override + public Translation translateToHpJson(MapAction action) { + return new MapActionTranslation(action); + } + + @Override + public boolean addToHpJsonProcessors(MapAction action, List<Translation> processors, boolean asNewProcessor) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translating map action"); + addToHpJsonProcessors(action, processors); + return true; + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MappingRulesTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MappingRulesTranslator.java new file mode 100644 index 0000000..0164446 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MappingRulesTranslator.java @@ -0,0 +1,69 @@ +package org.onap.sdc.dcae.rule.editor.translators; + +import java.util.List; +import java.util.stream.Collectors; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.MappingRules; + +public class MappingRulesTranslator implements IRuleElementTranslator<MappingRules> { + + private static MappingRulesTranslator mappingRulesTranslator = new MappingRulesTranslator(); + + public static MappingRulesTranslator getInstance() { + return mappingRulesTranslator; + } + + private MappingRulesTranslator() { + } + + private RuleTranslator ruleTranslator = RuleTranslator.getInstance(); + + public Translation translateToHpJson(MappingRules mappingRules) { + return new MappingRulesTranslation(mappingRules); + } + + public Translation translateToHpJson(MappingRules mappingRules, String entryPointPhaseName, String lastPhaseName, String runPhase) { + // 1806 US349308 assign Vfcmt name as rule phaseName + mappingRules.getRules().forEach((k,v) -> v.setPhase(runPhase)); + return new MappingRulesTranslation(mappingRules, entryPointPhaseName, lastPhaseName, runPhase); + } + + private class MappingRulesTranslation extends Translation { + + private List<Translation> processing; + + private MappingRulesTranslation(MappingRules mappingRules) { + processing = mappingRules.getRules().values().stream().map(ruleTranslator::translateToHpJson).collect(Collectors.toList()); + } + + private MappingRulesTranslation(MappingRules mappingRules, String entryPointPhaseName, String lastPhaseName, String runPhase) { + this(mappingRules); + //hardcoded entry point processor + processing.add(0, new RunPhaseRuleTranslation(entryPointPhaseName, runPhase)); + //hardcoded map_publish processor + processing.add(new RunPhaseRuleTranslation(runPhase, lastPhaseName)); + } + } + + private class RunPhaseRuleTranslation extends RuleTranslation { + + private RunPhaseRuleTranslation(String phaseName, String runPhase) { + phase = phaseName; + if ("snmp_map".equals(phaseName)) + processors.add(new SnmpConvertor()); + processors.add(new RunPhaseProcessorsTranslation(runPhase)); + } + } + + // hardcoded SNMP processor + private class SnmpConvertor extends ProcessorTranslation { + private String array = "varbinds"; + private String datacolumn = "varbind_value"; + private String keycolumn = "varbind_oid"; + + private SnmpConvertor() { + clazz = "SnmpConvertor"; + } + } + +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RegexActionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RegexActionTranslator.java new file mode 100644 index 0000000..c49a04e --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RegexActionTranslator.java @@ -0,0 +1,44 @@ +package org.onap.sdc.dcae.rule.editor.translators; + +import org.onap.sdc.common.onaplog.Enums.LogLevel; +import java.util.List; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction; + +public class RegexActionTranslator extends CopyActionTranslator<BaseAction> { + + private static RegexActionTranslator regexActionTranslator = new RegexActionTranslator(); + + public static RegexActionTranslator getInstance() { + return regexActionTranslator; + } + + private RegexActionTranslator(){} + + private class RegexCopyActionTranslation extends ProcessorTranslation { + + private String regex; + private String field; + private String value; + + private RegexCopyActionTranslation(BaseAction action) { + clazz = "ExtractText"; + regex = action.getRegexValue(); + field = action.getTarget(); + value = action.getFromValue(); + } + } + + @Override + public boolean addToHpJsonProcessors(BaseAction action, List<Translation> processors, boolean asNewProcessor) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translating copy action as regex action"); + addToHpJsonProcessors(action, processors); + return true; + } + + @Override + public Translation translateToHpJson(BaseAction action) { + return new RegexCopyActionTranslation(action); + } + +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RuleTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RuleTranslator.java new file mode 100644 index 0000000..f7dea47 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RuleTranslator.java @@ -0,0 +1,51 @@ +package org.onap.sdc.dcae.rule.editor.translators; + +import com.google.gson.Gson; +import org.onap.sdc.common.onaplog.Enums.LogLevel; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.*; +import org.onap.sdc.dcae.rule.editor.enums.OperatorTypeEnum; +import org.onap.sdc.dcae.rule.editor.enums.RuleEditorElementType; +import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils; + +public class RuleTranslator implements IRuleElementTranslator<Rule> { + + private static RuleTranslator ruleTranslator = new RuleTranslator(); + + public static RuleTranslator getInstance() { + return ruleTranslator; + } + + private RuleTranslator() { + } + + private class ActionRuleTranslation extends RuleTranslation { + private ActionRuleTranslation(Rule rule) { + phase = rule.getPhase(); + filter = rule.isConditionalRule() ? getConditionTranslator(rule.getCondition()).translateToHpJson(rule.getCondition()) : null; + boolean asNewProcessor = true; + for (BaseAction action : rule.getActions()) { + // consecutive copy actions are aggregated into a single processor + asNewProcessor = getActionTranslator(action).addToHpJsonProcessors(action, processors, asNewProcessor); + } + } + } + + public Translation translateToHpJson(Rule rule) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Start translating rule {}", rule.getUid()); + Translation translation = new ActionRuleTranslation(rule); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Finished translation for rule {}. Result: {}", rule.getUid(), new Gson().toJson(translation)); + return translation; + } + + private IRuleElementTranslator getConditionTranslator(BaseCondition condition){ + return condition instanceof ConditionGroup ? ConditionGroupTranslator.getInstance() : + ValidationUtils.validateNotEmpty(OperatorTypeEnum.getTypeByName(((Condition)condition).getOperator()).getModifiedType()) ? FieldConditionTranslator.getInstance() : ConditionTranslator.getInstance(); + } + + private CopyActionTranslator getActionTranslator(BaseAction action) { + ActionTypeEnum type = ActionTypeEnum.getTypeByName(action.getActionType()); + if(ActionTypeEnum.COPY == type && ValidationUtils.validateNotEmpty(action.getRegexValue())) + return RegexActionTranslator.getInstance(); + return (CopyActionTranslator)RuleEditorElementType.getElementTypeByName(type.getType()).getTranslator(); + } +}
\ No newline at end of file diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/EmptyStringTranslationSerializer.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/EmptyStringTranslationSerializer.java new file mode 100644 index 0000000..c65076f --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/EmptyStringTranslationSerializer.java @@ -0,0 +1,14 @@ +package org.onap.sdc.dcae.rule.editor.utils; + +import com.google.gson.*; + +import java.lang.reflect.Type; + +public class EmptyStringTranslationSerializer implements JsonSerializer<String> { + + public JsonElement serialize(String src, Type typeOfSrc, JsonSerializationContext context) { + if("\"\"".equals(src)) + return new JsonPrimitive(""); + return new JsonPrimitive(src); + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/RulesPayloadUtils.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/RulesPayloadUtils.java new file mode 100644 index 0000000..33f9e92 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/RulesPayloadUtils.java @@ -0,0 +1,38 @@ +package org.onap.sdc.dcae.rule.editor.utils; + +import java.util.List; + +import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.*; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; + +public class RulesPayloadUtils { + private static Gson gson = new GsonBuilder().serializeNulls() + .registerTypeAdapter(BaseAction.class, new ActionDeserializer()) + .registerTypeAdapter(BaseCondition.class, new ConditionDeserializer()).create(); + + public static Rule parsePayloadToRule(String payload) throws JsonParseException { + return gson.fromJson(payload, Rule.class); + } + + public static MappingRules parseMappingRulesArtifactPayload(String payload) throws JsonParseException { + return gson.fromJson(payload, MappingRules.class); + } + + public static SchemaInfo extractInfoFromDescription(Artifact rulesArtifact) { + try { + return gson.fromJson(rulesArtifact.getArtifactDescription(), SchemaInfo.class); + }catch (JsonParseException e) { + return null; + } + } + + public static String buildSchemaAndRulesResponse(String payload, List<EventTypeDefinitionUI> schema) { + return "{\"schema\":"+gson.toJson(schema)+","+payload.replaceFirst("\\{", ""); + } + + +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/ValidationUtils.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/ValidationUtils.java new file mode 100644 index 0000000..7a3b206 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/ValidationUtils.java @@ -0,0 +1,20 @@ +package org.onap.sdc.dcae.rule.editor.utils; + +import org.apache.commons.lang3.StringUtils; + + +public class ValidationUtils { + + private static final String EXPLICIT_EMPTY = "\"\""; + + public static boolean validateNotEmpty(String value){ + return StringUtils.isNoneBlank(value); + } + + public static boolean validateTargetField(String value) { + return validateNotEmpty(value) && !EXPLICIT_EMPTY.equals(value); + } + + + +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ActionValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ActionValidator.java new file mode 100644 index 0000000..3eb0eb5 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ActionValidator.java @@ -0,0 +1,40 @@ +package org.onap.sdc.dcae.rule.editor.validators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction; +import org.onap.sdc.dcae.errormng.ActionStatus; +import org.onap.sdc.dcae.errormng.ErrConfMgr; +import org.onap.sdc.dcae.errormng.ResponseFormat; +import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils; + +import java.util.List; + +public class ActionValidator<A extends BaseAction> implements IRuleElementValidator<A> { + + private static ActionValidator actionValidator = new ActionValidator(); + + public static ActionValidator getInstance() { + return actionValidator; + } + + ActionValidator(){} + + public boolean validate(A action, List<ResponseFormat> errors) { + + // validate from is populated + boolean valid = validateFromValue(action, errors); + //validate target is populated + if (!ValidationUtils.validateTargetField(action.getTarget())) { + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "target", action.getActionType(), action.getTarget())); + } + return valid; + } + + protected boolean validateFromValue(A action, List<ResponseFormat> errors) { + if(!ValidationUtils.validateNotEmpty(action.getFromValue())) { + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "from", action.getActionType(), action.getTarget())); + return false; + } + return true; + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConcatActionValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConcatActionValidator.java new file mode 100644 index 0000000..965c898 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConcatActionValidator.java @@ -0,0 +1,29 @@ +package org.onap.sdc.dcae.rule.editor.validators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction; +import org.onap.sdc.dcae.errormng.ActionStatus; +import org.onap.sdc.dcae.errormng.ErrConfMgr; +import org.onap.sdc.dcae.errormng.ResponseFormat; +import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils; + +import java.util.List; + +public class ConcatActionValidator extends ActionValidator<BaseAction> { + + private static ConcatActionValidator concatActionValidator = new ConcatActionValidator(); + + public static ConcatActionValidator getInstance() { + return concatActionValidator; + } + + private ConcatActionValidator(){} + + @Override + protected boolean validateFromValue(BaseAction action, List<ResponseFormat> errors) { + if(!ValidationUtils.validateNotEmpty(action.getFromValue()) || 2 > action.getFromValues().size()) { + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_CONCAT_VALUE, null, action.getTarget())); + return false; + } + return true; + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConditionGroupValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConditionGroupValidator.java new file mode 100644 index 0000000..995a817 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConditionGroupValidator.java @@ -0,0 +1,40 @@ +package org.onap.sdc.dcae.rule.editor.validators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.ConditionGroup; +import org.onap.sdc.dcae.errormng.ActionStatus; +import org.onap.sdc.dcae.errormng.ErrConfMgr; +import org.onap.sdc.dcae.errormng.ResponseFormat; +import org.onap.sdc.dcae.rule.editor.enums.ConditionTypeEnum; +import org.onap.sdc.dcae.rule.editor.enums.RuleEditorElementType; +import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils; +import org.springframework.util.CollectionUtils; + +import java.util.List; + +public class ConditionGroupValidator implements IRuleElementValidator<ConditionGroup> { + + private static ConditionGroupValidator conditionGroupValidator = new ConditionGroupValidator(); + + public static ConditionGroupValidator getInstance() { + return conditionGroupValidator; + } + + private ConditionGroupValidator(){} + + public boolean validate(ConditionGroup condition, List<ResponseFormat> errors) { + boolean valid = true; + if(!ValidationUtils.validateNotEmpty(condition.getType()) || null == ConditionTypeEnum.getTypeByName(condition.getType())) { + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.INVALID_GROUP_CONDITION, null, condition.getType())); + } + if(CollectionUtils.isEmpty(condition.getChildren()) || 2 > condition.getChildren().size()) { + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_CONDITION_ITEM, null, null)); + } else { + valid = condition.getChildren().stream() + .map(c -> RuleEditorElementType.getElementTypeByName(c.getClass().getSimpleName()).getValidator().validate(c, errors)) + .reduce(true, (x,y) -> x && y) && valid; + } + return valid; + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConditionValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConditionValidator.java new file mode 100644 index 0000000..1b4ae94 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConditionValidator.java @@ -0,0 +1,40 @@ +package org.onap.sdc.dcae.rule.editor.validators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.Condition; +import org.onap.sdc.dcae.errormng.ActionStatus; +import org.onap.sdc.dcae.errormng.ErrConfMgr; +import org.onap.sdc.dcae.errormng.ResponseFormat; +import org.onap.sdc.dcae.rule.editor.enums.OperatorTypeEnum; +import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils; +import org.springframework.util.CollectionUtils; + +import java.util.List; + +public class ConditionValidator implements IRuleElementValidator<Condition> { + + private static ConditionValidator conditionValidator = new ConditionValidator(); + + public static ConditionValidator getInstance() { + return conditionValidator; + } + + private ConditionValidator(){} + + public boolean validate(Condition condition, List<ResponseFormat> errors) { + boolean valid = true; + if(!ValidationUtils.validateNotEmpty(condition.getLeft())) { + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_OPERAND, null, "left")); + } + if(CollectionUtils.isEmpty(condition.getRight())) { + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_OPERAND, null, "right")); + } + if(!ValidationUtils.validateNotEmpty(condition.getOperator()) || null == OperatorTypeEnum.getTypeByName(condition.getOperator())) { + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.INVALID_OPERATOR, null, condition.getOperator())); + } + return valid; + } + +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/DateFormatterValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/DateFormatterValidator.java new file mode 100644 index 0000000..d5ec0fc --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/DateFormatterValidator.java @@ -0,0 +1,41 @@ +package org.onap.sdc.dcae.rule.editor.validators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.DateFormatterAction; +import org.onap.sdc.dcae.errormng.ActionStatus; +import org.onap.sdc.dcae.errormng.ErrConfMgr; +import org.onap.sdc.dcae.errormng.ResponseFormat; +import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils; + +import java.util.List; + +public class DateFormatterValidator extends ActionValidator<DateFormatterAction> { + private static DateFormatterValidator dateFormatterValidator = new DateFormatterValidator(); + + public static DateFormatterValidator getInstance() { + return dateFormatterValidator; + } + + private DateFormatterValidator(){} + + @Override + public boolean validate(DateFormatterAction action, List<ResponseFormat> errors) { + boolean valid = super.validate(action, errors); + if(!ValidationUtils.validateNotEmpty(action.getFromFormat())){ + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "from format", action.getActionType(), action.getTarget())); + } + if(!ValidationUtils.validateNotEmpty(action.getFromTz())){ + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "from timezone", action.getActionType(), action.getTarget())); + } + if(!ValidationUtils.validateNotEmpty(action.getToFormat())){ + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "to format", action.getActionType(), action.getTarget())); + } + if(!ValidationUtils.validateNotEmpty(action.getToTz())){ + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "to timezone", action.getActionType(), action.getTarget())); + } + return valid; + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/IRuleElementValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/IRuleElementValidator.java new file mode 100644 index 0000000..dd1eaf4 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/IRuleElementValidator.java @@ -0,0 +1,9 @@ +package org.onap.sdc.dcae.rule.editor.validators; + +import org.onap.sdc.dcae.errormng.ResponseFormat; + +import java.util.List; + +public interface IRuleElementValidator <T> { + boolean validate(T element, List<ResponseFormat> errors); +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/MapActionValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/MapActionValidator.java new file mode 100644 index 0000000..8cbcaa8 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/MapActionValidator.java @@ -0,0 +1,49 @@ +package org.onap.sdc.dcae.rule.editor.validators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.MapAction; +import org.onap.sdc.dcae.errormng.ActionStatus; +import org.onap.sdc.dcae.errormng.ErrConfMgr; +import org.onap.sdc.dcae.errormng.ResponseFormat; +import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils; +import org.springframework.util.CollectionUtils; + +import java.util.List; + +public class MapActionValidator extends ActionValidator<MapAction> { + + private static MapActionValidator mapActionValidator = new MapActionValidator(); + + public static MapActionValidator getInstance() { + return mapActionValidator; + } + + private MapActionValidator(){} + + @Override + public boolean validate(MapAction action, List<ResponseFormat> errors) { + boolean valid = super.validate(action, errors); + if (action.getMap() == null || CollectionUtils.isEmpty(action.getMapValues())) { + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ENTRY, null, action.getTarget())); + } else { + if (action.mapHasDefault() && !ValidationUtils.validateNotEmpty(action.getMapDefaultValue())) { + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_DEFAULT_VALUE, null, action.getTarget())); + } + try { + if (!validateMapValues(action)) { + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ENTRY, null, action.getTarget())); + } + } catch (IllegalStateException err) { + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.DUPLICATE_KEY, null)); + } + } + return valid; + } + + private boolean validateMapValues(MapAction action) { + return action.transformToMap().entrySet().stream().noneMatch(p -> !ValidationUtils.validateNotEmpty(p.getKey()) || !ValidationUtils.validateNotEmpty(p.getValue())); + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/RuleValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/RuleValidator.java new file mode 100644 index 0000000..371d1e9 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/RuleValidator.java @@ -0,0 +1,56 @@ +package org.onap.sdc.dcae.rule.editor.validators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.ActionTypeEnum; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseCondition; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.Rule; +import org.onap.sdc.dcae.errormng.ActionStatus; +import org.onap.sdc.dcae.errormng.ErrConfMgr; +import org.onap.sdc.dcae.errormng.ResponseFormat; +import org.onap.sdc.dcae.errormng.ServiceException; +import org.onap.sdc.dcae.rule.editor.enums.RuleEditorElementType; +import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils; +import org.springframework.util.CollectionUtils; + +import java.util.List; + +public class RuleValidator implements IRuleElementValidator<Rule> { + + private static RuleValidator ruleValidator = new RuleValidator(); + + public static RuleValidator getInstance() { + return ruleValidator; + } + + private RuleValidator(){} + + + public boolean validate(Rule rule, List<ResponseFormat> errors) { + boolean valid = true; + if(rule.isConditionalRule()) + valid = getConditionValidator(rule.getCondition()).validate(rule.getCondition(), errors); + if(!ValidationUtils.validateNotEmpty(rule.getDescription())) { + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_RULE_DESCRIPTION, null, null)); + } + if(CollectionUtils.isEmpty(rule.getActions())) { + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION, null, null)); + } else { + valid = rule.getActions().stream() + .map(a -> getActionValidator(a).validate(a, errors)) + .reduce(true, (x,y) -> x && y) && valid; + } + return valid; + } + + + private IRuleElementValidator getActionValidator(BaseAction action) { + ActionTypeEnum type = ActionTypeEnum.getTypeByName(action.getActionType()); + return RuleEditorElementType.getElementTypeByName(type.getType()).getValidator(); + } + + private IRuleElementValidator getConditionValidator(BaseCondition condition) { + return RuleEditorElementType.getElementTypeByName(condition.getClass().getSimpleName()).getValidator(); + } +} |