FINERACT-2119: Address jobs by name
This commit is contained in:
committed by
Adam Saghy
parent
eef6a8da5e
commit
3aaa2ffe9c
+74
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* 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.fineract.infrastructure.core.api;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.apache.fineract.infrastructure.core.service.DefaultOption;
|
||||
|
||||
@AllArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
@Getter
|
||||
public abstract class IdTypeResolver {
|
||||
|
||||
public enum IdType implements DefaultOption {
|
||||
|
||||
ID, //
|
||||
EXTERNAL_ID, //
|
||||
SHORT_NAME,; //
|
||||
|
||||
@Override
|
||||
public boolean isDefault() {
|
||||
return this == ID;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static IdType resolveDefault() {
|
||||
return IdType.ID;
|
||||
}
|
||||
|
||||
public static IdType resolve(String idType) {
|
||||
return resolve(IdType.class, idType);
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> T resolve(@NotNull Class<T> clazz, String idType) {
|
||||
if (idType == null) {
|
||||
return clazz.isAssignableFrom(DefaultOption.class) ? (T) DefaultOption.getDefault((Class) clazz) : null;
|
||||
}
|
||||
idType = formatIdType(idType);
|
||||
try {
|
||||
return Enum.valueOf(clazz, idType);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw resolveFailed(idType, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String formatIdType(String idType) {
|
||||
return idType == null ? null : idType.replaceAll("-", "_").toUpperCase();
|
||||
}
|
||||
|
||||
public static RuntimeException resolveFailed(String idType, Exception e) {
|
||||
return new PlatformApiDataValidationException("error.msg.id.type.not.found", "Provided type " + idType + " is not supported",
|
||||
"idType", e, idType);
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -51,14 +51,18 @@ public class MultiException extends Exception {
|
||||
private final List<Throwable> throwables;
|
||||
|
||||
@SuppressFBWarnings("CT_CONSTRUCTOR_THROW")
|
||||
public MultiException(List<Throwable> problems) {
|
||||
super("MultiException with " + problems.size() + " contained causes (details available)");
|
||||
public MultiException(String message, List<Throwable> problems) {
|
||||
super(message);
|
||||
if (problems.isEmpty()) {
|
||||
throw new IllegalArgumentException("List of Throwables must not be empty");
|
||||
}
|
||||
this.throwables = new ArrayList<>(problems);
|
||||
}
|
||||
|
||||
public MultiException(List<Throwable> problems) {
|
||||
this("MultiException with " + problems.size() + " contained causes (details available)", problems);
|
||||
}
|
||||
|
||||
public List<Throwable> getCauses() {
|
||||
return Collections.unmodifiableList(throwables);
|
||||
}
|
||||
|
||||
+12
@@ -56,6 +56,18 @@ public class PlatformApiDataValidationException extends AbstractPlatformExceptio
|
||||
this.errors = errors;
|
||||
}
|
||||
|
||||
public PlatformApiDataValidationException(String messageCode, String userMessage, String parameterName, Throwable cause,
|
||||
final Object... userMessageArgs) {
|
||||
this("validation.msg.validation.errors.exist", "Validation errors exist.",
|
||||
List.of(ApiParameterError.parameterError(messageCode, userMessage, parameterName, userMessageArgs)), cause);
|
||||
}
|
||||
|
||||
public PlatformApiDataValidationException(String messageCode, String userMessage, String parameterName,
|
||||
final Object... userMessageArgs) {
|
||||
this("validation.msg.validation.errors.exist", "Validation errors exist.",
|
||||
List.of(ApiParameterError.parameterError(messageCode, userMessage, parameterName, userMessageArgs)), null);
|
||||
}
|
||||
|
||||
public List<ApiParameterError> getErrors() {
|
||||
return this.errors;
|
||||
}
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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.fineract.infrastructure.core.service;
|
||||
|
||||
public interface DefaultOption {
|
||||
|
||||
boolean isDefault();
|
||||
|
||||
static <T extends Enum<T> & DefaultOption> T getDefault(Class<T> clazz) {
|
||||
for (T enumConstant : clazz.getEnumConstants()) {
|
||||
if (enumConstant.isDefault()) {
|
||||
return enumConstant;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+21
@@ -34,6 +34,9 @@ public class JobDetailData {
|
||||
@SuppressWarnings("unused")
|
||||
private String displayName;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private String shortName;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private Date nextRunTime;
|
||||
|
||||
@@ -50,4 +53,22 @@ public class JobDetailData {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private JobDetailHistoryData lastRunHistory;
|
||||
|
||||
public JobDetailData(Long jobId, String displayName, String shortName, Date nextRunTime, String initializingError,
|
||||
String cronExpression, boolean active, boolean currentlyRunning, Long version, Date jobRunStartTime, Date jobRunEndTime,
|
||||
String status, String jobRunErrorMessage, String triggerType, String jobRunErrorLog) {
|
||||
this.jobId = jobId;
|
||||
this.displayName = displayName;
|
||||
this.shortName = shortName;
|
||||
this.nextRunTime = nextRunTime;
|
||||
this.initializingError = initializingError;
|
||||
this.cronExpression = cronExpression;
|
||||
this.active = active;
|
||||
this.currentlyRunning = currentlyRunning;
|
||||
if (version != null) {
|
||||
this.lastRunHistory = new JobDetailHistoryData().setVersion(version).setJobRunStartTime(jobRunStartTime)
|
||||
.setJobRunEndTime(jobRunEndTime).setStatus(status).setJobRunErrorMessage(jobRunErrorMessage).setTriggerType(triggerType)
|
||||
.setJobRunErrorLog(jobRunErrorLog);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+35
@@ -18,11 +18,23 @@
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.jobs.exception;
|
||||
|
||||
import static java.util.stream.Collectors.mapping;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.apache.fineract.infrastructure.core.exception.MultiException;
|
||||
|
||||
public class JobExecutionException extends MultiException {
|
||||
|
||||
public JobExecutionException(String message, List<Throwable> problems) {
|
||||
super(message, problems);
|
||||
}
|
||||
|
||||
public JobExecutionException(List<Throwable> problems) {
|
||||
super(problems);
|
||||
}
|
||||
@@ -30,4 +42,27 @@ public class JobExecutionException extends MultiException {
|
||||
public JobExecutionException(MultiException multiException) {
|
||||
super(multiException.getCauses());
|
||||
}
|
||||
|
||||
public static void throwErrors(@NotNull Map<Throwable, List<String>> errorMap) throws JobExecutionException {
|
||||
int size = errorMap.size();
|
||||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
List<Throwable> errors;
|
||||
StringBuilder msg = new StringBuilder("Job failed on ");
|
||||
Stream<Map.Entry<Throwable, List<String>>> entryStream = errorMap.entrySet().stream().filter(e -> e.getValue() != null);
|
||||
if (size < 10) {
|
||||
errors = new ArrayList<>(errorMap.keySet());
|
||||
Map<String, List<List<String>>> errorTypes = entryStream
|
||||
.collect(Collectors.groupingBy(e -> e.getKey().getClass().getSimpleName(), mapping(Map.Entry::getValue, toList())));
|
||||
errorTypes.forEach((key, value) -> msg.append(key).append(':').append(value.size()).append(':')
|
||||
.append(value.stream().flatMap(List::stream).collect(Collectors.joining(","))).append(";\n"));
|
||||
} else {
|
||||
errors = List.of(errorMap.keySet().iterator().next());
|
||||
Map<String, Long> errorTypes = entryStream
|
||||
.collect(Collectors.groupingBy(e -> e.getKey().getClass().getSimpleName(), Collectors.counting()));
|
||||
errorTypes.forEach((key, value) -> msg.append(key).append(':').append(value).append(";\n"));
|
||||
}
|
||||
throw new JobExecutionException(msg.toString(), errors);
|
||||
}
|
||||
}
|
||||
|
||||
+8
-5
@@ -18,7 +18,9 @@
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.jobs.service;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.infrastructure.core.api.IdTypeResolver;
|
||||
import org.apache.fineract.infrastructure.core.service.Page;
|
||||
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
||||
import org.apache.fineract.infrastructure.jobs.data.JobDetailData;
|
||||
@@ -26,14 +28,15 @@ import org.apache.fineract.infrastructure.jobs.data.JobDetailHistoryData;
|
||||
|
||||
public interface SchedulerJobRunnerReadService {
|
||||
|
||||
List<JobDetailData> findAllJobDeatils();
|
||||
List<JobDetailData> findAllJobDetails();
|
||||
|
||||
JobDetailData retrieveOne(Long jobId);
|
||||
JobDetailData retrieveOne(@NotNull IdTypeResolver.IdType idType, String identifier);
|
||||
|
||||
JobDetailData retrieveOneByName(String jobName);
|
||||
Page<JobDetailHistoryData> retrieveJobHistory(@NotNull IdTypeResolver.IdType idType, String identifier,
|
||||
SearchParameters searchParameters);
|
||||
|
||||
Page<JobDetailHistoryData> retrieveJobHistory(Long jobId, SearchParameters searchParameters);
|
||||
@NotNull
|
||||
Long retrieveId(@NotNull IdTypeResolver.IdType idType, String identifier);
|
||||
|
||||
boolean isUpdatesAllowed();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user