001/*
002 * Copyright 2016 DuraSpace, Inc.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.fcrepo.camel.reindexing;
017
018import static org.slf4j.LoggerFactory.getLogger;
019
020import java.util.HashSet;
021import java.util.Iterator;
022import java.util.Set;
023
024import com.fasterxml.jackson.core.JsonProcessingException;
025import com.fasterxml.jackson.databind.JsonNode;
026import com.fasterxml.jackson.databind.ObjectMapper;
027
028import org.apache.camel.Exchange;
029import org.apache.camel.Message;
030import org.apache.camel.Processor;
031import org.fcrepo.camel.FcrepoHeaders;
032import org.slf4j.Logger;
033
034/**
035 * A processor that converts the REST uri into the
036 * identifying path for an fcrepo node.
037 *
038 * This assumes that the `rest.prefix` value is stored
039 * in the CamelFcrepoRestPrefix header.
040 *
041 * @author Aaron Coburn
042 */
043public class RestProcessor implements Processor {
044
045    private static final Logger LOGGER = getLogger(RestProcessor.class);
046
047    private static final int BAD_REQUEST = 400;
048
049    /**
050     * Convert the incoming REST request into the correct
051     * Fcrepo header fields.
052     *
053     * @param exchange the current message exchange
054     */
055    public void process(final Exchange exchange) throws Exception {
056        final Message in = exchange.getIn();
057
058        final String path = in.getHeader(Exchange.HTTP_PATH, "", String.class);
059        final String contentType = in.getHeader(Exchange.CONTENT_TYPE, "", String.class);
060        final String body = in.getBody(String.class);
061        final Set<String> endpoints = new HashSet<>();
062
063        for (final String s : in.getHeader(ReindexingHeaders.RECIPIENTS, "", String.class).split(",")) {
064            endpoints.add(s.trim());
065        }
066
067        in.removeHeaders("CamelHttp*");
068        in.removeHeader("JMSCorrelationID");
069        in.setBody(null);
070
071        if (contentType.equals("application/json") && body != null && !body.trim().isEmpty()) {
072            final ObjectMapper mapper = new ObjectMapper();
073            try {
074                final JsonNode root = mapper.readTree(body);
075                final Iterator<JsonNode> ite = root.elements();
076                while (ite.hasNext()) {
077                    final JsonNode n = ite.next();
078                    endpoints.add(n.asText());
079                }
080            } catch (JsonProcessingException e) {
081                LOGGER.debug("Invalid JSON", e);
082                in.setHeader(Exchange.HTTP_RESPONSE_CODE, BAD_REQUEST);
083                in.setBody("Invalid JSON");
084            }
085        }
086
087        in.setHeader(FcrepoHeaders.FCREPO_IDENTIFIER, path);
088        in.setHeader(ReindexingHeaders.RECIPIENTS, String.join(",", endpoints));
089    }
090}