com.seagate.kinetic.common.protocol.codec.KineticEncoder.java Source code

Java tutorial

Introduction

Here is the source code for com.seagate.kinetic.common.protocol.codec.KineticEncoder.java

Source

/**
 * Copyright 2013-2015 Seagate Technology LLC.
 *
 * This Source Code Form is subject to the terms of the Mozilla
 * Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at
 * https://mozilla.org/MP:/2.0/.
 * 
 * This program is distributed in the hope that it will be useful,
 * but is provided AS-IS, WITHOUT ANY WARRANTY; including without 
 * the implied warranty of MERCHANTABILITY, NON-INFRINGEMENT or 
 * FITNESS FOR A PARTICULAR PURPOSE. See the Mozilla Public 
 * License for more details.
 *
 * See www.openkinetic.org for more project information
 */
package com.seagate.kinetic.common.protocol.codec;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

import java.util.logging.Level;
import java.util.logging.Logger;

import com.seagate.kinetic.common.lib.KineticMessage;
import com.seagate.kinetic.common.lib.ProtocolMessageUtil;

import com.seagate.kinetic.proto.Kinetic.Message;
import com.seagate.kinetic.proto.Kinetic.Message.Builder;

/**
 *
 * Kinetic protocol buffer message encoder (version2 protocol).
 * <p>
 * The client library, simulator, or a Kinetic drive uses the following protocol
 * to encode a message.
 * <p>
 * <ul>
 * <li>1. write magic byte 'F'
 * <li>2. write protocol buffer message length.
 * <li>3. write value length (0 if no value)
 * <li>4. write protobuf message byte[]
 * <li>5. write value byte[] if any
 * </ul>
 * <p>
 *
 * To log/print the encoded message, set the "kinetic.io.out" Java System
 * property to true.
 * <p>
 * For example, set the following Java VM argument when running a Kinetic
 * application or Simulator.
 * <p>
 * -D"kinetic.io.out"=true
 *
 * @author chiaming
 */
public class KineticEncoder extends MessageToByteEncoder<KineticMessage> {

    private final Logger logger = Logger.getLogger(KineticEncoder.class.getName());

    private static boolean printMessage = Boolean.getBoolean("kinetic.io.out");

    @Override
    protected void encode(ChannelHandlerContext ctx, KineticMessage km, ByteBuf out) throws Exception {

        try {

            // get value to write separately
            // byte[] value = builder.getValue().toByteArray();
            byte[] value = km.getValue();

            // 1. write magic number
            out.writeByte((byte) 'F');

            //get message
            Message.Builder messageBuilder = (Builder) km.getMessage();

            // build message
            Message msg = messageBuilder.build();

            // get proto message bytes
            byte[] protoMessageBytes = msg.toByteArray();

            // 2. write protobuf message message size, 4 byte
            out.writeInt(protoMessageBytes.length);

            // 3. write attached value size, 4 byte
            if (value != null) {
                out.writeInt(value.length);
            } else {
                out.writeInt(0);
            }

            // 4. write protobuf message byte[]
            out.writeBytes(protoMessageBytes);

            // 5 (optional) write attached value if any
            if (value != null && value.length > 0) {
                // write value
                out.writeBytes(value);
            }

            // log message out
            if (printMessage) {

                logger.info("outbound protocol message:");

                String printMsg = ProtocolMessageUtil.toString(km);

                logger.info(printMsg);
            }

        } catch (Exception e) {
            logger.log(Level.WARNING, e.getMessage(), e);
            throw e;
        }
    }

}