Skip to content

Commit

Permalink
Merge branch '2.5.x' into 2.6.x
Browse files Browse the repository at this point in the history
Closes gh-30166
  • Loading branch information
wilkinsona committed Mar 11, 2022
2 parents 7c3c5d3 + cced7ed commit 4c1d1a6
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 25 deletions.
@@ -0,0 +1,101 @@
/*
* Copyright 2012-2022 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
*
* https://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 org.springframework.boot.build.devtools;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;

import org.gradle.api.DefaultTask;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;

/**
* Task for documenting Devtools' property defaults.
*
* @author Andy Wilkinson
*/
public class DocumentDevtoolsPropertyDefaults extends DefaultTask {

private Configuration devtools;

private final RegularFileProperty outputFile;

public DocumentDevtoolsPropertyDefaults() {
this.devtools = getProject().getConfigurations().create("devtools");
this.outputFile = getProject().getObjects().fileProperty();
this.outputFile.convention(getProject().getLayout().getBuildDirectory()
.file("docs/generated/using/devtools-property-defaults.adoc"));
Map<String, String> dependency = new HashMap<>();
dependency.put("path", ":spring-boot-project:spring-boot-devtools");
dependency.put("configuration", "propertyDefaults");
this.devtools.getDependencies().add(getProject().getDependencies().project(dependency));
}

@InputFiles
public FileCollection getDevtools() {
return this.devtools;
}

@OutputFile
public RegularFileProperty getOutputFile() {
return this.outputFile;
}

@TaskAction
void documentPropertyDefaults() throws IOException {
Map<String, String> properties = loadProperties();
documentProperties(properties);
}

private Map<String, String> loadProperties() throws IOException, FileNotFoundException {
Properties properties = new Properties();
Map<String, String> sortedProperties = new TreeMap<>();
try (FileInputStream stream = new FileInputStream(this.devtools.getSingleFile())) {
properties.load(stream);
for (String name : properties.stringPropertyNames()) {
sortedProperties.put(name, properties.getProperty(name));
}
}
return sortedProperties;
}

private void documentProperties(Map<String, String> properties) throws IOException {
try (PrintWriter writer = new PrintWriter(new FileWriter(this.outputFile.getAsFile().get()))) {
writer.println("[cols=\"3,1\"]");
writer.println("|===");
writer.println("| Name | Default Value");
properties.forEach((name, value) -> {
writer.println();
writer.printf("| `%s`%n", name);
writer.printf("| `%s`%n", value);
});
writer.println("|===");
}
}

}
7 changes: 7 additions & 0 deletions spring-boot-project/spring-boot-devtools/build.gradle
Expand Up @@ -13,6 +13,13 @@ configurations {
intTestDependencies {
extendsFrom dependencyManagement
}
propertyDefaults
}

artifacts {
propertyDefaults(file("build/resources/main/org/springframework/boot/devtools/env/devtools-property-defaults.properties")) {
builtBy(processResources)
}
}

dependencies {
Expand Down
Expand Up @@ -16,9 +16,11 @@

package org.springframework.boot.devtools.env;

import java.util.Collections;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.logging.Log;

Expand Down Expand Up @@ -60,23 +62,19 @@ public class DevToolsPropertyDefaultsPostProcessor implements EnvironmentPostPro
private static final Map<String, Object> PROPERTIES;

static {
Map<String, Object> properties = new HashMap<>();
properties.put("spring.thymeleaf.cache", "false");
properties.put("spring.freemarker.cache", "false");
properties.put("spring.groovy.template.cache", "false");
properties.put("spring.mustache.cache", "false");
properties.put("server.servlet.session.persistent", "true");
properties.put("spring.h2.console.enabled", "true");
properties.put("spring.web.resources.cache.period", "0");
properties.put("spring.web.resources.chain.cache", "false");
properties.put("spring.template.provider.cache", "false");
properties.put("spring.mvc.log-resolved-exception", "true");
properties.put("server.error.include-binding-errors", "ALWAYS");
properties.put("server.error.include-message", "ALWAYS");
properties.put("server.error.include-stacktrace", "ALWAYS");
properties.put("server.servlet.jsp.init-parameters.development", "true");
properties.put("spring.reactor.debug", "true");
PROPERTIES = Collections.unmodifiableMap(properties);
Properties properties = new Properties();
try (InputStream stream = DevToolsPropertyDefaultsPostProcessor.class
.getResourceAsStream("devtools-property-defaults.properties")) {
properties.load(stream);
}
catch (IOException ex) {
throw new RuntimeException("Failed to load devtools-property-defaults.properties", ex);
}
Map<String, Object> map = new HashMap<>();
for (String name : properties.stringPropertyNames()) {
map.put(name, properties.getProperty(name));
}
PROPERTIES = map;
}

@Override
Expand Down
@@ -0,0 +1,15 @@
server.error.include-binding-errors=always
server.error.include-message=always
server.error.include-stacktrace=always
server.servlet.jsp.init-parameters.development=true
server.servlet.session.persistent=true
spring.freemarker.cache=false
spring.groovy.template.cache=false
spring.h2.console.enabled=true
spring.mustache.cache=false
spring.mvc.log-resolved-exception=true
spring.reactor.debug=true
spring.template.provider.cache=false
spring.thymeleaf.cache=false
spring.web.resources.cache.period=0
spring.web.resources.chain.cache=false
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2022 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.
Expand All @@ -18,6 +18,7 @@

import java.net.URL;
import java.util.Collections;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;

Expand Down Expand Up @@ -107,9 +108,11 @@ void postProcessEnablesIncludeStackTraceProperty() throws Exception {
this.context = getContext(application::run);
ConfigurableEnvironment environment = this.context.getEnvironment();
String includeStackTrace = environment.getProperty("server.error.include-stacktrace");
assertThat(includeStackTrace).isEqualTo(ErrorProperties.IncludeAttribute.ALWAYS.toString());
assertThat(includeStackTrace)
.isEqualTo(ErrorProperties.IncludeAttribute.ALWAYS.toString().toLowerCase(Locale.ENGLISH));
String includeMessage = environment.getProperty("server.error.include-message");
assertThat(includeMessage).isEqualTo(ErrorProperties.IncludeAttribute.ALWAYS.toString());
assertThat(includeMessage)
.isEqualTo(ErrorProperties.IncludeAttribute.ALWAYS.toString().toLowerCase(Locale.ENGLISH));
}

protected ConfigurableApplicationContext getContext(Supplier<ConfigurableApplicationContext> supplier)
Expand Down
3 changes: 3 additions & 0 deletions spring-boot-project/spring-boot-docs/build.gradle
Expand Up @@ -249,6 +249,8 @@ task documentConfigurationProperties(type: org.springframework.boot.build.contex
outputDir = file("${buildDir}/docs/generated/")
}

task documentDevtoolsPropertyDefaults(type: org.springframework.boot.build.devtools.DocumentDevtoolsPropertyDefaults) {}

tasks.withType(org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask) {
dependsOn dependencyVersions
asciidoctorj {
Expand Down Expand Up @@ -309,6 +311,7 @@ syncDocumentationSourceForAsciidoctor {
dependsOn documentDependencyVersions
dependsOn documentVersionProperties
dependsOn documentConfigurationProperties
dependsOn documentDevtoolsPropertyDefaults
from("${buildDir}/docs/generated") {
into "asciidoc"
}
Expand Down
Expand Up @@ -67,13 +67,15 @@ Cache options are usually configured by settings in your `application.properties
For example, Thymeleaf offers the configprop:spring.thymeleaf.cache[] property.
Rather than needing to set these properties manually, the `spring-boot-devtools` module automatically applies sensible development-time configuration.

Because you need more information about web requests while developing Spring MVC and Spring WebFlux applications, developer tools suggests you to enable `DEBUG` logging for the `web` logging group.
This will give you information about the incoming request, which handler is processing it, the response outcome, and other details.
If you wish to log all request details (including potentially sensitive information), you can turn on the configprop:spring.mvc.log-request-details[] or configprop:spring.codec.log-request-details[] configuration properties.
The following table lists all the properties that are applied:

include::devtools-property-defaults.adoc[]

NOTE: If you do not want property defaults to be applied you can set configprop:spring.devtools.add-properties[] to `false` in your `application.properties`.

TIP: For a complete list of the properties that are applied by the devtools, see {spring-boot-devtools-module-code}/env/DevToolsPropertyDefaultsPostProcessor.java[DevToolsPropertyDefaultsPostProcessor].
Because you need more information about web requests while developing Spring MVC and Spring WebFlux applications, developer tools suggests you to enable `DEBUG` logging for the `web` logging group.
This will give you information about the incoming request, which handler is processing it, the response outcome, and other details.
If you wish to log all request details (including potentially sensitive information), you can turn on the configprop:spring.mvc.log-request-details[] or configprop:spring.codec.log-request-details[] configuration properties.



Expand Down

0 comments on commit 4c1d1a6

Please sign in to comment.