Skip to content

Commit 325642b

Browse files
committed
Introduce ValidatorSource.
1 parent 3831a4d commit 325642b

File tree

9 files changed

+87
-33
lines changed

9 files changed

+87
-33
lines changed

readme.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ Use `WrapErrors` to wrap all exceptions in `ServiceException.InternalError` with
8181

8282
Provide `CorrelationSource` to enable correlations for error responses.
8383

84+
Provide `ValidatorSource` to configure a resource manager for validators.
85+
8486
[json-data]: https://github.com/hrytsenko/json-data
8587
[Spring Boot]: https://spring.io/projects/spring-boot
8688
[Spring Cloud OpenFeign]: https://spring.io/projects/spring-cloud-openfeign

src/main/java/com/github/hrytsenko/jsondata/springboot/AutoConfiguration.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
*/
1616
package com.github.hrytsenko.jsondata.springboot;
1717

18+
import com.github.hrytsenko.jsondata.JsonResources;
19+
import com.github.hrytsenko.jsondata.JsonValidator;
1820
import com.github.hrytsenko.jsondata.springboot.error.CorrelationSource;
21+
import com.github.hrytsenko.jsondata.springboot.web.ValidatorSource;
1922
import lombok.extern.slf4j.Slf4j;
2023
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2124
import org.springframework.context.annotation.Bean;
@@ -34,4 +37,14 @@ public CorrelationSource undefinedCorrelationSource() {
3437
return () -> "UNDEFINED";
3538
}
3639

40+
@Bean
41+
@ConditionalOnMissingBean
42+
public ValidatorSource defaultValidatorSource() {
43+
log.info("Use default validator source");
44+
return resourceName -> {
45+
String schema = JsonResources.readResource(resourceName);
46+
return JsonValidator.create(schema);
47+
};
48+
}
49+
3750
}

src/main/java/com/github/hrytsenko/jsondata/springboot/web/ValidateRequestAspect.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@
1616
package com.github.hrytsenko.jsondata.springboot.web;
1717

1818
import com.github.hrytsenko.jsondata.JsonEntity;
19-
import com.github.hrytsenko.jsondata.JsonResources;
20-
import com.github.hrytsenko.jsondata.JsonValidator;
2119
import com.github.hrytsenko.jsondata.JsonValidatorException;
20+
import lombok.AllArgsConstructor;
2221
import org.aspectj.lang.JoinPoint;
2322
import org.aspectj.lang.annotation.Aspect;
2423
import org.aspectj.lang.annotation.Before;
@@ -28,23 +27,22 @@
2827
@Aspect
2928
@Order(0)
3029
@Configuration
30+
@AllArgsConstructor
3131
class ValidateRequestAspect {
3232

33+
ValidatorSource validatorSource;
34+
3335
@Before("@annotation(config)")
3436
public void handle(JoinPoint point, ValidateRequest config) {
3537
JsonEntity<?> target = (JsonEntity<?>) point.getArgs()[0];
3638

37-
String resourceName = config.value();
39+
String schemaName = config.value();
3840
try {
39-
JsonValidator.create(loadSchema(resourceName))
41+
validatorSource.getValidator(schemaName)
4042
.validate(target);
4143
} catch (JsonValidatorException exception) {
42-
throw new ValidateRequestException("Invalid request " + resourceName, exception);
44+
throw new ValidateRequestException("Invalid request " + schemaName, exception);
4345
}
4446
}
4547

46-
String loadSchema(String resourceName) {
47-
return JsonResources.readResource(resourceName);
48-
}
49-
5048
}

src/main/java/com/github/hrytsenko/jsondata/springboot/web/ValidateResponseAspect.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@
1616
package com.github.hrytsenko.jsondata.springboot.web;
1717

1818
import com.github.hrytsenko.jsondata.JsonEntity;
19-
import com.github.hrytsenko.jsondata.JsonResources;
20-
import com.github.hrytsenko.jsondata.JsonValidator;
2119
import com.github.hrytsenko.jsondata.JsonValidatorException;
20+
import lombok.AllArgsConstructor;
2221
import lombok.SneakyThrows;
2322
import org.aspectj.lang.ProceedingJoinPoint;
2423
import org.aspectj.lang.annotation.Around;
@@ -29,26 +28,24 @@
2928
@Aspect
3029
@Order(0)
3130
@Configuration
31+
@AllArgsConstructor
3232
class ValidateResponseAspect {
3333

34+
ValidatorSource validatorSource;
35+
3436
@Around("@annotation(config)")
3537
@SneakyThrows
3638
public Object handle(ProceedingJoinPoint point, ValidateResponse config) {
3739
JsonEntity<?> target = (JsonEntity<?>) point.proceed();
3840

39-
String resourceName = config.value();
41+
String schemaName = config.value();
4042
try {
41-
JsonValidator.create(loadSchema(resourceName))
43+
validatorSource.getValidator(config.value())
4244
.validate(target);
4345
} catch (JsonValidatorException exception) {
44-
throw new ValidateResponseException("Invalid response " + resourceName, exception);
46+
throw new ValidateResponseException("Invalid response " + schemaName, exception);
4547
}
4648

4749
return target;
4850
}
49-
50-
String loadSchema(String resourceName) {
51-
return JsonResources.readResource(resourceName);
52-
}
53-
5451
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (C) 2020 Anton Hrytsenko
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.github.hrytsenko.jsondata.springboot.web;
17+
18+
import com.github.hrytsenko.jsondata.JsonValidator;
19+
20+
public interface ValidatorSource {
21+
22+
JsonValidator getValidator(String name);
23+
24+
}

src/test/java/com/github/hrytsenko/jsondata/springboot/AutoConfigurationTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package com.github.hrytsenko.jsondata.springboot;
1717

1818
import com.github.hrytsenko.jsondata.springboot.error.CorrelationSource;
19+
import com.github.hrytsenko.jsondata.springboot.web.ValidatorSource;
1920
import org.junit.jupiter.api.Assertions;
2021
import org.junit.jupiter.api.Test;
2122

@@ -30,4 +31,12 @@ void correlationSource_undefined() {
3031
Assertions.assertEquals("UNDEFINED", actualCorrelation);
3132
}
3233

34+
@Test
35+
void validatorSource_default() {
36+
ValidatorSource validatorSource = new AutoConfiguration().defaultValidatorSource();
37+
38+
Assertions.assertDoesNotThrow(
39+
() -> validatorSource.getValidator("empty-schema.json"));
40+
}
41+
3342
}

src/test/java/com/github/hrytsenko/jsondata/springboot/web/ValidateRequestAspectTest.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.github.hrytsenko.jsondata.JsonBean;
1919
import com.github.hrytsenko.jsondata.JsonParser;
20+
import com.github.hrytsenko.jsondata.JsonValidator;
2021
import org.aspectj.lang.JoinPoint;
2122
import org.junit.jupiter.api.Assertions;
2223
import org.junit.jupiter.api.BeforeEach;
@@ -25,38 +26,42 @@
2526

2627
class ValidateRequestAspectTest {
2728

29+
ValidatorSource validatorSource;
2830
ValidateRequestAspect aspect;
2931

3032
@BeforeEach
3133
void init() {
32-
aspect = Mockito.spy(new ValidateRequestAspect());
34+
validatorSource = Mockito.mock(ValidatorSource.class);
35+
aspect = new ValidateRequestAspect(validatorSource);
3336
}
3437

3538
@Test
3639
void validate_success() {
37-
String sourceSchema = "{\"properties\":{\"foo\":{\"enum\":[\"FOO\"]}},\"required\":[\"foo\"]}";
40+
JsonValidator sourceValidator = JsonValidator.create(
41+
"{\"properties\":{\"foo\":{\"enum\":[\"FOO\"]}},\"required\":[\"foo\"]}");
3842
JsonBean sourceRequest = JsonParser.stringToEntity("{'foo':'FOO'}", JsonBean::create);
3943

4044
JoinPoint sourceJoinPoint = mockJoinPoint(sourceRequest);
4145
ValidateRequest sourceConfig = Mockito.mock(ValidateRequest.class);
4246

43-
Mockito.doReturn(sourceSchema)
44-
.when(aspect).loadSchema(Mockito.any());
47+
Mockito.doReturn(sourceValidator)
48+
.when(validatorSource).getValidator(Mockito.any());
4549

4650
Assertions.assertDoesNotThrow(
4751
() -> aspect.handle(sourceJoinPoint, sourceConfig));
4852
}
4953

5054
@Test
5155
void validate_failure() {
52-
String sourceSchema = "{\"properties\":{\"foo\":{\"enum\":[\"FOO\"]}},\"required\":[\"foo\"]}";
56+
JsonValidator sourceValidator = JsonValidator.create(
57+
"{\"properties\":{\"foo\":{\"enum\":[\"FOO\"]}},\"required\":[\"foo\"]}");
5358
JsonBean sourceRequest = JsonParser.stringToEntity("{'foo':'BAR'}", JsonBean::create);
5459

5560
JoinPoint sourcePoint = mockJoinPoint(sourceRequest);
5661
ValidateRequest sourceConfig = Mockito.mock(ValidateRequest.class);
5762

58-
Mockito.doReturn(sourceSchema)
59-
.when(aspect).loadSchema(Mockito.any());
63+
Mockito.doReturn(sourceValidator)
64+
.when(validatorSource).getValidator(Mockito.any());
6065

6166
Assertions.assertThrows(ValidateRequestException.class,
6267
() -> aspect.handle(sourcePoint, sourceConfig));

src/test/java/com/github/hrytsenko/jsondata/springboot/web/ValidateResponseAspectTest.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.github.hrytsenko.jsondata.JsonBean;
1919
import com.github.hrytsenko.jsondata.JsonParser;
20+
import com.github.hrytsenko.jsondata.JsonValidator;
2021
import lombok.SneakyThrows;
2122
import org.aspectj.lang.ProceedingJoinPoint;
2223
import org.junit.jupiter.api.Assertions;
@@ -26,38 +27,42 @@
2627

2728
class ValidateResponseAspectTest {
2829

30+
ValidatorSource validatorSource;
2931
ValidateResponseAspect aspect;
3032

3133
@BeforeEach
3234
void init() {
33-
aspect = Mockito.spy(new ValidateResponseAspect());
35+
validatorSource = Mockito.mock(ValidatorSource.class);
36+
aspect = new ValidateResponseAspect(validatorSource);
3437
}
3538

3639
@Test
3740
void validate_success() {
38-
String sourceSchema = "{\"properties\":{\"foo\":{\"enum\":[\"FOO\"]}},\"required\":[\"foo\"]}";
41+
JsonValidator sourceValidator = JsonValidator.create(
42+
"{\"properties\":{\"foo\":{\"enum\":[\"FOO\"]}},\"required\":[\"foo\"]}");
3943
JsonBean sourceResponse = JsonParser.stringToEntity("{'foo':'FOO'}", JsonBean::create);
4044

4145
ProceedingJoinPoint sourceJoinPoint = mockJoinPoint(sourceResponse);
4246
ValidateResponse sourceConfig = Mockito.mock(ValidateResponse.class);
4347

44-
Mockito.doReturn(sourceSchema)
45-
.when(aspect).loadSchema(Mockito.any());
48+
Mockito.doReturn(sourceValidator)
49+
.when(validatorSource).getValidator(Mockito.any());
4650

4751
Assertions.assertDoesNotThrow(
4852
() -> aspect.handle(sourceJoinPoint, sourceConfig));
4953
}
5054

5155
@Test
5256
void validate_failure() {
53-
String sourceSchema = "{\"properties\":{\"foo\":{\"enum\":[\"FOO\"]}},\"required\":[\"foo\"]}";
57+
JsonValidator sourceValidator = JsonValidator.create(
58+
"{\"properties\":{\"foo\":{\"enum\":[\"FOO\"]}},\"required\":[\"foo\"]}");
5459
JsonBean sourceResponse = JsonParser.stringToEntity("{'foo':'BAR'}", JsonBean::create);
5560

5661
ProceedingJoinPoint sourcePoint = mockJoinPoint(sourceResponse);
5762
ValidateResponse sourceConfig = Mockito.mock(ValidateResponse.class);
5863

59-
Mockito.doReturn(sourceSchema)
60-
.when(aspect).loadSchema(Mockito.any());
64+
Mockito.doReturn(sourceValidator)
65+
.when(validatorSource).getValidator(Mockito.any());
6166

6267
Assertions.assertThrows(ValidateResponseException.class,
6368
() -> aspect.handle(sourcePoint, sourceConfig));
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

0 commit comments

Comments
 (0)