1
0
mirror of https://gitee.com/dcren/initializr.git synced 2025-04-05 17:38:06 +08:00

Remove use of org.json

This commit removes all use of org.json in production code and moves
the json api to a test only dependency.

Closes gh-507
This commit is contained in:
Stephane Nicoll 2017-12-29 13:29:28 +01:00
parent 8e5b910af6
commit 63becddb94
23 changed files with 353 additions and 260 deletions

View File

@ -16,8 +16,8 @@
package io.spring.initializr.actuate;
import com.fasterxml.jackson.databind.JsonNode;
import io.spring.initializr.web.AbstractFullStackInitializrIntegrationTests;
import org.json.JSONObject;
import org.junit.Test;
import org.springframework.test.context.ActiveProfiles;
@ -45,35 +45,32 @@ public class ActuatorIntegrationTests
@Test
public void metricsAvailableByDefault() {
downloadZip("/starter.zip?packaging=jar&javaVersion=1.8&style=web&style=jpa");
JSONObject result = metricsEndpoint();
int requests = result.getInt("counter.initializr.requests");
int packaging = result.getInt("counter.initializr.packaging.jar");
int javaVersion = result.getInt("counter.initializr.java_version.1_8");
int webDependency = result.getInt("counter.initializr.dependency.web");
int jpaDependency = result.getInt("counter.initializr.dependency.data-jpa");
JsonNode result = metricsEndpoint();
int requests = result.get("counter.initializr.requests").intValue();
int packaging = result.get("counter.initializr.packaging.jar").intValue();
int javaVersion = result.get("counter.initializr.java_version.1_8").intValue();
int webDependency = result.get("counter.initializr.dependency.web").intValue();
int jpaDependency = result.get("counter.initializr.dependency.data-jpa")
.intValue();
// No jpa dep this time
downloadZip("/starter.zip?packaging=jar&javaVersion=1.8&style=web");
JSONObject updatedResult = metricsEndpoint();
JsonNode updatedResult = metricsEndpoint();
assertEquals("Number of request should have increased", requests + 1,
updatedResult.getInt("counter.initializr.requests"));
updatedResult.get("counter.initializr.requests").intValue());
assertEquals("jar packaging metric should have increased", packaging + 1,
updatedResult.getInt("counter.initializr.packaging.jar"));
updatedResult.get("counter.initializr.packaging.jar").intValue());
assertEquals("java version metric should have increased", javaVersion + 1,
updatedResult.getInt("counter.initializr.java_version.1_8"));
updatedResult.get("counter.initializr.java_version.1_8").intValue());
assertEquals("web dependency metric should have increased", webDependency + 1,
updatedResult.getInt("counter.initializr.dependency.web"));
updatedResult.get("counter.initializr.dependency.web").intValue());
assertEquals("jpa dependency metric should not have increased", jpaDependency,
updatedResult.getInt("counter.initializr.dependency.data-jpa"));
updatedResult.get("counter.initializr.dependency.data-jpa").intValue());
}
private JSONObject metricsEndpoint() {
private JsonNode metricsEndpoint() {
return parseJson(getRestTemplate().getForObject(createUrl("/metrics"), String.class));
}
private JSONObject parseJson(String content) {
return new JSONObject(content);
}
}

View File

@ -20,10 +20,9 @@ import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.databind.JsonNode;
import io.spring.initializr.actuate.stat.MainControllerStatsIntegrationTests.StatsMockController;
import io.spring.initializr.web.AbstractFullStackInitializrIntegrationTests;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
@ -74,12 +73,12 @@ public class MainControllerStatsIntegrationTests
assertEquals("No stat got generated", 1, statsMockController.stats.size());
StatsMockController.Content content = statsMockController.stats.get(0);
JSONObject json = new JSONObject(content.json);
assertEquals("com.foo", json.get("groupId"));
assertEquals("bar", json.get("artifactId"));
JSONArray list = json.getJSONArray("dependencies");
assertEquals(1, list.length());
assertEquals("web", list.get(0));
JsonNode json = parseJson(content.json);
assertEquals("com.foo", json.get("groupId").textValue());
assertEquals("bar", json.get("artifactId").textValue());
JsonNode list = json.get("dependencies");
assertEquals(1, list.size());
assertEquals("web", list.get(0).textValue());
}
@Test
@ -104,7 +103,7 @@ public class MainControllerStatsIntegrationTests
assertEquals("No stat got generated", 1, statsMockController.stats.size());
StatsMockController.Content content = statsMockController.stats.get(0);
JSONObject json = new JSONObject(content.json);
JsonNode json = parseJson(content.json);
assertFalse("requestIp property should not be set", json.has("requestIp"));
}
@ -116,8 +115,8 @@ public class MainControllerStatsIntegrationTests
assertEquals("No stat got generated", 1, statsMockController.stats.size());
StatsMockController.Content content = statsMockController.stats.get(0);
JSONObject json = new JSONObject(content.json);
assertEquals("Wrong requestIp", "10.0.0.123", json.get("requestIp"));
JsonNode json = parseJson(content.json);
assertEquals("Wrong requestIp", "10.0.0.123", json.get("requestIp").textValue());
}
@Test
@ -128,7 +127,7 @@ public class MainControllerStatsIntegrationTests
assertEquals("No stat got generated", 1, statsMockController.stats.size());
StatsMockController.Content content = statsMockController.stats.get(0);
JSONObject json = new JSONObject(content.json);
JsonNode json = parseJson(content.json);
assertFalse("requestIpv4 property should not be set if value is not a valid IPv4",
json.has("requestIpv4"));
}
@ -141,7 +140,7 @@ public class MainControllerStatsIntegrationTests
assertEquals("No stat got generated", 1, statsMockController.stats.size());
StatsMockController.Content content = statsMockController.stats.get(0);
JSONObject json = new JSONObject(content.json);
JsonNode json = parseJson(content.json);
assertFalse("requestCountry property should not be set if value is set to xx",
json.has("requestCountry"));
}
@ -158,13 +157,13 @@ public class MainControllerStatsIntegrationTests
assertEquals("No stat got generated", 1, statsMockController.stats.size());
StatsMockController.Content content = statsMockController.stats.get(0);
JSONObject json = new JSONObject(content.json);
assertEquals("com.example", json.get("groupId"));
assertEquals("demo", json.get("artifactId"));
assertEquals(true, json.get("invalid"));
assertEquals(true, json.get("invalidType"));
JsonNode json = parseJson(content.json);
assertEquals("com.example", json.get("groupId").textValue());
assertEquals("demo", json.get("artifactId").textValue());
assertEquals(true, json.get("invalid").booleanValue());
assertEquals(true, json.get("invalidType").booleanValue());
assertNotNull(json.get("errorMessage"));
assertTrue(((String) json.get("errorMessage")).contains("invalid-type"));
assertTrue(json.get("errorMessage").textValue().contains("invalid-type"));
}
@Test

View File

@ -16,13 +16,14 @@
package io.spring.initializr.service;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.metadata.InitializrMetadataBuilder;
import io.spring.initializr.metadata.InitializrMetadataProvider;
import org.json.JSONObject;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -55,13 +56,13 @@ public class InitializrServiceSmokeTests {
private InitializrMetadataProvider metadataProvider;
@Test
public void metadataCanBeSerialized() throws URISyntaxException {
public void metadataCanBeSerialized() throws URISyntaxException, IOException {
RequestEntity<Void> request = RequestEntity.get(new URI("/"))
.accept(MediaType.parseMediaType("application/vnd.initializr.v2.1+json"))
.build();
ResponseEntity<String> response = this.restTemplate.exchange(request, String.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
new JSONObject(response.getBody());
new ObjectMapper().readTree(response.getBody());
}
@Test

View File

@ -36,10 +36,6 @@
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
@ -79,6 +75,11 @@
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId>

View File

@ -23,6 +23,7 @@ import javax.cache.configuration.MutableConfiguration;
import javax.cache.expiry.CreatedExpiryPolicy;
import javax.cache.expiry.Duration;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.spring.initializr.generator.ProjectGenerator;
import io.spring.initializr.generator.ProjectRequestPostProcessor;
import io.spring.initializr.generator.ProjectRequestResolver;
@ -45,6 +46,7 @@ import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@ -67,7 +69,8 @@ import org.springframework.web.servlet.resource.ResourceUrlProvider;
*/
@Configuration
@EnableConfigurationProperties(InitializrProperties.class)
@AutoConfigureAfter({ CacheAutoConfiguration.class, WebClientAutoConfiguration.class })
@AutoConfigureAfter({ CacheAutoConfiguration.class, JacksonAutoConfiguration.class,
WebClientAutoConfiguration.class })
public class InitializrAutoConfiguration {
private final List<ProjectRequestPostProcessor> postProcessors;
@ -110,11 +113,12 @@ public class InitializrAutoConfiguration {
@ConditionalOnMissingBean(InitializrMetadataProvider.class)
public InitializrMetadataProvider initializrMetadataProvider(
InitializrProperties properties,
ObjectMapper objectMapper,
RestTemplateBuilder restTemplateBuilder) {
InitializrMetadata metadata = InitializrMetadataBuilder
.fromInitializrProperties(properties).build();
return new DefaultInitializrMetadataProvider(metadata,
restTemplateBuilder.build());
objectMapper, restTemplateBuilder.build());
}
@Bean

View File

@ -16,15 +16,17 @@
package io.spring.initializr.web.mapper;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.spring.initializr.metadata.BillOfMaterials;
import io.spring.initializr.metadata.Dependency;
import io.spring.initializr.metadata.DependencyMetadata;
import io.spring.initializr.metadata.Repository;
import org.json.JSONObject;
/**
* A {@link DependencyMetadataJsonMapper} handling the metadata format for v2.1.
@ -33,59 +35,70 @@ import org.json.JSONObject;
*/
public class DependencyMetadataV21JsonMapper implements DependencyMetadataJsonMapper {
private static final JsonNodeFactory nodeFactory = JsonNodeFactory.instance;
@Override
public String write(DependencyMetadata metadata) {
JSONObject json = new JSONObject();
ObjectNode json = nodeFactory.objectNode();
json.put("bootVersion", metadata.getBootVersion().toString());
json.put("dependencies",
metadata.getDependencies().entrySet().stream()
json.set("dependencies",
mapNode(metadata.getDependencies().entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
entry -> mapDependency(entry.getValue()))));
json.put("repositories",
metadata.getRepositories().entrySet().stream()
entry -> mapDependency(entry.getValue())))));
json.set("repositories",
mapNode(metadata.getRepositories().entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
entry -> mapRepository(entry.getValue()))));
json.put("boms", metadata.getBoms().entrySet().stream().collect(Collectors
.toMap(Map.Entry::getKey, entry -> mapBom(entry.getValue()))));
entry -> mapRepository(entry.getValue())))));
json.set("boms",
mapNode(metadata.getBoms().entrySet().stream().collect(Collectors
.toMap(Map.Entry::getKey, entry -> mapBom(entry.getValue())))));
return json.toString();
}
private static Map<String, Object> mapDependency(Dependency dep) {
Map<String, Object> result = new LinkedHashMap<>();
result.put("groupId", dep.getGroupId());
result.put("artifactId", dep.getArtifactId());
private static JsonNode mapDependency(Dependency dep) {
ObjectNode node = nodeFactory.objectNode();
node.put("groupId", dep.getGroupId());
node.put("artifactId", dep.getArtifactId());
if (dep.getVersion() != null) {
result.put("version", dep.getVersion());
node.put("version", dep.getVersion());
}
result.put("scope", dep.getScope());
node.put("scope", dep.getScope());
if (dep.getBom() != null) {
result.put("bom", dep.getBom());
node.put("bom", dep.getBom());
}
if (dep.getRepository() != null) {
result.put("repository", dep.getRepository());
node.put("repository", dep.getRepository());
}
return result;
return node;
}
private static Map<String, Object> mapRepository(Repository repo) {
Map<String, Object> result = new LinkedHashMap<>();
result.put("name", repo.getName());
result.put("url", repo.getUrl());
result.put("snapshotEnabled", repo.isSnapshotsEnabled());
return result;
private static JsonNode mapRepository(Repository repo) {
ObjectNode node = nodeFactory.objectNode();
node.put("name", repo.getName())
.put("url", (repo.getUrl() != null ? repo.getUrl().toString() : null))
.put("snapshotEnabled", repo.isSnapshotsEnabled());
return node;
}
private static Map<String, Object> mapBom(BillOfMaterials bom) {
Map<String, Object> result = new LinkedHashMap<>();
result.put("groupId", bom.getGroupId());
result.put("artifactId", bom.getArtifactId());
private static JsonNode mapBom(BillOfMaterials bom) {
ObjectNode node = nodeFactory.objectNode();
node.put("groupId", bom.getGroupId());
node.put("artifactId", bom.getArtifactId());
if (bom.getVersion() != null) {
result.put("version", bom.getVersion());
node.put("version", bom.getVersion());
}
if (bom.getRepositories() != null) {
result.put("repositories", bom.getRepositories());
ArrayNode array = nodeFactory.arrayNode();
bom.getRepositories().forEach(array::add);
node.set("repositories", array);
}
return result;
return node;
}
private static JsonNode mapNode(Map<String, JsonNode> content) {
ObjectNode node = nodeFactory.objectNode();
content.forEach(node::set);
return node;
}
}

View File

@ -16,13 +16,11 @@
package io.spring.initializr.web.mapper;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.spring.initializr.metadata.Dependency;
import io.spring.initializr.metadata.Type;
import org.json.JSONObject;
import org.springframework.hateoas.TemplateVariable;
import org.springframework.hateoas.TemplateVariables;
@ -49,30 +47,29 @@ public class InitializrMetadataV21JsonMapper extends InitializrMetadataV2JsonMap
}
@Override
protected Map<String, Object> links(JSONObject parent, List<Type> types,
String appUrl) {
Map<String, Object> links = super.links(parent, types, appUrl);
links.put("dependencies", dependenciesLink(appUrl));
parent.put("_links", links);
protected ObjectNode links(ObjectNode parent, List<Type> types, String appUrl) {
ObjectNode links = super.links(parent, types, appUrl);
links.set("dependencies", dependenciesLink(appUrl));
parent.set("_links", links);
return links;
}
@Override
protected Map<String, Object> mapDependency(Dependency dependency) {
Map<String, Object> content = mapValue(dependency);
protected ObjectNode mapDependency(Dependency dependency) {
ObjectNode content = mapValue(dependency);
if (dependency.getVersionRange() != null) {
content.put("versionRange", dependency.getVersionRange());
}
if (dependency.getLinks() != null && !dependency.getLinks().isEmpty()) {
content.put("_links", LinkMapper.mapLinks(dependency.getLinks()));
content.set("_links", LinkMapper.mapLinks(dependency.getLinks()));
}
return content;
}
private Map<String, Object> dependenciesLink(String appUrl) {
private ObjectNode dependenciesLink(String appUrl) {
String uri = appUrl != null ? appUrl + "/dependencies" : "/dependencies";
UriTemplate uriTemplate = new UriTemplate(uri, this.dependenciesVariables);
Map<String, Object> result = new LinkedHashMap<>();
ObjectNode result = nodeFactory().objectNode();
result.put("href", uriTemplate.toString());
result.put("templated", true);
return result;

View File

@ -16,12 +16,13 @@
package io.spring.initializr.web.mapper;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.spring.initializr.metadata.DefaultMetadataElement;
import io.spring.initializr.metadata.DependenciesCapability;
import io.spring.initializr.metadata.Dependency;
@ -33,7 +34,6 @@ import io.spring.initializr.metadata.SingleSelectCapability;
import io.spring.initializr.metadata.TextCapability;
import io.spring.initializr.metadata.Type;
import io.spring.initializr.metadata.TypeCapability;
import org.json.JSONObject;
import org.springframework.hateoas.TemplateVariable;
import org.springframework.hateoas.TemplateVariables;
@ -47,6 +47,8 @@ import org.springframework.util.StringUtils;
*/
public class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMapper {
private static final JsonNodeFactory nodeFactory = JsonNodeFactory.instance;
private final TemplateVariables templateVariables;
public InitializrMetadataV2JsonMapper() {
@ -74,9 +76,13 @@ public class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMap
TemplateVariable.VariableType.REQUEST_PARAM));
}
protected JsonNodeFactory nodeFactory() {
return nodeFactory;
}
@Override
public String write(InitializrMetadata metadata, String appUrl) {
JSONObject delegate = new JSONObject();
ObjectNode delegate = nodeFactory.objectNode();
links(delegate, metadata.getTypes().getContent(), appUrl);
dependencies(delegate, metadata.getDependencies());
type(delegate, metadata.getTypes());
@ -93,15 +99,15 @@ public class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMap
return delegate.toString();
}
protected Map<String, Object> links(JSONObject parent, List<Type> types, String appUrl) {
Map<String, Object> content = new LinkedHashMap<>();
types.forEach(it -> content.put(it.getId(), link(appUrl, it)));
parent.put("_links", content);
protected ObjectNode links(ObjectNode parent, List<Type> types, String appUrl) {
ObjectNode content = nodeFactory.objectNode();
types.forEach(it -> content.set(it.getId(), link(appUrl, it)));
parent.set("_links", content);
return content;
}
protected Map<String, Object> link(String appUrl, Type type) {
Map<String, Object> result = new LinkedHashMap<>();
protected ObjectNode link(String appUrl, Type type) {
ObjectNode result = nodeFactory.objectNode();
result.put("href", generateTemplatedUri(appUrl, type));
result.put("templated", true);
return result;
@ -114,68 +120,73 @@ public class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMap
return uriTemplate.toString();
}
protected void dependencies(JSONObject parent, DependenciesCapability capability) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("type", capability.getType().getName());
map.put("values",
capability.getContent().stream().map(this::mapDependencyGroup)
.collect(Collectors.toList()));
parent.put(capability.getId(), map);
protected void dependencies(ObjectNode parent, DependenciesCapability capability) {
ObjectNode dependencies = nodeFactory.objectNode();
dependencies.put("type", capability.getType().getName());
ArrayNode values = nodeFactory.arrayNode();
values.addAll(capability.getContent().stream().map(this::mapDependencyGroup)
.collect(Collectors.toList()));
dependencies.set("values", values);
parent.set(capability.getId(), dependencies);
}
protected void type(JSONObject parent, TypeCapability capability) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("type", "action");
protected void type(ObjectNode parent, TypeCapability capability) {
ObjectNode type = nodeFactory.objectNode();
type.put("type", "action");
Type defaultType = capability.getDefault();
if (defaultType != null) {
map.put("default", defaultType.getId());
type.put("default", defaultType.getId());
}
map.put("values", capability.getContent().stream().map(this::mapType)
ArrayNode values = nodeFactory.arrayNode();
values.addAll(capability.getContent().stream().map(this::mapType)
.collect(Collectors.toList()));
parent.put("type", map);
type.set("values", values);
parent.set("type", type);
}
protected void singleSelect(JSONObject parent, SingleSelectCapability capability) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("type", capability.getType().getName());
protected void singleSelect(ObjectNode parent, SingleSelectCapability capability) {
ObjectNode single = nodeFactory.objectNode();
single.put("type", capability.getType().getName());
DefaultMetadataElement defaultType = capability.getDefault();
if (defaultType != null) {
map.put("default", defaultType.getId());
single.put("default", defaultType.getId());
}
map.put("values", capability.getContent().stream().map(this::mapValue)
ArrayNode values = nodeFactory.arrayNode();
values.addAll(capability.getContent().stream().map(this::mapValue)
.collect(Collectors.toList()));
parent.put(capability.getId(), map);
single.set("values", values);
parent.set(capability.getId(), single);
}
protected void text(JSONObject parent, TextCapability capability) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("type", capability.getType().getName());
protected void text(ObjectNode parent, TextCapability capability) {
ObjectNode text = nodeFactory.objectNode();
text.put("type", capability.getType().getName());
String defaultValue = capability.getContent();
if (StringUtils.hasText(defaultValue)) {
map.put("default", defaultValue);
text.put("default", defaultValue);
}
parent.put(capability.getId(), map);
parent.set(capability.getId(), text);
}
protected Map<String, Object> mapDependencyGroup(DependencyGroup group) {
Map<String, Object> result = new LinkedHashMap<>();
protected ObjectNode mapDependencyGroup(DependencyGroup group) {
ObjectNode result = nodeFactory.objectNode();
result.put("name", group.getName());
if ((group instanceof Describable)
&& ((Describable) group).getDescription() != null) {
result.put("description", ((Describable) group).getDescription());
}
List<Object> items = new ArrayList<>();
ArrayNode items = nodeFactory.arrayNode();
group.getContent().forEach(it -> {
Map<String, Object> dependency = mapDependency(it);
JsonNode dependency = mapDependency(it);
if (dependency != null) {
items.add(dependency);
}
});
result.put("values", items);
result.set("values", items);
return result;
}
protected Map<String, Object> mapDependency(Dependency dependency) {
protected ObjectNode mapDependency(Dependency dependency) {
if (dependency.getVersionRange() == null) {
// only map the dependency if no versionRange is set
return mapValue(dependency);
@ -183,15 +194,17 @@ public class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMap
return null;
}
protected Map<String, Object> mapType(Type type) {
Map<String, Object> result = mapValue(type);
protected ObjectNode mapType(Type type) {
ObjectNode result = mapValue(type);
result.put("action", type.getAction());
result.put("tags", type.getTags());
ObjectNode tags = nodeFactory.objectNode();
type.getTags().forEach(tags::put);
result.set("tags", tags);
return result;
}
protected Map<String, Object> mapValue(MetadataElement value) {
Map<String, Object> result = new LinkedHashMap<>();
protected ObjectNode mapValue(MetadataElement value) {
ObjectNode result = nodeFactory.objectNode();
result.put("id", value.getId());
result.put("name", value.getName());
if ((value instanceof Describable)

View File

@ -21,6 +21,9 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.spring.initializr.metadata.Link;
/**
@ -30,43 +33,45 @@ import io.spring.initializr.metadata.Link;
*/
public class LinkMapper {
private static final JsonNodeFactory nodeFactory = JsonNodeFactory.instance;
/**
* Map the specified links to a json model. If several links share the same relation,
* they are grouped together.
* @param links the links to map
* @return a model for the specified links
*/
public static Map<String, Object> mapLinks(List<Link> links) {
Map<String, Object> result = new LinkedHashMap<>();
public static ObjectNode mapLinks(List<Link> links) {
ObjectNode result = nodeFactory.objectNode();
Map<String, List<Link>> byRel = new LinkedHashMap<>();
links.forEach(it -> byRel.computeIfAbsent(it.getRel(),
k -> new ArrayList<>()).add(it));
byRel.forEach((rel, l) -> {
if (l.size() == 1) {
Map<String, Object> root = new LinkedHashMap<>();
ObjectNode root = JsonNodeFactory.instance.objectNode();
mapLink(l.get(0), root);
result.put(rel, root);
result.set(rel, root);
}
else {
List<Map<String, Object>> root = new ArrayList<>();
ArrayNode root = JsonNodeFactory.instance.arrayNode();
l.forEach(link -> {
Map<String, Object> model = new LinkedHashMap<>();
mapLink(link, model);
root.add(model);
ObjectNode node = JsonNodeFactory.instance.objectNode();
mapLink(link, node);
root.add(node);
});
result.put(rel, root);
result.set(rel, root);
}
});
return result;
}
private static void mapLink(Link link, Map<String, Object> model) {
model.put("href", link.getHref());
private static void mapLink(Link link, ObjectNode node) {
node.put("href", link.getHref());
if (link.isTemplated()) {
model.put("templated", true);
node.put("templated", true);
}
if (link.getDescription() != null) {
model.put("title", link.getDescription());
node.put("title", link.getDescription());
}
}

View File

@ -18,6 +18,7 @@ package io.spring.initializr.web.support;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.spring.initializr.metadata.DefaultMetadataElement;
import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.metadata.InitializrMetadataProvider;
@ -40,11 +41,13 @@ public class DefaultInitializrMetadataProvider implements InitializrMetadataProv
.getLogger(DefaultInitializrMetadataProvider.class);
private final InitializrMetadata metadata;
private final ObjectMapper objectMapper;
private final RestTemplate restTemplate;
public DefaultInitializrMetadataProvider(InitializrMetadata metadata,
RestTemplate restTemplate) {
ObjectMapper objectMapper, RestTemplate restTemplate) {
this.metadata = metadata;
this.objectMapper = objectMapper;
this.restTemplate = restTemplate;
}
@ -71,7 +74,8 @@ public class DefaultInitializrMetadataProvider implements InitializrMetadataProv
if (StringUtils.hasText(url)) {
try {
log.info("Fetching boot metadata from {}", url);
return new SpringBootMetadataReader(restTemplate, url).getBootVersions();
return new SpringBootMetadataReader(objectMapper, restTemplate, url)
.getBootVersions();
}
catch (Exception e) {
log.warn("Failed to fetch spring boot metadata", e);

View File

@ -16,12 +16,14 @@
package io.spring.initializr.web.support;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import io.spring.initializr.metadata.DefaultMetadataElement;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.web.client.RestTemplate;
@ -33,28 +35,29 @@ import org.springframework.web.client.RestTemplate;
*/
public class SpringBootMetadataReader {
private final JSONObject content;
private final JsonNode content;
/**
* Parse the content of the metadata at the specified url
*/
public SpringBootMetadataReader(RestTemplate restTemplate, String url) {
this.content = new JSONObject(restTemplate.getForObject(url, String.class));
public SpringBootMetadataReader(ObjectMapper objectMapper,
RestTemplate restTemplate, String url) throws IOException {
this.content = objectMapper.readTree(
restTemplate.getForObject(url, String.class));
}
/**
* Return the boot versions parsed by this instance.
*/
public List<DefaultMetadataElement> getBootVersions() {
JSONArray array = content.getJSONArray("projectReleases");
ArrayNode array = (ArrayNode) content.get("projectReleases");
List<DefaultMetadataElement> list = new ArrayList<>();
for (int i = 0; i < array.length(); i++) {
JSONObject it = array.getJSONObject(i);
for (JsonNode it : array) {
DefaultMetadataElement version = new DefaultMetadataElement();
version.setId(it.getString("version"));
String name = it.getString("versionDisplayName");
version.setName(it.getBoolean("snapshot") ? name + " (SNAPSHOT)" : name);
version.setDefault(it.getBoolean("current"));
version.setId(it.get("version").textValue());
String name = it.get("versionDisplayName").textValue();
version.setName(it.get("snapshot").booleanValue() ? name + " (SNAPSHOT)" : name);
version.setDefault(it.get("current").booleanValue());
list.add(version);
}
return list;

View File

@ -18,15 +18,15 @@ package io.spring.initializr.web.ui;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.spring.initializr.metadata.Dependency;
import io.spring.initializr.metadata.DependencyGroup;
import io.spring.initializr.metadata.InitializrMetadataProvider;
import io.spring.initializr.util.Version;
import org.json.JSONObject;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
@ -74,31 +74,31 @@ public class UiController {
}
private static String writeDependencies(List<DependencyItem> items) {
JSONObject json = new JSONObject();
List<Map<String, Object>> maps = new ArrayList<>();
ObjectNode json = JsonNodeFactory.instance.objectNode();
ArrayNode maps = JsonNodeFactory.instance.arrayNode();
items.forEach(d -> maps.add(mapDependency(d)));
json.put("dependencies", maps);
json.set("dependencies", maps);
return json.toString();
}
private static Map<String, Object> mapDependency(DependencyItem item) {
Map<String, Object> result = new HashMap<>();
private static ObjectNode mapDependency(DependencyItem item) {
ObjectNode node = JsonNodeFactory.instance.objectNode();
Dependency d = item.dependency;
result.put("id", d.getId());
result.put("name", d.getName());
result.put("group", item.group);
node.put("id", d.getId());
node.put("name", d.getName());
node.put("group", item.group);
if (d.getDescription() != null) {
result.put("description", d.getDescription());
node.put("description", d.getDescription());
}
if (d.getWeight() > 0) {
result.put("weight", d.getWeight());
node.put("weight", d.getWeight());
}
if (!CollectionUtils.isEmpty(d.getKeywords()) || !CollectionUtils.isEmpty(d.getAliases())) {
List<String> all = new ArrayList<>(d.getKeywords());
all.addAll(d.getAliases());
result.put("keywords", StringUtils.collectionToCommaDelimitedString(all));
node.put("keywords", StringUtils.collectionToCommaDelimitedString(all));
}
return result;
return node;
}
private static class DependencyItem {

View File

@ -25,6 +25,8 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.metadata.InitializrMetadataBuilder;
import io.spring.initializr.metadata.InitializrMetadataProvider;
@ -36,6 +38,7 @@ import io.spring.initializr.web.support.DefaultInitializrMetadataProvider;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Expand;
import org.apache.tools.ant.taskdefs.Untar;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Rule;
@ -71,6 +74,8 @@ public abstract class AbstractInitializrIntegrationTests {
protected static final MediaType CURRENT_METADATA_MEDIA_TYPE =
InitializrMetadataVersion.V2_1.getMediaType();
private static final ObjectMapper objectMapper = new ObjectMapper();
@Rule
public final TemporaryFolder folder = new TemporaryFolder();
@ -103,22 +108,41 @@ public abstract class AbstractInitializrIntegrationTests {
actual.isCompatibleWith(expected));
}
protected JsonNode parseJson(String text) {
try {
return objectMapper.readTree(text);
}
catch (IOException ex) {
throw new IllegalArgumentException("Invalid json", ex);
}
}
protected void validateMetadata(ResponseEntity<String> response, MediaType mediaType,
String version, JSONCompareMode compareMode) {
validateContentType(response, mediaType);
JSONObject json = new JSONObject(response.getBody());
JSONObject expected = readMetadataJson(version);
JSONAssert.assertEquals(expected, json, compareMode);
try {
validateContentType(response, mediaType);
JSONObject json = new JSONObject(response.getBody());
JSONObject expected = readMetadataJson(version);
JSONAssert.assertEquals(expected, json, compareMode);
}
catch (JSONException ex) {
throw new IllegalArgumentException("Invalid json", ex);
}
}
protected void validateCurrentMetadata(ResponseEntity<String> response) {
validateContentType(response, CURRENT_METADATA_MEDIA_TYPE);
validateCurrentMetadata(new JSONObject(response.getBody()));
validateCurrentMetadata(response.getBody());
}
protected void validateCurrentMetadata(JSONObject json) {
JSONObject expected = readMetadataJson("2.1.0");
JSONAssert.assertEquals(expected, json, JSONCompareMode.STRICT);
protected void validateCurrentMetadata(String json) {
try {
JSONObject expected = readMetadataJson("2.1.0");
JSONAssert.assertEquals(expected, new JSONObject(json), JSONCompareMode.STRICT);
}
catch (JSONException ex) {
throw new IllegalArgumentException("Invalid json", ex);
}
}
private JSONObject readMetadataJson(String version) {
@ -205,7 +229,7 @@ public abstract class AbstractInitializrIntegrationTests {
expand.setSrc(archiveFile);
Untar.UntarCompressionMethod method = new Untar.UntarCompressionMethod();
method.setValue("gzip");
expand.setCompression(method );
expand.setCompression(method);
expand.execute();
}
@ -267,7 +291,8 @@ public abstract class AbstractInitializrIntegrationTests {
public InitializrMetadataProvider initializrMetadataProvider(
InitializrProperties properties) {
return new DefaultInitializrMetadataProvider(InitializrMetadataBuilder
.fromInitializrProperties(properties).build(), new RestTemplate()) {
.fromInitializrProperties(properties).build(), new ObjectMapper(),
new RestTemplate()) {
@Override
protected void updateInitializrMetadata(InitializrMetadata metadata) {
// Disable metadata fetching from spring.io

View File

@ -21,6 +21,7 @@ import org.junit.After;
import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration;
import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.boot.web.client.RestTemplateCustomizer;
@ -68,7 +69,8 @@ public class InitializrAutoConfigurationTests {
if (config != null) {
ctx.register(config);
}
ctx.register(WebClientAutoConfiguration.class, InitializrAutoConfiguration.class);
ctx.register(WebClientAutoConfiguration.class, JacksonAutoConfiguration.class,
InitializrAutoConfiguration.class);
ctx.refresh();
this.context = ctx;
}

View File

@ -16,11 +16,14 @@
package io.spring.initializr.web.mapper;
import java.io.IOException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.spring.initializr.metadata.Dependency;
import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.metadata.Link;
import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder;
import org.json.JSONObject;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
@ -31,27 +34,29 @@ import static org.junit.Assert.assertTrue;
*/
public class InitializrMetadataJsonMapperTests {
private static final ObjectMapper objectMapper = new ObjectMapper();
private final InitializrMetadataJsonMapper jsonMapper =
new InitializrMetadataV21JsonMapper();
@Test
public void withNoAppUrl() {
public void withNoAppUrl() throws IOException {
InitializrMetadata metadata = new InitializrMetadataTestBuilder()
.addType("foo", true, "/foo.zip", "none", "test")
.addDependencyGroup("foo", "one", "two").build();
String json = jsonMapper.write(metadata, null);
JSONObject result = new JSONObject(json);
JsonNode result = objectMapper.readTree(json);
assertEquals("/foo.zip?type=foo{&dependencies,packaging,javaVersion,language,bootVersion," +
"groupId,artifactId,version,name,description,packageName}", get(result, "_links.foo.href"));
}
@Test
public void withAppUrl() {
public void withAppUrl() throws IOException {
InitializrMetadata metadata = new InitializrMetadataTestBuilder()
.addType("foo", true, "/foo.zip", "none", "test")
.addDependencyGroup("foo", "one", "two").build();
String json = jsonMapper.write(metadata, "http://server:8080/my-app");
JSONObject result = new JSONObject(json);
JsonNode result = objectMapper.readTree(json);
assertEquals("http://server:8080/my-app/foo.zip?type=foo{&dependencies,packaging,javaVersion," +
"language,bootVersion,groupId,artifactId,version,name,description,packageName}",
get(result, "_links.foo.href"));
@ -72,13 +77,13 @@ public class InitializrMetadataJsonMapperTests {
assertTrue(second > 0);
}
private Object get(JSONObject result, String path) {
private Object get(JsonNode result, String path) {
String[] nodes = path.split("\\.");
for (int i = 0; i < nodes.length - 1; i++) {
String node = nodes[i];
result = result.getJSONObject(node);
result = result.path(node);
}
return result.getString(nodes[nodes.length - 1]);
return result.get(nodes[nodes.length - 1]).textValue();
}
}

View File

@ -18,8 +18,9 @@ package io.spring.initializr.web.mapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.spring.initializr.metadata.Link;
import org.junit.Test;
@ -37,28 +38,27 @@ public class LinkMapperTests {
public void mapSimpleRel() {
List<Link> links = new ArrayList<>();
links.add(Link.create("a", "https://example.com", "some description"));
Map<String, Object> model = LinkMapper.mapLinks(links);
ObjectNode model = LinkMapper.mapLinks(links);
assertEquals(1, model.size());
assertTrue(model.containsKey("a"));
@SuppressWarnings("unchecked")
Map<String, Object> linkModel = (Map<String, Object>) model.get("a");
assertTrue(model.has("a"));
ObjectNode linkModel = (ObjectNode) model.get("a");
assertEquals(2, linkModel.size());
assertEquals("https://example.com", linkModel.get("href"));
assertEquals("some description", linkModel.get("title"));
assertEquals("https://example.com", linkModel.get("href").textValue());
assertEquals("some description", linkModel.get("title").textValue());
}
@Test
public void mapTemplatedRel() {
List<Link> links = new ArrayList<>();
links.add(Link.create("a", "https://example.com/{bootVersion}/a", true));
Map<String, Object> model = LinkMapper.mapLinks(links);
ObjectNode model = LinkMapper.mapLinks(links);
assertEquals(1, model.size());
assertTrue(model.containsKey("a"));
@SuppressWarnings("unchecked")
Map<String, Object> linkModel = (Map<String, Object>) model.get("a");
assertTrue(model.has("a"));
ObjectNode linkModel = (ObjectNode) model.get("a");
assertEquals(2, linkModel.size());
assertEquals("https://example.com/{bootVersion}/a", linkModel.get("href"));
assertEquals(true, linkModel.get("templated"));
assertEquals("https://example.com/{bootVersion}/a",
linkModel.get("href").textValue());
assertEquals(true, linkModel.get("templated").booleanValue());
}
@Test
@ -66,33 +66,34 @@ public class LinkMapperTests {
List<Link> links = new ArrayList<>();
links.add(Link.create("a", "https://example.com", "some description"));
links.add(Link.create("a", "https://example.com/2"));
Map<String, Object> model = LinkMapper.mapLinks(links);
ObjectNode model = LinkMapper.mapLinks(links);
assertEquals(1, model.size());
assertTrue(model.containsKey("a"));
@SuppressWarnings("unchecked")
List<Map<String, Object>> linksModel = (List<Map<String, Object>>) model.get("a");
assertTrue(model.has("a"));
ArrayNode linksModel = (ArrayNode) model.get("a");
assertEquals(2, linksModel.size());
assertEquals("https://example.com", linksModel.get(0).get("href"));
assertEquals("https://example.com/2", linksModel.get(1).get("href"));
assertEquals("https://example.com", linksModel.get(0).get("href").textValue());
assertEquals("https://example.com/2", linksModel.get(1).get("href").textValue());
}
@Test
public void keepOrdering() {
List<Link> links = new ArrayList<>();
links.add(Link.create("a", "https://example.com"));
links.add(Link.create("b", "https://example.com"));
Map<String, Object> model = LinkMapper.mapLinks(links);
assertEquals("[a, b]", model.keySet().toString());
links.add(Link.create("first", "https://example.com"));
links.add(Link.create("second", "https://example.com"));
ObjectNode model = LinkMapper.mapLinks(links);
String json = model.toString();
assertTrue(json.indexOf("first") < json.indexOf("second"));
}
@Test
public void keepOrderingWithMultipleUrlForSameRel() {
List<Link> links = new ArrayList<>();
links.add(Link.create("a", "https://example.com"));
links.add(Link.create("b", "https://example.com"));
links.add(Link.create("a", "https://example.com"));
Map<String, Object> model = LinkMapper.mapLinks(links);
assertEquals("[a, b]", model.keySet().toString());
links.add(Link.create("first", "https://example.com"));
links.add(Link.create("second", "https://example.com"));
links.add(Link.create("first", "https://example.com"));
ObjectNode model = LinkMapper.mapLinks(links);
String json = model.toString();
assertTrue(json.indexOf("first") < json.indexOf("second"));
}
}

View File

@ -17,6 +17,7 @@
package io.spring.initializr.web.project;
import io.spring.initializr.web.AbstractInitializrControllerIntegrationTests;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Test;
import org.skyscreamer.jsonassert.JSONAssert;
@ -38,27 +39,28 @@ public class MainControllerDependenciesTests
extends AbstractInitializrControllerIntegrationTests {
@Test
public void noBootVersion() {
public void noBootVersion() throws JSONException {
ResponseEntity<String> response = execute("/dependencies", String.class, null,
"application/json");
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue()));
validateContentType(response, CURRENT_METADATA_MEDIA_TYPE);
validateDependenciesOutput("1.1.4", new JSONObject(response.getBody()));
validateDependenciesOutput("1.1.4", response.getBody());
}
@Test
public void filteredDependencies() {
public void filteredDependencies() throws JSONException {
ResponseEntity<String> response = execute("/dependencies?bootVersion=1.2.1.RELEASE",
String.class, null, "application/json");
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue()));
validateContentType(response, CURRENT_METADATA_MEDIA_TYPE);
validateDependenciesOutput("1.2.1", new JSONObject(response.getBody()));
validateDependenciesOutput("1.2.1", response.getBody());
}
protected void validateDependenciesOutput(String version, JSONObject actual) {
protected void validateDependenciesOutput(String version, String actual)
throws JSONException {
JSONObject expected = readJsonFrom(
"metadata/dependencies/test-dependencies-" + version + ".json");
JSONAssert.assertEquals(expected, actual, JSONCompareMode.STRICT);
JSONAssert.assertEquals(expected, new JSONObject(actual), JSONCompareMode.STRICT);
}
}

View File

@ -22,6 +22,7 @@ import java.net.URISyntaxException;
import io.spring.initializr.metadata.Dependency;
import io.spring.initializr.web.AbstractInitializrControllerIntegrationTests;
import io.spring.initializr.web.mapper.InitializrMetadataVersion;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Ignore;
import org.junit.Test;
@ -195,7 +196,7 @@ public class MainControllerIntegrationTests
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue()));
validateContentType(response,
AbstractInitializrControllerIntegrationTests.CURRENT_METADATA_MEDIA_TYPE);
validateCurrentMetadata(new JSONObject(response.getBody()));
validateCurrentMetadata(response.getBody());
}
@Test
@ -205,7 +206,7 @@ public class MainControllerIntegrationTests
"application/vnd.initializr.v2+json");
validateContentType(response,
AbstractInitializrControllerIntegrationTests.CURRENT_METADATA_MEDIA_TYPE);
validateCurrentMetadata(new JSONObject(response.getBody()));
validateCurrentMetadata(response.getBody());
}
@Test
@ -213,7 +214,7 @@ public class MainControllerIntegrationTests
ResponseEntity<String> response = invokeHome(null, "application/hal+json");
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue()));
validateContentType(response, MainController.HAL_JSON_CONTENT_TYPE);
validateCurrentMetadata(new JSONObject(response.getBody()));
validateCurrentMetadata(response.getBody());
}
@Test
@ -252,7 +253,7 @@ public class MainControllerIntegrationTests
ResponseEntity<String> response = invokeHome("curl/1.2.4", "application/json");
validateContentType(response,
AbstractInitializrControllerIntegrationTests.CURRENT_METADATA_MEDIA_TYPE);
validateCurrentMetadata(new JSONObject(response.getBody()));
validateCurrentMetadata(response.getBody());
}
@Test
@ -279,7 +280,7 @@ public class MainControllerIntegrationTests
ResponseEntity<String> response = invokeHome("HTTPie/0.8.0", "application/json");
validateContentType(response,
AbstractInitializrControllerIntegrationTests.CURRENT_METADATA_MEDIA_TYPE);
validateCurrentMetadata(new JSONObject(response.getBody()));
validateCurrentMetadata(response.getBody());
}
@Test
@ -299,7 +300,7 @@ public class MainControllerIntegrationTests
ResponseEntity<String> response = invokeHome("SpringBootCli/1.2.0", "*/*");
validateContentType(response,
AbstractInitializrControllerIntegrationTests.CURRENT_METADATA_MEDIA_TYPE);
validateCurrentMetadata(new JSONObject(response.getBody()));
validateCurrentMetadata(response.getBody());
}
@Test
@ -311,8 +312,7 @@ public class MainControllerIntegrationTests
@Test
// Test that the current output is exactly what we expect
public void validateCurrentProjectMetadata() {
JSONObject json = getMetadataJson();
validateCurrentMetadata(json);
validateCurrentMetadata(getMetadataJson());
}
private void validateCurlHelpContent(ResponseEntity<String> response) {
@ -443,19 +443,23 @@ public class MainControllerIntegrationTests
assertFalse("google analytics should be disabled", body.contains("GoogleAnalyticsObject"));
}
private JSONObject getMetadataJson() {
private String getMetadataJson() {
return getMetadataJson(null);
}
private JSONObject getMetadataJson(String userAgentHeader, String... acceptHeaders) {
String json = invokeHome(userAgentHeader, acceptHeaders).getBody();
return new JSONObject(json);
private String getMetadataJson(String userAgentHeader, String... acceptHeaders) {
return invokeHome(userAgentHeader, acceptHeaders).getBody();
}
private static void assertStandardErrorBody(String body, String message) {
assertNotNull("error body must be available", body);
JSONObject model = new JSONObject(body);
assertEquals(message, model.get("message"));
try {
JSONObject model = new JSONObject(body);
assertEquals(message, model.get("message"));
}
catch (JSONException ex) {
throw new IllegalArgumentException(ex);
}
}
}

View File

@ -20,6 +20,7 @@ import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.metadata.InitializrMetadataBuilder;
import io.spring.initializr.metadata.InitializrMetadataProvider;
import io.spring.initializr.web.AbstractFullStackInitializrIntegrationTests;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Test;
import org.skyscreamer.jsonassert.JSONAssert;
@ -77,7 +78,7 @@ public class MainControllerServiceMetadataIntegrationTests
}
@Test
public void validateJson() {
public void validateJson() throws JSONException {
ResponseEntity<String> response = execute("/metadata/config", String.class, null,
"application/json");
validateContentType(response, MediaType.APPLICATION_JSON);

View File

@ -18,6 +18,7 @@ package io.spring.initializr.web.support;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.spring.initializr.metadata.DefaultMetadataElement;
import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder;
@ -43,6 +44,8 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat
*/
public class DefaultInitializrMetadataProviderTests {
private static final ObjectMapper objectMapper = new ObjectMapper();
private RestTemplate restTemplate;
private MockRestServiceServer mockServer;
@ -61,7 +64,8 @@ public class DefaultInitializrMetadataProviderTests {
.build();
assertEquals("0.0.9.RELEASE", metadata.getBootVersions().getDefault().getId());
DefaultInitializrMetadataProvider provider =
new DefaultInitializrMetadataProvider(metadata, restTemplate);
new DefaultInitializrMetadataProvider(metadata, objectMapper,
restTemplate);
expectJson(metadata.getConfiguration().getEnv().getSpringBootMetadataUrl(),
"metadata/sagan/spring-boot.json");
@ -83,7 +87,8 @@ public class DefaultInitializrMetadataProviderTests {
.addBootVersion("0.0.8.RELEASE", false).build();
assertEquals("0.0.9.RELEASE", metadata.getBootVersions().getDefault().getId());
DefaultInitializrMetadataProvider provider =
new DefaultInitializrMetadataProvider(metadata, restTemplate);
new DefaultInitializrMetadataProvider(metadata, objectMapper,
restTemplate);
expectJson(metadata.getConfiguration().getEnv().getSpringBootMetadataUrl(),
"metadata/sagan/spring-boot-no-default.json");

View File

@ -16,9 +16,11 @@
package io.spring.initializr.web.support;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.spring.initializr.metadata.DefaultMetadataElement;
import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.metadata.InitializrMetadataBuilder;
@ -43,20 +45,22 @@ public class SpringBootMetadataReaderTests {
private final InitializrMetadata metadata =
InitializrMetadataBuilder.create().build();
private final ObjectMapper objectMapper = new ObjectMapper();
private final RestTemplate restTemplate = new RestTemplate();
private final MockRestServiceServer server =
MockRestServiceServer.bindTo(restTemplate).build();
@Test
public void readAvailableVersions() {
public void readAvailableVersions() throws IOException {
server.expect(requestTo("https://spring.io/project_metadata/spring-boot"))
.andRespond(withSuccess(
new ClassPathResource("metadata/sagan/spring-boot.json"),
MediaType.APPLICATION_JSON));
List<DefaultMetadataElement> versions = new SpringBootMetadataReader(restTemplate,
metadata.getConfiguration().getEnv()
.getSpringBootMetadataUrl()).getBootVersions();
List<DefaultMetadataElement> versions = new SpringBootMetadataReader(objectMapper,
restTemplate, metadata.getConfiguration().getEnv()
.getSpringBootMetadataUrl()).getBootVersions();
assertNotNull("spring boot versions should not be null", versions);
AtomicBoolean defaultFound = new AtomicBoolean(false);
versions.forEach(it -> {

View File

@ -17,6 +17,7 @@
package io.spring.initializr.web.ui;
import io.spring.initializr.web.AbstractInitializrControllerIntegrationTests;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Test;
import org.skyscreamer.jsonassert.JSONAssert;
@ -34,23 +35,24 @@ public class UiControllerIntegrationTests
extends AbstractInitializrControllerIntegrationTests {
@Test
public void dependenciesNoVersion() {
public void dependenciesNoVersion() throws JSONException {
ResponseEntity<String> response = execute("/ui/dependencies", String.class, null);
validateContentType(response, MediaType.APPLICATION_JSON);
validateDependenciesOutput("all", new JSONObject(response.getBody()));
validateDependenciesOutput("all", response.getBody());
}
@Test
public void dependenciesSpecificVersion() {
public void dependenciesSpecificVersion() throws JSONException {
ResponseEntity<String> response = execute(
"/ui/dependencies?version=1.1.2.RELEASE", String.class, null);
validateContentType(response, MediaType.APPLICATION_JSON);
validateDependenciesOutput("1.1.2", new JSONObject(response.getBody()));
validateDependenciesOutput("1.1.2", response.getBody());
}
protected void validateDependenciesOutput(String version, JSONObject actual) {
protected void validateDependenciesOutput(String version, String actual)
throws JSONException {
JSONObject expected = readJsonFrom(
"metadata/ui/test-dependencies-" + version + ".json");
JSONAssert.assertEquals(expected, actual, JSONCompareMode.STRICT);
JSONAssert.assertEquals(expected, new JSONObject(actual), JSONCompareMode.STRICT);
}
}

View File

@ -92,6 +92,11 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
<version>0.0.20131108.vaadin1</version>
</dependency>
<dependency>
<groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId>