Search in sources :

Example 1 with LogParameters

use of com.twinsoft.convertigo.engine.LogParameters in project convertigo by convertigo.

the class RequestableStep method stepExecute.

@Override
protected boolean stepExecute(Context javascriptContext, Scriptable scope) throws EngineException {
    if (isEnabled()) {
        if (super.stepExecute(javascriptContext, scope)) {
            try {
                request = new HashMap<String, Object>();
                try {
                    prepareForRequestable(javascriptContext, scope);
                } catch (Exception e) {
                    Engine.logBeans.error("An error occured while preparing transaction step \"" + RequestableStep.this.getName() + "\"", e);
                    xmlHttpDocument = ConvertigoError.get(e).buildErrorDocument(sequence.getRequester(), sequence.context, false);
                    flushDocument();
                    return true;
                }
                if (bInternalInvoke) {
                    Engine.logBeans.debug("(RequestableStep) Internal invoke requested");
                    InternalRequester internalRequester = new InternalRequester(request, sequence.context.httpServletRequest);
                    LogParameters logParameters = sequence.context.logParameters;
                    Object result = internalRequester.processRequest();
                    // MDC log parameters must return to their original values, because
                    // the internal requester has been executed on the same thread as us.
                    Log4jHelper.mdcSet(logParameters);
                    if (result != null) {
                        xmlHttpDocument = (Document) result;
                        // if (Engine.isStudioMode()) {
                        // ((Sequence)sequence.getOriginal()).fireDataChanged(new SequenceEvent(this, result));
                        // }
                        // else {
                        // sequence.fireDataChanged(new SequenceEvent(this, result));
                        // }
                        ((Sequence) sequence.getOriginal()).fireDataChanged(new SequenceEvent(this, result));
                        flushDocument();
                    }
                } else {
                    Engine.logBeans.debug("(RequestableStep) requesting : " + method.getURI());
                    byte[] result = executeMethod();
                    Engine.logBeans.debug("(RequestableStep) Total read bytes: " + ((result != null) ? result.length : 0));
                    if (result != null) {
                        makeDocument(result);
                        if (Engine.isStudioMode()) {
                            ((Sequence) sequence.getOriginal()).fireDataChanged(new SequenceEvent(this, result));
                        } else {
                            sequence.fireDataChanged(new SequenceEvent(this, result));
                        }
                        flushDocument();
                    }
                }
            } catch (Exception e) {
                setErrorStatus(true);
                Engine.logBeans.error("An error occured while invoking transaction step \"" + RequestableStep.this.getName() + "\"", e);
            } finally {
                if (!bInternalInvoke && (method != null))
                    method.releaseConnection();
            }
            return true;
        }
    }
    return false;
}
Also used : LogParameters(com.twinsoft.convertigo.engine.LogParameters) InternalRequester(com.twinsoft.convertigo.engine.requesters.InternalRequester) NativeJavaObject(org.mozilla.javascript.NativeJavaObject) URIException(org.apache.commons.httpclient.URIException) EngineException(com.twinsoft.convertigo.engine.EngineException) TransformerException(javax.xml.transform.TransformerException) ConnectionException(com.twinsoft.convertigo.beans.connectors.ConnectionException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException)

Example 2 with LogParameters

use of com.twinsoft.convertigo.engine.LogParameters in project convertigo by convertigo.

the class Add method getServiceResult.

protected void getServiceResult(HttpServletRequest request, JSONObject response) throws Exception {
    try {
        JSONArray logs = new JSONArray(request.getParameter("logs"));
        JSONObject env = new JSONObject(request.getParameter("env"));
        String uid = env.getString("uid");
        if (uid == null) {
            throw new IllegalArgumentException();
        }
        HttpSession httpSession = request.getSession();
        Map<String, LogParameters> logParametersMap = GenericUtils.cast(httpSession.getAttribute(Add.class.getCanonicalName()));
        if (logParametersMap == null) {
            httpSession.setAttribute(Add.class.getCanonicalName(), logParametersMap = new HashMap<String, LogParameters>());
        }
        LogParameters logParameters = logParametersMap.get(uid);
        if (logParameters == null) {
            logParametersMap.put(uid, logParameters = new LogParameters());
            logParameters.put(mdcKeys.ContextID.toString().toLowerCase(), httpSession.getId());
        }
        Log4jHelper.mdcSet(logParameters);
        logParameters.put(mdcKeys.ClientIP.toString().toLowerCase(), request.getRemoteAddr());
        if (EnginePropertiesManager.getProperty(PropertyName.NET_REVERSE_DNS).equalsIgnoreCase("true")) {
            Log4jHelper.mdcPut(mdcKeys.ClientHostName, request.getRemoteHost());
        }
        for (Iterator<String> iKey = GenericUtils.cast(env.keys()); iKey.hasNext(); ) {
            String key = iKey.next();
            logParameters.put(key.toLowerCase(), env.get(key));
        }
        if (SessionAttribute.authenticatedUser.get(httpSession) != null) {
            Log4jHelper.mdcPut(mdcKeys.User, SessionAttribute.authenticatedUser.string(httpSession));
        }
        for (int i = 0; i < logs.length(); i++) {
            JSONObject log = logs.getJSONObject(i);
            Level level = Level.toLevel(log.getString("level"), Level.OFF);
            if (Engine.logDevices.isEnabledFor(level)) {
                String msg = log.getString("msg");
                String time = log.getString("time");
                msg = "(" + time + ") " + msg;
                Engine.logDevices.log(level, msg);
            }
        }
        response.put("remoteLogLevel", Engine.logDevices.getEffectiveLevel().toString().toLowerCase());
    } finally {
        Log4jHelper.mdcClear();
    }
}
Also used : JSONObject(org.codehaus.jettison.json.JSONObject) LogParameters(com.twinsoft.convertigo.engine.LogParameters) HashMap(java.util.HashMap) HttpSession(javax.servlet.http.HttpSession) JSONArray(org.codehaus.jettison.json.JSONArray) Level(org.apache.log4j.Level)

Example 3 with LogParameters

use of com.twinsoft.convertigo.engine.LogParameters in project convertigo by convertigo.

the class RestApiServlet method service.

@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    if (request.getCharacterEncoding() == null) {
        try {
            // Set encoding if needed
            request.setCharacterEncoding("UTF-8");
        } catch (Exception e) {
            throw new ServletException(e);
        }
    }
    try {
        if (EnginePropertiesManager.getPropertyAsBoolean(PropertyName.XSRF_API)) {
            HttpUtils.checkXSRF(request, response);
        }
        HttpSessionListener.checkSession(request);
    } catch (Throwable e) {
        throw new ServletException(e.getMessage(), e);
    }
    if (Engine.isEngineMode() && KeyManager.getCV(Session.EmulIDURLMAPPER) < 1) {
        String msg;
        if (KeyManager.has(Session.EmulIDURLMAPPER) && KeyManager.hasExpired(Session.EmulIDURLMAPPER)) {
            Engine.logEngine.error(msg = "Key expired for the URL Mapper.");
            throw new ServletException(new KeyExpiredException(msg));
        }
        Engine.logEngine.error(msg = "No key for the URL Mapper.");
        throw new ServletException(new MaxCvsExceededException(msg));
    }
    HttpServletRequestTwsWrapper wrapped_request = new HttpServletRequestTwsWrapper(request);
    request = wrapped_request;
    try {
        HttpSessionListener.checkSession(request);
    } catch (TASException e) {
        HttpUtils.terminateSession(request.getSession());
        throw new RuntimeException(e);
    }
    HttpSession httpSession = request.getSession();
    LogParameters logParameters = GenericUtils.cast(httpSession.getAttribute(RestApiServlet.class.getCanonicalName()));
    if (logParameters == null) {
        httpSession.setAttribute(RestApiServlet.class.getCanonicalName(), logParameters = new LogParameters());
        logParameters.put(mdcKeys.ContextID.toString().toLowerCase(), httpSession.getId());
    }
    Log4jHelper.mdcSet(logParameters);
    logParameters.put(mdcKeys.ClientIP.toString().toLowerCase(), request.getRemoteAddr());
    String encoded = request.getParameter(Parameter.RsaEncoded.getName());
    if (encoded != null) {
        String query = Engine.theApp.rsaManager.decrypt(encoded, request.getSession());
        wrapped_request.clearParameters();
        wrapped_request.addQuery(query);
    }
    String method = request.getMethod();
    String uri = request.getRequestURI();
    String query = request.getQueryString();
    Engine.logEngine.debug("(RestApiServlet) Requested URI: " + method + " " + uri);
    boolean isYaml = request.getParameter("YAML") != null;
    boolean isJson = request.getParameter("JSON") != null;
    if ("GET".equalsIgnoreCase(method) && (query == null || query.isEmpty()) && (uri.endsWith("/" + SwaggerUtils.servletMappingPath) || uri.endsWith("/" + OpenApiUtils.servletMappingPath))) {
        isJson = true;
    }
    // Generate YAML/JSON definition (swagger specific)
    if ("GET".equalsIgnoreCase(method) && (isYaml || isJson)) {
        try {
            String requestUrl = HttpUtils.originalRequestURL(request);
            // force endpoint in definition
            try {
                String endPointUrl = EnginePropertiesManager.getProperty(PropertyName.APPLICATION_SERVER_CONVERTIGO_ENDPOINT);
                if (endPointUrl != null && !endPointUrl.isEmpty()) {
                    requestUrl = endPointUrl + (uri.indexOf("/" + SwaggerUtils.servletMappingPath) != -1 ? uri.substring(uri.indexOf("/" + SwaggerUtils.servletMappingPath)) : uri.substring(uri.indexOf("/" + OpenApiUtils.servletMappingPath)));
                    Engine.logEngine.debug("(RestApiServlet) Force requestUrl: " + requestUrl);
                } else {
                    Engine.logEngine.debug("(RestApiServlet) Set requestUrl: " + requestUrl);
                }
            } catch (Throwable t) {
                Engine.logEngine.error("(RestApiServlet) Unable to retrieve server endpoint url: ", t);
            }
            Engine.logEngine.debug("(RestApiServlet) Projects path: " + new File(Engine.PROJECTS_PATH).getAbsolutePath());
            String output = uri.indexOf("/" + SwaggerUtils.servletMappingPath) != -1 ? buildSwaggerDefinition(requestUrl, request.getParameter("__project"), isYaml) : buildOpenApiDefinition(requestUrl, request.getParameter("__project"), isYaml);
            response.setCharacterEncoding("UTF-8");
            response.setContentType((isYaml ? MimeType.Yaml : MimeType.Json).value());
            Writer writer = response.getWriter();
            writer.write(output);
            Engine.logEngine.debug("(RestApiServlet) Definition sent :\n" + output);
        } catch (Exception e) {
            throw new ServletException(e);
        }
    } else // Handle REST request
    {
        long t0 = System.currentTimeMillis();
        try {
            Collection<UrlMapper> collection = RestApiManager.getInstance().getUrlMappers();
            if (collection.size() > 0) {
                if (method.equalsIgnoreCase("OPTIONS")) {
                    String origin = HeaderName.Origin.getHeader(request);
                    if (origin != null) {
                        Set<String> methods = new HashSet<String>();
                        String corsOrigin = null;
                        for (UrlMapper urlMapper : collection) {
                            String co = HttpUtils.filterCorsOrigin(urlMapper.getProject().getCorsOrigin(), origin);
                            if (co != null) {
                                if (corsOrigin == null || co.length() > corsOrigin.length()) {
                                    corsOrigin = co;
                                }
                                urlMapper.addMatchingMethods(wrapped_request, methods);
                            }
                        }
                        HttpUtils.applyCorsHeaders(request, response, corsOrigin, String.join(", ", methods));
                    }
                    response.setStatus(HttpServletResponse.SC_NO_CONTENT);
                    return;
                }
                // Found a matching operation
                UrlMappingOperation urlMappingOperation = null;
                List<UrlAuthentication> urlAuthentications = null;
                for (UrlMapper urlMapper : collection) {
                    urlMappingOperation = urlMapper.getMatchingOperation(request);
                    if (urlMappingOperation != null) {
                        urlAuthentications = urlMapper.getAuthenticationList();
                        break;
                    }
                }
                // Handle request
                if (urlMappingOperation != null) {
                    StringBuffer buf;
                    // Request headers
                    if (Engine.logEngine.isDebugEnabled()) {
                        buf = new StringBuffer();
                        buf.append("(RestApiServlet) Request headers:\n");
                        Enumeration<String> headerNames = request.getHeaderNames();
                        while (headerNames.hasMoreElements()) {
                            String headerName = headerNames.nextElement();
                            String headerValue = request.getHeader(headerName);
                            buf.append(" " + headerName + "=" + headerValue + "\n");
                        }
                        Engine.logEngine.debug(buf.toString());
                        Engine.logEngine.debug("(RestApiServlet) Request parameters: " + Collections.list(request.getParameterNames()));
                    }
                    // The response content
                    String content = null;
                    // Check for authentication
                    if (urlMappingOperation.isTargetAuthenticationContextRequired()) {
                        // Case Authentications are defined for mapper
                        if (urlAuthentications != null) {
                            boolean authenticated = false;
                            int len = urlAuthentications.size();
                            if (len > 0) {
                                for (UrlAuthentication urlAuthentication : urlAuthentications) {
                                    // Handle Auth request
                                    response.reset();
                                    RequestAttribute.responseHeader.set(request, new HashMap<String, String>());
                                    RequestAttribute.responseStatus.set(request, new HashMap<Integer, String>());
                                    urlAuthentication.handleAuthRequest(request, response);
                                    // Check user has been authenticated
                                    authenticated = SessionAttribute.authenticatedUser.string(request.getSession()) != null;
                                    if (authenticated) {
                                        break;
                                    }
                                }
                                // Handle User request
                                if (authenticated) {
                                    response.reset();
                                    RequestAttribute.responseHeader.set(request, new HashMap<String, String>());
                                    RequestAttribute.responseStatus.set(request, new HashMap<Integer, String>());
                                    content = urlMappingOperation.handleRequest(request, response);
                                }
                            } else // HTTP authentication required
                            {
                                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                            }
                        } else // HTTP authentication required
                        {
                            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                        }
                    } else // Handle User request
                    {
                        content = urlMappingOperation.handleRequest(request, response);
                    }
                    // Set response status
                    ServletUtils.applyCustomStatus(request, response);
                    Engine.logEngine.debug("(RestApiServlet) Response status code: " + response.getStatus());
                    // Set response headers
                    ServletUtils.applyCustomHeaders(request, response);
                    if (Engine.logEngine.isDebugEnabled()) {
                        buf = new StringBuffer();
                        buf.append("(RestApiServlet) Response headers:\n");
                        Collection<String> headerNames = response.getHeaderNames();
                        for (String headerName : headerNames) {
                            String headerValue = response.getHeader(headerName);
                            buf.append(" " + headerName + "=" + headerValue + "\n");
                        }
                        Engine.logEngine.debug(buf.toString());
                    }
                    // terminate session to avoid max session exceeded (case new session initiated for authentication)
                    if (response.getStatus() == HttpServletResponse.SC_UNAUTHORIZED) {
                        if (urlMappingOperation instanceof com.twinsoft.convertigo.beans.rest.AbstractRestOperation) {
                            com.twinsoft.convertigo.beans.rest.AbstractRestOperation aro = (com.twinsoft.convertigo.beans.rest.AbstractRestOperation) urlMappingOperation;
                            if (aro.isTerminateSession()) {
                                Engine.logEngine.debug("(RestApiServlet) requireEndOfContext because of required authentication");
                                request.setAttribute("convertigo.requireEndOfContext", true);
                            }
                        }
                    }
                    if (content != null) {
                        Writer writer = response.getWriter();
                        writer.write(content);
                    }
                    Engine.logEngine.debug("(RestApiServlet) Request successfully handled");
                } else {
                    Engine.logEngine.debug("(RestApiServlet) No matching operation for request");
                    super.service(request, response);
                }
            } else {
                Engine.logEngine.debug("(RestApiServlet) No mapping defined");
                super.service(request, response);
            }
        } catch (Exception e) {
            throw new ServletException(e);
        } finally {
            Requester requester = (Requester) request.getAttribute("convertigo.requester");
            if (requester != null) {
                Engine.logEngine.debug("(RestApiServlet) processRequestEnd, onFinally");
                processRequestEnd(request, requester);
                onFinally(request);
            } else {
                Engine.logEngine.debug("(RestApiServlet) terminate session");
                try {
                    HttpUtils.terminateSession(httpSession);
                } catch (Exception e) {
                    Engine.logEngine.warn("(RestApiServlet) unabled to terminate session", e);
                }
            }
            long t1 = System.currentTimeMillis();
            Engine.theApp.pluginsManager.fireHttpServletRequestEnd(request, t0, t1);
        }
    }
}
Also used : TASException(com.twinsoft.tas.TASException) ServletException(javax.servlet.ServletException) Requester(com.twinsoft.convertigo.engine.requesters.Requester) MaxCvsExceededException(com.twinsoft.convertigo.engine.MaxCvsExceededException) HttpServletRequestTwsWrapper(com.twinsoft.convertigo.engine.util.HttpServletRequestTwsWrapper) HashSet(java.util.HashSet) UrlMapper(com.twinsoft.convertigo.beans.core.UrlMapper) UrlMappingOperation(com.twinsoft.convertigo.beans.core.UrlMappingOperation) HttpSession(javax.servlet.http.HttpSession) ServletException(javax.servlet.ServletException) MaxCvsExceededException(com.twinsoft.convertigo.engine.MaxCvsExceededException) TASException(com.twinsoft.tas.TASException) IOException(java.io.IOException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) KeyExpiredException(com.twinsoft.convertigo.engine.KeyExpiredException) EngineException(com.twinsoft.convertigo.engine.EngineException) KeyExpiredException(com.twinsoft.convertigo.engine.KeyExpiredException) LogParameters(com.twinsoft.convertigo.engine.LogParameters) UrlAuthentication(com.twinsoft.convertigo.beans.core.UrlAuthentication) File(java.io.File) Writer(java.io.Writer)

Example 4 with LogParameters

use of com.twinsoft.convertigo.engine.LogParameters in project convertigo by convertigo.

the class FullSyncServlet method service.

@Override
protected void service(final HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    StringBuffer debug = new StringBuffer();
    HttpMethodType method;
    try {
        HttpUtils.checkCV(request);
        String corsOrigin = HttpUtils.applyCorsHeaders(request, response);
        if (corsOrigin != null) {
            debug.append("Added CORS header for: " + corsOrigin + "\n");
        }
        method = HttpMethodType.valueOf(request.getMethod());
        if (method == HttpMethodType.OPTIONS) {
            response.setStatus(HttpServletResponse.SC_NO_CONTENT);
            return;
        }
        if (method != HttpMethodType.HEAD) {
            HttpSessionListener.checkSession(request);
        }
    } catch (Throwable e) {
        throw new ServletException(e);
    }
    HttpSession httpSession = request.getSession();
    try {
        FullSyncClient fsClient = Engine.theApp.couchDbManager.getFullSyncClient();
        RequestParser requestParser = new RequestParser(request, fsClient.getPrefix());
        boolean isUtilsSession = "true".equals(httpSession.getAttribute("__isUtilsSession"));
        boolean isUtilsRequest = false;
        if (isUtilsSession || "_utils".equals(requestParser.special)) {
            Engine.authenticatedSessionManager.checkRoles(httpSession, Role.WEB_ADMIN, Role.FULLSYNC_CONFIG, Role.FULLSYNC_VIEW);
            httpSession.setAttribute("__isUtilsSession", "true");
            String referer = request.getHeader("Referer");
            isUtilsRequest = (referer != null && referer.contains("/_utils/") && !"_all_dbs".equals(requestParser.getSpecial()));
        } else {
            Engine.theApp.couchDbManager.checkRequest(requestParser.getPath(), requestParser.getSpecial(), requestParser.getDocId());
        }
        synchronized (httpSession) {
            Set<HttpServletRequest> set = SessionAttribute.fullSyncRequests.get(httpSession);
            if (set == null) {
                SessionAttribute.fullSyncRequests.set(httpSession, set = new HashSet<HttpServletRequest>());
            }
            set.add(request);
        }
        LogParameters logParameters = GenericUtils.cast(httpSession.getAttribute(FullSyncServlet.class.getCanonicalName()));
        if (logParameters == null) {
            httpSession.setAttribute(FullSyncServlet.class.getCanonicalName(), logParameters = new LogParameters());
            logParameters.put(mdcKeys.ContextID.toString().toLowerCase(), httpSession.getId());
        }
        Log4jHelper.mdcSet(logParameters);
        logParameters.put(mdcKeys.ClientIP.toString().toLowerCase(), request.getRemoteAddr());
        if (EnginePropertiesManager.getProperty(PropertyName.NET_REVERSE_DNS).equalsIgnoreCase("true")) {
            Log4jHelper.mdcPut(mdcKeys.ClientHostName, request.getRemoteHost());
        }
        String dbName = requestParser.getDbName();
        FullSyncAuthentication fsAuth = Engine.theApp.couchDbManager.getFullSyncAuthentication(request.getSession());
        if (fsAuth == null) {
            Log4jHelper.mdcPut(mdcKeys.User, "(anonymous)");
            debug.append("Anonymous user\n");
            Boolean allowAnonymous = null;
            for (String projectName : Engine.theApp.databaseObjectsManager.getAllProjectNamesList()) {
                try {
                    Project project = Engine.theApp.databaseObjectsManager.getOriginalProjectByName(projectName);
                    for (Connector connector : project.getConnectorsList()) {
                        if (connector instanceof FullSyncConnector) {
                            FullSyncConnector fullSyncConnector = (FullSyncConnector) connector;
                            if (fullSyncConnector.getDatabaseName().equals(dbName)) {
                                allowAnonymous = fullSyncConnector.getAnonymousReplication() == FullSyncAnonymousReplication.allow;
                                break;
                            }
                        }
                    }
                    if (allowAnonymous != null) {
                        break;
                    }
                } catch (Exception e) {
                // TODO: handle exception
                }
            }
            if (allowAnonymous == Boolean.FALSE) {
                throw new SecurityException("The '" + dbName + "' database deny pull synchronization for an anonymous session");
            }
        } else {
            Log4jHelper.mdcPut(mdcKeys.User, "'" + fsAuth.getAuthenticatedUser() + "'");
            debug.append("Authenticated user: ").append(fsAuth.getAuthenticatedUser()).append('\n').append("Authenticated groups: ").append(fsAuth.getGroups()).append('\n');
        }
        String url = Engine.theApp.couchDbManager.getFullSyncUrl() + requestParser.getPath();
        URIBuilder builder = new URIBuilder(url);
        String query = request.getQueryString();
        if (query != null) {
            try {
                // needed for PouchDB replication
                URI uri = URI.create(url + "?" + request.getQueryString());
                query = uri.getQuery();
            } catch (Exception e) {
                debug.append("parse query failed (" + e.getMessage() + "), use as it; query=" + query + "\n");
            }
            builder.setCustomQuery(query);
        }
        String special = requestParser.getSpecial();
        boolean isChanges = "_changes".equals(special);
        String version = fsClient.getServerVersion();
        if (isChanges && version.compareTo("2.") >= 0) {
            method = HttpMethodType.POST;
        }
        debug.append("dbName=" + dbName + " special=" + special + " couchdb=" + version + (requestParser.hasAttachment() ? " attachment=true" : "") + "\n");
        HttpRequestBase newRequest;
        switch(method) {
            case DELETE:
                if (isUtilsRequest) {
                    Engine.authenticatedSessionManager.checkRoles(httpSession, Role.WEB_ADMIN, Role.FULLSYNC_CONFIG);
                    if (requestParser.getDocId() == null && StringUtils.isNotBlank(requestParser.getDbName()) && DelegateServlet.canDelegate()) {
                        JSONObject instruction = new JSONObject();
                        JSONObject variables = new JSONObject();
                        try {
                            instruction.put("action", "deleteDatabase");
                            variables.put("db", fsClient.getPrefix() + requestParser.getDbName());
                            instruction.put("variables", variables);
                            JSONObject deleteResponse = DelegateServlet.delegate(instruction);
                            if (deleteResponse != null) {
                                JSONObject meta = CouchKey._c8oMeta.JSONObject(deleteResponse);
                                CouchKey._c8oMeta.remove(deleteResponse);
                                response.setStatus(meta.getInt("statusCode"));
                                JSONObject headers = meta.getJSONObject("headers");
                                for (java.util.Iterator<?> i = headers.keys(); i.hasNext(); ) {
                                    String key = (String) i.next();
                                    response.addHeader(key, headers.getString(key));
                                }
                                response.setCharacterEncoding("UTF-8");
                                try (Writer w = response.getWriter()) {
                                    w.write(deleteResponse.toString());
                                }
                                return;
                            }
                        } catch (Exception e) {
                        }
                    }
                    newRequest = new HttpDelete();
                } else {
                    // disabled to prevent db delete
                    throw new ServletException("Invalid HTTP method");
                }
                break;
            case GET:
                newRequest = new HttpGet();
                break;
            case HEAD:
                newRequest = new HttpHead();
                break;
            case OPTIONS:
                newRequest = new HttpOptions();
                break;
            case POST:
                if (isUtilsRequest) {
                    Engine.authenticatedSessionManager.checkRoles(httpSession, Role.WEB_ADMIN, Role.FULLSYNC_CONFIG);
                }
                newRequest = new HttpPost();
                break;
            case PUT:
                if (isUtilsRequest) {
                    Engine.authenticatedSessionManager.checkRoles(httpSession, Role.WEB_ADMIN, Role.FULLSYNC_CONFIG);
                }
                newRequest = new HttpPut();
                break;
            case TRACE:
                newRequest = new HttpTrace();
                break;
            default:
                throw new ServletException("Invalid HTTP method");
        }
        if (method.equals(HttpMethodType.POST) && "_bulk_docs".equals(special)) {
            int n = fsClient.getN();
            if (n > 1) {
                for (NameValuePair kv : builder.getQueryParams()) {
                    if ("w".equals(kv.getName())) {
                        n = 0;
                        break;
                    }
                }
                if (n > 1) {
                    builder.addParameter("w", Integer.toString(n));
                }
            }
        }
        URI uri = builder.build();
        newRequest.setURI(uri);
        debug.append(method.name() + " URI: " + uri.toString() + "\n");
        String requestStringEntity = null;
        HttpEntity httpEntity = null;
        JSONObject bulkDocsRequest = null;
        boolean isCBL = false;
        boolean isCBLiOS = false;
        {
            String agent = HeaderName.UserAgent.getHeader(request);
            isCBL = agent != null && agent.startsWith("CouchbaseLite/1.");
            if (isCBL) {
                isCBLiOS = agent.contains("iOS");
                isCBL = version != null && version.compareTo("1.7") >= 0;
            }
        }
        for (String headerName : Collections.list(request.getHeaderNames())) {
            if (!(HeaderName.TransferEncoding.is(headerName) || HeaderName.ContentLength.is(headerName) || HeaderName.UserAgent.is(headerName) || HeaderName.Expect.is(headerName) || HeaderName.Connection.is(headerName) || HeaderName.Host.is(headerName) || HeaderName.Cookie.is(headerName) || HeaderName.ContentEncoding.is(headerName) || HeaderName.Origin.is(headerName) || (isChanges && (HeaderName.IfNoneMatch.is(headerName) || HeaderName.IfModifiedSince.is(headerName) || HeaderName.CacheControl.is(headerName) || HeaderName.AcceptEncoding.is(headerName))))) {
                for (String headerValue : Collections.list(request.getHeaders(headerName))) {
                    debug.append("request Header: " + headerName + "=" + headerValue + "\n");
                    newRequest.addHeader(headerName, headerValue);
                }
            } else {
                debug.append("skip request Header: " + headerName + "=" + request.getHeader(headerName) + "\n");
            }
        }
        {
            Header authBasicHeader = fsClient.getAuthBasicHeader();
            if (authBasicHeader != null) {
                debug.append("request add BasicHeader");
                newRequest.addHeader(authBasicHeader);
            }
        }
        if (request.getInputStream() != null) {
            String reqContentType = request.getContentType();
            if (reqContentType != null && reqContentType.startsWith("multipart/related;")) {
                final MimeMultipart mp = new MimeMultipart(new ByteArrayDataSource(request.getInputStream(), reqContentType));
                final long[] size = { request.getIntHeader(HeaderName.ContentLength.value()) };
                final boolean chunked = size[0] == -1;
                int count = mp.getCount();
                debug.append("handle multipart/related: " + reqContentType + "; " + count + " parts; original size of " + size[0]);
                final File mpTmp;
                if (chunked) {
                    mpTmp = File.createTempFile("c8o", "mpTmp");
                    mpTmp.deleteOnExit();
                } else {
                    mpTmp = null;
                }
                try {
                    bulkDocsRequest = new JSONObject();
                    JSONArray bulkDocsArray = new JSONArray();
                    CouchKey.docs.put(bulkDocsRequest, bulkDocsArray);
                    for (int i = 0; i < count; i++) {
                        BodyPart part = mp.getBodyPart(i);
                        ContentTypeDecoder contentType = new ContentTypeDecoder(part.getContentType());
                        if (contentType.mimeType() == MimeType.Json) {
                            String charset = contentType.getCharset("UTF-8");
                            List<javax.mail.Header> headers = Collections.list(GenericUtils.<Enumeration<javax.mail.Header>>cast(part.getAllHeaders()));
                            byte[] buf = IOUtils.toByteArray(part.getInputStream());
                            if (!chunked) {
                                size[0] -= buf.length;
                            }
                            String json = new String(buf, charset);
                            try {
                                JSONObject docRequest = new JSONObject(json);
                                Engine.theApp.couchDbManager.handleDocRequest(dbName, docRequest, fsAuth);
                                bulkDocsArray.put(docRequest);
                                json = docRequest.toString();
                            } catch (JSONException e) {
                                debug.append("failed to parse [ " + e.getMessage() + "]: " + json);
                            }
                            part.setContent(buf = json.getBytes(charset), part.getContentType());
                            if (!chunked) {
                                size[0] += buf.length;
                            }
                            for (javax.mail.Header header : headers) {
                                String name = header.getName();
                                if (HeaderName.ContentLength.is(name)) {
                                    part.setHeader(name, Integer.toString(buf.length));
                                } else {
                                    part.setHeader(name, header.getValue());
                                }
                            }
                        }
                    }
                    if (chunked) {
                        try (FileOutputStream fos = new FileOutputStream(mpTmp)) {
                            mp.writeTo(fos);
                        }
                        size[0] = mpTmp.length();
                    }
                    debug.append("; new size of " + size[0] + "\n");
                    httpEntity = new AbstractHttpEntity() {

                        @Override
                        public void writeTo(OutputStream output) throws IOException {
                            if (chunked) {
                                try (FileInputStream fis = new FileInputStream(mpTmp)) {
                                    IOUtils.copyLarge(fis, output);
                                }
                            } else {
                                try {
                                    mp.writeTo(output);
                                } catch (MessagingException e) {
                                    new IOException(e);
                                }
                            }
                        }

                        @Override
                        public boolean isStreaming() {
                            return false;
                        }

                        @Override
                        public boolean isRepeatable() {
                            return true;
                        }

                        @Override
                        public long getContentLength() {
                            return size[0];
                        }

                        @Override
                        public InputStream getContent() throws IOException, IllegalStateException {
                            return null;
                        }
                    };
                } finally {
                    if (mpTmp != null) {
                        mpTmp.delete();
                    }
                }
            } else {
                InputStream is = null;
                try {
                    if ("gzip".equals(HeaderName.ContentEncoding.getHeader(request))) {
                        is = new GZIPInputStream(request.getInputStream());
                    } else {
                        is = request.getInputStream();
                    }
                    requestStringEntity = IOUtils.toString(is, "UTF-8");
                    debug.append("request Entity:\n" + requestStringEntity + "\n");
                } finally {
                    if (is != null) {
                        is.close();
                    }
                }
            }
        }
        boolean isNewStringEntity = false;
        if (method == HttpMethodType.POST && "_bulk_docs".equals(special)) {
            try {
                bulkDocsRequest = new JSONObject(requestStringEntity);
                Engine.theApp.couchDbManager.handleBulkDocsRequest(dbName, bulkDocsRequest, fsAuth);
                String newEntity = bulkDocsRequest.toString();
                if (!newEntity.equals(requestStringEntity)) {
                    requestStringEntity = newEntity;
                    isNewStringEntity = true;
                }
            } catch (JSONException e) {
                debug.append("failed to parse [ " + e.getMessage() + "]: " + requestStringEntity);
            }
        } else if (isChanges) {
            requestStringEntity = Engine.theApp.couchDbManager.handleChangesUri(dbName, newRequest, requestStringEntity, fsAuth);
            if (requestStringEntity != null) {
                debug.append("request new Entity:\n" + requestStringEntity + "\n");
            }
            uri = newRequest.getURI();
            debug.append("Changed to " + newRequest.getMethod() + " URI: " + uri + "\n");
        }
        if (!isChanges && newRequest instanceof HttpEntityEnclosingRequest) {
            HttpEntityEnclosingRequest entityRequest = ((HttpEntityEnclosingRequest) newRequest);
            if (entityRequest.getEntity() == null) {
                if (httpEntity != null) {
                // already exists
                } else if (requestStringEntity != null) {
                    if (isNewStringEntity) {
                        debug.append("request new Entity:\n" + requestStringEntity + "\n");
                    }
                    httpEntity = new StringEntity(requestStringEntity, "UTF-8");
                } else {
                    httpEntity = new InputStreamEntity(request.getInputStream());
                }
                entityRequest.setEntity(httpEntity);
            }
        }
        Map<AbstractFullSyncListener, JSONArray> listeners = Engine.theApp.couchDbManager.handleBulkDocsRequest(dbName, bulkDocsRequest);
        long requestTime = System.currentTimeMillis();
        CloseableHttpResponse newResponse = null;
        try {
            newResponse = httpClient.get().execute(newRequest);
        } catch (IOException e) {
            debug.append("retry request because: " + e.getMessage());
            newResponse = httpClient.get().execute(newRequest);
        }
        requestTime = System.currentTimeMillis() - requestTime;
        int code = newResponse.getStatusLine().getStatusCode();
        debug.append("response Code: " + code + " in " + requestTime + " ms\n");
        if (isCBLiOS && code == 400) {
            code = 500;
            debug.append("response changed Code to: " + code + " (for iOS CBL)\n");
        }
        response.setStatus(code);
        boolean isCblBulkGet = isCBL && version.compareTo("2.3.") < 0 && "_bulk_get".equals(special);
        if (!isCblBulkGet) {
            for (Header header : newResponse.getAllHeaders()) {
                if (isCBL && HeaderName.Server.is(header)) {
                    response.addHeader("Server", "Couchbase Sync Gateway/0.81");
                    debug.append("response Header: Server=Couchbase Sync Gateway/0.81\n");
                } else if (!(HeaderName.TransferEncoding.is(header) || HeaderName.ContentLength.is(header) || HeaderName.AccessControlAllowOrigin.is(header) || (isChanges && (HeaderName.ETag.is(header) || HeaderName.LastModified.is(header) || HeaderName.CacheControl.is(header))))) {
                    response.addHeader(header.getName(), header.getValue());
                    debug.append("response Header: " + header.getName() + "=" + header.getValue() + "\n");
                } else {
                    debug.append("skip response Header: " + header.getName() + "=" + header.getValue() + "\n");
                }
            }
            ServletUtils.applyCustomHeaders(request, response);
        }
        HttpEntity responseEntity = newResponse.getEntity();
        ContentTypeDecoder contentType = new ContentTypeDecoder(responseEntity == null || responseEntity.getContentType() == null ? "" : responseEntity.getContentType().getValue());
        debug.append("response ContentType charset=" + contentType.getCharset("n/a") + " mime=" + contentType.getMimeType() + "\n");
        OutputStream os = response.getOutputStream();
        String responseStringEntity = null;
        if (responseEntity != null) {
            // InputStream is = null;
            try (InputStream is = responseEntity.getContent()) {
                if (code >= 200 && code < 300 && !isUtilsRequest && contentType.mimeType().in(MimeType.Plain, MimeType.Json) && !"_design".equals(special) && !requestParser.hasAttachment() && ((isChanges && version.compareTo("2.") < 0) || "_bulk_get".equals(special) || "_all_docs".equals(special) || "_all_dbs".equals(special) || StringUtils.isNotEmpty(requestParser.getDocId()) || (bulkDocsRequest != null && listeners != null))) {
                    String charset = contentType.getCharset("UTF-8");
                    try (OutputStreamWriter writer = new OutputStreamWriter(os, charset);
                        BufferedInputStream bis = new BufferedInputStream(is)) {
                        if (isChanges) {
                            Engine.logCouchDbManager.info("(FullSyncServlet) Entering in continuous loop:\n" + debug);
                            try (BufferedReader br = new BufferedReader(new InputStreamReader(bis, charset))) {
                                Engine.theApp.couchDbManager.filterChanges(httpSession.getId(), dbName, uri, fsAuth, br, writer);
                            }
                        } else if (bulkDocsRequest != null) {
                            Engine.logCouchDbManager.info("(FullSyncServlet) Handle bulkDocsRequest:\n" + debug);
                            responseStringEntity = IOUtils.toString(bis, charset);
                            writer.write(responseStringEntity);
                            writer.flush();
                            if (listeners != null) {
                                Engine.theApp.couchDbManager.handleBulkDocsResponse(request, listeners, bulkDocsRequest, responseStringEntity);
                            }
                        } else if (isCblBulkGet) {
                            Engine.logCouchDbManager.info("(FullSyncServlet) Checking text response documents for CBL BulkGet:\n" + debug);
                            Engine.theApp.couchDbManager.checkCblBulkGetResponse(special, fsAuth, bis, charset, response);
                        } else {
                            Engine.logCouchDbManager.info("(FullSyncServlet) Checking response documents:\n" + debug);
                            Engine.theApp.couchDbManager.checkResponse(special, fsAuth, bis, charset, writer);
                        }
                    }
                } else if (code >= 200 && code < 300 && contentType.mimeType() == MimeType.MultiPartRelated && "_bulk_get".equals(special)) {
                    Engine.logCouchDbManager.info("(FullSyncServlet) Checking multipart response documents for CBL BulkGet:\n" + debug);
                    Engine.theApp.couchDbManager.checkCblBulkGetResponse(fsAuth, is, response);
                } else if (Pattern.matches(".*/bundle\\..*?\\.js", uri.getPath())) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(IOUtils.toString(is, "UTF-8").replace("json=function(e){var t", "json=function(e){e=e.replace('../../','../');var t"));
                    sb.append("\n$(\"#primary-navbar\").remove();");
                    byte[] b = sb.toString().getBytes("UTF-8");
                    HeaderName.ContentLength.addHeader(response, Integer.toString(b.length));
                    os.write(b);
                } else if (Pattern.matches(".*/styles\\..*?\\.css", uri.getPath())) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(IOUtils.toString(is, "UTF-8"));
                    sb.append("\n.closeMenu #dashboard { left: 0px; }");
                    sb.append("\n.closeMenu .pusher { padding-right: 0px; }");
                    sb.append("\nbutton.add-new-database-btn { display: none; }");
                    sb.append("\n#notification-center-btn { display: none; }");
                    sb.append("\na.fonticon-replicate { display: none; }");
                    sb.append("\n.faux-header__doc-header-dropdown-itemwrapper a.faux-header__doc-header-dropdown-item[href*=\"replication\"] { display: none; }\n");
                    byte[] b = sb.toString().getBytes("UTF-8");
                    HeaderName.ContentLength.addHeader(response, Integer.toString(b.length));
                    os.write(b);
                } else if (requestParser.docId == null && requestParser.special == null && !fsClient.getPrefix().isEmpty()) {
                    String content = IOUtils.toString(is, "UTF-8");
                    content = content.replace("\"db_name\":\"" + fsClient.getPrefix(), "\"db_name\":\"");
                    byte[] bytes = content.getBytes("UTF-8");
                    HeaderName.ContentLength.addHeader(response, Integer.toString(bytes.length));
                    debug.append("response Header: " + HeaderName.ContentLength.value() + "=" + bytes.length + "\n");
                    Engine.logCouchDbManager.info("(FullSyncServlet) Remove prefix from response:\n" + debug);
                    os.write(bytes);
                } else {
                    String contentLength = HeaderName.ContentLength.getHeader(newResponse);
                    if (contentLength != null) {
                        HeaderName.ContentLength.addHeader(response, contentLength);
                        debug.append("response Header: " + HeaderName.ContentLength.value() + "=" + contentLength + "\n");
                    }
                    Engine.logCouchDbManager.info("(FullSyncServlet) Copying response stream:\n" + debug);
                    StreamUtils.copyAutoFlush(is, os);
                }
            } finally {
                newResponse.close();
            }
        }
    } catch (SecurityException e) {
        Engine.logCouchDbManager.warn("(FullSyncServlet) Failed to process request due to a security exception:\n" + e.getMessage() + "\n" + debug);
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        HttpUtils.terminateNewSession(httpSession);
    } catch (EngineException e) {
        String message = e.getMessage();
        if (message != null && message.contains("anonymous user")) {
            Engine.logCouchDbManager.warn("(FullSyncServlet) Failed to process request: " + message + "\n" + debug);
        } else {
            Engine.logCouchDbManager.error("(FullSyncServlet) Failed to process request:\n" + debug, e);
        }
        HttpUtils.terminateNewSession(httpSession);
    } catch (Exception e) {
        if ("ClientAbortException".equals(e.getClass().getSimpleName())) {
            Engine.logCouchDbManager.info("(FullSyncServlet) Client disconnected:\n" + debug);
        } else {
            Engine.logCouchDbManager.error("(FullSyncServlet) Failed to process request:\n" + debug, e);
        }
        HttpUtils.terminateNewSession(httpSession);
    } finally {
        Log4jHelper.mdcClear();
        synchronized (httpSession) {
            Set<HttpServletRequest> set = SessionAttribute.fullSyncRequests.get(httpSession);
            if (set != null) {
                set.remove(request);
            }
        }
    }
}
Also used : HttpPost(org.apache.http.client.methods.HttpPost) BodyPart(javax.mail.BodyPart) HttpRequestBase(org.apache.http.client.methods.HttpRequestBase) HttpMethodType(com.twinsoft.convertigo.engine.enums.HttpMethodType) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) HttpOptions(org.apache.http.client.methods.HttpOptions) EngineException(com.twinsoft.convertigo.engine.EngineException) FullSyncClient(com.twinsoft.convertigo.engine.providers.couchdb.FullSyncClient) HttpPut(org.apache.http.client.methods.HttpPut) ServletException(javax.servlet.ServletException) HttpServletRequest(javax.servlet.http.HttpServletRequest) StringEntity(org.apache.http.entity.StringEntity) MimeMultipart(javax.mail.internet.MimeMultipart) BufferedInputStream(java.io.BufferedInputStream) HttpEntityEnclosingRequest(org.apache.http.HttpEntityEnclosingRequest) AbstractFullSyncListener(com.twinsoft.convertigo.beans.couchdb.AbstractFullSyncListener) CloseableHttpResponse(org.apache.http.client.methods.CloseableHttpResponse) ByteArrayDataSource(javax.mail.util.ByteArrayDataSource) HashSet(java.util.HashSet) FileInputStream(java.io.FileInputStream) FullSyncAuthentication(com.twinsoft.convertigo.engine.providers.couchdb.CouchDbManager.FullSyncAuthentication) URIBuilder(org.apache.http.client.utils.URIBuilder) Project(com.twinsoft.convertigo.beans.core.Project) LogParameters(com.twinsoft.convertigo.engine.LogParameters) JSONObject(org.codehaus.jettison.json.JSONObject) Header(org.apache.http.Header) FileOutputStream(java.io.FileOutputStream) File(java.io.File) Connector(com.twinsoft.convertigo.beans.core.Connector) FullSyncConnector(com.twinsoft.convertigo.beans.connectors.FullSyncConnector) HttpDelete(org.apache.http.client.methods.HttpDelete) HttpEntity(org.apache.http.HttpEntity) AbstractHttpEntity(org.apache.http.entity.AbstractHttpEntity) HttpGet(org.apache.http.client.methods.HttpGet) FullSyncConnector(com.twinsoft.convertigo.beans.connectors.FullSyncConnector) URI(java.net.URI) HttpHead(org.apache.http.client.methods.HttpHead) GZIPInputStream(java.util.zip.GZIPInputStream) AbstractHttpEntity(org.apache.http.entity.AbstractHttpEntity) NameValuePair(org.apache.http.NameValuePair) InputStreamReader(java.io.InputStreamReader) MessagingException(javax.mail.MessagingException) HttpSession(javax.servlet.http.HttpSession) GZIPInputStream(java.util.zip.GZIPInputStream) BufferedInputStream(java.io.BufferedInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) JSONArray(org.codehaus.jettison.json.JSONArray) JSONException(org.codehaus.jettison.json.JSONException) IOException(java.io.IOException) ServletException(javax.servlet.ServletException) MessagingException(javax.mail.MessagingException) EngineException(com.twinsoft.convertigo.engine.EngineException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) JSONException(org.codehaus.jettison.json.JSONException) InputStreamEntity(org.apache.http.entity.InputStreamEntity) HttpTrace(org.apache.http.client.methods.HttpTrace) BufferedReader(java.io.BufferedReader) ContentTypeDecoder(com.twinsoft.convertigo.engine.util.ContentTypeDecoder) OutputStreamWriter(java.io.OutputStreamWriter) Writer(java.io.Writer) OutputStreamWriter(java.io.OutputStreamWriter)

Example 5 with LogParameters

use of com.twinsoft.convertigo.engine.LogParameters in project convertigo by convertigo.

the class Log4jHelper method mdcPut.

public static void mdcPut(mdcKeys key, Object value) {
    LogParameters logParameters = (LogParameters) MDC.get("ContextualParameters");
    if (logParameters == null) {
        throw new IllegalStateException("ContextualParameters is null: call mdcInit() before!");
    }
    logParameters.put(key.toString().toLowerCase(), value);
}
Also used : LogParameters(com.twinsoft.convertigo.engine.LogParameters)

Aggregations

LogParameters (com.twinsoft.convertigo.engine.LogParameters)5 EngineException (com.twinsoft.convertigo.engine.EngineException)3 IOException (java.io.IOException)3 HttpSession (javax.servlet.http.HttpSession)3 File (java.io.File)2 Writer (java.io.Writer)2 HashSet (java.util.HashSet)2 ServletException (javax.servlet.ServletException)2 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)1 ConnectionException (com.twinsoft.convertigo.beans.connectors.ConnectionException)1 FullSyncConnector (com.twinsoft.convertigo.beans.connectors.FullSyncConnector)1 Connector (com.twinsoft.convertigo.beans.core.Connector)1 Project (com.twinsoft.convertigo.beans.core.Project)1 UrlAuthentication (com.twinsoft.convertigo.beans.core.UrlAuthentication)1 UrlMapper (com.twinsoft.convertigo.beans.core.UrlMapper)1 UrlMappingOperation (com.twinsoft.convertigo.beans.core.UrlMappingOperation)1 AbstractFullSyncListener (com.twinsoft.convertigo.beans.couchdb.AbstractFullSyncListener)1 KeyExpiredException (com.twinsoft.convertigo.engine.KeyExpiredException)1 MaxCvsExceededException (com.twinsoft.convertigo.engine.MaxCvsExceededException)1 HttpMethodType (com.twinsoft.convertigo.engine.enums.HttpMethodType)1