/**
* =============================================================================
*
* ORCID (R) Open Source
* http://orcid.org
*
* Copyright (c) 2012-2014 ORCID, Inc.
* Licensed under an MIT-Style License (MIT)
* http://orcid.org/open-source-license
*
* This copyright and license information (including a link to the full license)
* shall be included in its entirety in all copies or substantial portion of
* the software.
*
* =============================================================================
*/
package org.orcid.persistence.messaging;
import java.util.Map;
import javax.annotation.Resource;
import org.orcid.utils.listener.LastModifiedMessage;
import org.orcid.utils.listener.MessageConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jms.JmsException;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/** This class allows you to send text messages via JMS/ActiveMQ.
* It is available as a Spring managed Bean.
*
* Spring config will scan this package for Component annotated classes
* and register all methods annotated with JmsListener.
*
* To create a listener, look at EchoTestMessageListener2 & 3 for examples of queue listeners.
*
* It has a failsafe - if the connection to the broker goes down, it stops trying to send messages for one minute.
* send(LastModifiedMessage mess, JmsDestination d) will instead write REINDEX flags to records so that they are picked up by the scheduler
* Different logic can be implemented for future message types.
*
* @author tom
*
*/
@Component
public class JmsMessageSender {
private static final Logger LOG = LoggerFactory.getLogger(JmsMessageSender.class);
private boolean enabled = false;
private boolean pauseForAWhile = false;
public enum JmsDestination{
TEST(MessageConstants.Queues.TEST),
TEST_REPLY(MessageConstants.Queues.TEST_REPLY),
UPDATED_ORCIDS(MessageConstants.Queues.UPDATED_ORCIDS),
REINDEX(MessageConstants.Queues.REINDEX);
public final String value;
JmsDestination(String value){
this.value = value;
}
}
@Resource
private JmsTemplate jmsTemplate;
protected boolean sendText(final String text, JmsDestination dest ) throws JmsException{
if (isEnabled() && !pauseForAWhile){
jmsTemplate.convertAndSend(dest.value, text);
return true;
}
LOG.info("Not sending message: isEnabled="+isEnabled()+" pauseForAWhile"+pauseForAWhile);
return false;
}
protected boolean sendMap(final Map<String,String> map, JmsDestination dest) throws JmsException{
if (isEnabled() && !pauseForAWhile){
jmsTemplate.convertAndSend(dest.value, map);
return true;
}
LOG.info("Not sending message: isEnabled="+isEnabled()+" pauseForAWhile="+pauseForAWhile);
return false;
}
/**Sends a LastModifiedMessage to the selected queue
*
* @param mess the message
* @param d the destination queue
* @return true if message sent successfully
*/
public boolean send(LastModifiedMessage mess, JmsDestination d){
try{
return this.sendMap(mess.getMap(), d);
} catch(JmsException e) {
//TODO: How we unflag the problem?
//flagConnectionProblem(e);
LOG.error("Couldnt send " + mess.getOrcid() + " to the message queue", e);
}
return false;
}
/** Silenty discard messages for a while
*
*/
public void flagConnectionProblem(Exception e){
LOG.error("JMS connection problem found, pausing messaging. "+e.getMessage());
pauseForAWhile = true;
}
public boolean isEnabled(){
return enabled;
}
public void setEnabled(boolean enabled){
this.enabled = enabled;
}
/** retry connecting if bad after every couple of minutes
*
*/
@Scheduled(fixedDelay=60000)
public void timer(){
synchronized(this){
if (pauseForAWhile){
pauseForAWhile = false;
}
}
}
}