package com.linkedin.thirdeye.rootcause.impl;
import com.linkedin.thirdeye.rootcause.Entity;
import com.linkedin.thirdeye.rootcause.PipelineContext;
import java.util.HashSet;
import java.util.Set;
/**
* TimeRangeEntity represents a time-range as investigated by the user for purposes of
* root cause search. The URN namespace is defined as 'thirdeye:timerange:{start}:{end}'.
*/
public class TimeRangeEntity extends Entity {
public static final EntityType TYPE = new EntityType("thirdeye:timerange:");
public static final String TYPE_CURRENT = "current";
public static final String TYPE_BASELINE = "baseline";
private final String type;
private final long start;
private final long end;
protected TimeRangeEntity(String urn, double score, String type, long start, long end) {
super(urn, score);
this.type = type;
this.start = start;
this.end = end;
}
public long getStart() {
return start;
}
public long getEnd() {
return end;
}
public String getType() {
return type;
}
public static TimeRangeEntity fromURN(String urn, double score) {
if(!TYPE.isType(urn))
throw new IllegalArgumentException(String.format("URN '%s' is not type '%s'", urn, TYPE.getPrefix()));
String[] parts = urn.split(":", 5);
if(parts.length != 5)
throw new IllegalArgumentException(String.format("Timerange URN must have 5 parts but has '%d'", parts.length));
return fromRange(score, parts[2], Long.valueOf(parts[3]), Long.valueOf(parts[4]));
}
public static TimeRangeEntity fromRange(double score, String type, long start, long end) {
String urn = TYPE.formatURN(type, start, end);
return new TimeRangeEntity(urn, score, type, start, end);
}
/**
* Returns the TimeRangeEntity contained in the search context of an execution context.
* Expects exactly one TimeRange entity and returns {@code null} if none or multiple
* time range entities are found. If the search context contains an instance of
* TimeRangeEntity it returns the instance. Otherwise, constructs a new instance of
* TimeRangeEntity from an encoding URN.
*
* @param context execution context
* @return TimeRangeEntity
*/
public static TimeRangeEntity getContextTimeRange(PipelineContext context, String type) {
Set<TimeRangeEntity> timeRanges = context.filter(TimeRangeEntity.class);
Set<TimeRangeEntity> matching = new HashSet<>();
for(TimeRangeEntity e : timeRanges) {
if(e.getType().equals(type))
matching.add(e);
}
if(matching.size() != 1)
throw new IllegalArgumentException(String.format("Must contain exactly one of type '%s'", type));
return matching.iterator().next();
}
public static TimeRangeEntity getContextCurrent(PipelineContext context) {
return getContextTimeRange(context, TYPE_CURRENT);
}
public static TimeRangeEntity getContextBaseline(PipelineContext context) {
return getContextTimeRange(context, TYPE_BASELINE);
}
}