Add SPI registry implementations
[bgpcep.git] / bgp / parser-impl / src / main / java / org / opendaylight / protocol / bgp / parser / impl / message / BGPNotificationMessageParser.java
1 /*
2  * Copyright (c) 2013 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 package org.opendaylight.protocol.bgp.parser.impl.message;
9
10 import java.util.Arrays;
11
12 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
13 import org.opendaylight.protocol.bgp.parser.BGPError;
14 import org.opendaylight.protocol.bgp.parser.spi.MessageParser;
15 import org.opendaylight.protocol.bgp.parser.spi.MessageSerializer;
16 import org.opendaylight.protocol.util.ByteArray;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.Notify;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.NotifyBuilder;
19 import org.opendaylight.yangtools.yang.binding.Notification;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 import com.google.common.primitives.UnsignedBytes;
24
25 /**
26  * Parser for BGPNotification message.
27  */
28 public final class BGPNotificationMessageParser implements MessageParser, MessageSerializer {
29         public static final MessageParser PARSER;
30         public static final MessageSerializer SERIALIZER;
31
32         static {
33                 final BGPNotificationMessageParser p = new BGPNotificationMessageParser();
34                 PARSER = p;
35                 SERIALIZER = p;
36         }
37
38         private static final Logger logger = LoggerFactory.getLogger(BGPNotificationMessageParser.class);
39
40         private static final int ERROR_SIZE = 2; // bytes
41
42         private BGPNotificationMessageParser() {
43
44         }
45
46         /**
47          * Serializes BGP Notification message.
48          * 
49          * @param msg to be serialized
50          * @return BGP Notification message converted to byte array
51          */
52         @Override
53         public byte[] serializeMessage(final Notification msg) {
54                 if (msg == null) {
55                         throw new IllegalArgumentException("BGP Notification message cannot be null");
56                 }
57
58                 final Notify ntf = (Notify)msg;
59                 logger.trace("Started serializing Notification message: {}", ntf);
60
61                 final byte[] msgBody = (ntf.getData() == null) ? new byte[ERROR_SIZE] : new byte[ERROR_SIZE + ntf.getData().length];
62
63                 msgBody[0] = ByteArray.intToBytes(ntf.getErrorCode())[Integer.SIZE / Byte.SIZE - 1];
64
65                 msgBody[1] = ByteArray.intToBytes(ntf.getErrorSubcode())[Integer.SIZE / Byte.SIZE - 1];
66
67                 if (ntf.getData() != null) {
68                         System.arraycopy(ntf.getData(), 0, msgBody, ERROR_SIZE, ntf.getData().length);
69                 }
70                 logger.trace("Notification message serialized to: {}", Arrays.toString(msgBody));
71                 return msgBody;
72         }
73
74         /**
75          * Parses BGP Notification message to bytes.
76          * 
77          * @param bytes byte array to be parsed
78          * @return BGPNotification message
79          * @throws BGPDocumentedException
80          */
81         @Override
82         public Notify parseMessage(final byte[] bytes, final int messageLength) throws BGPDocumentedException {
83                 if (bytes == null || bytes.length == 0) {
84                         throw new IllegalArgumentException("Byte array cannot be null or empty.");
85                 }
86                 logger.trace("Started parsing of notification message: {}", Arrays.toString(bytes));
87
88                 if (bytes.length < ERROR_SIZE) {
89                         throw new BGPDocumentedException("Notification message too small.", BGPError.BAD_MSG_LENGTH, ByteArray.intToBytes(bytes.length));
90                 }
91                 final int errorCode = UnsignedBytes.toInt(bytes[0]);
92                 final int errorSubcode = UnsignedBytes.toInt(bytes[1]);
93
94                 byte[] data = null;
95                 if (bytes.length > ERROR_SIZE) {
96                         data = ByteArray.subByte(bytes, ERROR_SIZE, bytes.length - ERROR_SIZE);
97                 }
98                 logger.trace("Notification message was parsed: err = {}, data = {}.", BGPError.forValue(errorCode, errorSubcode),
99                                 Arrays.toString(data));
100                 final NotifyBuilder builder = new NotifyBuilder().setErrorCode((short) errorCode).setErrorSubcode((short) errorSubcode);
101                 if (data != null) {
102                         builder.setData(data);
103                 }
104                 return builder.build();
105         }
106
107         @Override
108         public int messageType() {
109                 return 3;
110         }
111 }