/*
* Copyright (c) 2013 Lockheed Martin Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.eurekastreams.server.action.execution.notification.notifier;
import java.io.StringWriter;
import java.net.URI;
import java.net.URLDecoder;
import java.util.Collection;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.eurekastreams.commons.server.UserActionRequest;
import org.eurekastreams.server.domain.NotificationType;
import org.eurekastreams.server.domain.Person;
import org.eurekastreams.server.persistence.mappers.DomainMapper;
import org.eurekastreams.server.search.modelview.PersonModelView;
/**
* Notifier for REST endpoints, takes a template and sends it to a REST endpoint.
*
*/
public class JSONNotifier implements Notifier
{
/** Apache Velocity templating engine. */
private final VelocityEngine velocityEngine;
/** Global context for Apache Velocity templating engine. (Holds system-wide properties.) */
private final Context velocityGlobalContext;
/** Message templates by notification type. */
private final Map<NotificationType, String> templates;
/** Templates detailing where to send the rest notifications. */
private final Map<String, String> endpointTemplates;
/** Lookup the recipient of the notification. */
private final DomainMapper<Long, Person> placeholderPersonMapper;
/** Logs. */
private final Log logger = LogFactory.getLog(JSONNotifier.class);
/** Object used to send http requests. */
private final HttpClientBuilder httpClientBuilder;
/**
* Constructor.
* @param inVelocityEngine
* Velocity engine used for templating
* @param inVelocityGlobalContext
* Global context for Apache Velocity templating engine.
* @param inTemplates
* Message templates by notification type.
* @param inEndpointTemplates
* The templates containing the endpoints where the REST calls will be made.
* @param inPlaceholderPersonMapper
* The mapper to lookup users.
* @param inHttpClientBuilder
* Used to build an http client to post to endpoint
*/
public JSONNotifier(final VelocityEngine inVelocityEngine,
final Context inVelocityGlobalContext,
final Map<NotificationType, String> inTemplates,
final Map<String, String> inEndpointTemplates,
final DomainMapper<Long, Person> inPlaceholderPersonMapper,
final HttpClientBuilder inHttpClientBuilder)
{
velocityEngine = inVelocityEngine;
velocityGlobalContext = inVelocityGlobalContext;
templates = inTemplates;
endpointTemplates = inEndpointTemplates;
placeholderPersonMapper = inPlaceholderPersonMapper;
httpClientBuilder = inHttpClientBuilder;
}
@Override
public Collection<UserActionRequest> notify(final NotificationType inType,
final Collection<Long> inRecipients,
final Map<String, Object> inProperties,
final Map<Long, PersonModelView> inRecipientIndex) throws Exception
{
//wrap context to prevent changes to properties map
Context velocityContext = new VelocityContext(new VelocityContext(inProperties, velocityGlobalContext));
velocityContext.put("context", velocityContext);
velocityContext.put("type", inType);
String template = templates.get(inType);
for (long recipientId : inRecipients)
{
Person recipient = placeholderPersonMapper.execute(recipientId);
if (recipient == null)
{
continue;
}
if (template == null)
{
return null;
}
velocityContext.put("recipient", recipient);
StringWriter writer = new StringWriter();
velocityEngine.evaluate(velocityContext, writer, "JsonNotification-" + inType, template);
String message = writer.toString();
sendJSONNotification(message, velocityContext);
}
return null;
}
/**
* Make the http call to the specified endpoint.
* @param message
* message to be sent to the endpoint
* @param velocityContext
* velocity engine used to format the message and endpoint
*/
private void sendJSONNotification(final String message, final Context velocityContext)
{
try
{
for (String key : endpointTemplates.keySet())
{
StringWriter endpointString = new StringWriter();
velocityEngine.evaluate(velocityContext,
endpointString,
"jsonEnpoint",
URLDecoder.decode(endpointTemplates.get(key), "UTF-8"));
// Make the http request here.
URI endpoint = new URI(endpointString.toString());
logger.debug("Target url for json notifier request " + endpoint.toString());
//send post
httpClientBuilder.post(endpoint, message);
}
}
catch (Exception ex)
{
String msg = "Error occurred connection to json notifier endpoint " + ex;
logger.error(msg, ex);
}
}
}