Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
pl.edu.icm.unity.engine.notifications.NotificationProducerImpl Maven / Gradle / Ivy
/*
* Copyright (c) 2013 ICM Uniwersytet Warszawski All rights reserved.
* See LICENCE.txt file for licensing information.
*/
package pl.edu.icm.unity.engine.notifications;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future;
import java.util.stream.Collectors;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import pl.edu.icm.unity.MessageSource;
import pl.edu.icm.unity.base.msgtemplates.GenericMessageTemplateDef;
import pl.edu.icm.unity.base.utils.Log;
import pl.edu.icm.unity.engine.api.notification.NotificationProducer;
import pl.edu.icm.unity.engine.api.notification.NotificationStatus;
import pl.edu.icm.unity.engine.msgtemplate.MessageTemplateProcessor;
import pl.edu.icm.unity.exceptions.EngineException;
import pl.edu.icm.unity.exceptions.IllegalIdentityValueException;
import pl.edu.icm.unity.store.api.MembershipDAO;
import pl.edu.icm.unity.store.api.generic.MessageTemplateDB;
import pl.edu.icm.unity.store.api.tx.Transactional;
import pl.edu.icm.unity.store.api.tx.TxManager;
import pl.edu.icm.unity.types.basic.EntityParam;
import pl.edu.icm.unity.types.basic.GroupMembership;
import pl.edu.icm.unity.types.basic.MessageTemplate;
import pl.edu.icm.unity.types.basic.MessageTemplate.Message;
/**
* Internal (shouldn't be exposed directly to end-users) subsystem for sending notifications.
* @author K. Benedyczak
*/
@Component
public class NotificationProducerImpl implements NotificationProducer, InternalFacilitiesManagement
{
private static final Logger log = Log.getLogger(Log.U_SERVER_NOTIFY, NotificationProducerImpl.class);
private NotificationFacilitiesRegistry facilitiesRegistry;
private MembershipDAO dbGroups;
private MessageTemplateDB mtDB;
private MessageSource msg;
private TxManager txManager;
private final MessageTemplateProcessor messageTemplateProcessor = new MessageTemplateProcessor();
private final ChannelInstanceFactory channelFactory;
@Autowired
public NotificationProducerImpl(
ChannelInstanceFactory channelFactory,
NotificationFacilitiesRegistry facilitiesRegistry,
MembershipDAO dbGroups, MessageTemplateDB mtDB, MessageSource msg,
TxManager txManager)
{
this.channelFactory = channelFactory;
this.dbGroups = dbGroups;
this.txManager = txManager;
this.facilitiesRegistry = facilitiesRegistry;
this.mtDB = mtDB;
this.msg = msg;
}
@Transactional(autoCommit=false)
@Override
public Future sendNotification(EntityParam recipient, String templateId,
Map params, String locale, String preferredAddress, boolean onlyToConfirmed)
throws EngineException
{
recipient.validateInitialization();
Map allTemplates = mtDB.getAllAsMap();
NotificationChannelInstance channel = channelFactory.loadChannel(getChannelFromTemplate(allTemplates, templateId));
NotificationFacility facility = facilitiesRegistry.getByName(channel.getFacilityId());
String recipientAddress = facility.getAddressForEntity(recipient, preferredAddress, onlyToConfirmed);
txManager.commit();
return sendMessageOverChannel(recipientAddress, templateId, params, locale, allTemplates, channel);
}
@Override
@Transactional
public void sendNotificationToGroup(String group, String templateId,
Map params, String locale) throws EngineException
{
if (templateId == null)
return;
Map allTemplates = mtDB.getAllAsMap();
List memberships = dbGroups.getMembers(group);
NotificationChannelInstance channel = channelFactory.loadChannel(getChannelFromTemplate(allTemplates, templateId));
NotificationFacility facility = facilitiesRegistry.getByName(channel.getFacilityId());
for (GroupMembership membership: memberships)
{
try
{
String recipientAddress = facility.getAddressForEntity(
new EntityParam(membership.getEntityId()), null, false);
sendMessageOverChannel(recipientAddress, templateId, params, locale,
allTemplates, channel);
} catch (IllegalIdentityValueException e)
{
log.trace("Can not get address for entity " + membership.getEntityId(), e);
}
}
}
@Override
@Transactional
public Collection sendNotification(Set groups, List singleRecipients, String templateId,
Map params, String locale) throws EngineException
{
if (templateId == null)
return Collections.emptyList();
Set allRecipiets = getRecipients(groups, singleRecipients);
Map allTemplates = mtDB.getAllAsMap();
NotificationChannelInstance channel = channelFactory.loadChannel(getChannelFromTemplate(allTemplates, templateId));
NotificationFacility facility = facilitiesRegistry.getByName(channel.getFacilityId());
List recipientAddresses = new ArrayList<>();
for (Long membership: allRecipiets)
{
try
{
String recipientAddress = facility.getAddressForEntity(
new EntityParam(membership), null, false);
sendMessageOverChannel(recipientAddress, templateId, params, locale,
allTemplates, channel);
recipientAddresses.add(recipientAddress);
} catch (IllegalIdentityValueException e)
{
log.trace("Can not get address for entity " + membership, e);
}
}
return recipientAddresses;
}
private Set getRecipients(Set groups, List singleRecipients)
{
Set allRecipiets = new HashSet<>();
if (singleRecipients != null)
{
allRecipiets.addAll(singleRecipients);
}
if (groups != null)
{
for (String group : groups)
{
dbGroups.getMembers(group).stream().map(m -> m.getEntityId()).forEach(allRecipiets::add);
}
}
return allRecipiets;
}
@Override
@Transactional(autoCommit=false)
public Future sendNotification(String recipientAddress,
String templateId, Map params, String locale)
throws EngineException
{
Map allTemplates = mtDB.getAllAsMap();
NotificationChannelInstance channel = channelFactory.loadChannel(getChannelFromTemplate(allTemplates, templateId));
txManager.commit();
return sendMessageOverChannel(recipientAddress, templateId, params, locale, allTemplates, channel);
}
@Override
public NotificationFacility getNotificationFacilityForChannel(String channelName)
throws EngineException
{
NotificationChannelInstance channel = channelFactory.loadChannel(channelName);
return facilitiesRegistry.getByName(channel.getFacilityId());
}
@Override
public NotificationFacility getNotificationFacilityForMessageTemplate(String templateId)
throws EngineException
{
NotificationFacility notificationFacility = getNotificationFacilityForChannel(
mtDB.get(templateId).getNotificationChannel());
return notificationFacility;
}
public Message getResolvedMessage(Map allTemplates,
String templateId, Map params, String locale)
{
MessageTemplate requested = allTemplates.get(templateId);
if (requested == null)
throw new IllegalArgumentException("There is no message template " + templateId);
Map genericTemplates = allTemplates.entrySet().stream()
.filter(e -> e.getValue().getConsumer().equals(GenericMessageTemplateDef.NAME))
.collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
return messageTemplateProcessor.getMessage(requested, locale, msg.getDefaultLocaleCode(),
params, genericTemplates);
}
@Override
@Transactional
public String getAddressForEntity(EntityParam recipient, String templateId, boolean onlyConfirmed) throws EngineException
{
Map allTemplates = mtDB.getAllAsMap();
NotificationChannelInstance channel = channelFactory.loadChannel(getChannelFromTemplate(allTemplates, templateId));
NotificationFacility facility = facilitiesRegistry.getByName(channel.getFacilityId());
return facility.getAddressForEntity(recipient, null, onlyConfirmed);
}
private Future sendMessageOverChannel(String recipientAddress,
String templateId, Map params, String locale,
Map allTemplates,
NotificationChannelInstance channel)
{
if (channel.providesMessageTemplatingFunctionality())
{
return channel.sendExternalTemplateMessage(recipientAddress,
new MessageTemplateParams(templateId, params));
} else
{
Message templateMsg = getResolvedMessage(allTemplates, templateId, params, locale);
return channel.sendNotification(recipientAddress, templateMsg);
}
}
private String getChannelFromTemplate(Map allTemplates,
String templateId) throws EngineException
{
MessageTemplate messageTemplate = allTemplates.get(templateId);
if (messageTemplate == null)
throw new IllegalArgumentException(
"There is no message template: " + templateId);
String channel = messageTemplate.getNotificationChannel();
if (channel == null | channel.isEmpty())
{
throw new IllegalArgumentException(
"There is no configured notification channel in message template: "
+ templateId);
}
return channel;
}
}