<artifactId>groupbasedpolicy-ise-adapter</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.groupbasedpolicy</groupId>
+ <artifactId>sxp-ep-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<!-- GBP configuration -->
<dependency>
<module>features</module>
<module>sxp-mapper</module>
<module>groupbasedpolicy-ise-adapter</module>
+ <module>sxp-integration</module>
</modules>
<build>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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 -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-parent</artifactId>
+ <version>0.6.0-SNAPSHOT</version>
+ <relativePath/>
+ </parent>
+
+ <groupId>org.opendaylight.groupbasedpolicy</groupId>
+ <artifactId>sxp-integration</artifactId>
+ <version>0.5.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <properties>
+ <sxp.version>1.4.0-SNAPSHOT</sxp.version>
+ </properties>
+
+ <modules>
+ <module>sxp-ep-provider</module>
+ <!--<module>ep-sgt-mapper</module>-->
+ </modules>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.groupbasedpolicy</groupId>
+ <artifactId>groupbasedpolicy-artifacts</artifactId>
+ <version>${project.version}</version>
+ <scope>import</scope>
+ <type>pom</type>
+ </dependency>
+
+ <!-- sxp -->
+ <dependency>
+ <groupId>org.opendaylight.sxp</groupId>
+ <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>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.groupbasedpolicy</groupId>
+ <artifactId>groupbasedpolicy</artifactId>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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 -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.groupbasedpolicy</groupId>
+ <artifactId>sxp-integration</artifactId>
+ <version>0.5.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <artifactId>sxp-ep-provider</artifactId>
+ <packaging>bundle</packaging>
+ <name>sxp-integration_sxp-ep-provider</name>
+
+ <dependencies>
+ <!-- model dependencies -->
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-inet-types-2013-07-15</artifactId>
+
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>yang-ext</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.groupbasedpolicy</groupId>
+ <artifactId>l2-l3-domain-extension</artifactId>
+ </dependency>
+
+ <!-- sxp deps -->
+ <dependency>
+ <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>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-broker-impl</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <!-- project build -->
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<snapshot>
+ <configuration>
+ <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <module>
+ <type xmlns:sxp-mapper="urn:opendaylight:params:xml:ns:yang:controller:config:groupbasedpolicy:sxp-mapper">
+ sxp-mapper:sxp-mapper-impl
+ </type>
+ <name>sxp-mapper</name>
+
+ <data-broker>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
+ <name>binding-data-broker</name>
+ </data-broker>
+ <rpc-registry>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+ <name>binding-rpc-broker</name>
+ </rpc-registry>
+ <domain-specific-registry>
+ <type xmlns:gbp="urn:opendaylight:params:xml:ns:yang:controller:config:groupbasedpolicy">
+ gbp:domain-specific-registry
+ </type>
+ <name>domain-specific-registry</name>
+ </domain-specific-registry>
+ </module>
+ </modules>
+ </data>
+
+ </configuration>
+
+ <required-capabilities>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:config:groupbasedpolicy:sxp-mapper?module=sxp-mapper-cfg&revision=2016-03-02</capability>
+ </required-capabilities>
+
+</snapshot>
--- /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.controller.config.yang.config.groupbasedpolicy.sxp_integration.sxp_ep_provider;
+
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SxpEpProviderProviderImpl;
+
+/**
+* sxp-ep-provider impl module
+*/
+public class SxpEpProviderProviderModule extends org.opendaylight.controller.config.yang.config.groupbasedpolicy.sxp_integration.sxp_ep_provider.AbstractSxpEpProviderProviderModule {
+ public SxpEpProviderProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public SxpEpProviderProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.config.groupbasedpolicy.sxp_integration.sxp_ep_provider.SxpEpProviderProviderModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void customValidation() {
+ // add custom validation form module attributes here.
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ return new SxpEpProviderProviderImpl(getDataBrokerDependency(), getRpcRegistryDependency(),
+ getDomainSpecificRegistryDependency());
+ }
+
+}
--- /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
+ */
+
+/*
+* Generated file
+*
+* Generated from: yang module name: sxp-ep-provider-cfg yang module local name: sxp-ep-provider-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Thu Jul 21 17:55:05 CEST 2016
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.config.groupbasedpolicy.sxp_integration.sxp_ep_provider;
+public class SxpEpProviderProviderModuleFactory extends org.opendaylight.controller.config.yang.config.groupbasedpolicy.sxp_integration.sxp_ep_provider.AbstractSxpEpProviderProviderModuleFactory {
+
+}
--- /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.ep.provider.impl;
+
+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.ep.provider.impl;
+
+import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.SxpEpMapper;
+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 ClusteredDataTreeChangeListener<T>, AutoCloseable {
+
+ InstanceIdentifier<SxpEpMapper> SXP_MAPPER_TEMPLATE_PARENT_PATH = InstanceIdentifier.create(SxpEpMapper.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.ep.provider.impl;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.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.ep.provider.impl;
+
+import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
+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 ClusteredDataTreeChangeListener<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.ep.provider.impl;
+
+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 ReadableAsyncByKey<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.ep.provider.impl;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+
+/**
+ * Purpose: simple 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
+ */
+ 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.ep.provider.impl;
+
+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.ep.provider.impl;
+
+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.ep.provider.impl;
+
+import com.google.common.base.Preconditions;
+import java.util.Collection;
+import java.util.Map.Entry;
+import org.opendaylight.groupbasedpolicy.api.EndpointAugmentor;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.EpPolicyTemplateValueKey;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.EpPolicyTemplateValueKeyFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.ContainmentEndpointWithLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+
+public class SxpEndpointAugmentorImpl implements EndpointAugmentor {
+
+ private final ReadableByKey<EpPolicyTemplateValueKey, EndpointPolicyTemplateBySgt> epPolicyTemplateDao;
+ private final EpPolicyTemplateValueKeyFactory epPolicyTemplateKeyFactory;
+
+ public SxpEndpointAugmentorImpl(final ReadableByKey<EpPolicyTemplateValueKey, EndpointPolicyTemplateBySgt> epPolicyTemplateDao,
+ final EpPolicyTemplateValueKeyFactory epPolicyTemplateKeyFactory) {
+ this.epPolicyTemplateKeyFactory = Preconditions.checkNotNull(epPolicyTemplateKeyFactory, "epPolicyTemplateKeyFactory can not be null");
+ this.epPolicyTemplateDao = Preconditions.checkNotNull(epPolicyTemplateDao, "epPolicyTemplateDao can not be null");
+ }
+
+ @Override
+ public Entry<Class<? extends Augmentation<AddressEndpoint>>, Augmentation<AddressEndpoint>> buildAddressEndpointAugmentation(
+ AddressEndpointReg input) {
+ return null;
+ }
+
+ @Override
+ public Entry<Class<? extends Augmentation<ContainmentEndpoint>>, Augmentation<ContainmentEndpoint>> buildContainmentEndpointAugmentation(
+ ContainmentEndpointReg input) {
+ return null;
+ }
+
+ @Override
+ public Entry<Class<? extends Augmentation<AddressEndpointWithLocation>>, Augmentation<AddressEndpointWithLocation>> buildAddressEndpointWithLocationAugmentation(
+ AddressEndpoint input) {
+ final EpPolicyTemplateValueKey templateValueKey = epPolicyTemplateKeyFactory.createKey(
+ input.getTenant(), input.getEndpointGroup(), input.getCondition());
+
+ final Collection<EndpointPolicyTemplateBySgt> epPolicyTemplates = epPolicyTemplateDao.readBy(templateValueKey);
+ final Entry<Class<? extends Augmentation<AddressEndpointWithLocation>>, Augmentation<AddressEndpointWithLocation>> entry;
+
+ if (epPolicyTemplates.isEmpty()) {
+ entry = null;
+ } else {
+ //TODO: cover case when multiple templates found
+// final Augmentation<AddressEndpointWithLocation> addressEndpointWithLocationAug =
+// new AddressEndpointWithLocationAugBuilder()
+// .setSgt(Iterables.getFirst(epPolicyTemplates, null).getSgt())
+// .build();
+// entry = new AbstractMap.SimpleEntry<>(AddressEndpointWithLocationAug.class, addressEndpointWithLocationAug);
+ }
+
+ return null; //entry;
+ }
+
+ @Override
+ public Entry<Class<? extends Augmentation<ContainmentEndpointWithLocation>>, Augmentation<ContainmentEndpointWithLocation>> buildContainmentEndpointWithLocationAugmentation(
+ ContainmentEndpoint input) {
+ return null;
+ }
+
+}
--- /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.ep.provider.impl;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.groupbasedpolicy.api.DomainSpecificRegistry;
+import org.opendaylight.groupbasedpolicy.api.EndpointAugmentor;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.EPForwardingTemplateDaoImpl;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.EPPolicyTemplateDaoImpl;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.EpPolicyTemplateValueKeyFactory;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.MasterDatabaseBindingDaoImpl;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.SimpleCachedDaoEPForwardingTemplateImpl;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.SimpleCachedDaoImpl;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.listen.EPForwardingTemplateListenerImpl;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.listen.EPPolicyTemplateListenerImpl;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.listen.MasterDatabaseBindingListenerImpl;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.EPTemplateUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.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 SxpEpProviderProviderImpl implements AutoCloseable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SxpEpProviderProviderImpl.class);
+
+ private final MasterDatabaseBindingListenerImpl sxpDatabaseListener;
+ private final SxpMapperReactor sxpMapperReactor;
+ private final EPTemplateListener epPolicyTemplateListener;
+ private final EPTemplateListener epForwardingTemplateListener;
+ private final DomainSpecificRegistry domainSpecificRegistry;
+ private final EndpointAugmentor sxpEndpointAugmentor;
+
+ public SxpEpProviderProviderImpl(final DataBroker dataBroker, final RpcProviderRegistry rpcRegistryDependency,
+ final DomainSpecificRegistry domainSpecificRegistry) {
+ LOG.info("starting SxmMapper ..");
+ this.domainSpecificRegistry = domainSpecificRegistry;
+
+ final BaseEndpointService endpointService = rpcRegistryDependency.getRpcService(BaseEndpointService.class);
+ sxpMapperReactor = new SxpMapperReactorImpl(endpointService, dataBroker);
+
+ final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateCachedDao = new SimpleCachedDaoImpl<>();
+ final SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> epForwardingTemplateCachedDao =
+ new SimpleCachedDaoEPForwardingTemplateImpl();
+ final SimpleCachedDao<IpPrefix, MasterDatabaseBinding> masterDBBindingCachedDao = new SimpleCachedDaoImpl<>();
+
+ final EpPolicyTemplateValueKeyFactory epPolicyTemplateKeyFactory = new EpPolicyTemplateValueKeyFactory(
+ EPTemplateUtil.createEndpointGroupIdOrdering(), EPTemplateUtil.createConditionNameOrdering());
+ final EPPolicyTemplateDaoImpl epPolicyTemplateDao = new EPPolicyTemplateDaoImpl(dataBroker, epPolicyTemplateCachedDao, epPolicyTemplateKeyFactory);
+ 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, epForwardingTemplateDao);
+ epForwardingTemplateListener = new EPForwardingTemplateListenerImpl(dataBroker, sxpMapperReactor, epForwardingTemplateCachedDao,
+ masterDBBindingDao, epPolicyTemplateDao);
+ sxpEndpointAugmentor = new SxpEndpointAugmentorImpl(epPolicyTemplateDao, epPolicyTemplateKeyFactory);
+ domainSpecificRegistry.getEndpointAugmentorRegistry().register(sxpEndpointAugmentor);
+ LOG.info("started SxmMapper");
+ }
+
+ @Override
+ public void close() throws Exception {
+ sxpDatabaseListener.close();
+ epPolicyTemplateListener.close();
+ epForwardingTemplateListener.close();
+ domainSpecificRegistry.getEndpointAugmentorRegistry().unregister(sxpEndpointAugmentor);
+ }
+}
--- /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.ep.provider.impl;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.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 policy template
+ * @param epForwardingTemplate forwarding template
+ * @param masterDatabaseBinding sxpMasterDB item
+ */
+ ListenableFuture<RpcResult<Void>> processTemplatesAndSxpMasterDB(EndpointPolicyTemplateBySgt epPolicyTemplate,
+ 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.ep.provider.impl;
+
+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.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.JdkFutureAdapters;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Collections;
+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.ep.provider.impl.util.SxpListenerUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.Endpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.NetworkDomainContainmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.AddressEndpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointRegBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Purpose: exclusively processes sxp master database changes and EGP templates changes
+ */
+public class SxpMapperReactorImpl implements SxpMapperReactor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SxpMapperReactorImpl.class);
+
+ private final BaseEndpointService l3EndpointService;
+ private final DataBroker dataBroker;
+
+ public SxpMapperReactorImpl(final BaseEndpointService l3EndpointService, final DataBroker dataBroker) {
+ this.l3EndpointService = Preconditions.checkNotNull(l3EndpointService, "l3Endpoint service missing");
+ this.dataBroker = Preconditions.checkNotNull(dataBroker, "dataBroker missing");
+ }
+
+ @Override
+ public ListenableFuture<RpcResult<Void>> processTemplatesAndSxpMasterDB(
+ final EndpointPolicyTemplateBySgt epPolicyTemplate,
+ final EndpointForwardingTemplateBySubnet epForwardingTemplate,
+ final MasterDatabaseBinding masterDBBinding) {
+ LOG.debug("processing ep-templates + sxpMasterDB entry: {} - {}",
+ masterDBBinding.getSecurityGroupTag(), masterDBBinding.getIpPrefix());
+ // apply sxpMasterDB to policy template
+ final Ipv4Prefix address = new Ipv4Prefix(epForwardingTemplate.getIpPrefix().getIpv4Prefix().getValue());
+ final NetworkContainment networkContainment = new NetworkContainmentBuilder()
+ .setContainment(new NetworkDomainContainmentBuilder()
+ .setNetworkDomainType(epForwardingTemplate.getNetworkContainment().getNetworkDomainType())
+ .setNetworkDomainId(epForwardingTemplate.getNetworkContainment().getNetworkDomainId())
+ .build())
+ .build();
+ final RegisterEndpointInput epInput = new RegisterEndpointInputBuilder().setAddressEndpointReg(
+ Collections.singletonList(new AddressEndpointRegBuilder().setAddressType(IpPrefixType.class)
+ .setAddress(address.getValue())
+ .setContextType(L3Context.class)
+ .setContextId(epForwardingTemplate.getL3Context())
+ .setNetworkContainment(networkContainment)
+ .setCondition(epPolicyTemplate.getConditions())
+ .setTenant(epPolicyTemplate.getTenant())
+ .setEndpointGroup(epPolicyTemplate.getEndpointGroups())
+ .build()))
+ .build();
+ epForwardingTemplate.getL3Context();
+
+ return chainL3EPServiceIfEpAbsent(epInput);
+ }
+
+ private CheckedFuture<Optional<AddressEndpoint>, ReadFailedException> findExistingEndPoint(final ContextId containment,
+ final String address) {
+ KeyedInstanceIdentifier<AddressEndpoint, AddressEndpointKey> addressEndpointPath =
+ InstanceIdentifier.create(Endpoints.class).child(AddressEndpoints.class).child(AddressEndpoint.class,
+ new AddressEndpointKey(address, IpPrefixType.class, containment, L3Context.class));
+ final ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
+ final CheckedFuture<Optional<AddressEndpoint>, ReadFailedException> read = rTx.read(
+ LogicalDatastoreType.OPERATIONAL, addressEndpointPath);
+ Futures.addCallback(read, SxpListenerUtil.createTxCloseCallback(rTx));
+ return read;
+ }
+
+ private ListenableFuture<RpcResult<Void>> chainL3EPServiceIfEpAbsent(final RegisterEndpointInput epInput) {
+ AddressEndpointReg addressEndpoint = epInput.getAddressEndpointReg().get(0);
+ CheckedFuture<Optional<AddressEndpoint>, ReadFailedException> existingEndpointFuture =
+ findExistingEndPoint(addressEndpoint.getContextId(), addressEndpoint.getAddress());
+
+ return Futures.transform(existingEndpointFuture, new AsyncFunction<Optional<AddressEndpoint>, RpcResult<Void>>() {
+ @Override
+ public ListenableFuture<RpcResult<Void>> apply(final Optional<AddressEndpoint> input) throws Exception {
+ final ListenableFuture<RpcResult<Void>> nextResult;
+ if (input == null || !input.isPresent() || !isSameEpg(epInput, input.get())) {
+ // invoke service
+ return JdkFutureAdapters.listenInPoolThread(l3EndpointService.registerEndpoint(epInput));
+ } else {
+ final String existingL3EpMsg = String.format("address-endpoint for given key already exists: %s | %s",
+ addressEndpoint.getContextId(), addressEndpoint.getAddress() );
+ nextResult = Futures.immediateFailedFuture(new IllegalStateException(existingL3EpMsg));
+ }
+ return nextResult;
+ }
+ });
+ }
+
+ private boolean isSameEpg(RegisterEndpointInput epInput, AddressEndpoint input) {
+ if (epInput == null || epInput.getAddressEndpointReg() == null || epInput.getAddressEndpointReg().isEmpty()) {
+ return true;
+ }
+ final AddressEndpointReg epInputAddressEndpoint = epInput.getAddressEndpointReg().get(0);
+ if (epInputAddressEndpoint.getEndpointGroup() == null || epInputAddressEndpoint.getEndpointGroup().isEmpty()) {
+ return true;
+ }
+ if (input == null || input.getEndpointGroup() == null || input.getEndpointGroup().isEmpty()) {
+ return true;
+ }
+ final EndpointGroupId addressEndpointGroupId = epInputAddressEndpoint.getEndpointGroup().get(0);
+ final EndpointGroupId existingEndpointGroupId = input.getEndpointGroup().get(0);
+ return addressEndpointGroupId.equals(existingEndpointGroupId);
+ }
+
+}
+
--- /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.ep.provider.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.ep.provider.impl.DSAsyncDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.EPTemplateListener;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SimpleCachedDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.SxpListenerUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.SxpEpMapper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Purpose: general dao for EndPoint templates
+ */
+public class EPForwardingTemplateDaoImpl implements DSAsyncDao<IpPrefix, EndpointForwardingTemplateBySubnet> {
+
+ private 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<SxpEpMapper>, ReadFailedException> read =
+ rTx.read(LogicalDatastoreType.CONFIGURATION, buildReadPath(key));
+
+ Futures.addCallback(read, SxpListenerUtil.createTxCloseCallback(rTx));
+
+ readResult = Futures.transform(read, new Function<Optional<SxpEpMapper>, Optional<EndpointForwardingTemplateBySubnet>>() {
+ @Nullable
+ @Override
+ public Optional<EndpointForwardingTemplateBySubnet> apply(@Nullable final Optional<SxpEpMapper> 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 lookup(cachedDao, key);
+ } else {
+ return Optional.absent();
+ }
+ }
+ });
+ }
+ return readResult;
+ }
+
+ protected InstanceIdentifier<SxpEpMapper> 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.ep.provider.impl.dao;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+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 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.ep.provider.impl.DSAsyncDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.EPTemplateListener;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.ReadableByKey;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SimpleCachedDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.SxpListenerUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.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>,
+ ReadableByKey<EpPolicyTemplateValueKey, EndpointPolicyTemplateBySgt> {
+
+ private static final ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> READ_FUTURE_ABSENT = Futures.immediateFuture(Optional.absent());
+
+ private final DataBroker dataBroker;
+ private final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> cachedDao;
+ private final EpPolicyTemplateValueKeyFactory keyFactory;
+
+ public EPPolicyTemplateDaoImpl(final DataBroker dataBroker,
+ final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> cachedDao,
+ final EpPolicyTemplateValueKeyFactory keyFactory) {
+ this.dataBroker = dataBroker;
+ this.cachedDao = cachedDao;
+ this.keyFactory = keyFactory;
+ }
+
+ @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 if (!cachedDao.isEmpty()) {
+ return READ_FUTURE_ABSENT;
+ } 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, keyFactory.sortValueKeyLists(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);
+ }
+
+ @Override
+ public Collection<EndpointPolicyTemplateBySgt> readBy(@Nonnull final EpPolicyTemplateValueKey specialKey) {
+ final Predicate<EpPolicyTemplateValueKey> templateValuePredicate = Predicates.equalTo(specialKey);
+ final Collection<EndpointPolicyTemplateBySgt> foundTemplates = new ArrayList<>();
+
+ for (EndpointPolicyTemplateBySgt epPolicyTemplate : cachedDao.values()) {
+ final EpPolicyTemplateValueKey templateValueKey = keyFactory.createKeyWithDefaultOrdering(epPolicyTemplate);
+ if (templateValuePredicate.apply(templateValueKey)) {
+ foundTemplates.add(epPolicyTemplate);
+ }
+ }
+
+ return foundTemplates;
+ }
+}
--- /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.ep.provider.impl.dao;
+
+import java.util.List;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt;
+
+/**
+ * Purpose: composite key holcer for {@link EndpointPolicyTemplateBySgt}
+ */
+public class EpPolicyTemplateValueKey {
+
+ private final TenantId tenantId;
+ private final List<EndpointGroupId> epgId;
+ private final List<ConditionName> conditionName;
+
+ public EpPolicyTemplateValueKey(final TenantId tenantId, final List<EndpointGroupId> epgId, final List<ConditionName> conditionName) {
+ this.tenantId = tenantId;
+ this.epgId = epgId;
+ this.conditionName = conditionName;
+ }
+
+ public EpPolicyTemplateValueKey(AddressEndpointWithLocation endpoint) {
+ this(endpoint.getTenant(), endpoint.getEndpointGroup(), endpoint.getCondition());
+ }
+
+ public TenantId getTenantId() {
+ return tenantId;
+ }
+
+ public List<EndpointGroupId> getEpgId() {
+ return epgId;
+ }
+
+ public List<ConditionName> getConditionName() {
+ return conditionName;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ final EpPolicyTemplateValueKey that = (EpPolicyTemplateValueKey) o;
+
+ if (tenantId != null ? !tenantId.equals(that.tenantId) : that.tenantId != null) return false;
+ if (epgId != null ? !epgId.equals(that.epgId) : that.epgId != null) return false;
+ return conditionName != null ? conditionName.equals(that.conditionName) : that.conditionName == null;
+
+ }
+
+ @Override
+ public int hashCode() {
+ return tenantId != null ? tenantId.hashCode() : 0;
+ }
+}
--- /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.ep.provider.impl.dao;
+
+import com.google.common.collect.Ordering;
+import java.util.Collections;
+import java.util.List;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt;
+
+/**
+ * Purpose: create cache keys with ordered lists inside
+ */
+public class EpPolicyTemplateValueKeyFactory {
+ private final Ordering<EndpointGroupId> epgIdOrdering;
+ private final Ordering<ConditionName> conditionOrdering;
+
+ public EpPolicyTemplateValueKeyFactory(final Ordering<EndpointGroupId> epgIdOrdering,
+ final Ordering<ConditionName> conditionOrdering) {
+ this.epgIdOrdering = epgIdOrdering;
+ this.conditionOrdering = conditionOrdering;
+ }
+
+ public EndpointPolicyTemplateBySgt sortValueKeyLists(final EndpointPolicyTemplateBySgt template) {
+ if (template.getEndpointGroups() != null) {
+ Collections.sort(template.getEndpointGroups(), epgIdOrdering);
+ }
+ if (template.getConditions() != null) {
+ Collections.sort(template.getConditions(), conditionOrdering);
+ }
+ return template;
+ }
+
+ public EpPolicyTemplateValueKey createKeyWithDefaultOrdering(final EndpointPolicyTemplateBySgt newSource) {
+ return new EpPolicyTemplateValueKey(
+ newSource.getTenant(), newSource.getEndpointGroups(), newSource.getConditions());
+ }
+
+ public EpPolicyTemplateValueKey sortValueKeyLists(final EpPolicyTemplateValueKey existingKey) {
+ Collections.sort(existingKey.getEpgId(), epgIdOrdering);
+ if (existingKey.getConditionName() != null) {
+ Collections.sort(existingKey.getConditionName(), conditionOrdering);
+ }
+ return existingKey;
+ }
+
+ public EpPolicyTemplateValueKey createKey(final TenantId tenant, final List<EndpointGroupId> endpointGroup,
+ final List<ConditionName> condition) {
+ return sortValueKeyLists(new EpPolicyTemplateValueKey(tenant, endpointGroup, condition));
+ }
+}
--- /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.ep.provider.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 java.util.stream.Collectors;
+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.ep.provider.impl.DSAsyncDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.MasterDatabaseBindingListener;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.ReadableAsyncByKey;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SimpleCachedDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.SxpListenerUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.MasterDatabaseFields;
+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.SxpDatabasesFields;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.SxpNodeIdentity;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.SxpDomains;
+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>,
+ ReadableAsyncByKey<Sgt, MasterDatabaseBinding> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MasterDatabaseBindingDaoImpl.class);
+ private static final ListenableFuture<Optional<MasterDatabaseBinding>> READ_FUTURE_ABSENT = Futures.immediateFuture(Optional.absent());
+
+ 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 if (!cachedDao.isEmpty()) {
+ return READ_FUTURE_ABSENT;
+ } 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()) {
+ java.util.Optional.ofNullable(node.getAugmentation(SxpNodeIdentity.class))
+ .map(SxpNodeIdentity::getSxpDomains)
+ .map(SxpDomains::getSxpDomain)
+ .ifPresent((sxpDomain) -> {
+ final List<MasterDatabaseBinding> masterDBBindings = sxpDomain.stream()
+ .map(SxpDatabasesFields::getMasterDatabase)
+ .filter(masterDb -> masterDb != null)
+ .map(MasterDatabaseFields::getMasterDatabaseBinding)
+ .filter(binding -> binding != null)
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList());
+
+ 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.ep.provider.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.ep.provider.impl.SimpleCachedDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.EPTemplateUtil;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.SubnetInfoKeyDecorator;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.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 (EPTemplateUtil.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 = EPTemplateUtil.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 (EPTemplateUtil.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 = EPTemplateUtil.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.ep.provider.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.ep.provider.impl.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.ep.provider.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.apache.commons.lang3.tuple.Pair;
+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.ep.provider.impl.DSAsyncDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.EPTemplateListener;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SimpleCachedDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SxpMapperReactor;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.L3EPServiceUtil;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.SxpListenerUtil;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.EPTemplateUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.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.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+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;
+ private final DSAsyncDao<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateDao;
+
+ public EPForwardingTemplateListenerImpl(final DataBroker dataBroker,
+ final SxpMapperReactor sxpMapperReactor,
+ final SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> templateCachedDao,
+ final DSAsyncDao<IpPrefix, MasterDatabaseBinding> masterDBBindingDao,
+ final DSAsyncDao<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateDao) {
+ this.sxpMapperReactor = Preconditions.checkNotNull(sxpMapperReactor);
+ this.templateCachedDao = Preconditions.checkNotNull(templateCachedDao);
+ this.masterDBBindingDao = Preconditions.checkNotNull(masterDBBindingDao);
+ this.epPolicyTemplateDao = Preconditions.checkNotNull(epPolicyTemplateDao);
+ 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();
+ processWithEPTemplates(epForwardingTemplate);
+ }
+ }
+
+ private void processWithEPTemplates(final EndpointForwardingTemplateBySubnet epForwardingTemplate) {
+ final ListenableFuture<Optional<MasterDatabaseBinding>> sxpMasterDbItemRead =
+ masterDBBindingDao.read(epForwardingTemplate.getIpPrefix());
+
+ // find all available epForwardingTemplates and pair those to sxpMasterDBBinding
+ final ListenableFuture<Optional<Pair<MasterDatabaseBinding, EndpointPolicyTemplateBySgt>>> searchResult =
+ Futures.transform(sxpMasterDbItemRead, createReadAndPairTemplateToBindingFunction(epForwardingTemplate));
+
+ // invoke sxpMapperReactor.process for every valid combination of sxpMasterDBBinding, epPolicyTemplate, epForwardingTemplate
+ final ListenableFuture<RpcResult<Void>> rpcResult =
+ Futures.transform(searchResult, createProcessAllFunction(epForwardingTemplate));
+
+ Futures.addCallback(rpcResult, ANY_RPC_FUTURE_CALLBACK);
+ }
+
+ private AsyncFunction<Optional<Pair<MasterDatabaseBinding, EndpointPolicyTemplateBySgt>>, RpcResult<Void>>
+ createProcessAllFunction(final EndpointForwardingTemplateBySubnet epForwardingTemplate) {
+ return new AsyncFunction<Optional<Pair<MasterDatabaseBinding, EndpointPolicyTemplateBySgt>>, RpcResult<Void>>() {
+ @Override
+ public ListenableFuture<RpcResult<Void>>
+ apply(final Optional<Pair<MasterDatabaseBinding, EndpointPolicyTemplateBySgt>> input) throws Exception {
+ final ListenableFuture<RpcResult<Void>> result;
+ if (input == null || !input.isPresent()) {
+ LOG.debug("no epPolicyTemplate available for ip-prefix: {}", epForwardingTemplate.getIpPrefix());
+ result = Futures.immediateFuture(
+ RpcResultBuilder.<Void>failed()
+ .withError(RpcError.ErrorType.APPLICATION,
+ "no epForwardingTemplate available for ip-prefix " + epForwardingTemplate.getIpPrefix())
+ .build());
+ } else {
+ LOG.trace("processing epForwardingTemplate event for ip-prefix: {}", epForwardingTemplate.getIpPrefix());
+ final Pair<MasterDatabaseBinding, EndpointPolicyTemplateBySgt> pair = input.get();
+ final MasterDatabaseBinding sxpMasterDBBinding = pair.getLeft();
+ final EndpointPolicyTemplateBySgt epPolicyTemplate = pair.getRight();
+ LOG.trace("processing epForwardingTemplate event with resolved sxpMasterDb entry and " +
+ "epPolicyTemplate for sgt/ip-prefix: {}/{}",
+ sxpMasterDBBinding.getSecurityGroupTag(), sxpMasterDBBinding.getImplementedInterface());
+ result = sxpMapperReactor.processTemplatesAndSxpMasterDB(epPolicyTemplate, epForwardingTemplate, sxpMasterDBBinding);
+ }
+
+ return result;
+ }
+ };
+ }
+
+ private AsyncFunction<Optional<MasterDatabaseBinding>, Optional<Pair<MasterDatabaseBinding, EndpointPolicyTemplateBySgt>>>
+ createReadAndPairTemplateToBindingFunction(final EndpointForwardingTemplateBySubnet epFowardingTemplate) {
+ return new AsyncFunction<Optional<MasterDatabaseBinding>, Optional<Pair<MasterDatabaseBinding, EndpointPolicyTemplateBySgt>>>() {
+ @Override
+ public ListenableFuture<Optional<Pair<MasterDatabaseBinding, EndpointPolicyTemplateBySgt>>>
+ apply(final Optional<MasterDatabaseBinding> input) throws Exception {
+ final ListenableFuture<Pair<MasterDatabaseBinding, EndpointPolicyTemplateBySgt>> result;
+ if (input == null || !input.isPresent()) {
+ LOG.debug("no sxpMasterDB entry available for ip-prefix: {}", epFowardingTemplate.getIpPrefix());
+ result = Futures.immediateFuture(null);
+ } else {
+ LOG.trace("processing sxpMasterDB entry for ip-prefix: {}", epFowardingTemplate.getIpPrefix());
+ final MasterDatabaseBinding masterDBItem = input.get();
+ final ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> epPolicyTemplateRead =
+ epPolicyTemplateDao.read(masterDBItem.getSecurityGroupTag());
+ result = EPTemplateUtil.wrapToPair(masterDBItem, epPolicyTemplateRead);
+ }
+
+ return EPTemplateUtil.wrapToOptional(result);
+ }
+ };
+ }
+
+
+ @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.ep.provider.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.Collections;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.apache.commons.lang3.tuple.Pair;
+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.ep.provider.impl.DSAsyncDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.EPTemplateListener;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.ReadableAsyncByKey;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SimpleCachedDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SxpMapperReactor;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.EPTemplateUtil;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.L3EPServiceUtil;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.SxpListenerUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.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.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+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 ReadableAsyncByKey<Sgt, MasterDatabaseBinding> masterDBBindingDao;
+ private final DSAsyncDao<IpPrefix, EndpointForwardingTemplateBySubnet> epForwardingTemplateDao;
+
+ public EPPolicyTemplateListenerImpl(final DataBroker dataBroker,
+ final SxpMapperReactor sxpMapperReactor,
+ final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> templateCachedDao,
+ final ReadableAsyncByKey<Sgt, MasterDatabaseBinding> masterDBBindingDao,
+ final DSAsyncDao<IpPrefix, EndpointForwardingTemplateBySubnet> epForwardingTemplateDao) {
+ this.sxpMapperReactor = Preconditions.checkNotNull(sxpMapperReactor);
+ this.templateCachedDao = Preconditions.checkNotNull(templateCachedDao);
+ this.masterDBBindingDao = Preconditions.checkNotNull(masterDBBindingDao);
+ this.epForwardingTemplateDao = Preconditions.checkNotNull(epForwardingTemplateDao);
+ 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();
+ processWithEPTemplates(epPolicyTemplate);
+ }
+ }
+
+ private void processWithEPTemplates(final EndpointPolicyTemplateBySgt epPolicyTemplate) {
+ final ListenableFuture<Collection<MasterDatabaseBinding>> sxpMasterDbItemsRead =
+ masterDBBindingDao.readBy(epPolicyTemplate.getSgt());
+
+ // find all available epForwardingTemplates and pair those to sxpMasterDBBinding
+ final ListenableFuture<List<Pair<MasterDatabaseBinding, EndpointForwardingTemplateBySubnet>>> epForwardingTemplatesRead =
+ Futures.transform(sxpMasterDbItemsRead, createReadAndPairTemplateToBindingFunction(epPolicyTemplate));
+
+ // invoke sxpMapperReactor.process for every valid combination of sxpMasterDBBinding, epPolicyTemplate, epForwardingTemplate
+ final ListenableFuture<List<RpcResult<Void>>> rpcResult =
+ Futures.transform(epForwardingTemplatesRead, createProcessAllFunction(epPolicyTemplate));
+
+ Futures.addCallback(rpcResult, RPC_RESULT_FUTURE_CALLBACK);
+ }
+
+ private AsyncFunction<List<Pair<MasterDatabaseBinding, EndpointForwardingTemplateBySubnet>>, List<RpcResult<Void>>>
+ createProcessAllFunction(final EndpointPolicyTemplateBySgt epPolicyTemplate) {
+ return new AsyncFunction<List<Pair<MasterDatabaseBinding, EndpointForwardingTemplateBySubnet>>, List<RpcResult<Void>>>() {
+ @Override
+ public ListenableFuture<List<RpcResult<Void>>>
+ apply(final List<Pair<MasterDatabaseBinding, EndpointForwardingTemplateBySubnet>> input) throws Exception {
+ final ListenableFuture<List<RpcResult<Void>>> result;
+ if (input == null || input.isEmpty()) {
+ LOG.debug("no epForwardingTemplate available for sgt: {}", epPolicyTemplate.getSgt());
+ result = Futures.immediateFuture(Collections.singletonList(
+ RpcResultBuilder.<Void>failed()
+ .withError(RpcError.ErrorType.APPLICATION,
+ "no epForwardingTemplate available for sgt " + epPolicyTemplate.getSgt())
+ .build()));
+ } else {
+ LOG.trace("processing epPolicyTemplate event for sgt: {}", epPolicyTemplate.getSgt());
+ List<ListenableFuture<RpcResult<Void>>> allResults = new ArrayList<>(input.size());
+ for (Pair<MasterDatabaseBinding, EndpointForwardingTemplateBySubnet> pair : input) {
+ final MasterDatabaseBinding sxpMasterDBBinding = pair.getLeft();
+ final EndpointForwardingTemplateBySubnet epForwardingTemplate = pair.getRight();
+ if (epForwardingTemplate != null) {
+ LOG.trace("processing epPolicyTemplate event with resolved sxpMasterDb entry and " +
+ "epForwardingTemplate for sgt/ip-prefix: {}/{}",
+ sxpMasterDBBinding.getSecurityGroupTag(), sxpMasterDBBinding.getImplementedInterface());
+ allResults.add(sxpMapperReactor.processTemplatesAndSxpMasterDB(
+ epPolicyTemplate, epForwardingTemplate, sxpMasterDBBinding));
+ }
+ }
+ result = Futures.successfulAsList(allResults);
+ }
+
+ return result;
+ }
+};
+ }
+
+ private AsyncFunction<Collection<MasterDatabaseBinding>, List<Pair<MasterDatabaseBinding, EndpointForwardingTemplateBySubnet>>>
+ createReadAndPairTemplateToBindingFunction(final EndpointPolicyTemplateBySgt epPolicyTemplate) {
+ return new AsyncFunction<Collection<MasterDatabaseBinding>, List<Pair<MasterDatabaseBinding, EndpointForwardingTemplateBySubnet>>>() {
+ @Override
+ public ListenableFuture<List<Pair<MasterDatabaseBinding, EndpointForwardingTemplateBySubnet>>>
+ apply(final Collection<MasterDatabaseBinding> input) throws Exception {
+ final ListenableFuture<List<Pair<MasterDatabaseBinding, EndpointForwardingTemplateBySubnet>>> result;
+ if (input == null || input.isEmpty()) {
+ LOG.debug("no sxpMasterDB entry available for sgt: {}", epPolicyTemplate.getSgt());
+ result = Futures.immediateFuture(Collections.emptyList());
+ } else {
+ LOG.trace("processing sxpMasterDB entries for sgt: {}", epPolicyTemplate.getSgt());
+ List<ListenableFuture<Pair<MasterDatabaseBinding, EndpointForwardingTemplateBySubnet>>> allResults =
+ new ArrayList<>(input.size());
+ for (MasterDatabaseBinding masterDBItem : input) {
+ final ListenableFuture<Optional<EndpointForwardingTemplateBySubnet>> epForwardingTemplateRead =
+ epForwardingTemplateDao.read(masterDBItem.getIpPrefix());
+ allResults.add(EPTemplateUtil.wrapToPair(masterDBItem, epForwardingTemplateRead));
+ }
+ result = Futures.successfulAsList(allResults);
+ }
+
+ return result;
+ }
+ };
+ }
+
+ @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.ep.provider.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.ClusteredDataTreeChangeListener;
+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.ep.provider.impl.DSAsyncDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.MasterDatabaseBindingListener;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SimpleCachedDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SxpMapperReactor;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.EPTemplateUtil;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.L3EPServiceUtil;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.SxpListenerUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.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.network.topology.topology.node.SxpDomains;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.sxp.domains.SxpDomain;
+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.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+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 ClusteredDataTreeChangeListener> 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);
+
+ //TODO: get exact sxp-node path from config (pointing to ise listener).. start listening later - when config appears
+ sxpDbPath = MasterDatabaseBindingListener.SXP_TOPOLOGY_PATH
+ .child(Node.class)
+ .augmentation(SxpNodeIdentity.class)
+ .child(SxpDomains.class)
+ .child(SxpDomain.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
+ LOG.debug("ip-sgt mapping was removed - NOOP: {}",
+ change.getRootPath().getRootIdentifier().firstKeyOf(MasterDatabaseBinding.class));
+ } else {
+ final IpPrefix ipPrefixKey = sxpMasterDBItem.getIpPrefix();
+ SxpListenerUtil.updateCachedDao(masterDBBindingDaoCached, ipPrefixKey, change);
+ processWithEPTemplates(sxpMasterDBItem);
+ }
+ }
+ }
+
+ private void processWithEPTemplates(final MasterDatabaseBinding sxpMasterDBItem) {
+ final ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> epPolicyTemplateFuture =
+ epPolicyTemplateDao.read(sxpMasterDBItem.getSecurityGroupTag());
+
+ final ListenableFuture<Optional<EndpointForwardingTemplateBySubnet>> epForwardingTemplateFuture =
+ epForwardingTemplateDao.read(sxpMasterDBItem.getIpPrefix());
+
+ final ListenableFuture<EPTemplateUtil.OptionalMutablePair<EndpointPolicyTemplateBySgt, EndpointForwardingTemplateBySubnet>> compositeRead
+ = EPTemplateUtil.compositeRead(epPolicyTemplateFuture, epForwardingTemplateFuture);
+
+ final ListenableFuture<RpcResult<Void>> rpcResult = Futures.transform(compositeRead,
+ new AsyncFunction<EPTemplateUtil.OptionalMutablePair<EndpointPolicyTemplateBySgt, EndpointForwardingTemplateBySubnet>, RpcResult<Void>>() {
+ @Override
+ public ListenableFuture<RpcResult<Void>> apply(final EPTemplateUtil.OptionalMutablePair<EndpointPolicyTemplateBySgt, EndpointForwardingTemplateBySubnet> input) throws Exception {
+ final ListenableFuture<RpcResult<Void>> result;
+ if (input == null) {
+ LOG.debug("no ep*Templates available for sgt/ip-prefix: {}/{}",
+ sxpMasterDBItem.getSecurityGroupTag(),
+ sxpMasterDBItem.getIpPrefix());
+ result = RpcResultBuilder.<Void>failed()
+ .withError(RpcError.ErrorType.APPLICATION,
+ "no ep-templates available for" + sxpMasterDBItem)
+ .buildFuture();
+
+ } else if (!input.getLeft().isPresent()) {
+ LOG.debug("no epPolicyTemplate available for sgt: {}", sxpMasterDBItem.getSecurityGroupTag());
+ result = RpcResultBuilder.<Void>failed()
+ .withError(RpcError.ErrorType.APPLICATION,
+ "no epPolicyTemplate available for " + sxpMasterDBItem)
+ .buildFuture();
+ } else if (!input.getRight().isPresent()) {
+ LOG.debug("no epForwardingTemplate available for ip-prefix: {}",
+ sxpMasterDBItem.getIpPrefix());
+ result = RpcResultBuilder.<Void>failed()
+ .withError(RpcError.ErrorType.APPLICATION,
+ "no epForwardingTemplate available for " + sxpMasterDBItem)
+ .buildFuture();
+ } else {
+ LOG.trace("processing sxpMasterDB event and epPolicyTemplate for sgt/ip-prefix: {}/{}",
+ sxpMasterDBItem.getSecurityGroupTag(),
+ sxpMasterDBItem.getIpPrefix());
+ result = sxpMapperReactor.processTemplatesAndSxpMasterDB(input.getLeft().get(),
+ input.getRight().get(), sxpMasterDBItem);
+ }
+ return result;
+ }
+ });
+
+ 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.ep.provider.impl.util;
+
+import com.google.common.base.Function;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Optional;
+import com.google.common.collect.Ordering;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.apache.commons.lang3.tuple.MutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.commons.net.util.SubnetUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt;
+
+/**
+ * Purpose: util methods for {@link EndpointForwardingTemplateBySubnet} and {@link EndpointPolicyTemplateBySgt}
+ */
+public final class EPTemplateUtil {
+
+ public static final String FULL_IPV4_MASK_SUFFIX = "/32";
+ private static final Comparable EMPTY_COMPARABLE = "";
+
+ private EPTemplateUtil() {
+ 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());
+ }
+
+ public static <L, R> ListenableFuture<OptionalMutablePair<L, R>> compositeRead(
+ final ListenableFuture<Optional<L>> leftRead, final ListenableFuture<Optional<R>> rightRead) {
+
+ final OptionalMutablePair<L, R> compositeResult = new OptionalMutablePair<>();
+ final List<ListenableFuture<?>> results = new ArrayList<>(2);
+
+ results.add(Futures.transform(leftRead, new Function<Optional<L>, OptionalMutablePair<L, R>>() {
+ @Nullable
+ @Override
+ public OptionalMutablePair<L, R> apply(@Nullable final Optional<L> input) {
+ compositeResult.setLeft(input);
+ return compositeResult;
+ }
+ }));
+
+ results.add(Futures.transform(rightRead, new Function<Optional<R>, OptionalMutablePair<L, R>>() {
+ @Nullable
+ @Override
+ public OptionalMutablePair<L, R> apply(@Nullable final Optional<R> input) {
+ compositeResult.setRight(input);
+ return compositeResult;
+ }
+ }));
+
+ return Futures.transform(Futures.successfulAsList(results),
+ new Function<List<?>, OptionalMutablePair<L, R>>() {
+ @Nullable
+ @Override
+ public OptionalMutablePair<L, R> apply(@Nullable final List<?> input) {
+ return compositeResult;
+ }
+ });
+ }
+
+ public static <K, V> ListenableFuture<Pair<K, V>> wrapToPair(
+ final K keyItem,
+ final ListenableFuture<Optional<V>> valueFromRead) {
+ return Futures.transform(valueFromRead, new Function<Optional<V>, Pair<K, V>>() {
+ @Nullable
+ @Override
+ public Pair<K, V> apply(@Nullable final Optional<V> input) {
+ return new MutablePair<>(keyItem, input.orNull());
+ }
+ });
+ }
+
+ public static <V> ListenableFuture<Optional<V>> wrapToOptional(final ListenableFuture<V> value) {
+ return Futures.transform(value, new Function<V, Optional<V>>() {
+ @Nullable
+ @Override
+ public Optional<V> apply(@Nullable final V input) {
+ return Optional.fromNullable(input);
+ }
+ });
+ }
+
+ public static Ordering<EndpointGroupId> createEndpointGroupIdOrdering() {
+ return Ordering.natural().onResultOf(new Function<EndpointGroupId, Comparable>() {
+ @Nullable
+ @Override
+ public Comparable apply(@Nullable final EndpointGroupId input) {
+ if (input == null) {
+ return EMPTY_COMPARABLE;
+ }
+ return MoreObjects.firstNonNull(input.getValue(), EMPTY_COMPARABLE);
+ }
+ });
+ }
+
+ public static Ordering<ConditionName> createConditionNameOrdering() {
+ return Ordering.natural().onResultOf(new Function<ConditionName, Comparable>() {
+ @Nullable
+ @Override
+ public Comparable apply(@Nullable final ConditionName input) {
+ if (input == null) {
+ return EMPTY_COMPARABLE;
+ }
+ return MoreObjects.firstNonNull(input.getValue(), EMPTY_COMPARABLE);
+ }
+ });
+ }
+
+ public static class OptionalMutablePair<L, R> extends MutablePair<Optional<L>, Optional<R>> {
+ public OptionalMutablePair() {
+ super(Optional.absent(), Optional.absent());
+ }
+ }
+}
--- /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.ep.provider.impl.util;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.IpPrefixEqualCommand;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.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.ep.provider.impl.util;
+
+import javax.annotation.Nonnull;
+import org.apache.commons.net.util.SubnetUtils;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.IpPrefixEqualCommand;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.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.ep.provider.impl.util;
+
+import com.google.common.util.concurrent.FutureCallback;
+import javax.annotation.Nullable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Purpose: place for common functionality regarding endpoint tasks
+ */
+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.ep.provider.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.ep.provider.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.ep.provider.impl.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
+ */
+
+module sxp-ep-provider-cfg {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:config:groupbasedpolicy:sxp-integration:sxp-ep-provider";
+ prefix "sxp-ep-prvd-cfg";
+
+ import config { prefix config; revision-date 2013-04-05; }
+ import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
+ import groupbasedpolicy-cfg {prefix gbpcfg; revision-date 2015-11-06; }
+
+ description
+ "This module contains the base YANG definitions for
+ sxf-integration : sxp-ep-provider impl configuration.";
+
+ revision "2016-07-22" {
+ description
+ "Initial revision.";
+ }
+
+ identity sxp-ep-provider-impl {
+ description
+ "sxp-ep-provider impl module";
+
+ base "config:module-type";
+ config:java-name-prefix SxpEpProviderProvider;
+ }
+
+ // Augments the 'configuration' choice node under modules/module.
+ augment "/config:modules/config:module/config:configuration" {
+ case sxp-ep-provider-impl {
+ when "/config:modules/config:module/config:type = 'sxp-ep-provider-impl'";
+
+ //wires in the data-broker service
+ container data-broker {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity mdsal:binding-async-data-broker;
+ }
+ }
+ }
+ //RPC Registry
+ container rpc-registry {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity mdsal:binding-rpc-registry;
+ }
+ }
+ }
+ //Domain specific registry
+ container domain-specific-registry {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity gbpcfg:domain-specific-registry;
+ }
+ }
+ }
+ }
+ }
+}
--- /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
+ */
+
+module sxp-ep-provider-model {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:config:groupbasedpolicy:sxp-ep-provider:model";
+ prefix "sxp-ep-prvd-model";
+
+ import sxp-database { prefix sxp-database; revision-date 2016-03-08; }
+ import gbp-common { prefix gbp-common; revision-date 2014-04-21; }
+ import ietf-inet-types { prefix inet; revision-date 2013-07-15; }
+ import forwarding { prefix forwarding; revision-date 2016-04-27; }
+ import base-endpoint { prefix base-edpoint; revision-date 2016-04-27; }
+ import yang-ext { prefix ext; revision-date 2013-07-09; }
+ import renderer { prefix renderer; revision-date 2015-11-03; }
+
+ description
+ "This module contains the YANG definitions for
+ sxp-ep-provider implementation.";
+
+ revision "2016-03-02" {
+ description
+ "Initial revision.";
+ }
+
+ container sxp-ep-mapper {
+ description "root point for endpoint templates";
+
+ list endpoint-policy-template-by-sgt {
+ key sgt;
+ leaf sgt {
+ type sxp-database:sgt;
+ description
+ "SGT for which this endpoint template is used";
+ }
+ leaf tenant {
+ type gbp-common:tenant-id;
+ mandatory true;
+ description
+ "The tenant of this endpoint";
+ }
+ leaf-list endpoint-groups {
+ type gbp-common:endpoint-group-id;
+ min-elements 1;
+ description
+ "The groups associated with this endpoint";
+ }
+ leaf-list conditions {
+ type gbp-common:condition-name;
+ description
+ "The conditions associated with this endpoint";
+ }
+ }
+
+ list endpoint-forwarding-template-by-subnet {
+ description "If the IP from IP/SGT binding is inside of ip-prefix then
+ the endpoint will be in the l3-context.";
+ key ip-prefix;
+ leaf ip-prefix {
+ type inet:ip-prefix;
+ description
+ "The IP prefix where an endpoint can be connected.";
+ }
+ leaf l3-context {
+ type gbp-common:context-id;
+ mandatory true;
+ description
+ "The context for the endpoint's layer 3 address";
+ }
+ container network-containment {
+ description
+ "The network domain associated with this endpoint's fowarding
+ context.";
+ uses forwarding:network-domain-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.ep.provider.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.EpPolicyTemplateValueKey;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.EpPolicyTemplateValueKeyFactory;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.EPTemplateUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointRegBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointRegBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgtBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+
+/**
+ * Test for {@link SxpEndpointAugmentorImpl}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class SxpEndpointAugmentorImplTest {
+
+ @Mock
+ private ReadableByKey<EpPolicyTemplateValueKey, EndpointPolicyTemplateBySgt> epPolicyDao;
+ @Spy
+ private EpPolicyTemplateValueKeyFactory keyFactory = new EpPolicyTemplateValueKeyFactory(
+ EPTemplateUtil.createEndpointGroupIdOrdering(), EPTemplateUtil.createConditionNameOrdering());
+ @Captor
+ private ArgumentCaptor<EpPolicyTemplateValueKey> keyCapt;
+
+ private SxpEndpointAugmentorImpl augmetor;
+
+ @Before
+ public void setUp() throws Exception {
+ augmetor = new SxpEndpointAugmentorImpl(epPolicyDao, keyFactory);
+ }
+
+ @Test
+ public void testBuildAddressEndpointWithLocationAugmentation() throws Exception {
+ final TenantId tenantId = new TenantId("tn1");
+ final AddressEndpoint endpoint = new AddressEndpointBuilder()
+ .setTenant(tenantId)
+ .setCondition(buildConditions(new String[]{"cn2", "cn1"}))
+ .setEndpointGroup(buildEndpointGroupIds(new String[]{"epg2", "epg1"}))
+ .build();
+
+ Mockito.doCallRealMethod().when(keyFactory).sortValueKeyLists(Matchers.<EndpointPolicyTemplateBySgt>any());
+ final List<ConditionName> conditions = buildConditions(new String[]{"cn1", "cn2"});
+ final List<EndpointGroupId> endpointGroupIds = buildEndpointGroupIds(new String[]{"epg1", "epg2"});
+ final EndpointPolicyTemplateBySgt epPolicyTemplate = new EndpointPolicyTemplateBySgtBuilder()
+ .setTenant(tenantId)
+ .setEndpointGroups(endpointGroupIds)
+ .setConditions(conditions)
+ .setSgt(new Sgt(42))
+ .build();
+
+ Mockito.when(epPolicyDao.readBy(keyCapt.capture())).thenReturn(Collections.singletonList(epPolicyTemplate));
+
+ final Map.Entry<Class<? extends Augmentation<AddressEndpointWithLocation>>, Augmentation<AddressEndpointWithLocation>>
+ augmentationEntry = augmetor.buildAddressEndpointWithLocationAugmentation(endpoint);
+
+// Assert.assertEquals(AddressEndpointWithLocationAug.class, augmentationEntry.getKey());
+// Assert.assertTrue(DataObject.class.isAssignableFrom(augmentationEntry.getValue().getClass()));
+// Assert.assertEquals(AddressEndpointWithLocationAug.class, ((DataObject) augmentationEntry.getValue()).getImplementedInterface());
+// Assert.assertEquals(42, ((AddressEndpointWithLocationAug) augmentationEntry.getValue()).getSgt().getValue().intValue());
+
+ final EpPolicyTemplateValueKey keyValue = keyCapt.getValue();
+ Assert.assertEquals(tenantId, keyValue.getTenantId());
+ Assert.assertEquals(endpointGroupIds, keyValue.getEpgId());
+ Assert.assertEquals(conditions, keyValue.getConditionName());
+ }
+
+ private static List<EndpointGroupId> buildEndpointGroupIds(final String[] names) {
+ final List<EndpointGroupId> endpointGroupIds = new ArrayList<>();
+ for (String epgId : names) {
+ endpointGroupIds.add(new EndpointGroupId(epgId));
+ }
+ return endpointGroupIds;
+ }
+
+ private static List<ConditionName> buildConditions(final String[] names) {
+ final List<ConditionName> conditions = new ArrayList<>();
+ for (String condition : names) {
+ conditions.add(new ConditionName(condition));
+ }
+ return conditions;
+ }
+
+ @Test
+ public void testBuildAddressEndpointAugmentation() throws Exception {
+ final AddressEndpointReg endpoint = new AddressEndpointRegBuilder().build();
+ Assert.assertNull(augmetor.buildAddressEndpointAugmentation(endpoint));
+ }
+
+ @Test
+ public void testBuildContainmentEndpointAugmentation() throws Exception {
+ final ContainmentEndpointReg endpoint = new ContainmentEndpointRegBuilder().build();
+ Assert.assertNull(augmetor.buildContainmentEndpointAugmentation(endpoint));
+ }
+
+ @Test
+ public void testBuildContainmentEndpointWithLocationAugmentation() throws Exception {
+ final ContainmentEndpoint endpoint = new ContainmentEndpointBuilder().build();
+ Assert.assertNull(augmetor.buildContainmentEndpointWithLocationAugmentation(endpoint));
+ }
+}
\ 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.ep.provider.impl;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+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.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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.endpoint.forwarding.template.by.subnet.NetworkContainment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+
+/**
+ * Test for {@link SxpMapperReactorImpl}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class SxpMapperReactorImplTest {
+
+ private static final IpPrefix IP_PREFIX = new IpPrefix(new Ipv4Prefix("10.11.12.1/32"));
+
+ @Mock
+ private BaseEndpointService l3EndpointService;
+ @Mock
+ private EndpointPolicyTemplateBySgt epPolicyTemplate;
+ @Mock
+ private MasterDatabaseBinding masterDBBinding;
+ @Mock
+ private EndpointForwardingTemplateBySubnet epForwardingTemplate;
+ @Mock
+ private NetworkContainment networkContainment;
+ @Mock
+ private DataBroker dataBroker;
+ @Mock
+ private ReadOnlyTransaction rTx;
+
+ private SxpMapperReactorImpl sxpMapperReactor;
+
+ @Before
+ public void setUp() throws Exception {
+ sxpMapperReactor = new SxpMapperReactorImpl(l3EndpointService, dataBroker);
+ Mockito.when(l3EndpointService.registerEndpoint(Matchers.<RegisterEndpointInput>any()))
+ .thenReturn(RpcResultBuilder.<Void>success().buildFuture());
+ Mockito.when(masterDBBinding.getIpPrefix()).thenReturn(IP_PREFIX);
+ Mockito.when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx);
+ Mockito.when(rTx.read(Matchers.same(LogicalDatastoreType.OPERATIONAL),
+ Matchers.<InstanceIdentifier<AddressEndpoint>>any())).thenReturn(Futures.immediateCheckedFuture(Optional.absent()));
+ Mockito.when(epForwardingTemplate.getNetworkContainment()).thenReturn(networkContainment);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ Mockito.verifyNoMoreInteractions(l3EndpointService);
+ }
+
+ @Test
+ public void testProcessTemplatesAndSxpMasterDB() throws Exception {
+ Mockito.when(epForwardingTemplate.getIpPrefix()).thenReturn(IP_PREFIX);
+ sxpMapperReactor.processTemplatesAndSxpMasterDB(epPolicyTemplate, 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.ep.provider.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.ep.provider.impl.SimpleCachedDao;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.SxpEpMapper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.SxpEpMapperBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnetBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Test for {@link EPForwardingTemplateDaoImpl}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class EPForwardingTemplateDaoImplTest {
+
+ public static final InstanceIdentifier<SxpEpMapper> SXP_MAPPER_PATH = InstanceIdentifier.create(SxpEpMapper.class);
+ private static final IpPrefix KEY_1 = new IpPrefix(new Ipv4Prefix("1.2.3.4/32"));
+ private final SxpEpMapper 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 SxpEpMapperBuilder()
+ .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<SxpEpMapper>>any())).thenReturn(
+ Futures.<Optional<SxpEpMapper>, ReadFailedException>immediateCheckedFuture(Optional.<SxpEpMapper>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<SxpEpMapper>>any())).thenReturn(
+ Futures.<Optional<SxpEpMapper>, 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<SxpEpMapper> 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.ep.provider.impl.dao;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+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 org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.InOrder;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+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.ep.provider.impl.SimpleCachedDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.EPTemplateUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.SxpEpMapper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgtBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.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;
+ @Spy
+ private EpPolicyTemplateValueKeyFactory keyFactory = new EpPolicyTemplateValueKeyFactory(
+ EPTemplateUtil.createEndpointGroupIdOrdering(), EPTemplateUtil.createConditionNameOrdering());
+ @Captor
+ ArgumentCaptor<Sgt> sgtCapt;
+ @Captor
+ ArgumentCaptor<EndpointPolicyTemplateBySgt> epPolicyTemplateCapt;
+
+ 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, keyFactory);
+ }
+
+ @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(cachedDao.isEmpty()).thenReturn(true);
+ 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)));
+ Mockito.doCallRealMethod().when(keyFactory).sortValueKeyLists(Matchers.<EndpointPolicyTemplateBySgt>any());
+
+ 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(SxpEpMapper.class)
+ .child(EndpointPolicyTemplateBySgt.class, new EndpointPolicyTemplateBySgtKey(KEY_1));
+
+ final InstanceIdentifier<EndpointPolicyTemplateBySgt> readPath = dao.buildReadPath(KEY_1);
+ Assert.assertEquals(expectedPath, readPath);
+ }
+
+ @Test
+ public void testReadBy_single() throws Exception {
+ final EpPolicyTemplateValueKey key = new EpPolicyTemplateValueKey(new TenantId("tn1"),
+ buildEndpointGroupIds(new String[]{"epg1", "epg2"}),
+ buildConditions(new String[]{"cn1", "cn2"}));
+
+ Mockito.doCallRealMethod().when(keyFactory).createKeyWithDefaultOrdering(Matchers.<EndpointPolicyTemplateBySgt>any());
+
+ Mockito.when(cachedDao.values()).thenReturn(Lists.newArrayList(
+ createEpPolicytemplate(new Sgt(1), new String[]{"cn2", "cn1"}, new String[]{"epg1", "epg2"}, "tn1"),
+ createEpPolicytemplate(new Sgt(2), new String[]{"cn1", "cn2"}, new String[]{"epg2", "epg1"}, "tn1"),
+ createEpPolicytemplate(new Sgt(3), new String[]{"cn2", "cn1"}, new String[]{"epg2", "epg1"}, "tn1"),
+ createEpPolicytemplate(new Sgt(4), new String[]{"cn1", "cn2"}, new String[]{"epg1", "epg2"}, "tn1")
+ ));
+
+ final Collection<EndpointPolicyTemplateBySgt> policyTemplates = dao.readBy(key);
+ Assert.assertEquals(1, policyTemplates.size());
+ Assert.assertEquals(4, Iterables.getFirst(policyTemplates, null).getSgt().getValue().intValue());
+ }
+
+ @Test
+ public void testRead_unsortedLists() throws Exception {
+ final EndpointPolicyTemplateBySgt epPolicytemplateUnsorted = createEpPolicytemplate(new Sgt(1),
+ new String[]{"cn2", "cn1"}, new String[]{"epg2", "epg1"}, "tn1");
+
+ Mockito.doCallRealMethod().when(keyFactory).createKeyWithDefaultOrdering(Matchers.<EndpointPolicyTemplateBySgt>any());
+
+ Mockito.when(cachedDao.find(Matchers.<Sgt>any())).thenReturn(
+ Optional.<EndpointPolicyTemplateBySgt>absent());
+ Mockito.when(cachedDao.isEmpty()).thenReturn(true);
+ 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(epPolicytemplateUnsorted)));
+
+ dao.read(new Sgt(1));
+
+ Mockito.verify(cachedDao).update(sgtCapt.capture(), epPolicyTemplateCapt.capture());
+ Mockito.verify(cachedDao).find(sgtCapt.capture());
+
+ Assert.assertEquals(1, sgtCapt.getValue().getValue().intValue());
+ final EndpointPolicyTemplateBySgt template = epPolicyTemplateCapt.getValue();
+ Assert.assertEquals(1, template.getSgt().getValue().intValue());
+ Assert.assertEquals("tn1", template.getTenant().getValue());
+ Assert.assertEquals(buildEndpointGroupIds(new String[]{"epg1", "epg2"}), template.getEndpointGroups());
+ Assert.assertEquals(buildConditions(new String[]{"cn1", "cn2"}), template.getConditions());
+ }
+
+
+ private EndpointPolicyTemplateBySgt createEpPolicytemplate(final Sgt sgt, final String[] conditionNames,
+ final String[] epgIds, final String tenant) {
+ return new EndpointPolicyTemplateBySgtBuilder()
+ .setSgt(sgt)
+ .setEndpointGroups(buildEndpointGroupIds(epgIds))
+ .setConditions(buildConditions(conditionNames))
+ .setTenant(new TenantId(tenant))
+ .build();
+ }
+
+ private static List<EndpointGroupId> buildEndpointGroupIds(final String[] names) {
+ final List<EndpointGroupId> endpointGroupIds = new ArrayList<>();
+ for (String epgId : names) {
+ endpointGroupIds.add(new EndpointGroupId(epgId));
+ }
+ return endpointGroupIds;
+ }
+
+ private static List<ConditionName> buildConditions(final String[] names) {
+ final List<ConditionName> conditions = new ArrayList<>();
+ for (String condition : names) {
+ conditions.add(new ConditionName(condition));
+ }
+ return conditions;
+ }
+}
\ 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.ep.provider.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.ep.provider.impl.SimpleCachedDao;
+import org.opendaylight.sxp.core.Configuration;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.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.network.topology.topology.node.SxpDomainsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.sxp.domains.SxpDomainBuilder;
+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()
+ .setSxpDomains(new SxpDomainsBuilder()
+ .setSxpDomain(Collections.singletonList(new SxpDomainBuilder()
+ .setDomainName("global")
+ .setMasterDatabase(new MasterDatabaseBuilder()
+ .setMasterDatabaseBinding(Lists.newArrayList(MASTER_DB_BINDING_VALUE))
+ .build())
+ .build()))
+ .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(cachedDao.isEmpty()).thenReturn(true);
+ 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.ep.provider.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.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.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.ep.provider.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.ep.provider.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.ClusteredDataTreeChangeListener;
+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.ep.provider.impl.DSAsyncDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.EPTemplateListener;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SimpleCachedDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SxpMapperReactor;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnetKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.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.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+
+/**
+ * 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 DSAsyncDao<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateDao;
+ @Mock
+ private ListenerRegistration<? extends EPTemplateListener> listenerRegistration;
+ @Mock
+ private DataTreeModification<EndpointForwardingTemplateBySubnet> dataTreeModification;
+ @Mock
+ private DataObjectModification<EndpointForwardingTemplateBySubnet> dataObjectModification;
+
+ private EPForwardingTemplateListenerImpl listener;
+ public static final Sgt SGT = new Sgt(1);
+ public static final EndpointPolicyTemplateBySgt EP_POLICY_TEMPLATE = new EndpointPolicyTemplateBySgtBuilder()
+ .setSgt(SGT)
+ .build();
+
+ 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.<ClusteredDataTreeChangeListener>any())).thenReturn(listenerRegistration);
+ listener = new EPForwardingTemplateListenerImpl(dataBroker, sxpMapper, simpleCachedDao, masterDBBindingDao, epPolicyTemplateDao);
+ }
+
+ @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 IpPrefix ipPrefix = buildIpPrefix("1.2.3.4/32");
+ final MasterDatabaseBinding masterDBBinding = new MasterDatabaseBindingBuilder()
+ .setSecurityGroupTag(SGT)
+ .setIpPrefix(ipPrefix)
+ .build();
+ Mockito.when(masterDBBindingDao.read(Matchers.<IpPrefix>any())).thenReturn(
+ Futures.immediateFuture(Optional.of(masterDBBinding)));
+ Mockito.when(epPolicyTemplateDao.read(Matchers.<Sgt>any())).thenReturn(
+ Futures.immediateFuture(Optional.of(EP_POLICY_TEMPLATE)));
+ Mockito.when(sxpMapper.processTemplatesAndSxpMasterDB(Matchers.<EndpointPolicyTemplateBySgt>any(),
+ Matchers.<EndpointForwardingTemplateBySubnet>any(),Matchers.<MasterDatabaseBinding>any())).thenReturn(
+ RpcResultBuilder.success((Void) null).buildFuture());
+
+ listener.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+ final InOrder inOrder = Mockito.inOrder(masterDBBindingDao, simpleCachedDao, epPolicyTemplateDao, sxpMapper);
+ inOrder.verify(simpleCachedDao).update(IP_PREFIX_TMPL, EP_FW_TEMPLATE_VALUE);
+ inOrder.verify(masterDBBindingDao).read(IP_PREFIX_TMPL);
+ inOrder.verify(epPolicyTemplateDao).read(SGT);
+ inOrder.verify(sxpMapper).processTemplatesAndSxpMasterDB(EP_POLICY_TEMPLATE, EP_FW_TEMPLATE_VALUE, masterDBBinding);
+ 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.ep.provider.impl.listen;
+
+import com.google.common.base.Optional;
+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.ClusteredDataTreeChangeListener;
+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.ep.provider.impl.DSAsyncDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.EPTemplateListener;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.ReadableAsyncByKey;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SimpleCachedDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SxpMapperReactor;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgtBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.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;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+
+/**
+ * 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 static final IpPrefix IP_PREFIX_1 = new IpPrefix(new Ipv4Prefix("1.2.3.4/32"));
+ private static final IpPrefix IP_PREFIX_2 = new IpPrefix(new Ipv4Prefix("1.2.3.5/32"));
+ private final EndpointPolicyTemplateBySgt EP_PL_TEMPLATE_VALUE;
+
+ @Mock
+ private DataBroker dataBroker;
+ @Mock
+ private SxpMapperReactor sxpMapper;
+ @Mock
+ private SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> simpleCachedDao;
+ @Mock
+ private DSAsyncDao<IpPrefix, EndpointForwardingTemplateBySubnet> epForwardingTemplateDao;
+ @Mock
+ private ReadableAsyncByKey<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.<ClusteredDataTreeChangeListener>any())).thenReturn(listenerRegistration);
+ listener = new EPPolicyTemplateListenerImpl(dataBroker, sxpMapper, simpleCachedDao, masterDBDao, epForwardingTemplateDao);
+ }
+
+ @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 masterDBBinding1 = new MasterDatabaseBindingBuilder()
+ .setSecurityGroupTag(SGT_1)
+ .setIpPrefix(IP_PREFIX_1)
+ .build();
+ final MasterDatabaseBinding masterDBBinding2 = new MasterDatabaseBindingBuilder()
+ .setSecurityGroupTag(SGT_1)
+ .setIpPrefix(IP_PREFIX_2)
+ .build();
+
+ final EndpointForwardingTemplateBySubnet epForwardingTemplate1 = new EndpointForwardingTemplateBySubnetBuilder()
+ .setIpPrefix(IP_PREFIX_1)
+ .build();
+ final EndpointForwardingTemplateBySubnet epForwardingTemplate2 = new EndpointForwardingTemplateBySubnetBuilder()
+ .setIpPrefix(IP_PREFIX_2)
+ .build();
+
+ Mockito.when(masterDBDao.readBy(Matchers.<Sgt>any())).thenReturn(
+ Futures.immediateFuture(Lists.newArrayList(masterDBBinding1, masterDBBinding2)));
+ Mockito.when(epForwardingTemplateDao.read(Matchers.<IpPrefix>any())).thenReturn(
+ Futures.immediateFuture(Optional.of(epForwardingTemplate1)),
+ Futures.immediateFuture(Optional.of(epForwardingTemplate2)));
+ Mockito.when(sxpMapper.processTemplatesAndSxpMasterDB(Matchers.<EndpointPolicyTemplateBySgt>any(),
+ Matchers.<EndpointForwardingTemplateBySubnet>any(), Matchers.<MasterDatabaseBinding>any())).thenReturn(
+ RpcResultBuilder.success((Void) null).buildFuture());
+
+ listener.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+ final InOrder inOrder = Mockito.inOrder(masterDBDao, simpleCachedDao, epForwardingTemplateDao, sxpMapper);
+ inOrder.verify(simpleCachedDao).update(SGT_1, EP_PL_TEMPLATE_VALUE);
+ inOrder.verify(masterDBDao).readBy(SGT_1);
+ inOrder.verify(epForwardingTemplateDao).read(IP_PREFIX_1);
+ inOrder.verify(epForwardingTemplateDao).read(IP_PREFIX_2);
+ inOrder.verify(sxpMapper).processTemplatesAndSxpMasterDB(EP_PL_TEMPLATE_VALUE, epForwardingTemplate1, masterDBBinding1);
+ inOrder.verify(sxpMapper).processTemplatesAndSxpMasterDB(EP_PL_TEMPLATE_VALUE, epForwardingTemplate2, masterDBBinding2);
+ 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.ep.provider.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.ClusteredDataTreeChangeListener;
+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.ep.provider.impl.DSAsyncDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.EPTemplateListener;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.MasterDatabaseBindingListener;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SimpleCachedDao;
+import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SxpMapperReactor;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.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.network.topology.topology.node.SxpDomains;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.sxp.domains.SxpDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.sxp.domains.SxpDomainKey;
+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(SxpDomains.class)
+ .child(SxpDomain.class, new SxpDomainKey("global"))
+ .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.<ClusteredDataTreeChangeListener>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(epForwardingTemplateDao).read(IP_PREFIX);
+ inOrder.verify(sxpMapper).processTemplatesAndSxpMasterDB(epPolicyTemplate, 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.ep.provider.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.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+
+/**
+ * Test for {@link EPTemplateUtil}.
+ */
+public class EPTemplateUtilTest {
+
+ 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(EPTemplateUtil.isPlain(IP_PREFIX_24));
+ Assert.assertTrue(EPTemplateUtil.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 = EPTemplateUtil.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
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">\r
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">\r
+\r
+ <appender name="console" class="org.apache.log4j.ConsoleAppender">\r
+ <layout class="org.apache.log4j.PatternLayout">\r
+ <param name="ConversionPattern" value="%-6p %d{HH:mm:ss.SSS} [%10.10t] %30.30c %x - %m%n"/>\r
+ </layout>\r
+ <!-- <param name="Threshold" value="DEBUG" /> -->\r
+ </appender>\r
+\r
+ <logger name="org.opendaylight.groupbasedpolicy.sxp.mapper" additivity="false">\r
+ <level value="DEBUG"/>\r
+ <appender-ref ref="console"/>\r
+ </logger>\r
+\r
+ <logger name="org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao" additivity="false">\r
+ <level value="TRACE"/>\r
+ <appender-ref ref="console"/>\r
+ </logger>\r
+\r
+ <root>\r
+ <priority value="INFO"/>\r
+ <appender-ref ref="console"/>\r
+ </root>\r
+</log4j:configuration>\r