package org.opendaylight.controller.config.yang.bgp.rib.impl;
import com.google.common.base.Optional;
+import java.util.Collections;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeIdentifier;
import org.opendaylight.protocol.bgp.openconfig.spi.InstanceConfigurationIdentifier;
import org.opendaylight.protocol.bgp.openconfig.spi.pojo.BGPAppPeerInstanceConfiguration;
import org.opendaylight.protocol.bgp.rib.impl.ApplicationPeer;
+import org.opendaylight.protocol.bgp.rib.impl.BGPPeer;
import org.opendaylight.protocol.bgp.rib.impl.RIBImpl;
+import org.opendaylight.protocol.bgp.rib.impl.StrictBGPPeerRegistry;
+import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry;
+import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionPreferences;
+import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.ApplicationRib;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@Override
public java.lang.AutoCloseable createInstance() {
+ // add to peer-registry to catch any conflicting peer addresses
+ addToPeerRegistry();
+
final YangInstanceIdentifier id = YangInstanceIdentifier.builder().node(ApplicationRib.QNAME).nodeWithKey(ApplicationRib.QNAME, APP_ID_QNAME, getApplicationRibId().getValue()).node(Tables.QNAME).node(Tables.QNAME).build();
final DOMDataTreeChangeService service = (DOMDataTreeChangeService) getDataBrokerDependency().getSupportedExtensions().get(DOMDataTreeChangeService.class);
- return service.registerDataTreeChangeListener(new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, id), new ApplicationPeer(getApplicationRibId(), getBgpPeerId(), (RIBImpl) getTargetRibDependency(), new AppPeerModuleTracker(getTargetRibDependency().getOpenConfigProvider())));
+ final ListenerRegistration<ApplicationPeer> listenerRegistration = service.registerDataTreeChangeListener(new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, id), new ApplicationPeer(getApplicationRibId(), getBgpPeerId(), (RIBImpl) getTargetRibDependency(), new AppPeerModuleTracker(getTargetRibDependency().getOpenConfigProvider())));
+
+ return new CloseableNoEx() {
+ @Override
+ public void close() {
+ listenerRegistration.close();
+ removeFromPeerRegistry();
+ }
+ };
+ }
+
+ private interface CloseableNoEx extends AutoCloseable {
+ @Override
+ void close();
+ }
+
+ private void addToPeerRegistry() {
+ final RIB r = getTargetRibDependency();
+
+ final IpAddress bgpPeerId = new IpAddress(getBgpPeerId());
+ final BGPPeer bgpClientPeer = new BGPPeer(bgpPeerId.getIpv4Address().getValue(), r, PeerRole.Internal);
+
+ final BGPSessionPreferences prefs = new BGPSessionPreferences(r.getLocalAs(), 0, r.getBgpIdentifier(),
+ r.getLocalAs(), Collections.emptyList());
+
+ final BGPPeerRegistry peerRegistry = getPeerRegistryBackwards();
+ peerRegistry.addPeer(bgpPeerId, bgpClientPeer, prefs);
+ }
+
+ private void removeFromPeerRegistry() {
+ final IpAddress bgpPeerId = new IpAddress(getBgpPeerId());
+ final BGPPeerRegistry peerRegistry = getPeerRegistryBackwards();
+ peerRegistry.removePeer(bgpPeerId);
+ }
+
+ private BGPPeerRegistry getPeerRegistryBackwards() {
+ return getPeerRegistry() == null ? StrictBGPPeerRegistry.GLOBAL : getPeerRegistryDependency();
}
private final class AppPeerModuleTracker implements BGPConfigModuleTracker {
package org.opendaylight.controller.config.yang.bgp.rib.impl;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.util.List;
+
import javax.management.InstanceNotFoundException;
import javax.management.ObjectName;
+
import org.junit.Test;
import org.opendaylight.controller.config.api.jmx.CommitStatus;
import org.opendaylight.controller.config.spi.ModuleFactory;
public class BGPApplicationPeerModuleTest extends AbstractRIBImplModuleTest {
private static final String INSTANCE_NAME = "application-peer-instance";
+ private static final String INSTANCE_NAME2 = "application-peer-instance-2";
private static final String FACTORY_NAME = BGPApplicationPeerModuleFactory.NAME;
private static final ApplicationRibId APP_RIB_ID = new ApplicationRibId("application-peer-test");
private static final ApplicationRibId NEW_APP_RIB_ID = new ApplicationRibId("new-application-peer-name");
+ private ObjectName dataBroker = null;
+ private ObjectName ribModule = null;
+
@Override
protected List<ModuleFactory> getModuleFactories() {
final List<ModuleFactory> moduleFactories = super.getModuleFactories();
assertEquals(NEW_APP_RIB_ID, getApplicationRibId());
}
+ @Test
+ public void testConflictingPeerAddress() throws Exception {
+ createApplicationPeerInstance();
+ try {
+ createApplicationPeerInstance(INSTANCE_NAME2);
+ fail();
+ } catch (IllegalStateException e) {
+ assertTrue(e.getMessage().contains("getInstance() failed for ModuleIdentifier"));
+ final Throwable ex = e.getCause();
+ assertNotNull(ex);
+ assertTrue(ex.getMessage().contains("Peer for IpAddress"));
+ assertTrue(ex.getMessage().contains("already present"));
+ }
+ }
+
private CommitStatus createApplicationPeerInstance() throws Exception {
+ return createApplicationPeerInstance(INSTANCE_NAME);
+ }
+
+ private CommitStatus createApplicationPeerInstance(final String instanceName) throws Exception {
final ConfigTransactionJMXClient transaction = this.configRegistryClient.createTransaction();
- final ObjectName objName = transaction.createModule(BGPApplicationPeerModuleFactory.NAME, INSTANCE_NAME);
+ final ObjectName objName = transaction.createModule(BGPApplicationPeerModuleFactory.NAME, instanceName);
final BGPApplicationPeerModuleMXBean mxBean = transaction.newMXBeanProxy(objName, BGPApplicationPeerModuleMXBean.class);
final ObjectName dataBrokerON = lookupDomAsyncDataBroker(transaction);
mxBean.setDataBroker(dataBrokerON);
mxBean.setBgpPeerId(BGP_ID);
mxBean.setApplicationRibId(APP_RIB_ID);
- mxBean.setTargetRib(createRIBImplModuleInstance(transaction, createAsyncDataBrokerInstance(transaction)));
+ if (this.dataBroker == null) {
+ this.dataBroker = createAsyncDataBrokerInstance(transaction);
+ }
+ if (this.ribModule == null) {
+ this.ribModule = createRIBImplModuleInstance(transaction, this.dataBroker);
+ }
+ mxBean.setTargetRib(this.ribModule);
return transaction.commit();
}