added tests, fixed ipPrefix based lookup 72/37972/4
authorMichal Rehak <mirehak@cisco.com>
Tue, 19 Apr 2016 17:51:34 +0000 (19:51 +0200)
committerMichal Rehak <mirehak@cisco.com>
Tue, 26 Apr 2016 11:43:01 +0000 (13:43 +0200)
Change-Id: I52f607f3e58d9fe198f587c3cd80452fc02e0bf4
Signed-off-by: Michal Rehak <mirehak@cisco.com>
33 files changed:
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/DSAsyncDao.java [moved from sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/DSDaoAsync.java with 94% similarity]
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/EPTemplateListener.java
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/IpPrefixEqualCommand.java [new file with mode: 0644]
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/ReadableByKey.java [new file with mode: 0644]
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/SimpleCachedDao.java [moved from sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/DSDaoCached.java with 77% similarity]
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/SimpleDao.java [moved from sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/DSDao.java with 88% similarity]
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/SxpMapperReactor.java
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/SxpMapperProviderImpl.java
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/SxpMapperReactorImpl.java
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/EPForwardingTemplateDaoImpl.java
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/EPPolicyTemplateDaoImpl.java
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/MasterDatabaseBindingDaoImpl.java
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/SimpleCachedDaoEPForwardingTemplateImpl.java [moved from sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/DSDaoCachedEPForwardingTemplateImpl.java with 51% similarity]
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/SimpleCachedDaoImpl.java [moved from sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/DSDaoCachedImpl.java with 68% similarity]
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/listen/EPForwardingTemplateListenerImpl.java
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/listen/EPPolicyTemplateListenerImpl.java
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/listen/MasterDatabaseBindingListenerImpl.java
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/util/ForwardingTemplateUtil.java
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/util/IpPrefixEqualCommandDirectImpl.java [new file with mode: 0644]
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/util/IpPrefixEqualCommandSubnetImpl.java [new file with mode: 0644]
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/util/L3EPServiceUtil.java [new file with mode: 0644]
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/util/SubnetInfoKeyDecorator.java [new file with mode: 0644]
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/util/SxpListenerUtil.java
sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/SxpMapperReactorImplTest.java [new file with mode: 0644]
sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/EPForwardingTemplateDaoImplTest.java [new file with mode: 0644]
sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/EPPolicyTemplateDaoImplTest.java [new file with mode: 0644]
sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/MasterDatabaseBindingDaoImplTest.java [new file with mode: 0644]
sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/SimpleCachedDaoEPForwardingTemplateImplTest.java [new file with mode: 0644]
sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/SimpleCachedDaoImplTest.java [new file with mode: 0644]
sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/listen/EPForwardingTemplateListenerImplTest.java [new file with mode: 0644]
sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/listen/EPPolicyTemplateListenerImplTest.java [new file with mode: 0644]
sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/listen/MasterDatabaseBindingListenerImplTest.java [new file with mode: 0644]
sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/util/ForwardingTemplateUtilTest.java [new file with mode: 0644]

similarity index 94%
rename from sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/DSDaoAsync.java
rename to sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/DSAsyncDao.java
index 75b5fded92fabf1e26e18b69a16760d281799ca8..ac31581ee2a761215335b59f315b481b8d864802 100644 (file)
@@ -22,7 +22,7 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
  * @param <K> data key type
  * @param <V> data type
  */
-public interface DSDaoAsync<K, V extends DataObject> {
+public interface DSAsyncDao<K, V extends DataObject> {
 
     /**
      * @param key for search
index 1f9fe0cfa0c348f9e98352b799b5a5570fdd1e5f..f7898e78b4e3b5bd3055dd4cbdc080cb53598166 100644 (file)
@@ -14,7 +14,7 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
- * Purpose: provide listener capability to EB templates
+ * Purpose: provide listener capability to EndPoint templates
  */
 public interface EPTemplateListener<T extends DataObject> extends DataTreeChangeListener<T>, AutoCloseable {
 
diff --git a/sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/IpPrefixEqualCommand.java b/sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/IpPrefixEqualCommand.java
new file mode 100644 (file)
index 0000000..1c3a2cf
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * 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.sxp.mapper.api;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+
+/**
+ * Purpose: provide different strategies for {@link IpPrefix} comparison
+ */
+public interface IpPrefixEqualCommand {
+
+    boolean isEqualTo(IpPrefix value);
+}
diff --git a/sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/ReadableByKey.java b/sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/ReadableByKey.java
new file mode 100644 (file)
index 0000000..fc46e6d
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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.sxp.mapper.api;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Collection;
+import javax.annotation.Nonnull;
+
+/**
+ * Purpose: simple asynchronous search interface allowing for custom key and returning list of values
+ *
+ * @param <X> special key type
+ * @param <V> value type
+ */
+public interface ReadableByKey<X, V> {
+
+    /**
+     * @param specialKey custom key to search by
+     * @return list of found values
+     */
+    ListenableFuture<Collection<V>> readBy(@Nonnull X specialKey);
+}
similarity index 77%
rename from sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/DSDaoCached.java
rename to sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/SimpleCachedDao.java
index 233191188351d57bcb147c6420d8aa3216d2ff3e..d3e139012465d1c3486bfc2f52699f55b14dbef8 100644 (file)
@@ -13,7 +13,7 @@ import javax.annotation.Nullable;
 /**
  * Purpose: encapsulate access to DS by exposing
  * <dl>
- * <dt>read</dt>
+ * <dt>find</dt>
  * <dd>search through cached values</dd>
  * <dt>update</dt>
  * <dd>stores given pair (key, value) to local cache</dd>
@@ -22,7 +22,7 @@ import javax.annotation.Nullable;
  * @param <K> data key type
  * @param <V> data type
  */
-public interface DSDaoCached<K, V> extends DSDao<K, V> {
+public interface SimpleCachedDao<K, V> extends SimpleDao<K, V> {
 
     /**
      * store given pair to local cache
@@ -36,4 +36,14 @@ public interface DSDaoCached<K, V> extends DSDao<K, V> {
      * invalidate all cache entries
      */
     void invalidateCache();
+
+    /**
+     * @return true if there is nothing cached
+     */
+    boolean isEmpty();
+
+    /**
+     * @return unmodifiable iterator through all cached values
+     */
+    Iterable<V> values();
 }
similarity index 88%
rename from sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/DSDao.java
rename to sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/api/SimpleDao.java
index 9c6c3d50410d05d8725cca7bc8190ef5e225700a..1616eac25dd29c08da84bc542d98177929d6e1f1 100644 (file)
@@ -13,19 +13,19 @@ import javax.annotation.Nonnull;
 /**
  * Purpose: encapsulate access to DS by exposing
  * <dl>
- * <dt>read</dt>
+ * <dt>find</dt>
  * <dd>search through available values (e.g.: in  local cache)</dd>
  * </dl>
  *
  * @param <K> data key type
  * @param <V> data type
  */
-public interface DSDao<K, V> {
+public interface SimpleDao<K, V> {
 
     /**
      * @param key for search
      * @return value found by key
      */
-    Optional<V> read(@Nonnull K key);
+    Optional<V> find(@Nonnull K key);
 
 }
index 1dbd69362163fdd946006988e21c29d87fde1450..304c95d4b9c47eb370377bc70f8e290d0d2ee0cd 100644 (file)
@@ -8,8 +8,28 @@
 
 package org.opendaylight.groupbasedpolicy.sxp.mapper.api;
 
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
 /**
  * Purpose: process given ip-sgt binding and EP-template in order to create L3-EP
  */
 public interface SxpMapperReactor {
+
+    /**
+     * apply sgt/ip binding on policy template and delegate to appropriate GBP service
+     *  @param epPolicyTemplate template
+     * @param masterDatabaseBinding sxpMasterDB item
+     */
+    ListenableFuture<RpcResult<Void>> processPolicyAndSxpMasterDB(EndpointPolicyTemplateBySgt epPolicyTemplate, MasterDatabaseBinding masterDatabaseBinding);
+
+    /**
+     * apply sgt/ip binding on forwarding template and delegate to appropriate GBP service
+     *  @param epForwardingTemplate template
+     * @param masterDatabaseBinding sxpMasterDB item
+     */
+    ListenableFuture<RpcResult<Void>> processForwardingAndSxpMasterDB(EndpointForwardingTemplateBySubnet epForwardingTemplate, MasterDatabaseBinding masterDatabaseBinding);
 }
index 290fe24cb5b915abb2c3c62c3af2ce2e0923cd26..1e6fd913e0d4703e7d4894657e8649fbdd517b1b 100644 (file)
@@ -10,12 +10,12 @@ package org.opendaylight.groupbasedpolicy.sxp.mapper.impl;
 
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSDaoAsync;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSDaoCached;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSAsyncDao;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.api.EPTemplateListener;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SxpMapperReactor;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao.DSDaoCachedEPForwardingTemplateImpl;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao.DSDaoCachedImpl;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao.SimpleCachedDaoEPForwardingTemplateImpl;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao.SimpleCachedDaoImpl;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao.EPForwardingTemplateDaoImpl;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao.EPPolicyTemplateDaoImpl;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao.MasterDatabaseBindingDaoImpl;
@@ -28,12 +28,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controll
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * SxpMapper provider implementation.
  */
 public class SxpMapperProviderImpl implements AutoCloseable {
 
+    private static final Logger LOG = LoggerFactory.getLogger(SxpMapperProviderImpl.class);
+
     private final DataBroker dataBrokerDependency;
     private final RpcProviderRegistry rpcRegistryDependency;
     private final MasterDatabaseBindingListenerImpl sxpDatabaseListener;
@@ -42,28 +46,30 @@ public class SxpMapperProviderImpl implements AutoCloseable {
     private final EPTemplateListener epForwardingTemplateListener;
 
     public SxpMapperProviderImpl(final DataBroker dataBroker, final RpcProviderRegistry rpcRegistryDependency) {
+        LOG.info("starting SxmMapper ..");
         this.dataBrokerDependency = dataBroker;
         this.rpcRegistryDependency = rpcRegistryDependency;
 
         final EndpointService endpointService = rpcRegistryDependency.getRpcService(EndpointService.class);
         sxpMapperReactor = new SxpMapperReactorImpl(endpointService);
 
-        final DSDaoCached<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateCachedDao = new DSDaoCachedImpl<>();
-        final DSDaoCached<IpPrefix, EndpointForwardingTemplateBySubnet> epForwardingTemplateCachedDao = new DSDaoCachedImpl<>();
-                new DSDaoCachedEPForwardingTemplateImpl();
-        final DSDaoCached<IpPrefix, MasterDatabaseBinding> masterDBBindingCachedDao = new DSDaoCachedImpl<>();
+        final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateCachedDao = new SimpleCachedDaoImpl<>();
+        final SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> epForwardingTemplateCachedDao =
+                new SimpleCachedDaoEPForwardingTemplateImpl();
+        final SimpleCachedDao<IpPrefix, MasterDatabaseBinding> masterDBBindingCachedDao = new SimpleCachedDaoImpl<>();
 
-        final DSDaoAsync<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateDao = new EPPolicyTemplateDaoImpl(dataBroker, epPolicyTemplateCachedDao);
+        final DSAsyncDao<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateDao = new EPPolicyTemplateDaoImpl(dataBroker, epPolicyTemplateCachedDao);
         final EPForwardingTemplateDaoImpl epForwardingTemplateDao = new EPForwardingTemplateDaoImpl(dataBroker,
                 epForwardingTemplateCachedDao);
-        final MasterDatabaseBindingDaoImpl masterDBBindingDao = new MasterDatabaseBindingDaoImpl(dataBroker, masterDBBindingCachedDao);
+        final  MasterDatabaseBindingDaoImpl masterDBBindingDao = new MasterDatabaseBindingDaoImpl(dataBroker, masterDBBindingCachedDao);
 
         sxpDatabaseListener = new MasterDatabaseBindingListenerImpl(dataBroker, sxpMapperReactor, masterDBBindingCachedDao,
                 epPolicyTemplateDao, epForwardingTemplateDao);
         epPolicyTemplateListener = new EPPolicyTemplateListenerImpl(dataBroker, sxpMapperReactor, epPolicyTemplateCachedDao,
-                masterDBBindingDao, epForwardingTemplateDao);
+                masterDBBindingDao);
         epForwardingTemplateListener = new EPForwardingTemplateListenerImpl(dataBroker, sxpMapperReactor, epForwardingTemplateCachedDao,
-                masterDBBindingDao, epPolicyTemplateDao);
+                masterDBBindingDao);
+        LOG.info("started SxmMapper");
     }
 
     // register listeners to ip/sgt and EP-templates (by SGT, by subnet) -> 3x
index 069dc0b75d3227ae0388079b12244e8264edf3ed..8ed0329b82044c987f33d3ba49200b4f329d9b54 100644 (file)
@@ -8,8 +8,16 @@
 
 package org.opendaylight.groupbasedpolicy.sxp.mapper.impl;
 
+import com.google.common.util.concurrent.JdkFutureAdapters;
+import com.google.common.util.concurrent.ListenableFuture;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SxpMapperReactor;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding;
+import org.opendaylight.yangtools.yang.common.RpcResult;
 
 /**
  * Purpose: exclusively processes sxp master database changes and EGP templates changes
@@ -20,4 +28,28 @@ public class SxpMapperReactorImpl implements SxpMapperReactor {
     public SxpMapperReactorImpl(final EndpointService l3EndpointService) {
         this.l3EndpointService = l3EndpointService;
     }
+
+    @Override
+    public ListenableFuture<RpcResult<Void>> processPolicyAndSxpMasterDB(final EndpointPolicyTemplateBySgt template, final MasterDatabaseBinding masterDatabaseBinding) {
+        // apply sxpMasterDB to policy template
+        final RegisterEndpointInput input = new RegisterEndpointInputBuilder()
+                .setCondition(template.getConditions())
+                .setTenant(template.getTenant())
+                .setEndpointGroups(template.getEndpointGroups())
+                .build();
+
+        // invoke service
+        return JdkFutureAdapters.listenInPoolThread(l3EndpointService.registerEndpoint(input));
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<Void>> processForwardingAndSxpMasterDB(final EndpointForwardingTemplateBySubnet template, final MasterDatabaseBinding masterDatabaseBinding) {
+        // apply sxpMasterDB to policy template
+        final RegisterEndpointInput input = new RegisterEndpointInputBuilder()
+                .setNetworkContainment(template.getNetworkContainment())
+                .build();
+
+        // invoke service
+        return JdkFutureAdapters.listenInPoolThread(l3EndpointService.registerEndpoint(input));
+    }
 }
index b3f0099c52d0f8f2d4e33a4d8eaecbe2a8b88658..65ce34eb912241c60d4a17e4ac029dc31aff9da1 100644 (file)
@@ -19,9 +19,9 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSDaoAsync;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSDaoCached;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSAsyncDao;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.api.EPTemplateListener;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.SxpListenerUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.SxpMapper;
@@ -31,13 +31,14 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 /**
  * Purpose: general dao for EndPoint templates
  */
-public class EPForwardingTemplateDaoImpl implements DSDaoAsync<IpPrefix, EndpointForwardingTemplateBySubnet> {
+public class EPForwardingTemplateDaoImpl implements DSAsyncDao<IpPrefix, EndpointForwardingTemplateBySubnet> {
 
+    public static final ListenableFuture<Optional<EndpointForwardingTemplateBySubnet>> READ_FUTURE_ABSENT = Futures.immediateFuture(Optional.absent());
     private final DataBroker dataBroker;
-    private final DSDaoCached<IpPrefix, EndpointForwardingTemplateBySubnet> cachedDao;
+    private final SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> cachedDao;
 
     public EPForwardingTemplateDaoImpl(final DataBroker dataBroker,
-                                       final DSDaoCached<IpPrefix, EndpointForwardingTemplateBySubnet> cachedDao) {
+                                       final SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> cachedDao) {
         this.dataBroker = dataBroker;
         this.cachedDao = cachedDao;
     }
@@ -45,8 +46,11 @@ public class EPForwardingTemplateDaoImpl implements DSDaoAsync<IpPrefix, Endpoin
     @Override
     public ListenableFuture<Optional<EndpointForwardingTemplateBySubnet>> read(@Nonnull final IpPrefix key) {
         final Optional<EndpointForwardingTemplateBySubnet> value = lookup(cachedDao, key);
+        final ListenableFuture<Optional<EndpointForwardingTemplateBySubnet>> readResult;
         if (value.isPresent()) {
-            return Futures.immediateFuture(value);
+            readResult = Futures.immediateFuture(value);
+        } else if (!cachedDao.isEmpty()) {
+            return READ_FUTURE_ABSENT;
         } else {
             final ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
             final CheckedFuture<Optional<SxpMapper>, ReadFailedException> read =
@@ -54,7 +58,7 @@ public class EPForwardingTemplateDaoImpl implements DSDaoAsync<IpPrefix, Endpoin
 
             Futures.addCallback(read, SxpListenerUtil.createTxCloseCallback(rTx));
 
-            return Futures.transform(read, new Function<Optional<SxpMapper>, Optional<EndpointForwardingTemplateBySubnet>>() {
+            readResult = Futures.transform(read, new Function<Optional<SxpMapper>, Optional<EndpointForwardingTemplateBySubnet>>() {
                 @Nullable
                 @Override
                 public Optional<EndpointForwardingTemplateBySubnet> apply(@Nullable final Optional<SxpMapper> input) {
@@ -69,21 +73,22 @@ public class EPForwardingTemplateDaoImpl implements DSDaoAsync<IpPrefix, Endpoin
                                 cachedDao.update(template.getIpPrefix(), template);
                             }
                         }
-                        return cachedDao.read(key);
+                        return cachedDao.find(key);
                     } else {
                         return Optional.absent();
                     }
                 }
             });
         }
+        return readResult;
     }
 
     protected InstanceIdentifier<SxpMapper> buildReadPath(final IpPrefix key) {
         return EPTemplateListener.SXP_MAPPER_TEMPLATE_PARENT_PATH;
     }
 
-    private Optional<EndpointForwardingTemplateBySubnet> lookup(final DSDaoCached<IpPrefix, EndpointForwardingTemplateBySubnet> cachedDao, final IpPrefix key) {
-        return cachedDao.read(key);
+    private Optional<EndpointForwardingTemplateBySubnet> lookup(final SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> cachedDao, final IpPrefix key) {
+        return cachedDao.find(key);
     }
 
 }
index aade564ad975e4054892a89710dc51e459e09892..de2f60f7044fc38a58a16d0975e52194c76cd3cd 100644 (file)
@@ -18,8 +18,8 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSDaoAsync;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSDaoCached;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSAsyncDao;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.api.EPTemplateListener;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.SxpListenerUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
@@ -30,13 +30,13 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 /**
  * Purpose: general dao for EndPoint templates
  */
-public class EPPolicyTemplateDaoImpl implements DSDaoAsync<Sgt, EndpointPolicyTemplateBySgt> {
+public class EPPolicyTemplateDaoImpl implements DSAsyncDao<Sgt, EndpointPolicyTemplateBySgt> {
 
     private final DataBroker dataBroker;
-    private final DSDaoCached<Sgt, EndpointPolicyTemplateBySgt> cachedDao;
+    private final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> cachedDao;
 
     public EPPolicyTemplateDaoImpl(final DataBroker dataBroker,
-                                   final DSDaoCached<Sgt, EndpointPolicyTemplateBySgt> cachedDao) {
+                                   final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> cachedDao) {
         this.dataBroker = dataBroker;
         this.cachedDao = cachedDao;
     }
@@ -71,8 +71,8 @@ public class EPPolicyTemplateDaoImpl implements DSDaoAsync<Sgt, EndpointPolicyTe
                 .child(EndpointPolicyTemplateBySgt.class, new EndpointPolicyTemplateBySgtKey(key));
     }
 
-    private Optional<EndpointPolicyTemplateBySgt> lookup(final DSDaoCached<Sgt, EndpointPolicyTemplateBySgt> cachedDao, final Sgt key) {
-        return cachedDao.read(key);
+    private Optional<EndpointPolicyTemplateBySgt> lookup(final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> cachedDao, final Sgt key) {
+        return cachedDao.find(key);
     }
 
 }
index 17d820a3293cc4016204858ca83a03a4b878d726..e2bf49988d3c95147ae430e7257f84ad018f901a 100644 (file)
@@ -12,6 +12,8 @@ import com.google.common.base.Optional;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -19,9 +21,10 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSDaoAsync;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSDaoCached;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSAsyncDao;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.api.MasterDatabaseBindingListener;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.ReadableByKey;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.SxpListenerUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
@@ -36,15 +39,16 @@ import org.slf4j.LoggerFactory;
 /**
  * Purpose: general dao for EndPoint templates
  */
-public class MasterDatabaseBindingDaoImpl implements DSDaoAsync<IpPrefix, MasterDatabaseBinding> {
+public class MasterDatabaseBindingDaoImpl implements DSAsyncDao<IpPrefix, MasterDatabaseBinding>,
+        ReadableByKey<Sgt, MasterDatabaseBinding> {
 
     private static final Logger LOG = LoggerFactory.getLogger(MasterDatabaseBindingDaoImpl.class);
 
     private final DataBroker dataBroker;
-    private final DSDaoCached<IpPrefix, MasterDatabaseBinding> cachedDao;
+    private final SimpleCachedDao<IpPrefix, MasterDatabaseBinding> cachedDao;
 
     public MasterDatabaseBindingDaoImpl(final DataBroker dataBroker,
-                              final DSDaoCached<IpPrefix, MasterDatabaseBinding> cachedDao) {
+                              final SimpleCachedDao<IpPrefix, MasterDatabaseBinding> cachedDao) {
         this.dataBroker = dataBroker;
         this.cachedDao = cachedDao;
     }
@@ -112,7 +116,32 @@ public class MasterDatabaseBindingDaoImpl implements DSDaoAsync<IpPrefix, Master
         return MasterDatabaseBindingListener.SXP_TOPOLOGY_PATH;
     }
 
-    private Optional<MasterDatabaseBinding> lookup(final DSDaoCached<IpPrefix, MasterDatabaseBinding> cachedDao, final IpPrefix key) {
-        return cachedDao.read(key);
+    private Optional<MasterDatabaseBinding> lookup(final SimpleCachedDao<IpPrefix, MasterDatabaseBinding> cachedDao, final IpPrefix key) {
+        return cachedDao.find(key);
+    }
+
+    @Override
+    public ListenableFuture<Collection<MasterDatabaseBinding>> readBy(@Nonnull final Sgt specialKey) {
+        final ListenableFuture<Void> cacheUpdatedFt;
+        if (!cachedDao.isEmpty()) {
+            cacheUpdatedFt = Futures.immediateFuture(null);
+        } else {
+            cacheUpdatedFt = updateCache();
+        }
+
+        return Futures.transform(cacheUpdatedFt, new Function<Void, Collection<MasterDatabaseBinding>>() {
+            @Nullable
+            @Override
+            public Collection<MasterDatabaseBinding> apply(@Nullable final Void input) {
+                final Collection<MasterDatabaseBinding> foundGroups = new ArrayList<>();
+
+                for (MasterDatabaseBinding masterDBItem : cachedDao.values()) {
+                    if (masterDBItem.getSecurityGroupTag().equals(specialKey)) {
+                        foundGroups.add(masterDBItem);
+                    }
+                }
+                return foundGroups;
+            }
+        });
     }
 }
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -8,25 +8,30 @@
 package org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao;
 
 import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
+import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.regex.Pattern;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import org.apache.commons.net.util.SubnetUtils;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSDaoCached;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.ForwardingTemplateUtil;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.SubnetInfoKeyDecorator;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnet;
 
 /**
- * Purpose: generic implementation of {@link DSDaoCached}
+ * Purpose: generic implementation of {@link SimpleCachedDao}
  */
-public class DSDaoCachedEPForwardingTemplateImpl implements DSDaoCached<IpPrefix, EndpointForwardingTemplateBySubnet> {
+public class SimpleCachedDaoEPForwardingTemplateImpl implements SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> {
 
     private final ConcurrentMap<IpPrefix, EndpointForwardingTemplateBySubnet> plainCache;
-    private final ConcurrentMap<SubnetUtils.SubnetInfo, EndpointForwardingTemplateBySubnet> subnetCache;
+    private final ConcurrentMap<SubnetInfoKeyDecorator, EndpointForwardingTemplateBySubnet> subnetCache;
+    private final Pattern IP_MASK_EATER_RE = Pattern.compile("/[0-9]+");
 
-    public DSDaoCachedEPForwardingTemplateImpl() {
+    public SimpleCachedDaoEPForwardingTemplateImpl() {
         plainCache = new ConcurrentHashMap<>();
         subnetCache = new ConcurrentHashMap<>();
     }
@@ -45,7 +50,7 @@ public class DSDaoCachedEPForwardingTemplateImpl implements DSDaoCached<IpPrefix
 
     private EndpointForwardingTemplateBySubnet updateSubnetCache(final IpPrefix key, final EndpointForwardingTemplateBySubnet value) {
         final EndpointForwardingTemplateBySubnet previousValue;
-        final SubnetUtils.SubnetInfo subnetKey = ForwardingTemplateUtil.buildSubnetInfo(key);
+        final SubnetInfoKeyDecorator subnetKey = ForwardingTemplateUtil.buildSubnetInfoKey(key);
         if (value != null) {
             previousValue = subnetCache.put(subnetKey, value);
         } else {
@@ -65,19 +70,58 @@ public class DSDaoCachedEPForwardingTemplateImpl implements DSDaoCached<IpPrefix
     }
 
     @Override
-    public Optional<EndpointForwardingTemplateBySubnet> read(@Nonnull final IpPrefix key) {
+    public Optional<EndpointForwardingTemplateBySubnet> find(@Nonnull final IpPrefix key) {
         final Optional<EndpointForwardingTemplateBySubnet> template;
         if (ForwardingTemplateUtil.isPlain(key)) {
-            template = Optional.fromNullable(plainCache.get(key));
+            final Optional<EndpointForwardingTemplateBySubnet> fastPlain = Optional.fromNullable(plainCache.get(key));
+            if (fastPlain.isPresent()) {
+                template = fastPlain;
+            } else {
+                template = lookupSlowSubnet(key.getIpv4Prefix().getValue());
+            }
         } else {
-            template = Optional.fromNullable(subnetCache.get(ForwardingTemplateUtil.buildSubnetInfo(key)));
+            final SubnetInfoKeyDecorator keyDecorator = ForwardingTemplateUtil.buildSubnetInfoKey(key);
+            final Optional<EndpointForwardingTemplateBySubnet> fastSubnet =
+                    Optional.fromNullable(subnetCache.get(keyDecorator));
+            if (fastSubnet.isPresent()) {
+                template = fastSubnet;
+            } else {
+                template = Optional.absent();
+            }
         }
         return template;
     }
 
+    private Optional<EndpointForwardingTemplateBySubnet> lookupSlowSubnet(final String value) {
+        final String plainIp = IP_MASK_EATER_RE.matcher(value).replaceFirst("");
+        EndpointForwardingTemplateBySubnet valueCandidate = null;
+        int addressCount = 0;
+        for (Map.Entry<SubnetInfoKeyDecorator, EndpointForwardingTemplateBySubnet> entry : subnetCache.entrySet()) {
+            final SubnetUtils.SubnetInfo subnetInfo = entry.getKey().getDelegate();
+            if (subnetInfo.isInRange(plainIp)) {
+                final int addressCountTmp = subnetInfo.getAddressCount();
+                if (valueCandidate == null || addressCount > addressCountTmp) {
+                    valueCandidate = entry.getValue();
+                    addressCount = addressCountTmp;
+                }
+            }
+        }
+        return Optional.fromNullable(valueCandidate);
+    }
+
     @Override
     public void invalidateCache() {
         plainCache.clear();
         subnetCache.clear();
     }
+
+    @Override
+    public boolean isEmpty() {
+        return plainCache.isEmpty() && subnetCache.isEmpty();
+    }
+
+    @Override
+    public Iterable<EndpointForwardingTemplateBySubnet> values() {
+        return Iterables.unmodifiableIterable(Iterables.concat(plainCache.values(), subnetCache.values()));
+    }
 }
similarity index 68%
rename from sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/DSDaoCachedImpl.java
rename to sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/SimpleCachedDaoImpl.java
index 243f1e2da91a0bcbd0409b458661c2fc5544596c..b57ac7471947cda48c17397ad51260f7b80ba892 100644 (file)
@@ -8,21 +8,22 @@
 package org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao;
 
 import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSDaoCached;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 
 /**
- * Purpose: generic implementation of {@link DSDaoCached}
+ * Purpose: generic implementation of {@link SimpleCachedDao}
  */
-public class DSDaoCachedImpl<K, V extends DataObject> implements DSDaoCached<K, V> {
+public class SimpleCachedDaoImpl<K, V extends DataObject> implements SimpleCachedDao<K, V> {
 
     private final ConcurrentMap<K, V> cache;
 
-    public DSDaoCachedImpl() {
+    public SimpleCachedDaoImpl() {
         cache = new ConcurrentHashMap<>();
     }
 
@@ -39,7 +40,7 @@ public class DSDaoCachedImpl<K, V extends DataObject> implements DSDaoCached<K,
     }
 
     @Override
-    public Optional<V> read(@Nonnull final K key) {
+    public Optional<V> find(@Nonnull final K key) {
         return Optional.fromNullable(cache.get(key));
     }
 
@@ -47,4 +48,14 @@ public class DSDaoCachedImpl<K, V extends DataObject> implements DSDaoCached<K,
     public void invalidateCache() {
         cache.clear();
     }
+
+    @Override
+    public boolean isEmpty() {
+        return cache.isEmpty();
+    }
+
+    @Override
+    public Iterable<V> values() {
+        return Iterables.unmodifiableIterable(cache.values());
+    }
 }
index 9d20b3b2f20f0f2055f491e408121da36e1c6d4b..83d021acc969340129f30725b234cdc3b1141dd9 100644 (file)
@@ -7,25 +7,32 @@
  */
 package org.opendaylight.groupbasedpolicy.sxp.mapper.impl.listen;
 
+import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 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.groupbasedpolicy.sxp.mapper.api.DSDaoAsync;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSDaoCached;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSAsyncDao;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.api.EPTemplateListener;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SxpMapperReactor;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.L3EPServiceUtil;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.SxpListenerUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnet;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -35,22 +42,23 @@ import org.slf4j.LoggerFactory;
 public class EPForwardingTemplateListenerImpl implements EPTemplateListener<EndpointForwardingTemplateBySubnet> {
 
     private static final Logger LOG = LoggerFactory.getLogger(EPForwardingTemplateListenerImpl.class);
+
+    public static final FutureCallback<RpcResult<Void>> ANY_RPC_FUTURE_CALLBACK =
+            L3EPServiceUtil.createFailureLoggingCallback("failed to read epForwardingTemplate");
+
     private final SxpMapperReactor sxpMapperReactor;
-    private final DSDaoCached<IpPrefix, EndpointForwardingTemplateBySubnet> templateCachedDao;
-    private final DSDaoAsync<IpPrefix, MasterDatabaseBinding> masterDBBindingDao;
-    private final DSDaoAsync<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateDao;
+    private final SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> templateCachedDao;
+    private final DSAsyncDao<IpPrefix, MasterDatabaseBinding> masterDBBindingDao;
     private final ListenerRegistration<? extends EPTemplateListener> listenerRegistration;
     private final InstanceIdentifier<EndpointForwardingTemplateBySubnet> templatePath;
 
     public EPForwardingTemplateListenerImpl(final DataBroker dataBroker,
                                             final SxpMapperReactor sxpMapperReactor,
-                                            final DSDaoCached<IpPrefix, EndpointForwardingTemplateBySubnet> templateCachedDao,
-                                            final DSDaoAsync<IpPrefix, MasterDatabaseBinding> masterDBBindingDao,
-                                            final DSDaoAsync<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateDao) {
+                                            final SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> templateCachedDao,
+                                            final DSAsyncDao<IpPrefix, MasterDatabaseBinding> masterDBBindingDao) {
         this.sxpMapperReactor = Preconditions.checkNotNull(sxpMapperReactor);
         this.templateCachedDao = Preconditions.checkNotNull(templateCachedDao);
         this.masterDBBindingDao = Preconditions.checkNotNull(masterDBBindingDao);
-        this.epPolicyTemplateDao = epPolicyTemplateDao;
         templatePath = EPTemplateListener.SXP_MAPPER_TEMPLATE_PARENT_PATH.child(EndpointForwardingTemplateBySubnet.class);
 
         final DataTreeIdentifier<EndpointForwardingTemplateBySubnet> dataTreeIdentifier = new DataTreeIdentifier<>(
@@ -68,10 +76,32 @@ public class EPForwardingTemplateListenerImpl implements EPTemplateListener<Endp
             final IpPrefix changeKey = changePath.firstKeyOf(EndpointForwardingTemplateBySubnet.class).getIpPrefix();
             SxpListenerUtil.updateCachedDao(templateCachedDao, changeKey, change);
 
-            // TODO: sxpMapperReactor.process(template)
+            final EndpointForwardingTemplateBySubnet epForwardingTemplate = change.getRootNode().getDataAfter();
+            processWithSxpMasterDB(changeKey, epForwardingTemplate);
         }
     }
 
+    private void processWithSxpMasterDB(final IpPrefix changeKey, final EndpointForwardingTemplateBySubnet epForwardingTemplate) {
+        final ListenableFuture<Optional<MasterDatabaseBinding>> sxpMasterDbItemFuture = masterDBBindingDao.read(changeKey);
+
+        final ListenableFuture<RpcResult<Void>> allRpcResult = Futures.transform(sxpMasterDbItemFuture, new AsyncFunction<Optional<MasterDatabaseBinding>, RpcResult<Void>>() {
+            @Override
+            public ListenableFuture<RpcResult<Void>> apply(final Optional<MasterDatabaseBinding> input) throws Exception {
+                if (input == null && input.isPresent()) {
+                    LOG.debug("no epForwardingTemplate available for sgt: {}", changeKey);
+                    throw new IllegalArgumentException("no epForwardingTemplate available");
+                } else {
+                    List<ListenableFuture<RpcResult<Void>>> resultBag = new ArrayList<>();
+                    LOG.trace("processing sxpMasterDB event and epForwardingTemplate for sgt: {}", changeKey);
+                    final ListenableFuture<RpcResult<Void>> rpcResult = sxpMapperReactor.processForwardingAndSxpMasterDB(epForwardingTemplate, input.get());
+                    return rpcResult;
+                }
+            }
+        });
+
+        Futures.addCallback(allRpcResult, ANY_RPC_FUTURE_CALLBACK);
+    }
+
     @Override
     public void close() throws Exception {
         LOG.debug("closing listener registration to {}", templatePath);
index 3e784ad5e68063c82ccec964041028f978efc0a7..6bd4a9d9b012b2b0559dfaceda4478ce10e09557 100644 (file)
@@ -8,24 +8,30 @@
 package org.opendaylight.groupbasedpolicy.sxp.mapper.impl.listen;
 
 import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 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.groupbasedpolicy.sxp.mapper.api.DSDaoAsync;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSDaoCached;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.api.EPTemplateListener;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.ReadableByKey;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SxpMapperReactor;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.L3EPServiceUtil;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.SxpListenerUtil;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnet;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -35,22 +41,23 @@ import org.slf4j.LoggerFactory;
 public class EPPolicyTemplateListenerImpl implements EPTemplateListener<EndpointPolicyTemplateBySgt> {
 
     private static final Logger LOG = LoggerFactory.getLogger(EPPolicyTemplateListenerImpl.class);
+
+    private static final FutureCallback<List<RpcResult<Void>>> RPC_RESULT_FUTURE_CALLBACK =
+            L3EPServiceUtil.createFailureLoggingCallback("failed to apply epPolicyTemplate");
+
     private final ListenerRegistration<? extends EPTemplateListener> listenerRegistration;
     private final InstanceIdentifier<EndpointPolicyTemplateBySgt> templatePath;
     private final SxpMapperReactor sxpMapperReactor;
-    private final DSDaoCached<Sgt, EndpointPolicyTemplateBySgt> templateCachedDao;
-    private final DSDaoAsync<IpPrefix, MasterDatabaseBinding> masterDBBindingDao;
-    private final DSDaoAsync<IpPrefix, EndpointForwardingTemplateBySubnet> epForwardingTemplateDao;
+    private final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> templateCachedDao;
+    private final ReadableByKey<Sgt, MasterDatabaseBinding> masterDBBindingDao;
 
     public EPPolicyTemplateListenerImpl(final DataBroker dataBroker,
                                         final SxpMapperReactor sxpMapperReactor,
-                                        final DSDaoCached<Sgt, EndpointPolicyTemplateBySgt> templateCachedDao,
-                                        final DSDaoAsync<IpPrefix, MasterDatabaseBinding> masterDBBindingDao,
-                                        final DSDaoAsync<IpPrefix, EndpointForwardingTemplateBySubnet> epForwardingTemplateDao) {
+                                        final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> templateCachedDao,
+                                        final ReadableByKey<Sgt, MasterDatabaseBinding> masterDBBindingDao) {
         this.sxpMapperReactor = Preconditions.checkNotNull(sxpMapperReactor);
         this.templateCachedDao = Preconditions.checkNotNull(templateCachedDao);
         this.masterDBBindingDao = Preconditions.checkNotNull(masterDBBindingDao);
-        this.epForwardingTemplateDao = epForwardingTemplateDao;
         templatePath = EPTemplateListener.SXP_MAPPER_TEMPLATE_PARENT_PATH.child(EndpointPolicyTemplateBySgt.class);
 
         final DataTreeIdentifier<EndpointPolicyTemplateBySgt> dataTreeIdentifier = new DataTreeIdentifier<>(
@@ -63,15 +70,39 @@ public class EPPolicyTemplateListenerImpl implements EPTemplateListener<Endpoint
     public void onDataTreeChanged(@Nonnull final Collection<DataTreeModification<EndpointPolicyTemplateBySgt>> collection) {
         for (DataTreeModification<EndpointPolicyTemplateBySgt> change : collection) {
             LOG.trace("received modification: {} -> {}", change.getRootPath(), change.getRootNode().getModificationType());
+
             // update cached dao
             final InstanceIdentifier<EndpointPolicyTemplateBySgt> changePath = change.getRootPath().getRootIdentifier();
             final Sgt changeKey = changePath.firstKeyOf(EndpointPolicyTemplateBySgt.class).getSgt();
             SxpListenerUtil.updateCachedDao(templateCachedDao, changeKey, change);
 
-            // TODO: sxpMapperReactor.process(template)
+            final EndpointPolicyTemplateBySgt epPolicyTemplate = change.getRootNode().getDataAfter();
+            processWithSxpMasterDB(changeKey, epPolicyTemplate);
         }
     }
 
+    private void processWithSxpMasterDB(final Sgt changeKey, final EndpointPolicyTemplateBySgt epPolicyTemplate) {
+        final ListenableFuture<Collection<MasterDatabaseBinding>> sxpMasterDbItemFuture = masterDBBindingDao.readBy(changeKey);
+        final ListenableFuture<List<RpcResult<Void>>> rpcResult = Futures.transform(sxpMasterDbItemFuture, new AsyncFunction<Collection<MasterDatabaseBinding>, List<RpcResult<Void>>>() {
+            @Override
+            public ListenableFuture<List<RpcResult<Void>>> apply(final Collection<MasterDatabaseBinding> input) throws Exception {
+                if (input == null || input.isEmpty()) {
+                    LOG.debug("no epPolicyTemplate available from sgt: {}", changeKey);
+                    throw new IllegalArgumentException("no epPolicyTemplate available");
+                } else {
+                    LOG.trace("processing sxpMasterDB event and epPolicyTemplate for sgt: {}", changeKey);
+                    List<ListenableFuture<RpcResult<Void>>> allResults = new ArrayList<>(input.size());
+                    for (MasterDatabaseBinding masterDBItem : input) {
+                            allResults.add(sxpMapperReactor.processPolicyAndSxpMasterDB(epPolicyTemplate, masterDBItem));
+                    }
+                    return Futures.successfulAsList(allResults);
+                }
+            }
+        });
+
+        Futures.addCallback(rpcResult, RPC_RESULT_FUTURE_CALLBACK);
+    }
+
     @Override
     public void close() throws Exception {
         LOG.debug("closing listener registration to {}", templatePath);
index 0888693487a715293f9df519be6e500aefb67e56..7a03b45fd5b25223afa3baa2155fa03f41e5cec9 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.groupbasedpolicy.sxp.mapper.impl.listen;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.util.Collection;
@@ -19,10 +20,11 @@ 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.groupbasedpolicy.sxp.mapper.api.DSDaoAsync;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSDaoCached;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSAsyncDao;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.api.MasterDatabaseBindingListener;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SxpMapperReactor;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.L3EPServiceUtil;
 import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.SxpListenerUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnet;
@@ -45,19 +47,25 @@ public class MasterDatabaseBindingListenerImpl implements MasterDatabaseBindingL
 
     private static final Logger LOG = LoggerFactory.getLogger(MasterDatabaseBindingListenerImpl.class);
 
+    private static final FutureCallback<RpcResult<Void>> RPC_POLICY_RESULT_FUTURE_CALLBACK =
+            L3EPServiceUtil.createFailureLoggingCallback("failed to read epPolicyTemplate");
+
+    public static final FutureCallback<RpcResult<Void>> RPC_FW_RESULT_FUTURE_CALLBACK =
+            L3EPServiceUtil.createFailureLoggingCallback("failed to read epForwardingTemplate");
+
     private final SxpMapperReactor sxpMapperReactor;
-    private final DSDaoCached<IpPrefix, MasterDatabaseBinding> masterDBBindingDaoCached;
-    private final DSDaoAsync<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateDao;
-    private final DSDaoAsync<IpPrefix, EndpointForwardingTemplateBySubnet> epForwardingTemplateDao;
+    private final SimpleCachedDao<IpPrefix, MasterDatabaseBinding> masterDBBindingDaoCached;
+    private final DSAsyncDao<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateDao;
+    private final DSAsyncDao<IpPrefix, EndpointForwardingTemplateBySubnet> epForwardingTemplateDao;
 
     private final ListenerRegistration<? extends DataTreeChangeListener> listenerRegistration;
     private final InstanceIdentifier<MasterDatabaseBinding> sxpDbPath;
 
     public MasterDatabaseBindingListenerImpl(final DataBroker dataBroker,
                                              final SxpMapperReactor sxpMapperReactor,
-                                             final DSDaoCached<IpPrefix, MasterDatabaseBinding> masterDBBindingDaoCached,
-                                             final DSDaoAsync<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateDao,
-                                             final DSDaoAsync<IpPrefix, EndpointForwardingTemplateBySubnet> epForwardingTemplateDao) {
+                                             final SimpleCachedDao<IpPrefix, MasterDatabaseBinding> masterDBBindingDaoCached,
+                                             final DSAsyncDao<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateDao,
+                                             final DSAsyncDao<IpPrefix, EndpointForwardingTemplateBySubnet> epForwardingTemplateDao) {
         this.sxpMapperReactor = Preconditions.checkNotNull(sxpMapperReactor);
         this.masterDBBindingDaoCached = Preconditions.checkNotNull(masterDBBindingDaoCached);
         this.epPolicyTemplateDao = Preconditions.checkNotNull(epPolicyTemplateDao);
@@ -104,12 +112,12 @@ public class MasterDatabaseBindingListenerImpl implements MasterDatabaseBindingL
                     LOG.debug("no epForwardingTemplate available for ipPrefix: {}", changeKey);
                     throw new IllegalArgumentException("no epForwardingTemplate available");
                 } else {
-                    // TODO: invoke reactor
-                    return null; //sxpMapperReactor.processForwardingAndSxpMasterDB(input.get(), sxpMasterDBItem);
+                    LOG.trace("processing sxpMasterDB event and epForwardingTemplate for ip-prefix: {}", changeKey);
+                    return sxpMapperReactor.processForwardingAndSxpMasterDB(input.get(), sxpMasterDBItem);
                 }
             }
         });
-        //Futures.addCallback(Futures.successfulAsList(rpcResultBag), RPC_FW_RESULT_FUTURE_CALLBACK);
+        Futures.addCallback(rpcResult, RPC_FW_RESULT_FUTURE_CALLBACK);
     }
 
     private void processWithEPPolicyTemplate(final Sgt changeKey, final MasterDatabaseBinding sxpMasterDBItem) {
@@ -124,13 +132,12 @@ public class MasterDatabaseBindingListenerImpl implements MasterDatabaseBindingL
                     throw new IllegalArgumentException("no epPolicyTemplate available");
                 } else {
                     LOG.trace("processing sxpMasterDB event and epPolicyTemplate for sgt: {}", changeKey);
-                    // TODO: invoke reactor
-                    return null; //sxpMapperReactor.processPolicyAndSxpMasterDB(input.get(), sxpMasterDBItem);
+                    return sxpMapperReactor.processPolicyAndSxpMasterDB(input.get(), sxpMasterDBItem);
                 }
             }
         });
 
-        //Futures.addCallback(rpcResult, RPC_POLICY_RESULT_FUTURE_CALLBACK);
+        Futures.addCallback(rpcResult, RPC_POLICY_RESULT_FUTURE_CALLBACK);
     }
 
     @Override
index 4db3e3dd67ead442a08500f6223948ef9577b9d0..e513e42bfcb05613cb712242001df74ab41b1b56 100644 (file)
@@ -14,15 +14,19 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 /**
  * Purpose: util methods for {@link org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnet}
  */
-public class ForwardingTemplateUtil {
+public final class ForwardingTemplateUtil {
 
     public static final String FULL_IPV4_MASK_SUFFIX = "/32";
 
+    private ForwardingTemplateUtil() {
+        throw new IllegalAccessError("constructing util class");
+    }
+
     public static boolean isPlain(final IpPrefix key) {
         return key.getIpv4Prefix().getValue().endsWith(FULL_IPV4_MASK_SUFFIX);
     }
 
-    public static SubnetUtils.SubnetInfo buildSubnetInfo(@Nonnull final IpPrefix value) {
-        return new SubnetUtils(value.getIpv4Prefix().getValue()).getInfo();
+    public static SubnetInfoKeyDecorator buildSubnetInfoKey(@Nonnull final IpPrefix value) {
+        return new SubnetInfoKeyDecorator(new SubnetUtils(value.getIpv4Prefix().getValue()).getInfo());
     }
 }
diff --git a/sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/util/IpPrefixEqualCommandDirectImpl.java b/sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/util/IpPrefixEqualCommandDirectImpl.java
new file mode 100644 (file)
index 0000000..6538124
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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.sxp.mapper.impl.util;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.IpPrefixEqualCommand;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+
+/**
+ * Purpose: provide simple equal using direct invocation of {@link Object#equals(Object)} method
+ */
+public class IpPrefixEqualCommandDirectImpl implements IpPrefixEqualCommand {
+    private final IpPrefix myValue;
+
+    public IpPrefixEqualCommandDirectImpl(@Nonnull final IpPrefix myValue) {
+        this.myValue = myValue;
+    }
+
+    @Override
+    public boolean isEqualTo(final IpPrefix value) {
+        return myValue.equals(value);
+    }
+}
diff --git a/sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/util/IpPrefixEqualCommandSubnetImpl.java b/sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/util/IpPrefixEqualCommandSubnetImpl.java
new file mode 100644 (file)
index 0000000..e6442a8
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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.sxp.mapper.impl.util;
+
+import javax.annotation.Nonnull;
+import org.apache.commons.net.util.SubnetUtils;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.IpPrefixEqualCommand;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+
+/**
+ * Purpose: provide equal using {@link SubnetUtils.SubnetInfo#isInRange(String)} method
+ */
+public class IpPrefixEqualCommandSubnetImpl implements IpPrefixEqualCommand {
+    private final SubnetUtils.SubnetInfo myValue;
+
+    public IpPrefixEqualCommandSubnetImpl(@Nonnull final IpPrefix myValue) {
+        this.myValue = new SubnetUtils(stripToCidr(myValue)).getInfo();
+    }
+
+    @Override
+    public boolean isEqualTo(final IpPrefix value) {
+        return myValue.isInRange(stripToCidr(value));
+    }
+
+    private String stripToCidr(final IpPrefix value) {
+        return value.getIpv4Prefix().getValue();
+    }
+}
diff --git a/sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/util/L3EPServiceUtil.java b/sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/util/L3EPServiceUtil.java
new file mode 100644 (file)
index 0000000..622f747
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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.sxp.mapper.impl.util;
+
+import com.google.common.util.concurrent.FutureCallback;
+import javax.annotation.Nullable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Purpose: TODO!
+ */
+public final class L3EPServiceUtil {
+
+    private static final Logger LOG = LoggerFactory.getLogger(L3EPServiceUtil.class);
+
+    private L3EPServiceUtil() {
+        throw new IllegalAccessError("constructing util class");
+    }
+
+    public static <O> FutureCallback<O> createFailureLoggingCallback(final String failMessage) {
+        return new FutureCallback<O>() {
+            @Override
+            public void onSuccess(@Nullable final O result) {
+                // NOOP
+            }
+
+            @Override
+            public void onFailure(final Throwable t) {
+                LOG.warn(failMessage, t);
+            }
+        };
+    }
+
+}
diff --git a/sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/util/SubnetInfoKeyDecorator.java b/sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/util/SubnetInfoKeyDecorator.java
new file mode 100644 (file)
index 0000000..3fae07e
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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.sxp.mapper.impl.util;
+
+import org.apache.commons.net.util.SubnetUtils;
+
+/**
+ * Purpose: wraps {@link SubnetUtils.SubnetInfo} and overwrites hashcode and equals methods in order to
+ * be applicable as map key
+ *
+ */
+public class SubnetInfoKeyDecorator {
+
+    private final SubnetUtils.SubnetInfo delegate;
+
+    public SubnetInfoKeyDecorator(final SubnetUtils.SubnetInfo delegate) {
+        this.delegate = delegate;
+    }
+
+    public SubnetUtils.SubnetInfo getDelegate() {
+        return delegate;
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        final SubnetInfoKeyDecorator that = (SubnetInfoKeyDecorator) o;
+
+        return delegate.getCidrSignature().equals(that.delegate.getCidrSignature());
+
+    }
+
+    @Override
+    public int hashCode() {
+        return delegate.getCidrSignature().hashCode();
+    }
+}
index 83ca3ff909255052df4dd4b31c2c41f42724e69c..de874fc0f32d1f415830d0fdf2a16eab2a9e950e 100644 (file)
@@ -12,14 +12,20 @@ import com.google.common.util.concurrent.FutureCallback;
 import javax.annotation.Nullable;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSDaoCached;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 
 /**
  * Purpose: provide general logic used by listeners
  */
-public class SxpListenerUtil {
-    public static <K, V extends DataObject> void updateCachedDao(final DSDaoCached<K, V> valueCachedDao,
+public final class SxpListenerUtil {
+
+    private SxpListenerUtil() {
+        throw new IllegalAccessError("constructing util class");
+    }
+
+
+    public static <K, V extends DataObject> void updateCachedDao(final SimpleCachedDao<K, V> valueCachedDao,
                                                                  final K key,
                                                                  final DataTreeModification<V> change) {
         final V value = change.getRootNode().getDataAfter();
diff --git a/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/SxpMapperReactorImplTest.java b/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/SxpMapperReactorImplTest.java
new file mode 100644 (file)
index 0000000..3c7af75
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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.sxp.mapper.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+
+/**
+ * Test for {@link SxpMapperReactorImpl}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class SxpMapperReactorImplTest {
+
+    @Mock
+    private EndpointService l3EndpointService;
+    @Mock
+    private EndpointPolicyTemplateBySgt epPolicyTemplate;
+    @Mock
+    private MasterDatabaseBinding masterDBBinding;
+    @Mock
+    private EndpointForwardingTemplateBySubnet epForwardingTemplate;
+
+    private SxpMapperReactorImpl sxpMapperReactor;
+
+    @Before
+    public void setUp() throws Exception {
+        sxpMapperReactor = new SxpMapperReactorImpl(l3EndpointService);
+        Mockito.when(l3EndpointService.registerEndpoint(Matchers.<RegisterEndpointInput>any()))
+                .thenReturn(RpcResultBuilder.<Void>success().buildFuture());
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        Mockito.verifyNoMoreInteractions(l3EndpointService);
+    }
+
+    @Test
+    public void testProcessPolicyAndSxpMasterDB() throws Exception {
+        sxpMapperReactor.processPolicyAndSxpMasterDB(epPolicyTemplate, masterDBBinding);
+        Mockito.verify(l3EndpointService).registerEndpoint(Matchers.<RegisterEndpointInput>any());
+    }
+
+    @Test
+    public void testProcessForwardingAndSxpMasterDB() throws Exception {
+        sxpMapperReactor.processForwardingAndSxpMasterDB(epForwardingTemplate, masterDBBinding);
+        Mockito.verify(l3EndpointService).registerEndpoint(Matchers.<RegisterEndpointInput>any());
+    }
+}
\ No newline at end of file
diff --git a/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/EPForwardingTemplateDaoImplTest.java b/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/EPForwardingTemplateDaoImplTest.java
new file mode 100644 (file)
index 0000000..e1ee8a2
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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.sxp.mapper.impl.dao;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.SxpMapper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.SxpMapperBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnetBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Test for {@link EPForwardingTemplateDaoImpl}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class EPForwardingTemplateDaoImplTest {
+
+    public static final InstanceIdentifier<SxpMapper> SXP_MAPPER_PATH = InstanceIdentifier.create(SxpMapper.class);
+    private static final IpPrefix KEY_1 = new IpPrefix(new Ipv4Prefix("1.2.3.4/32"));
+    private final SxpMapper SXP_MAPPER_VALUE;
+    private final EndpointForwardingTemplateBySubnet EP_FW_TEMPLATE_VALUE;
+
+    @Mock
+    private DataBroker dataBroker;
+    @Mock
+    private SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> cachedDao;
+    @Mock
+    private ReadOnlyTransaction rTx;
+
+    private EPForwardingTemplateDaoImpl dao;
+
+    public EPForwardingTemplateDaoImplTest() {
+        EP_FW_TEMPLATE_VALUE = new EndpointForwardingTemplateBySubnetBuilder()
+                .setIpPrefix(KEY_1)
+                .build();
+        SXP_MAPPER_VALUE = new SxpMapperBuilder()
+                .setEndpointForwardingTemplateBySubnet(Lists.newArrayList(EP_FW_TEMPLATE_VALUE))
+                .build();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        dao = new EPForwardingTemplateDaoImpl(dataBroker, cachedDao);
+    }
+
+    @Test
+    public void testRead_absent() throws Exception {
+        Mockito.when(cachedDao.find(Matchers.<IpPrefix>any())).thenReturn(Optional.<EndpointForwardingTemplateBySubnet>absent());
+        Mockito.when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx);
+        Mockito.when(rTx.read(Matchers.eq(LogicalDatastoreType.CONFIGURATION),
+                Matchers.<InstanceIdentifier<SxpMapper>>any())).thenReturn(
+                Futures.<Optional<SxpMapper>, ReadFailedException>immediateCheckedFuture(Optional.<SxpMapper>absent()));
+
+
+        final ListenableFuture<Optional<EndpointForwardingTemplateBySubnet>> read = dao.read(KEY_1);
+        Assert.assertTrue(read.isDone());
+        Assert.assertFalse(read.get().isPresent());
+    }
+
+    @Test
+    public void testRead_presentCached() throws Exception {
+        Mockito.when(cachedDao.find(Matchers.<IpPrefix>any())).thenReturn(Optional.of(EP_FW_TEMPLATE_VALUE));
+
+        final ListenableFuture<Optional<EndpointForwardingTemplateBySubnet>> read = dao.read(KEY_1);
+        Assert.assertTrue(read.isDone());
+        Assert.assertTrue(read.get().isPresent());
+        Assert.assertEquals(KEY_1, read.get().get().getIpPrefix());
+    }
+
+    @Test
+    public void testRead_presentDS() throws Exception {
+        Mockito.when(cachedDao.find(Matchers.<IpPrefix>any())).thenReturn(
+                Optional.<EndpointForwardingTemplateBySubnet>absent(),
+                Optional.of(EP_FW_TEMPLATE_VALUE));
+        Mockito.when(cachedDao.isEmpty()).thenReturn(true, false);
+        Mockito.when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx);
+        Mockito.when(rTx.read(Matchers.eq(LogicalDatastoreType.CONFIGURATION),
+                Matchers.<InstanceIdentifier<SxpMapper>>any())).thenReturn(
+                Futures.<Optional<SxpMapper>, ReadFailedException>immediateCheckedFuture(Optional.of(SXP_MAPPER_VALUE)));
+
+        final ListenableFuture<Optional<EndpointForwardingTemplateBySubnet>> read = dao.read(KEY_1);
+        Assert.assertTrue(read.isDone());
+        Assert.assertTrue(read.get().isPresent());
+        Assert.assertEquals(KEY_1, read.get().get().getIpPrefix());
+
+        final InOrder inOrder = Mockito.inOrder(cachedDao);
+        inOrder.verify(cachedDao).invalidateCache();
+        inOrder.verify(cachedDao).update(KEY_1, EP_FW_TEMPLATE_VALUE);
+        inOrder.verify(cachedDao).find(KEY_1);
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    @Test
+    public void testBuildReadPath() throws Exception {
+        final InstanceIdentifier<SxpMapper> readPath = dao.buildReadPath(KEY_1);
+        Assert.assertEquals(SXP_MAPPER_PATH, readPath);
+    }
+}
\ No newline at end of file
diff --git a/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/EPPolicyTemplateDaoImplTest.java b/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/EPPolicyTemplateDaoImplTest.java
new file mode 100644 (file)
index 0000000..a15a98b
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * 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.sxp.mapper.impl.dao;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.SxpMapper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgtBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgtKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+
+/**
+ * Test for {@link EPPolicyTemplateDaoImpl}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class EPPolicyTemplateDaoImplTest {
+
+    private static final Sgt KEY_1 = new Sgt(1);
+    private final EndpointPolicyTemplateBySgt EP_POLICY_TEMPLATE_VALUE;
+    @Mock
+    private DataBroker dataBroker;
+    @Mock
+    private SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> cachedDao;
+    @Mock
+    private ReadOnlyTransaction rTx;
+
+    private EPPolicyTemplateDaoImpl dao;
+
+    public EPPolicyTemplateDaoImplTest() {
+        EP_POLICY_TEMPLATE_VALUE = new EndpointPolicyTemplateBySgtBuilder()
+                .setSgt(KEY_1)
+                .build();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        dao = new EPPolicyTemplateDaoImpl(dataBroker, cachedDao);
+    }
+
+    @Test
+    public void testRead_absent() throws Exception {
+        Mockito.when(cachedDao.find(Matchers.<Sgt>any())).thenReturn(Optional.<EndpointPolicyTemplateBySgt>absent());
+        Mockito.when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx);
+        Mockito.when(rTx.read(Matchers.eq(LogicalDatastoreType.CONFIGURATION),
+                Matchers.<InstanceIdentifier<EndpointPolicyTemplateBySgt>>any())).thenReturn(
+                Futures.<Optional<EndpointPolicyTemplateBySgt>, ReadFailedException>immediateCheckedFuture(
+                        Optional.<EndpointPolicyTemplateBySgt>absent()));
+
+
+        final ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> read = dao.read(KEY_1);
+        Assert.assertTrue(read.isDone());
+        Assert.assertFalse(read.get().isPresent());
+    }
+
+    @Test
+    public void testRead_presentCached() throws Exception {
+        Mockito.when(cachedDao.find(Matchers.<Sgt>any())).thenReturn(Optional.of(EP_POLICY_TEMPLATE_VALUE));
+
+        final ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> read = dao.read(KEY_1);
+        Assert.assertTrue(read.isDone());
+        Assert.assertTrue(read.get().isPresent());
+        Assert.assertEquals(KEY_1, read.get().get().getSgt());
+    }
+
+    @Test
+    public void testRead_presentDS() throws Exception {
+        Mockito.when(cachedDao.find(Matchers.<Sgt>any())).thenReturn(
+                Optional.<EndpointPolicyTemplateBySgt>absent());
+        Mockito.when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx);
+        Mockito.when(rTx.read(Matchers.eq(LogicalDatastoreType.CONFIGURATION),
+                Matchers.<InstanceIdentifier<EndpointPolicyTemplateBySgt>>any())).thenReturn(
+                Futures.<Optional<EndpointPolicyTemplateBySgt>, ReadFailedException>immediateCheckedFuture(
+                        Optional.of(EP_POLICY_TEMPLATE_VALUE)));
+
+        final ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> read = dao.read(KEY_1);
+        Assert.assertTrue(read.isDone());
+        Assert.assertTrue(read.get().isPresent());
+        Assert.assertEquals(KEY_1, read.get().get().getSgt());
+
+        final InOrder inOrder = Mockito.inOrder(cachedDao);
+        inOrder.verify(cachedDao).update(KEY_1, EP_POLICY_TEMPLATE_VALUE);
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    @Test
+    public void testBuildReadPath() throws Exception {
+        final KeyedInstanceIdentifier<EndpointPolicyTemplateBySgt, EndpointPolicyTemplateBySgtKey> expectedPath =
+                InstanceIdentifier.create(SxpMapper.class)
+                        .child(EndpointPolicyTemplateBySgt.class, new EndpointPolicyTemplateBySgtKey(KEY_1));
+
+        final InstanceIdentifier<EndpointPolicyTemplateBySgt> readPath = dao.buildReadPath(KEY_1);
+        Assert.assertEquals(expectedPath, readPath);
+    }
+}
\ No newline at end of file
diff --git a/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/MasterDatabaseBindingDaoImplTest.java b/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/MasterDatabaseBindingDaoImplTest.java
new file mode 100644 (file)
index 0000000..024e161
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * 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.sxp.mapper.impl.dao;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Collection;
+import java.util.Collections;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
+import org.opendaylight.sxp.core.Configuration;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBindingBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.SxpNodeIdentity;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.SxpNodeIdentityBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.sxp.databases.fields.MasterDatabaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Test for {@link MasterDatabaseBindingDaoImpl}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class MasterDatabaseBindingDaoImplTest {
+
+    private static final Sgt KEY_1 = new Sgt(1);
+    private static final IpPrefix IP_PREFIX = new IpPrefix(new Ipv4Prefix("1.2.3.4/32"));
+    private final Topology TOPOLOGY_VALUE;
+    private final MasterDatabaseBinding MASTER_DB_BINDING_VALUE;
+
+    @Mock
+    private DataBroker dataBroker;
+    @Mock
+    private SimpleCachedDao<IpPrefix, MasterDatabaseBinding> cachedDao;
+    @Mock
+    private ReadOnlyTransaction rTx;
+
+    private MasterDatabaseBindingDaoImpl dao;
+
+    public MasterDatabaseBindingDaoImplTest() {
+        MASTER_DB_BINDING_VALUE = new MasterDatabaseBindingBuilder()
+                .setSecurityGroupTag(KEY_1)
+                .setIpPrefix(IP_PREFIX)
+                .build();
+
+        TOPOLOGY_VALUE = new TopologyBuilder()
+                .setTopologyId(new TopologyId(Configuration.TOPOLOGY_NAME))
+                .setNode(Lists.newArrayList(new NodeBuilder()
+                        .setNodeId(new NodeId("utNodeId"))
+                        .addAugmentation(SxpNodeIdentity.class, new SxpNodeIdentityBuilder()
+                                .setMasterDatabase(new MasterDatabaseBuilder()
+                                        .setMasterDatabaseBinding(Lists.newArrayList(MASTER_DB_BINDING_VALUE))
+                                        .build())
+                                .build())
+                        .build()))
+                .build();
+    }
+
+
+    @Before
+    public void setUp() throws Exception {
+        dao = new MasterDatabaseBindingDaoImpl(dataBroker, cachedDao);
+    }
+
+    @Test
+    public void testRead_absent() throws Exception {
+        Mockito.when(cachedDao.find(Matchers.<IpPrefix>any())).thenReturn(Optional.<MasterDatabaseBinding>absent());
+        Mockito.when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx);
+        Mockito.when(rTx.read(Matchers.eq(LogicalDatastoreType.CONFIGURATION),
+                Matchers.<InstanceIdentifier<Topology>>any())).thenReturn(
+                Futures.<Optional<Topology>, ReadFailedException>immediateCheckedFuture(
+                        Optional.<Topology>absent()));
+
+
+        final ListenableFuture<Optional<MasterDatabaseBinding>> read = dao.read(IP_PREFIX);
+        Assert.assertTrue(read.isDone());
+        Assert.assertFalse(read.get().isPresent());
+    }
+
+    @Test
+    public void testRead_presentCached() throws Exception {
+        Mockito.when(cachedDao.find(Matchers.<IpPrefix>any())).thenReturn(Optional.of(MASTER_DB_BINDING_VALUE));
+
+        final ListenableFuture<Optional<MasterDatabaseBinding>> read = dao.read(IP_PREFIX);
+        Assert.assertTrue(read.isDone());
+        Assert.assertTrue(read.get().isPresent());
+        Assert.assertEquals(KEY_1, read.get().get().getSecurityGroupTag());
+    }
+
+    @Test
+    public void testRead_presentDS() throws Exception {
+        Mockito.when(cachedDao.find(Matchers.<IpPrefix>any())).thenReturn(
+                Optional.<MasterDatabaseBinding>absent(),
+                Optional.of(MASTER_DB_BINDING_VALUE));
+        Mockito.when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx);
+        Mockito.when(rTx.read(Matchers.eq(LogicalDatastoreType.CONFIGURATION),
+                Matchers.<InstanceIdentifier<Topology>>any())).thenReturn(
+                Futures.<Optional<Topology>, ReadFailedException>immediateCheckedFuture(
+                        Optional.of(TOPOLOGY_VALUE)));
+
+        final ListenableFuture<Optional<MasterDatabaseBinding>> read = dao.read(IP_PREFIX);
+        Assert.assertTrue(read.isDone());
+        Assert.assertTrue(read.get().isPresent());
+        Assert.assertEquals(KEY_1, read.get().get().getSecurityGroupTag());
+
+        final InOrder inOrder = Mockito.inOrder(cachedDao);
+        inOrder.verify(cachedDao).invalidateCache();
+        inOrder.verify(cachedDao).update(IP_PREFIX, MASTER_DB_BINDING_VALUE);
+        inOrder.verify(cachedDao).find(IP_PREFIX);
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    @Test
+    public void testReadBy() throws Exception {
+        Mockito.when(cachedDao.isEmpty()).thenReturn(false);
+        Mockito.when(cachedDao.values()).thenReturn(Collections.singleton(MASTER_DB_BINDING_VALUE));
+
+        final ListenableFuture<Collection<MasterDatabaseBinding>> readByFt = dao.readBy(KEY_1);
+        Assert.assertTrue(readByFt.isDone());
+        Assert.assertEquals(1, readByFt.get().size());
+    }
+}
\ No newline at end of file
diff --git a/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/SimpleCachedDaoEPForwardingTemplateImplTest.java b/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/SimpleCachedDaoEPForwardingTemplateImplTest.java
new file mode 100644 (file)
index 0000000..cddce65
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 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.sxp.mapper.impl.dao;
+
+import com.google.common.collect.Iterables;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnetBuilder;
+
+/**
+ * Test for {@link SimpleCachedDaoEPForwardingTemplateImpl}.
+ */
+public class SimpleCachedDaoEPForwardingTemplateImplTest {
+
+    private static final IpPrefix IP_PREFIX_1 = buildIpPrefix("1.2.3.0/24");
+
+
+    private static final IpPrefix IP_PREFIX_2 = buildIpPrefix("1.2.3.4/32");
+
+    private SimpleCachedDaoEPForwardingTemplateImpl dao;
+
+    @Before
+    public void setUp() throws Exception {
+        dao = new SimpleCachedDaoEPForwardingTemplateImpl();
+        Assert.assertTrue(dao.isEmpty());
+    }
+
+    @Test
+    public void testUpdate() throws Exception {
+        dao.update(IP_PREFIX_1, buildValue(IP_PREFIX_1));
+        dao.update(IP_PREFIX_2, buildValue(IP_PREFIX_2));
+
+        Assert.assertEquals(2, Iterables.size(dao.values()));
+    }
+
+    private EndpointForwardingTemplateBySubnet buildValue(final IpPrefix ipPrefix) {
+        return new EndpointForwardingTemplateBySubnetBuilder()
+                .setIpPrefix(ipPrefix)
+                .build();
+    }
+
+    @Test
+    public void testFind() throws Exception {
+        final EndpointForwardingTemplateBySubnet value1 = buildValue(IP_PREFIX_1);
+        final EndpointForwardingTemplateBySubnet value2 = buildValue(IP_PREFIX_2);
+        dao.update(IP_PREFIX_1, value1);
+        dao.update(IP_PREFIX_2, value2);
+        Assert.assertFalse(dao.isEmpty());
+
+        Assert.assertTrue(dao.find(IP_PREFIX_1).isPresent());
+        Assert.assertEquals(value1, dao.find(IP_PREFIX_1).get());
+        Assert.assertTrue(dao.find(IP_PREFIX_2).isPresent());
+        Assert.assertEquals(value2, dao.find(IP_PREFIX_2).get());
+
+        final IpPrefix key = buildIpPrefix("1.2.3.1/32");
+        Assert.assertTrue(dao.find(key).isPresent());
+        Assert.assertEquals(value1, dao.find(key).get());
+    }
+
+    private static IpPrefix buildIpPrefix(final String ipv4PrefixValue) {
+        return new IpPrefix(new Ipv4Prefix(ipv4PrefixValue));
+    }
+
+    @Test
+    public void testInvalidateCache() throws Exception {
+        dao.update(IP_PREFIX_1, buildValue(IP_PREFIX_1));
+        dao.update(IP_PREFIX_2, buildValue(IP_PREFIX_2));
+
+        Assert.assertEquals(2, Iterables.size(dao.values()));
+        dao.invalidateCache();
+        Assert.assertTrue(dao.isEmpty());
+    }
+}
\ No newline at end of file
diff --git a/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/SimpleCachedDaoImplTest.java b/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/dao/SimpleCachedDaoImplTest.java
new file mode 100644 (file)
index 0000000..c66d366
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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.sxp.mapper.impl.dao;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Test for {@link SimpleCachedDaoImpl}.
+ */
+public class SimpleCachedDaoImplTest {
+
+    private static final String KEY_1 = "dummyKey1";
+    private static final String KEY_2 = "dummyKey2";
+    private static final DummyDataObject DUMMY_DATA_1 = new DummyDataObject("dummyData1");
+    private static final DummyDataObject DUMMY_DATA_2 = new DummyDataObject("dummyData2");
+
+    private SimpleCachedDaoImpl<String, DummyDataObject> dao;
+
+    @Before
+    public void setUp() throws Exception {
+        dao = new SimpleCachedDaoImpl<>();
+        Assert.assertFalse(dao.find(KEY_1).isPresent());
+    }
+
+    @Test
+    public void testUpdate() throws Exception {
+        dao.update(KEY_1, DUMMY_DATA_1);
+        final Optional<DummyDataObject> dataOpt = dao.find(KEY_1);
+        Assert.assertTrue(dataOpt.isPresent());
+        Assert.assertEquals(DUMMY_DATA_1.getDummyData(), dataOpt.get().getDummyData());
+    }
+
+    @Test
+    public void testInvalidateCache() throws Exception {
+        dao.update(KEY_1, DUMMY_DATA_1);
+        Assert.assertTrue(dao.find(KEY_1).isPresent());
+        dao.invalidateCache();
+        Assert.assertFalse(dao.find(KEY_1).isPresent());
+    }
+
+    @Test
+    public void testIsEmpty() throws Exception {
+        Assert.assertTrue(dao.isEmpty());
+        dao.update(KEY_1, DUMMY_DATA_1);
+        Assert.assertFalse(dao.isEmpty());
+    }
+
+    @Test
+    public void testValues() throws Exception {
+        Assert.assertEquals(0, Iterables.size(dao.values()));
+        dao.update(KEY_1, DUMMY_DATA_1);
+        dao.update(KEY_1, DUMMY_DATA_2);
+        Assert.assertEquals(1, Iterables.size(dao.values()));
+
+        dao.update(KEY_2, DUMMY_DATA_2);
+        Assert.assertEquals(2, Iterables.size(dao.values()));
+    }
+
+    private static final class DummyDataObject implements DataObject {
+        private final String dummyData;
+
+        public DummyDataObject(final String dummyData) {
+            this.dummyData = dummyData;
+        }
+
+        public String getDummyData() {
+            return dummyData;
+        }
+
+        @Override
+        public Class<? extends DataContainer> getImplementedInterface() {
+            return getClass();
+        }
+    }
+}
\ No newline at end of file
diff --git a/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/listen/EPForwardingTemplateListenerImplTest.java b/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/listen/EPForwardingTemplateListenerImplTest.java
new file mode 100644 (file)
index 0000000..7dd05f3
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * 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.sxp.mapper.impl.listen;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+import java.util.Collections;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+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.groupbasedpolicy.sxp.mapper.api.DSAsyncDao;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.EPTemplateListener;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SxpMapperReactor;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnetKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBindingBuilder;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+
+/**
+ * Test for {@link EPForwardingTemplateListenerImpl}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class EPForwardingTemplateListenerImplTest {
+
+    private static final IpPrefix IP_PREFIX_TMPL = buildIpPrefix("1.2.3.0/24");
+    private static final EndpointForwardingTemplateBySubnetKey EP_FW_TEMPLATE_KEY =
+            new EndpointForwardingTemplateBySubnetKey(IP_PREFIX_TMPL);
+    private static final KeyedInstanceIdentifier<EndpointForwardingTemplateBySubnet, EndpointForwardingTemplateBySubnetKey> EP_FW_TEMPLATE_PATH =
+            EPTemplateListener.SXP_MAPPER_TEMPLATE_PARENT_PATH
+                    .child(EndpointForwardingTemplateBySubnet.class, EP_FW_TEMPLATE_KEY);
+    private static final DataTreeIdentifier<EndpointForwardingTemplateBySubnet> TEMPLATE_TREE_PATH =
+            new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, EP_FW_TEMPLATE_PATH);
+    private final EndpointForwardingTemplateBySubnet EP_FW_TEMPLATE_VALUE;
+
+
+    @Mock
+    private DataBroker dataBroker;
+    @Mock
+    private SxpMapperReactor sxpMapper;
+    @Mock
+    private SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> simpleCachedDao;
+    @Mock
+    private DSAsyncDao<IpPrefix, MasterDatabaseBinding> masterDBBindingDao;
+    @Mock
+    private ListenerRegistration<? extends EPTemplateListener> listenerRegistration;
+    @Mock
+    private DataTreeModification<EndpointForwardingTemplateBySubnet> dataTreeModification;
+    @Mock
+    private DataObjectModification<EndpointForwardingTemplateBySubnet> dataObjectModification;
+
+    private EPForwardingTemplateListenerImpl listener;
+
+    public EPForwardingTemplateListenerImplTest() {
+        EP_FW_TEMPLATE_VALUE = new EndpointForwardingTemplateBySubnetBuilder()
+                .setIpPrefix(IP_PREFIX_TMPL)
+                .build();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        Mockito.when(dataBroker.registerDataTreeChangeListener(Matchers.<DataTreeIdentifier>any(),
+                Matchers.<DataTreeChangeListener>any())).thenReturn(listenerRegistration);
+        listener = new EPForwardingTemplateListenerImpl(dataBroker, sxpMapper, simpleCachedDao, masterDBBindingDao);
+    }
+
+    @Test
+    public void testOnDataTreeChanged() throws Exception {
+        Mockito.when(dataTreeModification.getRootNode()).thenReturn(dataObjectModification);
+        Mockito.when(dataTreeModification.getRootPath()).thenReturn(TEMPLATE_TREE_PATH);
+        Mockito.when(dataObjectModification.getDataAfter()).thenReturn(EP_FW_TEMPLATE_VALUE);
+
+        final Sgt sgt = new Sgt(1);
+        final IpPrefix ipPrefix = buildIpPrefix("1.2.3.4/32");
+        final MasterDatabaseBinding prefixGroup = new MasterDatabaseBindingBuilder()
+                .setSecurityGroupTag(sgt)
+                .setIpPrefix(ipPrefix)
+                .build();
+        Mockito.when(masterDBBindingDao.read(Matchers.<IpPrefix>any())).thenReturn(
+                Futures.immediateFuture(Optional.of(prefixGroup)));
+
+        listener.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+        final InOrder inOrder = Mockito.inOrder(masterDBBindingDao, simpleCachedDao, sxpMapper);
+        inOrder.verify(simpleCachedDao).update(IP_PREFIX_TMPL, EP_FW_TEMPLATE_VALUE);
+        inOrder.verify(masterDBBindingDao).read(IP_PREFIX_TMPL);
+        inOrder.verify(sxpMapper).processForwardingAndSxpMasterDB(EP_FW_TEMPLATE_VALUE, prefixGroup);
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    private static IpPrefix buildIpPrefix(final String ipv4PrefixValue) {
+        return new IpPrefix(new Ipv4Prefix(ipv4PrefixValue));
+    }
+
+    @Test
+    public void testClose() throws Exception {
+        Mockito.verify(listenerRegistration, Mockito.never()).close();
+        listener.close();
+        Mockito.verify(listenerRegistration).close();
+    }
+}
\ No newline at end of file
diff --git a/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/listen/EPPolicyTemplateListenerImplTest.java b/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/listen/EPPolicyTemplateListenerImplTest.java
new file mode 100644 (file)
index 0000000..81fe8d0
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * 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.sxp.mapper.impl.listen;
+
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Futures;
+import java.util.Collections;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+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.groupbasedpolicy.sxp.mapper.api.EPTemplateListener;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.ReadableByKey;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SxpMapperReactor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgtBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgtKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBindingBuilder;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+
+/**
+ * Test for {@link EPPolicyTemplateListenerImpl}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class EPPolicyTemplateListenerImplTest {
+
+    private static final Sgt SGT_1 = new Sgt(1);
+    private static final KeyedInstanceIdentifier<EndpointPolicyTemplateBySgt, EndpointPolicyTemplateBySgtKey> EP_PL_TEMPLATE_PATH =
+            EPTemplateListener.SXP_MAPPER_TEMPLATE_PARENT_PATH
+                    .child(EndpointPolicyTemplateBySgt.class, new EndpointPolicyTemplateBySgtKey(SGT_1));
+    private static final DataTreeIdentifier<EndpointPolicyTemplateBySgt> TEMPLATE_TREE_PATH =
+            new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, EP_PL_TEMPLATE_PATH);
+    private final EndpointPolicyTemplateBySgt EP_PL_TEMPLATE_VALUE;
+
+    @Mock
+    private DataBroker dataBroker;
+    @Mock
+    private SxpMapperReactor sxpMapper;
+    @Mock
+    private SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> simpleCachedDao;
+    @Mock
+    private ReadableByKey<Sgt, MasterDatabaseBinding> masterDBDao;
+    @Mock
+    private ListenerRegistration<? extends EPTemplateListener> listenerRegistration;
+    @Mock
+    private DataTreeModification<EndpointPolicyTemplateBySgt> dataTreeModification;
+    @Mock
+    private DataObjectModification<EndpointPolicyTemplateBySgt> dataObjectModification;
+
+    private EPPolicyTemplateListenerImpl listener;
+
+    public EPPolicyTemplateListenerImplTest() {
+        EP_PL_TEMPLATE_VALUE = new EndpointPolicyTemplateBySgtBuilder()
+                .setSgt(SGT_1)
+                .build();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        Mockito.when(dataBroker.registerDataTreeChangeListener(Matchers.<DataTreeIdentifier>any(),
+                Matchers.<DataTreeChangeListener>any())).thenReturn(listenerRegistration);
+        listener = new EPPolicyTemplateListenerImpl(dataBroker, sxpMapper, simpleCachedDao, masterDBDao);
+    }
+
+    @Test
+    public void testOnDataTreeChanged() throws Exception {
+        Mockito.when(dataTreeModification.getRootNode()).thenReturn(dataObjectModification);
+        Mockito.when(dataTreeModification.getRootPath()).thenReturn(TEMPLATE_TREE_PATH);
+        Mockito.when(dataObjectModification.getDataAfter()).thenReturn(EP_PL_TEMPLATE_VALUE);
+
+        final MasterDatabaseBinding masterDBBinding = new MasterDatabaseBindingBuilder()
+                .setSecurityGroupTag(SGT_1)
+                .build();
+        Mockito.when(masterDBDao.readBy(Matchers.<Sgt>any())).thenReturn(
+                Futures.immediateFuture(Lists.newArrayList(masterDBBinding)));
+
+        listener.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+        final InOrder inOrder = Mockito.inOrder(masterDBDao, simpleCachedDao, sxpMapper);
+        inOrder.verify(simpleCachedDao).update(SGT_1, EP_PL_TEMPLATE_VALUE);
+        inOrder.verify(masterDBDao).readBy(SGT_1);
+        inOrder.verify(sxpMapper).processPolicyAndSxpMasterDB(EP_PL_TEMPLATE_VALUE, masterDBBinding);
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    @Test
+    public void testClose() throws Exception {
+        Mockito.verify(listenerRegistration, Mockito.never()).close();
+        listener.close();
+        Mockito.verify(listenerRegistration).close();
+    }
+}
\ No newline at end of file
diff --git a/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/listen/MasterDatabaseBindingListenerImplTest.java b/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/listen/MasterDatabaseBindingListenerImplTest.java
new file mode 100644 (file)
index 0000000..fb77dd7
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * 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.sxp.mapper.impl.listen;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+import java.util.Collections;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+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.groupbasedpolicy.sxp.mapper.api.DSAsyncDao;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.EPTemplateListener;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.MasterDatabaseBindingListener;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SxpMapperReactor;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgtBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBindingBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBindingKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.SxpNodeIdentity;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.sxp.databases.fields.MasterDatabase;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+
+/**
+ * Test for {@link MasterDatabaseBindingListenerImpl}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class MasterDatabaseBindingListenerImplTest {
+
+    private static final Sgt SGT_1 = new Sgt(1);
+    private static final IpPrefix IP_PREFIX = new IpPrefix(new Ipv4Prefix("1.2.3.4/32"));
+    private static final KeyedInstanceIdentifier<MasterDatabaseBinding, MasterDatabaseBindingKey> MASTER_DB_PATH =
+            MasterDatabaseBindingListener.SXP_TOPOLOGY_PATH
+                    .child(Node.class, new NodeKey(new NodeId("utNodeId")))
+                    .augmentation(SxpNodeIdentity.class)
+                    .child(MasterDatabase.class)
+                    .child(MasterDatabaseBinding.class, new MasterDatabaseBindingKey(IP_PREFIX));
+    private static final DataTreeIdentifier<MasterDatabaseBinding> MASTER_DB_BINDING_TREE_PATH =
+            new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, MASTER_DB_PATH);
+    private final MasterDatabaseBinding MASTER_DB_BINDING_VALUE;
+
+    @Mock
+    private DataBroker dataBroker;
+    @Mock
+    private SxpMapperReactor sxpMapper;
+    @Mock
+    private DSAsyncDao<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateDao;
+    @Mock
+    private DSAsyncDao<IpPrefix, EndpointForwardingTemplateBySubnet> epForwardingTemplateDao;
+    @Mock
+    private SimpleCachedDao<IpPrefix, MasterDatabaseBinding> cachedDao;
+    @Mock
+    private ListenerRegistration<? extends EPTemplateListener> listenerRegistration;
+    @Mock
+    private DataTreeModification<MasterDatabaseBinding> dataTreeModification;
+    @Mock
+    private DataObjectModification<MasterDatabaseBinding> dataObjectModification;
+
+    private MasterDatabaseBindingListenerImpl listener;
+
+    public MasterDatabaseBindingListenerImplTest() {
+        MASTER_DB_BINDING_VALUE = new MasterDatabaseBindingBuilder()
+                .setSecurityGroupTag(SGT_1)
+                .setIpPrefix(IP_PREFIX)
+                .build();
+    }
+
+
+    @Before
+    public void setUp() throws Exception {
+        Mockito.when(dataBroker.registerDataTreeChangeListener(Matchers.<DataTreeIdentifier>any(),
+                Matchers.<DataTreeChangeListener>any())).thenReturn(listenerRegistration);
+        listener = new MasterDatabaseBindingListenerImpl(dataBroker, sxpMapper, cachedDao, epPolicyTemplateDao,
+                epForwardingTemplateDao);
+    }
+
+    @Test
+    public void testOnDataTreeChanged() throws Exception {
+        Mockito.when(dataTreeModification.getRootNode()).thenReturn(dataObjectModification);
+        Mockito.when(dataTreeModification.getRootPath()).thenReturn(MASTER_DB_BINDING_TREE_PATH);
+        Mockito.when(dataObjectModification.getDataAfter()).thenReturn(MASTER_DB_BINDING_VALUE);
+
+        // prepare epPolicy template
+        final EndpointPolicyTemplateBySgt epPolicyTemplate = new EndpointPolicyTemplateBySgtBuilder()
+                .setSgt(SGT_1)
+                .build();
+        Mockito.when(epPolicyTemplateDao.read(Matchers.<Sgt>any())).thenReturn(
+                Futures.immediateFuture(Optional.of(epPolicyTemplate)));
+
+        // prepare epForwarding template
+        final IpPrefix ipPrefixSubnet = new IpPrefix(new Ipv4Prefix("1.2.3.0/24"));
+        final EndpointForwardingTemplateBySubnet epForwardingTemplate = new EndpointForwardingTemplateBySubnetBuilder()
+                .setIpPrefix(ipPrefixSubnet)
+                .build();
+        Mockito.when(epForwardingTemplateDao.read(Matchers.<IpPrefix>any())).thenReturn(
+                Futures.immediateFuture(Optional.of(epForwardingTemplate)));
+
+        listener.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+        final InOrder inOrder = Mockito.inOrder(cachedDao, epPolicyTemplateDao, epForwardingTemplateDao, sxpMapper);
+        inOrder.verify(cachedDao).update(IP_PREFIX, MASTER_DB_BINDING_VALUE);
+        inOrder.verify(epPolicyTemplateDao).read(SGT_1);
+        inOrder.verify(sxpMapper).processPolicyAndSxpMasterDB(epPolicyTemplate, MASTER_DB_BINDING_VALUE);
+        inOrder.verify(epForwardingTemplateDao).read(IP_PREFIX);
+        inOrder.verify(sxpMapper).processForwardingAndSxpMasterDB(epForwardingTemplate, MASTER_DB_BINDING_VALUE);
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    @Test
+    public void testClose() throws Exception {
+        Mockito.verify(listenerRegistration, Mockito.never()).close();
+        listener.close();
+        Mockito.verify(listenerRegistration).close();
+    }
+}
\ No newline at end of file
diff --git a/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/util/ForwardingTemplateUtilTest.java b/sxp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/util/ForwardingTemplateUtilTest.java
new file mode 100644 (file)
index 0000000..8a67e2b
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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.sxp.mapper.impl.util;
+
+import org.apache.commons.net.util.SubnetUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+
+/**
+ * Test for {@link ForwardingTemplateUtil}.
+ */
+public class ForwardingTemplateUtilTest {
+
+    public static final IpPrefix IP_PREFIX_24 = new IpPrefix(new Ipv4Prefix("1.2.3.0/24"));
+    public static final IpPrefix IP_PREFIX_32 = new IpPrefix(new Ipv4Prefix("1.2.3.4/32"));
+
+    @Test
+    public void testIsPlain() throws Exception {
+        Assert.assertFalse(ForwardingTemplateUtil.isPlain(IP_PREFIX_24));
+        Assert.assertTrue(ForwardingTemplateUtil.isPlain(IP_PREFIX_32));
+    }
+
+    @Test
+    public void testBuildSubnetInfoKey() throws Exception {
+        checkSubnetInfoBuilder(IP_PREFIX_24, "1.2.3.1", "1.2.3.254", 254);
+        checkSubnetInfoBuilder(IP_PREFIX_32, "0.0.0.0", "0.0.0.0", 0);
+    }
+
+    private void checkSubnetInfoBuilder(final IpPrefix ipPrefix, final String expectedLow, final String expectedHigh, final int expectedCount) {
+        final SubnetInfoKeyDecorator subnetInfoKey = ForwardingTemplateUtil.buildSubnetInfoKey(ipPrefix);
+        final SubnetUtils.SubnetInfo subnetInfo = subnetInfoKey.getDelegate();
+        Assert.assertEquals(expectedLow, subnetInfo.getLowAddress());
+        Assert.assertEquals(expectedHigh, subnetInfo.getHighAddress());
+        Assert.assertEquals(expectedCount, subnetInfo.getAddressCount());
+        Assert.assertEquals(ipPrefix.getIpv4Prefix().getValue(), subnetInfo.getCidrSignature());
+    }
+}
\ No newline at end of file