Bug 3242: Tenant CONF -> OPER validation in PolicyEnforcer pattern not returning... 20/20820/11
authorPeter Žeby <peter.zeby@pantheon.sk>
Wed, 20 May 2015 14:31:32 +0000 (16:31 +0200)
committerMartin Sunal <msunal@cisco.com>
Wed, 3 Jun 2015 15:17:08 +0000 (15:17 +0000)
Change-Id: I05413d84ad1a7c6fbe7d0d07b39fe448b7f67186
Signed-off-by: Andrej Kincel <akincel@cisco.com>
Signed-off-by: Peter Žeby <peter.zeby@pantheon.sk>
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/PolicyResolver.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/AbstractValidator.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/PolicyValidator.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/SimpleResult.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/ValidationResult.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/Validator.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/validators/ActionInstanceValidator.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/validators/SubjectFeatureInstancesValidator.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/validators/TenantValidator.java [new file with mode: 0644]

index 94d51d5672c52e7ac0743134f98ac316fadec698..32642d2447fd758ca6326ca46c10fb8f17593885 100644 (file)
@@ -5,7 +5,6 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-
 package org.opendaylight.groupbasedpolicy.resolver;
 
 import java.util.Collection;
@@ -36,7 +35,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Contract;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Subject;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.Rule;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ActionInstance;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -51,6 +49,8 @@ import com.google.common.collect.Table.Cell;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.groupbasedpolicy.resolver.validator.PolicyValidator;
+import org.opendaylight.groupbasedpolicy.resolver.validator.ValidationResult;
 
 /**
  * The policy resolver is a utility for renderers to help in resolving
@@ -71,6 +71,7 @@ import com.google.common.util.concurrent.ListenableFuture;
  *
  */
 public class PolicyResolver implements AutoCloseable {
+
     private static final Logger LOG = LoggerFactory.getLogger(PolicyResolver.class);
 
     private final DataBroker dataProvider;
@@ -83,7 +84,6 @@ public class PolicyResolver implements AutoCloseable {
 
     protected ConcurrentMap<TenantId, TenantContext> resolvedTenants;
 
-
     /**
      * Store a policy object for each endpoint group pair. The table is stored
      * with the key as (consumer, provider). Two endpoints could appear in both
@@ -95,7 +95,6 @@ public class PolicyResolver implements AutoCloseable {
      * Store validators for ActionDefinitions from Renderers
      *
      */
-
     protected ConcurrentMap<ActionDefinitionId, ActionInstanceValidator> registeredActions = new ConcurrentHashMap<>();
 
     public PolicyResolver(DataBroker dataProvider,
@@ -111,24 +110,23 @@ public class PolicyResolver implements AutoCloseable {
     // *************
     // AutoCloseable
     // *************
-
     @Override
     public void close() throws Exception {
         for (TenantContext ctx : resolvedTenants.values()) {
-            if (ctx.registration != null)
+            if (ctx.registration != null) {
                 ctx.registration.close();
+            }
         }
     }
 
     // *************************
     // PolicyResolver public API
     // *************************
-
     /**
      * Get a snapshot of the current policy
      *
      * @return the {@link PolicyInfo} object representing an immutable snapshot
-     *         of the policy state
+     * of the policy state
      */
     public PolicyInfo getCurrentPolicy() {
         return policy.get();
@@ -137,25 +135,26 @@ public class PolicyResolver implements AutoCloseable {
     /**
      * Get the normalized tenant for the given ID
      *
-     * @param tenant
-     *            the tenant ID
+     * @param tenant the tenant ID
      * @return the {@link Tenant}
      */
     public IndexedTenant getTenant(TenantId tenant) {
         TenantContext tc = resolvedTenants.get(tenant);
-        if (tc == null)
+        if (tc == null) {
             return null;
+        }
         return tc.tenant.get();
     }
 
     public void registerActionDefinitions(ActionDefinitionId actionDefinitionId, ActionInstanceValidator validator) {
         registeredActions.putIfAbsent(actionDefinitionId, validator);
     }
+
     /**
      * Register a listener to receive update events.
      *
-     * @param listener
-     *            the {@link PolicyListener} object to receive the update events
+     * @param listener the {@link PolicyListener} object to receive the update
+     * events
      */
     public PolicyScope registerListener(PolicyListener listener) {
         PolicyScope ps = new PolicyScope(this, listener);
@@ -167,8 +166,7 @@ public class PolicyResolver implements AutoCloseable {
     /**
      * Remove the listener registered for the given {@link PolicyScope}.
      *
-     * @param scope
-     *            the scope to remove
+     * @param scope the scope to remove
      * @see PolicyResolver#registerListener(PolicyListener)
      */
     public void removeListener(PolicyScope scope) {
@@ -178,15 +176,12 @@ public class PolicyResolver implements AutoCloseable {
     // **************
     // Implementation
     // **************
-
     /**
      * Atomically update the active policy and notify policy listeners of
      * relevant changes
      *
-     * @param policyMap
-     *            the new policy to set
-     * @param egConditions
-     *            the map of endpoint groups to relevant condition sets
+     * @param policyMap the new policy to set
+     * @param egConditions the map of endpoint groups to relevant condition sets
      * @return the set of groups with updated policy
      */
     protected Set<EgKey> updatePolicy(Table<EgKey, EgKey, Policy> policyMap,
@@ -200,9 +195,10 @@ public class PolicyResolver implements AutoCloseable {
         for (Cell<EgKey, EgKey, Policy> cell : newPolicy.getPolicyMap().cellSet()) {
             Policy newp = cell.getValue();
             Policy oldp = null;
-            if (oldPolicy != null)
+            if (oldPolicy != null) {
                 oldp = oldPolicy.getPolicyMap().get(cell.getRowKey(),
                         cell.getColumnKey());
+            }
             if (oldp == null || !newp.equals(oldp)) {
                 notifySet.add(cell.getRowKey());
                 notifySet.add(cell.getColumnKey());
@@ -225,8 +221,8 @@ public class PolicyResolver implements AutoCloseable {
      */
     private void notifyListeners(Set<EgKey> updatedGroups) {
         for (final PolicyScope scope : policyListenerScopes) {
-            Set<EgKey> filtered =
-                    Sets.filter(updatedGroups, new Predicate<EgKey>() {
+            Set<EgKey> filtered
+                    Sets.filter(updatedGroups, new Predicate<EgKey>() {
                         @Override
                         public boolean apply(EgKey input) {
                             return scope.contains(input.getTenantId(),
@@ -243,20 +239,19 @@ public class PolicyResolver implements AutoCloseable {
      * Subscribe the resolver to updates related to a particular tenant Make
      * sure that this can't be called concurrently with subscribe
      *
-     * @param tenantId
-     *            the tenant ID to subscribe to
+     * @param tenantId the tenant ID to subscribe to
      */
     protected void subscribeTenant(TenantId tenantId) {
-        if (!resolvedTenants.containsKey(tenantId))
+        if (!resolvedTenants.containsKey(tenantId)) {
             updateTenant(tenantId);
+        }
     }
 
     /**
      * Unsubscribe the resolver from updates related to a particular tenant Make
      * sure that this can't be called concurrently with subscribe
      *
-     * @param tenantId
-     *            the tenant ID to subscribe to
+     * @param tenantId the tenant ID to subscribe to
      */
     protected void unsubscribeTenant(TenantId tenantId) {
         TenantContext context = resolvedTenants.get(tenantId);
@@ -267,8 +262,9 @@ public class PolicyResolver implements AutoCloseable {
     }
 
     private void updateTenant(final TenantId tenantId) {
-        if (dataProvider == null)
+        if (dataProvider == null) {
             return;
+        }
 
         TenantContext context = resolvedTenants.get(tenantId);
         if (context == null) {
@@ -280,8 +276,8 @@ public class PolicyResolver implements AutoCloseable {
                             DataChangeScope.SUBTREE);
 
             context = new TenantContext(registration);
-            TenantContext oldContext =
-                    resolvedTenants.putIfAbsent(tenantId, context);
+            TenantContext oldContext
+                    resolvedTenants.putIfAbsent(tenantId, context);
             if (oldContext != null) {
                 // already registered in a different thread; just use the other
                 // context
@@ -295,8 +291,8 @@ public class PolicyResolver implements AutoCloseable {
         // Resolve the new tenant and update atomically
         final AtomicReference<IndexedTenant> tenantRef = context.tenant;
         final IndexedTenant ot = tenantRef.get();
-        ReadOnlyTransaction transaction =
-                dataProvider.newReadOnlyTransaction();
+        ReadOnlyTransaction transaction
+                dataProvider.newReadOnlyTransaction();
         final InstanceIdentifier<Tenant> tiid = TenantUtils.tenantIid(tenantId);
         ListenableFuture<Optional<Tenant>> unresolved;
 
@@ -325,10 +321,6 @@ public class PolicyResolver implements AutoCloseable {
                 }
             }
 
-
-
-
-
             @Override
             public void onFailure(Throwable t) {
                 LOG.error("Count not get tenant {}", tenantId, t);
@@ -353,13 +345,15 @@ public class PolicyResolver implements AutoCloseable {
         Set<IndexedTenant> result = new HashSet<>();
         for (TenantContext tenant : tenantCtxs) {
             IndexedTenant t = tenant.tenant.get();
-            if (t != null)
+            if (t != null) {
                 result.add(t);
+            }
         }
         return result;
     }
 
     protected static class TenantContext {
+
         ListenerRegistration<DataChangeListener> registration;
 
         AtomicReference<IndexedTenant> tenant = new AtomicReference<>();
@@ -372,6 +366,7 @@ public class PolicyResolver implements AutoCloseable {
 
     @Immutable
     private class PolicyChangeListener implements DataChangeListener {
+
         final TenantId tenantId;
 
         public PolicyChangeListener(TenantId tenantId) {
@@ -387,40 +382,19 @@ public class PolicyResolver implements AutoCloseable {
     }
 
     private boolean isValidTenant(Tenant t) {
-        if(validActionInstances(t.getSubjectFeatureInstances().getActionInstance())) {
+        ValidationResult validationResult = PolicyValidator.validate(t, this);
+        if (validationResult == null) {
             return true;
         }
-        return false;
-    }
-
-    private boolean validActionInstances(List<ActionInstance> actionInstances) {
-        for(ActionInstance actionInstance : actionInstances) {
-            if(!(registeredActions.get(actionInstance.getActionDefinitionId()).isValid(actionInstance))) {
-                return false;
-            };
-        }
-        return true;
-    }
-
-    private boolean validContracts(List<Contract> contracts) {
-        for (Contract contract: contracts) {
-            validateSubjects(contract.getSubject());
-        }
-        return false;
+        return validationResult.getResult().getValue();
     }
 
-    private void validateSubjects(List<Subject> subjects) {
-        for(Subject subject: subjects) {
-            validateRules(subject.getRule());
+    public ActionInstanceValidator getActionInstanceValidator(ActionDefinitionId actionDefinitionId) {
+        if (registeredActions == null) {
+            return null;
         }
+        return registeredActions.get(actionDefinitionId);
 
     }
 
-    private void validateRules(List<Rule> rules) {
-
-    }
-
-    private void validateActionRefs(List<ActionRef> actionRefs) {
-
-    }
 }
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/AbstractValidator.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/AbstractValidator.java
new file mode 100644 (file)
index 0000000..e92cff7
--- /dev/null
@@ -0,0 +1,120 @@
+package org.opendaylight.groupbasedpolicy.resolver.validator;
+
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+import java.util.Collections;
+import java.util.List;
+
+import org.opendaylight.groupbasedpolicy.resolver.PolicyResolver;
+import org.opendaylight.yangtools.yang.binding.ChildOf;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+
+/**
+ * Abstract class for all Validators, that will be used to validate concrete
+ * Policy objects. Contains basic functions needed for validation.
+ *
+ * @param <U>
+ */
+public abstract class AbstractValidator<U extends DataContainer> implements Validator<U> {
+
+    /**
+     * Instance of {@link PolicyResolver} that contains additional data required
+     * for individual validation process
+     */
+    private PolicyResolver policyResolver;
+
+    /**
+     *
+     * @return Instance of {@link PolicyResolver}
+     */
+    protected final PolicyResolver getPolicyResolver() {
+        return policyResolver;
+    }
+
+    /**
+     * {@link PolicyResolver} contains additional data required for individual
+     * validation process
+     *
+     * @param policyResolver Istance of {@link PolicyResolver}
+     */
+    public final void setPolicyResolver(PolicyResolver policyResolver) {
+        this.policyResolver = policyResolver;
+    }
+
+    @Override
+    public ValidationResult validate(U objectToValidate) {
+        ValidationResult result = new ValidationResult(this.getClass());
+
+        SimpleResult selfValidationResult = validateSelf(objectToValidate);
+
+        if (selfValidationResult.isFailure()) {
+            result.setResult(ValidationResult.Result.FAIL_BASE);
+        }
+
+        result.setDescription(selfValidationResult.getDescription());
+
+        List<? extends DataContainer> childObjects = getChildObjects(objectToValidate);
+        this.validateChildren(childObjects, result);
+
+        return result;
+    }
+
+    /**
+     * This function is supposed to do base validation of given object (e.g.
+     * metadata check).
+     *
+     * Individual validators can override this method, to provide their own
+     * validation function.
+     *
+     * @param objectToValidate Object to validate by validator
+     * @return {@link SimpleResult} object
+     */
+    protected SimpleResult validateSelf(U objectToValidate) {
+
+        return new SimpleResult(true, "Default validation");
+    }
+
+    /**
+     * Function to validate all children in list. Result of all validations is
+     * saved to its parent {@link ValidationResult}.
+     *
+     * @param childObjects List of objects to validate
+     * @param parentResult Result of base validation.
+     */
+    private void validateChildren(List<? extends DataContainer> childObjects, ValidationResult parentResult) {
+        if (childObjects == null) {
+            return;
+        }
+
+        for (DataContainer child : childObjects) {
+            Validator<DataContainer> validator = PolicyValidator.createValidator(child, getPolicyResolver());
+            if (validator != null) {
+                parentResult.addChildResult(validator.validate(child));
+            }
+        }
+    }
+
+    /**
+     * Return list of all children objects of given object, that should be
+     * validated.
+     *
+     * Individual validators must override this method, if they want to execute
+     * validation on their children.
+     *
+     * @param <T>
+     * @param objectToValidate Object that is validated by this validator
+     * @return List of child objects associated to {@code objectToValidate}. If
+     * there is not any child, return empty list or {@code null}.
+     */
+    protected <T extends DataContainer & ChildOf<U>> List<T> getChildObjects(U objectToValidate) {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public abstract Class<U> getType();
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/PolicyValidator.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/PolicyValidator.java
new file mode 100644 (file)
index 0000000..7679afb
--- /dev/null
@@ -0,0 +1,74 @@
+package org.opendaylight.groupbasedpolicy.resolver.validator;
+
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+import java.util.HashMap;
+import java.util.Map;
+import javax.annotation.Nullable;
+import org.opendaylight.groupbasedpolicy.resolver.PolicyResolver;
+import org.opendaylight.groupbasedpolicy.resolver.validator.validators.ActionInstanceValidator;
+import org.opendaylight.groupbasedpolicy.resolver.validator.validators.SubjectFeatureInstancesValidator;
+import org.opendaylight.groupbasedpolicy.resolver.validator.validators.TenantValidator;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+
+/**
+ *
+ * Factory to create concrete {@link Validator} class for object to validate.
+ *
+ */
+public class PolicyValidator {
+
+    /**
+     * Map of Objects and their corresponding validators.
+     */
+    private static final Map<Class<? extends DataContainer>, AbstractValidator<? extends DataContainer>> VALIDATORS;
+
+    static {
+        VALIDATORS = new HashMap<>();
+        TenantValidator tenantValidator = new TenantValidator();
+        VALIDATORS.put(tenantValidator.getType(), tenantValidator);
+        SubjectFeatureInstancesValidator subjectFeatureInstancesValidator = new SubjectFeatureInstancesValidator();
+        VALIDATORS.put(subjectFeatureInstancesValidator.getType(), subjectFeatureInstancesValidator);
+        ActionInstanceValidator actionInstanceValidator = new ActionInstanceValidator();
+        VALIDATORS.put(actionInstanceValidator.getType(), actionInstanceValidator);
+    }
+
+    /**
+     * Validator Returns {@link Validator} for given object.
+     *
+     * @param <T>
+     * @param object Object, for which validator should be created.
+     * @param policyResolver Instance of {@link PolicyResolver} that contains
+     * additional data required for individual validation process
+     * @return Concrete {@link Validator} for given object
+     */
+    @SuppressWarnings("unchecked")
+    static <T extends DataContainer> Validator<T> createValidator(T object, PolicyResolver policyResolver) {
+        AbstractValidator validator = VALIDATORS.get(object.getImplementedInterface());
+        if (validator == null) {
+            return null;
+        }
+        validator.setPolicyResolver(policyResolver);
+        return (Validator<T>) validator;
+    }
+
+    /**
+     * @param <T>
+     * @param object Object to validate
+     * @param policyResolver Instance of {@link PolicyResolver} that contains
+     * additional data required for individual validation process
+     * @return {@code null} if validator for the object does not exist;
+     * {@link ValidationResult} otherwise
+     */
+    public static @Nullable
+    <T extends DataContainer> ValidationResult validate(T object, PolicyResolver policyResolver) {
+        Validator<T> validator = createValidator(object, policyResolver);
+        return validator.validate(object);
+    }
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/SimpleResult.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/SimpleResult.java
new file mode 100644 (file)
index 0000000..27e4f63
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.groupbasedpolicy.resolver.validator;
+
+/**
+ * Class that represents simple result (e.g. SUCCESS/FAILURE and description of
+ * that result). Provide option to save custom result (state/code), which can be
+ * evaluated by other processes.
+ *
+ * @see SimpleResult#code
+ *
+ */
+public class SimpleResult {
+
+    /**
+     * Code of result.
+     */
+    private final int code;
+    /**
+     * Description of result.
+     */
+    private final String description;
+
+    /**
+     * Construct new {@link SimpleResult}.
+     *
+     * @param result State of result ({@code true} on success and {@code false}
+     * on failure).
+     * @param description Description of result.
+     */
+    public SimpleResult(boolean result, String description) {
+        this.code = result ? 0 : 1;
+        this.description = description;
+    }
+
+    /**
+     * Construct new {@link SimpleResult} with empty description.
+     *
+     * @param result State of result ({@code true} on SUCCESS and {@code false}
+     * on FAILURE).
+     */
+    public SimpleResult(boolean result) {
+        this(result, null);
+    }
+
+    /**
+     * Construct new {@link SimpleResult}.
+     *
+     * @param code Code of result, where 0 is expected as SUCCESS and everything
+     * else as FAILURE.
+     * @param description Description of result.
+     */
+    public SimpleResult(int code, String description) {
+        this.code = code;
+        this.description = description;
+    }
+
+    /**
+     * Construct new {@link SimpleResult} with empty description.
+     *
+     * @param code Code of result, where 0 is expected as SUCCESS and everything
+     * else as FAILURE.
+     */
+    public SimpleResult(int code) {
+        this(code, null);
+    }
+
+    /**
+     * Returns code of result.
+     *
+     * @return Code of result
+     */
+    public int getCode() {
+        return code;
+    }
+
+    /**
+     * Returns {@code true} if code of result IS {@code 0}, otherwise returns
+     * {@code false}.
+     *
+     * @return {@code true} or {@code false} based on value of {@code code}
+     */
+    public boolean isSuccess() {
+        return getCode() == 0;
+    }
+
+    /**
+     * Returns {@code true} if code of result IS NOT {@code 0}, otherwise
+     * returns {@code false}.
+     *
+     * @return {@code true} or {@code false} based on value of {@code code}
+     */
+    public boolean isFailure() {
+        return !isSuccess();
+    }
+
+    /**
+     * Returns saved description of result or empty string.
+     *
+     * @return Description of result.
+     */
+    public String getDescription() {
+        if (description == null) {
+            return "";
+        } else {
+            return description;
+        }
+    }
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/ValidationResult.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/ValidationResult.java
new file mode 100644 (file)
index 0000000..a6a17d1
--- /dev/null
@@ -0,0 +1,155 @@
+package org.opendaylight.groupbasedpolicy.resolver.validator;
+
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Class to hold validation results of object and his children.
+ *
+ */
+public class ValidationResult {
+
+    /**
+     * Enumeration of possible results.
+     */
+    public enum Result {
+
+        /**
+         * Everything is OK
+         */
+        SUCCESS(true),
+        /**
+         * Base validation failed
+         */
+        FAIL_BASE(false),
+        /**
+         * Validation of (any) child failed
+         */
+        FAIL_CHILD(false),
+        /**
+         * Base validation and validation of (any) child failed
+         */
+        FAIL_BASE_AND_CHILD(false);
+
+        private boolean value;
+
+        Result(boolean value) {
+            this.value = value;
+        }
+
+        public boolean getValue() {
+            return this.value;
+        }
+    }
+
+    /**
+     * Variable to store result of validation. The final result is based on base
+     * status and status of all children.
+     */
+    private Result result = Result.SUCCESS;
+
+    /**
+     * Class of {@link Validator}, which returns result.
+     */
+    private final Class<? extends Validator> validatorClass;
+
+    /**
+     * List of all children validations.
+     */
+    private List<ValidationResult> childResults = new ArrayList<>();
+
+    /**
+     * Human-readable description of current status.
+     */
+    private String description;
+
+    /**
+     * Create new {@link ValidationResult} to store result of validation.
+     *
+     * @param validatorClass Creator of {@link ValidationResult}
+     */
+    public ValidationResult(Class<? extends Validator> validatorClass) {
+        this.validatorClass = validatorClass;
+    }
+
+    /**
+     *
+     * @return Current result
+     */
+    public Result getResult() {
+        return result;
+    }
+
+    /**
+     *
+     * @param result Result to set
+     */
+    public void setResult(Result result) {
+        this.result = result;
+    }
+
+    /**
+     *
+     * @return List of result child objects
+     */
+    public List<ValidationResult> getChildResults() {
+        return childResults;
+    }
+
+    /**
+     * Add new child result. Result of his parent is based on status of base and
+     * all children.
+     *
+     * @param childResult
+     */
+    public void addChildResult(ValidationResult childResult) {
+        if (!childResult.getResult().getValue()) {
+
+            //if validation already failed for base or child
+            if (this.getResult().equals(ValidationResult.Result.FAIL_BASE)
+                    || this.getResult().equals(ValidationResult.Result.FAIL_BASE_AND_CHILD)) {
+                this.setResult(ValidationResult.Result.FAIL_BASE_AND_CHILD);
+
+                //if validation failed only for child
+            } else {
+                this.setResult(ValidationResult.Result.FAIL_CHILD);
+            }
+        }
+
+        this.childResults.add(childResult);
+    }
+
+    /**
+     * Returns {@link Validator} class in which the result arises.
+     *
+     * @return {@link Validator} class
+     */
+    public Class<? extends Validator> getValidatorClass() {
+        return validatorClass;
+    }
+
+    /**
+     *
+     * @return Current result description
+     */
+    public String getDescription() {
+        return description;
+    }
+
+    /**
+     * Set human-readable description of result.
+     *
+     * @param description Result description to set
+     */
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/Validator.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/Validator.java
new file mode 100644 (file)
index 0000000..c71f77e
--- /dev/null
@@ -0,0 +1,34 @@
+package org.opendaylight.groupbasedpolicy.resolver.validator;
+
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+/**
+ * Interface for Validators used to validate Policy objects
+ *
+ * @param <T>
+ */
+public interface Validator<T> {
+
+    /**
+     * Validate given object and his children. The result of all validations is
+     * stored in {@link ValidationResult} object.
+     *
+     * @param objectToValidate Object that should be validated by
+     * {@link Validator}
+     * @return Result of performed validation
+     */
+    ValidationResult validate(T objectToValidate);
+
+    /**
+     * Returns the Policy object type for which it is intended validator.
+     *
+     * @return Class of Policy object;
+     */
+    Class<T> getType();
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/validators/ActionInstanceValidator.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/validators/ActionInstanceValidator.java
new file mode 100644 (file)
index 0000000..6d894bd
--- /dev/null
@@ -0,0 +1,37 @@
+package org.opendaylight.groupbasedpolicy.resolver.validator.validators;
+
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+import org.opendaylight.groupbasedpolicy.resolver.validator.AbstractValidator;
+import org.opendaylight.groupbasedpolicy.resolver.validator.SimpleResult;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ActionInstance;
+
+/**
+ * Validator for {@link ActionInstance}
+ */
+public class ActionInstanceValidator extends AbstractValidator<ActionInstance> {
+
+    @Override
+    protected SimpleResult validateSelf(ActionInstance objectToValidate) {
+        org.opendaylight.groupbasedpolicy.resolver.ActionInstanceValidator action = getPolicyResolver().getActionInstanceValidator(objectToValidate.getActionDefinitionId());
+        if (action == null) {
+            return new SimpleResult(false, "Action not registered in PolicyResolver.");
+        }
+
+        boolean isValid = action.isValid(objectToValidate);
+
+        return new SimpleResult(isValid, "Validation result of " + action.getClass().getName() + " class.");
+    }
+
+    @Override
+    public Class<ActionInstance> getType() {
+        return ActionInstance.class;
+    }
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/validators/SubjectFeatureInstancesValidator.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/validators/SubjectFeatureInstancesValidator.java
new file mode 100644 (file)
index 0000000..1d685b9
--- /dev/null
@@ -0,0 +1,37 @@
+package org.opendaylight.groupbasedpolicy.resolver.validator.validators;
+
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.groupbasedpolicy.resolver.validator.AbstractValidator;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.SubjectFeatureInstances;
+import org.opendaylight.yangtools.yang.binding.ChildOf;
+
+/**
+ * Validator for {@link SubjectFeatureInstances}
+ */
+public class SubjectFeatureInstancesValidator extends AbstractValidator<SubjectFeatureInstances> {
+
+    @Override
+    protected List<ChildOf<SubjectFeatureInstances>> getChildObjects(SubjectFeatureInstances objectToValidate) {
+        List<ChildOf<SubjectFeatureInstances>> childObjects = new ArrayList<>();
+
+        childObjects.addAll(objectToValidate.getActionInstance());
+        childObjects.addAll(objectToValidate.getClassifierInstance());
+
+        return childObjects;
+    }
+
+    @Override
+    public Class<SubjectFeatureInstances> getType() {
+        return SubjectFeatureInstances.class;
+    }
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/validators/TenantValidator.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/validator/validators/TenantValidator.java
new file mode 100644 (file)
index 0000000..39a6c74
--- /dev/null
@@ -0,0 +1,35 @@
+package org.opendaylight.groupbasedpolicy.resolver.validator.validators;
+
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.groupbasedpolicy.resolver.validator.AbstractValidator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
+import org.opendaylight.yangtools.yang.binding.ChildOf;
+
+/**
+ * Validator for {@link Tenant}
+ */
+public class TenantValidator extends AbstractValidator<Tenant> {
+
+    @Override
+    protected List<ChildOf<Tenant>> getChildObjects(Tenant objectToValidate) {
+        List<ChildOf<Tenant>> childObjects = new ArrayList<>();
+
+        childObjects.add(objectToValidate.getSubjectFeatureInstances());
+
+        return childObjects;
+    }
+
+    @Override
+    public Class<Tenant> getType() {
+        return Tenant.class;
+    }
+
+}