summaryrefslogtreecommitdiffstats
path: root/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors
diff options
context:
space:
mode:
Diffstat (limited to 'infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors')
-rw-r--r--infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors/BgpPeerWriterFactory.java110
-rw-r--r--infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors/NeighborCustomizer.java139
-rw-r--r--infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors/NetworkInstanceCustomizer.java70
-rw-r--r--infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors/ProtocolCustomizer.java75
4 files changed, 394 insertions, 0 deletions
diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors/BgpPeerWriterFactory.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors/BgpPeerWriterFactory.java
new file mode 100644
index 000000000..064c70b57
--- /dev/null
+++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors/BgpPeerWriterFactory.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.bgp.neighbors;
+
+import com.google.common.collect.Sets;
+import com.google.inject.Inject;
+import io.fd.honeycomb.infra.bgp.BgpConfiguration;
+import io.fd.honeycomb.translate.impl.write.GenericListWriter;
+import io.fd.honeycomb.translate.write.WriterFactory;
+import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder;
+import javax.annotation.Nonnull;
+import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService;
+import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry;
+import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
+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.neighbor.group.AfiSafis;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Config;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Timers;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Transport;
+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;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Neighbors;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.NetworkInstances;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstance;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.Protocols;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.AfiSafi1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Config1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Config2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Protocol1;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Initializes writer for Bgp Neighbors ({@link Neighbor} node) and all its parents required by HC infra.
+ */
+public final class BgpPeerWriterFactory implements WriterFactory {
+ private static final InstanceIdentifier<NetworkInstance> NETWORK_INSTANCE_ID =
+ InstanceIdentifier.create(NetworkInstances.class)
+ .child(NetworkInstance.class);
+
+ private static final InstanceIdentifier<Protocol> PROTOCOL_ID =
+ NETWORK_INSTANCE_ID.child(Protocols.class).child(Protocol.class);
+
+ private static final InstanceIdentifier<Neighbor> NEIGHBOR_ID =
+ PROTOCOL_ID.augmentation(Protocol1.class).child(Bgp.class).child(Neighbors.class).child(Neighbor.class);
+
+ @Inject
+ private BgpConfiguration configuration;
+ @Inject
+ private RIB globalRib;
+ @Inject
+ private BGPOpenConfigMappingService mappingService;
+ @Inject
+ private BGPPeerRegistry peerRegistry;
+
+ @Override
+ public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) {
+ // NetworkInstances
+ // NetworkInstance =
+ registry.add(new GenericListWriter<>(NETWORK_INSTANCE_ID,
+ new NetworkInstanceCustomizer(configuration.bgpNetworkInstanceName)));
+
+ // Protocols
+ // Protocol =
+ registry.add(
+ new GenericListWriter<>(PROTOCOL_ID, new ProtocolCustomizer(configuration.bgpProtocolInstanceName.get())));
+
+ // Protocol1 augmentation (from bgp-openconfig-extensions)
+ // Bgp
+ // Neighbors
+ // Neighbor=
+ final InstanceIdentifier<Neighbor> neighbor = InstanceIdentifier.create(Neighbor.class);
+ registry.subtreeAdd(
+ // TODO (HONEYCOMB-359): there might be more subnodes that needs to be handled
+ Sets.newHashSet(
+ neighbor.child(Config.class),
+ neighbor.child(Config.class).augmentation(Config2.class),
+ neighbor.child(AfiSafis.class),
+ neighbor.child(AfiSafis.class).child(AfiSafi.class),
+ neighbor.child(AfiSafis.class).child(AfiSafi.class).augmentation(AfiSafi1.class),
+ neighbor.child(Timers.class),
+ neighbor.child(Timers.class).child(
+ org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers.Config.class),
+ neighbor.child(Transport.class),
+ neighbor.child(Transport.class).child(
+ org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.transport.Config.class),
+ neighbor.child(Transport.class).child(
+ org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.transport.Config.class)
+ .augmentation(Config1.class)
+ ),
+ new GenericListWriter<>(
+ NEIGHBOR_ID,
+ new NeighborCustomizer(globalRib, peerRegistry, mappingService)));
+ }
+}
+
diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors/NeighborCustomizer.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors/NeighborCustomizer.java
new file mode 100644
index 000000000..50ae45b40
--- /dev/null
+++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors/NeighborCustomizer.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.bgp.neighbors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static org.opendaylight.protocol.bgp.openconfig.impl.util.OpenConfigUtil.APPLICATION_PEER_GROUP_NAME;
+
+import com.google.common.annotations.VisibleForTesting;
+import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
+import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import java.util.HashMap;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import javax.annotation.concurrent.GuardedBy;
+import javax.annotation.concurrent.ThreadSafe;
+import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService;
+import org.opendaylight.protocol.bgp.rib.impl.config.AppPeer;
+import org.opendaylight.protocol.bgp.rib.impl.config.BgpPeer;
+import org.opendaylight.protocol.bgp.rib.impl.config.PeerBean;
+import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry;
+import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighborPeerGroupConfig;
+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.NeighborKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Config2;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Writer responsible for management of BGP Neighbors. Partially based on BgpDeployerImpl from ODL's BGP (was hard to
+ * use directly due to OSGI dependencies).
+ */
+@ThreadSafe
+final class NeighborCustomizer implements ListWriterCustomizer<Neighbor, NeighborKey> {
+ private static final Logger LOG = LoggerFactory.getLogger(NeighborCustomizer.class);
+ private final RIB globalRib;
+ private final BGPPeerRegistry peerRegistry;
+ private final BGPOpenConfigMappingService mappingService;
+
+ @GuardedBy("this")
+ private final Map<InstanceIdentifier<Neighbor>, PeerBean> peers = new HashMap<>();
+
+ public NeighborCustomizer(@Nonnull final RIB globalRib, @Nonnull final BGPPeerRegistry peerRegistry,
+ @Nonnull final BGPOpenConfigMappingService mappingService) {
+ this.globalRib = checkNotNull(globalRib, "globalRib should not be null");
+ this.peerRegistry = checkNotNull(peerRegistry, "globalRib should not be null");
+ this.mappingService = checkNotNull(mappingService, "globalRib should not be null");
+ }
+
+ @VisibleForTesting
+ synchronized void addPeer(@Nonnull final InstanceIdentifier<Neighbor> id,
+ @Nonnull final PeerBean peer) {
+ peers.put(id, peer);
+ }
+
+ @VisibleForTesting
+ synchronized boolean isPeerConfigured(@Nonnull final InstanceIdentifier<Neighbor> id) {
+ return peers.containsKey(id);
+ }
+
+ @Override
+ public synchronized void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Neighbor> id,
+ @Nonnull final Neighbor neighbor,
+ @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ final PeerBean peer;
+ if (isApplicationPeer(neighbor)) {
+ LOG.debug("Creating AppPeer bean for {}: {}", id, neighbor);
+ peer = new AppPeer();
+ } else {
+ LOG.debug("Starting BgpPeer bean for {}: {}", id, neighbor);
+ peer = new BgpPeer(null, peerRegistry);
+ }
+ LOG.debug("Starting bgp peer for {}", id);
+ peer.start(globalRib, neighbor, mappingService, null);
+ addPeer(id, peer);
+ }
+
+ @Override
+ public synchronized void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Neighbor> id,
+ @Nonnull final Neighbor dataBefore,
+ @Nonnull final Neighbor dataAfter,
+ @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ LOG.debug("Updating Peer instance {} with configuration: {}", id, dataAfter);
+ final PeerBean peer = peers.get(id);
+ checkState(peer != null, "Could not find peer bean while updating neighbor {}", id);
+ closePeerBean(peer);
+ peer.start(globalRib, dataAfter, mappingService, null);
+ LOG.debug("Peer instance updated {}", peer);
+ }
+
+ @Override
+ public synchronized void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Neighbor> id,
+ @Nonnull final Neighbor dataBefore,
+ @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ LOG.debug("Removing Peer instance: {}", id);
+ final PeerBean peer = peers.remove(id);
+ if (peer != null) {
+ closePeerBean(peer);
+ LOG.debug("Peer instance removed {}", peer);
+ }
+ }
+
+ private static boolean isApplicationPeer(@Nonnull final Neighbor neighbor) {
+ return java.util.Optional.of(neighbor.getConfig())
+ .map(config -> config.getAugmentation(Config2.class))
+ .map(BgpNeighborPeerGroupConfig::getPeerGroup)
+ .map(APPLICATION_PEER_GROUP_NAME::equals)
+ .orElse(false);
+ }
+
+ private static void closePeerBean(final PeerBean peer) {
+ try {
+ peer.closeServiceInstance().get();
+ } catch (final Exception e) {
+ LOG.error("Peer instance failed to close service instance", e);
+ }
+ peer.close();
+ }
+}
diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors/NetworkInstanceCustomizer.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors/NetworkInstanceCustomizer.java
new file mode 100644
index 000000000..1505537ab
--- /dev/null
+++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors/NetworkInstanceCustomizer.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.bgp.neighbors;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
+import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstance;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstanceKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Dummy customizer for handling network-instance node required by BGP peer configuration (HC implements the same model
+ * as ODL BGP).
+ *
+ * Ensures that at most one network instance is created.
+ *
+ * Update and delete is not supported, because HC does not support runtime BGP server reconfiguration.
+ */
+final class NetworkInstanceCustomizer implements ListWriterCustomizer<NetworkInstance, NetworkInstanceKey> {
+ private final String networkInstanceName;
+
+ NetworkInstanceCustomizer(@Nonnull final String networkInstanceName) {
+ this.networkInstanceName = checkNotNull(networkInstanceName, "network instance name should not be null");
+ }
+
+ @Override
+ public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<NetworkInstance> id,
+ @Nonnull final NetworkInstance dataAfter,
+ @Nonnull final WriteContext writeContext) throws WriteFailedException {
+ final String instanceName = dataAfter.getName();
+ checkArgument(networkInstanceName.equals(instanceName),
+ "Only single network instance named %s is supported, but %s was given", networkInstanceName, instanceName);
+ }
+
+ @Override
+ public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<NetworkInstance> id,
+ @Nonnull final NetworkInstance dataBefore,
+ @Nonnull final NetworkInstance dataAfter,
+ @Nonnull final WriteContext writeContext) throws WriteFailedException {
+ throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter,
+ new UnsupportedOperationException("Network instance update is not supported"));
+ }
+
+ @Override
+ public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<NetworkInstance> id,
+ @Nonnull final NetworkInstance dataBefore,
+ @Nonnull final WriteContext writeContext) throws WriteFailedException {
+ throw new WriteFailedException.DeleteFailedException(id,
+ new UnsupportedOperationException("Network instance delete is not supported"));
+ }
+}
diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors/ProtocolCustomizer.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors/ProtocolCustomizer.java
new file mode 100644
index 000000000..7e0dd8f45
--- /dev/null
+++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/neighbors/ProtocolCustomizer.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.bgp.neighbors;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
+import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.ProtocolKey;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.policy.types.rev151009.BGP;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.policy.types.rev151009.InstallProtocolType;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Dummy customizer for handling network-instance's protocol node required by BGP peer configuration (HC implements the
+ * same model as ODL BGP).
+ *
+ * Ensures that at most one protocol is created.
+ *
+ * Update and delete is not supported, because HC does not support runtime BGP server reconfiguration.
+ */
+final class ProtocolCustomizer implements ListWriterCustomizer<Protocol, ProtocolKey> {
+ private final String protocolInstanceName;
+
+ ProtocolCustomizer(@Nonnull final String protocolInstanceName) {
+ this.protocolInstanceName = checkNotNull(protocolInstanceName, "protocol instance name should not be null");
+ }
+
+ @Override
+ public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Protocol> id,
+ @Nonnull final Protocol dataAfter, @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ final String protocolName = dataAfter.getName();
+ checkArgument(protocolInstanceName.equals(protocolName),
+ "Only single protocol named %s is supported, but %s was given", protocolInstanceName, protocolName);
+
+ final Class<? extends InstallProtocolType> identifier = dataAfter.getIdentifier();
+ checkArgument(BGP.class.equals(identifier),
+ "Only BGP protocol type is supported, but %s was given", identifier);
+ }
+
+ @Override
+ public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Protocol> id,
+ @Nonnull final Protocol dataBefore, @Nonnull final Protocol dataAfter,
+ @Nonnull final WriteContext writeContext) throws WriteFailedException {
+ throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter,
+ new UnsupportedOperationException("Network instance protocol update is not supported"));
+ }
+
+ @Override
+ public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Protocol> id,
+ @Nonnull final Protocol dataBefore, @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ throw new WriteFailedException.DeleteFailedException(id,
+ new UnsupportedOperationException("Network instance protocol delete is not supported"));
+ }
+}