The registry is holding supported AFI/SAFI in form of BGPTableType and OpenConfig AfiSafiType.
Currenlty, this two AFI/SAFI representations mapping is held in static map, which lacks of extensibility.
The registry provider context is supposed to be activated in BGP-MP extensions.
The registry would be consumed in BGP configuration mapping procedures.
Change-Id: Ib34147f56d85bf418b29924d6d1f805d4ed1a757
Signed-off-by: Milos Fabian <milfabia@cisco.com>
<groupId>${project.groupId}</groupId>
<artifactId>bgp-openconfig-api</artifactId>
</dependency>
+ <!-- test scope dependencies -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ </dependency>
</dependencies>
<scm>
--- /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.protocol.bgp.openconfig.spi;
+
+import com.google.common.base.Preconditions;
+import java.util.List;
+import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.yangtools.concepts.AbstractRegistration;
+
+public abstract class AbstractBGPTableTypeRegistryProviderActivator implements AutoCloseable, BGPTableTypeRegistryProviderActivator {
+
+ @GuardedBy("this")
+ private List<AbstractRegistration> registrations;
+
+ @GuardedBy("this")
+ protected abstract List<AbstractRegistration> startBGPTableTypeRegistryProviderImpl(BGPTableTypeRegistryProvider provider);
+
+ @Override
+ public final synchronized void startBGPTableTypeRegistryProvider(final BGPTableTypeRegistryProvider provider) {
+ Preconditions.checkState(this.registrations == null);
+ this.registrations = Preconditions.checkNotNull(startBGPTableTypeRegistryProviderImpl(provider));
+ }
+
+ @Override
+ public final synchronized void stopBGPTableTypeRegistryProvider() {
+ if (this.registrations == null) {
+ return;
+ }
+ this.registrations.forEach(AbstractRegistration::close);
+ this.registrations = null;
+ }
+
+ @Override
+ public final void close() {
+ stopBGPTableTypeRegistryProvider();
+ };
+}
--- /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.protocol.bgp.openconfig.spi;
+
+import java.util.Optional;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.AfiSafiType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
+
+/**
+ * Provides access to BGP AFI/SAFI registry.
+ *
+ */
+public interface BGPTableTypeRegistryConsumer {
+
+ /**
+ * Looks for BgpTableType based on OpenConfig AFI/SAFI.
+ * @param afiSafiType
+ * @return Optional of BgpTableType or empty, if the table type is not supported.
+ */
+ @Nonnull Optional<BgpTableType> getTableType(@Nonnull Class<? extends AfiSafiType> afiSafiType);
+
+ /**
+ * Looks for AfiSafiType based on BgpTableType.
+ * @param bgpTableType
+ * @return Optional of OpenConfig AFI/SAFI or empty, if the table type is not supported.
+ */
+ @Nonnull Optional<Class<? extends AfiSafiType>> getAfiSafiType(@Nonnull BgpTableType bgpTableType);
+
+}
--- /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.protocol.bgp.openconfig.spi;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.AfiSafiType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
+import org.opendaylight.yangtools.concepts.AbstractRegistration;
+
+/**
+ * The BGP extension may provide supported table type (AFI/SAFI).
+ *
+ */
+public interface BGPTableTypeRegistryProvider extends BGPTableTypeRegistryConsumer {
+
+ /**
+ * Register supported AFI/SAFI.
+ * @param afi Local representation of AFI.
+ * @param safi Local representation of SAFI.
+ * @param afiSafiType OpenConfig AFI/SAFI representation.
+ * @return Registration ticket.
+ */
+ @Nonnull AbstractRegistration registerBGPTableType(@Nonnull Class<? extends AddressFamily> afi,
+ @Nonnull Class<? extends SubsequentAddressFamily> safi, @Nonnull Class<? extends AfiSafiType> afiSafiType);
+
+}
--- /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.protocol.bgp.openconfig.spi;
+
+import javax.annotation.Nonnull;
+
+public interface BGPTableTypeRegistryProviderActivator {
+
+ void startBGPTableTypeRegistryProvider(@Nonnull BGPTableTypeRegistryProvider provider);
+
+ void stopBGPTableTypeRegistryProvider();
+
+}
--- /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.protocol.bgp.openconfig.spi;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import java.util.Optional;
+import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.AfiSafiType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
+import org.opendaylight.yangtools.concepts.AbstractRegistration;
+
+public final class SimpleBGPTableTypeRegistryProvider implements BGPTableTypeRegistryProvider {
+
+ @GuardedBy("this")
+ private final BiMap<BgpTableType, Class<? extends AfiSafiType>> tableTypes = HashBiMap.create();
+
+ @Override
+ public synchronized AbstractRegistration registerBGPTableType(final Class<? extends AddressFamily> afi,
+ final Class<? extends SubsequentAddressFamily> safi, final Class<? extends AfiSafiType> afiSafiType) {
+ final BgpTableType tableType = new BgpTableTypeImpl(afi, safi);
+ final Class<? extends AfiSafiType> prev = this.tableTypes.putIfAbsent(tableType, afiSafiType);
+ Preconditions.checkState(prev == null, "AFI %s SAFI %s is already registered with %s", afi, safi, prev);
+ return new AbstractRegistration() {
+ @Override
+ protected void removeRegistration() {
+ synchronized (SimpleBGPTableTypeRegistryProvider.this) {
+ SimpleBGPTableTypeRegistryProvider.this.tableTypes.remove(tableType);
+ }
+ }
+ };
+ }
+
+ @Override
+ public synchronized Optional<BgpTableType> getTableType(final Class<? extends AfiSafiType> afiSafiType) {
+ final BgpTableType tableType = this.tableTypes.inverse().get(afiSafiType);
+ return Optional.ofNullable(tableType);
+ }
+
+ @Override
+ public synchronized Optional<Class<? extends AfiSafiType>> getAfiSafiType(final BgpTableType bgpTableType) {
+ final Class<? extends AfiSafiType> afiSafi = this.tableTypes.get(bgpTableType);
+ return Optional.ofNullable(afiSafi);
+ }
+
+}
--- /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.protocol.bgp.openconfig.spi;
+
+import com.google.common.base.Preconditions;
+import java.util.List;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class SimpleBGPTableTypeRegistryProviderActivator implements AutoCloseable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SimpleBGPTableTypeRegistryProviderActivator.class);
+
+ private final BGPTableTypeRegistryProvider providerContext;
+ private final List<BGPTableTypeRegistryProviderActivator> extensionActivators;
+
+ public SimpleBGPTableTypeRegistryProviderActivator(final BGPTableTypeRegistryProvider providerContext,
+ final List<BGPTableTypeRegistryProviderActivator> extensionActivators) {
+ this.providerContext = Preconditions.checkNotNull(providerContext);
+ this.extensionActivators = Preconditions.checkNotNull(extensionActivators);
+ }
+
+ public void start() {
+ LOG.info("Starting {} BGPTableTypeRegistryProviderActivator instances", this.extensionActivators.size());
+
+ this.extensionActivators.forEach(activator -> activator.startBGPTableTypeRegistryProvider(this.providerContext));
+ }
+
+ @Override
+ public void close() {
+ LOG.info("Stopping {} BGPTableTypeRegistryProviderActivator instances", this.extensionActivators.size());
+
+ this.extensionActivators.forEach(BGPTableTypeRegistryProviderActivator::stopBGPTableTypeRegistryProvider);
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0">
+
+ <odl:specific-reference-list id="extensionActivators" interface="org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryProviderActivator"/>
+
+ <bean id="extensionProviderContext" class="org.opendaylight.protocol.bgp.openconfig.spi.SimpleBGPTableTypeRegistryProvider"/>
+
+ <bean id="extensionProviderContextActivator" class="org.opendaylight.protocol.bgp.openconfig.spi.SimpleBGPTableTypeRegistryProviderActivator"
+ init-method="start" destroy-method="close">
+ <argument ref="extensionProviderContext"/>
+ <argument ref="extensionActivators"/>
+ </bean>
+
+ <service ref="extensionProviderContext">
+ <interfaces>
+ <value>org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer</value>
+ <value>org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryProvider</value>
+ </interfaces>
+ </service>
+</blueprint>
\ 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.protocol.bgp.openconfig.spi;
+
+import java.util.Collections;
+import java.util.List;
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4UNICAST;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
+import org.opendaylight.yangtools.concepts.AbstractRegistration;
+
+public class BGPTableTypeRegistryProviderActivatorTest {
+
+ @Test
+ public void testBGPTableTypeRegistryProviderActivator() {
+ final AbstractBGPTableTypeRegistryProviderActivator activator = new AbstractBGPTableTypeRegistryProviderActivator(){
+ @Override
+ protected List<AbstractRegistration> startBGPTableTypeRegistryProviderImpl(
+ final BGPTableTypeRegistryProvider provider) {
+ return Collections.singletonList(provider.registerBGPTableType(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class, IPV4UNICAST.class));
+ }};
+
+ final SimpleBGPTableTypeRegistryProvider provider = new SimpleBGPTableTypeRegistryProvider();
+ activator.startBGPTableTypeRegistryProvider(provider);
+ Assert.assertTrue(provider.getTableType(IPV4UNICAST.class).isPresent());
+ activator.stopBGPTableTypeRegistryProvider();
+ Assert.assertFalse(provider.getTableType(IPV4UNICAST.class).isPresent());
+ activator.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.protocol.bgp.openconfig.spi;
+
+import java.util.Collections;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+public class SimpleBGPTableTypeRegistryProviderActivatorTest {
+
+ @Mock
+ private BGPTableTypeRegistryProviderActivator providerActivator;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testSimpleBGPTableTypeRegistryProviderActivator() {
+ final SimpleBGPTableTypeRegistryProvider provider = new SimpleBGPTableTypeRegistryProvider();
+ final SimpleBGPTableTypeRegistryProviderActivator activator = new SimpleBGPTableTypeRegistryProviderActivator(provider,
+ Collections.singletonList(this.providerActivator));
+ activator.start();
+ Mockito.verify(this.providerActivator).startBGPTableTypeRegistryProvider(Mockito.any());
+ activator.close();
+ Mockito.verify(this.providerActivator).stopBGPTableTypeRegistryProvider();
+ }
+
+}
--- /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.protocol.bgp.openconfig.spi;
+
+import java.util.Optional;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.AfiSafiType;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4UNICAST;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV6UNICAST;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
+import org.opendaylight.yangtools.concepts.AbstractRegistration;
+
+public class SimpleBGPTableTypeRegistryProviderTest {
+
+ private BGPTableTypeRegistryProvider provider;
+ private AbstractRegistration registration;
+
+ @Before
+ public void setUp() {
+ this.provider = new SimpleBGPTableTypeRegistryProvider();
+ this.registration = this.provider.registerBGPTableType(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class, IPV4UNICAST.class);
+ }
+
+ @Test
+ public void testBGPTableTypeRegistryProvider() {
+
+ final Optional<Class<? extends AfiSafiType>> afiSafiType = this.provider.getAfiSafiType(new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class));
+ Assert.assertTrue(afiSafiType.isPresent());
+ final Optional<Class<? extends AfiSafiType>> afiSafiType2 = this.provider.getAfiSafiType(new BgpTableTypeImpl(Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class));
+ Assert.assertFalse(afiSafiType2.isPresent());
+
+ final Optional<BgpTableType> tableType = this.provider.getTableType(IPV4UNICAST.class);
+ Assert.assertTrue(tableType.isPresent());
+ final Optional<BgpTableType> tableType2 = this.provider.getTableType(IPV6UNICAST.class);
+ Assert.assertFalse(tableType2.isPresent());
+
+ this.registration.close();
+ final Optional<BgpTableType> tableType3 = this.provider.getTableType(IPV4UNICAST.class);
+ Assert.assertFalse(tableType3.isPresent());
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void testDuplicatedRegistration() {
+ this.provider.registerBGPTableType(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class, IPV4UNICAST.class);
+ }
+
+}