blob: 5c3c2342507e733bd0a18ade2b6994af6d389f63 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.elasticjob.lite.ui.service.impl;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.elasticjob.tracing.event.JobExecutionEvent;
import org.apache.shardingsphere.elasticjob.tracing.event.JobStatusTraceEvent;
import org.apache.shardingsphere.elasticjob.lite.ui.dao.search.JobExecutionLogRepository;
import org.apache.shardingsphere.elasticjob.lite.ui.dao.search.JobStatusTraceLogRepository;
import org.apache.shardingsphere.elasticjob.lite.ui.domain.JobExecutionLog;
import org.apache.shardingsphere.elasticjob.lite.ui.domain.JobStatusTraceLog;
import org.apache.shardingsphere.elasticjob.lite.ui.dto.request.BasePageRequest;
import org.apache.shardingsphere.elasticjob.lite.ui.dto.request.FindJobExecutionEventsRequest;
import org.apache.shardingsphere.elasticjob.lite.ui.dto.request.FindJobStatusTraceEventsRequest;
import org.apache.shardingsphere.elasticjob.lite.ui.service.EventTraceHistoryService;
import org.apache.shardingsphere.elasticjob.lite.ui.util.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.convert.QueryByExamplePredicateBuilder;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import javax.persistence.criteria.Predicate;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* Event trace history service implementation.
*/
@Slf4j
@Component
public final class EventTraceHistoryServiceImpl implements EventTraceHistoryService {
@Autowired
private JobExecutionLogRepository jobExecutionLogRepository;
@Autowired
private JobStatusTraceLogRepository jobStatusTraceLogRepository;
@Override
public Page<JobExecutionEvent> findJobExecutionEvents(final FindJobExecutionEventsRequest findJobExecutionEventsRequest) {
Example<JobExecutionLog> jobExecutionLogExample = getExample(findJobExecutionEventsRequest, JobExecutionLog.class);
Specification<JobExecutionLog> specification = getSpecWithExampleAndDate(jobExecutionLogExample, findJobExecutionEventsRequest.getStart(),
findJobExecutionEventsRequest.getEnd(), "startTime");
Page<JobExecutionLog> page = jobExecutionLogRepository.findAll(specification, getPageable(findJobExecutionEventsRequest, JobExecutionLog.class));
return new PageImpl<>(page.getContent().stream().map(JobExecutionLog::toJobExecutionEvent).collect(Collectors.toList()), null, page.getTotalElements());
}
@Override
public List<String> findJobNamesInExecutionLog(final String jobNamePrefix) {
return jobExecutionLogRepository.findJobNameByJobNameLike(jobNamePrefix);
}
@Override
public List<String> findIpInExecutionLog(final String ipPrefix) {
return jobExecutionLogRepository.findIpByIpLike(ipPrefix);
}
@Override
public Page<JobStatusTraceEvent> findJobStatusTraceEvents(final FindJobStatusTraceEventsRequest findJobStatusTraceEventsRequest) {
Example<JobStatusTraceLog> jobStatusTraceLogExample = getExample(findJobStatusTraceEventsRequest, JobStatusTraceLog.class);
Specification<JobStatusTraceLog> specification = getSpecWithExampleAndDate(jobStatusTraceLogExample, findJobStatusTraceEventsRequest.getStart(),
findJobStatusTraceEventsRequest.getEnd(), "creationTime");
Page<JobStatusTraceLog> page = jobStatusTraceLogRepository.findAll(specification, getPageable(findJobStatusTraceEventsRequest, JobStatusTraceLog.class));
return new PageImpl<>(page.getContent().stream().map(JobStatusTraceLog::toJobStatusTraceEvent).collect(Collectors.toList()), null, page.getTotalElements());
}
private <T> Pageable getPageable(final BasePageRequest pageRequest, final Class<T> clazz) {
int page = 0;
int perPage = BasePageRequest.DEFAULT_PAGE_SIZE;
if (pageRequest.getPageNumber() > 0 && pageRequest.getPageSize() > 0) {
page = pageRequest.getPageNumber() - 1;
perPage = pageRequest.getPageSize();
}
return new PageRequest(page, perPage, getSort(pageRequest, clazz));
}
private <T> Sort getSort(final BasePageRequest pageRequest, final Class<T> clazz) {
Sort sort = null;
boolean sortFieldIsPresent = Arrays.stream(clazz.getDeclaredFields())
.map(Field::getName)
.anyMatch(e -> e.equals(pageRequest.getSortBy()));
if (!sortFieldIsPresent) {
return sort;
}
if (!Strings.isNullOrEmpty(pageRequest.getSortBy())) {
Sort.Direction order = Sort.Direction.ASC;
try {
order = Sort.Direction.valueOf(pageRequest.getOrderType());
} catch (IllegalArgumentException ignored) {
}
sort = new Sort(order, pageRequest.getSortBy());
}
return sort;
}
private <T> Specification<T> getSpecWithExampleAndDate(final Example<T> example, final Date from, final Date to, final String field) {
return (root, query, builder) -> {
final List<Predicate> predicates = new ArrayList<>();
if (from != null) {
predicates.add(builder.greaterThan(root.get(field), from));
}
if (to != null) {
predicates.add(builder.lessThan(root.get(field), to));
}
predicates.add(QueryByExamplePredicateBuilder.getPredicate(root, builder, example));
return builder.and(predicates.toArray(new Predicate[0]));
};
}
private <T> Example<T> getExample(final Object source, final Class<T> clazz) {
T instance = BeanUtils.newInstance(clazz);
BeanUtils.copyProperties(source, instance);
return Example.of(instance);
}
}