2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.protocol.bgp.parser.spi;
10 import com.google.common.base.Preconditions;
11 import com.google.common.primitives.UnsignedBytes;
13 import io.netty.buffer.ByteBuf;
15 import java.util.Arrays;
17 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
18 import org.opendaylight.protocol.bgp.parser.BGPError;
19 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
20 import org.opendaylight.protocol.util.ByteArray;
21 import org.opendaylight.yangtools.yang.binding.Notification;
23 public abstract class AbstractMessageRegistry implements MessageRegistry {
25 private static final byte[] MARKER;
27 protected abstract Notification parseBody(final int type, final ByteBuf body, final int messageLength) throws BGPDocumentedException;
29 protected abstract byte[] serializeMessageImpl(final Notification message);
32 MARKER = new byte[MessageUtil.MARKER_LENGTH];
33 Arrays.fill(MARKER, UnsignedBytes.MAX_VALUE);
37 public final Notification parseMessage(final ByteBuf buffer) throws BGPDocumentedException, BGPParsingException {
38 Preconditions.checkArgument(buffer != null && buffer.isReadable(), "Array of bytes cannot be null or empty.");
39 Preconditions.checkArgument(buffer.readableBytes() >= MessageUtil.COMMON_HEADER_LENGTH,
40 "Too few bytes in passed array. Passed: %s. Expected: >= %s.", buffer.readableBytes(), MessageUtil.COMMON_HEADER_LENGTH);
41 final byte[] marker = ByteArray.readBytes(buffer, MessageUtil.MARKER_LENGTH);
43 if (!Arrays.equals(marker, MARKER)) {
44 throw new BGPDocumentedException("Marker not set to ones.", BGPError.CONNECTION_NOT_SYNC);
46 final int messageLength = buffer.readUnsignedShort();
47 // to be sent with Error message
48 final byte typeBytes = buffer.readByte();
49 final int messageType = UnsignedBytes.toInt(typeBytes);
51 final ByteBuf msgBody = buffer.slice(buffer.readerIndex(), messageLength - MessageUtil.COMMON_HEADER_LENGTH);
53 if (messageLength < MessageUtil.COMMON_HEADER_LENGTH) {
54 throw BGPDocumentedException.badMessageLength("Message length field not within valid range.", messageLength);
56 if (msgBody.readableBytes() != messageLength - MessageUtil.COMMON_HEADER_LENGTH) {
57 throw new BGPParsingException("Size doesn't match size specified in header. Passed: " + msgBody.readableBytes()
58 + "; Expected: " + (messageLength - MessageUtil.COMMON_HEADER_LENGTH) + ". ");
60 final Notification msg = parseBody(messageType, msgBody, messageLength);
62 throw new BGPDocumentedException("Unhandled message type " + messageType, BGPError.BAD_MSG_TYPE, new byte[] { typeBytes });
64 buffer.skipBytes(messageLength - MessageUtil.COMMON_HEADER_LENGTH);
69 public final byte[] serializeMessage(final Notification message) {
70 Preconditions.checkNotNull(message, "BGPMessage is mandatory.");
71 final byte[] ret = serializeMessageImpl(message);
72 Preconditions.checkNotNull(ret, "Unknown instance of BGPMessage. Passed ", message.getClass());