Skip to content
This repository has been archived by the owner on Jul 20, 2021. It is now read-only.

Commit

Permalink
Fix NPE when non-default property null value is used
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderYastrebov committed Aug 12, 2016
1 parent 96654aa commit 6ac6b48
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 15 deletions.
30 changes: 15 additions & 15 deletions src/main/java/org/zalando/twintip/spring/SchemaResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
* limitations under the License.
* #L%
*/

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand All @@ -36,6 +35,7 @@
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.net.URI;
Expand All @@ -55,9 +55,9 @@ public class SchemaResource {

@Autowired
public SchemaResource(
@Value("${twintip.yaml}") final Resource yamlResource,
@Value("${twintip.cors:true}") final boolean enableCors,
@Value("${twintip.baseUrl:}") final String baseUrl) throws IOException {
@Value("${twintip.yaml}") final Resource yamlResource,
@Value("${twintip.cors:true}") final boolean enableCors,
@Value("${twintip.baseUrl:}") final String baseUrl) throws IOException {

this.json = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
this.yaml = new ObjectMapper(new YAMLFactory());
Expand All @@ -66,30 +66,30 @@ public SchemaResource(
});
this.enableCors = enableCors;

if (!baseUrl.isEmpty()) {
if (!StringUtils.isEmpty(baseUrl)) {
updateApiUrl(node, URI.create(baseUrl));
}
}

@RequestMapping(method = RequestMethod.GET, value = SCHEMA_DISCOVERY_MAPPING,
produces = MediaType.APPLICATION_JSON_VALUE)
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public SchemaDiscovery discover(
@Value("${twintip.mapping}") final String mapping,
@Value("${twintip.type:swagger-2.0}") final String type,
@Value("${twintip.ui:}") final String uiPath) {
@Value("${twintip.mapping}") final String mapping,
@Value("${twintip.type:swagger-2.0}") final String type,
@Value("${twintip.ui:}") final String uiPath) {
return new SchemaDiscovery(mapping, type, uiPath);
}

@RequestMapping(method = RequestMethod.GET, value = "${twintip.mapping}",
produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.ALL_VALUE})
produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.ALL_VALUE})
@ResponseStatus(HttpStatus.OK)
public ResponseEntity<String> jsonSchema() throws JsonProcessingException {
return response(json.writeValueAsString(node));
}

@RequestMapping(method = RequestMethod.GET, value = "${twintip.mapping}",
produces = {"application/yaml", "application/x-yaml", "text/yaml"})
produces = {"application/yaml", "application/x-yaml", "text/yaml"})
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public ResponseEntity<String> yamlSchema() throws JsonProcessingException {
Expand All @@ -100,10 +100,10 @@ private ResponseEntity<String> response(final String body) {
final ResponseEntity.BodyBuilder builder = ResponseEntity.ok();
if (enableCors) {
builder
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET")
.header("Access-Control-Max-Age", "3600")
.header("Access-Control-Allow-Headers", "");
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET")
.header("Access-Control-Max-Age", "3600")
.header("Access-Control-Allow-Headers", "");
}
return builder.body(body);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package org.zalando.twintip.spring;

/*
* #%L
* twintip-spring-web
* %%
* Copyright (C) 2015 Zalando SE
* %%
* 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
*
* 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.
* #L%
*/
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.http.HttpMethod;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.request;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration
@TestPropertySource(properties = {
"twintip.mapping=/api",
"twintip.yaml=classpath:/petstore.yml"
})
public class SchemaResourcePropertiesNullValueTest {

@Configuration
@EnableWebMvc
@Import(SchemaResource.class)
public static class TestConfiguration {

@Bean
public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
final PropertySourcesPlaceholderConfigurer c = new PropertySourcesPlaceholderConfigurer();
c.setNullValue("");
return c;
}

@Bean
public MockMvc mvc(final WebApplicationContext context) {
return MockMvcBuilders.webAppContextSetup(context).build();
}
}

@Autowired
private MockMvc mvc;

@Test
public void apiDefaultBaseUrl() throws Exception {
mvc.perform(request(HttpMethod.GET, "/api"))
.andExpect(content().contentType(APPLICATION_JSON))
.andExpect(jsonPath("$.host", is("petstore.swagger.io")))
.andExpect(jsonPath("$.schemes", hasSize(1)));
}

}

0 comments on commit 6ac6b48

Please sign in to comment.