<artifactId>sxp-api</artifactId>
<version>${sxp.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.sxp</groupId>
+ <artifactId>sxp-core</artifactId>
+ <version>${sxp.version}</version>
+ </dependency>
</dependencies>
</dependencyManagement>
<groupId>org.opendaylight.sxp</groupId>
<artifactId>sxp-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.sxp</groupId>
+ <artifactId>sxp-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-net</groupId>
+ <artifactId>commons-net</artifactId>
+ </dependency>
<!-- testing dependencies -->
<dependency>
package org.opendaylight.controller.config.yang.config.groupbasedpolicy.sxp_mapper;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.SxpMapperProviderImpl;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.SxpMapperProviderImpl;
/**
* sxp-mapper impl module
+++ /dev/null
-/*
- * 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;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
-
-/**
- * SxpMapper provider implementation.
- */
-public class SxpMapperProviderImpl implements AutoCloseable {
-
- private final DataBroker dataBrokerDependency;
- private final RpcProviderRegistry rpcRegistryDependency;
-
- public SxpMapperProviderImpl(final DataBroker dataBrokerDependency, final RpcProviderRegistry rpcRegistryDependency) {
- this.dataBrokerDependency = dataBrokerDependency;
- this.rpcRegistryDependency = rpcRegistryDependency;
- }
-
- @Override
- public void close() throws Exception {
- //TODO: stub
- }
-}
--- /dev/null
+/**
+ * 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.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Purpose: encapsulate access to DS by exposing
+ * <dl>
+ * <dt>read</dt>
+ * <dd>search through values (either in local cache or directly in DataStore)</dd>
+ * </dl>
+ *
+ * @param <K> data key type
+ * @param <V> data type
+ */
+public interface DSAsyncDao<K, V extends DataObject> {
+
+ /**
+ * @param key for search
+ * @return value found by key
+ */
+ ListenableFuture<Optional<V>> read(@Nonnull K key);
+
+}
--- /dev/null
+/*
+ * 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.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.SxpMapper;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Purpose: provide listener capability to EndPoint templates
+ */
+public interface EPTemplateListener<T extends DataObject> extends DataTreeChangeListener<T>, AutoCloseable {
+
+ InstanceIdentifier<SxpMapper> SXP_MAPPER_TEMPLATE_PARENT_PATH = InstanceIdentifier.create(SxpMapper.class);
+
+ //NOBODY
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.sxp.core.Configuration;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+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.TopologyKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+
+/**
+ * Purpose: provide listener capability to {@link MasterDatabaseBinding} (Sxp - MasterDB)
+ */
+public interface MasterDatabaseBindingListener extends DataTreeChangeListener<MasterDatabaseBinding>, AutoCloseable {
+ /** path to SXP topology */
+ KeyedInstanceIdentifier<Topology, TopologyKey> SXP_TOPOLOGY_PATH = InstanceIdentifier.create(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(new TopologyId(Configuration.TOPOLOGY_NAME)));
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/**
+ * 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 javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+/**
+ * Purpose: encapsulate access to DS by exposing
+ * <dl>
+ * <dt>find</dt>
+ * <dd>search through cached values</dd>
+ * <dt>update</dt>
+ * <dd>stores given pair (key, value) to local cache</dd>
+ * </dl>
+ *
+ * @param <K> data key type
+ * @param <V> data type
+ */
+public interface SimpleCachedDao<K, V> extends SimpleDao<K, V> {
+
+ /**
+ * store given pair to local cache
+ *
+ * @param key associated to value
+ * @param value associated to key
+ */
+ V update(@Nonnull K key, @Nullable V value);
+
+ /**
+ * 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();
+}
--- /dev/null
+/**
+ * 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.base.Optional;
+import javax.annotation.Nonnull;
+
+/**
+ * Purpose: encapsulate access to DS by exposing
+ * <dl>
+ * <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 SimpleDao<K, V> {
+
+ /**
+ * @param key for search
+ * @return value found by key
+ */
+ Optional<V> find(@Nonnull K key);
+
+}
--- /dev/null
+/*
+ * 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 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);
+}
--- /dev/null
+/*
+ * 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.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+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.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;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.listen.EPForwardingTemplateListenerImpl;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.listen.EPPolicyTemplateListenerImpl;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.listen.MasterDatabaseBindingListenerImpl;
+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.groupbasedpolicy.endpoint.rev140421.EndpointService;
+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.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;
+ private final SxpMapperReactor sxpMapperReactor;
+ private final EPTemplateListener epPolicyTemplateListener;
+ 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 SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateCachedDao = new SimpleCachedDaoImpl<>();
+ final SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> epForwardingTemplateCachedDao =
+ new SimpleCachedDaoEPForwardingTemplateImpl();
+ final SimpleCachedDao<IpPrefix, MasterDatabaseBinding> masterDBBindingCachedDao = new SimpleCachedDaoImpl<>();
+
+ final DSAsyncDao<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateDao = new EPPolicyTemplateDaoImpl(dataBroker, epPolicyTemplateCachedDao);
+ final EPForwardingTemplateDaoImpl epForwardingTemplateDao = new EPForwardingTemplateDaoImpl(dataBroker,
+ epForwardingTemplateCachedDao);
+ final MasterDatabaseBindingDaoImpl masterDBBindingDao = new MasterDatabaseBindingDaoImpl(dataBroker, masterDBBindingCachedDao);
+
+ sxpDatabaseListener = new MasterDatabaseBindingListenerImpl(dataBroker, sxpMapperReactor, masterDBBindingCachedDao,
+ epPolicyTemplateDao, epForwardingTemplateDao);
+ epPolicyTemplateListener = new EPPolicyTemplateListenerImpl(dataBroker, sxpMapperReactor, epPolicyTemplateCachedDao,
+ masterDBBindingDao);
+ epForwardingTemplateListener = new EPForwardingTemplateListenerImpl(dataBroker, sxpMapperReactor, epForwardingTemplateCachedDao,
+ masterDBBindingDao);
+ LOG.info("started SxmMapper");
+ }
+
+ // register listeners to ip/sgt and EP-templates (by SGT, by subnet) -> 3x
+ // exclusively write L3-EP to DS upon DataChangeEvent
+
+ @Override
+ public void close() throws Exception {
+ //TODO: stub
+ sxpDatabaseListener.close();
+ epPolicyTemplateListener.close();
+ epForwardingTemplateListener.close();
+ }
+}
--- /dev/null
+/*
+ * 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 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
+ */
+public class SxpMapperReactorImpl implements SxpMapperReactor {
+ private final EndpointService l3EndpointService;
+
+ 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));
+ }
+}
--- /dev/null
+/**
+ * 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.Function;
+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.List;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+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.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;
+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.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Purpose: general dao for EndPoint templates
+ */
+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 SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> cachedDao;
+
+ public EPForwardingTemplateDaoImpl(final DataBroker dataBroker,
+ final SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> cachedDao) {
+ this.dataBroker = dataBroker;
+ this.cachedDao = cachedDao;
+ }
+
+ @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()) {
+ readResult = Futures.immediateFuture(value);
+ } else if (!cachedDao.isEmpty()) {
+ return READ_FUTURE_ABSENT;
+ } else {
+ final ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
+ final CheckedFuture<Optional<SxpMapper>, ReadFailedException> read =
+ rTx.read(LogicalDatastoreType.CONFIGURATION, buildReadPath(key));
+
+ Futures.addCallback(read, SxpListenerUtil.createTxCloseCallback(rTx));
+
+ readResult = Futures.transform(read, new Function<Optional<SxpMapper>, Optional<EndpointForwardingTemplateBySubnet>>() {
+ @Nullable
+ @Override
+ public Optional<EndpointForwardingTemplateBySubnet> apply(@Nullable final Optional<SxpMapper> input) {
+ if (input.isPresent()) {
+ // clean cache
+ cachedDao.invalidateCache();
+
+ // iterate through all template entries and update cachedDao
+ final List<EndpointForwardingTemplateBySubnet> templateLot = input.get().getEndpointForwardingTemplateBySubnet();
+ if (templateLot != null) {
+ for (EndpointForwardingTemplateBySubnet template : templateLot) {
+ cachedDao.update(template.getIpPrefix(), template);
+ }
+ }
+ 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 SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> cachedDao, final IpPrefix key) {
+ return cachedDao.find(key);
+ }
+
+}
--- /dev/null
+/**
+ * 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.Function;
+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 javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+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.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;
+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;
+
+/**
+ * Purpose: general dao for EndPoint templates
+ */
+public class EPPolicyTemplateDaoImpl implements DSAsyncDao<Sgt, EndpointPolicyTemplateBySgt> {
+
+ private final DataBroker dataBroker;
+ private final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> cachedDao;
+
+ public EPPolicyTemplateDaoImpl(final DataBroker dataBroker,
+ final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> cachedDao) {
+ this.dataBroker = dataBroker;
+ this.cachedDao = cachedDao;
+ }
+
+ @Override
+ public ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> read(@Nonnull final Sgt key) {
+ final Optional<EndpointPolicyTemplateBySgt> cachedEndpointPolicyTemplateBySgtalue = lookup(cachedDao, key);
+ if (cachedEndpointPolicyTemplateBySgtalue.isPresent()) {
+ return Futures.immediateFuture(cachedEndpointPolicyTemplateBySgtalue);
+ } else {
+ final ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
+ final CheckedFuture<Optional<EndpointPolicyTemplateBySgt>, ReadFailedException> read =
+ rTx.read(LogicalDatastoreType.CONFIGURATION, buildReadPath(key));
+
+ Futures.addCallback(read, SxpListenerUtil.createTxCloseCallback(rTx));
+
+ return Futures.transform(read, new Function<Optional<EndpointPolicyTemplateBySgt>, Optional<EndpointPolicyTemplateBySgt>>() {
+ @Nullable
+ @Override
+ public Optional<EndpointPolicyTemplateBySgt> apply(@Nullable final Optional<EndpointPolicyTemplateBySgt> input) {
+ if (input.isPresent()) {
+ cachedDao.update(key, input.get());
+ }
+ return input;
+ }
+ });
+ }
+ }
+
+ protected InstanceIdentifier<EndpointPolicyTemplateBySgt> buildReadPath(final Sgt key) {
+ return EPTemplateListener.SXP_MAPPER_TEMPLATE_PARENT_PATH
+ .child(EndpointPolicyTemplateBySgt.class, new EndpointPolicyTemplateBySgtKey(key));
+ }
+
+ private Optional<EndpointPolicyTemplateBySgt> lookup(final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> cachedDao, final Sgt key) {
+ return cachedDao.find(key);
+ }
+
+}
--- /dev/null
+/**
+ * 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.Function;
+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;
+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.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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.SxpNodeIdentity;
+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.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Purpose: general dao for EndPoint templates
+ */
+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 SimpleCachedDao<IpPrefix, MasterDatabaseBinding> cachedDao;
+
+ public MasterDatabaseBindingDaoImpl(final DataBroker dataBroker,
+ final SimpleCachedDao<IpPrefix, MasterDatabaseBinding> cachedDao) {
+ this.dataBroker = dataBroker;
+ this.cachedDao = cachedDao;
+ }
+
+ @Override
+ public ListenableFuture<Optional<MasterDatabaseBinding>> read(@Nonnull final IpPrefix key) {
+ final Optional<MasterDatabaseBinding> cachedMasterDatabaseBinding = lookup(cachedDao, key);
+ if (cachedMasterDatabaseBinding.isPresent()) {
+ return Futures.immediateFuture(cachedMasterDatabaseBinding);
+ } else {
+ final ListenableFuture<Void> cacheUpdatedFt = updateCache();
+
+ return Futures.transform(cacheUpdatedFt, new Function<Void, Optional<MasterDatabaseBinding>>() {
+ @Nullable
+ @Override
+ public Optional<MasterDatabaseBinding> apply(@Nullable final Void input) {
+ return lookup(cachedDao, key);
+ }
+ });
+ }
+ }
+
+ private ListenableFuture<Void> updateCache() {
+ final ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
+ final CheckedFuture<Optional<Topology>, ReadFailedException> read =
+ rTx.read(LogicalDatastoreType.CONFIGURATION, buildReadPath(null));
+
+ Futures.addCallback(read, SxpListenerUtil.createTxCloseCallback(rTx));
+
+ return Futures.transform(read, new Function<Optional<Topology>, Void>() {
+ @Nullable
+ @Override
+ public Void apply(@Nullable final Optional<Topology> input) {
+ if (input.isPresent()) {
+ // clean cache
+ cachedDao.invalidateCache();
+
+ for (Node node : input.get().getNode()) {
+ final SxpNodeIdentity sxpNodeIdentity = node.getAugmentation(SxpNodeIdentity.class);
+ if (sxpNodeIdentity != null) {
+ final List<MasterDatabaseBinding> masterDBBindings = sxpNodeIdentity.getMasterDatabase().getMasterDatabaseBinding();
+ if (masterDBBindings != null) {
+ for (MasterDatabaseBinding masterDBItem : masterDBBindings) {
+ // update all
+ final MasterDatabaseBinding previousValue = cachedDao.update(
+ masterDBItem.getIpPrefix(), masterDBItem);
+ if (previousValue != null) {
+ LOG.warn("updated key already obtained: [node:{}, sgt:{}]",
+ node.getNodeId().getValue(),
+ masterDBItem.getSecurityGroupTag());
+ }
+ }
+ }
+ }
+ }
+ } else {
+ LOG.warn("failed to update cache of SxpMasterDB - no data");
+ }
+ return null;
+ }
+ });
+ }
+
+ private InstanceIdentifier<Topology> buildReadPath(final Sgt key) {
+ return MasterDatabaseBindingListener.SXP_TOPOLOGY_PATH;
+ }
+
+ 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;
+ }
+ });
+ }
+}
--- /dev/null
+/*
+ * 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 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.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 SimpleCachedDao}
+ */
+public class SimpleCachedDaoEPForwardingTemplateImpl implements SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> {
+
+ private final ConcurrentMap<IpPrefix, EndpointForwardingTemplateBySubnet> plainCache;
+ private final ConcurrentMap<SubnetInfoKeyDecorator, EndpointForwardingTemplateBySubnet> subnetCache;
+ private final Pattern IP_MASK_EATER_RE = Pattern.compile("/[0-9]+");
+
+ public SimpleCachedDaoEPForwardingTemplateImpl() {
+ plainCache = new ConcurrentHashMap<>();
+ subnetCache = new ConcurrentHashMap<>();
+ }
+
+ @Override
+ public EndpointForwardingTemplateBySubnet update(@Nonnull final IpPrefix key, @Nullable final EndpointForwardingTemplateBySubnet value) {
+ final EndpointForwardingTemplateBySubnet previousValue;
+ if (ForwardingTemplateUtil.isPlain(key)) {
+ previousValue = updatePlainCache(key, value);
+ } else {
+ previousValue = updateSubnetCache(key, value);
+ }
+
+ return previousValue;
+ }
+
+ private EndpointForwardingTemplateBySubnet updateSubnetCache(final IpPrefix key, final EndpointForwardingTemplateBySubnet value) {
+ final EndpointForwardingTemplateBySubnet previousValue;
+ final SubnetInfoKeyDecorator subnetKey = ForwardingTemplateUtil.buildSubnetInfoKey(key);
+ if (value != null) {
+ previousValue = subnetCache.put(subnetKey, value);
+ } else {
+ previousValue = subnetCache.remove(subnetKey);
+ }
+ return previousValue;
+ }
+
+ private EndpointForwardingTemplateBySubnet updatePlainCache(final @Nonnull IpPrefix key, final @Nullable EndpointForwardingTemplateBySubnet value) {
+ final EndpointForwardingTemplateBySubnet previousValue;
+ if (value != null) {
+ previousValue = plainCache.put(key, value);
+ } else {
+ previousValue = plainCache.remove(key);
+ }
+ return previousValue;
+ }
+
+ @Override
+ public Optional<EndpointForwardingTemplateBySubnet> find(@Nonnull final IpPrefix key) {
+ final Optional<EndpointForwardingTemplateBySubnet> template;
+ if (ForwardingTemplateUtil.isPlain(key)) {
+ final Optional<EndpointForwardingTemplateBySubnet> fastPlain = Optional.fromNullable(plainCache.get(key));
+ if (fastPlain.isPresent()) {
+ template = fastPlain;
+ } else {
+ template = lookupSlowSubnet(key.getIpv4Prefix().getValue());
+ }
+ } else {
+ 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()));
+ }
+}
--- /dev/null
+/**
+ * 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 java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Purpose: generic implementation of {@link SimpleCachedDao}
+ */
+public class SimpleCachedDaoImpl<K, V extends DataObject> implements SimpleCachedDao<K, V> {
+
+ private final ConcurrentMap<K, V> cache;
+
+ public SimpleCachedDaoImpl() {
+ cache = new ConcurrentHashMap<>();
+ }
+
+ @Override
+ public V update(@Nonnull final K key, @Nullable final V value) {
+ final V previousValue;
+ if (value != null) {
+ previousValue = cache.put(key, value);
+ } else {
+ previousValue = cache.remove(key);
+ }
+
+ return previousValue;
+ }
+
+ @Override
+ public Optional<V> find(@Nonnull final K key) {
+ return Optional.fromNullable(cache.get(key));
+ }
+
+ @Override
+ public void invalidateCache() {
+ cache.clear();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return cache.isEmpty();
+ }
+
+ @Override
+ public Iterable<V> values() {
+ return Iterables.unmodifiableIterable(cache.values());
+ }
+}
--- /dev/null
+/**
+ * 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.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.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.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;
+
+/**
+ * Purpose: listens to EP forwarding template and propagates change events for further processing
+ */
+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 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 SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> templateCachedDao,
+ final DSAsyncDao<IpPrefix, MasterDatabaseBinding> masterDBBindingDao) {
+ this.sxpMapperReactor = Preconditions.checkNotNull(sxpMapperReactor);
+ this.templateCachedDao = Preconditions.checkNotNull(templateCachedDao);
+ this.masterDBBindingDao = Preconditions.checkNotNull(masterDBBindingDao);
+ templatePath = EPTemplateListener.SXP_MAPPER_TEMPLATE_PARENT_PATH.child(EndpointForwardingTemplateBySubnet.class);
+
+ final DataTreeIdentifier<EndpointForwardingTemplateBySubnet> dataTreeIdentifier = new DataTreeIdentifier<>(
+ LogicalDatastoreType.CONFIGURATION, templatePath);
+ listenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIdentifier, this);
+ LOG.debug("started listening to {}", templatePath);
+ }
+
+ @Override
+ public void onDataTreeChanged(@Nonnull final Collection<DataTreeModification<EndpointForwardingTemplateBySubnet>> collection) {
+ for (DataTreeModification<EndpointForwardingTemplateBySubnet> change : collection) {
+ LOG.trace("received modification: {} -> {}", change.getRootPath(), change.getRootNode().getModificationType());
+ // update cached dao
+ final InstanceIdentifier<EndpointForwardingTemplateBySubnet> changePath = change.getRootPath().getRootIdentifier();
+ final IpPrefix changeKey = changePath.firstKeyOf(EndpointForwardingTemplateBySubnet.class).getIpPrefix();
+ SxpListenerUtil.updateCachedDao(templateCachedDao, changeKey, change);
+
+ 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);
+ listenerRegistration.close();
+ }
+}
--- /dev/null
+/**
+ * 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.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.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.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;
+
+/**
+ * Purpose: listens to EP policy template and propagates change events for further processing
+ */
+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 SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> templateCachedDao;
+ private final ReadableByKey<Sgt, MasterDatabaseBinding> masterDBBindingDao;
+
+ public EPPolicyTemplateListenerImpl(final DataBroker dataBroker,
+ final SxpMapperReactor sxpMapperReactor,
+ 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);
+ templatePath = EPTemplateListener.SXP_MAPPER_TEMPLATE_PARENT_PATH.child(EndpointPolicyTemplateBySgt.class);
+
+ final DataTreeIdentifier<EndpointPolicyTemplateBySgt> dataTreeIdentifier = new DataTreeIdentifier<>(
+ LogicalDatastoreType.CONFIGURATION, templatePath);
+ listenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIdentifier, this);
+ LOG.debug("started listening to {}", templatePath);
+ }
+
+ @Override
+ 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);
+
+ 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);
+ listenerRegistration.close();
+ }
+}
--- /dev/null
+/*
+ * 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.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;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+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.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;
+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.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.network.topology.topology.Node;
+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;
+
+/**
+ * listens to sxp master database and propagates change events for further processing
+ */
+public class MasterDatabaseBindingListenerImpl implements MasterDatabaseBindingListener {
+
+ 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 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 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);
+ this.epForwardingTemplateDao = Preconditions.checkNotNull(epForwardingTemplateDao);
+ sxpDbPath = MasterDatabaseBindingListener.SXP_TOPOLOGY_PATH
+ .child(Node.class)
+ .augmentation(SxpNodeIdentity.class)
+ .child(MasterDatabase.class)
+ .child(MasterDatabaseBinding.class);
+
+ final DataTreeIdentifier<MasterDatabaseBinding> dataTreeIdentifier = new DataTreeIdentifier<>(
+ LogicalDatastoreType.OPERATIONAL, sxpDbPath);
+ listenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIdentifier, this);
+ LOG.debug("started listening to {}", sxpDbPath);
+ }
+
+ @Override
+ public void onDataTreeChanged(@Nonnull final Collection<DataTreeModification<MasterDatabaseBinding>> collection) {
+ for (DataTreeModification<MasterDatabaseBinding> change : collection) {
+ LOG.trace("received modification: {} -> {}", change.getRootPath(), change.getRootNode().getModificationType());
+ // update cached dao
+ final MasterDatabaseBinding sxpMasterDBItem = change.getRootNode().getDataAfter();
+ if (sxpMasterDBItem == null) {
+ //TODO: cover sgt-ip mapping removal
+ } else {
+ final Sgt sgtKey = sxpMasterDBItem.getSecurityGroupTag();
+ final IpPrefix ipPrefixKey = sxpMasterDBItem.getIpPrefix();
+ SxpListenerUtil.updateCachedDao(masterDBBindingDaoCached, ipPrefixKey, change);
+
+ processWithEPPolicyTemplate(sgtKey, sxpMasterDBItem);
+ processWithEPForwardingTemplate(ipPrefixKey, sxpMasterDBItem);
+ }
+ }
+ }
+
+ private void processWithEPForwardingTemplate(final IpPrefix changeKey, final MasterDatabaseBinding sxpMasterDBItem) {
+ final ListenableFuture<Optional<EndpointForwardingTemplateBySubnet>> epForwardingTemplateFuture =
+ epForwardingTemplateDao.read(changeKey);
+
+ final ListenableFuture<RpcResult<Void>> rpcResult = Futures.transform(epForwardingTemplateFuture, new AsyncFunction<Optional<EndpointForwardingTemplateBySubnet>, RpcResult<Void>>() {
+ @Override
+ public ListenableFuture<RpcResult<Void>> apply(final Optional<EndpointForwardingTemplateBySubnet> input) throws Exception {
+ if (input == null || !input.isPresent()) {
+ LOG.debug("no epForwardingTemplate available for ipPrefix: {}", changeKey);
+ throw new IllegalArgumentException("no epForwardingTemplate available");
+ } else {
+ LOG.trace("processing sxpMasterDB event and epForwardingTemplate for ip-prefix: {}", changeKey);
+ return sxpMapperReactor.processForwardingAndSxpMasterDB(input.get(), sxpMasterDBItem);
+ }
+ }
+ });
+ Futures.addCallback(rpcResult, RPC_FW_RESULT_FUTURE_CALLBACK);
+ }
+
+ private void processWithEPPolicyTemplate(final Sgt changeKey, final MasterDatabaseBinding sxpMasterDBItem) {
+ final ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> epPolicyTemplateFuture =
+ epPolicyTemplateDao.read(changeKey);
+
+ final ListenableFuture<RpcResult<Void>> rpcResult = Futures.transform(epPolicyTemplateFuture, new AsyncFunction<Optional<EndpointPolicyTemplateBySgt>, RpcResult<Void>>() {
+ @Override
+ public ListenableFuture<RpcResult<Void>> apply(final Optional<EndpointPolicyTemplateBySgt> input) throws Exception {
+ if (input == null || !input.isPresent()) {
+ LOG.debug("no epPolicyTemplate available for sgt: {}", changeKey);
+ throw new IllegalArgumentException("no epPolicyTemplate available");
+ } else {
+ LOG.trace("processing sxpMasterDB event and epPolicyTemplate for sgt: {}", changeKey);
+ return sxpMapperReactor.processPolicyAndSxpMasterDB(input.get(), sxpMasterDBItem);
+ }
+ }
+ });
+
+ Futures.addCallback(rpcResult, RPC_POLICY_RESULT_FUTURE_CALLBACK);
+ }
+
+ @Override
+ public void close() throws Exception {
+ LOG.debug("closing listener registration to {}", sxpDbPath);
+ listenerRegistration.close();
+ }
+}
--- /dev/null
+/**
+ * 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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+
+/**
+ * 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 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 SubnetInfoKeyDecorator buildSubnetInfoKey(@Nonnull final IpPrefix value) {
+ return new SubnetInfoKeyDecorator(new SubnetUtils(value.getIpv4Prefix().getValue()).getInfo());
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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();
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ };
+ }
+
+}
--- /dev/null
+/*
+ * 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();
+ }
+}
--- /dev/null
+/**
+ * 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.base.Optional;
+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.SimpleCachedDao;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Purpose: provide general logic used by listeners
+ */
+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();
+ valueCachedDao.update(key, value);
+ }
+
+ public static FutureCallback<Optional<?>> createTxCloseCallback(final ReadOnlyTransaction rTx) {
+ return new FutureCallback<Optional<?>>() {
+ @Override
+ public void onSuccess(@Nullable final Optional<?> result) {
+ rTx.close();
+ }
+
+ @Override
+ public void onFailure(final Throwable t) {
+ rTx.close();
+ }
+ };
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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