Bug-2064: Implementation of RFC5492 Error handling.
[bgpcep.git] / bgp / rib-impl / src / main / java / org / opendaylight / protocol / bgp / rib / impl / BGPSessionStats.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.Optional;
12 import com.google.common.base.Preconditions;
13 import com.google.common.base.Stopwatch;
14 import com.google.common.collect.Lists;
15 import io.netty.channel.Channel;
16 import java.net.InetSocketAddress;
17 import java.util.Collection;
18 import java.util.List;
19 import java.util.concurrent.TimeUnit;
20 import org.opendaylight.controller.config.yang.bgp.rib.impl.AdvertizedTableTypes;
21 import org.opendaylight.controller.config.yang.bgp.rib.impl.BgpSessionState;
22 import org.opendaylight.controller.config.yang.bgp.rib.impl.ErrorMsgs;
23 import org.opendaylight.controller.config.yang.bgp.rib.impl.ErrorReceived;
24 import org.opendaylight.controller.config.yang.bgp.rib.impl.ErrorSent;
25 import org.opendaylight.controller.config.yang.bgp.rib.impl.KeepAliveMsgs;
26 import org.opendaylight.controller.config.yang.bgp.rib.impl.MessagesStats;
27 import org.opendaylight.controller.config.yang.bgp.rib.impl.PeerPreferences;
28 import org.opendaylight.controller.config.yang.bgp.rib.impl.Received;
29 import org.opendaylight.controller.config.yang.bgp.rib.impl.Sent;
30 import org.opendaylight.controller.config.yang.bgp.rib.impl.SpeakerPreferences;
31 import org.opendaylight.controller.config.yang.bgp.rib.impl.TotalMsgs;
32 import org.opendaylight.controller.config.yang.bgp.rib.impl.UpdateMsgs;
33 import org.opendaylight.protocol.bgp.rib.impl.BGPSessionImpl.State;
34 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionPreferences;
35 import org.opendaylight.protocol.util.StatisticsUtil;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Notify;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Open;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.BgpParameters;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.bgp.parameters.OptionalCapabilities;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.bgp.parameters.optional.capabilities.CParameters;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.As4BytesCase;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.MultiprotocolCase;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.multiprotocol._case.MultiprotocolCapability;
45
46 final class BGPSessionStats {
47     private final Stopwatch sessionStopwatch;
48     private final BgpSessionState stats;
49     private final TotalMsgs totalMsgs = new TotalMsgs();
50     private final KeepAliveMsgs kaMsgs = new KeepAliveMsgs();
51     private final UpdateMsgs updMsgs = new UpdateMsgs();
52     private final ErrorMsgs errMsgs = new ErrorMsgs();
53
54     public BGPSessionStats(final Open remoteOpen, final int holdTimerValue, final int keepAlive, final Channel channel,
55             final Optional<BGPSessionPreferences> localPreferences, final Collection<BgpTableType> tableTypes) {
56         this.sessionStopwatch = new Stopwatch();
57         this.stats = new BgpSessionState();
58         this.stats.setHoldtimeCurrent(holdTimerValue);
59         this.stats.setKeepaliveCurrent(keepAlive);
60         this.stats.setPeerPreferences(setPeerPref(remoteOpen, channel, tableTypes));
61         this.stats.setSpeakerPreferences(setSpeakerPref(channel, localPreferences));
62         initMsgs();
63     }
64
65     private void initMsgs() {
66         this.totalMsgs.setReceived(new Received());
67         this.totalMsgs.setSent(new Sent());
68         this.kaMsgs.setReceived(new Received());
69         this.kaMsgs.setSent(new Sent());
70         this.updMsgs.setReceived(new Received());
71         this.updMsgs.setSent(new Sent());
72         this.errMsgs.setErrorReceived(new ErrorReceived());
73         this.errMsgs.setErrorSent(new ErrorSent());
74     }
75
76     public void startSessionStopwatch() {
77         this.sessionStopwatch.start();
78     }
79
80     public void updateSentMsgTotal() {
81         updateSentMsg(this.totalMsgs.getSent());
82     }
83
84     public void updateReceivedMsgTotal() {
85         updateReceivedMsg(this.totalMsgs.getReceived());
86     }
87
88     public void updateReceivedMsgKA() {
89         updateReceivedMsg(this.kaMsgs.getReceived());
90     }
91
92     public void updateSentMsgKA() {
93         updateSentMsg(this.kaMsgs.getSent());
94     }
95
96     public void updateSentMsgUpd() {
97         updateSentMsg(this.updMsgs.getSent());
98     }
99
100     public void updateReceivedMsgUpd() {
101         updateReceivedMsg(this.updMsgs.getReceived());
102     }
103
104     public void updateReceivedMsgErr(final Notify error) {
105         Preconditions.checkNotNull(error);
106         final ErrorReceived received = this.errMsgs.getErrorReceived();
107         received.setCount(received.getCount() + 1);
108         received.setTimestamp(StatisticsUtil.getCurrentTimestampInSeconds());
109         received.setCode(error.getErrorCode());
110         received.setSubCode(error.getErrorSubcode());
111     }
112
113     public void updateSentMsgErr(final Notify error) {
114         Preconditions.checkNotNull(error);
115         final ErrorSent sent = this.errMsgs.getErrorSent();
116         sent.setCount(sent.getCount() + 1);
117         sent.setTimestamp(StatisticsUtil.getCurrentTimestampInSeconds());
118         sent.setCode(error.getErrorCode());
119         sent.setSubCode(error.getErrorSubcode());
120     }
121
122     public BgpSessionState getBgpSessionState(final State state) {
123         Preconditions.checkNotNull(state);
124         final MessagesStats msgs = new MessagesStats();
125         msgs.setTotalMsgs(this.totalMsgs);
126         msgs.setErrorMsgs(this.errMsgs);
127         msgs.setKeepAliveMsgs(this.kaMsgs);
128         msgs.setUpdateMsgs(this.updMsgs);
129         this.stats.setSessionDuration(StatisticsUtil.formatElapsedTime(this.sessionStopwatch.elapsed(TimeUnit.SECONDS)));
130         this.stats.setSessionState(state.toString());
131         this.stats.setMessagesStats(msgs);
132         return this.stats;
133     }
134
135     public void resetStats() {
136         initMsgs();
137     }
138
139     private static void updateReceivedMsg(final Received received) {
140         Preconditions.checkNotNull(received);
141         received.setCount(received.getCount() + 1);
142         received.setTimestamp(StatisticsUtil.getCurrentTimestampInSeconds());
143     }
144
145     private static boolean isAs4ByteCapable(final CParameters cp) {
146         if (cp instanceof As4BytesCase) {
147             return ((As4BytesCase) cp).getAs4BytesCapability() != null;
148         }
149         return false;
150     }
151
152     private static void updateSentMsg(final Sent sent) {
153         Preconditions.checkNotNull(sent);
154         sent.setCount(sent.getCount() + 1);
155         sent.setTimestamp(StatisticsUtil.getCurrentTimestampInSeconds());
156     }
157
158     private static AdvertizedTableTypes addTableType(final BgpTableType type) {
159         Preconditions.checkNotNull(type);
160         final AdvertizedTableTypes att = new AdvertizedTableTypes();
161         att.setAfi(type.getAfi().getSimpleName());
162         att.setSafi(type.getSafi().getSimpleName());
163         return att;
164     }
165
166     private static SpeakerPreferences setSpeakerPref(final Channel channel, final Optional<BGPSessionPreferences> localPreferences) {
167         Preconditions.checkNotNull(channel);
168         final SpeakerPreferences pref = new SpeakerPreferences();
169         final InetSocketAddress isa = (InetSocketAddress) channel.localAddress();
170         pref.setAddress(isa.getAddress().getHostAddress());
171         pref.setPort(isa.getPort());
172         final List<AdvertizedTableTypes> tt = Lists.newArrayList();
173         if (localPreferences.isPresent()) {
174             final BGPSessionPreferences localPref = localPreferences.get();
175             pref.setBgpId(localPref.getBgpId().getValue());
176             pref.setAs(localPref.getMyAs().getValue());
177             pref.setHoldtime(localPref.getHoldTime());
178             if (localPref.getParams() != null && !localPref.getParams().isEmpty()) {
179                 for (final BgpParameters param : localPref.getParams()) {
180                     for (final OptionalCapabilities capa : param.getOptionalCapabilities()) {
181                         final CParameters cp = capa.getCParameters();
182                         if (cp instanceof MultiprotocolCase) {
183                             final MultiprotocolCapability mc = ((MultiprotocolCase) cp).getMultiprotocolCapability();
184                             final AdvertizedTableTypes att = new AdvertizedTableTypes();
185                             att.setAfi(mc.getAfi().getSimpleName());
186                             att.setSafi(mc.getSafi().getSimpleName());
187                             tt.add(att);
188                         }
189                         pref.setFourOctetAsCapability(isAs4ByteCapable(cp));
190                     }
191                 }
192             }
193         }
194         pref.setAdvertizedTableTypes(tt);
195         return pref;
196     }
197
198     private static PeerPreferences setPeerPref(final Open remoteOpen, final Channel channel, final Collection<BgpTableType> tableTypes) {
199         Preconditions.checkNotNull(remoteOpen);
200         Preconditions.checkNotNull(channel);
201         final PeerPreferences pref = new PeerPreferences();
202         final InetSocketAddress isa = (InetSocketAddress) channel.remoteAddress();
203         pref.setAddress(isa.getAddress().getHostAddress());
204         pref.setPort(isa.getPort());
205         pref.setBgpId(remoteOpen.getBgpIdentifier().getValue());
206         pref.setAs(remoteOpen.getMyAsNumber().longValue());
207         pref.setHoldtime(remoteOpen.getHoldTimer());
208         final List<AdvertizedTableTypes> tt = Lists.newArrayList();
209         for (final BgpTableType t : tableTypes) {
210             tt.add(addTableType(t));
211         }
212         if (remoteOpen.getBgpParameters() != null && !remoteOpen.getBgpParameters().isEmpty()) {
213             for (final BgpParameters param : remoteOpen.getBgpParameters()) {
214                 for (final OptionalCapabilities capa : param.getOptionalCapabilities()) {
215                     pref.setFourOctetAsCapability(isAs4ByteCapable(capa.getCParameters()));
216                 }
217
218             }
219         }
220         pref.setAdvertizedTableTypes(tt);
221         return pref;
222     }
223 }