package org.deephacks.confit.spi;
import com.google.common.base.Optional;
import org.deephacks.confit.ConfigChanges;
import org.deephacks.confit.ConfigChanges.ConfigChange;
import org.deephacks.confit.ConfigObserver;
import org.deephacks.confit.model.Bean;
import org.deephacks.confit.model.BeanId;
import org.deephacks.confit.model.Events;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Responsible for sending notifications to observers when configuration is
* created, deleted or updated. Each notification provide state information
* before and after a change was made to a particular instance of a specific
* type.
*/
public abstract class NotificationManager {
protected static final BeanManager beanManager = BeanManager.lookup();
protected static final SchemaManager schemaManager = SchemaManager.lookup();
protected static final Set<ConfigObserver> observers = new HashSet<>();
private static Lookup lookup = Lookup.get();
/**
* Lookup the most suitable NotificationManager available.
*
* @return NotificationManager.
*/
public static NotificationManager lookup() {
return lookup.lookup(NotificationManager.class);
}
/**
* Register an observer interested in configuration state changes.
*
* @param observer the instance to receive notifications
*/
public void register(ConfigObserver observer) {
observers.add(observer);
}
/**
* Called after configuration changes have been validated, committed to
* storage and cached. The NotificationManager should send notifications to
* observers when this method is called.
*
* Changes are delivered as Bean instances and should be converted to fully
* initialized objects when delivered to observers.
*
* @param changes state changes
*/
public abstract void fire(ConfigChanges changes);
/**
* Fire a notification for a collection of beans that have been created.
*
* @param beans created beans
*/
public final void fireCreate(Collection<Bean> beans) {
ConfigChanges changes = new ConfigChanges();
for (Bean bean : beans) {
changes.add(ConfigChange.created(bean));
}
fire(changes);
}
/**
* Create a changes object from a delete operation.
*
* @param schemaName schemaName of deleted instances
* @param instanceIds id of deleted instances
* @return changes object
*/
public final ConfigChanges deleted(String schemaName, Collection<String> instanceIds) {
ConfigChanges changes = new ConfigChanges();
for (String instanceId : instanceIds) {
BeanId id = BeanId.create(instanceId, schemaName);
Optional<Bean> before = beanManager.getEager(id);
if (!before.isPresent()) {
throw Events.CFG304_BEAN_DOESNT_EXIST(id);
}
Bean bean = before.get();
schemaManager.setSchema(Arrays.asList(bean));
changes.add(ConfigChange.deleted(bean));
}
return changes;
}
/**
* Fire a notification for a collection of beans that have been deleted.
*
* @param beans deleted beans
*/
public final void fireDelete(List<Bean> beans) {
ConfigChanges changes = new ConfigChanges();
for (Bean bean : beans) {
changes.add(ConfigChange.deleted(bean));
}
fire(changes);
}
/**
* Create a changes object from an update operation.
*
* @param after state after the update have been made
* @return changes object
*/
public final ConfigChanges updated(Collection<Bean> after) {
ConfigChanges changes = new ConfigChanges();
for (Bean bean : after) {
Optional<Bean> optional = beanManager.getEager(bean.getId());
if (!optional.isPresent()) {
throw Events.CFG304_BEAN_DOESNT_EXIST(bean.getId());
}
Bean before = optional.get();
schemaManager.setSchema(Arrays.asList(before));
changes.add(ConfigChange.updated(before, bean));
}
return changes;
}
}