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

org.swisspush.gateleen.expansion.RecursiveExpansionRootHandler Maven / Gradle / Ivy

There is a newer version: 2.1.15
Show newest version
package org.swisspush.gateleen.expansion;

import org.swisspush.gateleen.core.util.*;
import org.swisspush.gateleen.core.util.ExpansionDeltaUtil.CollectionResourceContainer;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

import java.util.Set;

/**
 * Creates a root handler for the recursive HTTP GET.
 * 
 * @author https://github.com/ljucam [Mario Ljuca]
 */
public class RecursiveExpansionRootHandler extends RecursiveRootHandlerBase {
    private static final String ETAG_HEADER = "Etag";
    private static final String IF_NONE_MATCH_HEADER = "if-none-match";

    private final HttpServerRequest req;
    private final Buffer data;
    private final Set finalOriginalParams;

    /**
     * Creates an instance of the root handler for the
     * recursive HTTP GET.
     * 
     * @param req req
     * @param data data
     * @param finalOriginalParams finalOriginalParams
     */
    public RecursiveExpansionRootHandler(final HttpServerRequest req, Buffer data, Set finalOriginalParams) {
        this.req = req;
        this.data = data;
        this.finalOriginalParams = finalOriginalParams;
    }

    @Override
    public void handle(ResourceNode node) {
        if (log.isTraceEnabled()) {
            log.trace("parent handler called > {}", (node != null ? node.getNodeName() : "not found"));
        }

        /*
         * each recursive has one json object (container).
         * This container contains one json object, with the
         * name of the 'expanded' resource, aka the parent
         * or root.
         * {
         * "parent" :{ ... }
         * }
         */

        try {
            CollectionResourceContainer collection = ExpansionDeltaUtil.verifyCollectionResponse(req, data, finalOriginalParams);

            // pure data
            if (node.getObject() instanceof Buffer) {
                try {
                    node.setObject(new JsonObject(((Buffer) node.getObject()).toString("UTF-8")));
                } catch (Exception e) {
                    log.error("Error in result of sub resource '{}' Message: {}", node.getNodeName(), e.getMessage());
                    node.setObject(new ResourceCollectionException(e.getMessage()));
                }
            }

            checkIfError(node);

            JsonObject container = new JsonObject();
            if (node.getObject() instanceof JsonObject) {
                container.put(collection.getCollectionName(), (JsonObject) node.getObject());
            } else {
                container.put(collection.getCollectionName(), (JsonArray) node.getObject());
            }

            buildAndSendResult(req, container, node.geteTag());
        } catch (ResourceCollectionException exception) {
            handleResponseError(req, exception);
        } catch (Exception exception) {
            ResponseStatusCodeLogUtil.info(req, StatusCode.INTERNAL_SERVER_ERROR, RecursiveExpansionRootHandler.class);
            req.response().setStatusCode(StatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
            req.response().setStatusMessage(StatusCode.INTERNAL_SERVER_ERROR.getStatusMessage());
            req.response().end(exception.getMessage());
        }
    }

    /**
     * Creates the final result and sends it
     * as a response to the client.
     * 
     * @param req
     * @param responseObject
     * @param collectedeTags
     */
    private void buildAndSendResult(HttpServerRequest req, JsonObject responseObject, String collectedeTags) {
        String etagFromResources = HashCodeGenerator.createSHA256HashCode(collectedeTags);

        if (finalOriginalParams.contains("delta")) {
            req.response().headers().set("x-delta", "" + xDeltaResponseNumber);
        }

        JsonObject responseContent = makeCachedResponse(req, etagFromResources, responseObject);

        if (responseContent == null) {
            if (log.isTraceEnabled()) {
                log.trace("end response without content");
            }
            req.response().end();
        } else {
            if (log.isTraceEnabled()) {
                log.trace("end response with content");
            }
            req.response().end(responseObject.toString());
        }
    }

    /**
     * Creates a cached response. 
* If no cached data is found, the responseObject is * returned.
* If cached data is found, null is returned instead. * * @param req - original request * @param etagFromResources - new etags * @param responseObject - the response object * @return */ private JsonObject makeCachedResponse(HttpServerRequest req, String etagFromResources, JsonObject responseObject) { JsonObject result = responseObject; if (log.isTraceEnabled()) { log.trace("Header from request: {}", req.headers().get(IF_NONE_MATCH_HEADER)); log.trace("Header from response: {}", etagFromResources); } if (etagFromResources != null) { req.response().headers().add(ETAG_HEADER, etagFromResources); String ifNoneMatch = req.headers().get(IF_NONE_MATCH_HEADER); if (etagFromResources.equals(ifNoneMatch)) { ResponseStatusCodeLogUtil.debug(req, StatusCode.NOT_MODIFIED, RecursiveExpansionRootHandler.class); req.response().setStatusCode(StatusCode.NOT_MODIFIED.getStatusCode()); req.response().setStatusMessage(StatusCode.NOT_MODIFIED.getStatusMessage()); req.response().headers().add("Content-Length", "0"); req.response().setChunked(false); result = null; } else { ResponseStatusCodeLogUtil.debug(req, StatusCode.OK, RecursiveExpansionRootHandler.class); } } else { ResponseStatusCodeLogUtil.debug(req, StatusCode.OK, RecursiveExpansionRootHandler.class); } return result; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy