Introduced ForwardingResolver 83/39183/3
authorMartin Sunal <msunal@cisco.com>
Fri, 20 May 2016 13:49:27 +0000 (15:49 +0200)
committerMartin Sunal <msunal@cisco.com>
Mon, 23 May 2016 12:49:57 +0000 (12:49 +0000)
- ForwardingResolver listens on forwarding in CONF and stores it to OPER DS
- PolicyResolver changed: listens on tenant without waiting for input from
  renderers

Change-Id: I3119d195452c9a69990c9ab3b574a5204e14b2ef
Signed-off-by: Martin Sunal <msunal@cisco.com>
groupbasedpolicy/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/GroupbasedpolicyModule.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/FollowedTenantListener.java [deleted file]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/ForwardingResolver.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/PolicyResolver.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/IidFactory.java
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/resolver/ForwardingResolverTest.java [new file with mode: 0644]
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/resolver/PolicyResolverTest.java

index 3ba11fa66ed98de515637835653c3ba748c4c626..fcec2c0f5c23a41221210da905527275d995e39d 100644 (file)
@@ -13,6 +13,7 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFaile
 import org.opendaylight.groupbasedpolicy.api.PolicyValidatorRegistry;
 import org.opendaylight.groupbasedpolicy.location.resolver.LocationResolver;
 import org.opendaylight.groupbasedpolicy.renderer.RendererManager;
+import org.opendaylight.groupbasedpolicy.resolver.ForwardingResolver;
 import org.opendaylight.groupbasedpolicy.sf.SubjectFeatureDefinitionProvider;
 import org.opendaylight.groupbasedpolicy.sf.SupportedActionDefinitionListener;
 import org.opendaylight.groupbasedpolicy.sf.SupportedClassifierDefinitionListener;
@@ -64,6 +65,7 @@ public class GroupbasedpolicyModule extends org.opendaylight.controller.config.y
         private final SupportedActionDefinitionListener supportedActionDefinitionListener;
         private final LocationResolver locationResolver;
         private final RendererManager rendererManager;
+        private final ForwardingResolver forwardingResolver;
 
         Instance(DataBroker dataProvider, PolicyValidatorRegistry validatorRegistry) throws TransactionCommitFailedException {
             sfdp = new SubjectFeatureDefinitionProvider(dataProvider);
@@ -71,6 +73,7 @@ public class GroupbasedpolicyModule extends org.opendaylight.controller.config.y
             supportedActionDefinitionListener = new SupportedActionDefinitionListener(dataProvider);
             locationResolver = new LocationResolver(dataProvider);
             rendererManager = new RendererManager(dataProvider);
+            forwardingResolver = new ForwardingResolver(dataProvider);
         }
 
         @Override
@@ -80,6 +83,7 @@ public class GroupbasedpolicyModule extends org.opendaylight.controller.config.y
             supportedActionDefinitionListener.close();
             locationResolver.close();
             rendererManager.close();
+            forwardingResolver.close();
         }
     }
 
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/FollowedTenantListener.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/FollowedTenantListener.java
deleted file mode 100644 (file)
index ef4cc89..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.Collection;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.Interests;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.interests.FollowedTenants;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.interests.followed.tenants.FollowedTenant;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-import com.google.common.collect.HashMultiset;
-import com.google.common.collect.Multiset;
-
-public class FollowedTenantListener implements DataTreeChangeListener<FollowedTenant>, Closeable {
-
-    private final PolicyResolver policyResolver;
-    private final ListenerRegistration<FollowedTenantListener> listenerRegistration;
-    private final Multiset<TenantId> countedFollowedTenants = HashMultiset.create();
-
-    public FollowedTenantListener(DataBroker dataProvider, PolicyResolver policyResolver) {
-        this.policyResolver = policyResolver;
-        listenerRegistration = dataProvider.registerDataTreeChangeListener(
-                new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
-                        InstanceIdentifier.builder(Renderers.class)
-                            .child(Renderer.class)
-                            .child(Interests.class)
-                            .child(FollowedTenants.class)
-                            .child(FollowedTenant.class)
-                            .build()),
-                this);
-    }
-
-    @Override
-    public void onDataTreeChanged(Collection<DataTreeModification<FollowedTenant>> changes) {
-        for (DataTreeModification<FollowedTenant> change : changes) {
-            DataObjectModification<FollowedTenant> rootNode = change.getRootNode();
-            TenantId tenantId = change.getRootPath().getRootIdentifier().firstKeyOf(FollowedTenant.class).getId();
-            switch (rootNode.getModificationType()) {
-                case WRITE:
-                    policyResolver.subscribeTenant(tenantId);
-                    countedFollowedTenants.add(tenantId);
-                    break;
-                case DELETE:
-                    countedFollowedTenants.remove(tenantId);
-                    if (countedFollowedTenants.count(tenantId) == 0) {
-                        policyResolver.unsubscribeTenant(tenantId);
-                    }
-                    break;
-                case SUBTREE_MODIFIED:
-                    // NOOP
-                    break;
-            }
-        }
-    }
-
-    @Override
-    public void close() throws IOException {
-        if (listenerRegistration != null)
-            listenerRegistration.close();
-    }
-
-}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/ForwardingResolver.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/ForwardingResolver.java
new file mode 100644 (file)
index 0000000..4d8877e
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 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;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.util.DataTreeChangeHandler;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.ForwardingByTenant;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+
+public class ForwardingResolver extends DataTreeChangeHandler<ForwardingByTenant> {
+
+    public ForwardingResolver(DataBroker dataProvider) {
+        super(dataProvider);
+    }
+
+    @Override
+    protected void onWrite(DataObjectModification<ForwardingByTenant> rootNode,
+            InstanceIdentifier<ForwardingByTenant> rootIdentifier) {
+        ForwardingByTenant forwardingByTenant = rootNode.getDataAfter();
+        updateForwarding(rootIdentifier, forwardingByTenant);
+    }
+
+    @Override
+    protected void onDelete(DataObjectModification<ForwardingByTenant> rootNode,
+            InstanceIdentifier<ForwardingByTenant> rootIdentifier) {
+        WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
+        wTx.delete(LogicalDatastoreType.OPERATIONAL, rootIdentifier);
+        wTx.submit();
+    }
+
+    @Override
+    protected void onSubtreeModified(DataObjectModification<ForwardingByTenant> rootNode,
+            InstanceIdentifier<ForwardingByTenant> rootIdentifier) {
+        ForwardingByTenant forwardingByTenant = rootNode.getDataAfter();
+        updateForwarding(rootIdentifier, forwardingByTenant);
+    }
+
+    @VisibleForTesting
+    void updateForwarding(InstanceIdentifier<ForwardingByTenant> rootIdentifier,
+            ForwardingByTenant forwardingByTenant) {
+        Preconditions.checkNotNull(rootIdentifier);
+        Preconditions.checkNotNull(forwardingByTenant);
+        // TODO add validation of forwarding
+        WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
+        wTx.put(LogicalDatastoreType.OPERATIONAL, rootIdentifier, forwardingByTenant);
+        wTx.submit();
+    }
+
+}
index 4ed80025e626a2b26e624d7fb2caab8a8896d878..b275bcd315653258123328490c24258d4c89198e 100755 (executable)
@@ -19,7 +19,6 @@ import javax.annotation.concurrent.Immutable;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -38,13 +37,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Tenants;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Policy;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.SubjectFeatureInstances;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstanceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPolicies;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPoliciesBuilder;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -52,11 +49,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
 import com.google.common.collect.HashMultimap;
-import com.google.common.collect.HashMultiset;
 import com.google.common.collect.Multimaps;
-import com.google.common.collect.Multiset;
 import com.google.common.collect.SetMultimap;
 import com.google.common.collect.Table;
 
@@ -80,12 +74,8 @@ public class PolicyResolver implements PolicyValidatorRegistry, AutoCloseable {
 
     private final DataBroker dataProvider;
 
-    private final FollowedTenantListener followedTenantListener;
-
     protected final ConcurrentMap<TenantId, IndexedTenant> resolvedTenants;
 
-    protected final Multiset<TenantId> subscribersPerTenant = HashMultiset.create();
-
     private PolicyChangeListener tenantChangeListener;
 
     /*
@@ -100,7 +90,6 @@ public class PolicyResolver implements PolicyValidatorRegistry, AutoCloseable {
 
     public PolicyResolver(DataBroker dataProvider) {
         this.dataProvider = dataProvider;
-        followedTenantListener = new FollowedTenantListener(dataProvider, this);
         resolvedTenants = new ConcurrentHashMap<>();
         tenantChangeListener =
                 new PolicyChangeListener(dataProvider, new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
@@ -116,9 +105,6 @@ public class PolicyResolver implements PolicyValidatorRegistry, AutoCloseable {
         if (tenantChangeListener != null) {
             tenantChangeListener.close();
         }
-        if (followedTenantListener != null) {
-            followedTenantListener.close();
-        }
     }
 
     // *************************
@@ -145,44 +131,10 @@ public class PolicyResolver implements PolicyValidatorRegistry, AutoCloseable {
         classifierInstanceValidatorsByDefinition.remove(classifierDefinitionId, validator);
     }
 
-    /**
-     * Subscribe the resolver to updates related to a particular tenant.
-     *
-     * @param tenantId the tenant ID to subscribe to
-     */
-    protected void subscribeTenant(TenantId tenantId) {
-        synchronized (subscribersPerTenant) {
-            if (subscribersPerTenant.count(tenantId) == 0) {
-                ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction();
-                Optional<Tenant> potentialTenant = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
-                        IidFactory.tenantIid(tenantId), rTx);
-                if (potentialTenant.isPresent()) {
-                    updateTenant(tenantId, potentialTenant.get());
-                }
-                rTx.close();
-            }
-            subscribersPerTenant.add(tenantId);
-        }
-    }
-
-    /**
-     * Unsubscribe the resolver from updates related to a particular tenant.
-     *
-     * @param tenantId the tenant ID to unsubscribe from
-     */
-    protected void unsubscribeTenant(TenantId tenantId) {
-        synchronized (subscribersPerTenant) {
-            subscribersPerTenant.remove(tenantId);
-            if (subscribersPerTenant.count(tenantId) == 0) {
-                // nobody is interested in the tenant - can be removed from OPER and resolved policy
-                updateTenant(tenantId, null);
-            }
-        }
-    }
-
     @VisibleForTesting
     void updateTenant(final TenantId tenantId, final Tenant unresolvedTenant) {
         if (dataProvider == null) {
+            LOG.error("Tenant {} will not be resolved because because dataProvider is NULL", tenantId.getValue());
             return;
         }
 
@@ -218,10 +170,6 @@ public class PolicyResolver implements PolicyValidatorRegistry, AutoCloseable {
     }
 
     private void updateResolvedPolicy(WriteTransaction wTx) {
-        if (dataProvider == null) {
-            LOG.error("Couldn't Write Resolved Tenants Policy Info to Datastore because dataProvider is NULL");
-            return;
-        }
         Set<IndexedTenant> indexedTenants = getIndexedTenants(resolvedTenants.values());
         Table<EgKey, EgKey, org.opendaylight.groupbasedpolicy.dto.Policy> policyMap =
                 PolicyResolverUtils.resolvePolicy(indexedTenants);
@@ -242,7 +190,8 @@ public class PolicyResolver implements PolicyValidatorRegistry, AutoCloseable {
         return result;
     }
 
-    private boolean isPolicyValid(Policy policy) {
+    @VisibleForTesting
+    boolean isPolicyValid(Policy policy) {
         if (policy != null && policy.getSubjectFeatureInstances() != null) {
             SubjectFeatureInstances subjectFeatureInstances = policy.getSubjectFeatureInstances();
             if (actionInstancesAreValid(subjectFeatureInstances.getActionInstance())
@@ -316,47 +265,20 @@ public class PolicyResolver implements PolicyValidatorRegistry, AutoCloseable {
         @Override
         protected void onWrite(DataObjectModification<Tenant> rootNode, InstanceIdentifier<Tenant> rootIdentifier) {
             Tenant tenantAfter = rootNode.getDataAfter();
-            synchronized (subscribersPerTenant) {
-                if (subscribersPerTenant.contains(tenantAfter.getId())) {
-                    updateTenant(tenantAfter.getId(), tenantAfter);
-                    tenantAfter.getPolicy().getContract().get(0).getId();
-                    tenantAfter.getPolicy().getContract().get(0).getSubject().get(0).getName();
-                    tenantAfter.getPolicy().getContract().get(0).getSubject().get(0).getRule().get(0).getName();
-                    List<ClassifierRef> cref = tenantAfter.getPolicy()
-                            .getContract()
-                            .get(0)
-                            .getSubject()
-                            .get(0)
-                            .getRule()
-                            .get(0)
-                            .getClassifierRef();
-                    cref.get(0).getInstanceName();
-                    tenantAfter.getPolicy().getSubjectFeatureInstances().getClassifierInstance().get(0).getName();
-                    tenantAfter.getPolicy().getSubjectFeatureInstances().getClassifierInstance().get(0).getParameterValue()
-                            .get(0);
-                }
-            }
+            updateTenant(tenantAfter.getId(), tenantAfter);
         }
 
         @Override
         protected void onDelete(DataObjectModification<Tenant> rootNode, InstanceIdentifier<Tenant> rootIdentifier) {
             TenantId tenantId = rootIdentifier.firstKeyOf(Tenant.class).getId();
-            synchronized (subscribersPerTenant) {
-                if (subscribersPerTenant.contains(tenantId)) {
-                    updateTenant(tenantId, null);
-                }
-            }
+            updateTenant(tenantId, null);
         }
 
         @Override
         protected void onSubtreeModified(DataObjectModification<Tenant> rootNode,
                 InstanceIdentifier<Tenant> rootIdentifier) {
             Tenant tenantAfter = rootNode.getDataAfter();
-            synchronized (subscribersPerTenant) {
-                if (subscribersPerTenant.contains(tenantAfter.getId())) {
-                    updateTenant(tenantAfter.getId(), tenantAfter);
-                }
-            }
+            updateTenant(tenantAfter.getId(), tenantAfter);
         }
 
     }
index 4e1835cb143c73827a04d3a05d5130ab81e9339f..592f6cd662641665308a6c2bf4245eec2876d073 100644 (file)
@@ -61,6 +61,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_l
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocationKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.AddressType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.ContextType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.Forwarding;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.ForwardingByTenant;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.ForwardingByTenantKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.SubjectFeatureDefinitions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Tenants;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
@@ -479,4 +482,15 @@ public class IidFactory {
             .child(ProviderAddressEndpointLocation.class, new ProviderAddressEndpointLocationKey(addr, addrType, containment, cType))
             .build();
     }
+
+    public static InstanceIdentifier<ForwardingByTenant> forwardingByTenantIid(TenantId tenantId) {
+        return forwardingByTenantIid(new ForwardingByTenantKey(tenantId));
+    }
+
+    public static InstanceIdentifier<ForwardingByTenant> forwardingByTenantIid(
+            ForwardingByTenantKey forwardingByTenantKey) {
+        return InstanceIdentifier.builder(Forwarding.class)
+            .child(ForwardingByTenant.class, forwardingByTenantKey)
+            .build();
+    }
 }
diff --git a/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/resolver/ForwardingResolverTest.java b/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/resolver/ForwardingResolverTest.java
new file mode 100644 (file)
index 0000000..dce8236
--- /dev/null
@@ -0,0 +1,101 @@
+package org.opendaylight.groupbasedpolicy.resolver;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.test.CustomDataBrokerTest;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.Forwarding;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.ForwardingByTenant;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.ForwardingByTenantBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Optional;
+
+public class ForwardingResolverTest extends CustomDataBrokerTest {
+
+    private static final TenantId TENANT_ID_1 = new TenantId("tenant_1");
+
+    private ForwardingResolver fwdResolver;
+
+    @Before
+    public void init() {
+        fwdResolver = new ForwardingResolver(getDataBroker());
+    }
+
+    @Override
+    public Collection<Class<?>> getClassesFromModules() {
+        return Arrays.asList(Forwarding.class);
+    }
+
+    @Test
+    public void testOnWrite() throws Exception {
+        ForwardingByTenant forwardingByTenant = new ForwardingByTenantBuilder().setTenantId(TENANT_ID_1).build();
+        DataObjectModification<ForwardingByTenant> domMock = Mockito.mock(DataObjectModification.class);
+        Mockito.when(domMock.getDataAfter()).thenReturn(forwardingByTenant);
+        InstanceIdentifier<ForwardingByTenant> forwardingByTenantIid = IidFactory.forwardingByTenantIid(TENANT_ID_1);
+        fwdResolver.onWrite(domMock, forwardingByTenantIid);
+
+        ReadOnlyTransaction rTx = getDataBroker().newReadOnlyTransaction();
+        Optional<ForwardingByTenant> potenatialFwdByTenant =
+                rTx.read(LogicalDatastoreType.OPERATIONAL, forwardingByTenantIid).get();
+        Assert.assertTrue(potenatialFwdByTenant.isPresent());
+        Assert.assertEquals(forwardingByTenant, potenatialFwdByTenant.get());
+    }
+
+    @Test
+    public void testOnSubtreeModified() throws Exception {
+        ForwardingByTenant forwardingByTenant = new ForwardingByTenantBuilder().setTenantId(TENANT_ID_1).build();
+        DataObjectModification<ForwardingByTenant> domMock = Mockito.mock(DataObjectModification.class);
+        Mockito.when(domMock.getDataAfter()).thenReturn(forwardingByTenant);
+        InstanceIdentifier<ForwardingByTenant> forwardingByTenantIid = IidFactory.forwardingByTenantIid(TENANT_ID_1);
+        fwdResolver.onSubtreeModified(domMock, forwardingByTenantIid);
+
+        ReadOnlyTransaction rTx = getDataBroker().newReadOnlyTransaction();
+        Optional<ForwardingByTenant> potenatialFwdByTenant =
+                rTx.read(LogicalDatastoreType.OPERATIONAL, forwardingByTenantIid).get();
+        Assert.assertTrue(potenatialFwdByTenant.isPresent());
+        Assert.assertEquals(forwardingByTenant, potenatialFwdByTenant.get());
+    }
+
+    @Test
+    public void testOnDelete() throws Exception {
+        ForwardingByTenant forwardingByTenant = new ForwardingByTenantBuilder().setTenantId(TENANT_ID_1).build();
+        InstanceIdentifier<ForwardingByTenant> forwardingByTenantIid = IidFactory.forwardingByTenantIid(TENANT_ID_1);
+        WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction();
+        wTx.put(LogicalDatastoreType.OPERATIONAL, forwardingByTenantIid, forwardingByTenant);
+        wTx.submit().get();
+        ReadOnlyTransaction rTx = getDataBroker().newReadOnlyTransaction();
+        Optional<ForwardingByTenant> potenatialFwdByTenant =
+                rTx.read(LogicalDatastoreType.OPERATIONAL, forwardingByTenantIid).get();
+        Assert.assertTrue(potenatialFwdByTenant.isPresent());
+        fwdResolver.onDelete(null, forwardingByTenantIid);
+
+        rTx = getDataBroker().newReadOnlyTransaction();
+        potenatialFwdByTenant = rTx.read(LogicalDatastoreType.OPERATIONAL, forwardingByTenantIid).get();
+        Assert.assertFalse(potenatialFwdByTenant.isPresent());
+    }
+
+    @Test
+    public void testUpdateForwarding() throws Exception {
+        ForwardingByTenant forwardingByTenant = new ForwardingByTenantBuilder().setTenantId(TENANT_ID_1).build();
+        InstanceIdentifier<ForwardingByTenant> forwardingByTenantIid = IidFactory.forwardingByTenantIid(TENANT_ID_1);
+        fwdResolver.updateForwarding(forwardingByTenantIid, forwardingByTenant);
+
+        ReadOnlyTransaction rTx = getDataBroker().newReadOnlyTransaction();
+        Optional<ForwardingByTenant> potenatialFwdByTenant =
+                rTx.read(LogicalDatastoreType.OPERATIONAL, forwardingByTenantIid).get();
+        Assert.assertTrue(potenatialFwdByTenant.isPresent());
+        Assert.assertEquals(forwardingByTenant, potenatialFwdByTenant.get());
+    }
+
+}
index bb8b88f8d52aecdda01924688d188e7161e010c0..65754a48916592136287954ecf86c166c913a8f6 100755 (executable)
@@ -1,40 +1,33 @@
 package org.opendaylight.groupbasedpolicy.resolver;
 
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import com.google.common.base.Optional;
 import org.junit.After;
-import org.junit.Assume;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 import org.mockito.Mockito;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.test.GbpDataBrokerTest;
-import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Tenants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.TenantsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Policy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.PolicyBuilder;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
 
-@RunWith(PowerMockRunner.class)
-@PrepareForTest(DataStoreHelper.class)
+import com.google.common.base.Optional;
+
 public class PolicyResolverTest extends GbpDataBrokerTest {
 
+    private static final TenantId TENANT_ID_1 = new TenantId("tenant_1");
+
     private DataBroker dataProvider;
     private PolicyResolver policyResolver;
-    private final TenantId tenantId = new TenantId("tenant-1");
 
     @Before
     public void init() {
@@ -54,47 +47,43 @@ public class PolicyResolverTest extends GbpDataBrokerTest {
     }
 
     @Test
-    public void testSubscribeTenant_Unknown() {
-        int oldSize = policyResolver.subscribersPerTenant.count(tenantId);
-        Assume.assumeTrue(oldSize == 0);
-
-        policyResolver.subscribeTenant(tenantId);
-
-        assertEquals(policyResolver.subscribersPerTenant.count(tenantId), oldSize + 1);
+    public void testUpdateTenant() throws Exception {
+        PolicyResolver spyPolicyResolver = Mockito.spy(policyResolver);
+        Mockito.when(spyPolicyResolver.isPolicyValid(Mockito.any(Policy.class))).thenReturn(true);
+
+        WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction();
+        wTx.put(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Tenants.class),
+                new TenantsBuilder().build());
+        wTx.submit().get();
+        Tenant tenant = new TenantBuilder().setId(TENANT_ID_1).setPolicy(new PolicyBuilder().build()).build();
+        spyPolicyResolver.updateTenant(TENANT_ID_1, tenant);
+        ReadOnlyTransaction rTx = getDataBroker().newReadOnlyTransaction();
+        Optional<Tenant> potentialTenant =
+                rTx.read(LogicalDatastoreType.OPERATIONAL, IidFactory.tenantIid(TENANT_ID_1)).get();
+        Assert.assertTrue(potentialTenant.isPresent());
+        Assert.assertEquals(tenant.getId(), potentialTenant.get().getId());
     }
 
     @Test
-    public void testSubscribeTenant_Known() {
-        Tenant unresolvedTenant = new TenantBuilder().setId(tenantId).build();
-
-        Optional<Tenant> potentialTenant = mock(Optional.class);
-        when(potentialTenant.isPresent()).thenReturn(true);
-        when(potentialTenant.get()).thenReturn(unresolvedTenant);
-
-        PowerMockito.mockStatic(DataStoreHelper.class);
-        when(DataStoreHelper.readFromDs(eq(LogicalDatastoreType.CONFIGURATION),
-                Mockito.<InstanceIdentifier<Tenant>>any(), any(ReadOnlyTransaction.class))).thenReturn(potentialTenant);
-
-        PolicyResolver spy = spy(policyResolver);
-
-        int oldSize = spy.subscribersPerTenant.count(tenantId);
-
-        spy.subscribeTenant(tenantId);
-
-        assertEquals(spy.subscribersPerTenant.count(tenantId), oldSize + 1);
-        verify(spy).updateTenant(eq(tenantId), any(Tenant.class));
+    public void testUpdateTenant_noPolicy() throws Exception {
+        Tenant tenant = new TenantBuilder().setId(TENANT_ID_1).build();
+        policyResolver.updateTenant(TENANT_ID_1, tenant);
+        ReadOnlyTransaction rTx = getDataBroker().newReadOnlyTransaction();
+        Optional<Tenant> potentialTenant =
+                rTx.read(LogicalDatastoreType.OPERATIONAL, IidFactory.tenantIid(TENANT_ID_1)).get();
+        Assert.assertFalse(potentialTenant.isPresent());
     }
 
     @Test
-    public void testUnsubscribeTenant() {
-        int oldSize = policyResolver.subscribersPerTenant.count(tenantId);
-        Assume.assumeTrue(oldSize == 0);
-
-        policyResolver.subscribeTenant(tenantId);
-        assertEquals(policyResolver.subscribersPerTenant.count(tenantId), oldSize + 1);
-
-        policyResolver.unsubscribeTenant(tenantId);
-        assertEquals(policyResolver.subscribersPerTenant.count(tenantId), oldSize);
+    public void testUpdateTenant_nullTenant() throws Exception {
+        Tenant tenant = new TenantBuilder().setId(TENANT_ID_1).build();
+        InstanceIdentifier<Tenant> tenantIid = IidFactory.tenantIid(TENANT_ID_1);
+        WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction();
+        wTx.put(LogicalDatastoreType.OPERATIONAL, tenantIid, tenant);
+        policyResolver.updateTenant(TENANT_ID_1, null);
+        ReadOnlyTransaction rTx = getDataBroker().newReadOnlyTransaction();
+        Optional<Tenant> potentialTenant = rTx.read(LogicalDatastoreType.OPERATIONAL, tenantIid).get();
+        Assert.assertFalse(potentialTenant.isPresent());
     }
 
 }