CollectorItem.java
package com.capitalone.dashboard.model;
import org.apache.commons.collections.CollectionUtils;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* <p>
* Represents a unique collection in an external tool. For example, for a CI tool
* the collector item would be a Job. For a project management tool, the collector item
* might be a Scope.
* </p>
* <p>
* Each {@link Collector} is responsible for specifying how it's {@link CollectorItem}s are
* uniquely identified by storing key/value pairs in the options Map. The description field will
* be visible to users in the UI to aid in selecting the correct {@link CollectorItem} for their dashboard.
* Ideally, the description will be unique for a given {@link Collector}.
* </p>
*/
@Document(collection="collector_items")
public class CollectorItem extends BaseModel {
private String description;
private String niceName;
private String environment;
private boolean enabled;
private List<CollectionError> errors = new ArrayList<>();
private boolean pushed;
private ObjectId collectorId;
private long lastUpdated;
private Map<String,Object> options = new HashMap<>();
@Transient
private Collector collector;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public ObjectId getCollectorId() {
return collectorId;
}
public void setCollectorId(ObjectId collectorId) {
this.collectorId = collectorId;
}
public Collector getCollector() {
return collector;
}
public void setCollector(Collector collector) {
this.collector = collector;
}
public Map<String, Object> getOptions() {
return options;
}
public void setOptions(Map<String,Object> options) {
this.options = options;
}
public boolean isPushed() {
return pushed;
}
public void setPushed(boolean pushed) {
this.pushed = pushed;
}
public long getLastUpdated() {
return lastUpdated;
}
public void setLastUpdated(long lastUpdated) {
this.lastUpdated = lastUpdated;
}
public String getNiceName() {
return niceName;
}
public void setNiceName(String niceName) {
this.niceName = niceName;
}
public String getEnvironment() {
return environment;
}
public void setEnvironment(String environment) {
this.environment = environment;
}
public List<CollectionError> getErrors() {
return errors;
}
public int getErrorCount() {
return errors.size();
}
/**
* Checks for collector items error threshold and resets it if window is met
* @param resetWindow - long time in milliseconds after which errors can be reset
* @param errorThreshold - number of errors to cross threshold
* @return true if (a) errors are within threshold and (b) reset if window is passed.
*/
public boolean checkErrorOrReset (long resetWindow, int errorThreshold) {
Optional<CollectionError> lastErrorOptional = errors.stream().max(Comparator.comparingLong(CollectionError::getTimestamp));
long lastErrorTimestamp = lastErrorOptional.isPresent() ? lastErrorOptional.get().getTimestamp() : System.currentTimeMillis();
if ((System.currentTimeMillis() - lastErrorTimestamp) >= resetWindow) {
//clear the oldest error so errors count drops below threshold
if (!CollectionUtils.isEmpty(errors)) {
errors.sort(Comparator.comparing(CollectionError::getTimestamp));
errors.remove(0);
}
return true;
} else {
return (errors.size() <= errorThreshold);
}
}
}