Modularize project structure

This commit splits the feature of Spring Initializr in several modules:

* `initializr-generator` is a standalone library that is responsible for
generating projects based on a `File` directory. It has a minimal set of
dependencies and is not web-related
* `initializr-web` provides the web integration (project generation,
meta-data, etc)
* `initializr-actuator` is an optional module that can be added to
support project-generation-specific statistics

Closes gh-214
This commit is contained in:
Stephane Nicoll
2016-04-05 17:50:45 +02:00
parent 35cfc8f139
commit 542ee7d91b
185 changed files with 1184 additions and 893 deletions

View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.spring.initalizr</groupId>
<artifactId>initializr</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>initializr-actuator</artifactId>
<name>Spring Initializr :: Actuator</name>
<dependencies>
<dependency>
<groupId>io.spring.initalizr</groupId>
<artifactId>initializr-generator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.spring.initalizr</groupId>
<artifactId>initializr-generator</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.spring.initalizr</groupId>
<artifactId>initializr-web</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.spring.initalizr</groupId>
<artifactId>initializr-web</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -14,11 +14,14 @@
* limitations under the License.
*/
package io.spring.initializr.config
package io.spring.initializr.actuate.autoconfigure
import io.spring.initializr.actuate.metric.ProjectGenerationMetricsListener
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.actuate.autoconfigure.ExportMetricWriter
import org.springframework.boot.actuate.autoconfigure.MetricExportAutoConfiguration
import org.springframework.boot.actuate.metrics.CounterService
import org.springframework.boot.actuate.metrics.repository.redis.RedisMetricRepository
import org.springframework.boot.actuate.metrics.writer.MetricWriter
import org.springframework.boot.autoconfigure.AutoConfigureAfter
@@ -35,35 +38,45 @@ import org.springframework.util.ObjectUtils
/**
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
* Auto-configuration} to export the metrics of an initializr instance.
* Auto-configuration} to handle the metrics of an initializr instance.
*
* @author Dave Syer
* @since 1.0
*/
@Configuration
@ConditionalOnBean(RedisConnectionFactory)
@ConditionalOnProperty(value = 'spring.metrics.export.enabled')
@EnableScheduling
@EnableConfigurationProperties(MetricsProperties)
@AutoConfigureAfter([RedisAutoConfiguration, MetricExportAutoConfiguration])
class InitializrMetricsExporterAutoConfiguration {
@Autowired
RedisConnectionFactory connectionFactory
@Autowired
MetricsProperties metrics
@Autowired
ApplicationContext context
class InitializrMetricsConfiguration {
@Bean
@ExportMetricWriter
MetricWriter writer() {
new RedisMetricRepository(connectionFactory,
metrics.prefix + metrics.getId(context.getId()) + '.'
+ ObjectUtils.getIdentityHexString(context) + '.',
metrics.key)
ProjectGenerationMetricsListener metricsListener(CounterService counterService) {
new ProjectGenerationMetricsListener(counterService)
}
@ConditionalOnBean(RedisConnectionFactory)
@ConditionalOnProperty(value = 'spring.metrics.export.enabled')
@EnableScheduling
@EnableConfigurationProperties(MetricsProperties)
@Configuration
public static class MetricsExportConfiguration {
@Autowired
RedisConnectionFactory connectionFactory
@Autowired
MetricsProperties metrics
@Autowired
ApplicationContext context
@Bean
@ExportMetricWriter
MetricWriter writer() {
new RedisMetricRepository(connectionFactory,
metrics.prefix + metrics.getId(context.getId()) + '.'
+ ObjectUtils.getIdentityHexString(context) + '.',
metrics.key)
}
}
}

View File

@@ -14,14 +14,14 @@
* limitations under the License.
*/
package io.spring.initializr.config
package io.spring.initializr.actuate.autoconfigure
import io.spring.initializr.actuate.stat.ProjectGenerationStatPublisher
import io.spring.initializr.actuate.stat.ProjectRequestDocumentFactory
import io.spring.initializr.actuate.stat.StatsProperties
import io.spring.initializr.metadata.InitializrMetadataProvider
import io.spring.initializr.stat.ProjectGenerationStatPublisher
import io.spring.initializr.stat.ProjectRequestDocumentFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.AutoConfigureAfter
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.boot.context.properties.EnableConfigurationProperties
@@ -40,7 +40,6 @@ import org.springframework.retry.support.RetryTemplate
*/
@Configuration
@EnableConfigurationProperties(StatsProperties)
@AutoConfigureAfter(InitializrAutoConfiguration)
@ConditionalOnProperty('initializr.stats.elastic.uri')
class InitializrStatsAutoConfiguration {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2012-2016 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.spring.initializr.config
package io.spring.initializr.actuate.autoconfigure
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.context.properties.ConfigurationProperties

View File

@@ -14,9 +14,12 @@
* limitations under the License.
*/
package io.spring.initializr.generator
package io.spring.initializr.actuate.metric
import io.spring.initializr.util.UserAgentWrapper
import io.spring.initializr.generator.ProjectFailedEvent
import io.spring.initializr.generator.ProjectGeneratedEvent
import io.spring.initializr.generator.ProjectRequest
import io.spring.initializr.util.Agent
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.actuate.metrics.CounterService
@@ -108,10 +111,9 @@ class ProjectGenerationMetricsListener {
protected void handleUserAgent(ProjectRequest request) {
String userAgent = request.parameters['user-agent']
if (userAgent) {
UserAgentWrapper wrapper = new UserAgentWrapper(userAgent)
def information = wrapper.extractAgentInformation()
if (information) {
increment(key("client_id.$information.id.id"))
Agent agent = Agent.fromUserAgent(userAgent)
if (agent) {
increment(key("client_id.$agent.id.id"))
}
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.spring.initializr.stat
package io.spring.initializr.actuate.stat
import java.nio.charset.StandardCharsets

View File

@@ -14,12 +14,11 @@
* limitations under the License.
*/
package io.spring.initializr.stat
package io.spring.initializr.actuate.stat
import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.databind.ObjectMapper
import groovy.util.logging.Slf4j
import io.spring.initializr.config.StatsProperties
import io.spring.initializr.generator.ProjectRequestEvent
import org.springframework.context.event.EventListener

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.spring.initializr.stat
package io.spring.initializr.actuate.stat
import groovy.transform.ToString

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.spring.initializr.stat
package io.spring.initializr.actuate.stat
import java.util.regex.Matcher
import java.util.regex.Pattern
@@ -23,9 +23,7 @@ import io.spring.initializr.generator.ProjectFailedEvent
import io.spring.initializr.generator.ProjectRequest
import io.spring.initializr.generator.ProjectRequestEvent
import io.spring.initializr.metadata.InitializrMetadataProvider
import io.spring.initializr.util.UserAgentWrapper
import static io.spring.initializr.util.UserAgentWrapper.AgentInformation
import io.spring.initializr.util.Agent
/**
* Create {@link ProjectRequestDocument} instances.
@@ -57,10 +55,10 @@ class ProjectRequestDocumentFactory {
document.requestIpv4 = extractIpv4(candidate)
}
AgentInformation agentInfo = extractAgentInformation(request)
if (agentInfo) {
document.clientId = agentInfo.id.id
document.clientVersion = agentInfo.version
Agent agent = extractAgentInformation(request)
if (agent) {
document.clientId = agent.id.id
document.clientVersion = agent.version
}
document.groupId = request.groupId
@@ -128,10 +126,10 @@ class ProjectRequestDocumentFactory {
}
}
private static AgentInformation extractAgentInformation(ProjectRequest request) {
private static Agent extractAgentInformation(ProjectRequest request) {
String userAgent = request.parameters['user-agent']
if (userAgent) {
return new UserAgentWrapper(userAgent).extractAgentInformation()
return Agent.fromUserAgent(userAgent)
}
return null
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.spring.initializr.config
package io.spring.initializr.actuate.stat
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.util.StringUtils

View File

@@ -0,0 +1,55 @@
{
"groups": [
{
"name": "initializr.stats",
"type": "io.spring.initializr.actuate.stat.StatsProperties",
"sourceType": "io.spring.initializr.actuate.stat.StatsProperties"
},
{
"name": "initializr.stats.elastic",
"type": "io.spring.initializr.actuate.stat.StatsProperties$Elastic",
"sourceType": "io.spring.initializr.actuate.stat.StatsProperties",
"sourceMethod": "getElastic()"
}
],
"properties": [
{
"name": "initializr.stats.elastic.uri",
"type": "java.lang.String",
"description": "Elastic service uri.",
"sourceType": "io.spring.initializr.actuate.stat.StatsProperties$Elastic"
},
{
"name": "initializr.stats.elastic.username",
"type": "java.lang.String",
"description": "Elastic service username.",
"sourceType": "io.spring.initializr.actuate.stat.StatsProperties$Elastic"
},
{
"name": "initializr.stats.elastic.password",
"type": "java.lang.String",
"description": "Elastic service password.",
"sourceType": "io.spring.initializr.actuate.stat.StatsProperties$Elastic"
},
{
"name": "initializr.stats.elastic.index-name",
"type": "java.lang.String",
"description": "Name of the index.",
"sourceType": "io.spring.initializr.actuate.stat.StatsProperties$Elastic"
},
{
"name": "initializr.stats.elastic.entity-name",
"type": "java.lang.String",
"description": "Name of the entity to use to publish stats.",
"sourceType": "io.spring.initializr.actuate.stat.StatsProperties$Elastic"
},
{
"name": "initializr.stats.elastic.max-attempts",
"type": "java.lang.Integer",
"description": "Number of attempts before giving up.",
"defaultValue": 3,
"sourceType": "io.spring.initializr.actuate.stat.StatsProperties$Elastic"
}
],
"hints": []
}

View File

@@ -0,0 +1,3 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
io.spring.initializr.actuate.autoconfigure.InitializrStatsAutoConfiguration,\
io.spring.initializr.actuate.autoconfigure.InitializrMetricsConfiguration

View File

@@ -0,0 +1,78 @@
/*
* Copyright 2012-2016 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
import groovy.json.JsonSlurper
import io.spring.initializr.web.AbstractInitializrControllerIntegrationTests
import org.junit.Test
import org.springframework.test.context.ActiveProfiles
import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertTrue
/**
* Tests for actuator specific features.
*
* @author Stephane Nicoll
*/
@ActiveProfiles('test-default')
class ActuatorIntegrationTests extends AbstractInitializrControllerIntegrationTests {
private final def slurper = new JsonSlurper()
@Test
void infoHasExternalProperties() {
def body = restTemplate.getForObject(createUrl('/info'), String)
assertTrue("Wrong body:\n$body", body.contains('"spring-boot"'))
assertTrue("Wrong body:\n$body", body.contains('"version":"1.1.4.RELEASE"'))
}
@Test
void metricsAvailableByDefault() {
downloadZip('/starter.zip?packaging=jar&javaVersion=1.8&style=web&style=jpa')
def result = metricsEndpoint()
def requests = result['counter.initializr.requests']
def packaging = result['counter.initializr.packaging.jar']
def javaVersion = result['counter.initializr.java_version.1_8']
def webDependency = result['counter.initializr.dependency.web']
def jpaDependency = result['counter.initializr.dependency.jpa']
downloadZip('/starter.zip?packaging=jar&javaVersion=1.8&style=web') // No jpa dep this time
def updatedResult = metricsEndpoint()
assertEquals 'Number of request should have increased',
requests + 1, updatedResult['counter.initializr.requests']
assertEquals 'jar packaging metric should have increased',
packaging + 1, updatedResult['counter.initializr.packaging.jar']
assertEquals 'java version metric should have increased',
javaVersion + 1, updatedResult['counter.initializr.java_version.1_8']
assertEquals 'web dependency metric should have increased',
webDependency + 1, updatedResult['counter.initializr.dependency.web']
assertEquals 'jpa dependency metric should not have increased',
jpaDependency, updatedResult['counter.initializr.dependency.jpa']
}
private def metricsEndpoint() {
parseJson(restTemplate.getForObject(createUrl('/metrics'), String))
}
private def parseJson(String content) {
slurper.parseText(content)
}
}

View File

@@ -14,16 +14,15 @@
* limitations under the License.
*/
package io.spring.initializr.metrics
package io.spring.initializr.actuate.metric
import io.spring.initializr.actuate.test.RedisRunning
import io.spring.initializr.generator.ProjectGeneratedEvent
import io.spring.initializr.generator.ProjectGenerationMetricsListener
import io.spring.initializr.generator.ProjectRequest
import io.spring.initializr.metadata.InitializrMetadataBuilder
import io.spring.initializr.metadata.InitializrMetadataProvider
import io.spring.initializr.metadata.InitializrProperties
import io.spring.initializr.test.OfflineInitializrMetadataProvider
import io.spring.initializr.test.RedisRunning
import io.spring.initializr.metadata.SimpleInitializrMetadataProvider
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -34,6 +33,7 @@ import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.boot.actuate.metrics.repository.redis.RedisMetricRepository
import org.springframework.boot.actuate.metrics.writer.MetricWriter
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.test.IntegrationTest
import org.springframework.boot.test.SpringApplicationConfiguration
import org.springframework.context.annotation.Bean
@@ -80,12 +80,13 @@ public class MetricsExportTests {
}
@EnableAutoConfiguration
@EnableConfigurationProperties(InitializrProperties)
static class Config {
@Bean
InitializrMetadataProvider initializrMetadataProvider(InitializrProperties properties) {
def metadata = InitializrMetadataBuilder.fromInitializrProperties(properties).build()
new OfflineInitializrMetadataProvider(metadata)
new SimpleInitializrMetadataProvider(metadata)
}
}
}

View File

@@ -14,13 +14,16 @@
* limitations under the License.
*/
package io.spring.initializr.generator
package io.spring.initializr.actuate.metric
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.ProjectGeneratedEvent
import io.spring.initializr.generator.ProjectRequest
import io.spring.initializr.metadata.Dependency
import io.spring.initializr.metadata.InitializrMetadata
import io.spring.initializr.test.InitializrMetadataTestBuilder
import io.spring.initializr.test.MetricsAssert
import io.spring.initializr.test.TestCounterService
import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder
import org.junit.Before
import org.junit.Test

View File

@@ -14,12 +14,12 @@
* limitations under the License.
*/
package io.spring.initializr.stat
package io.spring.initializr.actuate.stat
import io.spring.initializr.generator.ProjectRequest
import io.spring.initializr.metadata.InitializrMetadata
import io.spring.initializr.metadata.InitializrMetadataProvider
import io.spring.initializr.test.InitializrMetadataTestBuilder
import io.spring.initializr.metadata.SimpleInitializrMetadataProvider
import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder
/**
* @author Stephane Nicoll
@@ -35,12 +35,7 @@ abstract class AbstractInitializrStatTests {
.build()
protected InitializrMetadataProvider createProvider(def metadata) {
new InitializrMetadataProvider() {
@Override
InitializrMetadata get() {
return metadata
}
}
new SimpleInitializrMetadataProvider(metadata)
}
protected ProjectRequest createProjectRequest() {

View File

@@ -14,10 +14,10 @@
* limitations under the License.
*/
package io.spring.initializr.web
package io.spring.initializr.actuate.stat
import groovy.json.JsonSlurper
import io.spring.initializr.config.StatsProperties
import io.spring.initializr.web.AbstractInitializrControllerIntegrationTests
import org.junit.Before
import org.junit.Test
@@ -34,12 +34,14 @@ import org.springframework.web.bind.annotation.RestController
import org.springframework.web.client.HttpClientErrorException
import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertNotNull
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse
import static org.junit.Assert.fail;
import static org.junit.Assert.assertNotNull
import static org.junit.Assert.assertTrue
import static org.junit.Assert.fail
/**
* Integration tests for stats processing.
*
* @author Stephane Nicoll
*/
@SpringApplicationConfiguration(StatsMockController.class)

View File

@@ -14,9 +14,8 @@
* limitations under the License.
*/
package io.spring.initializr.stat
package io.spring.initializr.actuate.stat
import io.spring.initializr.config.StatsProperties
import io.spring.initializr.generator.ProjectGeneratedEvent
import io.spring.initializr.generator.ProjectRequest
import org.junit.Before

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.spring.initializr.stat
package io.spring.initializr.actuate.stat
import io.spring.initializr.generator.ProjectFailedEvent
import io.spring.initializr.generator.ProjectGeneratedEvent

View File

@@ -14,8 +14,9 @@
* limitations under the License.
*/
package io.spring.initializr.config
package io.spring.initializr.actuate.stat
import io.spring.initializr.actuate.stat.StatsProperties
import org.junit.Test
import static org.junit.Assert.assertThat

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.spring.initializr.test
package io.spring.initializr.actuate.test
import static org.junit.Assert.assertEquals
import static org.junit.Assert.fail

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2012-2016 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.spring.initializr.test
package io.spring.initializr.actuate.test
import org.junit.Assume
import org.junit.rules.TestWatcher

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.spring.initializr.test
package io.spring.initializr.actuate.test
import org.springframework.boot.actuate.metrics.CounterService

View File

@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.spring.initalizr</groupId>
<artifactId>initializr</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>initializr-generator</artifactId>
<name>Spring Initializr :: Generator</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-templates</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -19,9 +19,6 @@ package io.spring.initializr.generator
import groovy.transform.InheritConstructors
import io.spring.initializr.InitializrException
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.ResponseStatus
/**
* Thrown when a {@link ProjectRequest} is invalid.
*
@@ -29,6 +26,5 @@ import org.springframework.web.bind.annotation.ResponseStatus
* @since 1.0
*/
@InheritConstructors
@ResponseStatus(HttpStatus.BAD_REQUEST)
class InvalidProjectRequestException extends InitializrException {
}

View File

@@ -22,7 +22,7 @@ package io.spring.initializr.generator
* @author Stephane Nicoll
* @since 1.0
*/
class ProjectFailedEvent extends ProjectRequestEvent {
class ProjectFailedEvent extends ProjectRequestEvent {
/**
* The cause of the failure.

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2012-2016 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.metadata
/**
* A simple {@link InitializrMetadataProvider} implementation.
*
* @author Stephane Nicoll
* @since 1.0
*/
class SimpleInitializrMetadataProvider implements InitializrMetadataProvider {
private final InitializrMetadata metadata
SimpleInitializrMetadataProvider(InitializrMetadata metadata) {
this.metadata = metadata
}
@Override
InitializrMetadata get() {
this.metadata
}
}

View File

@@ -0,0 +1,109 @@
/*
* Copyright 2012-2016 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.util
/**
* Defines the agent that submitted a request.
*
* @author Stephane Nicoll
* @since 1.0
*/
class Agent {
/**
* The {@link AgentId}.
*/
final AgentId id
/**
* The version of the agent, if any
*/
final String version
Agent(AgentId id, String version) {
this.id = id
this.version = version
}
/**
* Create an {@link Agent} based on the specified {@code User-Agent} header.
* @param userAgent the user agent
* @return an {@link Agent} instance or {@code null}
*/
static Agent fromUserAgent(String userAgent) {
UserAgentHandler.parse(userAgent)
}
/**
* Defines the various known agents.
*/
static enum AgentId {
CURL('curl', 'curl'),
HTTPIE('httpie', 'HTTPie'),
SPRING_BOOT_CLI('spring', 'SpringBootCli'),
STS('sts', 'STS'),
INTELLIJ_IDEA('intellijidea', 'IntelliJ IDEA'),
BROWSER('browser', 'Browser')
final String id
final String name
private AgentId(String id, String name) {
this.id = id
this.name = name
}
}
private static class UserAgentHandler {
private static final TOOL_REGEX = '([^\\/]*)\\/([^ ]*).*'
private static final STS_REGEX = 'STS (.*)'
static Agent parse(String userAgent) {
def matcher = (userAgent =~ TOOL_REGEX)
if (matcher.matches()) {
String name = matcher.group(1)
for (AgentId id : AgentId.values()) {
if (name.equals(id.name)) {
String version = matcher.group(2)
return new Agent(id, version)
}
}
}
matcher = userAgent =~ STS_REGEX
if (matcher.matches()) {
return new Agent(AgentId.STS, matcher.group(1))
}
if (userAgent.equals(AgentId.INTELLIJ_IDEA.name)) {
return new Agent(AgentId.INTELLIJ_IDEA, null)
}
if (userAgent.contains('Mozilla/5.0')) { // Super heuristics
return new Agent(AgentId.BROWSER, null)
}
return null
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.

View File

@@ -47,17 +47,6 @@
"sourceType": "io.spring.initializr.metadata.InitializrProperties",
"sourceMethod": "getPackageName()"
},
{
"name": "initializr.stats",
"type": "io.spring.initializr.config.StatsProperties",
"sourceType": "io.spring.initializr.config.StatsProperties"
},
{
"name": "initializr.stats.elastic",
"type": "io.spring.initializr.config.StatsProperties$Elastic",
"sourceType": "io.spring.initializr.config.StatsProperties",
"sourceMethod": "getElastic()"
},
{
"name": "initializr.version",
"type": "io.spring.initializr.metadata.InitializrProperties$SimpleElement",
@@ -154,14 +143,19 @@
"type": "java.util.List<java.lang.String>",
"description": "The list of invalid application names. If such name is chosen or generated,\n the \"fallbackApplicationName\" should be used instead.",
"sourceType": "io.spring.initializr.metadata.InitializrConfiguration$Env",
"defaultValue": ["SpringApplication", "SpringBootApplication"]
"defaultValue": [
"SpringApplication",
"SpringBootApplication"
]
},
{
"name": "initializr.env.invalid-package-names",
"type": "java.util.List<java.lang.String>",
"description": "The list of invalid package names. If such name is chosen or generated, the default package name should be used instead.",
"sourceType": "io.spring.initializr.metadata.InitializrConfiguration$Env",
"defaultValue": ["org.springframework"]
"defaultValue": [
"org.springframework"
]
},
{
"name": "initializr.env.kotlin.version",
@@ -257,43 +251,6 @@
"description": "Available packaging types.",
"sourceType": "io.spring.initializr.metadata.InitializrProperties"
},
{
"name": "initializr.stats.elastic.uri",
"type": "java.lang.String",
"description": "Elastic service uri.",
"sourceType": "io.spring.initializr.config.StatsProperties$Elastic"
},
{
"name": "initializr.stats.elastic.username",
"type": "java.lang.String",
"description": "Elastic service username.",
"sourceType": "io.spring.initializr.config.StatsProperties$Elastic"
},
{
"name": "initializr.stats.elastic.password",
"type": "java.lang.String",
"description": "Elastic service password.",
"sourceType": "io.spring.initializr.config.StatsProperties$Elastic"
},
{
"name": "initializr.stats.elastic.index-name",
"type": "java.lang.String",
"description": "Name of the index.",
"sourceType": "io.spring.initializr.config.StatsProperties$Elastic"
},
{
"name": "initializr.stats.elastic.entity-name",
"type": "java.lang.String",
"description": "Name of the entity to use to publish stats.",
"sourceType": "io.spring.initializr.config.StatsProperties$Elastic"
},
{
"name": "initializr.stats.elastic.max-attempts",
"type": "java.lang.Integer",
"description": "Number of attempts before giving up.",
"defaultValue": 3,
"sourceType": "io.spring.initializr.config.StatsProperties$Elastic"
},
{
"name": "initializr.types",
"type": "java.util.List<io.spring.initializr.metadata.Type>",

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2012-2016 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 project.templates
{packageName};
import org.springframework.boot.SpringApplication;<% if (useSpringBootApplication) { %>
import org.springframework.boot.autoconfigure.SpringBootApplication;<% } else { %>
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;<% } %>
<% if (useSpringBootApplication) { %>
@SpringBootApplication<% } else { %>
@Configuration
@ComponentScan
@EnableAutoConfiguration <% } %>
public class ${applicationName} {
public static void main(String[] args) {
SpringApplication.run(${applicationName}.class, args);
}
}

View File

@@ -1,4 +1,4 @@
package ${packageName}
packageproject.templates ${packageName}
import org.springframework.boot.SpringApplication<% if (useSpringBootApplication) { %>
import org.springframework.boot.autoconfigure.SpringBootApplication<% } else { %>

View File

@@ -0,0 +1,34 @@
/*
* Copyright 2012-2016 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 project.templates
{packageName};
import org.junit.Test;
import org.junit.runner.RunWith;
${testImports}import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ${applicationName}.class)
${testAnnotations}public class ${applicationName}Tests {
@Test
public void contextLoads() {
}
}

View File

@@ -1,4 +1,4 @@
package ${packageName}
packageproject.templates ${packageName}
import org.junit.Test
import org.junit.runner.RunWith

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2012-2016 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 project.templates
{packageName};
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(${applicationName}.class);
}
}

View File

@@ -1,4 +1,4 @@
package ${packageName}
packageproject.templates ${packageName}
import org.springframework.boot.builder.SpringApplicationBuilder
import org.springframework.boot.context.web.SpringBootServletInitializer

View File

@@ -1,3 +1,5 @@
package project.templates
buildscript {
ext {
springBootVersion = '${bootVersion}'<% if (language=='kotlin') { %>

View File

@@ -18,7 +18,7 @@ package io.spring.initializr.generator
import io.spring.initializr.metadata.Dependency
import io.spring.initializr.metadata.Type
import io.spring.initializr.test.InitializrMetadataTestBuilder
import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder
import org.junit.Test
import static org.hamcrest.CoreMatchers.containsString

View File

@@ -19,11 +19,11 @@ package io.spring.initializr.generator
import io.spring.initializr.metadata.BillOfMaterials
import io.spring.initializr.metadata.Dependency
import io.spring.initializr.metadata.InitializrMetadata
import io.spring.initializr.metadata.InitializrMetadataProvider
import io.spring.initializr.test.GradleBuildAssert
import io.spring.initializr.test.InitializrMetadataTestBuilder
import io.spring.initializr.test.PomAssert
import io.spring.initializr.test.ProjectAssert
import io.spring.initializr.metadata.SimpleInitializrMetadataProvider
import io.spring.initializr.test.generator.GradleBuildAssert
import io.spring.initializr.test.generator.PomAssert
import io.spring.initializr.test.generator.ProjectAssert
import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -617,12 +617,7 @@ class ProjectGeneratorTests {
}
private void applyMetadata(InitializrMetadata metadata) {
projectGenerator.metadataProvider = new InitializrMetadataProvider() {
@Override
InitializrMetadata get() {
return metadata
}
}
projectGenerator.metadataProvider = new SimpleInitializrMetadataProvider(metadata)
}
private static class ProjectGeneratedEventMatcher extends ArgumentMatcher<ProjectGeneratedEvent> {

View File

@@ -19,7 +19,7 @@ package io.spring.initializr.generator
import io.spring.initializr.metadata.BillOfMaterials
import io.spring.initializr.metadata.Dependency
import io.spring.initializr.metadata.InitializrMetadataBuilder
import io.spring.initializr.test.InitializrMetadataTestBuilder
import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException

View File

@@ -16,7 +16,7 @@
package io.spring.initializr.metadata
import io.spring.initializr.test.InitializrMetadataTestBuilder
import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException

Some files were not shown because too many files have changed in this diff Show More