Skip to content

Commit

Permalink
Throw exception if lazy validation processing detects any errors
Browse files Browse the repository at this point in the history
  • Loading branch information
todvora committed Apr 19, 2024
1 parent 28af121 commit 3ab4f76
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 34 deletions.
16 changes: 10 additions & 6 deletions src/main/java/com/github/joschi/jadconfig/JadConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,18 @@ public void process() throws RepositoryException, ValidationException {
/**
* Processes the configuration provided by the configured {@link Repository} and filling the provided configuration
* beans.
*
* Instead of stopping processing on first encountered exception, tries to collect all validation problems and return them in single response,
* allowing identifying many problems at once.
*
* @return Response object, containing encountered problems if processing was not successful.
* <p>
* Instead of stopping processing on first encountered exception, tries to collect all validation problems and in
* case of any problems aggregate them all into single exception, listing all the field and validation issues.
*/
public ProcessingResponse processFailingLazily() throws RepositoryException {
public void processFailingLazily() throws RepositoryException, LazyValidationException {
final ProcessingResponse result = doProcessFailingLazily();
if (!result.isSuccess()) {
throw new LazyValidationException(result);
}
}

ProcessingResponse doProcessFailingLazily() throws RepositoryException {
ProcessingResponse response = new ProcessingResponse();

for (Repository repository : repositories) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.github.joschi.jadconfig;

import com.github.joschi.jadconfig.response.ProcessingOutcome;
import com.github.joschi.jadconfig.response.ProcessingResponse;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.Stream;

public class LazyValidationException extends ValidationException {
private final ProcessingResponse processingResponse;

public LazyValidationException(ProcessingResponse result) {
super(toMessage(result));
this.processingResponse = result;
}

private static String toMessage(ProcessingResponse result) {
final List<String> stringBuilder = new LinkedList<>();
stringBuilder.add("Following errors ocurred during configuration processing:");
result.getOutcomes().stream()
.filter(ProcessingOutcome::hasProblems)
.flatMap(processingOutcome -> Stream.concat(
processingOutcome.getFieldProcessingProblems().values().stream().map(e -> toMessage(processingOutcome, e)),
processingOutcome.getValidationMethodsProblems().values().stream().map(e -> toMessage(processingOutcome, e))
)).forEach(stringBuilder::add);
return String.join("\n", stringBuilder);
}

private static String toMessage(ProcessingOutcome processingOutcome, Exception exception) {
// TODO: should we distinct between field processing problem and validation method?
// TODO: should we include class name of the bean or not?
return exception.getMessage();
}

public ProcessingResponse getProcessingResponse() {
return processingResponse;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.github.joschi.jadconfig.response.ProcessingOutcome;
import com.github.joschi.jadconfig.response.ProcessingResponse;
import com.github.joschi.jadconfig.testbeans.ValidatedConfigurationBean;
import org.junit.Assert;
import org.junit.Test;

import java.util.HashMap;
Expand All @@ -13,35 +14,37 @@

public class JadConfigLazyProcessingTest {

private JadConfig jadConfig;
private Repository repository;


@Test
public void testProcess() throws RepositoryException {
HashMap<String, String> properties = new HashMap<>();
properties.put("test.byte","1");
properties.put("test.short","2");
properties.put("test.integer","-3");//negative, smaller than test.short
properties.put("test.integer.port","70000"); //bigger than allowed port
properties.put("test.long","4");
properties.put("test.string","Test");
repository = new InMemoryRepository(properties);
properties.put("test.byte", "1");
properties.put("test.short", "2");
properties.put("test.integer", "-3");//negative, smaller than test.short
properties.put("test.integer.port", "70000"); //bigger than allowed port
properties.put("test.long", "4");
properties.put("test.string", "Test");
Repository repository = new InMemoryRepository(properties);
ValidatedConfigurationBean configurationBean = new ValidatedConfigurationBean();
jadConfig = new JadConfig(repository, configurationBean);

ProcessingResponse response = jadConfig.processFailingLazily();
assertFalse(response.isSuccess());
assertEquals(1, response.getOutcomes().size());
ProcessingOutcome processingOutcome = response.getOutcomes().get(0);
assertEquals(configurationBean, processingOutcome.getConfigurationBean());
Map<String, Exception> fieldProcessingProblems = processingOutcome.getFieldProcessingProblems();
assertEquals(2, fieldProcessingProblems.size());
assertTrue(fieldProcessingProblems.containsKey("test.integer"));
assertTrue(fieldProcessingProblems.containsKey("test.integer.port"));

Map<String, Exception> validationMethodsProblems = processingOutcome.getValidationMethodsProblems();
assertEquals(1, validationMethodsProblems.size());
assertTrue(validationMethodsProblems.containsKey("validate"));
JadConfig jadConfig = new JadConfig(repository, configurationBean);
try {
jadConfig.processFailingLazily();
Assert.fail("Should throw an exception!");
} catch (LazyValidationException e) {
final ProcessingResponse response = e.getProcessingResponse();
assertFalse(response.isSuccess());
assertEquals(1, response.getOutcomes().size());
ProcessingOutcome processingOutcome = response.getOutcomes().get(0);
assertEquals(configurationBean, processingOutcome.getConfigurationBean());
Map<String, Exception> fieldProcessingProblems = processingOutcome.getFieldProcessingProblems();
assertEquals(2, fieldProcessingProblems.size());
assertTrue(fieldProcessingProblems.containsKey("test.integer"));
assertTrue(fieldProcessingProblems.containsKey("test.integer.port"));

Map<String, Exception> validationMethodsProblems = processingOutcome.getValidationMethodsProblems();
assertEquals(1, validationMethodsProblems.size());
assertTrue(validationMethodsProblems.containsKey("myCustomValidatorMethod"));
}


}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import com.github.joschi.jadconfig.validators.NoValidator;
import com.github.joschi.jadconfig.validators.PositiveIntegerValidator;
import com.github.joschi.jadconfig.validators.PositiveLongValidator;
import com.github.joschi.jadconfig.validators.PositiveSizeValidator;

public class ValidatedConfigurationBean {

Expand Down Expand Up @@ -54,7 +53,7 @@ public long getMyLong() {
}

@ValidatorMethod
public void validate() throws ValidationException {
public void myCustomValidatorMethod() throws ValidationException {

if (!"Test".equals(myString)) {
throw new ValidationException("BOOM");
Expand Down

0 comments on commit 3ab4f76

Please sign in to comment.