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

Java tutorial

Introduction

Here is the source code for org.ensembl.gti.seqstore.server.RequestResponseServerHandler.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.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import org.ensembl.gti.seqstore.database.SeqStore;
import org.ensembl.gti.seqstore.database.SeqStoreException;
import org.ensembl.gti.seqstore.encoding.GeneDelegate;
import org.ensembl.gti.seqstore.encoding.GeneProtos.Gene;
import org.ensembl.gti.seqstore.encoding.GenomeDelegate;
import org.ensembl.gti.seqstore.encoding.GenomeSequenceDelegate;
import org.ensembl.gti.seqstore.encoding.GenomeSequenceProtos.GenomeSequence;
import org.ensembl.gti.seqstore.encoding.RequestProtos.Request;
import org.ensembl.gti.seqstore.encoding.ResponseProtos.Response;
import org.ensembl.gti.seqstore.encoding.ResponseProtos.Response.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Handler for decoding incoming responses and dealing with as appropriate
 * 
 * @author dstaines
 *
 */
@Sharable
public class RequestResponseServerHandler extends ChannelInboundHandlerAdapter {

    private final SeqStore seqStore;

    public RequestResponseServerHandler(SeqStore seqStore) {
        this.seqStore = seqStore;
    }

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

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        log.trace("Reading message");
        ByteBuf in = (ByteBuf) msg;
        int l = in.readInt();
        log.trace("Reading message of length " + l);
        ByteBuf x = in.readBytes(l);
        Response response = null;
        try {
            Request request = Request.parseFrom(x.array());
            log.debug("Received " + request.getOperation());
            String responseMsg;
            switch (request.getOperation()) {
            case START_SESSION:
                log.debug("Creating new session for " + request.getClientId());
                Long id = seqStore.startSession(request.getClientId());
                responseMsg = id.toString();
                break;
            case ABORT_SESSION:
                log.debug("Aborting session " + request.getSessionId() + " for " + request.getClientId());
                seqStore.clearSession(request.getSessionId());
                responseMsg = "Aborted session " + request.getSessionId();
                break;
            case STORE_GENOME:
                log.debug("Storing " + request.getGeneCount() + " genes");
                long genomeId = seqStore.storeGenome(request.getSessionId(),
                        new GenomeDelegate(request.getGenome()));
                responseMsg = String.valueOf(genomeId);
                break;
            case STORE_GENOME_SEQUENCE:
                log.info("Storing " + request.getGenomeSequenceCount() + " genome sequences");
                int n = 0;
                for (GenomeSequence g : request.getGenomeSequenceList()) {
                    seqStore.storeGenomeSequence(request.getSessionId(), new GenomeSequenceDelegate(g));
                    n++;
                }
                responseMsg = "Stored " + n + " genome sequences";
                break;
            case STORE_GENE:
                log.debug("Storing " + request.getGeneCount() + " genes");
                n = 0;
                for (Gene g : request.getGeneList()) {
                    seqStore.storeGene(request.getSessionId(), new GeneDelegate(g));
                    n++;
                }
                responseMsg = "Stored " + n + " genes";
                break;
            default:
                responseMsg = "Unknown operation " + request.getOperation();
                response = Response.newBuilder().setStatus(Status.DATA_ERROR).setMessage(responseMsg).build();
                throw new UnsupportedOperationException(responseMsg);
            }
            response = Response.newBuilder().setStatus(Status.OK).setMessage(responseMsg).build();
        } catch (SeqStoreException e) {
            log.error("Error processing request", e);
            response = Response.newBuilder().setStatus(Status.DATA_ERROR).setMessage(e.getMessage()).build();
        } catch (Throwable e) {
            log.error("Error processing request", e);
            response = Response.newBuilder().setStatus(Status.SERVER_ERROR).setMessage(e.getMessage()).build();
        } finally {
            byte[] ra = response.toByteArray();
            ctx.write(Unpooled.copyInt(ra.length));
            ctx.write(Unpooled.copiedBuffer(ra));
            ctx.flush();
            if (x != null)
                x.release();
            if (in != null)
                in.release();

        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // Close the connection when an exception is raised.
        cause.printStackTrace();
        ctx.close();
    }
}