package com.linkedin.thirdeye.datalayer.bao.jdbc;
import com.google.inject.Singleton;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.joda.time.DateTime;
import com.google.inject.persist.Transactional;
import com.linkedin.thirdeye.anomaly.task.TaskConstants.TaskStatus;
import com.linkedin.thirdeye.datalayer.bao.TaskManager;
import com.linkedin.thirdeye.datalayer.dto.TaskDTO;
import com.linkedin.thirdeye.datalayer.pojo.TaskBean;
import com.linkedin.thirdeye.datalayer.util.Predicate;
@Singleton
public class TaskManagerImpl extends AbstractManagerImpl<TaskDTO> implements TaskManager {
private static final String FIND_BY_STATUS_ORDER_BY_CREATE_TIME_ASC =
" WHERE status = :status order by startTime asc";
private static final String FIND_BY_STATUS_ORDER_BY_CREATE_TIME_DESC =
" WHERE status = :status order by startTime desc";
public TaskManagerImpl() {
super(TaskDTO.class, TaskBean.class);
}
public Long save(TaskDTO entity) {
if (entity.getId() != null) {
//TODO: throw exception and force the caller to call update instead
update(entity);
return entity.getId();
}
TaskBean bean = (TaskBean) convertDTO2Bean(entity, TaskBean.class);
Long id = genericPojoDao.put(bean);
entity.setId(id);
return id;
}
@Override
public List<TaskDTO> findByJobIdStatusNotIn(Long jobId, TaskStatus status) {
Predicate jobIdPredicate = Predicate.EQ("jobId", jobId);
Predicate statusPredicate = Predicate.NEQ("status", status.toString());
Predicate predicate = Predicate.AND(statusPredicate, jobIdPredicate);
return findByPredicate(predicate);
}
@Override
public List<TaskDTO> findByStatusOrderByCreateTime(TaskStatus status, int fetchSize, boolean asc) {
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put("status", status.toString());
List<TaskBean> list;
String queryClause = (asc) ? FIND_BY_STATUS_ORDER_BY_CREATE_TIME_ASC : FIND_BY_STATUS_ORDER_BY_CREATE_TIME_DESC;
list = genericPojoDao.executeParameterizedSQL(queryClause, parameterMap, TaskBean.class);
List<TaskDTO> result = new ArrayList<>();
for (TaskBean bean : list) {
result.add(MODEL_MAPPER.map(bean, TaskDTO.class));
}
return result;
}
@Override
public boolean updateStatusAndWorkerId(Long workerId, Long id, Set<TaskStatus> permittedOldStatus,
TaskStatus newStatus, int expectedVersion) {
TaskDTO task = findById(id);
if (permittedOldStatus.contains(task.getStatus())) {
task.setStatus(newStatus);
task.setWorkerId(workerId);
//increment the version
task.setVersion(expectedVersion + 1);
Predicate predicate = Predicate.AND(
Predicate.EQ("id", id),
Predicate.EQ("version", expectedVersion));
int update = update(task, predicate);
return update == 1;
} else {
return false;
}
}
@Override
public void updateStatusAndTaskEndTime(Long id, TaskStatus oldStatus, TaskStatus newStatus,
Long taskEndTime) {
TaskDTO task = findById(id);
if (task.getStatus().equals(oldStatus)) {
task.setStatus(newStatus);
task.setEndTime(taskEndTime);
save(task);
}
}
@Override
@Transactional
public int deleteRecordsOlderThanDaysWithStatus(int days, TaskStatus status) {
DateTime expireDate = new DateTime().minusDays(days);
Timestamp expireTimestamp = new Timestamp(expireDate.getMillis());
Predicate timestampPredicate = Predicate.LT("createTime", expireTimestamp);
Predicate statusPredicate = Predicate.EQ("status", status.toString());
List<TaskBean> list =
genericPojoDao.get(Predicate.AND(statusPredicate, timestampPredicate), TaskBean.class);
for (TaskBean bean : list) {
deleteById(bean.getId());
}
return list.size();
}
@Override
@Transactional
public List<TaskDTO> findByStatusNotIn(TaskStatus status) {
Predicate statusPredicate = Predicate.NEQ("status", status.toString());
return findByPredicate(statusPredicate);
}
}