Upgrade to Spring Boot 2.0.0

This commit upgrades to Spring Boot 2.0.0.

Please note that this commit does not change metrics names to use new
features of Micrometer yet (see gh-526)

Closes gh-611
This commit is contained in:
Stephane Nicoll
2018-03-01 08:00:49 +01:00
parent 5629f95da2
commit fe7650f2c8
29 changed files with 216 additions and 290 deletions
+15
View File
@@ -15,6 +15,10 @@
<artifactId>initializr-generator</artifactId> <artifactId>initializr-generator</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId> <artifactId>spring-boot-actuator</artifactId>
@@ -28,6 +32,17 @@
<artifactId>spring-retry</artifactId> <artifactId>spring-retry</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<optional>true</optional>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId> <artifactId>spring-boot-configuration-processor</artifactId>
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
package io.spring.initializr.actuate.autoconfigure; package io.spring.initializr.actuate.autoconfigure;
import io.micrometer.core.instrument.MeterRegistry;
import io.spring.initializr.actuate.metric.ProjectGenerationMetricsListener; import io.spring.initializr.actuate.metric.ProjectGenerationMetricsListener;
import org.springframework.boot.actuate.metrics.CounterService; import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@@ -29,12 +33,15 @@ import org.springframework.context.annotation.Configuration;
* @author Dave Syer * @author Dave Syer
*/ */
@Configuration @Configuration
@ConditionalOnClass(MeterRegistry.class)
@AutoConfigureAfter(CompositeMeterRegistryAutoConfiguration.class)
public class InitializrMetricsConfiguration { public class InitializrMetricsConfiguration {
@Bean @Bean
@ConditionalOnSingleCandidate(MeterRegistry.class)
public ProjectGenerationMetricsListener metricsListener( public ProjectGenerationMetricsListener metricsListener(
CounterService counterService) { MeterRegistry meterRegistry) {
return new ProjectGenerationMetricsListener(counterService); return new ProjectGenerationMetricsListener(meterRegistry);
} }
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ import io.spring.initializr.metadata.InitializrMetadataProvider;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration; import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@@ -44,7 +44,7 @@ import org.springframework.retry.support.RetryTemplate;
@Configuration @Configuration
@EnableConfigurationProperties(StatsProperties.class) @EnableConfigurationProperties(StatsProperties.class)
@ConditionalOnProperty("initializr.stats.elastic.uri") @ConditionalOnProperty("initializr.stats.elastic.uri")
@AutoConfigureAfter(WebClientAutoConfiguration.class) @AutoConfigureAfter(RestTemplateAutoConfiguration.class)
class InitializrStatsAutoConfiguration { class InitializrStatsAutoConfiguration {
private final StatsProperties statsProperties; private final StatsProperties statsProperties;
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -18,28 +18,28 @@ package io.spring.initializr.actuate.metric;
import java.util.List; import java.util.List;
import io.micrometer.core.instrument.MeterRegistry;
import io.spring.initializr.generator.ProjectFailedEvent; import io.spring.initializr.generator.ProjectFailedEvent;
import io.spring.initializr.generator.ProjectGeneratedEvent; import io.spring.initializr.generator.ProjectGeneratedEvent;
import io.spring.initializr.generator.ProjectRequest; import io.spring.initializr.generator.ProjectRequest;
import io.spring.initializr.metadata.Dependency; import io.spring.initializr.metadata.Dependency;
import io.spring.initializr.util.Agent; import io.spring.initializr.util.Agent;
import org.springframework.boot.actuate.metrics.CounterService;
import org.springframework.context.event.EventListener; import org.springframework.context.event.EventListener;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
* A {@link ProjectGeneratedEvent} listener that uses a {@link CounterService} to update * A {@link ProjectGeneratedEvent} listener that uses a {@link MeterRegistry} to update
* various project related metrics. * various project related metrics.
* *
* @author Stephane Nicoll * @author Stephane Nicoll
*/ */
public class ProjectGenerationMetricsListener { public class ProjectGenerationMetricsListener {
private final CounterService counterService; private final MeterRegistry meterRegistry;
public ProjectGenerationMetricsListener(CounterService counterService) { public ProjectGenerationMetricsListener(MeterRegistry meterRegistry) {
this.counterService = counterService; this.meterRegistry = meterRegistry;
} }
@EventListener @EventListener
@@ -122,7 +122,7 @@ public class ProjectGenerationMetricsListener {
} }
protected void increment(String key) { protected void increment(String key) {
counterService.increment(key); meterRegistry.counter(key).increment();
} }
protected String key(String part) { protected String key(String part) {
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -16,6 +16,9 @@
package io.spring.initializr.actuate; package io.spring.initializr.actuate;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import io.spring.initializr.web.AbstractFullStackInitializrIntegrationTests; import io.spring.initializr.web.AbstractFullStackInitializrIntegrationTests;
import org.junit.Test; import org.junit.Test;
@@ -24,6 +27,7 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ActiveProfiles;
import static io.spring.initializr.web.AbstractInitializrIntegrationTests.*; import static io.spring.initializr.web.AbstractInitializrIntegrationTests.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@@ -35,47 +39,66 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
*/ */
@ActiveProfiles("test-default") @ActiveProfiles("test-default")
@SpringBootTest(classes = Config.class, webEnvironment = RANDOM_PORT, @SpringBootTest(classes = Config.class, webEnvironment = RANDOM_PORT,
properties = "management.security.enabled=false") properties = "management.endpoints.web.exposure.include=info,metrics")
public class ActuatorIntegrationTests public class ActuatorIntegrationTests
extends AbstractFullStackInitializrIntegrationTests { extends AbstractFullStackInitializrIntegrationTests {
@Test @Test
public void infoHasExternalProperties() { public void infoHasExternalProperties() {
String body = getRestTemplate().getForObject(createUrl("/info"), String.class); String body = getRestTemplate().getForObject(
createUrl("/actuator/info"), String.class);
assertTrue("Wrong body:\n" + body, body.contains("\"spring-boot\"")); assertTrue("Wrong body:\n" + body, body.contains("\"spring-boot\""));
assertTrue("Wrong body:\n" + body, assertTrue("Wrong body:\n" + body,
body.contains("\"version\":\"1.1.4.RELEASE\"")); body.contains("\"version\":\"1.1.4.RELEASE\""));
} }
@Test @Test
public void metricsAvailableByDefault() { public void metricsAreRegistered() {
downloadZip("/starter.zip?packaging=jar&javaVersion=1.8&style=web&style=jpa"); downloadZip("/starter.zip?packaging=jar&javaVersion=1.8&style=web&style=jpa");
JsonNode result = metricsEndpoint(); JsonNode result = metricsEndpoint();
int requests = result.get("counter.initializr.requests").intValue(); JsonNode names = result.get("names");
int packaging = result.get("counter.initializr.packaging.jar").intValue(); List<String> metrics = new ArrayList<>();
int javaVersion = result.get("counter.initializr.java_version.1_8").intValue(); for (JsonNode name : names) {
int webDependency = result.get("counter.initializr.dependency.web").intValue(); metrics.add(name.textValue());
int jpaDependency = result.get("counter.initializr.dependency.data-jpa") }
.intValue(); assertThat(metrics).contains("initializr.requests", "initializr.packaging.jar",
"initializr.java_version.1_8", "initializr.dependency.web",
"initializr.dependency.data-jpa");
int requests = metricValue("initializr.requests");
int packaging = metricValue("initializr.packaging.jar");
int javaVersion = metricValue("initializr.java_version.1_8");
int webDependency = metricValue("initializr.dependency.web");
int jpaDependency = metricValue("initializr.dependency.data-jpa");
// No jpa dep this time // No jpa dep this time
downloadZip("/starter.zip?packaging=jar&javaVersion=1.8&style=web"); downloadZip("/starter.zip?packaging=jar&javaVersion=1.8&style=web");
JsonNode updatedResult = metricsEndpoint();
assertEquals("Number of request should have increased", requests + 1, assertEquals("Number of request should have increased", requests + 1,
updatedResult.get("counter.initializr.requests").intValue()); metricValue("initializr.requests"));
assertEquals("jar packaging metric should have increased", packaging + 1, assertEquals("jar packaging metric should have increased", packaging + 1,
updatedResult.get("counter.initializr.packaging.jar").intValue()); metricValue("initializr.packaging.jar"));
assertEquals("java version metric should have increased", javaVersion + 1, assertEquals("java version metric should have increased", javaVersion + 1,
updatedResult.get("counter.initializr.java_version.1_8").intValue()); metricValue("initializr.java_version.1_8"));
assertEquals("web dependency metric should have increased", webDependency + 1, assertEquals("web dependency metric should have increased", webDependency + 1,
updatedResult.get("counter.initializr.dependency.web").intValue()); metricValue("initializr.dependency.web"));
assertEquals("jpa dependency metric should not have increased", jpaDependency, assertEquals("jpa dependency metric should not have increased", jpaDependency,
updatedResult.get("counter.initializr.dependency.data-jpa").intValue()); metricValue("initializr.dependency.data-jpa"));
} }
private JsonNode metricsEndpoint() { private JsonNode metricsEndpoint() {
return parseJson(getRestTemplate().getForObject(createUrl("/metrics"), String.class)); return parseJson(getRestTemplate().getForObject(
createUrl("/actuator/metrics"), String.class));
}
private int metricValue(String metric) {
JsonNode root = parseJson(getRestTemplate().getForObject(
createUrl("/actuator/metrics/" + metric), String.class));
JsonNode measurements = root.get("measurements");
assertThat(measurements.isArray());
assertThat(measurements.size()).isEqualTo(1);
JsonNode measurement = measurements.get(0);
return measurement.get("value").intValue();
} }
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -18,15 +18,13 @@ package io.spring.initializr.actuate.autoconfigure;
import io.spring.initializr.actuate.stat.ProjectGenerationStatPublisher; import io.spring.initializr.actuate.stat.ProjectGenerationStatPublisher;
import io.spring.initializr.metadata.InitializrMetadataProvider; import io.spring.initializr.metadata.InitializrMetadataProvider;
import org.junit.After;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor; import org.springframework.beans.DirectFieldAccessor;
import org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.web.client.RestTemplateCustomizer; import org.springframework.boot.web.client.RestTemplateCustomizer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
@@ -43,38 +41,23 @@ import static org.mockito.Mockito.mock;
*/ */
public class InitializrStatsAutoConfigurationTests { public class InitializrStatsAutoConfigurationTests {
private ConfigurableApplicationContext context; private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(RestTemplateAutoConfiguration.class,
@After InitializrStatsAutoConfiguration.class));
public void close() {
if (this.context != null) {
this.context.close();
}
}
@Test @Test
public void customRestTemplateBuilderIsUsed() { public void customRestTemplateBuilderIsUsed() {
load(CustomRestTemplateConfiguration.class, this.contextRunner.withUserConfiguration(CustomRestTemplateConfiguration.class)
"initializr.stats.elastic.uri=http://localhost:9200"); .withPropertyValues("initializr.stats.elastic.uri=http://localhost:9200")
assertThat(this.context.getBeansOfType(ProjectGenerationStatPublisher.class)) .run((context) -> {
.hasSize(1); assertThat(context).hasSingleBean(
ProjectGenerationStatPublisher.class);
RestTemplate restTemplate = (RestTemplate) new DirectFieldAccessor( RestTemplate restTemplate = (RestTemplate) new DirectFieldAccessor(
this.context.getBean(ProjectGenerationStatPublisher.class)) context.getBean(ProjectGenerationStatPublisher.class))
.getPropertyValue("restTemplate"); .getPropertyValue("restTemplate");
assertThat(restTemplate.getErrorHandler()).isSameAs( assertThat(restTemplate.getErrorHandler()).isSameAs(
CustomRestTemplateConfiguration.errorHandler); CustomRestTemplateConfiguration.errorHandler);
} });
private void load(Class<?> config, String... environment) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(ctx, environment);
if (config != null) {
ctx.register(config);
}
ctx.register(WebClientAutoConfiguration.class,
InitializrStatsAutoConfiguration.class);
ctx.refresh();
this.context = ctx;
} }
@Configuration @Configuration
@@ -96,6 +79,7 @@ public class InitializrStatsAutoConfigurationTests {
public RestTemplateCustomizer testRestTemplateCustomizer() { public RestTemplateCustomizer testRestTemplateCustomizer() {
return b -> b.setErrorHandler(errorHandler); return b -> b.setErrorHandler(errorHandler);
} }
} }
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -18,8 +18,8 @@ package io.spring.initializr.actuate.metric;
import java.util.Arrays; import java.util.Arrays;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import io.spring.initializr.actuate.test.MetricsAssert; import io.spring.initializr.actuate.test.MetricsAssert;
import io.spring.initializr.actuate.test.TestCounterService;
import io.spring.initializr.generator.ProjectFailedEvent; import io.spring.initializr.generator.ProjectFailedEvent;
import io.spring.initializr.generator.ProjectGeneratedEvent; import io.spring.initializr.generator.ProjectGeneratedEvent;
import io.spring.initializr.generator.ProjectRequest; import io.spring.initializr.generator.ProjectRequest;
@@ -42,9 +42,9 @@ public class ProjectGenerationMetricsListenerTests {
@Before @Before
public void setup() { public void setup() {
TestCounterService counterService = new TestCounterService(); SimpleMeterRegistry meterRegistry = new SimpleMeterRegistry();
listener = new ProjectGenerationMetricsListener(counterService); listener = new ProjectGenerationMetricsListener(meterRegistry);
metricsAssert = new MetricsAssert(counterService); metricsAssert = new MetricsAssert(meterRegistry);
} }
@Test @Test
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -33,8 +33,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.RequestEntity; import org.springframework.http.RequestEntity;
import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ActiveProfiles;
import org.springframework.util.Base64Utils; import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.HttpClientErrorException;
@@ -179,14 +178,14 @@ public class MainControllerStatsIntegrationTests
private final List<Content> stats = new ArrayList<>(); private final List<Content> stats = new ArrayList<>();
@RequestMapping(path = "/elastic/test/my-entity", method = RequestMethod.POST) @PostMapping("/elastic/test/my-entity")
public void handleProjectRequestDocument(RequestEntity<String> input) { public void handleProjectRequestDocument(RequestEntity<String> input) {
String authorization = input.getHeaders().getFirst(HttpHeaders.AUTHORIZATION); String authorization = input.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
Content content = new Content(authorization, input.getBody()); Content content = new Content(authorization, input.getBody());
this.stats.add(content); this.stats.add(content);
} }
@RequestMapping(path = "/elastic-error/test/my-entity", method = RequestMethod.POST) @PostMapping("/elastic-error/test/my-entity")
public void handleExpectedError() { public void handleExpectedError() {
throw new IllegalStateException("Expected exception"); throw new IllegalStateException("Expected exception");
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -18,45 +18,40 @@ package io.spring.initializr.actuate.test;
import java.util.Arrays; import java.util.Arrays;
import static org.junit.Assert.assertEquals; import io.micrometer.core.instrument.MeterRegistry;
import static org.junit.Assert.fail; import io.micrometer.core.instrument.search.Search;
import static org.assertj.core.api.Assertions.assertThat;
/** /**
* Metrics assertion based on {@link TestCounterService}. * Metrics assertion based on {@link MeterRegistry}.
* *
* @author Stephane Nicoll * @author Stephane Nicoll
*/ */
public class MetricsAssert { public class MetricsAssert {
private final TestCounterService counterService; private final MeterRegistry meterRegistry;
public MetricsAssert(TestCounterService counterService) { public MetricsAssert(MeterRegistry meterRegistry) {
this.counterService = counterService; this.meterRegistry = meterRegistry;
} }
public MetricsAssert hasValue(long value, String... metrics) { public MetricsAssert hasValue(long value, String... metrics) {
Arrays.asList(metrics).forEach(it -> { Arrays.asList(metrics).forEach(metric ->
Long actual = counterService.getValues().get(it); assertThat(meterRegistry.get(metric).counter().count()).isEqualTo(value));
if (actual == null) {
fail("Metric '" + it + "' not found, got '"
+ counterService.getValues().keySet() + "'");
}
assertEquals("Wrong value for metric " + it, value, actual.longValue());
});
return this; return this;
} }
public MetricsAssert hasNoValue(String... metrics) { public MetricsAssert hasNoValue(String... metrics) {
Arrays.asList(metrics).forEach(it -> Arrays.asList(metrics).forEach(metric ->
assertEquals("Metric '" + it + "' should not be registered", null, assertThat(Search.in(this.meterRegistry).name(n -> n.startsWith(metric))
counterService.getValues().get(it))); .counter()).isNull());
return this; return this;
} }
public MetricsAssert metricsCount(int count) { public MetricsAssert metricsCount(int count) {
assertEquals( assertThat(Search.in(this.meterRegistry).meters()).hasSize(count);
"Wrong number of metrics, got '" + counterService.getValues().keySet() + "'",
count, counterService.getValues().size());
return this; return this;
} }
} }
@@ -1,56 +0,0 @@
/*
* Copyright 2012-2017 the original author or 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
*
* 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.
*/
package io.spring.initializr.actuate.test;
import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.actuate.metrics.CounterService;
/**
* A test {@link CounterService} that keeps track of the metric values.
*
* @author Stephane Nicoll
*/
public class TestCounterService implements CounterService {
private final Map<String, Long> values = new HashMap<>();
@Override
public void increment(String metricName) {
Long value = getValues().get(metricName);
Long valueToSet = value != null ? ++value : 1;
getValues().put(metricName, valueToSet);
}
@Override
public void decrement(String metricName) {
Long value = getValues().get(metricName);
Long valueToSet = value != null ? +--value : -1;
getValues().put(metricName, valueToSet);
}
@Override
public void reset(String metricName) {
getValues().put(metricName, 0L);
}
public Map<String, Long> getValues() {
return values;
}
}
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@ import org.mockito.ArgumentMatcher;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import static org.mockito.Matchers.argThat; import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@@ -105,15 +105,17 @@ public abstract class AbstractProjectGeneratorTests {
} }
protected void verifyProjectSuccessfulEventFor(ProjectRequest request) { protected void verifyProjectSuccessfulEventFor(ProjectRequest request) {
verify(eventPublisher, times(1)).publishEvent(argThat(new ProjectGeneratedEventMatcher(request))); verify(eventPublisher, times(1)).publishEvent(
argThat(new ProjectGeneratedEventMatcher(request)));
} }
protected void verifyProjectFailedEventFor(ProjectRequest request, Exception ex) { protected void verifyProjectFailedEventFor(ProjectRequest request, Exception ex) {
verify(eventPublisher, times(1)).publishEvent(argThat(new ProjectFailedEventMatcher(request, ex))); verify(eventPublisher, times(1)).publishEvent(
argThat(new ProjectFailedEventMatcher(request, ex)));
} }
protected static class ProjectGeneratedEventMatcher protected static class ProjectGeneratedEventMatcher
extends ArgumentMatcher<ProjectGeneratedEvent> { implements ArgumentMatcher<ProjectGeneratedEvent> {
private final ProjectRequest request; private final ProjectRequest request;
@@ -122,16 +124,16 @@ public abstract class AbstractProjectGeneratorTests {
} }
@Override @Override
public boolean matches(Object argument) { public boolean matches(ProjectGeneratedEvent event) {
ProjectGeneratedEvent event = (ProjectGeneratedEvent) argument;
return request.equals(event.getProjectRequest()); return request.equals(event.getProjectRequest());
} }
} }
private static class ProjectFailedEventMatcher private static class ProjectFailedEventMatcher
extends ArgumentMatcher<ProjectFailedEvent> { implements ArgumentMatcher<ProjectFailedEvent> {
private final ProjectRequest request; private final ProjectRequest request;
private final Exception cause; private final Exception cause;
ProjectFailedEventMatcher(ProjectRequest request, Exception cause) { ProjectFailedEventMatcher(ProjectRequest request, Exception cause) {
@@ -140,8 +142,7 @@ public abstract class AbstractProjectGeneratorTests {
} }
@Override @Override
public boolean matches(Object argument) { public boolean matches(ProjectFailedEvent event) {
ProjectFailedEvent event = (ProjectFailedEvent) argument;
return request.equals(event.getProjectRequest()) return request.equals(event.getProjectRequest())
&& cause.equals(event.getCause()); && cause.equals(event.getCause());
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ import org.mockito.Mockito;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import static org.mockito.Matchers.argThat; import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
@@ -826,7 +826,7 @@ public class ProjectGeneratorTests extends AbstractProjectGeneratorTests {
applyMetadata(metadata); applyMetadata(metadata);
ProjectRequest request = createProjectRequest("one", "web", "two", "data-jpa"); ProjectRequest request = createProjectRequest("one", "web", "two", "data-jpa");
assertThat(generateGradleBuild(request).getGradleBuild()) assertThat(generateGradleBuild(request).getGradleBuild())
.containsSequence( .containsSubsequence(
"compile('org.springframework.boot:spring-boot-starter-data-jpa')", "compile('org.springframework.boot:spring-boot-starter-data-jpa')",
"compile('org.springframework.boot:spring-boot-starter-web')", "compile('org.springframework.boot:spring-boot-starter-web')",
"compile('com.example:second:1.2.3')", "compile('com.example:second:1.2.3')",
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -23,9 +23,9 @@ import java.util.Properties;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.boot.bind.PropertiesConfigurationFactory; import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.core.env.MutablePropertySources; import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
import org.springframework.core.env.PropertiesPropertySource; import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
@@ -208,19 +208,10 @@ public class InitializrMetadataBuilderTests {
} }
private static InitializrProperties load(Resource resource) { private static InitializrProperties load(Resource resource) {
PropertiesConfigurationFactory<InitializrProperties> factory = new PropertiesConfigurationFactory<>( ConfigurationPropertySource source = new MapConfigurationPropertySource(
InitializrProperties.class); loadProperties(resource));
factory.setTargetName("initializr"); Binder binder = new Binder(source);
MutablePropertySources sources = new MutablePropertySources(); return binder.bind("initializr", InitializrProperties.class).get();
sources.addFirst(new PropertiesPropertySource("main", loadProperties(resource)));
factory.setPropertySources(sources);
try {
factory.afterPropertiesSet();
return factory.getObject();
}
catch (Exception e) {
throw new IllegalStateException("Could not create InitializrProperties", e);
}
} }
private static Properties loadProperties(Resource resource) { private static Properties loadProperties(Resource resource) {
+4
View File
@@ -12,6 +12,10 @@
<name>Spring Initializr :: Service</name> <name>Spring Initializr :: Service</name>
<dependencies> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
@@ -1,36 +1,8 @@
endpoints:
actuator:
enabled: false
autoconfig:
enabled: false
beans:
enabled: false
configprops:
enabled: false
docs:
enabled: false
dump:
enabled: false
env:
enabled: false
heapdump:
enabled: false
logfile:
enabled: false
loggers:
enabled: false
trace:
enabled: false
logging: logging:
level: level:
org.springframework.core.env: warn org.springframework.core.env: warn
org.springframework.jndi: warn org.springframework.jndi: warn
management:
security:
enabled: false
server: server:
compression: compression:
enabled: true enabled: true
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -47,9 +47,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration; import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@@ -70,7 +70,7 @@ import org.springframework.web.servlet.resource.ResourceUrlProvider;
@Configuration @Configuration
@EnableConfigurationProperties(InitializrProperties.class) @EnableConfigurationProperties(InitializrProperties.class)
@AutoConfigureAfter({ CacheAutoConfiguration.class, JacksonAutoConfiguration.class, @AutoConfigureAfter({ CacheAutoConfiguration.class, JacksonAutoConfiguration.class,
WebClientAutoConfiguration.class }) RestTemplateAutoConfiguration.class })
public class InitializrAutoConfiguration { public class InitializrAutoConfiguration {
private final List<ProjectRequestPostProcessor> postProcessors; private final List<ProjectRequestPostProcessor> postProcessors;
@@ -90,9 +90,9 @@ public class InitializrAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public TemplateRenderer templateRenderer(Environment environment) { public TemplateRenderer templateRenderer(Environment environment) {
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(environment, Binder binder = Binder.get(environment);
"spring.mustache."); boolean cache = binder.bind("spring.mustache.cache", Boolean.class)
boolean cache = resolver.getProperty("cache", Boolean.class, true); .orElseGet(() -> true);
TemplateRenderer templateRenderer = new TemplateRenderer(); TemplateRenderer templateRenderer = new TemplateRenderer();
templateRenderer.setCache(cache); templateRenderer.setCache(cache);
return templateRenderer; return templateRenderer;
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -31,7 +31,8 @@ import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.accept.ContentNegotiationStrategy; import org.springframework.web.accept.ContentNegotiationStrategy;
import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.util.UrlPathHelper; import org.springframework.web.util.UrlPathHelper;
/** /**
@@ -39,7 +40,12 @@ import org.springframework.web.util.UrlPathHelper;
* *
* @author Stephane Nicoll * @author Stephane Nicoll
*/ */
public class WebConfig extends WebMvcConfigurerAdapter { public class WebConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addRedirectViewController("/info", "/actuator/info");
}
@Override @Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ import java.util.Map;
import io.spring.initializr.metadata.InitializrMetadataProvider; import io.spring.initializr.metadata.InitializrMetadataProvider;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.resource.ResourceUrlProvider; import org.springframework.web.servlet.resource.ResourceUrlProvider;
/** /**
@@ -37,7 +37,7 @@ public class LegacyStsController extends AbstractInitializrController {
super(metadataProvider, resourceUrlProvider); super(metadataProvider, resourceUrlProvider);
} }
@RequestMapping(value = "/sts", produces = "text/html") @GetMapping(path = "/sts", produces = "text/html")
public String stsHome(Map<String, Object> model) { public String stsHome(Map<String, Object> model) {
renderHome(model); renderHome(model);
return "sts-home"; return "sts-home";
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -58,9 +58,9 @@ import org.springframework.http.ResponseEntity.BodyBuilder;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.util.DigestUtils; import org.springframework.util.DigestUtils;
import org.springframework.util.StreamUtils; import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.resource.ResourceUrlProvider; import org.springframework.web.servlet.resource.ResourceUrlProvider;
@@ -107,18 +107,18 @@ public class MainController extends AbstractInitializrController {
return request; return request;
} }
@RequestMapping(value = "/metadata/config", produces = "application/json") @GetMapping(path = "/metadata/config", produces = "application/json")
@ResponseBody @ResponseBody
public InitializrMetadata config() { public InitializrMetadata config() {
return metadataProvider.get(); return metadataProvider.get();
} }
@RequestMapping(value = "/metadata/client") @GetMapping("/metadata/client")
public String client() { public String client() {
return "redirect:/"; return "redirect:/";
} }
@RequestMapping(value = "/", produces = "text/plain") @GetMapping(path = "/", produces = "text/plain")
public ResponseEntity<String> serviceCapabilitiesText( public ResponseEntity<String> serviceCapabilitiesText(
@RequestHeader(value = HttpHeaders.USER_AGENT, required = false) String userAgent) { @RequestHeader(value = HttpHeaders.USER_AGENT, required = false) String userAgent) {
String appUrl = generateAppUrl(); String appUrl = generateAppUrl();
@@ -150,19 +150,19 @@ public class MainController extends AbstractInitializrController {
return builder.eTag(createUniqueId(content)).body(content); return builder.eTag(createUniqueId(content)).body(content);
} }
@RequestMapping(value = "/", produces = "application/hal+json") @GetMapping(path = "/", produces = "application/hal+json")
public ResponseEntity<String> serviceCapabilitiesHal() { public ResponseEntity<String> serviceCapabilitiesHal() {
return serviceCapabilitiesFor(InitializrMetadataVersion.V2_1, return serviceCapabilitiesFor(InitializrMetadataVersion.V2_1,
HAL_JSON_CONTENT_TYPE); HAL_JSON_CONTENT_TYPE);
} }
@RequestMapping(value = "/", produces = { "application/vnd.initializr.v2.1+json", @GetMapping(path = "/", produces = { "application/vnd.initializr.v2.1+json",
"application/json" }) "application/json" })
public ResponseEntity<String> serviceCapabilitiesV21() { public ResponseEntity<String> serviceCapabilitiesV21() {
return serviceCapabilitiesFor(InitializrMetadataVersion.V2_1); return serviceCapabilitiesFor(InitializrMetadataVersion.V2_1);
} }
@RequestMapping(value = "/", produces = "application/vnd.initializr.v2+json") @GetMapping(path = "/", produces = "application/vnd.initializr.v2+json")
public ResponseEntity<String> serviceCapabilitiesV2() { public ResponseEntity<String> serviceCapabilitiesV2() {
return serviceCapabilitiesFor(InitializrMetadataVersion.V2); return serviceCapabilitiesFor(InitializrMetadataVersion.V2);
} }
@@ -190,7 +190,7 @@ public class MainController extends AbstractInitializrController {
} }
} }
@RequestMapping(value = "/dependencies", produces = { @GetMapping(path = "/dependencies", produces = {
"application/vnd.initializr.v2.1+json", "application/json" }) "application/vnd.initializr.v2.1+json", "application/json" })
public ResponseEntity<String> dependenciesV21( public ResponseEntity<String> dependenciesV21(
@RequestParam(required = false) String bootVersion) { @RequestParam(required = false) String bootVersion) {
@@ -215,25 +215,25 @@ public class MainController extends AbstractInitializrController {
return (frag, out) -> out.write(this.getLinkTo().apply(frag.execute())); return (frag, out) -> out.write(this.getLinkTo().apply(frag.execute()));
} }
@RequestMapping(value = "/", produces = "text/html") @GetMapping(path = "/", produces = "text/html")
public String home(Map<String, Object> model) { public String home(Map<String, Object> model) {
renderHome(model); renderHome(model);
return "home"; return "home";
} }
@RequestMapping("/spring") @GetMapping(path = { "/spring", "/spring.zip" })
public String spring() { public String spring() {
String url = metadataProvider.get().createCliDistributionURl("zip"); String url = metadataProvider.get().createCliDistributionURl("zip");
return "redirect:" + url; return "redirect:" + url;
} }
@RequestMapping(value = { "/spring.tar.gz", "spring.tgz" }) @GetMapping(path = { "/spring.tar.gz", "spring.tgz" })
public String springTgz() { public String springTgz() {
String url = metadataProvider.get().createCliDistributionURl("tar.gz"); String url = metadataProvider.get().createCliDistributionURl("tar.gz");
return "redirect:" + url; return "redirect:" + url;
} }
@RequestMapping("/pom") @GetMapping(path = { "/pom", "/pom.xml" })
@ResponseBody @ResponseBody
public ResponseEntity<byte[]> pom(BasicProjectRequest request) { public ResponseEntity<byte[]> pom(BasicProjectRequest request) {
request.setType("maven-build"); request.setType("maven-build");
@@ -241,7 +241,7 @@ public class MainController extends AbstractInitializrController {
return createResponseEntity(mavenPom, "application/octet-stream", "pom.xml"); return createResponseEntity(mavenPom, "application/octet-stream", "pom.xml");
} }
@RequestMapping("/build") @GetMapping(path = { "/build", "/build.gradle" })
@ResponseBody @ResponseBody
public ResponseEntity<byte[]> gradle(BasicProjectRequest request) { public ResponseEntity<byte[]> gradle(BasicProjectRequest request) {
request.setType("gradle-build"); request.setType("gradle-build");
@@ -251,7 +251,7 @@ public class MainController extends AbstractInitializrController {
"build.gradle"); "build.gradle");
} }
@RequestMapping("/starter.zip") @GetMapping("/starter.zip")
@ResponseBody @ResponseBody
public ResponseEntity<byte[]> springZip(BasicProjectRequest basicRequest) public ResponseEntity<byte[]> springZip(BasicProjectRequest basicRequest)
throws IOException { throws IOException {
@@ -282,7 +282,7 @@ public class MainController extends AbstractInitializrController {
return upload(download, dir, generateFileName(request, "zip"), "application/zip"); return upload(download, dir, generateFileName(request, "zip"), "application/zip");
} }
@RequestMapping(value = "/starter.tgz", produces = "application/x-compress") @GetMapping(path = "/starter.tgz", produces = "application/x-compress")
@ResponseBody @ResponseBody
public ResponseEntity<byte[]> springTgz(BasicProjectRequest basicRequest) public ResponseEntity<byte[]> springTgz(BasicProjectRequest basicRequest)
throws IOException { throws IOException {
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@ import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils; import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@@ -51,7 +51,7 @@ public class UiController {
this.metadataProvider = metadataProvider; this.metadataProvider = metadataProvider;
} }
@RequestMapping(value = "/ui/dependencies", produces = "application/json") @GetMapping(path = "/ui/dependencies", produces = "application/json")
public ResponseEntity<String> dependencies( public ResponseEntity<String> dependencies(
@RequestParam(required = false) String version) { @RequestParam(required = false) String version) {
List<DependencyGroup> dependencyGroups = metadataProvider.get() List<DependencyGroup> dependencyGroups = metadataProvider.get()
@@ -146,7 +146,7 @@ $(function () {
$("#starters div[data-id='" + id + "']").remove(); $("#starters div[data-id='" + id + "']").remove();
}; };
var initializeSearchEngine = function (engine, bootVersion) { var initializeSearchEngine = function (engine, bootVersion) {
$.getJSON("/ui/dependencies.json?version=" + bootVersion, function (data) { $.getJSON("/ui/dependencies?version=" + bootVersion, function (data) {
engine.clear(); engine.clear();
$.each(data.dependencies, function(idx, item) { $.each(data.dependencies, function(idx, item) {
if(item.weight === undefined) { if(item.weight === undefined) {
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -19,8 +19,8 @@ package io.spring.initializr.web;
import io.spring.initializr.web.AbstractInitializrIntegrationTests.Config; import io.spring.initializr.web.AbstractInitializrIntegrationTests.Config;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -17,16 +17,14 @@
package io.spring.initializr.web.autoconfigure; package io.spring.initializr.web.autoconfigure;
import io.spring.initializr.metadata.InitializrMetadataProvider; import io.spring.initializr.metadata.InitializrMetadataProvider;
import org.junit.After;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor; import org.springframework.beans.DirectFieldAccessor;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration; import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;
import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.web.client.RestTemplateCustomizer; import org.springframework.boot.web.client.RestTemplateCustomizer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.ResponseErrorHandler;
@@ -42,37 +40,23 @@ import static org.mockito.Mockito.mock;
*/ */
public class InitializrAutoConfigurationTests { public class InitializrAutoConfigurationTests {
private ConfigurableApplicationContext context; private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(RestTemplateAutoConfiguration.class,
JacksonAutoConfiguration.class,
InitializrAutoConfiguration.class));
@After
public void close() {
if (this.context != null) {
this.context.close();
}
}
@Test @Test
public void customRestTemplateBuilderIsUsed() { public void customRestTemplateBuilderIsUsed() {
load(CustomRestTemplateConfiguration.class); this.contextRunner.withUserConfiguration(CustomRestTemplateConfiguration.class)
assertThat(this.context.getBeansOfType(InitializrMetadataProvider.class)) .run((context) -> {
.hasSize(1); assertThat(context).hasSingleBean(InitializrMetadataProvider.class);
RestTemplate restTemplate = (RestTemplate) new DirectFieldAccessor( RestTemplate restTemplate = (RestTemplate) new DirectFieldAccessor(
this.context.getBean(InitializrMetadataProvider.class)) context.getBean(InitializrMetadataProvider.class))
.getPropertyValue("restTemplate"); .getPropertyValue("restTemplate");
assertThat(restTemplate.getErrorHandler()).isSameAs( assertThat(restTemplate.getErrorHandler()).isSameAs(
CustomRestTemplateConfiguration.errorHandler); CustomRestTemplateConfiguration.errorHandler);
} });
private void load(Class<?> config, String... environment) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(ctx, environment);
if (config != null) {
ctx.register(config);
}
ctx.register(WebClientAutoConfiguration.class, JacksonAutoConfiguration.class,
InitializrAutoConfiguration.class);
ctx.refresh();
this.context = ctx;
} }
@Configuration @Configuration
@@ -84,6 +68,7 @@ public class InitializrAutoConfigurationTests {
public RestTemplateCustomizer testRestTemplateCustomizer() { public RestTemplateCustomizer testRestTemplateCustomizer() {
return b -> b.setErrorHandler(errorHandler); return b -> b.setErrorHandler(errorHandler);
} }
} }
} }
@@ -29,6 +29,7 @@ import org.junit.Test;
import org.openqa.selenium.Keys; import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.firefox.FirefoxProfile; import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.interactions.Action; import org.openqa.selenium.interactions.Action;
import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.interactions.Actions;
@@ -59,14 +60,13 @@ public class ProjectGenerationSmokeTests
Boolean.getBoolean("smoke.test")); Boolean.getBoolean("smoke.test"));
downloadDir = folder.newFolder(); downloadDir = folder.newFolder();
FirefoxProfile fxProfile = new FirefoxProfile(); FirefoxProfile fxProfile = new FirefoxProfile();
fxProfile.setPreference("browser.download.folderList", 2); fxProfile.setPreference("browser.download.folderList", 2);
fxProfile.setPreference("browser.download.manager.showWhenStarting", false); fxProfile.setPreference("browser.download.manager.showWhenStarting", false);
fxProfile.setPreference("browser.download.dir", downloadDir.getAbsolutePath()); fxProfile.setPreference("browser.download.dir", downloadDir.getAbsolutePath());
fxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk", fxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk",
"application/zip,application/x-compress,application/octet-stream"); "application/zip,application/x-compress,application/octet-stream");
FirefoxOptions options = new FirefoxOptions().setProfile(fxProfile);
driver = new FirefoxDriver(fxProfile); driver = new FirefoxDriver(options);
Actions actions = new Actions(driver); Actions actions = new Actions(driver);
enterAction = actions.sendKeys(Keys.ENTER).build(); enterAction = actions.sendKeys(Keys.ENTER).build();
+8 -8
View File
@@ -37,7 +37,7 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.boot.version>1.5.10.RELEASE</spring.boot.version> <spring.boot.version>2.0.0.RELEASE</spring.boot.version>
<java.version>1.8</java.version> <java.version>1.8</java.version>
</properties> </properties>
@@ -79,16 +79,16 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-cloud-contract-dependencies</artifactId> <artifactId>spring-boot-dependencies</artifactId>
<version>1.2.1.RELEASE</version> <version>${spring.boot.version}</version>
<type>pom</type> <type>pom</type>
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-boot-dependencies</artifactId> <artifactId>spring-cloud-contract-dependencies</artifactId>
<version>${spring.boot.version}</version> <version>1.2.1.RELEASE</version>
<type>pom</type> <type>pom</type>
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
@@ -105,7 +105,7 @@
<dependency> <dependency>
<groupId>org.apache.ant</groupId> <groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId> <artifactId>ant</artifactId>
<version>1.10.1</version> <version>1.10.2</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>org.apache.ant</groupId> <groupId>org.apache.ant</groupId>