--- /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.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);
+ }
+ }
+
+}
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;
}
};
+ 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;
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);
}
}
}
}
- 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) {
}
}
- 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());
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) {
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;
}
};
+ 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;
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) {
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) {
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());
--- /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.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);
+ }
+ }
+
+}
}
}).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) {
}
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;
- }
}
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;
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;
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();
}
}
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) {
}
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) {
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;
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),