use of com.linkedin.thirdeye.datalayer.dto.AnomalyFunctionDTO in project pinot by linkedin.
the class AnomalyResource method updateAnomalyFunction.
// Edit anomaly function
@POST
@Path("/anomaly-function/update")
public Response updateAnomalyFunction(@NotNull @QueryParam("id") Long id, @NotNull @QueryParam("dataset") String dataset, @NotNull @QueryParam("functionName") String functionName, @NotNull @QueryParam("metric") String metric, @QueryParam("type") String type, @NotNull @QueryParam("windowSize") String windowSize, @NotNull @QueryParam("windowUnit") String windowUnit, @NotNull @QueryParam("windowDelay") String windowDelay, @QueryParam("cron") String cron, @QueryParam("windowDelayUnit") String windowDelayUnit, @QueryParam("exploreDimension") String exploreDimensions, @QueryParam("filters") String filters, @NotNull @QueryParam("properties") String properties, @QueryParam("isActive") boolean isActive) throws Exception {
if (id == null || StringUtils.isEmpty(dataset) || StringUtils.isEmpty(functionName) || StringUtils.isEmpty(metric) || StringUtils.isEmpty(windowSize) || StringUtils.isEmpty(windowUnit) || StringUtils.isEmpty(windowDelay) || StringUtils.isEmpty(properties)) {
throw new UnsupportedOperationException("Received null for one of the mandatory params: " + "id " + id + ",dataset " + dataset + ", functionName " + functionName + ", metric " + metric + ", windowSize " + windowSize + ", windowUnit " + windowUnit + ", windowDelay " + windowDelay + ", properties" + properties);
}
AnomalyFunctionDTO anomalyFunctionSpec = anomalyFunctionDAO.findById(id);
if (anomalyFunctionSpec == null) {
throw new IllegalStateException("AnomalyFunctionSpec with id " + id + " does not exist");
}
DatasetConfigDTO datasetConfig = DAO_REGISTRY.getDatasetConfigDAO().findByDataset(dataset);
TimeSpec timespec = ThirdEyeUtils.getTimeSpecFromDatasetConfig(datasetConfig);
TimeGranularity dataGranularity = timespec.getDataGranularity();
anomalyFunctionSpec.setActive(isActive);
anomalyFunctionSpec.setCollection(dataset);
anomalyFunctionSpec.setFunctionName(functionName);
anomalyFunctionSpec.setTopicMetric(metric);
anomalyFunctionSpec.setMetrics(Arrays.asList(metric));
if (StringUtils.isEmpty(type)) {
type = DEFAULT_FUNCTION_TYPE;
}
anomalyFunctionSpec.setType(type);
anomalyFunctionSpec.setWindowSize(Integer.valueOf(windowSize));
anomalyFunctionSpec.setWindowUnit(TimeUnit.valueOf(windowUnit));
// bucket size and unit are defaulted to the collection granularity
anomalyFunctionSpec.setBucketSize(dataGranularity.getSize());
anomalyFunctionSpec.setBucketUnit(dataGranularity.getUnit());
if (!StringUtils.isBlank(filters)) {
filters = URLDecoder.decode(filters, UTF8);
String filterString = ThirdEyeUtils.getSortedFiltersFromJson(filters);
anomalyFunctionSpec.setFilters(filterString);
}
anomalyFunctionSpec.setProperties(properties);
if (StringUtils.isNotEmpty(exploreDimensions)) {
// Ensure that the explore dimension names are ordered as schema dimension names
anomalyFunctionSpec.setExploreDimensions(getDimensions(dataset, exploreDimensions));
}
if (StringUtils.isEmpty(cron)) {
cron = DEFAULT_CRON;
} else {
// validate cron
if (!CronExpression.isValidExpression(cron)) {
throw new IllegalArgumentException("Invalid cron expression for cron : " + cron);
}
}
anomalyFunctionSpec.setCron(cron);
anomalyFunctionDAO.update(anomalyFunctionSpec);
return Response.ok(id).build();
}
use of com.linkedin.thirdeye.datalayer.dto.AnomalyFunctionDTO in project pinot by linkedin.
the class AnomalyResource method deleteAnomalyFunctions.
// Delete anomaly function
@DELETE
@Path("/anomaly-function/delete")
public Response deleteAnomalyFunctions(@NotNull @QueryParam("id") Long id, @QueryParam("functionName") String functionName) throws IOException {
if (id == null) {
throw new IllegalArgumentException("id is a required query param");
}
// call endpoint to stop if active
AnomalyFunctionDTO anomalyFunctionSpec = anomalyFunctionDAO.findById(id);
if (anomalyFunctionSpec == null) {
throw new IllegalStateException("No anomalyFunctionSpec with id " + id);
}
// delete dependent entities
// email config mapping
List<EmailConfigurationDTO> emailConfigurations = emailConfigurationDAO.findByFunctionId(id);
for (EmailConfigurationDTO emailConfiguration : emailConfigurations) {
emailConfiguration.getFunctions().remove(anomalyFunctionSpec);
emailConfigurationDAO.update(emailConfiguration);
}
// raw result mapping
List<RawAnomalyResultDTO> rawResults = rawAnomalyResultDAO.findAllByTimeAndFunctionId(0, System.currentTimeMillis(), id);
for (RawAnomalyResultDTO result : rawResults) {
rawAnomalyResultDAO.delete(result);
}
// merged anomaly mapping
List<MergedAnomalyResultDTO> mergedResults = anomalyMergedResultDAO.findByFunctionId(id);
for (MergedAnomalyResultDTO result : mergedResults) {
anomalyMergedResultDAO.delete(result);
}
// delete from db
anomalyFunctionDAO.deleteById(id);
return Response.noContent().build();
}
use of com.linkedin.thirdeye.datalayer.dto.AnomalyFunctionDTO in project pinot by linkedin.
the class AnomalyResource method createAnomalyFunction.
// Add anomaly function
@POST
@Path("/anomaly-function/create")
public Response createAnomalyFunction(@NotNull @QueryParam("dataset") String dataset, @NotNull @QueryParam("functionName") String functionName, @NotNull @QueryParam("metric") String metric, @NotNull @QueryParam("metricFunction") String metric_function, @QueryParam("type") String type, @NotNull @QueryParam("windowSize") String windowSize, @NotNull @QueryParam("windowUnit") String windowUnit, @QueryParam("windowDelay") String windowDelay, @QueryParam("cron") String cron, @QueryParam("windowDelayUnit") String windowDelayUnit, @QueryParam("exploreDimension") String exploreDimensions, @QueryParam("filters") String filters, @NotNull @QueryParam("properties") String properties, @QueryParam("isActive") boolean isActive) throws Exception {
if (StringUtils.isEmpty(dataset) || StringUtils.isEmpty(functionName) || StringUtils.isEmpty(metric) || StringUtils.isEmpty(windowSize) || StringUtils.isEmpty(windowUnit) || StringUtils.isEmpty(properties)) {
throw new UnsupportedOperationException("Received null for one of the mandatory params: " + "dataset " + dataset + ", functionName " + functionName + ", metric " + metric + ", windowSize " + windowSize + ", windowUnit " + windowUnit + ", properties" + properties);
}
DatasetConfigDTO datasetConfig = DAO_REGISTRY.getDatasetConfigDAO().findByDataset(dataset);
TimeSpec timespec = ThirdEyeUtils.getTimeSpecFromDatasetConfig(datasetConfig);
TimeGranularity dataGranularity = timespec.getDataGranularity();
AnomalyFunctionDTO anomalyFunctionSpec = new AnomalyFunctionDTO();
anomalyFunctionSpec.setActive(isActive);
anomalyFunctionSpec.setMetricFunction(MetricAggFunction.valueOf(metric_function));
anomalyFunctionSpec.setCollection(dataset);
anomalyFunctionSpec.setFunctionName(functionName);
anomalyFunctionSpec.setTopicMetric(metric);
anomalyFunctionSpec.setMetrics(Arrays.asList(metric));
if (StringUtils.isEmpty(type)) {
type = DEFAULT_FUNCTION_TYPE;
}
anomalyFunctionSpec.setType(type);
anomalyFunctionSpec.setWindowSize(Integer.valueOf(windowSize));
anomalyFunctionSpec.setWindowUnit(TimeUnit.valueOf(windowUnit));
// Setting window delay time / unit
TimeUnit dataGranularityUnit = dataGranularity.getUnit();
// default window delay time = 10 hours
int windowDelayTime = 10;
TimeUnit windowDelayTimeUnit = TimeUnit.HOURS;
if (dataGranularityUnit.equals(TimeUnit.MINUTES) || dataGranularityUnit.equals(TimeUnit.HOURS)) {
windowDelayTime = 4;
}
anomalyFunctionSpec.setWindowDelayUnit(windowDelayTimeUnit);
anomalyFunctionSpec.setWindowDelay(windowDelayTime);
// bucket size and unit are defaulted to the collection granularity
anomalyFunctionSpec.setBucketSize(dataGranularity.getSize());
anomalyFunctionSpec.setBucketUnit(dataGranularity.getUnit());
if (StringUtils.isNotEmpty(exploreDimensions)) {
anomalyFunctionSpec.setExploreDimensions(getDimensions(dataset, exploreDimensions));
}
if (!StringUtils.isBlank(filters)) {
filters = URLDecoder.decode(filters, UTF8);
String filterString = ThirdEyeUtils.getSortedFiltersFromJson(filters);
anomalyFunctionSpec.setFilters(filterString);
}
anomalyFunctionSpec.setProperties(properties);
if (StringUtils.isEmpty(cron)) {
cron = DEFAULT_CRON;
} else {
// validate cron
if (!CronExpression.isValidExpression(cron)) {
throw new IllegalArgumentException("Invalid cron expression for cron : " + cron);
}
}
anomalyFunctionSpec.setCron(cron);
Long id = anomalyFunctionDAO.save(anomalyFunctionSpec);
return Response.ok(id).build();
}
use of com.linkedin.thirdeye.datalayer.dto.AnomalyFunctionDTO in project pinot by linkedin.
the class OnboardResource method cloneAnomalyFunctionById.
/**
* clone Anomaly Function by Id to a function name appended with a name tag
*
* @param id function id to be cloned
* @param cloneNameTag an name tag that will append to original function name as serve as the cloned function name
* @param doCloneAnomaly does the associated anomaly instances will be clone to new function
* @return id of the clone function
*/
public Long cloneAnomalyFunctionById(long id, String cloneNameTag, boolean doCloneAnomaly) throws Exception {
// get anomaly function definition
AnomalyFunctionDTO anomalyFunction = anomalyFunctionDAO.findById(id);
// if cannot find then return
if (anomalyFunction == null) {
// LOG and exit
LOG.error("Anomaly Function With id [{}] does not found", id);
return null;
}
String functionName = anomalyFunction.getFunctionName();
String newFunctionName = functionName;
if (cloneNameTag != null && cloneNameTag.length() > 0) {
// update with input clone function name
newFunctionName = newFunctionName + "_" + cloneNameTag;
} else {
// set default clone function name
newFunctionName = newFunctionName + "_" + "clone_0";
}
LOG.info("Try to clone anomaly Function Id: {}, Name: {}, to new Name: {}", id, functionName, newFunctionName);
anomalyFunction.setFunctionName(newFunctionName);
// deactivate the function
anomalyFunction.setActive(false);
anomalyFunction.setId(null);
// exception should be handled when have duplicate name
long newId = anomalyFunctionDAO.save(anomalyFunction);
LOG.info("clone function id: {}, name: {} to id: {}, name: {}", id, functionName, newId, newFunctionName);
if (doCloneAnomaly) {
cloneAnomalyInstances(id, newId);
}
return newId;
}
use of com.linkedin.thirdeye.datalayer.dto.AnomalyFunctionDTO in project pinot by linkedin.
the class OnboardResource method cloneAnomalyInstances.
/**
* Clone merged anomaly instances of one function to another
* 1. get all merged anomaly instances with AnomalyFunctionId = srcId
* 2. set the associated anomalyFunctionId = destId
* 3. save the modified anomaly instances
* @param srcId the source function Id with anomalies to be cloned.
* @param destId the destination function Id which source anomalies to be cloned to.
* @return boolean to indicate if the clone is success or not
*/
public Boolean cloneAnomalyInstances(Long srcId, Long destId) {
// make sure both function can be identified by IDs
AnomalyFunctionDTO srcAnomalyFunction = anomalyFunctionDAO.findById(srcId);
// if cannot find then return
if (srcAnomalyFunction == null) {
// LOG and exit
LOG.error("Source Anomaly Function With id [{}] does not found", srcId);
return false;
}
AnomalyFunctionDTO destAnomalyFunction = anomalyFunctionDAO.findById(destId);
// if cannot find then return
if (destAnomalyFunction == null) {
// LOG and exit
LOG.error("Destination Anomaly Function With id [{}] does not found", destId);
return false;
}
LOG.info("clone merged anomaly results from source anomaly function id {} to id {}", srcId, destId);
List<MergedAnomalyResultDTO> mergedAnomalyResultDTOs = mergedAnomalyResultDAO.findByFunctionId(srcId);
if (mergedAnomalyResultDTOs == null || mergedAnomalyResultDTOs.isEmpty()) {
LOG.error("No merged anomaly results found for anomaly function Id: {}", srcId);
return false;
}
for (MergedAnomalyResultDTO mergedAnomalyResultDTO : mergedAnomalyResultDTOs) {
long oldId = mergedAnomalyResultDTO.getId();
// clean the Id, then will create a new Id when save
mergedAnomalyResultDTO.setId(null);
mergedAnomalyResultDTO.setRawAnomalyIdList(null);
mergedAnomalyResultDTO.setFunctionId(destId);
mergedAnomalyResultDTO.setFunction(destAnomalyFunction);
long newId = mergedAnomalyResultDAO.save(mergedAnomalyResultDTO);
LOG.debug("clone merged anomaly {} to {}", oldId, newId);
}
return true;
}
Aggregations