org.opendaylight.protocol.bgp.parser.spi.AbstractMessageRegistry.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.protocol.bgp.parser.spi.AbstractMessageRegistry.java

Source

/*
 * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.protocol.bgp.parser.spi;

import com.google.common.base.Preconditions;
import com.google.common.primitives.UnsignedBytes;
import io.netty.buffer.ByteBuf;
import java.util.Arrays;
import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
import org.opendaylight.protocol.bgp.parser.BGPError;
import org.opendaylight.protocol.bgp.parser.BGPParsingException;
import org.opendaylight.protocol.util.ByteArray;
import org.opendaylight.yangtools.yang.binding.Notification;

public abstract class AbstractMessageRegistry implements MessageRegistry {

    private static final byte[] MARKER;

    protected abstract Notification parseBody(int type, ByteBuf body, int messageLength,
            PeerSpecificParserConstraint constraint) throws BGPDocumentedException;

    protected abstract void serializeMessageImpl(final Notification message, final ByteBuf buffer);

    static {
        MARKER = new byte[MessageUtil.MARKER_LENGTH];
        Arrays.fill(MARKER, UnsignedBytes.MAX_VALUE);
    }

    @Override
    public final Notification parseMessage(final ByteBuf buffer)
            throws BGPDocumentedException, BGPParsingException {
        return parseMessage(buffer, null);
    }

    @Override
    public Notification parseMessage(final ByteBuf buffer, final PeerSpecificParserConstraint constraint)
            throws BGPDocumentedException, BGPParsingException {
        Preconditions.checkArgument(buffer != null && buffer.isReadable(),
                "Array of bytes cannot be null or empty.");
        Preconditions.checkArgument(buffer.readableBytes() >= MessageUtil.COMMON_HEADER_LENGTH,
                "Too few bytes in passed array. Passed: %s. Expected: >= %s.", buffer.readableBytes(),
                MessageUtil.COMMON_HEADER_LENGTH);
        final byte[] marker = ByteArray.readBytes(buffer, MessageUtil.MARKER_LENGTH);

        if (!Arrays.equals(marker, MARKER)) {
            throw new BGPDocumentedException("Marker not set to ones.", BGPError.CONNECTION_NOT_SYNC);
        }
        final int messageLength = buffer.readUnsignedShort();
        // to be sent with Error message
        final byte typeBytes = buffer.readByte();
        final int messageType = UnsignedBytes.toInt(typeBytes);

        if (messageLength < MessageUtil.COMMON_HEADER_LENGTH) {
            throw BGPDocumentedException.badMessageLength("Message length field not within valid range.",
                    messageLength);
        }

        if (messageLength - MessageUtil.COMMON_HEADER_LENGTH != buffer.readableBytes()) {
            throw new BGPParsingException(
                    "Size doesn't match size specified in header. Passed: " + buffer.readableBytes()
                            + "; Expected: " + (messageLength - MessageUtil.COMMON_HEADER_LENGTH) + ". ");
        }

        final ByteBuf msgBody = buffer.readSlice(messageLength - MessageUtil.COMMON_HEADER_LENGTH);

        final Notification msg = parseBody(messageType, msgBody, messageLength, constraint);
        if (msg == null) {
            throw new BGPDocumentedException("Unhandled message type " + messageType, BGPError.BAD_MSG_TYPE,
                    new byte[] { typeBytes });
        }
        return msg;
    }

    @Override
    public final void serializeMessage(final Notification message, final ByteBuf buffer) {
        Preconditions.checkNotNull(message, "BGPMessage is mandatory.");
        serializeMessageImpl(message, buffer);
    }
}