org.ensembl.gti.seqstore.server.MetaDataServer.java Source code

Java tutorial

Introduction

Here is the source code for org.ensembl.gti.seqstore.server.MetaDataServer.java

Source

/*
 * Copyright 2015 EMBL-European Bioinformatics Institute
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.ensembl.gti.seqstore.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;

import java.util.Properties;

import javax.sql.DataSource;

import org.ensembl.gti.seqstore.database.HybridEnaCramSeqStore;
import org.ensembl.gti.seqstore.database.cramstore.EnaCramSubmissionHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;

import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

public class MetaDataServer {

    public static class MetaDataServerOptions {

        @Parameter(names = { "-ena_ftp" }, description = "ENA FTP URI")
        private String ftpUri = "webin.ebi.ac.uk";

        @Parameter(names = { "-ena_submit" }, description = "ENA Submit URI")
        private String submitUri = "https://www-test.ebi.ac.uk/ena/submit/drop-box/submit/?auth=ENA%20USERNAME%20PASSWORD";

        @Parameter(names = { "-ena_centre" }, description = "ENA centre")
        private String centre = "EBI-GTI";

        @Parameter(names = { "-ena_user" }, description = "ENA user")
        private String submitUser;

        @Parameter(names = { "-ena_pass" }, description = "ENA password")
        private String submitPass;

        @Parameter(names = { "-uri", "-U" }, description = "Database URI")
        private String dbUri;

        @Parameter(names = { "-user", "-u" }, description = "Database username")
        private String dbUser;

        @Parameter(names = { "-pass", "-p" }, description = "Database password")
        private String dbPass;

        @Parameter(names = { "-port", "-P" }, description = "Server port")
        private int port;

        public MetaDataServerOptions() {

        }

        public MetaDataServerOptions(Properties properties) {
            this(properties.getProperty("db_uri"), properties.getProperty("db_user"),
                    properties.getProperty("db_pass"), Integer.parseInt(properties.getProperty("server_port")));
        }

        public MetaDataServerOptions(String uri, String user, String pass, int port) {
            this.setDbUri(uri);
            this.setDbUser(user);
            this.setDbPass(pass);
            this.setPort(port);
        }

        public String getCentre() {
            return centre;
        }

        public String getDbPass() {
            return dbPass;
        }

        public String getDbUri() {
            return dbUri;
        }

        public String getDbUser() {
            return dbUser;
        }

        public String getFtpUri() {
            return ftpUri;
        }

        public int getPort() {
            return port;
        }

        public String getSubmitPass() {
            return submitPass;
        }

        public String getSubmitUri() {
            return submitUri;
        }

        public String getSubmitUser() {
            return submitUser;
        }

        public void setCentre(String centre) {
            this.centre = centre;
        }

        public void setDbPass(String dbPass) {
            this.dbPass = dbPass;
        }

        public void setDbUri(String dbUri) {
            this.dbUri = dbUri;
        }

        public void setDbUser(String dbUser) {
            this.dbUser = dbUser;
        }

        public void setFtpUri(String ftpUri) {
            this.ftpUri = ftpUri;
        }

        public void setPort(int port) {
            this.port = port;
        }

        public void setSubmitPass(String submitPass) {
            this.submitPass = submitPass;
        }

        public void setSubmitUri(String submitUri) {
            this.submitUri = submitUri;
        }

        public void setSubmitUser(String submitUser) {
            this.submitUser = submitUser;
        }

    }

    public static DataSource buildDataSource(String dbUri, String dbUser, String dbPass) {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl(dbUri);
        config.setUsername(dbUser);
        config.setPassword(dbPass);
        config.addDataSourceProperty("cachePrepStmts", "true");
        config.addDataSourceProperty("prepStmtCacheSize", "250");
        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");

        return new HikariDataSource(config);

    }

    public static void main(String[] args) throws Exception {

        final Logger log = LoggerFactory.getLogger(MetaDataServer.class);

        Properties properties = new Properties();
        properties.load(new ClassPathResource("metadata_server.properties").getInputStream());

        MetaDataServerOptions opts = new MetaDataServerOptions(properties);

        new JCommander(opts, args);

        log.info("Starting ENA submission handler");
        EnaCramSubmissionHandler enaHandler = new EnaCramSubmissionHandler(opts.getFtpUri(), opts.getSubmitUri(),
                opts.getCentre(), opts.getSubmitUser(), opts.getSubmitPass());

        log.info("Starting server on " + opts.getPort());
        new MetaDataServer(opts.getPort(), buildDataSource(opts.getDbUri(), opts.getDbUser(), opts.getDbPass()),
                enaHandler).run();

    }

    private final int port;

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    private final DataSource ds;

    private final EnaCramSubmissionHandler handler;

    public MetaDataServer(int port, DataSource ds, EnaCramSubmissionHandler handler) {
        this.port = port;
        this.ds = ds;
        this.handler = handler;
    }

    protected ChannelHandlerAdapter getHandler() {
        return new RequestResponseServerHandler(new HybridEnaCramSeqStore(ds, handler));
    }

    public void run() throws Exception {
        log.info("Starting server");
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4),
                                    getHandler());
                        }
                    }).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);

            // Bind and start to accept incoming connections.
            log.info("Binding to port " + port);
            ChannelFuture f = b.bind(port).sync();

            // Wait until the server socket is closed.
            // In this example, this does not happen, but you can do that to
            // gracefully shut down your server.
            log.info("Syncing future");
            f.channel().closeFuture().sync();
        } finally {
            log.info("Shutting server server");
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

}