package org.opendaylight.protocol.bgp.openconfig.impl;
+import com.google.common.base.Preconditions;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.concurrent.GuardedBy;
import org.opendaylight.protocol.bgp.openconfig.impl.spi.BGPConfigHolder;
+import org.opendaylight.protocol.bgp.openconfig.impl.spi.OpenConfigComparator;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.modules.ModuleKey;
import org.opendaylight.yangtools.concepts.Identifier;
import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
final class BGPConfigHolderImpl<V extends DataObject> implements BGPConfigHolder<V> {
+ private static final Logger LOG = LoggerFactory.getLogger(BGPConfigHolderImpl.class);
+
@GuardedBy("this")
private final BiMap<ModuleKey, Identifier> moduleToOpenConfig = HashBiMap.<ModuleKey, Identifier>create();
@GuardedBy("this")
private final Map<Identifier, V> bgpOpenConfigConfig = new HashMap<>();
+ private final OpenConfigComparator<V> comparator;
+
+ public BGPConfigHolderImpl(final OpenConfigComparator<V> comparator) {
+ this.comparator = Preconditions.checkNotNull(comparator);
+ }
+
@Override
- public synchronized boolean remove(final ModuleKey moduleKey) {
+ public synchronized boolean remove(final ModuleKey moduleKey, final V removeValue) {
final Identifier key = getKey(moduleKey);
- if (key != null) {
+ if (key != null && this.comparator.isSame(bgpOpenConfigConfig.get(key), removeValue)) {
bgpOpenConfigConfig.remove(key);
moduleToOpenConfig.remove(moduleKey);
+ LOG.trace("Configuration removed: {}", moduleKey);
return true;
}
return false;
if (!moduleToOpenConfig.containsKey(moduleKey)) {
moduleToOpenConfig.put(moduleKey, key);
bgpOpenConfigConfig.put(key, newValue);
+ LOG.trace("Configuration added: {}", moduleKey);
return true;
- } else if (!bgpOpenConfigConfig.get(key).equals(newValue)) {
+ } else if (!this.comparator.isSame(bgpOpenConfigConfig.get(key), newValue)) {
bgpOpenConfigConfig.put(key, newValue);
+ LOG.trace("Configuration updated: {}", moduleKey);
return true;
}
return false;
import java.util.HashMap;
import java.util.Map;
+import org.opendaylight.protocol.bgp.openconfig.impl.comparator.OpenConfigComparatorFactory;
import org.opendaylight.protocol.bgp.openconfig.impl.spi.BGPConfigHolder;
import org.opendaylight.protocol.bgp.openconfig.impl.spi.BGPConfigStateStore;
import org.opendaylight.yangtools.yang.binding.DataObject;
}
@Override
- public <T extends DataObject> void registerBGPConfigHolder(final Class<T> clazz, final BGPConfigHolder<T> configHolder) {
- configHolderMap.put(clazz, configHolder);
+ public <T extends DataObject> void registerBGPConfigHolder(final Class<T> clazz) {
+ configHolderMap.put(clazz, new BGPConfigHolderImpl<T>(OpenConfigComparatorFactory.getComparator(clazz)));
}
package org.opendaylight.protocol.bgp.openconfig.impl;
-import com.google.common.base.Optional;
-import java.util.Collection;
-import java.util.concurrent.Callable;
+import javax.annotation.concurrent.GuardedBy;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.controller.md.sal.binding.api.MountPoint;
import org.opendaylight.controller.md.sal.binding.api.MountPointService;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.binding.api.MountPointService.MountPointListener;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public final class BGPOpenConfig implements BindingAwareConsumer, AutoCloseable, DataTreeChangeListener<Node>, BGPOpenConfigProvider {
+public final class BGPOpenConfig implements BindingAwareConsumer, AutoCloseable, BGPOpenConfigProvider, MountPointListener {
private static final Logger LOG = LoggerFactory.getLogger(BGPOpenConfig.class);
private final BGPConfigStateStore configStateHolders;
private BGPConfigModuleMapperProvider configModuleListener;
+ @GuardedBy("this")
private BGPOpenConfigListener openConfigListener;
- private ListenerRegistration<BGPOpenConfig> registration;
+
private MountPointService mountService;
private DataBroker dataBroker;
+ private ListenerRegistration<BGPOpenConfig> mpListenerRegistration;
+
public BGPOpenConfig() {
configStateHolders = new BGPConfigStateStoreImpl();
- configStateHolders.registerBGPConfigHolder(Global.class, new BGPConfigHolderImpl<Global>());
- configStateHolders.registerBGPConfigHolder(Neighbor.class, new BGPConfigHolderImpl<Neighbor>());
+ configStateHolders.registerBGPConfigHolder(Global.class);
+ configStateHolders.registerBGPConfigHolder(Neighbor.class);
}
@Override
throw new IllegalStateException(e);
}
mountService = session.getSALService(MountPointService.class);
- registration = dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
- NETCONF_TOPOLOGY.child(Node.class)), this);
- }
-
- @Override
- public void onDataTreeChanged(final Collection<DataTreeModification<Node>> changes) {
- for (final DataTreeModification<Node> dataTreeModification : changes) {
- final DataObjectModification<Node> rootNode = dataTreeModification.getRootNode();
- if (dataTreeModification.getRootPath().getRootIdentifier().firstKeyOf(Node.class).equals(CONFIG_NODE_KEY)) {
- switch (rootNode.getModificationType()) {
- case DELETE:
- closeOpenConfigListener();
- break;
- case SUBTREE_MODIFIED:
- closeOpenConfigListener();
- getConfigMountPoint();
- break;
- case WRITE:
- getConfigMountPoint();
- break;
- default:
- throw new IllegalArgumentException("Unhandled modification type " + rootNode.getModificationType());
- }
- }
- }
- }
-
- private void getConfigMountPoint() {
- final Callable<MountPoint> callable = new Callable<MountPoint>() {
- @Override
- public MountPoint call() {
- Optional<MountPoint> mp;
- do {
- mp = mountService.getMountPoint(CONTROLLER_CONFIG_IID);
- } while (!mp.isPresent());
- return mp.get();
- }
- };
- openConfigListener = new BGPOpenConfigListener(dataBroker, callable, configStateHolders);
+ mpListenerRegistration = mountService.registerListener(CONTROLLER_CONFIG_IID, this);
}
@Override
public void close() {
closeConfigModuleListener();
closeOpenConfigListener();
- if (registration != null) {
- registration.close();
- registration = null;
+ if (mpListenerRegistration != null) {
+ mpListenerRegistration.close();
+ mpListenerRegistration = null;
}
}
return configModuleListener.getOpenConfigMapper(clazz);
}
+ @Override
+ public void onMountPointCreated(final InstanceIdentifier<?> path) {
+ LOG.debug("Created mountpoint {}.", path);
+ if (openConfigListener == null) {
+ openConfigListener = new BGPOpenConfigListener(dataBroker, mountService.getMountPoint(path).get(), configStateHolders);
+ }
+ }
+
+ @Override
+ public void onMountPointRemoved(final InstanceIdentifier<?> path) {
+ LOG.debug("Removed mountpoint {}.", path);
+ closeOpenConfigListener();
+ }
+
}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bgp.openconfig.impl.comparator;
+
+import com.google.common.base.Preconditions;
+import java.util.List;
+import java.util.Objects;
+import org.opendaylight.protocol.bgp.openconfig.impl.spi.OpenConfigComparator;
+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.rev151009.bgp.top.bgp.Global;
+
+final class GlobalComparator implements OpenConfigComparator<Global> {
+
+ @Override
+ public boolean isSame(final Global global1, final Global global2) {
+ Preconditions.checkNotNull(global1);
+ Preconditions.checkNotNull(global2);
+ //do not care about an order of collections' entries
+ if (global1.getAfiSafis() != null && global2.getAfiSafis() != null) {
+ final List<AfiSafi> afiSafiA = global1.getAfiSafis().getAfiSafi();
+ final List<AfiSafi> afiSafiB = global2.getAfiSafis().getAfiSafi();
+ if (afiSafiA.size() != afiSafiB.size()) {
+ return false;
+ }
+ if (!afiSafiA.containsAll(afiSafiB) && !afiSafiB.containsAll(afiSafiA)) {
+ return false;
+ }
+ } else if (global1.getAfiSafis() != null || global2.getAfiSafis() != null) {
+ return false;
+ }
+ if (!Objects.equals(global1.getConfig(), global2.getConfig())) {
+ return false;
+ }
+ return true;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bgp.openconfig.impl.comparator;
+
+import com.google.common.base.Preconditions;
+import java.util.List;
+import java.util.Objects;
+import org.opendaylight.protocol.bgp.openconfig.impl.spi.OpenConfigComparator;
+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.rev151009.Neighbor1;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
+
+final class NeighborComparator implements OpenConfigComparator<Neighbor> {
+
+ @Override
+ public boolean isSame(final Neighbor neighbor1, final Neighbor neighbor2) {
+ Preconditions.checkNotNull(neighbor1);
+ Preconditions.checkNotNull(neighbor2);
+ //do not care about an order of collections' entries
+ if (neighbor1.getAfiSafis() != null && neighbor2.getAfiSafis() != null) {
+ final List<AfiSafi> afiSafiA = neighbor1.getAfiSafis().getAfiSafi();
+ final List<AfiSafi> afiSafiB = neighbor2.getAfiSafis().getAfiSafi();
+ if (afiSafiA.size() != afiSafiB.size()) {
+ return false;
+ }
+ if (!afiSafiA.containsAll(afiSafiB) && !afiSafiB.containsAll(afiSafiA)) {
+ return false;
+ }
+ } else if (neighbor1.getAfiSafis() != null || neighbor2.getAfiSafis() != null) {
+ return false;
+ }
+ if (!Objects.equals(neighbor1.getConfig(), neighbor2.getConfig())) {
+ return false;
+ }
+ if (!Objects.equals(neighbor1.getKey(), neighbor2.getKey())) {
+ return false;
+ }
+ if (!Objects.equals(neighbor1.getNeighborAddress(), neighbor2.getNeighborAddress())) {
+ return false;
+ }
+ if (!Objects.equals(neighbor1.getRouteReflector(), neighbor2.getRouteReflector())) {
+ return false;
+ }
+ if (!Objects.equals(neighbor1.getTimers(), neighbor2.getTimers())) {
+ return false;
+ }
+ if (!Objects.equals(neighbor1.getTransport(), neighbor2.getTransport())) {
+ return false;
+ }
+ if (!Objects.equals(neighbor1.getAugmentation(Neighbor1.class), neighbor2.getAugmentation(Neighbor1.class))) {
+ return false;
+ }
+ return true;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bgp.openconfig.impl.comparator;
+
+import com.google.common.collect.ImmutableMap;
+import org.opendaylight.protocol.bgp.openconfig.impl.spi.OpenConfigComparator;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+public final class OpenConfigComparatorFactory {
+
+ private static final ImmutableMap<Class<?>, OpenConfigComparator<? extends DataObject>> COMPARATORS = ImmutableMap.<Class<?>, OpenConfigComparator<? extends DataObject>>builder()
+ .put(Global.class, new GlobalComparator())
+ .put(Neighbor.class, new NeighborComparator())
+ .build();
+
+ public static <T extends DataObject> OpenConfigComparator<T> getComparator(final Class<T> clazz) {
+ return (OpenConfigComparator<T>) COMPARATORS.get(clazz);
+ }
+
+}
import com.google.common.util.concurrent.ListenableFuture;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.protocol.bgp.openconfig.impl.spi.BGPConfigHolder;
import org.opendaylight.protocol.bgp.openconfig.impl.spi.BGPConfigStateStore;
import org.opendaylight.protocol.bgp.openconfig.impl.util.GlobalIdentifier;
private final BGPConfigHolder<Neighbor> neighborState;
private final BGPConfigHolder<Global> globalState;
private final BGPConfigModuleProvider configModuleOp;
+ private final DataBroker dataBroker;
- public BGPAppPeerProvider(final BGPConfigStateStore configHolders, final BGPConfigModuleProvider configModuleWriter) {
+ public BGPAppPeerProvider(final BGPConfigStateStore configHolders, final BGPConfigModuleProvider configModuleWriter, final DataBroker dataBroker) {
+ this.dataBroker = dataBroker;
this.configModuleOp = Preconditions.checkNotNull(configModuleWriter);
this.globalState = Preconditions.checkNotNull(configHolders.getBGPConfigHolder(Global.class));
this.neighborState = Preconditions.checkNotNull(configHolders.getBGPConfigHolder(Neighbor.class));
}
- public void onNeighborRemoved(final Neighbor removedNeighbor, final DataBroker dataBroker) {
+ public void onNeighborRemoved(final Neighbor removedNeighbor) {
final ModuleKey moduleKey = neighborState.getModuleKey(removedNeighbor.getKey());
if (moduleKey != null) {
try {
- globalState.remove(moduleKey);
- final Optional<Module> maybeModule = configModuleOp.readModuleConfiguration(moduleKey, dataBroker.newReadOnlyTransaction()).get();
- if (maybeModule.isPresent()) {
- configModuleOp.removeModuleConfiguration(moduleKey, dataBroker.newWriteOnlyTransaction());
+ final ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
+ final Optional<Module> maybeModule = configModuleOp.readModuleConfiguration(moduleKey, rwTx).get();
+ if (maybeModule.isPresent() && neighborState.remove(moduleKey, removedNeighbor)) {
+ configModuleOp.removeModuleConfiguration(moduleKey, rwTx);
}
} catch (final Exception e) {
LOG.error("Failed to remove a configuration module: {}", moduleKey, e);
}
}
- public void onNeighborModified(final Neighbor modifiedAppNeighbor, final DataBroker dataBroker) {
+ public void onNeighborModified(final Neighbor modifiedAppNeighbor) {
final ModuleKey moduleKey = neighborState.getModuleKey(modifiedAppNeighbor.getKey());
final ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
if (moduleKey != null) {
package org.opendaylight.protocol.bgp.openconfig.impl.moduleconfig;
-import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import java.util.Collection;
-import java.util.concurrent.Callable;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
private static final Logger LOG = LoggerFactory.getLogger(BGPOpenConfigListener.class);
- private final BGPConfigModuleProvider configModuleWriter;
private final ListenerRegistration<BGPOpenConfigListener> registerDataTreeChangeListener;
private final BGPRibImplProvider ribImplProvider;
private final BGPPeerProvider peerProvider;
private final BGPAppPeerProvider appPeerProvider;
- private final Callable<MountPoint> callable;
- public BGPOpenConfigListener(final DataBroker dataBroker, final Callable<MountPoint> callable, final BGPConfigStateStore configStateHolders) {
- this.callable = Preconditions.checkNotNull(callable);
- this.configModuleWriter = new BGPConfigModuleProvider();
- this.ribImplProvider = new BGPRibImplProvider(configStateHolders, configModuleWriter);
- this.peerProvider = new BGPPeerProvider(configStateHolders, configModuleWriter);
- this.appPeerProvider = new BGPAppPeerProvider(configStateHolders, configModuleWriter);
+ public BGPOpenConfigListener(final DataBroker dataBroker, final MountPoint mountPoint, final BGPConfigStateStore configStateHolders) {
+ final DataBroker mpDataBroker = Preconditions.checkNotNull(mountPoint).getService(DataBroker.class).get();
+ final BGPConfigModuleProvider configModuleWriter = new BGPConfigModuleProvider();
+ this.ribImplProvider = new BGPRibImplProvider(configStateHolders, configModuleWriter, mpDataBroker);
+ this.peerProvider = new BGPPeerProvider(configStateHolders, configModuleWriter, mpDataBroker);
+ this.appPeerProvider = new BGPAppPeerProvider(configStateHolders, configModuleWriter, mpDataBroker);
this.registerDataTreeChangeListener = dataBroker.registerDataTreeChangeListener(
new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, OpenConfigUtil.BGP_IID), this);
}
@Override
- public synchronized void onDataTreeChanged(final Collection<DataTreeModification<Bgp>> changes) {
- try {
- final Optional<DataBroker> databroker = callable.call().getService(DataBroker.class);
- if (databroker.isPresent()) {
- for (final DataTreeModification<Bgp> dataTreeModification : changes) {
- final DataObjectModification<Bgp> rootNode = dataTreeModification.getRootNode();
- for (final DataObjectModification<? extends DataObject> dataObjectModification : rootNode.getModifiedChildren()) {
- final DataBroker db = databroker.get();
- switch (dataObjectModification.getModificationType()) {
- case DELETE:
- onOpenConfigRemoved(dataObjectModification.getDataBefore(), db);
- break;
- case SUBTREE_MODIFIED:
- case WRITE:
- onOpenConfigModified(dataObjectModification, db);
- break;
- default:
- throw new IllegalArgumentException("Unhandled modification type " + rootNode.getModificationType());
- }
- }
+ public void onDataTreeChanged(final Collection<DataTreeModification<Bgp>> changes) {
+ for (final DataTreeModification<Bgp> dataTreeModification : changes) {
+ final DataObjectModification<Bgp> rootNode = dataTreeModification.getRootNode();
+ for (final DataObjectModification<? extends DataObject> dataObjectModification : rootNode.getModifiedChildren()) {
+ switch (dataObjectModification.getModificationType()) {
+ case DELETE:
+ onOpenConfigRemoved(dataObjectModification.getDataBefore());
+ break;
+ case SUBTREE_MODIFIED:
+ case WRITE:
+ onOpenConfigModified(dataObjectModification);
+ break;
+ default:
+ throw new IllegalArgumentException("Unhandled modification type " + rootNode.getModificationType());
}
}
- } catch (final Exception e) {
- LOG.error("Failed to obtain MountPoint.", e);
- throw new IllegalStateException(e);
}
}
registerDataTreeChangeListener.close();
}
- private void onOpenConfigRemoved(final DataObject removedData, final DataBroker dataBroker) {
+ private void onOpenConfigRemoved(final DataObject removedData) {
if (removedData instanceof Global) {
- ribImplProvider.onGlobalRemoved((Global) removedData, dataBroker);
+ ribImplProvider.onGlobalRemoved((Global) removedData);
} else if (removedData instanceof Neighbors) {
final Neighbors neighbors = (Neighbors) removedData;
for (final Neighbor neighbor : neighbors.getNeighbor()) {
- removeNeighbor(neighbor, dataBroker);
+ removeNeighbor(neighbor);
}
} else {
LOG.info("Skipping unhandled removed data: {}", removedData);
}
}
- private void onOpenConfigModified(final DataObjectModification<? extends DataObject> dataObjectModification, final DataBroker dataBroker) {
+ private void onOpenConfigModified(final DataObjectModification<? extends DataObject> dataObjectModification) {
final DataObject modifiedData = dataObjectModification.getDataAfter();
if (modifiedData instanceof Global) {
- ribImplProvider.onGlobalModified((Global) modifiedData, dataBroker);
+ ribImplProvider.onGlobalModified((Global) modifiedData);
} else if (modifiedData instanceof Neighbors) {
for (final DataObjectModification<? extends DataObject> childModification : dataObjectModification.getModifiedChildren()) {
switch (childModification.getModificationType()) {
case DELETE:
final Neighbor before = (Neighbor) childModification.getDataBefore();
- removeNeighbor(before, dataBroker);
+ removeNeighbor(before);
break;
case SUBTREE_MODIFIED:
case WRITE:
final Neighbor after = (Neighbor) childModification.getDataAfter();
- modifyNeighbor(after, dataBroker);
+ modifyNeighbor(after);
break;
default:
break;
}
}
- private void removeNeighbor(final Neighbor neighbor, final DataBroker dataBroker) {
+ private void removeNeighbor(final Neighbor neighbor) {
if (isAppNeighbor(neighbor)) {
- appPeerProvider.onNeighborRemoved(neighbor, dataBroker);
+ appPeerProvider.onNeighborRemoved(neighbor);
} else {
- peerProvider.onNeighborRemoved(neighbor, dataBroker);
+ peerProvider.onNeighborRemoved(neighbor);
}
}
- private void modifyNeighbor(final Neighbor neighbor, final DataBroker dataBroker) {
+ private void modifyNeighbor(final Neighbor neighbor) {
if (isAppNeighbor(neighbor)) {
- appPeerProvider.onNeighborModified(neighbor, dataBroker);
+ appPeerProvider.onNeighborModified(neighbor);
} else {
- peerProvider.onNeighborModified(neighbor, dataBroker);
+ peerProvider.onNeighborModified(neighbor);
}
}
import java.util.concurrent.ExecutionException;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.protocol.bgp.openconfig.impl.spi.BGPConfigHolder;
import org.opendaylight.protocol.bgp.openconfig.impl.spi.BGPConfigStateStore;
private final BGPConfigHolder<Neighbor> neighborState;
private final BGPConfigHolder<Global> globalState;
private final BGPConfigModuleProvider configModuleOp;
+ private final DataBroker dataBroker;
- public BGPPeerProvider(final BGPConfigStateStore configHolders, final BGPConfigModuleProvider configModuleWriter) {
+ public BGPPeerProvider(final BGPConfigStateStore configHolders, final BGPConfigModuleProvider configModuleWriter, final DataBroker dataBroker) {
+ this.dataBroker = dataBroker;
this.configModuleOp = Preconditions.checkNotNull(configModuleWriter);
this.globalState = Preconditions.checkNotNull(configHolders.getBGPConfigHolder(Global.class));
this.neighborState = Preconditions.checkNotNull(configHolders.getBGPConfigHolder(Neighbor.class));
}
- public void onNeighborRemoved(final Neighbor removedNeighbor, final DataBroker dataBroker) {
+ public void onNeighborRemoved(final Neighbor removedNeighbor) {
final ModuleKey moduleKey = neighborState.getModuleKey(removedNeighbor.getKey());
if (moduleKey != null) {
try {
- globalState.remove(moduleKey);
- final Optional<Module> maybeModule = configModuleOp.readModuleConfiguration(moduleKey, dataBroker.newReadOnlyTransaction()).get();
- if (maybeModule.isPresent()) {
- configModuleOp.removeModuleConfiguration(moduleKey, dataBroker.newWriteOnlyTransaction());
+ final ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
+ final Optional<Module> maybeModule = configModuleOp.readModuleConfiguration(moduleKey, rwTx).get();
+ if (maybeModule.isPresent() && neighborState.remove(moduleKey, removedNeighbor)) {
+ configModuleOp.removeModuleConfiguration(moduleKey, rwTx);
}
} catch (InterruptedException | ExecutionException | TransactionCommitFailedException e) {
LOG.error("Failed to remove a configuration module: {}", moduleKey, e);
}
}
- public void onNeighborModified(final Neighbor modifiedNeighbor, final DataBroker dataBroker) {
+ public void onNeighborModified(final Neighbor modifiedNeighbor) {
final ModuleKey moduleKey = neighborState.getModuleKey(modifiedNeighbor.getKey());
final ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
final ListenableFuture<List<AdvertizedTable>> advertizedTablesFuture = new TableTypesFunction<AdvertizedTable>(rTx,
import java.util.List;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.protocol.bgp.openconfig.impl.spi.BGPConfigHolder;
import org.opendaylight.protocol.bgp.openconfig.impl.spi.BGPConfigStateStore;
import org.opendaylight.protocol.bgp.openconfig.impl.util.GlobalIdentifier;
private final BGPConfigHolder<Global> globalState;
private final BGPConfigModuleProvider configModuleWriter;
+ private final DataBroker dataBroker;
- public BGPRibImplProvider(final BGPConfigStateStore configHolders, final BGPConfigModuleProvider configModuleWriter) {
+ public BGPRibImplProvider(final BGPConfigStateStore configHolders, final BGPConfigModuleProvider configModuleWriter, final DataBroker dataBroker) {
this.globalState = Preconditions.checkNotNull(configHolders.getBGPConfigHolder(Global.class));
this.configModuleWriter = Preconditions.checkNotNull(configModuleWriter);
+ this.dataBroker = Preconditions.checkNotNull(dataBroker);
}
- public void onGlobalRemoved(final Global removedGlobal, final DataBroker dataBroker) {
+ public void onGlobalRemoved(final Global removedGlobal) {
final ModuleKey moduleKey = this.globalState.getModuleKey(GlobalIdentifier.GLOBAL_IDENTIFIER);
if (moduleKey != null) {
try {
- this.globalState.remove(moduleKey);
- final Optional<Module> maybeModule = this.configModuleWriter.readModuleConfiguration(moduleKey, dataBroker.newReadOnlyTransaction()).get();
- if (maybeModule.isPresent()) {
- this.configModuleWriter.removeModuleConfiguration(moduleKey, dataBroker.newWriteOnlyTransaction());
+ final ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
+ final Optional<Module> maybeModule = this.configModuleWriter.readModuleConfiguration(moduleKey, rwTx).get();
+ if (maybeModule.isPresent() && globalState.remove(moduleKey, removedGlobal)) {
+ this.configModuleWriter.removeModuleConfiguration(moduleKey, rwTx);
}
} catch (final Exception e) {
LOG.error("Failed to remove a configuration module: {}", moduleKey, e);
}
}
- public void onGlobalModified(final Global modifiedGlobal, final DataBroker dataBroker) {
+ public void onGlobalModified(final Global modifiedGlobal) {
final ModuleKey moduleKey = this.globalState.getModuleKey(GlobalIdentifier.GLOBAL_IDENTIFIER);
if (moduleKey != null && this.globalState.addOrUpdate(moduleKey, GlobalIdentifier.GLOBAL_IDENTIFIER, modifiedGlobal)) {
final ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
import org.opendaylight.protocol.bgp.openconfig.impl.spi.BGPConfigStateStore;
import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenconfigMapper;
import org.opendaylight.protocol.bgp.openconfig.spi.InstanceConfiguration;
-import org.opendaylight.protocol.bgp.openconfig.spi.InstanceConfigurationIdentifier;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.modules.ModuleKey;
import org.opendaylight.yangtools.concepts.Identifier;
import org.opendaylight.yangtools.yang.binding.DataObject;
}
@Override
- public final void removeConfiguration(final InstanceConfigurationIdentifier identifier) {
- LOG.debug("Remove configuration candidate: {}", identifier);
- final ModuleKey moduleKey = createModuleKey(identifier.getName());
+ public final void removeConfiguration(final F instanceConfiguration) {
+ final T openConfig = apply(instanceConfiguration);
+ LOG.debug("Remove configuration candidate: {} mapped to: {}", instanceConfiguration, openConfig);
+ final ModuleKey moduleKey = createModuleKey(instanceConfiguration.getIdentifier().getName());
final Identifier key = configHolder.getKey(moduleKey);
- if (configHolder.remove(moduleKey)) {
+ if (configHolder.remove(moduleKey, openConfig)) {
removeConfiguration(key);
LOG.debug("Configuration [{} <-> {}] removed", key, moduleKey);
}
/**
* Remove configuration stored configuration state. The stored configuration
- * is removed when configuration with such ModuleKey is present.
+ * is removed when configuration with such ModuleKey is present and value is same.
* @param moduleKey ModuleKey identifies configuration to be removed.
+ * @param removeValue Configuration to be removed.
* @return True if configuration was removed successfully, otherwise false.
*/
- boolean remove(@Nonnull ModuleKey moduleKey);
+ boolean remove(@Nonnull ModuleKey moduleKey, @Nonnull V removeValue);
/**
* Update or add a new configuration object. If configuration object is present for
public interface BGPConfigStateStore {
/**
- * Register BGP configuration holder and store it future use.
+ * Creates instance of BGP configuration holder and store it for future use.
* @param clazz the type BGP configuration holder
- * @param configHolder BGPConfigHolder
* @throws NullPointerException when input parameters are null.
*/
- <T extends DataObject> void registerBGPConfigHolder(@Nonnull Class<T> clazz, @Nonnull BGPConfigHolder<T> configHolder);
+ <T extends DataObject> void registerBGPConfigHolder(@Nonnull Class<T> clazz);
/**
* Retrieve BGPConfigHolder by input parameter class type.
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bgp.openconfig.impl.spi;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Comparator servers for comparing of configuration instances.
+ * Supplies equals(), since it can produce unwanted false negative
+ * results (comparing Collections with same items in different order).
+ *
+ * @param <T>
+ */
+public interface OpenConfigComparator<T extends DataObject> {
+
+ /**
+ * Compares two non-null objects.
+ * @param object1
+ * @param object2
+ * @return The result of comparison.
+ */
+ boolean isSame(@Nonnull T object1, @Nonnull T object2);
+
+}
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+
import org.junit.Test;
+import org.opendaylight.protocol.bgp.openconfig.impl.comparator.OpenConfigComparatorFactory;
import org.opendaylight.protocol.bgp.openconfig.impl.util.GlobalIdentifier;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.ConfigBuilder;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.GlobalBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.bgp.openconfig.rev150718.OpenconfigBgp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.modules.ModuleKey;
-import org.opendaylight.yangtools.yang.binding.DataContainer;
-import org.opendaylight.yangtools.yang.binding.DataObject;
public class BGPConfigHolderImplTest {
- private static final BGPConfigHolderImpl<DataObject> HOLDER = new BGPConfigHolderImpl<DataObject>();
+ private static final BGPConfigHolderImpl<Global> HOLDER = new BGPConfigHolderImpl<Global>(OpenConfigComparatorFactory.getComparator(Global.class));
@Test
public void test() {
final ModuleKey moduleKey2 = new ModuleKey("key2", OpenconfigBgp.class);
assertNull(HOLDER.getKey(moduleKey));
- final MyDataObject obj1 = new MyDataObject();
- final MyDataObject obj2 = new MyDataObject();
+ final Global obj1 = new GlobalBuilder().build();
+ final Global obj2 = new GlobalBuilder().setConfig(new ConfigBuilder().build()).build();
assertTrue(HOLDER.addOrUpdate(moduleKey, GlobalIdentifier.GLOBAL_IDENTIFIER, obj1));
assertFalse(HOLDER.addOrUpdate(moduleKey, GlobalIdentifier.GLOBAL_IDENTIFIER, obj1));
assertEquals(moduleKey, HOLDER.getModuleKey(GlobalIdentifier.GLOBAL_IDENTIFIER));
assertEquals(GlobalIdentifier.GLOBAL_IDENTIFIER, HOLDER.getKey(moduleKey));
assertTrue(HOLDER.addOrUpdate(moduleKey, GlobalIdentifier.GLOBAL_IDENTIFIER, obj2));
assertFalse(HOLDER.addOrUpdate(moduleKey, GlobalIdentifier.GLOBAL_IDENTIFIER, obj2));
- assertTrue(HOLDER.remove(moduleKey));
- assertFalse(HOLDER.remove(moduleKey2));
+ assertTrue(HOLDER.remove(moduleKey, obj2));
+ assertFalse(HOLDER.remove(moduleKey2, obj1));
assertTrue(HOLDER.addOrUpdate(moduleKey, GlobalIdentifier.GLOBAL_IDENTIFIER, obj2));
}
-
- private class MyDataObject implements DataObject {
- @Override
- public Class<? extends DataContainer> getImplementedInterface() {
- return null;
- }
- }
}
*/
package org.opendaylight.protocol.bgp.openconfig.impl;
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+
import org.junit.Test;
-import org.opendaylight.yangtools.yang.binding.DataContainer;
-import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
public class BGPConfigStateStoreImplTest {
private static final BGPConfigStateStoreImpl STORE = new BGPConfigStateStoreImpl();
- private static final BGPConfigHolderImpl<MyDataObject> HOLDER = new BGPConfigHolderImpl<MyDataObject>();
@Test
public void test() {
- assertNull(STORE.getBGPConfigHolder(MyDataObject.class));
- STORE.registerBGPConfigHolder(MyDataObject.class, HOLDER);
- assertEquals(HOLDER, STORE.getBGPConfigHolder(MyDataObject.class));
- }
-
- private class MyDataObject implements DataObject {
- @Override
- public Class<? extends DataContainer> getImplementedInterface() {
- return null;
- }
+ assertNull(STORE.getBGPConfigHolder(Neighbor.class));
+ STORE.registerBGPConfigHolder(Neighbor.class);
+ assertNotNull(STORE.getBGPConfigHolder(Neighbor.class));
}
}
* 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;
-import static org.junit.Assert.assertTrue;
+import com.google.common.base.Optional;
import com.google.common.util.concurrent.CheckedFuture;
-import java.util.Arrays;
-import java.util.Collection;
import org.junit.After;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.MountPoint;
import org.opendaylight.controller.md.sal.binding.api.MountPointService;
+import org.opendaylight.controller.md.sal.binding.api.MountPointService.MountPointListener;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
-import org.opendaylight.protocol.bgp.openconfig.impl.moduleconfig.BGPOpenConfigListener;
+import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenconfigMapper;
+import org.opendaylight.protocol.bgp.openconfig.spi.pojo.BGPAppPeerInstanceConfiguration;
+import org.opendaylight.protocol.bgp.openconfig.spi.pojo.BGPPeerInstanceConfiguration;
import org.opendaylight.protocol.bgp.openconfig.spi.pojo.BGPRibInstanceConfiguration;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
public class BGPOpenConfigTest {
- private static final BGPOpenConfig CONFIG = new BGPOpenConfig();
+ private final BGPOpenConfig bgpOpenConfig = new BGPOpenConfig();
private final ConsumerContext session = Mockito.mock(ConsumerContext.class);
+
private final DataBroker dataBroker = Mockito.mock(DataBroker.class);
private final MountPointService mountService = Mockito.mock(MountPointService.class);
private final ListenerRegistration<?> registration = Mockito.mock(ListenerRegistration.class);
private final BindingTransactionChain txChain = Mockito.mock(BindingTransactionChain.class);
private final WriteTransaction writeTx = Mockito.mock(WriteTransaction.class);
- private final ListenerRegistration<BGPOpenConfigListener> listener = Mockito.mock(ListenerRegistration.class);
-
- private Collection<DataTreeModification<Node>> changes;
@SuppressWarnings("unchecked")
@Before
public void setUp() throws Exception {
- Mockito.doNothing().when(this.registration).close();
-
Mockito.doReturn(this.dataBroker).when(this.session).getSALService(DataBroker.class);
Mockito.doReturn(this.mountService).when(this.session).getSALService(MountPointService.class);
- Mockito.doReturn(this.registration).when(this.dataBroker).registerDataTreeChangeListener(Mockito.any(DataTreeIdentifier.class), Mockito.eq(CONFIG));
+ Mockito.doReturn(this.registration).when(this.dataBroker).registerDataTreeChangeListener(Mockito.any(DataTreeIdentifier.class), Mockito.any(DataTreeChangeListener.class));
Mockito.doReturn(this.txChain).when(this.dataBroker).createTransactionChain(Mockito.any(TransactionChainListener.class));
Mockito.doReturn(this.writeTx).when(this.txChain).newWriteOnlyTransaction();
Mockito.doNothing().when(this.txChain).close();
Mockito.doReturn(checkedFuture).when(this.writeTx).submit();
Mockito.doReturn(null).when(checkedFuture).checkedGet();
- final DataTreeModification<Node> modif1 = Mockito.mock(DataTreeModification.class, Mockito.RETURNS_DEEP_STUBS);
- final DataTreeModification<Node> modif2 = Mockito.mock(DataTreeModification.class, Mockito.RETURNS_DEEP_STUBS);
- final DataTreeModification<Node> modif3 = Mockito.mock(DataTreeModification.class, Mockito.RETURNS_DEEP_STUBS);
-
- final DataObjectModification<Node> obj1 = Mockito.mock(DataObjectModification.class);
- final DataObjectModification<Node> obj2 = Mockito.mock(DataObjectModification.class);
- final DataObjectModification<Node> obj3 = Mockito.mock(DataObjectModification.class);
-
- Mockito.doReturn(obj1).when(modif1).getRootNode();
- Mockito.doReturn(obj2).when(modif2).getRootNode();
- Mockito.doReturn(obj3).when(modif3).getRootNode();
-
- Mockito.doReturn(ModificationType.DELETE).when(obj1).getModificationType();
- Mockito.doReturn(ModificationType.SUBTREE_MODIFIED).when(obj2).getModificationType();
- Mockito.doReturn(ModificationType.WRITE).when(obj3).getModificationType();
-
- final InstanceIdentifier<Topology> netconfTopo = InstanceIdentifier.builder(NetworkTopology.class)
- .child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName()))).build();
- final InstanceIdentifier<Node> iid = netconfTopo.child(Node.class, new NodeKey(new NodeId("controller-config")));
+ final MountPoint mp = Mockito.mock(MountPoint.class);
+ Mockito.doReturn(Optional.of(this.dataBroker)).when(mp).getService(DataBroker.class);
+ final ListenerRegistration<MountPointListener> mpRegistration = Mockito.mock(ListenerRegistration.class);
+ Mockito.doNothing().when(mpRegistration).close();
+ Mockito.doReturn(mpRegistration).when(this.mountService).registerListener(Mockito.<InstanceIdentifier<?>>any(), Mockito.any(MountPointListener.class));
+ Mockito.doReturn(Optional.of(mp)).when(this.mountService).getMountPoint(Mockito.any(InstanceIdentifier.class));
- final DataTreeIdentifier<Node> dtId = new DataTreeIdentifier<Node>(LogicalDatastoreType.CONFIGURATION, iid);
- Mockito.when(modif1.getRootPath()).thenReturn(dtId);
- Mockito.when(modif2.getRootPath()).thenReturn(dtId);
- Mockito.when(modif3.getRootPath()).thenReturn(dtId);
- this.changes = Arrays.asList(modif1, modif2, modif3);
-
- Mockito.doReturn(this.listener).when(this.dataBroker).registerDataTreeChangeListener(Mockito.any(DataTreeIdentifier.class), Mockito.any(DataTreeChangeListener.class));
- Mockito.doNothing().when(this.listener).close();
+ this.bgpOpenConfig.onSessionInitialized(this.session);
+ }
- CONFIG.onSessionInitialized(this.session);
+ @After
+ public void tearDown() {
+ this.bgpOpenConfig.close();
}
- @SuppressWarnings("unchecked")
@Test
- public void testInit() {
- Mockito.verify(this.session, Mockito.times(2)).getSALService(Mockito.any(Class.class));
- Mockito.verify(this.dataBroker).registerDataTreeChangeListener(Mockito.any(DataTreeIdentifier.class), Mockito.eq(CONFIG));
+ public void testOnSessionInitialized() {
+ Mockito.verify(this.session).getSALService(DataBroker.class);
+ Mockito.verify(this.session).getSALService(MountPointService.class);
}
@Test
- public void testGetMapper() {
- assertTrue(CONFIG.getOpenConfigMapper(BGPRibInstanceConfiguration.class).toString().contains("BGPGlobalProviderImpl"));
+ public void testOnMountPoint() {
+ this.bgpOpenConfig.onMountPointCreated(null);
+ Mockito.verify(this.mountService).getMountPoint(Mockito.any(InstanceIdentifier.class));
+ Mockito.verify(this.dataBroker).registerDataTreeChangeListener(Mockito.any(DataTreeIdentifier.class), Mockito.any(DataTreeChangeListener.class));
+ this.bgpOpenConfig.onMountPointRemoved(null);
+ Mockito.verify(this.registration).close();
}
- @SuppressWarnings("unchecked")
@Test
- public void testOnDataTreeChanged() {
- CONFIG.onDataTreeChanged(this.changes);
- Mockito.verify(this.dataBroker, Mockito.times(3)).registerDataTreeChangeListener(Mockito.any(DataTreeIdentifier.class), Mockito.any(DataTreeChangeListener.class));
+ public void testGetOpenConfigMapper() {
+ final BGPOpenconfigMapper<BGPRibInstanceConfiguration> rib = this.bgpOpenConfig.getOpenConfigMapper(BGPRibInstanceConfiguration.class);
+ Assert.assertNotNull(rib);
+ final BGPOpenconfigMapper<BGPPeerInstanceConfiguration> peer = this.bgpOpenConfig.getOpenConfigMapper(BGPPeerInstanceConfiguration.class);
+ Assert.assertNotNull(peer);
+ final BGPOpenconfigMapper<BGPAppPeerInstanceConfiguration> appPeer = this.bgpOpenConfig.getOpenConfigMapper(BGPAppPeerInstanceConfiguration.class);
+ Assert.assertNotNull(appPeer);
}
- @After
- public void close() {
- CONFIG.close();
- }
-}
\ No newline at end of file
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bgp.openconfig.impl.comparator;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.Lists;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafiBuilder;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.AfiSafisBuilder;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.GlobalBuilder;
+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;
+
+public class GlobalComparatorTest {
+
+ private static final GlobalComparator COMPARATOR = new GlobalComparator();
+
+ @Test
+ public void testIsSamePositiveSimple() {
+ final Global a = new GlobalBuilder().build();
+ final Global b = new GlobalBuilder().build();
+ assertTrue(COMPARATOR.isSame(a, b));
+ }
+
+ @Test
+ public void testIsSamePositiveCollection() {
+ final Global a = new GlobalBuilder().setAfiSafis(new AfiSafisBuilder()
+ .setAfiSafi(Lists.newArrayList(
+ new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class).build(),
+ new AfiSafiBuilder().setAfiSafiName(IPV6UNICAST.class).build()))
+ .build()).build();
+ final Global b = new GlobalBuilder().setAfiSafis(new AfiSafisBuilder()
+ .setAfiSafi(Lists.newArrayList(
+ new AfiSafiBuilder().setAfiSafiName(IPV6UNICAST.class).build(),
+ new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class).build()))
+ .build()).build();
+ assertTrue(COMPARATOR.isSame(a, b));
+ }
+
+ @Test
+ public void testIsSameNegativeCollectionSize() {
+ final Global a = new GlobalBuilder().setAfiSafis(new AfiSafisBuilder()
+ .setAfiSafi(Lists.newArrayList(
+ new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class).build(),
+ new AfiSafiBuilder().setAfiSafiName(IPV6UNICAST.class).build()))
+ .build()).build();
+ final Global b = new GlobalBuilder().setAfiSafis(new AfiSafisBuilder()
+ .setAfiSafi(Lists.newArrayList(
+ new AfiSafiBuilder().setAfiSafiName(IPV6UNICAST.class).build()))
+ .build()).build();
+ assertFalse(COMPARATOR.isSame(a, b));
+ }
+
+ @Test
+ public void testIsSameNegativeCollectionContent() {
+ final Global a = new GlobalBuilder().setAfiSafis(new AfiSafisBuilder()
+ .setAfiSafi(Lists.newArrayList(
+ new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class).build()))
+ .build()).build();
+ final Global b = new GlobalBuilder().setAfiSafis(new AfiSafisBuilder()
+ .setAfiSafi(Lists.newArrayList(
+ new AfiSafiBuilder().setAfiSafiName(IPV6UNICAST.class).build()))
+ .build()).build();
+ assertFalse(COMPARATOR.isSame(a, b));
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bgp.openconfig.impl.comparator;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.Lists;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafiBuilder;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.AfiSafisBuilder;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.NeighborBuilder;
+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;
+
+public class NeighborComparatorTest {
+
+ private static final NeighborComparator COMPARATOR = new NeighborComparator();
+
+ @Test
+ public void testIsSamePositiveSimple() {
+ final Neighbor a = new NeighborBuilder().build();
+ final Neighbor b = new NeighborBuilder().build();
+ assertTrue(COMPARATOR.isSame(a, b));
+ }
+
+ @Test
+ public void testIsSamePositiveCollection() {
+ final Neighbor a = new NeighborBuilder().setAfiSafis(new AfiSafisBuilder()
+ .setAfiSafi(Lists.newArrayList(
+ new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class).build(),
+ new AfiSafiBuilder().setAfiSafiName(IPV6UNICAST.class).build()))
+ .build()).build();
+ final Neighbor b = new NeighborBuilder().setAfiSafis(new AfiSafisBuilder()
+ .setAfiSafi(Lists.newArrayList(
+ new AfiSafiBuilder().setAfiSafiName(IPV6UNICAST.class).build(),
+ new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class).build()))
+ .build()).build();
+ assertTrue(COMPARATOR.isSame(a, b));
+ }
+
+ @Test
+ public void testIsSameNegativeCollectionSize() {
+ final Neighbor a = new NeighborBuilder().setAfiSafis(new AfiSafisBuilder()
+ .setAfiSafi(Lists.newArrayList(
+ new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class).build(),
+ new AfiSafiBuilder().setAfiSafiName(IPV6UNICAST.class).build()))
+ .build()).build();
+ final Neighbor b = new NeighborBuilder().setAfiSafis(new AfiSafisBuilder()
+ .setAfiSafi(Lists.newArrayList(
+ new AfiSafiBuilder().setAfiSafiName(IPV6UNICAST.class).build()))
+ .build()).build();
+ assertFalse(COMPARATOR.isSame(a, b));
+ }
+
+ @Test
+ public void testIsSameNegativeCollectionContent() {
+ final Neighbor a = new NeighborBuilder().setAfiSafis(new AfiSafisBuilder()
+ .setAfiSafi(Lists.newArrayList(
+ new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class).build()))
+ .build()).build();
+ final Neighbor b = new NeighborBuilder().setAfiSafis(new AfiSafisBuilder()
+ .setAfiSafi(Lists.newArrayList(
+ new AfiSafiBuilder().setAfiSafiName(IPV6UNICAST.class).build()))
+ .build()).build();
+ assertFalse(COMPARATOR.isSame(a, b));
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bgp.openconfig.impl.comparator;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+public class OpenConfigComparatorsTest {
+
+ @Test
+ public void testGetComparatorGlobal() {
+ assertNotNull(OpenConfigComparatorFactory.getComparator(Global.class));
+ }
+
+ @Test
+ public void testGetComparatorNeighbor() {
+ assertNotNull(OpenConfigComparatorFactory.getComparator(Neighbor.class));
+ }
+
+ @Test
+ public void testGetComparatorDataObject() {
+ assertNull(OpenConfigComparatorFactory.getComparator(DataObject.class));
+ }
+
+}
@Test
public void testRemoveConfiguration() {
- Mockito.doReturn(true).when(this.configHolder).remove(Mockito.any(ModuleKey.class));
- mapper.removeConfiguration(IDENTIFIER);
+ Mockito.doReturn(true).when(this.configHolder).remove(Mockito.any(ModuleKey.class), Mockito.any(Neighbor.class));
+ mapper.removeConfiguration(INSTANCE_CONFIGURATION);
Mockito.verify(wTx, Mockito.times(1)).delete(Mockito.any(LogicalDatastoreType.class), Mockito.any(InstanceIdentifier.class));
- Mockito.doReturn(false).when(this.configHolder).remove(Mockito.any(ModuleKey.class));
- mapper.removeConfiguration(IDENTIFIER);
+ Mockito.doReturn(false).when(this.configHolder).remove(Mockito.any(ModuleKey.class), Mockito.any(Neighbor.class));
+ mapper.removeConfiguration(INSTANCE_CONFIGURATION);
Mockito.verify(wTx, Mockito.times(1)).delete(Mockito.any(LogicalDatastoreType.class), Mockito.any(InstanceIdentifier.class));
}
void writeConfiguration(@Nonnull T instanceConfiguration);
/**
- * Remove an existing configuration identified by InstanceConfigurationIdentifier.
- * @param instanceConfiguration an identifier of the configuration instance
+ * Remove an existing configuration.
+ * @param instanceConfiguration An input configuration is mapped to OpenConfig API
* @throws NullPointerException when instanceConfiguration is null
*/
- void removeConfiguration(@Nonnull InstanceConfigurationIdentifier instanceConfiguration);
+ void removeConfiguration(@Nonnull T instanceConfiguration);
}
private final class AppPeerModuleTracker implements BGPConfigModuleTracker {
private final BGPOpenconfigMapper<BGPAppPeerInstanceConfiguration> appProvider;
- private final InstanceConfigurationIdentifier identifier;
+ private final BGPAppPeerInstanceConfiguration bgpAppPeerInstanceConfiguration;
public AppPeerModuleTracker(final Optional<BGPOpenConfigProvider> openConfigProvider) {
if (openConfigProvider.isPresent()) {
} else {
appProvider = null;
}
- identifier = new InstanceConfigurationIdentifier(getIdentifier().getInstanceName());
+ final InstanceConfigurationIdentifier identifier = new InstanceConfigurationIdentifier(getIdentifier().getInstanceName());
+ bgpAppPeerInstanceConfiguration = new BGPAppPeerInstanceConfiguration(identifier, getApplicationRibId().getValue(),
+ Rev130715Util.getIpv4Address(getBgpPeerId()));
}
@Override
public void onInstanceCreate() {
if (appProvider != null) {
- appProvider.writeConfiguration(new BGPAppPeerInstanceConfiguration(identifier, getApplicationRibId().getValue(),
- Rev130715Util.getIpv4Address(getBgpPeerId())));
+ appProvider.writeConfiguration(this.bgpAppPeerInstanceConfiguration);
}
}
@Override
public void onInstanceClose() {
if (appProvider != null) {
- appProvider.removeConfiguration(identifier);
+ appProvider.removeConfiguration(this.bgpAppPeerInstanceConfiguration);
}
}
private final class BGPPeerModuleTracker implements BGPConfigModuleTracker {
private final BGPOpenconfigMapper<BGPPeerInstanceConfiguration> neighborProvider;
- private final InstanceConfigurationIdentifier identifier;
+ private final BGPPeerInstanceConfiguration bgpPeerInstanceConfiguration;
public BGPPeerModuleTracker(final Optional<BGPOpenConfigProvider> openconfigProvider) {
if (openconfigProvider.isPresent()) {
} else {
neighborProvider = null;
}
- identifier = new InstanceConfigurationIdentifier(getIdentifier().getInstanceName());
+ final InstanceConfigurationIdentifier identifier = new InstanceConfigurationIdentifier(getIdentifier().getInstanceName());
+ this.bgpPeerInstanceConfiguration = new BGPPeerInstanceConfiguration(identifier, Rev130715Util.getIpvAddress(getNormalizedHost()),
+ Rev130715Util.getPort(getPort().getValue()), getHoldtimer(), getPeerRole(), getInitiateConnection(),
+ getAdvertizedTableDependency(), Rev130715Util.getASNumber(getAsOrDefault(getRibDependency()).getValue()),
+ getOptionaPassword(getPassword()));
}
@Override
public void onInstanceCreate() {
if (neighborProvider != null) {
- neighborProvider.writeConfiguration(new BGPPeerInstanceConfiguration(identifier, Rev130715Util.getIpvAddress(getNormalizedHost()),
- Rev130715Util.getPort(getPort().getValue()), getHoldtimer(), getPeerRole(), getInitiateConnection(),
- getAdvertizedTableDependency(), Rev130715Util.getASNumber(getAsOrDefault(getRibDependency()).getValue()),
- getOptionaPassword(getPassword())));
+ neighborProvider.writeConfiguration(this.bgpPeerInstanceConfiguration);
}
}
@Override
public void onInstanceClose() {
if (neighborProvider != null) {
- neighborProvider.removeConfiguration(identifier);
+ neighborProvider.removeConfiguration(this.bgpPeerInstanceConfiguration);
}
}
}
- private Optional<Rfc2385Key> getOptionaPassword(Rfc2385Key password) {
+ private Optional<Rfc2385Key> getOptionaPassword(final Rfc2385Key password) {
return password != null && ! password.getValue().isEmpty() ? Optional.of(password) : Optional.<Rfc2385Key>absent();
}
private final class RIBImplModuleTracker implements BGPConfigModuleTracker {
private final BGPOpenconfigMapper<BGPRibInstanceConfiguration> globalWriter;
- private final InstanceConfigurationIdentifier identifier;
+ private final BGPRibInstanceConfiguration bgpRibConfig;
public RIBImplModuleTracker(final BGPOpenconfigMapper<BGPRibInstanceConfiguration> globalWriter) {
this.globalWriter = globalWriter;
- this.identifier = new InstanceConfigurationIdentifier(getIdentifier().getInstanceName());
+ final InstanceConfigurationIdentifier identifier = new InstanceConfigurationIdentifier(getIdentifier().getInstanceName());
+ final List<BgpTableType> tableDependency = getLocalTableDependency();
+ final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber as = Rev130715Util.getASNumber(getLocalAs());
+ final Ipv4Address bgpRibId = Rev130715Util.getIpv4Address(getBgpRibId());
+ final Ipv4Address clusterId = Rev130715Util.getIpv4Address(getClusterId());
+ this.bgpRibConfig = new BGPRibInstanceConfiguration(identifier, as, bgpRibId, clusterId, tableDependency);
}
@Override
public void onInstanceCreate() {
if (globalWriter != null) {
- final List<BgpTableType> tableDependency = getLocalTableDependency();
- final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber as = Rev130715Util.getASNumber(getLocalAs());
- final Ipv4Address bgpRibId = Rev130715Util.getIpv4Address(getBgpRibId());
- final Ipv4Address clusterId = Rev130715Util.getIpv4Address(getClusterId());
-
- final BGPRibInstanceConfiguration bgpRibConfig = new BGPRibInstanceConfiguration(identifier, as, bgpRibId, clusterId, tableDependency);
- globalWriter.writeConfiguration(bgpRibConfig);
+ globalWriter.writeConfiguration(this.bgpRibConfig);
}
}
@Override
public void onInstanceClose() {
if (globalWriter != null) {
- globalWriter.removeConfiguration(identifier);
+ globalWriter.removeConfiguration(this.bgpRibConfig);
}
}