001/*
002 * Copyright 2015 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.jms.headers;
017
018import static com.google.common.base.Strings.isNullOrEmpty;
019import static java.util.stream.Collectors.joining;
020import static org.fcrepo.kernel.api.RdfLexicon.REPOSITORY_NAMESPACE;
021import static org.slf4j.LoggerFactory.getLogger;
022
023import java.io.IOException;
024import java.util.Set;
025import javax.jms.JMSException;
026import javax.jms.Message;
027
028import org.fcrepo.jms.observer.JMSEventMessageFactory;
029import org.fcrepo.kernel.api.observer.EventType;
030import org.fcrepo.kernel.api.observer.FedoraEvent;
031
032import org.slf4j.Logger;
033
034import com.fasterxml.jackson.databind.ObjectMapper;
035import com.fasterxml.jackson.databind.JsonNode;
036
037/**
038 * Generates JMS {@link Message}s composed entirely of headers, based entirely
039 * on information found in the {@link FedoraEvent} that triggers publication.
040 *
041 * @author ajs6f
042 * @author escowles
043 * @since Dec 2, 2013
044 */
045public class DefaultMessageFactory implements JMSEventMessageFactory {
046
047    public static final String JMS_NAMESPACE = "org.fcrepo.jms.";
048
049    public static final String TIMESTAMP_HEADER_NAME = JMS_NAMESPACE
050            + "timestamp";
051
052    public static final String IDENTIFIER_HEADER_NAME = JMS_NAMESPACE
053            + "identifier";
054
055    public static final String EVENT_TYPE_HEADER_NAME = JMS_NAMESPACE
056            + "eventType";
057
058    public static final String BASE_URL_HEADER_NAME = JMS_NAMESPACE
059            + "baseURL";
060
061    public static final String PROPERTIES_HEADER_NAME = JMS_NAMESPACE
062            + "properties";
063
064    public static final String USER_HEADER_NAME = JMS_NAMESPACE + "user";
065    public static final String USER_AGENT_HEADER_NAME = JMS_NAMESPACE + "userAgent";
066    public static final String EVENT_ID_HEADER_NAME = JMS_NAMESPACE + "eventID";
067
068    private String baseURL;
069    private String userAgent;
070
071    @Override
072    public Message getMessage(final FedoraEvent event,
073        final javax.jms.Session jmsSession) throws JMSException {
074
075        final Message message = jmsSession.createMessage();
076        message.setLongProperty(TIMESTAMP_HEADER_NAME, event.getDate());
077
078        // extract baseURL and userAgent from event UserData
079        try {
080            final String userdata = event.getUserData();
081            if (!isNullOrEmpty(userdata)) {
082                final ObjectMapper mapper = new ObjectMapper();
083                final JsonNode json = mapper.readTree(userdata);
084                String url = json.get("baseURL").asText();
085                while (url.endsWith("/")) {
086                    url = url.substring(0, url.length() - 1);
087                }
088                this.baseURL = url;
089                this.userAgent = json.get("userAgent").asText();
090                LOGGER.debug("MessageFactory baseURL: {}, userAgent: {}", baseURL, userAgent);
091
092            } else {
093                LOGGER.warn("MessageFactory event UserData is empty!");
094            }
095
096        } catch ( final IOException ex ) {
097            LOGGER.warn("Error setting baseURL or userAgent", ex);
098        }
099
100        message.setStringProperty(IDENTIFIER_HEADER_NAME, event.getPath());
101        message.setStringProperty(EVENT_TYPE_HEADER_NAME, getEventURIs(event
102                .getTypes()));
103        message.setStringProperty(BASE_URL_HEADER_NAME, baseURL);
104        message.setStringProperty(USER_HEADER_NAME, event.getUserID());
105        message.setStringProperty(USER_AGENT_HEADER_NAME, userAgent);
106        message.setStringProperty(PROPERTIES_HEADER_NAME, String.join(",", event.getProperties()));
107        message.setStringProperty(EVENT_ID_HEADER_NAME, event.getEventID());
108
109        LOGGER.trace("getMessage() returning: {}", message);
110        return message;
111    }
112
113    private static String getEventURIs(final Set<EventType> types) {
114        final String uris = types.stream()
115                                 .map(EventType::toString)
116                                 .map(REPOSITORY_NAMESPACE::concat)
117                                 .collect(joining(","));
118
119        LOGGER.debug("Constructed event type URIs: {}", uris);
120        return uris;
121    }
122
123    private static final Logger LOGGER = getLogger(DefaultMessageFactory.class);
124
125}