All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ait.tooling.server.rpc.servlet.RPCCommandServlet Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2014,2015 Ahome' Innovation Technologies. All rights reserved.
 *
 * 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 com.ait.tooling.server.rpc.servlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.log4j.MDC;

import com.ait.tooling.common.api.java.util.StringOps;
import com.ait.tooling.common.api.java.util.UUID;
import com.ait.tooling.common.server.io.NoSyncBufferedWriter;
import com.ait.tooling.server.core.json.JSONObject;
import com.ait.tooling.server.core.json.parser.JSONParser;
import com.ait.tooling.server.core.json.parser.JSONParserException;
import com.ait.tooling.server.core.security.AuthorizationResult;
import com.ait.tooling.server.core.security.session.IServerSession;
import com.ait.tooling.server.core.security.session.IServerSessionRepository;
import com.ait.tooling.server.core.servlet.HTTPServletBase;
import com.ait.tooling.server.core.support.CoreGroovySupport;
import com.ait.tooling.server.rpc.IJSONCommand;
import com.ait.tooling.server.rpc.JSONRequestContext;
import com.ait.tooling.server.rpc.support.spring.IRPCContext;
import com.ait.tooling.server.rpc.support.spring.RPCContextInstance;

public class RPCCommandServlet extends HTTPServletBase
{
    private static final long   serialVersionUID = 8890049936686095786L;

    private static final Logger logger           = Logger.getLogger(RPCCommandServlet.class);

    public RPCCommandServlet()
    {
    }

    @Override
    public void doPost(final HttpServletRequest request, final HttpServletResponse response) throws IOException
    {
        if (false == isRunning())
        {
            logger.error("server is suspended, refuse command request");

            response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);

            return;
        }
        final String userid = StringOps.toTrimOrNull(request.getHeader(X_USER_ID_HEADER));

        final String sessid = StringOps.toTrimOrNull(request.getHeader(X_SESSION_ID_HEADER));

        MDC.put("session", ((userid == null) ? "no-userid" : userid) + "-" + ((sessid == null) ? "no-sessid" : sessid));

        JSONObject object = parseJSON(request);

        if (null == object)
        {
            logger.error("passed body is not a JSONObject");

            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

            return;
        }
        String name = null;

        if (isCommandInBody())
        {
            if (false == object.isDefined("command"))
            {
                logger.error("no command key found");

                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

                return;
            }
            name = StringOps.toTrimOrNull(object.getAsString("command"));

            if (null == name)
            {
                logger.error("empty command key found");

                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

                return;
            }
        }
        else
        {
            name = StringOps.toTrimOrNull(request.getPathInfo());

            if (null != name)
            {
                int indx = name.lastIndexOf("/");

                if (indx >= 0)
                {
                    name = StringOps.toTrimOrNull(name.substring(indx + 1));
                }
                if (null != name)
                {
                    if (name.endsWith(".rpc"))
                    {
                        name = StringOps.toTrimOrNull(name.substring(0, name.length() - 4));
                    }
                }
            }
            if (null == name)
            {
                logger.error("empty command path found");

                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

                return;
            }
        }
        final IJSONCommand command = getRPCContext().getCommand(name);

        if (null == command)
        {
            logger.error("command not found " + name);

            response.setStatus(HttpServletResponse.SC_NOT_FOUND);

            return;
        }
        if (false == object.isDefined("request"))
        {
            logger.error("no request key found");

            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

            return;
        }
        object = object.getAsObject("request");

        if (null == object)
        {
            logger.error("empty request key found");

            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

            return;
        }
        List roles = null;

        if (null != sessid)
        {
            final String domain_name = StringOps.toTrimOrNull(getServletConfig().getInitParameter("session_domain_name"));

            final IServerSessionRepository repository = getServerContext().getServerSessionRepository((domain_name == null) ? "default" : domain_name);

            if (null != repository)
            {
                final IServerSession session = repository.getSession(sessid);

                if ((null != session) && (false == session.isExpired()))
                {
                    roles = session.getRoles();
                }
            }
        }
        if (null == roles)
        {
            roles = new ArrayList(0);
        }
        final AuthorizationResult resp = isAuthorized(command, roles);

        if (false == resp.isAuthorized())
        {
            logger.error("service authorization failed " + name + " for user " + userid + " code " + resp.getText());

            response.setStatus(HttpServletResponse.SC_FORBIDDEN);

            return;
        }
        final JSONRequestContext context = new JSONRequestContext(userid, sessid, resp.isAdmin(), roles, getServletContext(), request, response);

        try
        {
            final long tick = System.currentTimeMillis();

            final long time = System.nanoTime();

            final JSONObject result = command.execute(context, object);

            final long fast = System.nanoTime() - time;

            final long done = System.currentTimeMillis() - tick;

            if (done < 1)
            {
                logger.info("calling command " + name + " took " + fast + "nano's");
            }
            else
            {
                logger.info("calling command " + name + " took " + done + "ms's");
            }
            final JSONObject output = new JSONObject("result", result);

            writeJSON(response, output);
        }
        catch (Throwable e)
        {
            final String uuid = UUID.uuid();

            logger.error("calling command " + name + " ERROR UUID=" + uuid, e);

            final JSONObject output = new JSONObject("error", "A severe error occured with UUID=" + uuid + " , Please contact support.");

            writeJSON(response, output);
        }
    }

    protected boolean isCommandInBody()
    {
        return true;
    }

    protected JSONObject parseJSON(final HttpServletRequest request)
    {
        JSONObject object = null;

        final JSONParser parser = new JSONParser();

        try
        {
            final Object parsed = parser.parse(request.getReader());

            if (parsed instanceof JSONObject)
            {
                object = ((JSONObject) parsed);
            }
        }
        catch (JSONParserException e)
        {
            logger.error("JSONParserException", e);
        }
        catch (IOException e)
        {
            logger.error("IOException", e);
        }
        return object;
    }

    protected void writeJSON(final HttpServletResponse response, final JSONObject output) throws IOException
    {
        response.setStatus(HttpServletResponse.SC_OK);

        response.setContentType(CONTENT_TYPE_APPLICATION_JSON);

        response.getWriter().flush();

        final NoSyncBufferedWriter buff = new NoSyncBufferedWriter(response.getWriter(), 1024);

        output.writeJSONString(buff, true);

        buff.flush();
    }

    protected boolean isRunning()
    {
        return CoreGroovySupport.getCoreGroovySupport().getCoreServerManager().isRunning();
    }

    protected final IRPCContext getRPCContext()
    {
        return RPCContextInstance.getRPCContextInstance();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy