Bug-4827: BGP Add-Path OpenConfig Support II 10/37710/4
authorMilos Fabian <milfabia@cisco.com>
Thu, 14 Apr 2016 12:31:10 +0000 (14:31 +0200)
committerRobert Varga <nite@hq.sk>
Thu, 12 May 2016 07:58:15 +0000 (07:58 +0000)
Added mapping from OpenConfig API to BGP RIB and Peer Module
support BGP Add-Path configuration.
In "BGPPeer" configuration per AFI/SAFI Add-Path
capability is configured optionally.
In "BGPRibImpl" configuration per AFI/SAFI path selection
strategy is configured optionally.

Change-Id: Ie88148417037ffae869c39cc067fb4b5373ca25e
Signed-off-by: Milos Fabian <milfabia@cisco.com>
bgp/openconfig-impl/src/main/java/org/opendaylight/protocol/bgp/openconfig/impl/moduleconfig/AddPathFunction.java [new file with mode: 0644]
bgp/openconfig-impl/src/main/java/org/opendaylight/protocol/bgp/openconfig/impl/moduleconfig/BGPPeerProvider.java
bgp/openconfig-impl/src/main/java/org/opendaylight/protocol/bgp/openconfig/impl/moduleconfig/BGPRibImplProvider.java
bgp/openconfig-impl/src/main/java/org/opendaylight/protocol/bgp/openconfig/impl/moduleconfig/PathSelectionModeFunction.java [new file with mode: 0644]
bgp/openconfig-impl/src/main/java/org/opendaylight/protocol/bgp/openconfig/impl/moduleconfig/TableTypesFunction.java
bgp/openconfig-impl/src/main/java/org/opendaylight/protocol/bgp/openconfig/impl/util/OpenConfigUtil.java
bgp/openconfig-impl/src/test/java/org/opendaylight/protocol/bgp/openconfig/impl/util/OpenConfigUtilTest.java

diff --git a/bgp/openconfig-impl/src/main/java/org/opendaylight/protocol/bgp/openconfig/impl/moduleconfig/AddPathFunction.java b/bgp/openconfig-impl/src/main/java/org/opendaylight/protocol/bgp/openconfig/impl/moduleconfig/AddPathFunction.java
new file mode 100644 (file)
index 0000000..4d9a0aa
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * 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.impl.moduleconfig;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.protocol.bgp.openconfig.impl.util.OpenConfigUtil;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.neighbor.UseMultiplePaths;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.neighbor.use.multiple.paths.Config;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.AfiSafi2;
+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.SendReceive;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.AddPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.AddPathImpl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.BgpTableType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.BgpTableTypeImpl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.ServiceRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.modules.Module;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.modules.ModuleKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.services.Service;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.services.ServiceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.services.service.Instance;
+import org.opendaylight.yangtools.yang.binding.ChildOf;
+
+final class AddPathFunction {
+
+    private AddPathFunction() {
+        throw new UnsupportedOperationException();
+    }
+
+    public static <T extends ServiceRef & ChildOf<Module>> List<T> getAddPath(final ReadOnlyTransaction rTx, final BGPConfigModuleProvider
+            configModuleWriter, final Function<String, T> function, final List<AfiSafi> afiSafis) {
+        final ImmutableList<AfiSafi> afiSafisMultipath = FluentIterable.from(afiSafis).filter(new Predicate<AfiSafi>() {
+            @Override
+            public boolean apply(final AfiSafi afisafi) {
+                final AfiSafi2 afiSafi2 = afisafi.getAugmentation(AfiSafi2.class);
+                if (afiSafi2 != null) {
+                    final UseMultiplePaths useMultiplePaths = afiSafi2.getUseMultiplePaths();
+                    if (useMultiplePaths != null) {
+                        final Config useMultiplePathsConfig = useMultiplePaths.getConfig();
+                        if (useMultiplePathsConfig != null && useMultiplePathsConfig.isEnabled() != null) {
+                            return useMultiplePathsConfig.isEnabled();
+                        }
+                    }
+                }
+                return false;
+            }}).toList();
+        try {
+            final Optional<Service> maybeService = configModuleWriter.readConfigService(new ServiceKey(AddPath.class), rTx);
+            if (maybeService.isPresent()) {
+                final Service service = maybeService.get();
+                final List<Module> modules = new ArrayList<>();
+                final Map<String, String> moduleNameToService = new HashMap<>();
+                for (final Instance instance : service.getInstance()) {
+                    final String moduleName = OpenConfigUtil.getModuleName(instance.getProvider());
+                    final ModuleKey moduleKey = new ModuleKey(moduleName, AddPathImpl.class);
+                    final Optional<Module> moduleConfig = configModuleWriter.readModuleConfiguration(moduleKey, rTx);
+                    if (moduleConfig.isPresent()) {
+                        modules.add(moduleConfig.get());
+                    }
+                    moduleNameToService.put(moduleName, instance.getName());
+                }
+
+                return TableTypesFunction.toServices(function, afiSafisMultipath, afiSafiToModuleName(afiSafisMultipath, modules, configModuleWriter, rTx), moduleNameToService);
+            }
+            return Collections.emptyList();
+        } catch (final ReadFailedException e) {
+            throw new IllegalStateException(OpenConfigUtil.FAILED_TO_READ_SERVICE, e);
+        }
+    }
+
+    private static Map<Class<? extends AfiSafiType>, String> afiSafiToModuleName(final List<AfiSafi> afiSafis, final List<Module> modules, final BGPConfigModuleProvider configModuleWriter, final ReadTransaction rTx) throws ReadFailedException {
+        final Map<Class<? extends AfiSafiType>, String> afiSafiToModuleName = new HashMap<>(afiSafis.size());
+        for (final Module module : modules) {
+            final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.AddPathImpl config =
+                ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.AddPathImpl) module.getConfiguration());
+            if (config.getSendReceive() == SendReceive.Both) {
+                final Optional<AfiSafi> tryFind = Iterables.tryFind(afiSafis, new Predicate<AfiSafi>() {
+                    @Override
+                    public boolean apply(final AfiSafi input) {
+                        final Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType> bgpTableType = OpenConfigUtil.toBgpTableType(input.getAfiSafiName());
+                        return bgpTableType.isPresent() && tableTypeExists(configModuleWriter, rTx,
+                                (String) config.getAddressFamily().getName(), bgpTableType.get());
+                    }
+                });
+                if (tryFind.isPresent()) {
+                    afiSafiToModuleName.put(tryFind.get().getAfiSafiName(), module.getName());
+                }
+            }
+        }
+        return afiSafiToModuleName;
+    }
+
+    public static boolean tableTypeExists(final BGPConfigModuleProvider configModuleWriter, final ReadTransaction rTx,
+            final String instanceName, final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType tableType) {
+        try {
+            final Optional<Service> maybeService = configModuleWriter.readConfigService(new ServiceKey(BgpTableType.class), rTx);
+            if (maybeService.isPresent()) {
+                for (final Instance instance : maybeService.get().getInstance()) {
+                    final String moduleName = OpenConfigUtil.getModuleName(instance.getProvider());
+                    if (moduleName.equals(instanceName)) {
+                        final ModuleKey moduleKey = new ModuleKey(moduleName, BgpTableTypeImpl.class);
+                        final Optional<Module> moduleConfig = configModuleWriter.readModuleConfiguration(moduleKey, rTx);
+                        if (moduleConfig.isPresent()) {
+                            final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.BgpTableTypeImpl tableTypeImpl = (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.BgpTableTypeImpl)moduleConfig.get().getConfiguration();
+                            final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType moduleTableType = new org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl(tableTypeImpl.getAfi(), tableTypeImpl.getSafi());
+                            if (moduleTableType.equals(tableType)) {
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+            return false;
+        } catch (final ReadFailedException e) {
+            throw new IllegalStateException(OpenConfigUtil.FAILED_TO_READ_SERVICE, e);
+        }
+    }
+
+}
index 1c0c08b0f305f06a5c52b0fea645df447714c23e..555d9037a8851721b14b3fd2a729f33ee22fd628 100644 (file)
@@ -32,6 +32,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controll
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.BgpTableType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.RibInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.BgpPeerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.bgp.peer.AddPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.bgp.peer.AddPathBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.bgp.peer.AdvertizedTable;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.bgp.peer.AdvertizedTableBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.bgp.peer.Rib;
@@ -73,6 +75,16 @@ final class BGPPeerProvider {
         }
     };
 
+    private static final Function<String, AddPath> ADD_PATH_FUNCTION = new Function<String, AddPath>() {
+        @Override
+        public AddPath apply(final String name) {
+            return new AddPathBuilder()
+                .setName(name)
+                .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.AddPath.class)
+                .build();
+        }
+    };
+
     private final BGPConfigHolder<Neighbor> neighborState;
     private final BGPConfigHolder<Bgp> globalState;
     private final BGPConfigModuleProvider configModuleOp;
@@ -105,22 +117,28 @@ final class BGPPeerProvider {
         final ModuleKey moduleKey = this.neighborState.getModuleKey(modifiedNeighbor.getKey());
         final ReadOnlyTransaction rTx = this.dataBroker.newReadOnlyTransaction();
         final List<AdvertizedTable> advertizedTables = getAdvertizedTables(modifiedNeighbor, rTx);
+        final List<AddPath> addPathCapabilities = getAddPathCapabilities(modifiedNeighbor, rTx);
         if (moduleKey != null) {
-            updateExistingPeerConfiguration(moduleKey, modifiedNeighbor, advertizedTables, rTx);
+            updateExistingPeerConfiguration(moduleKey, modifiedNeighbor, advertizedTables, rTx, addPathCapabilities);
         } else {
-            createNewPeerConfiguration(moduleKey, modifiedNeighbor, advertizedTables, rTx);
+            createNewPeerConfiguration(moduleKey, modifiedNeighbor, advertizedTables, rTx, addPathCapabilities);
         }
     }
 
     private List<AdvertizedTable> getAdvertizedTables(final Neighbor modifiedNeighbor, final ReadOnlyTransaction rTx) {
-        return TableTypesFunction.getLocalTables(rTx, this.configModuleOp, this.ADVERTIZED_TABLE_FUNCTION, modifiedNeighbor.getAfiSafis().getAfiSafi());
+        return TableTypesFunction.getLocalTables(rTx, this.configModuleOp, ADVERTIZED_TABLE_FUNCTION, modifiedNeighbor.getAfiSafis().getAfiSafi());
+    }
+
+    private List<AddPath> getAddPathCapabilities(final Neighbor modifiedNeighbor, final ReadOnlyTransaction rTx) {
+        return AddPathFunction.getAddPath(rTx, this.configModuleOp, ADD_PATH_FUNCTION, modifiedNeighbor.getAfiSafis().getAfiSafi());
     }
 
-    private void updateExistingPeerConfiguration(final ModuleKey moduleKey, final Neighbor modifiedNeighbor, final List<AdvertizedTable> advertizedTables, final ReadOnlyTransaction rTx) {
-        if (this.neighborState.addOrUpdate(moduleKey, modifiedNeighbor.getKey(), modifiedNeighbor)) {
+    private void updateExistingPeerConfiguration(final ModuleKey moduleKey, final Neighbor modifiedNeighbor, final List<AdvertizedTable>
+        advertizedTables, final ReadOnlyTransaction rTx, final List<AddPath> addPathCapabilities) {
+        if (neighborState.addOrUpdate(moduleKey, modifiedNeighbor.getKey(), modifiedNeighbor)) {
             final Optional<Module> maybeModule = getOldModuleConfiguration(moduleKey, rTx);
             if (maybeModule.isPresent()) {
-                final Module peerConfigModule = toPeerConfigModule(modifiedNeighbor, maybeModule.get(), advertizedTables);
+                final Module peerConfigModule = toPeerConfigModule(modifiedNeighbor, maybeModule.get(), advertizedTables, addPathCapabilities);
                 putOldModuleConfigurationIntoNewModule(peerConfigModule);
             }
         }
@@ -144,13 +162,14 @@ final class BGPPeerProvider {
         }
     }
 
-    private void createNewPeerConfiguration(final ModuleKey moduleKey, final Neighbor modifiedNeighbor, final List<AdvertizedTable> advertizedTables, final ReadOnlyTransaction rTx) {
+    private void createNewPeerConfiguration(final ModuleKey moduleKey, final Neighbor modifiedNeighbor, final List<AdvertizedTable> advertizedTables,
+            final ReadOnlyTransaction rTx, final List<AddPath> addPathCapabilities) {
         final ModuleKey ribImplKey = this.globalState.getModuleKey(GlobalIdentifier.GLOBAL_IDENTIFIER);
         if (ribImplKey != null) {
             try {
-                final Rib rib = RibInstanceFunction.getRibInstance(this.configModuleOp, this.TO_RIB_FUNCTION, ribImplKey.getName(), rTx);
+                final Rib rib = RibInstanceFunction.getRibInstance(this.configModuleOp, TO_RIB_FUNCTION, ribImplKey.getName(), rTx);
                 final RpcRegistry rpcReg = RpcRegistryFunction.getRpcRegistryInstance(rTx, this.configModuleOp, RPC_REG_FUNCTION);
-                final Module peerConfigModule = toPeerConfigModule(modifiedNeighbor, advertizedTables, rib, rpcReg);
+                final Module peerConfigModule = toPeerConfigModule(modifiedNeighbor, advertizedTables, rib, rpcReg, addPathCapabilities);
                 this.configModuleOp.putModuleConfiguration(peerConfigModule, this.dataBroker.newWriteOnlyTransaction());
                 this.neighborState.addOrUpdate(peerConfigModule.getKey(), modifiedNeighbor.getKey(), modifiedNeighbor);
             } catch (final Exception e) {
@@ -160,10 +179,11 @@ final class BGPPeerProvider {
         }
     }
 
-    private static Module toPeerConfigModule(final Neighbor neighbor, final Module oldBgpPeer, final List<AdvertizedTable> tableTypes) {
+    private static Module toPeerConfigModule(final Neighbor neighbor, final Module oldBgpPeer, final List<AdvertizedTable> tableTypes,
+            final List<AddPath> addPathCapabilities) {
         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.BgpPeer bgpPeer =
             (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.BgpPeer) oldBgpPeer.getConfiguration();
-        final BgpPeerBuilder bgpPeerBuilder = toBgpPeerConfig(neighbor, tableTypes, bgpPeer.getRib(), bgpPeer.getRpcRegistry());
+        final BgpPeerBuilder bgpPeerBuilder = toBgpPeerConfig(neighbor, tableTypes, bgpPeer.getRib(), bgpPeer.getRpcRegistry(), addPathCapabilities);
         bgpPeerBuilder.setPeerRegistry(((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.BgpPeer) oldBgpPeer.getConfiguration()).getPeerRegistry());
         bgpPeerBuilder.setPort(((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.BgpPeer) oldBgpPeer.getConfiguration()).getPort());
 
@@ -172,21 +192,24 @@ final class BGPPeerProvider {
         return mBuilder.build();
     }
 
-    private static Module toPeerConfigModule(final Neighbor neighbor, final List<AdvertizedTable> tableTypes, final Rib rib, final RpcRegistry rpcReg) {
+    private static Module toPeerConfigModule(final Neighbor neighbor, final List<AdvertizedTable> tableTypes, final Rib rib, final RpcRegistry rpcReg,
+            final List<AddPath> addPathCapabilities) {
         final ModuleBuilder mBuilder = new ModuleBuilder();
         mBuilder.setName(createPeerName(neighbor.getNeighborAddress()));
         mBuilder.setType(BgpPeer.class);
-        mBuilder.setConfiguration(toBgpPeerConfig(neighbor, tableTypes, rib, rpcReg).build());
+        mBuilder.setConfiguration(toBgpPeerConfig(neighbor, tableTypes, rib, rpcReg, addPathCapabilities).build());
         mBuilder.setKey(new ModuleKey(mBuilder.getName(), mBuilder.getType()));
         return mBuilder.build();
     }
 
-    private static BgpPeerBuilder toBgpPeerConfig(final Neighbor neighbor, final List<AdvertizedTable> tableTypes, final Rib rib, final RpcRegistry rpcReg) {
+    private static BgpPeerBuilder toBgpPeerConfig(final Neighbor neighbor, final List<AdvertizedTable> tableTypes, final Rib rib, final RpcRegistry rpcReg,
+            final List<AddPath> addPathCapabilities) {
         final BgpPeerBuilder bgpPeerBuilder = new BgpPeerBuilder();
         if (rpcReg != null) {
             bgpPeerBuilder.setRpcRegistry(rpcReg);
         }
         bgpPeerBuilder.setAdvertizedTable(tableTypes);
+        bgpPeerBuilder.setAddPath(addPathCapabilities);
         bgpPeerBuilder.setRib(rib);
         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress ipAdress = null;
         if (neighbor.getNeighborAddress().getIpv4Address() != null) {
index ca260d24a31f7e09deeafe557699f18ea9f9da90..42f2700d3633963fb1741ea7be710f790ab91204 100644 (file)
@@ -22,11 +22,14 @@ import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.t
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.BgpBuilder;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.BgpPathSelectionMode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.BgpTableType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.RibImpl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.RibImplBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.rib.impl.LocalTable;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.rib.impl.LocalTableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.rib.impl.RibPathSelectionMode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.rib.impl.RibPathSelectionModeBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.modules.Module;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.modules.ModuleBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.modules.ModuleKey;
@@ -44,6 +47,13 @@ final class BGPRibImplProvider {
         }
     };
 
+    private static final Function<String, RibPathSelectionMode> PATH_SELECTION_MODE_FUNCTION = new Function<String, RibPathSelectionMode>() {
+        @Override
+        public RibPathSelectionMode apply(final String input) {
+            return new RibPathSelectionModeBuilder().setName(input).setType(BgpPathSelectionMode.class).build();
+        }
+    };
+
     private final BGPConfigHolder<Bgp> globalState;
     private final BGPConfigModuleProvider configModuleWriter;
     private final DataBroker dataBroker;
@@ -78,7 +88,8 @@ final class BGPRibImplProvider {
                 final Optional<Module> maybeModule = this.configModuleWriter.readModuleConfiguration(moduleKey, rTx);
                 if (maybeModule.isPresent()) {
                     final List<LocalTable> localTables = getAdvertizedTables(modifiedGlobal, rTx);
-                    final Module newModule = toRibImplConfigModule(modifiedGlobal, maybeModule.get(), localTables);
+                    final List<RibPathSelectionMode> pathSelectionModes = getPathSelectionModes(modifiedGlobal, rTx);
+                    final Module newModule = toRibImplConfigModule(modifiedGlobal, maybeModule.get(), localTables, pathSelectionModes);
                     this.configModuleWriter.putModuleConfiguration(newModule, dataBroker.newWriteOnlyTransaction());
                 }
             } catch (final Exception e) {
@@ -92,7 +103,13 @@ final class BGPRibImplProvider {
         return TableTypesFunction.getLocalTables(rTx, this.configModuleWriter, this.LOCAL_TABLE_FUNCTION, modifiedGlobal.getAfiSafis().getAfiSafi());
     }
 
-    private static Module toRibImplConfigModule(final Global globalConfig, final Module module, final List<LocalTable> tableTypes) {
+    private List<RibPathSelectionMode> getPathSelectionModes(final Global modifiedGlobal, final ReadOnlyTransaction rTx) {
+        return PathSelectionModeFunction.getPathSelectionMode(rTx, this.configModuleWriter, PATH_SELECTION_MODE_FUNCTION,
+                modifiedGlobal.getAfiSafis().getAfiSafi());
+    }
+
+    private static Module toRibImplConfigModule(final Global globalConfig, final Module module, final List<LocalTable> tableTypes,
+            final List<RibPathSelectionMode> pathSelectionModes) {
         final RibImpl ribImpl = (RibImpl) module.getConfiguration();
         final RibImplBuilder ribImplBuilder = new RibImplBuilder();
         if (globalConfig.getConfig() != null) {
@@ -108,6 +125,7 @@ final class BGPRibImplProvider {
         ribImplBuilder.setExtensions(ribImpl.getExtensions());
         ribImplBuilder.setRibId(ribImpl.getRibId());
         ribImplBuilder.setOpenconfigProvider(ribImpl.getOpenconfigProvider());
+        ribImplBuilder.setRibPathSelectionMode(pathSelectionModes);
 
         final ModuleBuilder mBuilder = new ModuleBuilder(module);
         mBuilder.setConfiguration(ribImplBuilder.build());
diff --git a/bgp/openconfig-impl/src/main/java/org/opendaylight/protocol/bgp/openconfig/impl/moduleconfig/PathSelectionModeFunction.java b/bgp/openconfig-impl/src/main/java/org/opendaylight/protocol/bgp/openconfig/impl/moduleconfig/PathSelectionModeFunction.java
new file mode 100644 (file)
index 0000000..1906c97
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * 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.impl.moduleconfig;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
+import com.google.common.collect.Iterables;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.protocol.bgp.openconfig.impl.util.OpenConfigUtil;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.use.multiple.paths.Config;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.use.multiple.paths.Ibgp;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.AfiSafi1;
+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.controller.bgp.path.selection.mode.rev160301.AdvertiseAllPaths;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.path.selection.mode.rev160301.AdvertiseNPaths;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.path.selection.mode.rev160301.PathSelectionModeFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.BgpPathSelectionMode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.BgpPsmImpl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.ModuleType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.ServiceRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.modules.Module;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.modules.ModuleKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.services.Service;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.services.ServiceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.services.service.Instance;
+import org.opendaylight.yangtools.yang.binding.ChildOf;
+
+final class PathSelectionModeFunction {
+
+    private static final Map<String, Class<? extends ModuleType>> PATH_SELECTION_MODULE_TYPES;
+
+    static {
+        final Builder<String, Class<? extends ModuleType>> builder = ImmutableMap.builder();
+        builder.put(AdvertiseNPaths.QNAME.getLocalName(), AdvertiseNPaths.class);
+        builder.put(AdvertiseAllPaths.QNAME.getLocalName(), AdvertiseAllPaths.class);
+        PATH_SELECTION_MODULE_TYPES = builder.build();
+    }
+
+    private PathSelectionModeFunction() {
+        throw new UnsupportedOperationException();
+    }
+
+    public static <T extends ServiceRef & ChildOf<Module>> List<T> getPathSelectionMode(final ReadOnlyTransaction rTx, final BGPConfigModuleProvider
+            configModuleWriter, final Function<String, T> function, final List<AfiSafi> afiSafis) {
+        final ImmutableList<AfiSafi> afiSafisMultipath = FluentIterable.from(afiSafis).filter(new Predicate<AfiSafi>() {
+            @Override
+            public boolean apply(final AfiSafi afisafi) {
+                final AfiSafi1 afiSafi1 = afisafi.getAugmentation(AfiSafi1.class);
+                if (afiSafi1 != null) {
+                    final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.UseMultiplePaths useMultiplePaths = afiSafi1.getUseMultiplePaths();
+                    if (useMultiplePaths != null) {
+                        final Config useMultiplePathsConfig = useMultiplePaths.getConfig();
+                        if (useMultiplePathsConfig != null && useMultiplePathsConfig.isEnabled() != null) {
+                            return useMultiplePathsConfig.isEnabled();
+                        }
+                    }
+                }
+                return false;
+            }}).toList();
+        try {
+            final Optional<Service> maybeService = configModuleWriter.readConfigService(new ServiceKey(BgpPathSelectionMode.class), rTx);
+            if (maybeService.isPresent()) {
+                final Service service = maybeService.get();
+                final List<Module> modules = new ArrayList<>();
+                final Map<String, String> moduleNameToService = new HashMap<>();
+                for (final Instance instance : service.getInstance()) {
+                    final String moduleName = OpenConfigUtil.getModuleName(instance.getProvider());
+                    final ModuleKey moduleKey = new ModuleKey(moduleName, BgpPsmImpl.class);
+                    final Optional<Module> moduleConfig = configModuleWriter.readModuleConfiguration(moduleKey, rTx);
+                    if (moduleConfig.isPresent()) {
+                        modules.add(moduleConfig.get());
+                    }
+                    moduleNameToService.put(moduleName, instance.getName());
+                }
+
+                return TableTypesFunction.toServices(function, afiSafisMultipath, afiSafiToModuleName(afiSafisMultipath, modules, configModuleWriter, rTx), moduleNameToService);
+            }
+            return Collections.emptyList();
+        } catch (final ReadFailedException e) {
+            throw new IllegalStateException(OpenConfigUtil.FAILED_TO_READ_SERVICE, e);
+        }
+    }
+
+    private static Class<? extends ModuleType> getModuleTypeClass(final String moduleType) {
+        return PATH_SELECTION_MODULE_TYPES.get(moduleType);
+    }
+
+    private static Map<Class<? extends AfiSafiType>, String> afiSafiToModuleName(final List<AfiSafi> afiSafis, final List<Module> modules, final BGPConfigModuleProvider configModuleWriter, final ReadTransaction rTx) throws ReadFailedException {
+        final Map<Class<? extends AfiSafiType>, String> afiSafiToModuleName = new HashMap<>(afiSafis.size());
+        for (final Module module : modules) {
+            final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.BgpPsmImpl config =
+                    ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.rib.impl.rev160330.modules.module.configuration.BgpPsmImpl) module.getConfiguration());
+
+            final Optional<AfiSafi> tryFind = Iterables.tryFind(afiSafis, new Predicate<AfiSafi>() {
+                @Override
+                public boolean apply(final AfiSafi input) {
+                    final Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType> bgpTableType = OpenConfigUtil.toBgpTableType(input.getAfiSafiName());
+                    if (bgpTableType.isPresent() && AddPathFunction.tableTypeExists(configModuleWriter, rTx,
+                            (String) config.getPathAddressFamily().getName(), bgpTableType.get())) {
+                        final Ibgp ibgp = input.getAugmentation(AfiSafi1.class).getUseMultiplePaths().getIbgp();
+                        return pathSelectionModeExists(configModuleWriter, rTx, (String) config.getPathSelectionMode().getName(), ibgp);
+                    }
+                    return false;
+                }
+            });
+            if (tryFind.isPresent()) {
+                afiSafiToModuleName.put(tryFind.get().getAfiSafiName(), module.getName());
+            }
+        }
+        return afiSafiToModuleName;
+    }
+
+    public static boolean pathSelectionModeExists(final BGPConfigModuleProvider configModuleWriter, final ReadTransaction rTx,
+            final String instanceName, final Ibgp ibgp) {
+
+        try {
+            final Optional<Service> maybeService = configModuleWriter.readConfigService(new ServiceKey(PathSelectionModeFactory.class), rTx);
+            if (maybeService.isPresent()) {
+                for (final Instance instance : maybeService.get().getInstance()) {
+                    final String provider = instance.getProvider();
+                    final String moduleName = OpenConfigUtil.getModuleName(provider);
+                    final String moduleType = OpenConfigUtil.getModuleType(provider);
+                    if (moduleName.equals(instanceName)) {
+                        final ModuleKey moduleKey = new ModuleKey(moduleName, getModuleTypeClass(moduleType));
+                        final Optional<Module> moduleConfig = configModuleWriter.readModuleConfiguration(moduleKey, rTx);
+                        if (moduleConfig.isPresent()) {
+                            if (ibgp != null && ibgp.getConfig() != null && ibgp.getConfig().getMaximumPaths() != null) {
+                                final long maxPaths = ibgp.getConfig().getMaximumPaths();
+                                if (moduleConfig.get().getType().equals(AdvertiseNPaths.class)) {
+                                    final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.path.selection.mode.rev160301.modules.module.configuration.AdvertiseNPaths config =
+                                            (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.path.selection.mode.rev160301.modules.module.configuration.AdvertiseNPaths)moduleConfig.get().getConfiguration();
+                                    if (maxPaths == config.getNBestPaths().longValue()) {
+                                        return true;
+                                    }
+                                }
+                            } else {
+                                if (moduleConfig.get().getType().equals(AdvertiseAllPaths.class)) {
+                                    return true;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            return false;
+        } catch (final ReadFailedException e) {
+            throw new IllegalStateException(OpenConfigUtil.FAILED_TO_READ_SERVICE, e);
+        }
+    }
+
+}
index d2012878106c4be95d550deb7eb7611ccf56caa3..9f509abe0810551c99343a4c427d63ac04357fa0 100644 (file)
@@ -66,14 +66,26 @@ final class TableTypesFunction {
                         }
                     }).toList();
 
-                return toTableTypes(function, afiSafis, afiSafiToModuleName(afiSafis, modules), moduleNameToService);
+                return toServices(function, afiSafis, afiSafiToModuleName(afiSafis, modules), moduleNameToService);
             }
             throw new IllegalStateException("No BgpTableType service present in configuration.");
-        } catch (ReadFailedException e) {
+        } catch (final ReadFailedException e) {
             throw new IllegalStateException("Failed to read service.", e);
         }
     }
 
+    public static <T extends ServiceRef & ChildOf<Module>> List<T> toServices(final Function<String, T> function, final List<AfiSafi> afiSafis,
+        final Map<Class<? extends AfiSafiType>, String> afiSafiToModuleName, final Map<String, String> moduleNameToService) {
+        final List<T> serives = new ArrayList<>(afiSafis.size());
+        for (final AfiSafi afiSafi : afiSafis) {
+            final String moduleName = afiSafiToModuleName.get(afiSafi.getAfiSafiName());
+            if (moduleName != null) {
+                serives.add(function.apply(moduleNameToService.get(moduleName)));
+            }
+        }
+        return serives;
+    }
+
     private static Map<Class<? extends AfiSafiType>, String> afiSafiToModuleName(final List<AfiSafi> afiSafis, final List<Module> modules) {
         final Map<Class<? extends AfiSafiType>, String> afiSafiToModuleName = new HashMap<>(afiSafis.size());
         for (final Module module : modules) {
@@ -86,16 +98,4 @@ final class TableTypesFunction {
         }
         return afiSafiToModuleName;
     }
-
-    private static <T extends ServiceRef & ChildOf<Module>> List<T> toTableTypes(final Function<String, T> function, final List<AfiSafi> afiSafis,
-        final Map<Class<? extends AfiSafiType>, String> afiSafiToModuleName, final Map<String, String> moduleNameToService) {
-        final List<T> tableTypes = new ArrayList<>(afiSafis.size());
-        for (final AfiSafi afiSafi : afiSafis) {
-            final String moduleName = afiSafiToModuleName.get(afiSafi.getAfiSafiName());
-            if (moduleName != null) {
-                tableTypes.add(function.apply(moduleNameToService.get(moduleName)));
-            }
-        }
-        return tableTypes;
-    }
 }
index 210324126be70112dfc2eeec5e6bc70309f3d1b3..be3ee909a34898d8dd4e6dae22d1c1225763d6e6 100644 (file)
@@ -9,8 +9,8 @@
 package org.opendaylight.protocol.bgp.openconfig.impl.util;
 
 import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMap.Builder;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.ImmutableBiMap;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -30,6 +30,7 @@ import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.AfiSa
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.AfiSafi2;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.AfiSafi2Builder;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp;
+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.IPV4LABELLEDUNICAST;
 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.IPV6LABELLEDUNICAST;
@@ -56,32 +57,27 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 public final class OpenConfigUtil {
 
+    private static final char EQUALS = '=';
+
     public static final InstanceIdentifier<Bgp> BGP_IID = InstanceIdentifier.create(Bgp.class);
 
     public static final String APPLICATION_PEER_GROUP_NAME = "application-peers";
 
-    private static final Map<BgpTableType, AfiSafi> TABLETYPE_TO_AFISAFI;
+    public static final String FAILED_TO_READ_SERVICE = "Failed to read service.";
+
+    private static final BiMap<BgpTableType, Class<? extends AfiSafiType>> TABLETYPE_TO_AFISAFI;
 
     static {
-        final Builder<BgpTableType, AfiSafi> b = ImmutableMap.builder();
-        b.put(new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class),
-            new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class).build());
-        b.put(new BgpTableTypeImpl(Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class),
-            new AfiSafiBuilder().setAfiSafiName(IPV6UNICAST.class).build());
-        b.put(new BgpTableTypeImpl(Ipv4AddressFamily.class, LabeledUnicastSubsequentAddressFamily.class),
-            new AfiSafiBuilder().setAfiSafiName(IPV4LABELLEDUNICAST.class).build());
-        b.put(new BgpTableTypeImpl(Ipv6AddressFamily.class, LabeledUnicastSubsequentAddressFamily.class),
-            new AfiSafiBuilder().setAfiSafiName(IPV6LABELLEDUNICAST.class).build());
-        b.put(new BgpTableTypeImpl(Ipv4AddressFamily.class, MplsLabeledVpnSubsequentAddressFamily.class),
-            new AfiSafiBuilder().setAfiSafiName(L3VPNIPV4UNICAST.class).build());
-        b.put(new BgpTableTypeImpl(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class),
-            new AfiSafiBuilder().setAfiSafiName(Linkstate.class).build());
-        b.put(new BgpTableTypeImpl(Ipv4AddressFamily.class, FlowspecSubsequentAddressFamily.class),
-            new AfiSafiBuilder().setAfiSafiName(Ipv4Flow.class).build());
-        b.put(new BgpTableTypeImpl(Ipv6AddressFamily.class, FlowspecSubsequentAddressFamily.class),
-            new AfiSafiBuilder().setAfiSafiName(Ipv6Flow.class).build());
-        b.put(new BgpTableTypeImpl(L2vpnAddressFamily.class, EvpnSubsequentAddressFamily.class),
-            new AfiSafiBuilder().setAfiSafiName(L2VPNEVPN.class).build());
+        final ImmutableBiMap.Builder<BgpTableType, Class<? extends AfiSafiType>> b = ImmutableBiMap.builder();
+        b.put(new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class), IPV4UNICAST.class);
+        b.put(new BgpTableTypeImpl(Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class), IPV6UNICAST.class);
+        b.put(new BgpTableTypeImpl(Ipv4AddressFamily.class, LabeledUnicastSubsequentAddressFamily.class), IPV4LABELLEDUNICAST.class);
+        b.put(new BgpTableTypeImpl(Ipv6AddressFamily.class, LabeledUnicastSubsequentAddressFamily.class), IPV6LABELLEDUNICAST.class);
+        b.put(new BgpTableTypeImpl(Ipv4AddressFamily.class, MplsLabeledVpnSubsequentAddressFamily.class), L3VPNIPV4UNICAST.class);
+        b.put(new BgpTableTypeImpl(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class), Linkstate.class);
+        b.put(new BgpTableTypeImpl(Ipv4AddressFamily.class, FlowspecSubsequentAddressFamily.class), Ipv4Flow.class);
+        b.put(new BgpTableTypeImpl(Ipv6AddressFamily.class, FlowspecSubsequentAddressFamily.class), Ipv6Flow.class);
+        b.put(new BgpTableTypeImpl(L2vpnAddressFamily.class, EvpnSubsequentAddressFamily.class), L2VPNEVPN.class);
         TABLETYPE_TO_AFISAFI = b.build();
     }
 
@@ -90,7 +86,15 @@ public final class OpenConfigUtil {
     }
 
     public static Optional<AfiSafi> toAfiSafi(final BgpTableType tableType) {
-        return Optional.fromNullable(TABLETYPE_TO_AFISAFI.get(tableType));
+        final Class<? extends AfiSafiType> afiSafi = TABLETYPE_TO_AFISAFI.get(tableType);
+        if (afiSafi != null) {
+            return Optional.of(new AfiSafiBuilder().setAfiSafiName(afiSafi).build());
+        }
+        return Optional.absent();
+    }
+
+    public static Optional<BgpTableType> toBgpTableType(final Class<? extends AfiSafiType> afiSafi) {
+        return Optional.fromNullable(TABLETYPE_TO_AFISAFI.inverse().get(afiSafi));
     }
 
     public static List<AfiSafi> toAfiSafis(final List<BgpTableType> advertizedTables, final BiFunction<AfiSafi, BgpTableType, AfiSafi> function) {
@@ -106,7 +110,11 @@ public final class OpenConfigUtil {
     }
 
     public static String getModuleName(final String provider) {
-        return provider.substring(provider.lastIndexOf('=') + 2, provider.length() - 2);
+        return provider.substring(provider.lastIndexOf(EQUALS) + 2, provider.length() - 2);
+    }
+
+    public static String getModuleType(final String provider) {
+        return provider.substring(provider.indexOf(EQUALS) + 2, provider.indexOf("']"));
     }
 
     public static AfiSafi toNeigborAfiSafiMultiPath(final AfiSafi afiSafi, final BgpTableType tableType, final Collection<AddressFamilies> addPathCapabilities) {
index d477f59cd41b3bd500d6eb91e70abe99d9f8c488..2f1f9dab40c05d8c3d4f60031a780f621cc04d7c 100644 (file)
@@ -12,6 +12,7 @@ import static org.junit.Assert.assertEquals;
 import static org.opendaylight.protocol.bgp.openconfig.impl.util.OpenConfigUtil.getModuleName;
 import static org.opendaylight.protocol.bgp.openconfig.impl.util.OpenConfigUtil.toAfiSafi;
 
+import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
@@ -47,12 +48,24 @@ public class OpenConfigUtilTest {
         assertEquals("concurrent-data-broker", moduleName);
     }
 
+    @Test
+    public void testGetModuleType() {
+        final String moduleType = OpenConfigUtil.getModuleType(TEST);
+        assertEquals("dom-concurrent-data-broker", moduleType);
+    }
+
     @Test
     public void testToAfiSafi() {
         assertEquals(toAfiSafi(BGP_TABLE_TYPE_IPV4).get(),
                 AFISAFI_IPV4);
     }
 
+    @Test
+    public void testToBgpTableType() {
+        final Optional<BgpTableType> bgpTableType = OpenConfigUtil.toBgpTableType(IPV4UNICAST.class);
+        assertEquals(BGP_TABLE_TYPE_IPV4, bgpTableType.get());
+    }
+
     @Test
     public void testToAfiSafis() {
         final List<AfiSafi> afiSafis = OpenConfigUtil.toAfiSafis(Lists.<BgpTableType>newArrayList(BGP_TABLE_TYPE_IPV4),