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

net.kut3.http.APIContext Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2019 Kut3Net.
 *
 * 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 net.kut3.http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.kut3.json.JsonArray;
import net.kut3.json.JsonObject;
import org.bson.Document;
import org.bson.json.JsonMode;
import org.bson.json.JsonWriterSettings;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 */
public final class APIContext {

    private static final Logger LOGGER = LoggerFactory.getLogger(APIContext.class);

    private static final String START_TIME = "startTime";
    private static final String END_TIME = "endTime";
    private static final String ERROR_DESCRIPTION = "errDesc";
    private static final String UTF8_CHARSET = "UTF-8";
    private static final String LOCATION_HEADER_LOG_FIELD = "locationHeader";
    private static final String ETAG_HEADER_LOG_FIELD = "etagHeader";
    private static final String WWW_AUTHENTICATE_HEADER_LOG_FIELD = "wwwAuthenticateHeader";
    private static final String HTTP_RESPONSE_CODE = "httpRespCode";
    private static final String RESPONSE_PAYLOAD = "respPayload";
    private static final String ERROR_PAYLOAD = "errPayload";
    private static final String RESPONSE_CODE = "respCode";
    private static final String CREDENTAIL = "credentail";

    private static APILogger API_LOGGER;
    private static boolean IS_DEBUG;

    private final HttpServletRequest req;
    private final HttpServletResponse resp;
    private final JsonObject logBuilder;

    private volatile boolean readPayload = false;
    
    private JsonObject payloadAsJsonObj;
    private Document payloadAsDoc;
    private JsonArray payloadAsJsonArray;
    private String rawPayload;
    private String[] extraPaths = null;

    /**
     *
     * @param req The current {@link HttpServletRequest}
     * @param resp The current {@link HttpServletResponse}
     */
    APIContext(HttpServletRequest req, HttpServletResponse resp) {
        this.req = req;
        this.resp = resp;
        
        this.logBuilder = new JsonObject()
                .set(START_TIME, System.currentTimeMillis());
    }

    /**
     *
     * @param apiLogger Logger to write log data
     */
    public synchronized static final void registerLogger(APILogger apiLogger) {
        if (null != API_LOGGER) {
            throw new IllegalStateException("API_LOGGER already set");
        }

        API_LOGGER = apiLogger;
    }

    /**
     *
     */
    public static final void enableDebug() {
        IS_DEBUG = true;
    }

    /**
     *
     * @return The value of the X-Request-ID header
     */
    public final String reqId() {
        return this.req.getHeader(HttpHeader.X_REQUEST_ID);
    }

    /**
     * Add data to log builder
     *
     * @param name Name of the field
     * @param value Value of the field
     * @return The current object
     */
    public final APIContext log(String name, String value) {
        this.logBuilder.set(name, value);
        return this;
    }

    /**
     * Add data to log builder
     *
     * @param name Name of the field
     * @param value Value of the field
     * @return The current object
     */
    public final APIContext log(String name, int value) {
        this.logBuilder.set(name, value);
        return this;
    }

    /**
     * Add data to log builder
     *
     * @param name Name of the field
     * @param value Value of the field
     * @return The current object
     */
    public final APIContext log(String name, long value) {
        this.logBuilder.set(name, value);
        return this;
    }

    /**
     * Add data to log builder
     *
     * @param name Name of the field
     * @param value Value of the field
     * @return The current object
     */
    public final APIContext log(String name, boolean value) {
        this.logBuilder.set(name, value);
        return this;
    }

    /**
     * Add data to log builder
     *
     * @param name Name of the field
     * @param value Value of the field
     * @return The current object
     */
    public final APIContext log(String name, JsonObject value) {
        this.logBuilder.set(name, value);
        return this;
    }

    /**
     * Add data to log builder
     *
     * @param name Name of the field
     * @param value Value of the field
     * @return The current object
     */
    public final APIContext log(String name, JsonArray value) {
        this.logBuilder.set(name, value);
        return this;
    }

    /**
     *
     * @param errDesc Error description
     * @return The current object
     */
    public final APIContext logErr(String errDesc) {
        this.logBuilder.set(ERROR_DESCRIPTION, errDesc);
        return this;
    }

    /**
     *
     * @param paramName Name of the parameter
     * @return The current object
     */
    public final APIContext logParam(String paramName) {
        this.logBuilder.set(paramName, this.req.getParameter(paramName));
        return this;
    }

    /**
     *
     * @return The request path
     */
    public final String reqPath() {
        return this.req.getRequestURI().substring(1);
    }

    /**
     *
     * @return The path info
     */
    public final String[] pathInfo() {
        if (null == this.extraPaths) {
            String pathInfo = this.req.getPathInfo();
            if (null == pathInfo) {
                return null;
            }

            if (pathInfo.length() == 1) {
                this.extraPaths = new String[0];
            } else {
                this.extraPaths = pathInfo.substring(1).split("/");
            }
        }

        return this.extraPaths;
    }

    /**
     *
     * @return The request payload as a JsonObject
     */
    public final JsonObject reqPayloadAsJsonObject() {
        if (null == this.payloadAsJsonObj) {
            String tmp = this.rawReqPayload();
            if (null == tmp) {
                return null;
            }

            this.payloadAsJsonObj = JsonObject.parse(tmp);
        }

        return this.payloadAsJsonObj;
    }

    /**
     *
     * @return The request payload as a Document
     */
    public final Document reqPayloadAsDoc() {
        if (null == this.payloadAsJsonObj) {
            String tmp = this.rawReqPayload();
            if (null == tmp) {
                return null;
            }

            this.payloadAsDoc = Document.parse(tmp);
        }

        return this.payloadAsDoc;
    }

    /**
     *
     * @return The request payload as a JsonArray
     */
    public final JsonArray reqPayloadAsJsonArray() {
        if (null == this.payloadAsJsonArray) {
            String tmp = this.rawReqPayload();
            if (null == tmp) {
                return null;
            }

            this.payloadAsJsonArray = JsonArray.parse(tmp);
        }

        return this.payloadAsJsonArray;
    }

    /**
     * 200
     *
     * @param respPayload Response payload
     */
    public final void ok(String respPayload) {
        this.resp.setStatus(HttpServletResponse.SC_OK);
        this.resp.setCharacterEncoding(UTF8_CHARSET);
        try {
            this.resp.getWriter().print(respPayload);

            if (IS_DEBUG) {
                this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_OK)
                        .set(RESPONSE_PAYLOAD, respPayload);
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * 200
     *
     * @param respPayload Response payload
     * @return The current object
     */
    public final APIContext ok(JsonObject respPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.ok(respPayload.toString());
        return this;
    }

    /**
     * 200
     *
     * @param respPayload Response payload
     * @return The current object
     */
    public final APIContext ok(Document respPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.ok(this.docToStr(respPayload));
        return this;
    }

    /**
     * 200
     *
     * @param respPayload Response payload
     * @return The current object
     */
    public final APIContext ok(JsonArray respPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.ok(respPayload.toString());
        return this;
    }

    /**
     * 201
     *
     * @param location The location points to the new created entity
     */
    public final void created(String location) {
        this.resp.setStatus(HttpServletResponse.SC_CREATED);
        this.resp.setHeader(HttpHeader.LOCATION, location);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_CREATED)
                    .set(LOCATION_HEADER_LOG_FIELD, location);
        }
    }

    /**
     * 201
     *
     * @param location The location points to the new created entity
     * @param etag The entity tag of the new created entity
     */
    public final void created(String location, String etag) {
        this.resp.setStatus(HttpServletResponse.SC_CREATED);
        this.resp.setHeader(HttpHeader.LOCATION, location);
        this.resp.setHeader(HttpHeader.ETAG, etag);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_CREATED)
                    .set(LOCATION_HEADER_LOG_FIELD, location)
                    .set(ETAG_HEADER_LOG_FIELD, etag);
        }
    }

    /**
     * 202
     */
    public final void accepted() {
        this.resp.setStatus(HttpServletResponse.SC_ACCEPTED);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_ACCEPTED);
        }
    }

    /**
     * 204
     */
    public final void noContent() {
        this.resp.setStatus(HttpServletResponse.SC_NO_CONTENT);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_NO_CONTENT);
        }
    }

    /**
     * 204
     *
     * @param etag The entity tag of the new created entity or updated entity
     */
    public final void noContent(String etag) {
        this.resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
        this.resp.setHeader(HttpHeader.ETAG, etag);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_NO_CONTENT)
                    .set(ETAG_HEADER_LOG_FIELD, etag);
        }
    }

    /**
     * 302
     *
     * @param location The location points to the found entity
     */
    public final void found(String location) {
        this.resp.setStatus(HttpServletResponse.SC_FOUND);
        this.resp.setHeader(HttpHeader.LOCATION, location);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_FOUND)
                    .set(LOCATION_HEADER_LOG_FIELD, location);
        }
    }

    /**
     * 400
     *
     * @param errDesc The error description for logging
     * @throws java.io.IOException Write response error
     */
    public final void badRequest(String errDesc) throws IOException {
        this.logBuilder.set(ERROR_DESCRIPTION, errDesc);
        this.resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        this.resp.setCharacterEncoding(UTF8_CHARSET);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_BAD_REQUEST);
        }
    }

    /**
     * 401
     *
     * @param wwwAuthenticateHeader The value of WWW-Authenticate header
     * @param errPayload The error payload
     */
    public final void unauthorized(String wwwAuthenticateHeader,
            String errPayload) {

        this.resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        this.resp.setHeader(HttpHeader.WWW_AUTHENTICATE, wwwAuthenticateHeader);
        this.resp.setContentType(UTF8_CHARSET);

        try {
            this.resp.getWriter().print(errPayload);

            if (IS_DEBUG) {
                this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_UNAUTHORIZED)
                        .set(WWW_AUTHENTICATE_HEADER_LOG_FIELD, wwwAuthenticateHeader)
                        .set(ERROR_PAYLOAD, errPayload);
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * 401
     *
     * @param wwwAuthenticateHeader The value of WWW-Authenticate header
     * @param errPayload The error payload
     * @return The current object
     */
    public final APIContext unauthorized(String wwwAuthenticateHeader,
            Document errPayload) {

        this.resp.setContentType(ContentType.JSON);
        this.unauthorized(wwwAuthenticateHeader, this.docToStr(errPayload));
        return this;
    }

    /**
     * 401
     *
     * @param wwwAuthenticateHeader The value of WWW-Authenticate header
     * @param errPayload The error payload
     * @return The current object
     */
    public final APIContext unauthorized(String wwwAuthenticateHeader,
            JsonObject errPayload) {

        this.resp.setContentType(ContentType.JSON);
        this.unauthorized(wwwAuthenticateHeader, errPayload.toString());
        return this;
    }

    /**
     * 401
     *
     * @param wwwAuthenticateHeader The value of WWW-Authenticate header
     */
    public final void unauthorized(String wwwAuthenticateHeader) {
        this.resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        this.resp.setHeader(HttpHeader.WWW_AUTHENTICATE, wwwAuthenticateHeader);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_UNAUTHORIZED)
                    .set(WWW_AUTHENTICATE_HEADER_LOG_FIELD, wwwAuthenticateHeader);
        }
    }

    /**
     * 403
     *
     * @param errDesc The error description
     */
    public final void forbidden(String errDesc) {
        this.logBuilder.set(ERROR_DESCRIPTION, errDesc);
        this.resp.setStatus(HttpServletResponse.SC_FORBIDDEN);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_FORBIDDEN);
        }
    }

    /**
     * 404
     *
     * @param errPayload The error payload
     */
    public final void notFound(String errPayload) {
        this.resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
        this.resp.setCharacterEncoding(UTF8_CHARSET);

        try {
            this.resp.getWriter().print(errPayload);

            if (IS_DEBUG) {
                this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_NOT_FOUND)
                        .set(ERROR_PAYLOAD, errPayload);
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * 404
     *
     * @param errPayload The error payload
     * @return The current object
     */
    public final APIContext notFound(Document errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.notFound(this.docToStr(errPayload));
        return this;
    }

    /**
     * 404
     *
     * @param errPayload The error payload
     * @return The current object
     */
    public final APIContext notFound(JsonObject errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.notFound(errPayload.toString());
        return this;
    }

    /**
     * 404
     */
    public final void notFound() {
        this.resp.setStatus(HttpServletResponse.SC_NOT_FOUND);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_NOT_FOUND);
        }
    }

    /**
     * 409
     *
     * @param errPayload The error payload
     */
    public final void conflict(String errPayload) {
        this.resp.setStatus(HttpServletResponse.SC_CONFLICT);
        this.resp.setCharacterEncoding(UTF8_CHARSET);

        try {
            this.resp.getWriter().print(errPayload);

            if (IS_DEBUG) {
                this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_CONFLICT)
                        .set(ERROR_PAYLOAD, errPayload);
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * 409
     *
     * @param errPayload The error payload
     * @return The current object
     */
    public final APIContext conflict(Document errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.conflict(this.docToStr(errPayload));
        return this;
    }

    /**
     * 409
     *
     * @param errPayload The error payload
     * @return The current object
     */
    public final APIContext conflict(JsonObject errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.conflict(errPayload.toString());
        return this;
    }

    /**
     * 410
     *
     * @param errPayload The error payload
     */
    public final void gone(String errPayload) {
        this.resp.setStatus(HttpServletResponse.SC_GONE);
        this.resp.setCharacterEncoding(UTF8_CHARSET);

        try {
            this.resp.getWriter().print(errPayload);

            if (IS_DEBUG) {
                this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_GONE)
                        .set(ERROR_PAYLOAD, errPayload);
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * 410
     *
     * @param errPayload The error payload
     * @return The current object
     */
    public final APIContext gone(JsonObject errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.gone(errPayload.toString());
        return this;
    }

    /**
     * 410
     *
     * @param errPayload The error payload
     */
    public final void preconditionFailed(String errPayload) {
        this.resp.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED);
        this.resp.setCharacterEncoding(UTF8_CHARSET);

        try {
            this.resp.getWriter().print(errPayload);

            if (IS_DEBUG) {
                this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_PRECONDITION_FAILED)
                        .set(ERROR_PAYLOAD, errPayload);
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * 410
     *
     * @param errPayload The error payload
     * @return The current object
     */
    public final APIContext preconditionFailed(Document errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.preconditionFailed(errPayload.toString());
        return this;
    }

    /**
     * 410
     *
     * @param errPayload The error payload
     * @return The current object
     */
    public final APIContext preconditionFailed(JsonObject errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.preconditionFailed(errPayload.toString());
        return this;
    }

    /**
     * 412
     */
    public final void preconditionFailed() {
        this.resp.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_PRECONDITION_FAILED);
        }
    }

    /**
     * 415
     *
     * @param errPayload The error payload
     */
    public final void unsupportedMediaType(String errPayload) {
        this.resp.setStatus(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
        this.resp.setCharacterEncoding(UTF8_CHARSET);

        try {
            this.resp.getWriter().print(errPayload);

            if (IS_DEBUG) {
                this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE)
                        .set(ERROR_PAYLOAD, errPayload);
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * 415
     *
     * @param errPayload The error payload
     * @return The current object
     */
    public final APIContext unsupportedMediaType(Document errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.unsupportedMediaType(this.docToStr(errPayload));
        return this;
    }

    /**
     * 415
     *
     * @param errPayload The error payload
     * @return The current object
     */
    public final APIContext unsupportedMediaType(JsonObject errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.unsupportedMediaType(errPayload.toString());
        return this;
    }

    /**
     * 415
     */
    public final void unsupportedMediaType() {
        this.resp.setStatus(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
        }
    }

    /**
     * 422
     *
     * @param errDesc The error description
     * @param errPayload The error payload
     * @throws java.io.IOException Write response error
     * @see 
     * https://tools.ietf.org/html/rfc4918#section-11.2
     */
    public final void unprocessableEntity(String errDesc, String errPayload)
            throws IOException {

        this.logBuilder.set(ERROR_DESCRIPTION, errDesc);

        this.resp.setStatus(422);
        this.resp.setCharacterEncoding(UTF8_CHARSET);
        this.resp.getWriter().print(errPayload);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, 422)
                    .set(ERROR_PAYLOAD, errPayload);
        }
    }

    /**
     * 422
     *
     * @param errPayload The error payload
     * @see 
     * https://tools.ietf.org/html/rfc4918#section-11.2
     * @return The current object
     */
    public final APIContext unprocessableEntity(JsonObject errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.unprocessableEntity(errPayload.toString());
        return this;
    }

    /**
     * 422
     *
     * @param errPayload The error payload
     * @see 
     * https://tools.ietf.org/html/rfc4918#section-11.2
     * @return The current object
     */
    public final APIContext unprocessableEntity(Document errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.unprocessableEntity(this.docToStr(errPayload));
        return this;
    }

    /**
     * 422
     *
     * @param errDesc The error description
     * @see 
     * https://tools.ietf.org/html/rfc4918#section-11.2
     */
    public final void unprocessableEntity(String errDesc) {
        this.logBuilder.set(ERROR_DESCRIPTION, errDesc);
        this.resp.setStatus(422);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, 422);
        }
    }

    /**
     * 423
     *
     * @param errPayload The error payload
     * @see 
     * https://tools.ietf.org/html/rfc4918#section-11.3
     */
    public final void locked(String errPayload) {
        this.resp.setStatus(423);
        this.resp.setCharacterEncoding(UTF8_CHARSET);

        try {
            this.resp.getWriter().print(errPayload);

            if (IS_DEBUG) {
                this.logBuilder.set(HTTP_RESPONSE_CODE, 423)
                        .set(ERROR_PAYLOAD, errPayload);
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * 423
     *
     * @param errPayload The error payload
     * @see 
     * https://tools.ietf.org/html/rfc4918#section-11.3
     * @return The current object
     */
    public final APIContext locked(Document errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.locked(this.docToStr(errPayload));
        return this;
    }

    /**
     * 423
     *
     * @param errPayload The error payload
     * @see 
     * https://tools.ietf.org/html/rfc4918#section-11.3
     * @return The current object
     */
    public final APIContext locked(JsonObject errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.locked(errPayload.toString());
        return this;
    }

    /**
     * 423
     *
     * @see 
     * https://tools.ietf.org/html/rfc4918#section-11.3
     */
    public final void locked() {
        this.resp.setStatus(423);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, 422);
        }
    }

    /**
     * 429
     *
     * @param errPayload The error payload
     * @see 
     * https://tools.ietf.org/html/rfc6585#section-4
     */
    public final void tooManyRequests(String errPayload) {
        this.resp.setStatus(429);
        this.resp.setCharacterEncoding(UTF8_CHARSET);

        try {
            this.resp.getWriter().print(errPayload);

            if (IS_DEBUG) {
                this.logBuilder.set(HTTP_RESPONSE_CODE, 429)
                        .set(ERROR_PAYLOAD, errPayload);
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * 429
     *
     * @param errPayload The error payload
     * @see 
     * https://tools.ietf.org/html/rfc6585#section-4
     * @return The current object
     */
    public final APIContext tooManyRequests(Document errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.tooManyRequests(this.docToStr(errPayload));
        return this;
    }

    /**
     * 429
     *
     * @param errPayload The error payload
     * @see 
     * https://tools.ietf.org/html/rfc6585#section-4
     * @return The current object
     */
    public final APIContext tooManyRequests(JsonObject errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.tooManyRequests(errPayload.toString());
        return this;
    }

    /**
     * 429
     *
     * @see 
     * https://tools.ietf.org/html/rfc6585#section-4
     */
    public final void tooManyRequests() {
        this.resp.setStatus(429);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, 429);
        }
    }

    /**
     * 500
     *
     * @param errPayload The error payload
     */
    public final void internalServerError(String errPayload) {
        this.resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        this.resp.setCharacterEncoding(UTF8_CHARSET);

        try {
            this.resp.getWriter().print(errPayload);

            if (IS_DEBUG) {
                this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_INTERNAL_SERVER_ERROR)
                        .set(ERROR_PAYLOAD, errPayload);
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * 500
     *
     * @param errPayload The error payload
     * @return The current object
     */
    public final APIContext internalServerError(Document errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.internalServerError(this.docToStr(errPayload));
        return this;
    }

    /**
     * 500
     *
     * @param errPayload The error payload
     * @return The current object
     */
    public final APIContext internalServerError(JsonObject errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.internalServerError(errPayload.toString());
        return this;
    }

    /**
     * 500
     */
    public final void internalServerError() {
        this.resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 503
     *
     * @param errPayload The error payload
     */
    public final void serviceUnavailable(String errPayload) {
        this.resp.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
        this.resp.setCharacterEncoding(UTF8_CHARSET);

        try {
            this.resp.getWriter().print(errPayload);

            if (IS_DEBUG) {
                this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_SERVICE_UNAVAILABLE)
                        .set(ERROR_PAYLOAD, errPayload);
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * 503
     *
     * @param errPayload The error payload
     * @return The current object
     */
    public final APIContext serviceUnavailable(Document errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.serviceUnavailable(this.docToStr(errPayload));
        return this;
    }

    /**
     * 503
     *
     * @param errPayload The error payload
     * @return The current object
     */
    public final APIContext serviceUnavailable(JsonObject errPayload) {
        this.resp.setContentType(ContentType.JSON);
        this.serviceUnavailable(errPayload.toString());
        return this;
    }

    /**
     * 503
     */
    public final void serviceUnavailable() {
        this.resp.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);

        if (IS_DEBUG) {
            this.logBuilder.set(HTTP_RESPONSE_CODE, HttpServletResponse.SC_SERVICE_UNAVAILABLE);
        }
    }

    /**
     *
     * @return The HTTP request method
     */
    public final String httpMethod() {
        return this.req.getMethod();
    }

    /**
     *
     * @return The current HTTP response code
     */
    public final int httpRespCode() {
        return this.resp.getStatus();
    }

    /**
     *
     * @param headerName Name of the header
     * @return Value of the header or null
     */
    public final String header(String headerName) {
        return this.req.getHeader(headerName);
    }

    /**
     *
     * @param paramName Name of the parameter
     * @return Value of the parameter or null
     */
    public final String param(String paramName) {
        return this.req.getParameter(paramName);
    }

    /**
     *
     * @param respCode The response code to log
     */
    public final void respCode(String respCode) {
        this.logBuilder.set(RESPONSE_CODE, respCode);
    }

    /**
     *
     */
    final void log() {
        if (null != API_LOGGER) {
            API_LOGGER.write(this.logBuilder
                    .set(END_TIME, System.currentTimeMillis())
                    .toString()
            );
        } else {
            LOGGER.info(this.logBuilder
                    .set(END_TIME, System.currentTimeMillis())
                    .toString()
            );
        }
    }

    /**
     * 405
     */
    final void methodNotAllowed() {
        this.resp.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
    }
    
    /**
     * 
     * @param name Name of the attr
     * @param value Value of the attr
     * @return The current object
     */
    public APIContext attr(String name, ObjectId value) {
        this.req.setAttribute(name, value);
        return this;
    }
    
    /**
     * 
     * @param name Name of the attr
     * @param value Value of the attr
     * @return The current object
     */
    public APIContext attr(String name, byte[] value) {
        this.req.setAttribute(name, value);
        return this;
    }
    
    /**
     * 
     * @param name Name of the attr
     * @return Value of the attr or null
     */
    public ObjectId attrAsObjId(String name) {
        return (ObjectId) this.req.getAttribute(name);
    }
    
    /**
     * 
     * @param name Name of the attr
     * @return Value of the attr or null
     */
    public byte[] attrAsBytesArr(String name) {
        return (byte[]) this.req.getAttribute(name);
    }

    /**
     *
     * @param credential The credential of the current request
     * @return The current object
     */
    public APIContext credential(Credential credential) {
        this.req.setAttribute(CREDENTAIL, credential);
        return this;
    }

    /**
     *
     * @return A {@link Credential} instance
     */
    public Credential credentail() {
        return (Credential) this.req.getAttribute(CREDENTAIL);
    }

    /**
     *
     * @param  The implementation type
     * @param clazz Class of the Credential implementation
     * @return The Credential object
     */
    public  T credential(Class clazz) {
        Object o = this.req.getAttribute(CREDENTAIL);
        if (null == o) {
            return null;
        }

        return clazz.cast(o);
    }

    /**
     *
     * @return The request payload as a string
     */
    private synchronized String rawReqPayload() {
        if (!this.readPayload) {
            this.readPayload = true;

            StringBuilder sb = new StringBuilder();
            try (BufferedReader reader
                    = new BufferedReader(new InputStreamReader(this.req.getInputStream(),
                            UTF8_CHARSET))) {

                String line;
                while (null != (line = reader.readLine())) {
                    sb.append(line);
                }

                if (sb.length() > 0) {
                    this.rawPayload = sb.toString();
                }

            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }

        return this.rawPayload;
    }

    private String docToStr(Document doc) {
        return doc.toJson(JsonWriterSettings.builder()
                .indent(false)
                .newLineCharacters("")
                .outputMode(JsonMode.STRICT)
                .build());
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy