/**
*
*/
package com.thinkbiganalytics.alerts.api.core;
/*-
* #%L
* thinkbig-alerts-core
* %%
* Copyright (C) 2017 ThinkBig Analytics
* %%
* 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.
* #L%
*/
import com.thinkbiganalytics.alerts.api.Alert;
import com.thinkbiganalytics.alerts.api.Alert.Level;
import com.thinkbiganalytics.alerts.api.Alert.State;
import com.thinkbiganalytics.alerts.api.AlertCriteria;
import org.joda.time.DateTime;
import java.net.URI;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;
/**
* A generic AlertCriteria implementation that simply records the criteria settings.
* It is useful as a base implementation to be extended by AlertProviders, AlertSources,
* and AlertManagers.
* <P>
* This implementation also has a default predicate implementation but subclasses are not
* required to support or use this implementation.
*/
public class BaseAlertCriteria implements AlertCriteria, Predicate<Alert> {
private int limit = Integer.MAX_VALUE;
private Set<URI> types = new HashSet<>();
private Set<Alert.State> states = new HashSet<>();
private Set<Alert.Level> levels = new HashSet<>();
private DateTime afterTime;
private DateTime beforeTime;
private boolean includeCleared = false;
/**
* Transfers the contents of this criteria to the given criteria.
*/
public AlertCriteria transfer(AlertCriteria criteria) {
AtomicReference<AlertCriteria> updated = new AtomicReference<AlertCriteria>(criteria);
updated.set(updated.get().limit(this.limit));
updated.set(updated.get().after(this.afterTime));
updated.set(updated.get().before(this.beforeTime));
updated.set(updated.get().includedCleared(this.isIncludeCleared()));
this.types.forEach((t) -> updated.set(updated.get().type(t)));
this.states.forEach((s) -> updated.set(updated.get().state(s)));
this.levels.forEach((l) -> updated.set(updated.get().level(l)));
return updated.get();
}
/* (non-Javadoc)
* @see java.util.function.Predicate#test(java.lang.Object)
*/
@Override
public boolean test(Alert alert) {
if (this.types.size() > 0 && !testTypes(alert)) {
return false;
}
if (this.states.size() > 0 && !testStates(alert)) {
return false;
}
if (this.levels.size() > 0 && !testLevels(alert)) {
return false;
}
if (this.afterTime != null && !testAfterTime(alert)) {
return false;
}
if (this.beforeTime != null && !testBeforeTime(alert)) {
return false;
}
if (!this.testCleared(alert)) {
return false;
}
return true;
}
/* (non-Javadoc)
* @see com.thinkbiganalytics.alerts.api.AlertCriteria#limit(int)
*/
@Override
public AlertCriteria limit(int size) {
this.limit = Math.max(0, size);
return this;
}
/* (non-Javadoc)
* @see com.thinkbiganalytics.alerts.api.AlertCriteria#type(java.net.URI)
*/
@Override
public AlertCriteria type(URI type, URI... others) {
if (type != null) {
this.types.add(type);
}
if (others != null) {
Arrays.stream(others).forEach(uri -> this.types.add(uri));
}
return this;
}
/* (non-Javadoc)
* @see com.thinkbiganalytics.alerts.api.AlertCriteria#state(com.thinkbiganalytics.alerts.api.Alert.State)
*/
@Override
public AlertCriteria state(State state, State... others) {
if (state != null) {
this.states.add(state);
}
if (others != null) {
Arrays.stream(others).forEach(s -> this.states.add(s));
}
return this;
}
/* (non-Javadoc)
* @see com.thinkbiganalytics.alerts.api.AlertCriteria#level(com.thinkbiganalytics.alerts.api.Alert.Level)
*/
@Override
public AlertCriteria level(Level level, Level... others) {
if (level != null) {
this.levels.add(level);
}
if (others != null) {
Arrays.stream(others).forEach(l -> this.levels.add(l));
}
return this;
}
/* (non-Javadoc)
* @see com.thinkbiganalytics.alerts.api.AlertCriteria#after(org.joda.time.DateTime)
*/
@Override
public AlertCriteria after(DateTime time) {
this.afterTime = time;
return this;
}
/* (non-Javadoc)
* @see com.thinkbiganalytics.alerts.api.AlertCriteria#before(org.joda.time.DateTime)
*/
@Override
public AlertCriteria before(DateTime time) {
this.beforeTime = time;
return this;
}
/* (non-Javadoc)
* @see com.thinkbiganalytics.alerts.api.AlertCriteria#includedCleared(boolean)
*/
@Override
public AlertCriteria includedCleared(boolean flag) {
this.includeCleared = flag;
return this;
}
protected boolean testTypes(Alert alert) {
return this.types.stream().anyMatch(uri -> {
// A match means the type URIs are equal (handles opaque URIs) or the matching URI is a parent as defined by relativize.
return uri.equals(alert.getType()) || uri.relativize(alert.getType()) != alert.getType();
});
}
protected boolean testStates(Alert alert) {
return this.states.contains(alert.getState());
}
protected boolean testLevels(Alert alert) {
return this.levels.contains(alert.getLevel());
}
protected boolean testAfterTime(Alert alert) {
return alert.getCreatedTime().isAfter(this.afterTime);
}
protected boolean testBeforeTime(Alert alert) {
return alert.getCreatedTime().isBefore(this.beforeTime);
}
protected boolean testCleared(Alert alert) {
return !alert.isCleared() || this.includeCleared;
}
protected int getLimit() {
return limit;
}
protected Set<URI> getTypes() {
return types;
}
protected Set<Alert.State> getStates() {
return states;
}
protected Set<Alert.Level> getLevels() {
return levels;
}
protected DateTime getAfterTime() {
return afterTime;
}
protected DateTime getBeforeTime() {
return beforeTime;
}
protected boolean isIncludeCleared() {
return includeCleared;
}
}