a3949d4d872d64a824f4c534b23ea4f352b6bd86
[bgpcep.git] / bgp / rib-impl / src / main / java / org / opendaylight / protocol / bgp / rib / impl / BGPPeer.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.protocol.bgp.rib.impl;
10
11 import com.google.common.base.Objects;
12 import com.google.common.base.Objects.ToStringHelper;
13 import com.google.common.base.Preconditions;
14 import com.google.common.net.InetAddresses;
15
16 import java.util.HashSet;
17 import java.util.Set;
18
19 import javax.annotation.concurrent.GuardedBy;
20
21 import org.opendaylight.protocol.bgp.rib.impl.spi.AdjRIBsOutRegistration;
22 import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
23 import org.opendaylight.protocol.bgp.rib.impl.spi.ReusableBGPPeer;
24 import org.opendaylight.protocol.bgp.rib.spi.BGPSession;
25 import org.opendaylight.protocol.bgp.rib.spi.BGPTerminationReason;
26 import org.opendaylight.protocol.bgp.rib.spi.Peer;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Update;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
30 import org.opendaylight.yangtools.yang.binding.Notification;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34
35 /**
36  * Class representing a peer. We have a single instance for each peer, which provides translation from BGP events into
37  * RIB actions.
38  */
39 public class BGPPeer implements ReusableBGPPeer, Peer, AutoCloseable {
40     private static final Logger LOG = LoggerFactory.getLogger(BGPPeer.class);
41
42     @GuardedBy("this")
43     private final Set<TablesKey> tables = new HashSet<>();
44     private final RIB rib;
45     private final String name;
46
47     @GuardedBy("this")
48     private BGPSession session;
49     @GuardedBy("this")
50     private byte[] rawIdentifier;
51     @GuardedBy("this")
52     private AdjRIBsOutRegistration reg;
53
54     public BGPPeer(final String name, final RIB rib) {
55         this.rib = Preconditions.checkNotNull(rib);
56         this.name = name;
57     }
58
59     @Override
60     public synchronized void close() {
61         dropConnection();
62         // TODO should this perform cleanup ?
63     }
64
65     @Override
66     public void onMessage(final BGPSession session, final Notification message) {
67         if (message instanceof Update) {
68             this.rib.updateTables(this, (Update) message);
69         } else {
70             LOG.info("Ignoring unhandled message class {}", message.getClass());
71         }
72     }
73
74     @Override
75     public synchronized void onSessionUp(final BGPSession session) {
76         LOG.info("Session with peer {} went up with tables: {}", this.name, session.getAdvertisedTableTypes());
77
78         this.session = session;
79         this.rawIdentifier = InetAddresses.forString(session.getBgpId().getValue()).getAddress();
80
81         for (final BgpTableType t : session.getAdvertisedTableTypes()) {
82             final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
83
84             this.tables.add(key);
85             this.rib.initTable(this, key);
86         }
87
88         // Not particularly nice, but what can
89         if (session instanceof BGPSessionImpl) {
90             reg = rib.registerRIBsOut(this, new SessionRIBsOut((BGPSessionImpl) session));
91         }
92     }
93
94     private synchronized void cleanup() {
95         // FIXME: BUG-196: support graceful restart
96         for (final TablesKey key : this.tables) {
97             this.rib.clearTable(this, key);
98         }
99
100         if (reg != null) {
101             reg.close();
102             reg = null;
103         }
104
105         this.tables.clear();
106         this.session = null;
107     }
108
109     @Override
110     public void onSessionDown(final BGPSession session, final Exception e) {
111         LOG.info("Session with peer {} went down", this.name, e);
112         cleanup();
113     }
114
115     @Override
116     public void onSessionTerminated(final BGPSession session, final BGPTerminationReason cause) {
117         LOG.info("Session with peer {} terminated: {}", this.name, cause);
118         cleanup();
119     }
120
121     @Override
122     public String toString() {
123         return addToStringAttributes(Objects.toStringHelper(this)).toString();
124     }
125
126     protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
127         toStringHelper.add("name", this.name);
128         toStringHelper.add("tables", this.tables);
129         return toStringHelper;
130     }
131
132     @Override
133     public String getName() {
134         return this.name;
135     }
136
137     protected RIB getRib() {
138         return this.rib;
139     }
140
141     @Override
142     public void releaseConnection() {
143         dropConnection();
144         cleanup();
145     }
146
147     @GuardedBy("this")
148     private void dropConnection() {
149         if (this.session != null) {
150             this.session.close();
151             this.session = null;
152         }
153     }
154
155     @Override
156     public synchronized byte[] getRawIdentifier() {
157         return rawIdentifier;
158     }
159 }