com.liferay.sync.engine.lan.server.file.LanFileServer.java Source code

Java tutorial

Introduction

Here is the source code for com.liferay.sync.engine.lan.server.file.LanFileServer.java

Source

/**
 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 */

package com.liferay.sync.engine.lan.server.file;

import com.liferay.sync.engine.lan.server.LanEngine;
import com.liferay.sync.engine.model.ModelListener;
import com.liferay.sync.engine.model.SyncAccount;
import com.liferay.sync.engine.model.SyncFile;
import com.liferay.sync.engine.service.SyncFileService;
import com.liferay.sync.engine.util.PropsValues;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

import java.net.BindException;
import java.net.InetSocketAddress;

import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author Dennis Ju
 */
public class LanFileServer {

    public int getPort() {
        return _port;
    }

    public ModelListener<SyncAccount> getSyncAccountListener() {
        if (syncAccountListener != null) {
            return syncAccountListener;
        }

        syncAccountListener = new ModelListener<SyncAccount>() {

            @Override
            public void onCreate(SyncAccount syncAccount) {
                updateDomainNameMapping(syncAccount);
            }

            @Override
            public void onRemove(SyncAccount syncAccount) {
                updateDomainNameMapping(syncAccount);
            }

            @Override
            public void onUpdate(SyncAccount syncAccount, Map<String, Object> originalValues) {

                if (originalValues.containsKey("active") || originalValues.containsKey("lanCertificate")
                        || originalValues.containsKey("lanKey")) {

                    updateDomainNameMapping(syncAccount);
                }
            }

            protected void updateDomainNameMapping(SyncAccount syncAccount) {
                if ((_lanFileServerInitializer != null) && syncAccount.isLanEnabled()) {

                    _lanFileServerInitializer.updateDomainNameMapping();
                }
            }

        };

        return syncAccountListener;
    }

    public void start() throws Exception {
        _childEventLoopGroup = new NioEventLoopGroup();
        _parentEventLoopGroup = new NioEventLoopGroup(1);

        ServerBootstrap serverBootstrap = new ServerBootstrap();

        serverBootstrap.group(_parentEventLoopGroup, _childEventLoopGroup);
        serverBootstrap.channel(NioServerSocketChannel.class);

        _syncTrafficShapingHandler = new SyncTrafficShapingHandler(_childEventLoopGroup);

        _lanFileServerInitializer = new LanFileServerInitializer(_syncTrafficShapingHandler);

        serverBootstrap.childHandler(_lanFileServerInitializer);

        serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);

        ChannelFuture channelFuture = serverBootstrap.bind(PropsValues.SYNC_LAN_SERVER_PORT);

        try {
            channelFuture.sync();
        } catch (Exception e) {

            // Compiling fails when directly catching BindException. Netty seems
            // to throw an undeclared exception.

            if (e instanceof BindException) {
                channelFuture = serverBootstrap.bind(0);

                channelFuture.sync();
            } else {
                throw e;
            }
        }

        Channel channel = channelFuture.channel();

        InetSocketAddress inetSocketAddress = (InetSocketAddress) channel.localAddress();

        _port = inetSocketAddress.getPort();

        channelFuture.sync();

        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                long count = SyncFileService.getSyncFilesCount(SyncFile.UI_EVENT_DOWNLOADING,
                        SyncFile.UI_EVENT_UPLOADING);

                long writeDelay = 0;

                if (count > 0) {
                    _syncTrafficShapingHandler.setWriteDelay(PropsValues.SYNC_LAN_SERVER_WRITE_DELAY);
                }

                _syncTrafficShapingHandler.setWriteDelay(writeDelay);
            }

        };

        ScheduledExecutorService scheduledExecutorService = LanEngine.getScheduledExecutorService();

        scheduledExecutorService.scheduleWithFixedDelay(runnable, 0, 500, TimeUnit.MILLISECONDS);
    }

    public void stop() {
        if (_syncTrafficShapingHandler != null) {
            _syncTrafficShapingHandler.release();
        }

        if (_childEventLoopGroup != null) {
            _childEventLoopGroup.shutdownGracefully();
        }

        if (_parentEventLoopGroup != null) {
            _parentEventLoopGroup.shutdownGracefully();
        }
    }

    protected ModelListener<SyncAccount> syncAccountListener;

    private EventLoopGroup _childEventLoopGroup;
    private LanFileServerInitializer _lanFileServerInitializer;
    private EventLoopGroup _parentEventLoopGroup;
    private int _port;
    private SyncTrafficShapingHandler _syncTrafficShapingHandler;

}