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