2 * Copyright (c) 2017 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package io.fd.honeycomb.infra.bgp.neighbors;
19 import static com.google.common.base.Preconditions.checkNotNull;
20 import static com.google.common.base.Preconditions.checkState;
22 import com.google.common.annotations.VisibleForTesting;
23 import io.fd.honeycomb.infra.bgp.BgpConfiguration;
24 import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
25 import io.fd.honeycomb.translate.write.WriteContext;
26 import io.fd.honeycomb.translate.write.WriteFailedException;
27 import java.util.HashMap;
29 import javax.annotation.Nonnull;
30 import javax.annotation.concurrent.GuardedBy;
31 import javax.annotation.concurrent.ThreadSafe;
32 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
33 import org.opendaylight.protocol.bgp.rib.impl.config.AppPeer;
34 import org.opendaylight.protocol.bgp.rib.impl.config.BgpPeer;
35 import org.opendaylight.protocol.bgp.rib.impl.config.PeerBean;
36 import org.opendaylight.protocol.bgp.rib.impl.config.PeerGroupConfigLoader;
37 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry;
38 import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
39 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Config;
40 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
41 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.NeighborKey;
42 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp;
43 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.NetworkInstances;
44 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstance;
45 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.Protocols;
46 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborPeerGroupConfig;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NetworkInstanceProtocol;
49 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
54 * Writer responsible for management of BGP Neighbors. Partially based on BgpDeployerImpl from ODL's BGP (was hard to
55 * use directly due to OSGI dependencies).
58 final class NeighborCustomizer implements ListWriterCustomizer<Neighbor, NeighborKey> {
59 private static final Logger LOG = LoggerFactory.getLogger(NeighborCustomizer.class);
60 private final RIB globalRib;
61 private final BGPPeerRegistry peerRegistry;
62 private final PeerGroupConfigLoader peerGroupLoader;
63 private BGPTableTypeRegistryConsumer tableTypeRegistry;
65 static final InstanceIdentifier<Bgp> bgpIid = InstanceIdentifier.create(NetworkInstances.class)
66 .child(NetworkInstance.class).child(Protocols.class).child(Protocol.class).augmentation(
67 NetworkInstanceProtocol.class).child(Bgp.class);
71 private final Map<InstanceIdentifier<Neighbor>, PeerBean> peers = new HashMap<>();
73 public NeighborCustomizer(@Nonnull final RIB globalRib, @Nonnull final BGPPeerRegistry peerRegistry,
74 @Nonnull final BGPTableTypeRegistryConsumer tableTypeRegistry,
75 final BgpConfiguration configuration) {
76 this.globalRib = checkNotNull(globalRib, "globalRib should not be null");
77 this.peerRegistry = checkNotNull(peerRegistry, "peerRegistry should not be null");
78 this.tableTypeRegistry = checkNotNull(tableTypeRegistry, "tableTypeRegistry should not be null");
79 this.peerGroupLoader = checkNotNull(configuration, "configuration should not be null");
83 synchronized void addPeer(@Nonnull final InstanceIdentifier<Neighbor> id,
84 @Nonnull final PeerBean peer) {
89 synchronized boolean isPeerConfigured(@Nonnull final InstanceIdentifier<Neighbor> id) {
90 return peers.containsKey(id);
94 public synchronized void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Neighbor> id,
95 @Nonnull final Neighbor neighbor,
96 @Nonnull final WriteContext writeContext)
97 throws WriteFailedException {
99 if (isAppPeer(neighbor)) {
100 LOG.debug("Creating AppPeer bean for {}: {}", id, neighbor);
101 peer = new AppPeer();
103 LOG.debug("Starting BgpPeer bean for {}: {}", id, neighbor);
104 peer = new BgpPeer(null);
106 LOG.debug("Starting bgp peer for {}", id);
107 peer.start(globalRib, neighbor, bgpIid, peerGroupLoader, tableTypeRegistry);
108 peer.instantiateServiceInstance();
112 static boolean isAppPeer(final Neighbor neighbor) {
113 Config config = neighbor.getConfig();
114 if (config != null) {
115 NeighborPeerGroupConfig config1 = config.augmentation(NeighborPeerGroupConfig.class);
116 if (config1 != null) {
117 String peerGroup = config1.getPeerGroup();
118 return peerGroup != null && peerGroup.equals("application-peers");
125 public synchronized void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Neighbor> id,
126 @Nonnull final Neighbor dataBefore,
127 @Nonnull final Neighbor dataAfter,
128 @Nonnull final WriteContext writeContext)
129 throws WriteFailedException {
130 LOG.debug("Updating Peer instance {} with configuration: {}", id, dataAfter);
131 final PeerBean peer = peers.get(id);
132 checkState(peer != null, "Could not find peer bean while updating neighbor {}", id);
134 peer.start(globalRib, dataAfter, bgpIid, peerGroupLoader, tableTypeRegistry);
135 peer.instantiateServiceInstance();
136 LOG.debug("Peer instance updated {}", peer);
140 public synchronized void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Neighbor> id,
141 @Nonnull final Neighbor dataBefore,
142 @Nonnull final WriteContext writeContext)
143 throws WriteFailedException {
144 LOG.debug("Removing Peer instance: {}", id);
145 final PeerBean peer = peers.remove(id);
148 LOG.debug("Peer instance removed {}", peer);
152 private static void closePeerBean(final PeerBean peer) {
154 peer.closeServiceInstance().get();
155 } catch (final Exception e) {
156 LOG.error("Peer instance failed to close service instance", e);