org.opendaylight.usc.plugin.UscRemoteDeviceHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.usc.plugin.UscRemoteDeviceHandler.java

Source

/*
 * Copyright (c) 2015 Huawei, 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.usc.plugin;

import org.opendaylight.usc.manager.UscRouteBrokerService;
import org.opendaylight.usc.manager.cluster.UscRouteIdentifier;
import org.opendaylight.usc.manager.cluster.message.UscRemoteDataMessage;
import org.opendaylight.usc.util.UscServiceUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.util.ReferenceCountUtil;

/**
 * This handler only for remote device, it will be added into the localServer
 * pipeline.this handler like a remote dummy device to process all of
 * communication with the remote device
 */
@Sharable
public class UscRemoteDeviceHandler extends ChannelInboundHandlerAdapter {

    private static final Logger LOG = LoggerFactory.getLogger(UscRemoteDeviceHandler.class);

    private UscRouteBrokerService broker;
    private ByteBuf buffer = Unpooled.buffer(10000);
    private UscRouteIdentifier routeId;

    public UscRemoteDeviceHandler() {
    }

    private boolean isRemote(ChannelHandlerContext ctx) {
        routeId = ctx.channel().attr(UscPlugin.ROUTE_IDENTIFIER).get();
        if (routeId != null) {
            LOG.trace("UscRemoteDeviceHandler:Channel read finished for route id(" + routeId + ")");
            if (broker == null) {
                broker = UscServiceUtils.getService(UscRouteBrokerService.class);
            }
            if (broker != null) {
                if (broker.isLocalRemoteSession(routeId)) {
                    return true;
                } else {
                    LOG.debug(
                            "It's not local to remote channel(" + routeId + ") message, pass it to other handler");
                }
            } else {
                LOG.error(
                        "Broker service is null! Can't check if it is remote channel message, and pass it to other handler.");
            }
        }
        return false;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (isRemote(ctx)) {
            ByteBuf payload = (ByteBuf) msg;
            byte[] data = getPayloadFromByteBuf(payload);
            writeBuffer(data);
            return;
        }
        ReferenceCountUtil.retain(msg);
        // propagate the data to rest of handlers in pipeline
        ctx.fireChannelRead(msg);
    }

    private byte[] getPayloadFromByteBuf(ByteBuf buf) {
        int length = buf.readableBytes();
        byte[] ret = new byte[length];
        for (int i = 0; i < length; i++) {
            ret[i] = buf.readByte();
        }
        return ret;
    }

    private void writeBuffer(byte[] data) {
        int newSize = 0;
        int oldSize = buffer.capacity();
        int length = data.length;
        if (buffer.writableBytes() <= length) {
            if (length > oldSize) {
                newSize = length * 2;
            } else {
                newSize = 2 * oldSize;
            }
            buffer.capacity(newSize);
        }
        buffer.writeBytes(data);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        if (isRemote(ctx)) {
            broker.removeLocalSession(routeId);
        }
        ctx.fireChannelInactive();
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        if (isRemote(ctx)) {
            byte[] data = getPayloadFromByteBuf(buffer);
            LOG.trace(
                    "Read complete,send message to remote channel: " + routeId + ",message is " + new String(data));
            broker.sendRequest(new UscRemoteDataMessage(routeId, data, true));
            buffer.clear();
            return;
        }
        // propagate the data to rest of handlers in pipeline
        ctx.fireChannelReadComplete();
    }
}