MVPN RFC6514 Extendend communities
[bgpcep.git] / bmp / bmp-parser-impl / src / main / java / org / opendaylight / protocol / bmp / parser / message / PeerDownHandler.java
1 /*
2  * Copyright (c) 2015 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.bmp.parser.message;
10
11 import static java.util.Objects.requireNonNull;
12 import static org.opendaylight.protocol.bmp.parser.message.PeerDownHandler.Reason.REASON_FOUR;
13 import static org.opendaylight.protocol.bmp.parser.message.PeerDownHandler.Reason.REASON_ONE;
14 import static org.opendaylight.protocol.bmp.parser.message.PeerDownHandler.Reason.REASON_THREE;
15 import static org.opendaylight.protocol.bmp.parser.message.PeerDownHandler.Reason.REASON_TWO;
16
17 import com.google.common.base.Preconditions;
18 import com.google.common.collect.ImmutableMap;
19 import io.netty.buffer.ByteBuf;
20 import java.util.Map;
21 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
22 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
23 import org.opendaylight.protocol.bgp.parser.spi.MessageRegistry;
24 import org.opendaylight.protocol.bmp.spi.parser.AbstractBmpPerPeerMessageParser;
25 import org.opendaylight.protocol.bmp.spi.parser.BmpDeserializationException;
26 import org.opendaylight.protocol.util.ByteBufWriteUtil;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.NotifyBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.NotifyMessage;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329.PeerDownNotification;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329.PeerDownNotificationBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329.peer.down.Data;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329.peer.down.data.FsmEventCode;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329.peer.down.data.FsmEventCodeBuilder;
34 import org.opendaylight.yangtools.yang.binding.Notification;
35
36 public class PeerDownHandler extends AbstractBmpPerPeerMessageParser<PeerDownNotificationBuilder> {
37
38     private static final int MESSAGE_TYPE = 2;
39     private final MessageRegistry msgRegistry;
40
41     public PeerDownHandler(final MessageRegistry bgpMssageRegistry) {
42         super(bgpMssageRegistry);
43         this.msgRegistry = getBgpMessageRegistry();
44     }
45
46     @Override
47     public void serializeMessageBody(final Notification message, final ByteBuf buffer) {
48         super.serializeMessageBody(message, buffer);
49         Preconditions.checkArgument(message instanceof PeerDownNotification,
50                 "An instance of PeerDownNotification is required");
51         final PeerDownNotification peerDown = (PeerDownNotification) message;
52         if (peerDown.isLocalSystemClosed()) {
53             if (peerDown.getData() instanceof FsmEventCode) {
54                 ByteBufWriteUtil.writeUnsignedByte(REASON_TWO.getValue(), buffer);
55                 ByteBufWriteUtil.writeUnsignedShort(((FsmEventCode) peerDown.getData()).getFsmEventCode(), buffer);
56             } else if (peerDown.getData()
57                     instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329
58                     .peer.down.data.Notification) {
59                 ByteBufWriteUtil.writeUnsignedByte(REASON_ONE.getValue(), buffer);
60                 serializePDU(peerDown.getData(), buffer);
61             }
62         } else {
63             if (peerDown.getData()
64                     instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329
65                     .peer.down.data.Notification) {
66                 ByteBufWriteUtil.writeUnsignedByte(REASON_THREE.getValue(), buffer);
67                 serializePDU(peerDown.getData(), buffer);
68             } else {
69                 ByteBufWriteUtil.writeUnsignedByte(REASON_FOUR.getValue(), buffer);
70             }
71         }
72     }
73
74     private void serializePDU(final Data data, final ByteBuf buffer) {
75         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329.peer.down.data
76                 .Notification notification = (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp
77                 .message.rev180329.peer.down.data.Notification) data;
78         this.msgRegistry.serializeMessage(new NotifyBuilder(notification.getNotification()).build(), buffer);
79     }
80
81     @Override
82     public Notification parseMessageBody(final ByteBuf bytes) throws BmpDeserializationException {
83         final PeerDownNotificationBuilder peerDown = new PeerDownNotificationBuilder()
84                 .setPeerHeader(parsePerPeerHeader(bytes));
85         final Reason reason = Reason.forValue(bytes.readUnsignedByte());
86         if (reason != null) {
87             switch (reason) {
88                 case REASON_ONE:
89                     peerDown.setLocalSystemClosed(true);
90                     peerDown.setData(parseBgpNotificationMessage(bytes));
91                     break;
92                 case REASON_TWO:
93                     peerDown.setLocalSystemClosed(true);
94                     peerDown.setData(new FsmEventCodeBuilder().setFsmEventCode(bytes.readUnsignedShort()).build());
95                     break;
96                 case REASON_THREE:
97                 case REASON_FOUR:
98                     peerDown.setLocalSystemClosed(false);
99                     peerDown.setData(parseBgpNotificationMessage(bytes));
100                     break;
101                 case REASON_FIVE:
102                     peerDown.setLocalSystemClosed(false);
103                     break;
104                 default:
105                     break;
106             }
107         }
108
109         return peerDown.build();
110     }
111
112     private org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329.peer.down.data
113             .Notification parseBgpNotificationMessage(final ByteBuf bytes) throws BmpDeserializationException {
114         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329.peer.down.data
115                 .NotificationBuilder notificationCBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.params
116                 .xml.ns.yang.bmp.message.rev180329.peer.down.data.NotificationBuilder();
117
118         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329.peer.down.data
119                 .notification.NotificationBuilder notificationBuilder = new org.opendaylight.yang.gen.v1.urn
120                 .opendaylight.params.xml.ns.yang.bmp.message.rev180329.peer.down.data.notification
121                 .NotificationBuilder();
122         try {
123             final Notification not = this.msgRegistry.parseMessage(bytes, null);
124             requireNonNull(not, "Notify message may not be null.");
125             Preconditions.checkArgument(not instanceof NotifyMessage,
126                     "An instance of NotifyMessage is required");
127             notificationBuilder.fieldsFrom((NotifyMessage) not);
128             notificationCBuilder.setNotification(notificationBuilder.build());
129         } catch (final BGPDocumentedException | BGPParsingException e) {
130             throw new BmpDeserializationException("Error while parsing BGP Notification message.", e);
131         }
132
133         return notificationCBuilder.build();
134     }
135
136     @Override
137     public int getBmpMessageType() {
138         return MESSAGE_TYPE;
139     }
140
141     public enum Reason {
142         REASON_ONE((short) 1),
143         REASON_TWO((short) 2),
144         REASON_THREE((short) 3),
145         REASON_FOUR((short) 4),
146         REASON_FIVE((short) 5);
147
148         private static final Map<Short, Reason> VALUE_MAP;
149
150         static {
151             final ImmutableMap.Builder<Short, Reason> b = ImmutableMap.builder();
152             for (final Reason enumItem : Reason.values()) {
153                 b.put(enumItem.getValue(), enumItem);
154             }
155             VALUE_MAP = b.build();
156         }
157
158         private final short value;
159
160         Reason(final short value) {
161             this.value = value;
162         }
163
164         public static Reason forValue(final short value) {
165             return VALUE_MAP.get(value);
166         }
167
168         public short getValue() {
169             return this.value;
170         }
171     }
172 }