001/*
002 * The contents of this file are subject to the license and copyright
003 * detailed in the LICENSE and NOTICE files at the root of the source
004 * tree.
005 */
006package org.fcrepo.camel.reindexing;
007
008import static java.lang.String.join;
009import static org.apache.camel.Exchange.CONTENT_TYPE;
010import static org.apache.camel.Exchange.HTTP_RESPONSE_CODE;
011import static org.fcrepo.camel.reindexing.ReindexingHeaders.REINDEXING_RECIPIENTS;
012import static org.slf4j.LoggerFactory.getLogger;
013
014import java.util.HashSet;
015import java.util.Iterator;
016import java.util.Set;
017
018import com.fasterxml.jackson.core.JsonProcessingException;
019import com.fasterxml.jackson.databind.JsonNode;
020import com.fasterxml.jackson.databind.ObjectMapper;
021
022import org.apache.camel.Exchange;
023import org.apache.camel.Message;
024import org.apache.camel.Processor;
025import org.slf4j.Logger;
026
027/**
028 * A processor that converts the REST uri into the
029 * identifying path for an fcrepo node.
030 *
031 * This assumes that the `rest.prefix` value is stored
032 * in the CamelFcrepoRestPrefix header.
033 *
034 * @author Aaron Coburn
035 */
036public class RestProcessor implements Processor {
037
038    private static final Logger LOGGER = getLogger(RestProcessor.class);
039
040    private static final int BAD_REQUEST = 400;
041
042    private static final ObjectMapper MAPPER = new ObjectMapper();
043
044    /**
045     * Convert the incoming REST request into the correct
046     * Fcrepo header fields.
047     *
048     * @param exchange the current message exchange
049     */
050    public void process(final Exchange exchange) throws Exception {
051        final Message in = exchange.getIn();
052
053        final String contentType = in.getHeader(CONTENT_TYPE, "", String.class);
054        final String body = in.getBody(String.class);
055        final Set<String> endpoints = new HashSet<>();
056
057        for (final String s : in.getHeader(REINDEXING_RECIPIENTS, "", String.class).split(",")) {
058            endpoints.add(s.trim());
059        }
060
061        if (contentType.equals("application/json") && body != null && !body.trim().isEmpty()) {
062            try {
063                final JsonNode root = MAPPER.readTree(body);
064                final Iterator<JsonNode> ite = root.elements();
065                while (ite.hasNext()) {
066                    final JsonNode n = ite.next();
067                    endpoints.add(n.asText());
068                }
069            } catch (JsonProcessingException e) {
070                LOGGER.debug("Invalid JSON", e);
071                in.setHeader(HTTP_RESPONSE_CODE, BAD_REQUEST);
072                in.setBody("Invalid JSON");
073            }
074        }
075        in.setHeader(REINDEXING_RECIPIENTS, join(",", endpoints));
076    }
077}