Package org.apache.isis.runtimes.dflt.remoting.transport

Source Code of org.apache.isis.runtimes.dflt.remoting.transport.ServerConnectionHandler

/*
*  Licensed to the Apache Software Foundation (ASF) under one
*  or more contributor license agreements.  See the NOTICE file
*  distributed with this work for additional information
*  regarding copyright ownership.  The ASF licenses this file
*  to you 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.apache.isis.runtimes.dflt.remoting.transport;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

import org.apache.log4j.Logger;

import org.apache.isis.core.commons.authentication.AuthenticationSession;
import org.apache.isis.core.commons.debug.DebugBuilder;
import org.apache.isis.core.commons.debug.DebuggableWithTitle;
import org.apache.isis.core.commons.exceptions.IsisException;
import org.apache.isis.runtimes.dflt.monitoring.servermonitor.Monitor;
import org.apache.isis.runtimes.dflt.remoting.common.exchange.OpenSessionRequest;
import org.apache.isis.runtimes.dflt.remoting.common.exchange.Request;
import org.apache.isis.runtimes.dflt.remoting.common.exchange.ResponseEnvelope;
import org.apache.isis.runtimes.dflt.remoting.server.ServerConnection;
import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;

/**
* Standard processing for processing an inbound {@link Request} and generating
* an outbound {@link ResponseEnvelope} (or some sort of {@link Exception}).
*
* <p>
* Used by the (socket transport) {@link Worker} and originally inlined; now
* factored out so can be reused by other transports, notably http.
*/
public class ServerConnectionHandler {

    private static final Logger LOG = Logger.getLogger(ServerConnectionHandler.class);
    private static final Logger ACCESS_LOG = Logger.getLogger("access_log");

    private final ServerConnection connection;

    private String debugRequest;
    private String debugAuthSession;
    private String debugResponse;
    private String debugContextId;

    private DebuggableWithTitle[] debugSessionInfo;

    private long responseTime;

    public ServerConnectionHandler(final ServerConnection connection) {
        this.connection = connection;
    }

    // /////////////////////////////////////////////////////
    // handleRequest
    // /////////////////////////////////////////////////////

    public void handleRequest() throws IOException {
        final long start = System.currentTimeMillis();
        final Request request = connection.readRequest();
        AuthenticationSession authenticationSession = null;
        try {
            authenticationSession = openSessionIfNotAuthenticateRequest(request);

            monitorRequest(authenticationSession, request);
            executeRequest(request);

            sendResponse(request);

        } catch (final Exception e) {
            sendExceptionResponse(e);

        } finally {
            closeSessionIfNotAuthenticateRequest(authenticationSession);
            calcResponseTime(start);
        }
    }

    private AuthenticationSession openSessionIfNotAuthenticateRequest(final Request request) {
        AuthenticationSession authenticationSession;
        if (LOG.isDebugEnabled()) {
            debugRequest = request.getId() + " - " + request.toString();
        }
        authenticationSession = request.getSession();

        if (authenticationSession == null) {
            if (LOG.isDebugEnabled()) {
                debugAuthSession = "(none)";
                debugContextId = "(none)";
            }

            if (!(request instanceof OpenSessionRequest)) {
                throw new IsisException("AuthenticationSession required for all requests (except the initial Authenticate request)");
            }
        } else {
            IsisContext.openSession(authenticationSession);

            if (LOG.isDebugEnabled()) {
                debugAuthSession = authenticationSession.toString();
                debugContextId = IsisContext.getSessionId();
                debugSessionInfo = IsisContext.debugSession();
            }
        }
        return authenticationSession;
    }

    private void monitorRequest(final AuthenticationSession authenticationSession, final Request request) {
        final String userName = authenticationSession != null ? authenticationSession.getUserName() : "**AUTHENTICATING**";
        final String message = "{" + userName + "|" + this + "}  " + request.toString();
        ACCESS_LOG.info(message);
        Monitor.addEvent("REQUEST", message, debugSessionInfo);
    }

    private void executeRequest(final Request request) {
        request.execute(connection.getServerFacade());
    }

    private void sendResponse(final Request request) throws IOException {
        final ResponseEnvelope response = new ResponseEnvelope(request);

        if (LOG.isDebugEnabled()) {
            debugResponse = response.toString();
            LOG.debug("sending " + debugResponse);
        }
        connection.sendResponse(response);
    }

    private void sendExceptionResponse(final Exception e) throws IOException {
        LOG.error("error during remote request", e);
        final StringWriter sw = new StringWriter();
        e.printStackTrace(new PrintWriter(sw));

        if (LOG.isDebugEnabled()) {
            debugResponse = sw.toString();
        }

        connection.sendResponse(e);
    }

    private void calcResponseTime(final long start) {
        responseTime = System.currentTimeMillis() - start;
    }

    private void closeSessionIfNotAuthenticateRequest(final AuthenticationSession authenticationSession) {
        if (authenticationSession == null) {
            return;
        }
        IsisContext.closeSession();
    }

    // /////////////////////////////////////////////////////
    // Debug
    // /////////////////////////////////////////////////////

    public void debug(final DebugBuilder debug) {
        debug.appendln("context Id", debugContextId);
        debug.appendln("authSession", debugAuthSession);
        debug.appendln("request", debugRequest);
        debug.appendln("response", debugResponse);
        debug.appendln("duration", responseTime / 1000.0f + " secs.");

        // TODO: the code below was commented out (by Rob, presumably?); I've
        // reinstated it but disabled it so no change in behaviour
        if (false) {
            debugSessionInfo(debug);
        }
    }

    private void debugSessionInfo(final DebugBuilder debug) {
        try {
            if (debugSessionInfo != null) {
                for (final DebuggableWithTitle info : debugSessionInfo) {
                    debug.appendTitle(info.debugTitle());
                    info.debugData(debug);
                }
            }
        } catch (final RuntimeException e) {
            debug.appendException(e);
        }
    }

}
TOP

Related Classes of org.apache.isis.runtimes.dflt.remoting.transport.ServerConnectionHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.