generated from micronaut-projects/micronaut-project-template
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
remove properties file
- Loading branch information
Showing
42 changed files
with
1,076 additions
and
191 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
plugins { | ||
id("io.micronaut.build.internal.json-schema-module") | ||
} | ||
dependencies { | ||
api(mn.micronaut.json.core) | ||
api(projects.micronautJsonSchemaAnnotations) | ||
api(libs.managed.json.schema.validator) | ||
|
||
// JSON Schema | ||
testAnnotationProcessor(projects.micronautJsonSchemaProcessor) | ||
|
||
// Validation | ||
testAnnotationProcessor(mnValidation.micronaut.validation.processor) | ||
testImplementation(mnValidation.micronaut.validation) | ||
|
||
// Serialization | ||
testImplementation(mn.micronaut.jackson.databind) | ||
|
||
testAnnotationProcessor(mn.micronaut.inject.java) | ||
testImplementation(libs.junit.jupiter.api) | ||
testImplementation(mnTest.micronaut.test.junit5) | ||
testRuntimeOnly(libs.junit.jupiter.engine) | ||
testImplementation(libs.junit.jupiter.params) | ||
} |
133 changes: 133 additions & 0 deletions
133
...lidation/src/main/java/io/micronaut/jsonschema/validation/DefaultJsonSchemaValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
/* | ||
* Copyright 2017-2024 original authors | ||
* | ||
* Licensed 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 | ||
* | ||
* https://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 io.micronaut.jsonschema.validation; | ||
|
||
import com.networknt.schema.*; | ||
import com.networknt.schema.resource.SchemaMappers; | ||
import io.micronaut.core.annotation.AnnotationValue; | ||
import io.micronaut.core.annotation.Internal; | ||
import io.micronaut.core.annotation.NonNull; | ||
import io.micronaut.core.beans.BeanIntrospection; | ||
import io.micronaut.core.beans.exceptions.IntrospectionException; | ||
import io.micronaut.core.io.ResourceLoader; | ||
import io.micronaut.core.naming.NameUtils; | ||
import io.micronaut.json.JsonMapper; | ||
import jakarta.inject.Singleton; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.net.MalformedURLException; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import java.util.Set; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
import java.util.function.Consumer; | ||
import java.util.function.Function; | ||
import java.util.stream.Collectors; | ||
|
||
@Singleton | ||
@Internal | ||
final class DefaultJsonSchemaValidator implements JsonSchemaValidator { | ||
private static final Logger LOG = LoggerFactory.getLogger(DefaultJsonSchemaValidator.class); | ||
private static final String CLASSPATH_PREFIX = "classpath:META-INF/schemas/"; | ||
private static final String SUFFIX = ".schema.json"; | ||
private static final String MEMBER_URI = "uri"; | ||
private static final ExecutionContextCustomizer CONTEXT_CUSTOMIZER = (executionContext, validationContext) -> { | ||
// By default since Draft 2019-09 the format keyword only generates annotations and not assertions | ||
validationContext.getConfig().setFormatAssertionsEnabled(true); | ||
}; | ||
|
||
private final Map<Class<?>, JsonSchema> jsonSchemaCache = new ConcurrentHashMap<>(); | ||
private final ResourceLoader resourceLoader; | ||
private final JsonMapper jsonMapper; | ||
private final SchemaValidatorsConfig schemaValidatorsConfig; | ||
|
||
DefaultJsonSchemaValidator(ResourceLoader resourceLoader, | ||
JsonMapper jsonMapper, | ||
SchemaValidatorsConfig schemaValidatorsConfig) { | ||
this.resourceLoader = resourceLoader; | ||
this.jsonMapper = jsonMapper; | ||
this.schemaValidatorsConfig = schemaValidatorsConfig; | ||
} | ||
|
||
@Override | ||
public <T> Set<? extends ValidationMessage> validate(@NonNull String json, @NonNull Class<T> type, List<Function<String, String>> mappings) { | ||
JsonSchema schema = jsonSchemaCache.computeIfAbsent(type, t -> jsonSchemaForClass(t, mappings)); | ||
return validate(schema, json); | ||
} | ||
|
||
@Override | ||
@NonNull | ||
public <T> Set<? extends ValidationMessage> validate(@NonNull Object value, @NonNull Class<T> type, List<Function<String, String>> mappings) throws IOException { | ||
JsonSchema schema = jsonSchemaCache.computeIfAbsent(type, t -> jsonSchemaForClass(t, mappings)); | ||
String json = jsonMapper.writeValueAsString(value); | ||
return validate(schema, json); | ||
} | ||
|
||
private <T> JsonSchema jsonSchemaForClass(@NonNull Class<T> type, List<Function<String, String>> mappings) { | ||
String jsonSchema = jsonSchemaStringForClass(type); | ||
if (jsonSchema == null) { | ||
throw new IllegalArgumentException("No schema found for type: " + type); | ||
} | ||
JsonSchemaFactory jsonSchemaFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012, builder -> { | ||
try { | ||
builder.schemaMappers(schemaMappersBuilderCustomizer(mappings)); | ||
} catch (MalformedURLException e) { | ||
LOG.warn("{}", e); | ||
} | ||
}); | ||
return jsonSchemaFactory.getSchema(jsonSchema, schemaValidatorsConfig); | ||
} | ||
|
||
private <T> String jsonSchemaStringForClass(@NonNull Class<T> type) { | ||
String path = jsonSchemaPath(type); | ||
try (InputStream inputStream = resourceLoader.getResourceAsStream(path).orElseThrow(() -> new IllegalArgumentException("No schema found for type: " + type + " at path: " + path))) { | ||
return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); | ||
} catch (IOException e) { | ||
return null; | ||
} | ||
} | ||
|
||
private static <T> String jsonSchemaPath(@NonNull Class<T> type) { | ||
String className = NameUtils.hyphenate(type.getSimpleName()); | ||
try { | ||
BeanIntrospection<T> introspection = BeanIntrospection.getIntrospection(type); | ||
AnnotationValue<io.micronaut.jsonschema.JsonSchema> jsonSchemaAnnotationValue = introspection.getAnnotation(io.micronaut.jsonschema.JsonSchema.class); | ||
Optional<String> uriOptional = jsonSchemaAnnotationValue.stringValue(MEMBER_URI); | ||
if (uriOptional.isPresent()) { | ||
className = uriOptional.get().replace("/", ""); | ||
} | ||
} catch (IntrospectionException e) { | ||
LOG.debug("Introspection exception for class {}.}", type, e); | ||
} | ||
String name = className + SUFFIX; | ||
return CLASSPATH_PREFIX + name; | ||
} | ||
|
||
private static Consumer<SchemaMappers.Builder> schemaMappersBuilderCustomizer(List<Function<String, String>> mappings) throws MalformedURLException { | ||
return builder -> mappings.forEach(builder::mappings); | ||
} | ||
|
||
private static Set<? extends ValidationMessage> validate(JsonSchema schema, String json) { | ||
return schema.validate(json, InputFormat.JSON, CONTEXT_CUSTOMIZER) | ||
.stream() | ||
.map(ValidationMessageAdapter::new) | ||
.collect(Collectors.toSet()); | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
...idation/src/main/java/io/micronaut/jsonschema/validation/JsonSchemaValidationFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Copyright 2017-2024 original authors | ||
* | ||
* Licensed 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 | ||
* | ||
* https://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 io.micronaut.jsonschema.validation; | ||
|
||
import com.networknt.schema.JsonSchemaFactory; | ||
import com.networknt.schema.PathType; | ||
import com.networknt.schema.SchemaValidatorsConfig; | ||
import io.micronaut.context.annotation.Bean; | ||
import io.micronaut.context.annotation.Factory; | ||
import io.micronaut.core.annotation.Internal; | ||
|
||
/** | ||
* {@link Factory} to instantiate {@link SchemaValidatorsConfig}, {@link JsonSchemaFactory} beans related to JSON Schema validation. | ||
* @author Sergio del Amo | ||
* @since 1.0.0 | ||
*/ | ||
@Internal | ||
@Factory | ||
class JsonSchemaValidationFactory { | ||
@Bean | ||
SchemaValidatorsConfig jsonSchemaValidator() { | ||
var config = new SchemaValidatorsConfig(); | ||
config.setPathType(PathType.JSON_POINTER); | ||
return config; | ||
} | ||
} |
85 changes: 85 additions & 0 deletions
85
...hema-validation/src/main/java/io/micronaut/jsonschema/validation/JsonSchemaValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/* | ||
* Copyright 2017-2024 original authors | ||
* | ||
* Licensed 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 | ||
* | ||
* https://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 io.micronaut.jsonschema.validation; | ||
|
||
import io.micronaut.context.annotation.DefaultImplementation; | ||
import io.micronaut.core.annotation.NonNull; | ||
|
||
import java.io.IOException; | ||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.function.Function; | ||
|
||
/** | ||
* JSON Schema Validator. | ||
* @author Sergio del Amo | ||
* @since 1.0.0 | ||
*/ | ||
@DefaultImplementation(DefaultJsonSchemaValidator.class) | ||
public interface JsonSchemaValidator { | ||
|
||
/** | ||
* | ||
* @param value JSON value to validate | ||
* @param type The type used to generate the JSON Schema | ||
* @return A set of validation messages. Empty if valid. | ||
* @param <T> Type used to generate the JSON Schema | ||
* @throws IOException If an error occurs validating the JSON against the schema. | ||
*/ | ||
@NonNull | ||
default <T> Set<? extends ValidationMessage> validate(@NonNull String value, @NonNull Class<T> type) throws IOException { | ||
return validate(value, type, List.of(s -> s.replace("http://localhost:8080/schemas", "classpath:META-INF/schemas"))); | ||
} | ||
|
||
|
||
|
||
/** | ||
* | ||
* @param value JSON value to validate | ||
* @param type The type used to generate the JSON Schema | ||
* @param mappings Additional mappings to be used when generating the JSON Schema | ||
* @return A set of validation messages. Empty if valid. | ||
* @param <T> Type used to generate the JSON Schema | ||
* @throws IOException If an error occurs validating the JSON against the schema. | ||
*/ | ||
@NonNull | ||
<T> Set<? extends ValidationMessage> validate(@NonNull String value, @NonNull Class<T> type, List<Function<String, String>> mappings) throws IOException; | ||
|
||
/** | ||
* | ||
* @param value Object to validate against a JSON schema | ||
* @param type The type used to generate the JSON Schema | ||
* @return A set of validation messages. Empty if valid. | ||
* @param <T> Type used to generate the JSON Schema | ||
* @throws IOException If an error occurs validating the JSON against the schema. | ||
*/ | ||
@NonNull | ||
default <T> Set<? extends ValidationMessage> validate(@NonNull Object value, @NonNull Class<T> type) throws IOException { | ||
return validate(value, type, List.of(s -> s.replace("http://localhost:8080/schemas", "classpath:META-INF/schemas"))); | ||
} | ||
|
||
/** | ||
* | ||
* @param value Object to validate against a JSON schema | ||
* @param type The type used to generate the JSON Schema | ||
* @param mappings Additional mappings to be used when generating the JSON Schema | ||
* @return A set of validation messages. Empty if valid. | ||
* @param <T> Type used to generate the JSON Schema | ||
* @throws IOException If an error occurs validating the JSON against the schema. | ||
*/ | ||
@NonNull | ||
<T> Set<? extends ValidationMessage> validate(@NonNull Object value, @NonNull Class<T> type, List<Function<String, String>> mappings) throws IOException; | ||
} |
31 changes: 31 additions & 0 deletions
31
...schema-validation/src/main/java/io/micronaut/jsonschema/validation/ValidationMessage.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* | ||
* Copyright 2017-2024 original authors | ||
* | ||
* Licensed 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 | ||
* | ||
* https://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 io.micronaut.jsonschema.validation; | ||
|
||
/** | ||
* JSON Schema Validation Message. | ||
* @author Sergio del Amo | ||
* @since 1.0.0 | ||
*/ | ||
@FunctionalInterface | ||
public interface ValidationMessage { | ||
|
||
/** | ||
* | ||
* @return JSON Schema Validation Message | ||
*/ | ||
String getMessage(); | ||
} |
Oops, something went wrong.