package com.intrbiz.bergamot.notification;
import java.io.File;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
import org.apache.log4j.Logger;
import com.intrbiz.Util;
import com.intrbiz.bergamot.accounting.model.AccountingNotificationType;
import com.intrbiz.bergamot.config.NotificationEngineCfg;
import com.intrbiz.bergamot.health.model.KnownDaemon;
import com.intrbiz.bergamot.model.message.CheckMO;
import com.intrbiz.bergamot.model.message.ContactMO;
import com.intrbiz.bergamot.model.message.ParameterMO;
import com.intrbiz.bergamot.model.message.ParameterisedMO;
import com.intrbiz.bergamot.model.message.ResourceMO;
import com.intrbiz.bergamot.model.message.ServiceMO;
import com.intrbiz.bergamot.model.message.TeamMO;
import com.intrbiz.bergamot.model.message.TrapMO;
import com.intrbiz.bergamot.model.message.notification.CheckNotification;
import com.intrbiz.bergamot.model.message.notification.Notification;
import com.intrbiz.bergamot.model.message.notification.PasswordResetNotification;
import com.intrbiz.bergamot.model.message.notification.RegisterContactNotification;
import com.intrbiz.bergamot.model.message.notification.SendAcknowledge;
import com.intrbiz.bergamot.model.message.notification.SendAlert;
import com.intrbiz.bergamot.model.message.notification.SendRecovery;
import com.intrbiz.express.DefaultContext;
import com.intrbiz.express.ExpressContext;
import com.intrbiz.express.ExpressExtensionRegistry;
import com.intrbiz.express.template.ExpressTemplate;
import com.intrbiz.express.template.loader.TemplateLoader;
import com.intrbiz.express.template.loader.impl.ClassPathTemplateSource;
import com.intrbiz.express.template.loader.impl.FileTemplateSource;
public abstract class AbstractNotificationEngine implements NotificationEngine
{
private Logger logger = Logger.getLogger(AbstractNotificationEngine.class);
private final String name;
protected NotificationEngineCfg config;
protected Notifier notifier;
protected final ExpressExtensionRegistry expressExtensions = new ExpressExtensionRegistry("bergamot").addSubRegistry(ExpressExtensionRegistry.getDefaultRegistry());
protected TemplateLoader templateLoader;
public AbstractNotificationEngine(String name)
{
super();
this.name = name;
}
@Override
public void configure(NotificationEngineCfg cfg) throws Exception
{
this.config = cfg;
// setup our template loader
this.templateLoader = new TemplateLoader();
String templatePath = cfg.getStringParameterValue("template.path", "/etc/bergamot/notifier/" + this.getName() + "/templates");
this.logger.info("Prefering templates from " + templatePath);
this.templateLoader.addSource(new FileTemplateSource(new File(templatePath)));
this.templateLoader.addSource(new ClassPathTemplateSource("/templates/" + this.getName()));
this.templateLoader.setCacheOn(cfg.getBooleanParameterValue("template.cache", true));
// configure
this.configure();
}
protected void configure() throws Exception
{
}
@Override
public NotificationEngineCfg getConfiguration()
{
return this.config;
}
@Override
public String getName()
{
return this.name;
}
@Override
public Notifier getNotifier()
{
return this.notifier;
}
@Override
public void setNotifier(Notifier notifier)
{
this.notifier = notifier;
}
public TemplateLoader getTemplateLoader()
{
return this.templateLoader;
}
public String applyTemplate(String name, Notification notification)
{
ExpressContext context = this.createContext(notification);
ExpressTemplate template = this.templateLoader.load(context, name);
if (template != null) return template.encodeToString(context, notification);
throw new NotificationException("Failed to find template: " + name);
}
public String applyTemplate(String name, KnownDaemon daemon)
{
ExpressContext context = this.createContext(daemon);
ExpressTemplate template = this.templateLoader.load(context, name);
if (template != null) return template.encodeToString(context, daemon);
throw new NotificationException("Failed to find template: " + name);
}
protected ExpressContext createContext(Notification notification)
{
return new DefaultContext(this.expressExtensions, new NotificationEngineEntityResolver(notification), this.templateLoader);
}
protected ExpressContext createContext(final KnownDaemon daemon)
{
ExpressContext ctx = new DefaultContext(this.expressExtensions, new KnownDaemonEntityResolver(daemon), this.templateLoader);
return ctx;
}
// util helpers
/**
* Look through a check notification for any parameters where the name start with the given prefix collecting the set of values
* @param notification the notification
* @param parameterNamePrefix find parameters where the name starts this prefix
* @return a unique set of parameter values
*/
protected Set<String> findNotificationParameters(CheckNotification notification, String parameterNamePrefix)
{
Set<String> urls = new TreeSet<String>();
// search contacts and teams
for (ContactMO to : notification.getTo())
{
this.findNotificationParameters(to, parameterNamePrefix, urls);
for (TeamMO team : to.getTeams())
{
this.findNotificationParameters(team, parameterNamePrefix, urls);
}
}
// search the check objects
CheckMO check = notification.getCheck();
this.findNotificationParameters(check, parameterNamePrefix, urls);
// go up the chain
if (check instanceof ServiceMO) this.findNotificationParameters(((ServiceMO) check).getHost(), parameterNamePrefix, urls);
if (check instanceof TrapMO) this.findNotificationParameters(((TrapMO) check).getHost(), parameterNamePrefix, urls);
if (check instanceof ResourceMO) this.findNotificationParameters(((ResourceMO) check).getCluster(), parameterNamePrefix, urls);
// done
return urls;
}
protected void findNotificationParameters(ParameterisedMO params, String parameterNamePrefix, Set<String> urls)
{
for (ParameterMO urlParam : params.getParametersStartingWith("slack.url"))
{
if (! Util.isEmpty(urlParam.getValue()))
urls.add(urlParam.getValue());
}
}
// accounting helpers
public static AccountingNotificationType getNotificationType(Notification notification)
{
if (notification instanceof SendAlert) return AccountingNotificationType.ALERT;
else if (notification instanceof SendRecovery) return AccountingNotificationType.RECOVERY;
else if (notification instanceof SendAcknowledge) return AccountingNotificationType.ACKNOWLEDGEMENT;
else if (notification instanceof PasswordResetNotification) return AccountingNotificationType.RESET;
else if (notification instanceof RegisterContactNotification) return AccountingNotificationType.REGISTER;
return null;
}
public static UUID getObjectId(Notification notification)
{
if (notification instanceof CheckNotification) return ((CheckNotification) notification).getCheck().getId();
else if (notification instanceof PasswordResetNotification) return ((PasswordResetNotification) notification).getContact().getId();
else if (notification instanceof RegisterContactNotification) return ((RegisterContactNotification) notification).getContact().getId();
return null;
}
}