package com.kn.lx.domain;
import com.kn.lx.util.Constants;
import com.kn.lx.config.Properties;
import com.kn.lx.input.elastic.QueryResultItemTO;
import com.kn.lx.input.elastic.QueryService;
import com.kn.lx.input.elastic.pr.PrQuery;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.apache.causeway.applib.annotation.Action;
import org.apache.causeway.applib.annotation.ActionLayout;
import org.apache.causeway.applib.annotation.DomainService;
import org.apache.causeway.applib.annotation.NatureOfService;
import org.apache.causeway.applib.annotation.Programmatic;
import org.apache.causeway.applib.annotation.SemanticsOf;
import org.springframework.transaction.annotation.Transactional;
import javax.inject.Inject;
import javax.inject.Named;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
@Named("lx.Tasks")
@DomainService(nature = NatureOfService.VIEW)
@RequiredArgsConstructor(onConstructor_ = {@Inject})
public class Tasks {
private final TaskRepository taskRepository;
private final QueryService queryService;
private final Executions executions;
private final Properties properties;
@Programmatic
public Task create(String className) {
final Task obj = new Task();
obj.setQueryClassName(className);
obj.setCronExpression(Constants.INSTANCE.getEVERY_FIVE_MINUTES());
obj.setActive(true);
taskRepository.saveAndFlush(obj);
return obj;
}
@ActionLayout(sequence = "1")
public List<Task> listAll() {
return taskRepository.findAll();
}
public void init() {
createIfAbsent(PrQuery.class.getCanonicalName());
}
@ActionLayout(sequence = "2")
public void createIfAbsent(final String name) {
final Task obj = taskRepository.findByQueryClassName(name);
if (null == obj) {
create(name);
}
}
@Action(semantics = SemanticsOf.SAFE)
@ActionLayout(sequence = "3", cssClassFa = "trash")
public void delete(Task task) {
taskRepository.delete(task);
}
List<QueryResultItemTO> executeQuery(PrQuery query) {
final Integer chunkSize = properties.getInteger(Constants.INSTANCE.getELASTIC_QUERY_CHUNK_SIZE());
query.setMaxNumberOfHits(chunkSize);
String latestTimeStamp = properties.getString(Constants.INSTANCE.getEND_TIME_STAMP());
if (latestTimeStamp.isEmpty()) {
latestTimeStamp = properties.getString(Constants.INSTANCE.getSTART_TIME_STAMP());
}
return queryService.searchBy(query, latestTimeStamp);
}
@NonNull PrQuery createForClass(String queryClassName) {
try {
return (PrQuery) Class.forName(queryClassName).getDeclaredConstructor().newInstance();
} catch (InstantiationException |
IllegalAccessException |
ClassNotFoundException |
InvocationTargetException |
NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
@Transactional
public Task execute(Task argTask) {
final Task task = update(argTask);
if (task.isActive()) {
final PrQuery query = createForClass(task.getQueryClassName());
final List<QueryResultItemTO> queryResultList = executeQuery(query);
final Execution e = executions.create(task, queryResultList);
e.setEndedAt(LocalDateTime.now());
e.setHits((long) queryResultList.size());
task.getExecutionList().add(e);
taskRepository.saveAndFlush(task);
executions.sendMessagesFor(e);
return task;
}
return null;
}
/**
* It seems argTask is out of sync when it reaches this point.
* Read it again.
*
* @param argTask Task to be synced
* @return Task, synced with DB
*/
private Task update(Task argTask) {
final Optional<? extends Task> optionalTask = taskRepository.findById(argTask.getId());
if (optionalTask.isPresent()) {
return optionalTask.get();
} else {
throw new RuntimeException("Task not found");
}
}
}