com.nettyhttpserver.server.NettyChannelTrafficShapingHandler.java Source code

Java tutorial

Introduction

Here is the source code for com.nettyhttpserver.server.NettyChannelTrafficShapingHandler.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package com.nettyhttpserver.server;

import com.nettyhttpserver.domain.ConnectionInfoDTO;
import com.nettyhttpserver.service.serverrequest.ServerRequestService;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.traffic.ChannelTrafficShapingHandler;
import io.netty.handler.traffic.TrafficCounter;
import java.net.InetSocketAddress;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 *
 * @author McKey
 */
public class NettyChannelTrafficShapingHandler extends ChannelTrafficShapingHandler {
    private final ApplicationContext context;
    private final ServerRequestService service;

    /**
     * List of last 16 connections.
     */
    private static List<ConnectionInfoDTO> serverConnectionList = Collections
            .synchronizedList(new ArrayList<ConnectionInfoDTO>());
    /**
     * Instance of {@link vlt.hamster.netty.status.ServerConnectionRecord
     * ServerConnectionRecord} used for accounting one channel.
     */
    private ConnectionInfoDTO connectionInfo = new ConnectionInfoDTO();

    public NettyChannelTrafficShapingHandler(long checkInterval) {
        super(checkInterval);
        context = new ClassPathXmlApplicationContext("nettyBeans.xml");
        service = context.getBean(ServerRequestService.class);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        connectionInfo.setIp(((InetSocketAddress) ctx.channel().remoteAddress()).getHostString());
        connectionInfo.setTimestamp(new Timestamp(System.currentTimeMillis()));
        super.channelActive(ctx);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof HttpRequest) {
            /*
             * Traffic accounting is recorded in ServerConnectionRecord instance
             */
            String uri = ((HttpRequest) msg).getUri();
            connectionInfo.setUri(uri);
            trafficAccounting();

        }
        super.channelRead(ctx, msg);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        trafficAccounting();
        if (connectionInfo.getUri() == null) {
            connectionInfo.setUri("No URI Accessed");
        }
        super.channelInactive(ctx);
    }

    /**
     * If there are more than 16 connections in list, removes the first one and
     * adds new one to the end.
     */
    private void addToConnectionList() {
        serverConnectionList.add(connectionInfo);
        if (serverConnectionList.size() > 16) {
            serverConnectionList.remove(0);
        }

    }

    /**
     * 
     * @return the backwards (from the last element) iterator of the list
     */
    public static ListIterator<ConnectionInfoDTO> getServerConnectionListIterator() {
        /*
         * The list copy is returned so no Concurrency exceptions will be thrown
         * wgile iterating over changing list.
         */
        List<ConnectionInfoDTO> list = new ArrayList<>(serverConnectionList);
        return list.listIterator(list.size());
    }

    private void trafficAccounting() {
        TrafficCounter tc = trafficCounter();
        connectionInfo.setRecivedBytes(Math.abs(tc.cumulativeReadBytes()));
        connectionInfo.setSentBytes(tc.cumulativeWrittenBytes());
        connectionInfo.setSpeed(tc.lastWrittenBytes() * 1000 / (tc.checkInterval()));
        connectionInfo.setTimestamp(new Timestamp(System.currentTimeMillis()));
        /*
         * Instance is added to List on last place (the last the newest)
         */
        if (serverConnectionList.contains(connectionInfo)) {
            serverConnectionList.remove(connectionInfo);
            addToConnectionList();
        } else {
            addToConnectionList();
        }
    }
}