1 /* 2 * Copyright (c) 2020 Network New Technologies Inc. 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.networknt.schema; 17 18 import com.fasterxml.jackson.databind.JsonNode; 19 import com.fasterxml.jackson.databind.ObjectMapper; 20 import com.networknt.schema.JsonSchemaFactory.Builder; 21 import com.networknt.schema.resource.MapSchemaMapper; 22 import com.networknt.schema.resource.SchemaMapper; 23 24 import org.junit.jupiter.api.Test; 25 26 import java.io.FileNotFoundException; 27 import java.io.IOException; 28 import java.io.UncheckedIOException; 29 import java.net.URL; 30 import java.net.UnknownHostException; 31 import java.util.HashMap; 32 33 import static org.junit.jupiter.api.Assertions.assertEquals; 34 import static org.junit.jupiter.api.Assertions.fail; 35 36 public class UriMappingTest { 37 38 private final ObjectMapper mapper = new ObjectMapper(); 39 40 /** 41 * Validate that a JSON URI Mapping file containing the URI Mapping schema is 42 * schema valid. 43 * 44 * @throws IOException if unable to parse the mapping file 45 */ 46 @Test testBuilderUriMappingUri()47 public void testBuilderUriMappingUri() throws IOException { 48 URL mappings = UriMappingTest.class.getResource("/draft4/extra/uri_mapping/uri-mapping.json"); 49 JsonMetaSchema draftV4 = JsonMetaSchema.getV4(); 50 Builder builder = JsonSchemaFactory.builder() 51 .defaultMetaSchemaIri(draftV4.getIri()) 52 .metaSchema(draftV4) 53 .schemaMappers(schemaMappers -> schemaMappers.add(getUriMappingsFromUrl(mappings))); 54 JsonSchemaFactory instance = builder.build(); 55 JsonSchema schema = instance.getSchema(SchemaLocation.of( 56 "https://raw.githubusercontent.com/networknt/json-schema-validator/master/src/test/resources/draft4/extra/uri_mapping/uri-mapping.schema.json")); 57 assertEquals(0, schema.validate(mapper.readTree(mappings)).size()); 58 } 59 60 /** 61 * Validate that local URI is used when attempting to get a schema that is not 62 * available publicly. Use the URL http://example.com/invalid/schema/url to use 63 * a public URL that returns a 404 Not Found. The locally mapped schema is a 64 * valid, but empty schema. 65 * 66 * @throws IOException if unable to parse the mapping file 67 */ 68 @Test testBuilderExampleMappings()69 public void testBuilderExampleMappings() throws IOException { 70 JsonSchemaFactory instance = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4); 71 SchemaLocation example = SchemaLocation.of("https://example.com/invalid/schema/url"); 72 // first test that attempting to use example URL throws an error 73 try { 74 JsonSchema schema = instance.getSchema(example); 75 schema.validate(mapper.createObjectNode()); 76 fail("Expected exception not thrown"); 77 } catch (JsonSchemaException ex) { 78 Throwable cause = ex.getCause(); 79 if (!(cause instanceof FileNotFoundException || cause instanceof UnknownHostException)) { 80 fail("Unexpected cause for JsonSchemaException", ex); 81 } 82 // passing, so do nothing 83 } catch (Exception ex) { 84 fail("Unexpected exception thrown", ex); 85 } 86 URL mappings = UriMappingTest.class.getResource("/draft4/extra/uri_mapping/invalid-schema-uri.json"); 87 JsonMetaSchema draftV4 = JsonMetaSchema.getV4(); 88 Builder builder = JsonSchemaFactory.builder() 89 .defaultMetaSchemaIri(draftV4.getIri()) 90 .metaSchema(draftV4) 91 .schemaMappers(schemaMappers -> schemaMappers.add(getUriMappingsFromUrl(mappings))); 92 instance = builder.build(); 93 JsonSchema schema = instance.getSchema(example); 94 assertEquals(0, schema.validate(mapper.createObjectNode()).size()); 95 } 96 97 /** 98 * Validate that a JSON URI Mapping file containing the URI Mapping schema is 99 * schema valid. 100 * 101 * @throws IOException if unable to parse the mapping file 102 */ 103 @Test testValidatorConfigUriMappingUri()104 public void testValidatorConfigUriMappingUri() throws IOException { 105 URL mappings = UriMappingTest.class.getResource("/draft4/extra/uri_mapping/uri-mapping.json"); 106 JsonSchemaFactory instance = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4)) 107 .schemaMappers(schemaMappers -> schemaMappers.add(getUriMappingsFromUrl(mappings))).build(); 108 JsonSchema schema = instance.getSchema(SchemaLocation.of( 109 "https://raw.githubusercontent.com/networknt/json-schema-validator/master/src/test/resources/draft4/extra/uri_mapping/uri-mapping.schema.json")); 110 assertEquals(0, schema.validate(mapper.readTree(mappings)).size()); 111 } 112 113 /** 114 * Validate that local URL is used when attempting to get a schema that is not 115 * available publicly. Use the URL http://example.com/invalid/schema/url to use 116 * a public URL that returns a 404 Not Found. The locally mapped schema is a 117 * valid, but empty schema. 118 * 119 * @throws IOException if unable to parse the mapping file 120 */ 121 @Test testValidatorConfigExampleMappings()122 public void testValidatorConfigExampleMappings() throws IOException { 123 URL mappings = UriMappingTest.class.getResource("/draft4/extra/uri_mapping/invalid-schema-uri.json"); 124 JsonSchemaFactory instance = JsonSchemaFactory 125 .builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4)).build(); 126 SchemaValidatorsConfig config = new SchemaValidatorsConfig(); 127 SchemaLocation example = SchemaLocation.of("https://example.com/invalid/schema/url"); 128 // first test that attempting to use example URL throws an error 129 try { 130 JsonSchema schema = instance.getSchema(example, config); 131 schema.validate(mapper.createObjectNode()); 132 fail("Expected exception not thrown"); 133 } catch (JsonSchemaException ex) { 134 Throwable cause = ex.getCause(); 135 if (!(cause instanceof FileNotFoundException || cause instanceof UnknownHostException)) { 136 fail("Unexpected cause for JsonSchemaException"); 137 } 138 // passing, so do nothing 139 } catch (Exception ex) { 140 fail("Unexpected exception thrown"); 141 } 142 instance = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4)) 143 .schemaMappers(schemaMappers -> schemaMappers.add(getUriMappingsFromUrl(mappings))).build(); 144 JsonSchema schema = instance.getSchema(example, config); 145 assertEquals(0, schema.validate(mapper.createObjectNode()).size()); 146 } 147 148 @Test testMappingsForRef()149 public void testMappingsForRef() throws IOException { 150 URL mappings = UriMappingTest.class.getResource("/draft4/extra/uri_mapping/schema-with-ref-mapping.json"); 151 JsonSchemaFactory instance = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4)) 152 .schemaMappers(schemaMappers -> schemaMappers.add(getUriMappingsFromUrl(mappings))).build(); 153 SchemaValidatorsConfig config = new SchemaValidatorsConfig(); 154 JsonSchema schema = instance.getSchema(SchemaLocation.of("resource:draft4/extra/uri_mapping/schema-with-ref.json"), 155 config); 156 assertEquals(0, schema.validate(mapper.readTree("[]")).size()); 157 } 158 getUriMappingsFromUrl(URL url)159 private SchemaMapper getUriMappingsFromUrl(URL url) { 160 HashMap<String, String> map = new HashMap<String, String>(); 161 try { 162 for (JsonNode mapping : mapper.readTree(url)) { 163 map.put(mapping.get("publicURL").asText(), 164 mapping.get("localURL").asText()); 165 } 166 } catch (IOException e) { 167 throw new UncheckedIOException(e); 168 } 169 return new MapSchemaMapper(map); 170 } 171 } 172