Skip to content

Commit 3381c0c

Browse files
authored
3.0.0-M3 Logging Date Format (#296)
1 parent 3488970 commit 3381c0c

File tree

11 files changed

+325
-7
lines changed

11 files changed

+325
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.springframework.sbm.boot.upgrade_27_30.actions;
2+
3+
import org.springframework.sbm.boot.properties.finder.SpringBootDefaultPropertiesFinder;
4+
import org.springframework.sbm.engine.context.ProjectContext;
5+
import org.springframework.sbm.engine.recipe.AbstractAction;
6+
7+
import java.util.Optional;
8+
9+
public class Boot_27_30_AddLoggingDateFormat extends AbstractAction {
10+
11+
public static final String LOGGING_PATTERN_DATEFORMAT = "logging.pattern.dateformat";
12+
13+
@Override
14+
public void apply(ProjectContext context) {
15+
SpringBootDefaultPropertiesFinder springBootDefaultPropertiesFinder = new SpringBootDefaultPropertiesFinder();
16+
17+
context.getApplicationModules()
18+
.getTopmostApplicationModules()
19+
.stream()
20+
.map(m -> m.searchMainResources(springBootDefaultPropertiesFinder))
21+
.filter(Optional::isPresent)
22+
.map(Optional::get)
23+
.forEach(p -> {
24+
if(!p.getProperty(LOGGING_PATTERN_DATEFORMAT).isPresent()) {
25+
p.setProperty(LOGGING_PATTERN_DATEFORMAT, "yyyy-MM-dd HH:mm:ss.SSS");
26+
}
27+
});
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package org.springframework.sbm.boot.upgrade_27_30.checks;
2+
3+
import org.springframework.sbm.boot.asciidoctor.ChangeSection;
4+
import org.springframework.sbm.boot.asciidoctor.Section;
5+
import org.springframework.sbm.boot.asciidoctor.TodoList;
6+
import org.springframework.sbm.boot.upgrade_27_30.Sbu30_PreconditionCheck;
7+
import org.springframework.sbm.boot.upgrade_27_30.Sbu30_PreconditionCheckResult;
8+
import org.springframework.sbm.boot.upgrade_27_30.Sbu30_UpgradeSectionBuilder;
9+
import org.springframework.sbm.boot.upgrade_27_30.filter.LoggingDateFormatPropertyFinder;
10+
import org.springframework.sbm.engine.context.ProjectContext;
11+
12+
import static org.springframework.sbm.engine.precondition.PreconditionCheck.ResultState.PASSED;
13+
14+
public class LoggingDateFormatOverrideSectionBuilder implements Sbu30_PreconditionCheck, Sbu30_UpgradeSectionBuilder {
15+
16+
@Override
17+
public boolean isApplicable(ProjectContext projectContext) {
18+
return projectContext
19+
.search(new LoggingDateFormatPropertyFinder())
20+
.isEmpty();
21+
}
22+
23+
@Override
24+
public Section build(ProjectContext projectContext) {
25+
return ChangeSection.RelevantChangeSection.builder()
26+
.title("Changes in logging date format of log messages to align with the ISO-8601")
27+
.paragraph("The new default format yyyy-MM-dd’T’HH:mm:ss.SSSXXX uses a T to separate the date and time instead of a space character and adds the timezone offset to the end. ")
28+
.relevanceSection()
29+
.paragraph("The scan found there is no existing override. Hence a default boot property will be created with date format set to old style i.e. yyyy-MM-dd HH:mm:ss.SSSXXX")
30+
.todoSection()
31+
.todoList(
32+
TodoList.builder()
33+
.todo(
34+
TodoList.Todo.builder()
35+
.text("If you wish to continue using new style remove the logging.pattern.dateformat from the applications.properties file.")
36+
.build()
37+
)
38+
.build()
39+
)
40+
.build();
41+
}
42+
43+
@Override
44+
public Sbu30_PreconditionCheckResult run(ProjectContext context) {
45+
return isApplicable(context) ? new Sbu30_PreconditionCheckResult(PASSED, "Override logging date format to yyyy-MM-dd HH:mm:ss.SSSXXX")
46+
: new Sbu30_PreconditionCheckResult(PASSED, "Already logging format provided. No overrides required.");
47+
}
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.springframework.sbm.boot.upgrade_27_30.conditions;
2+
3+
import org.springframework.sbm.boot.upgrade_27_30.filter.LoggingDateFormatPropertyFinder;
4+
import org.springframework.sbm.engine.context.ProjectContext;
5+
import org.springframework.sbm.engine.recipe.Condition;
6+
7+
import java.util.List;
8+
9+
public class LoggingDateFormatCondition implements Condition {
10+
11+
@Override
12+
public String getDescription() {
13+
return null;
14+
}
15+
16+
@Override
17+
public boolean evaluate(ProjectContext context) {
18+
return context.search(new LoggingDateFormatPropertyFinder()).isEmpty();
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.springframework.sbm.boot.upgrade_27_30.filter;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.springframework.sbm.boot.properties.api.SpringBootApplicationProperties;
5+
import org.springframework.sbm.boot.properties.search.SpringBootApplicationPropertiesResourceListFilter;
6+
import org.springframework.sbm.common.filter.PathPatternMatchingProjectResourceFinder;
7+
import org.springframework.sbm.project.resource.ProjectResource;
8+
import org.springframework.sbm.project.resource.ProjectResourceSet;
9+
import org.springframework.sbm.project.resource.filter.ProjectResourceFinder;
10+
import org.springframework.sbm.properties.api.PropertiesSource;
11+
12+
import java.io.IOException;
13+
import java.io.StringReader;
14+
import java.util.List;
15+
import java.util.Properties;
16+
import java.util.stream.Collectors;
17+
18+
@Slf4j
19+
public class LoggingDateFormatPropertyFinder implements ProjectResourceFinder<List<? extends PropertiesSource>> {
20+
21+
private static final String LOGGING_DATE_FORMAT_KEY = "logging.pattern.dateformat";
22+
23+
@Override
24+
public List<? extends PropertiesSource> apply(ProjectResourceSet projectResourceSet) {
25+
List<SpringBootApplicationProperties> springBootApplicationProperties = new SpringBootApplicationPropertiesResourceListFilter().apply(projectResourceSet);
26+
27+
return springBootApplicationProperties.stream()
28+
.filter(x -> x.getProperty(LOGGING_DATE_FORMAT_KEY).isPresent())
29+
.toList();
30+
}
31+
}

components/sbm-recipes-boot-upgrade/src/main/resources/recipes/boot-2.7-3.0-upgrade-report.yaml

+10-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,13 @@
88
- type: org.springframework.sbm.boot.upgrade_27_30.SpringBoot30UpgradeReport
99
description: "Create report"
1010
condition:
11-
type: org.springframework.sbm.common.migration.conditions.TrueCondition
11+
type: org.springframework.sbm.common.migration.conditions.TrueCondition
12+
- type: org.springframework.sbm.boot.properties.actions.AddSpringBootApplicationPropertiesAction
13+
description: "Adds default spring boot properties to project. For multi-module project, adds default spring boot properties to every module with jar packaging"
14+
condition:
15+
type: org.springframework.sbm.boot.upgrade_27_30.conditions.LoggingDateFormatCondition
16+
addDefaultPropertiesFileToTopModules: true
17+
- type: org.springframework.sbm.boot.upgrade_27_30.actions.Boot_27_30_AddLoggingDateFormat
18+
description: "Sets logging date format to yyyy-MM-dd HH:mm:ss.SSS"
19+
condition:
20+
type: org.springframework.sbm.boot.upgrade_27_30.conditions.LoggingDateFormatCondition
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.springframework.sbm.boot.upgrade_27_30.actions;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.springframework.sbm.boot.properties.SpringApplicationPropertiesPathMatcher;
5+
import org.springframework.sbm.boot.properties.SpringBootApplicationPropertiesRegistrar;
6+
import org.springframework.sbm.boot.properties.api.SpringBootApplicationProperties;
7+
import org.springframework.sbm.boot.properties.search.SpringBootApplicationPropertiesResourceListFilter;
8+
import org.springframework.sbm.engine.context.ProjectContext;
9+
import org.springframework.sbm.project.resource.TestProjectContext;
10+
11+
import java.util.List;
12+
13+
import static org.assertj.core.api.Assertions.assertThat;
14+
15+
public class Boot_27_30_AddLoggingDateFormatTest {
16+
17+
private static final String DUMMY_PROPERTY_FILE = "foo=bar\n" +
18+
"defaultBasePackage=org.springframework.sbm";
19+
20+
@Test
21+
public void givenAProjectWithoutLoggingDateFormatOverride_andSpringBootProperties_applyAction_expectPropertyAdded(){
22+
ProjectContext projectContext = TestProjectContext.buildProjectContext()
23+
.addRegistrar(new SpringBootApplicationPropertiesRegistrar(new SpringApplicationPropertiesPathMatcher()))
24+
.addProjectResource("src/main/resources/application.properties", DUMMY_PROPERTY_FILE)
25+
.build();
26+
27+
Boot_27_30_AddLoggingDateFormat action = new Boot_27_30_AddLoggingDateFormat();
28+
action.apply(projectContext);
29+
30+
List<SpringBootApplicationProperties> bootApplicationProperties = new SpringBootApplicationPropertiesResourceListFilter().apply(projectContext.getProjectResources());
31+
assertThat(bootApplicationProperties.size()).isEqualTo(1);
32+
assertThat(bootApplicationProperties.get(0).getProperty("logging.pattern.dateformat").isPresent()).isTrue();
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.springframework.sbm.boot.upgrade_27_30.confitions;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.springframework.sbm.boot.properties.SpringApplicationPropertiesPathMatcher;
5+
import org.springframework.sbm.boot.properties.SpringBootApplicationPropertiesRegistrar;
6+
import org.springframework.sbm.boot.upgrade_27_30.conditions.LoggingDateFormatCondition;
7+
import org.springframework.sbm.engine.context.ProjectContext;
8+
import org.springframework.sbm.project.resource.TestProjectContext;
9+
10+
import java.nio.file.Path;
11+
12+
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
13+
14+
public class LoggingDateFormatConditionTest {
15+
16+
private static final String APPLICATION_PROPERTIES_WITH_LOG_DATE_FORMAT = "foo=bar\n" +
17+
"migrate=true\n" +
18+
"logging.pattern.dateformat=xyz\n";
19+
20+
private static final String APPLICATION_PROPERTIES_WITHOUT_LOG_DATE_FORMAT = "foo=bar\n" +
21+
"migrate=true\n";
22+
23+
24+
@Test
25+
public void givenProjectWithLogDateFormatCustomization_evaluateCondition_expectFalse(){
26+
ProjectContext projectContext = TestProjectContext.buildProjectContext()
27+
.addRegistrar(new SpringBootApplicationPropertiesRegistrar(new SpringApplicationPropertiesPathMatcher()))
28+
.addProjectResource(Path.of("src", "main", "resources", "application.properties"), APPLICATION_PROPERTIES_WITH_LOG_DATE_FORMAT)
29+
.build();
30+
31+
LoggingDateFormatCondition condition = new LoggingDateFormatCondition();
32+
33+
assertThat(condition.evaluate(projectContext)).isFalse();
34+
}
35+
36+
@Test
37+
public void givenProjectWithoutLogDateFormatCustomization_evaluateCondition_expectTrue(){
38+
ProjectContext projectContext = TestProjectContext.buildProjectContext()
39+
.addRegistrar(new SpringBootApplicationPropertiesRegistrar(new SpringApplicationPropertiesPathMatcher()))
40+
.addProjectResource(Path.of("src", "main", "resources", "application.properties"), APPLICATION_PROPERTIES_WITHOUT_LOG_DATE_FORMAT)
41+
.build();
42+
43+
LoggingDateFormatCondition condition = new LoggingDateFormatCondition();
44+
45+
assertThat(condition.evaluate(projectContext)).isTrue();
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package org.springframework.sbm.boot.upgrade_27_30.filter;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.openrewrite.SourceFile;
5+
import org.springframework.sbm.boot.properties.SpringApplicationPropertiesPathMatcher;
6+
import org.springframework.sbm.boot.properties.SpringBootApplicationPropertiesRegistrar;
7+
import org.springframework.sbm.boot.upgrade_27_30.filter.LoggingDateFormatPropertyFinder;
8+
import org.springframework.sbm.build.api.BuildFile;
9+
import org.springframework.sbm.build.impl.OpenRewriteMavenBuildFile;
10+
import org.springframework.sbm.engine.context.ProjectContext;
11+
import org.springframework.sbm.project.resource.*;
12+
import org.springframework.sbm.properties.api.PropertiesSource;
13+
14+
import java.nio.file.Path;
15+
import java.util.List;
16+
17+
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
18+
19+
public class LoggingDateFormatPropertyFinderTest {
20+
21+
private static final String APPLICATION_PROPERTIES_WITH_LOG_DATE_FORMAT = "foo=bar\n" +
22+
"migrate=true\n" +
23+
"logging.pattern.dateformat=xyz\n";
24+
25+
private static final String MULTI_MODULE_POM_XML = "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
26+
"xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n" +
27+
" <modelVersion>4.0.0</modelVersion>\n" +
28+
"\n" +
29+
" <groupId>org.springframework.sbm</groupId>\n" +
30+
" <artifactId>spring-boot-migrator</artifactId>\n" +
31+
" <version>0.11.2-SNAPSHOT</version>\n" +
32+
" <packaging>pom</packaging>\n" +
33+
" <modules>\n" +
34+
" <module>module1</module>\n" +
35+
" <module>module2</module>\n" +
36+
" </modules>\n" +
37+
"</project>";
38+
39+
private static final String SUB_MODULE_POM_XML = "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
40+
"xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n" +
41+
" <parent>\n" +
42+
" <artifactId>spring-boot-migrator</artifactId>\n" +
43+
" <groupId>org.springframework.sbm</groupId>\n" +
44+
" <version>0.11.2-SNAPSHOT</version>\n" +
45+
" <relativePath>../../pom.xml</relativePath>\n" +
46+
" </parent>\n" +
47+
" <modelVersion>4.0.0</modelVersion>\n" +
48+
"\n" +
49+
" <artifactId>{{module}}</artifactId>\n" +
50+
"</project>";
51+
52+
@Test
53+
public void givenProjectWithLogDateFormatCustomization_findResources_returnResource(){
54+
ProjectContext projectContext = TestProjectContext.buildProjectContext()
55+
.addRegistrar(new SpringBootApplicationPropertiesRegistrar(new SpringApplicationPropertiesPathMatcher()))
56+
.addProjectResource(Path.of("src", "main", "resources", "application.properties"), APPLICATION_PROPERTIES_WITH_LOG_DATE_FORMAT)
57+
.build();
58+
59+
LoggingDateFormatPropertyFinder loggingDateFormatPropertyFinder = new LoggingDateFormatPropertyFinder();
60+
List<? extends PropertiesSource> propertiesSources = loggingDateFormatPropertyFinder.apply(projectContext.getProjectResources());
61+
62+
assertThat(propertiesSources.size()).isEqualTo(1);
63+
assertThat(propertiesSources.get(0).getProperty("logging.pattern.dateformat").isPresent()).isTrue();
64+
}
65+
66+
@Test
67+
public void givenMultiModuleProjectWithLogDateFormatCustomization_findResources_returnResource(){
68+
ProjectContext projectContext = TestProjectContext.buildProjectContext()
69+
.withMavenRootBuildFileSource(MULTI_MODULE_POM_XML)
70+
.addProjectResource(Path.of("module1","pom.xml"),SUB_MODULE_POM_XML.replace("{{module}}", "module1"))
71+
.addProjectResource(Path.of("module2","pom.xml"),SUB_MODULE_POM_XML.replace("{{module}}", "module2"))
72+
.addRegistrar(new SpringBootApplicationPropertiesRegistrar(new SpringApplicationPropertiesPathMatcher()))
73+
.addProjectResource(Path.of("module1","src", "main", "resources", "application.properties"), APPLICATION_PROPERTIES_WITH_LOG_DATE_FORMAT)
74+
.addProjectResource(Path.of("module2","src", "main", "resources", "application.properties"), APPLICATION_PROPERTIES_WITH_LOG_DATE_FORMAT)
75+
.build();
76+
77+
LoggingDateFormatPropertyFinder loggingDateFormatPropertyFinder = new LoggingDateFormatPropertyFinder();
78+
List<? extends PropertiesSource> propertiesSources = loggingDateFormatPropertyFinder.apply(projectContext.getProjectResources());
79+
80+
assertThat(propertiesSources.size()).isEqualTo(2);
81+
assertThat(propertiesSources.get(0).getProperty("logging.pattern.dateformat").isPresent()).isTrue();
82+
assertThat(propertiesSources.get(1).getProperty("logging.pattern.dateformat").isPresent()).isTrue();
83+
}
84+
}

components/sbm-support-boot/src/main/java/org/springframework/sbm/boot/properties/actions/AddSpringBootApplicationPropertiesAction.java

+17-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package org.springframework.sbm.boot.properties.actions;
1717

18+
import lombok.AllArgsConstructor;
19+
import lombok.NoArgsConstructor;
1820
import org.springframework.sbm.boot.properties.api.SpringBootApplicationProperties;
1921
import org.springframework.sbm.boot.properties.search.SpringBootApplicationPropertiesResourceListFilter;
2022
import org.springframework.sbm.build.api.ApplicationModule;
@@ -23,16 +25,27 @@
2325

2426
import java.nio.file.Path;
2527

28+
@NoArgsConstructor
29+
@AllArgsConstructor
2630
public class AddSpringBootApplicationPropertiesAction extends AbstractAction {
2731

2832
public static final Path APPLICATION_PROPERTIES_PATH = Path.of("src/main/resources/application.properties");
2933

34+
private Boolean addDefaultPropertiesFileToTopModules = Boolean.FALSE;
35+
3036
@Override
3137
public void apply(ProjectContext context) {
32-
SpringBootApplicationProperties springBootApplicationProperties =
33-
SpringBootApplicationProperties.newApplicationProperties(
34-
context.getProjectRootDirectory(), APPLICATION_PROPERTIES_PATH);
35-
context.getProjectResources().add(springBootApplicationProperties);
38+
if(addDefaultPropertiesFileToTopModules){
39+
context.getApplicationModules()
40+
.getTopmostApplicationModules()
41+
.stream()
42+
.forEach(this::apply);
43+
} else {
44+
SpringBootApplicationProperties springBootApplicationProperties =
45+
SpringBootApplicationProperties.newApplicationProperties(
46+
context.getProjectRootDirectory(), APPLICATION_PROPERTIES_PATH);
47+
context.getProjectResources().add(springBootApplicationProperties);
48+
}
3649
}
3750

3851
public void apply(ApplicationModule module) {

components/sbm-support-boot/src/main/java/org/springframework/sbm/boot/properties/finder/SpringBootDefaultPropertiesFinder.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ public class SpringBootDefaultPropertiesFinder implements ProjectResourceFinder<
2828
@Override
2929
public Optional<SpringBootApplicationProperties> apply(ProjectResourceSet projectResourceSet) {
3030
return projectResourceSet.stream()
31-
.filter(r -> r.getSourceFile() instanceof Properties.File)
32-
.map(r -> new SpringBootApplicationProperties(r.getAbsoluteProjectDir(), (Properties.File) r.getSourceFile()))
31+
.filter(r -> r instanceof SpringBootApplicationProperties)
32+
.map(SpringBootApplicationProperties.class::cast)
3333
.filter(SpringBootApplicationProperties::isDefaultProperties)
3434
.findFirst();
3535
}

components/sbm-support-boot/src/test/java/org/springframework/sbm/boot/properties/finder/SpringBootDefaultPropertiesFinderTest.java

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
package org.springframework.sbm.boot.properties.finder;
1717

1818
import org.junit.jupiter.api.Test;
19+
import org.springframework.sbm.boot.properties.SpringApplicationPropertiesPathMatcher;
20+
import org.springframework.sbm.boot.properties.SpringBootApplicationPropertiesRegistrar;
1921
import org.springframework.sbm.engine.context.ProjectContext;
2022
import org.springframework.sbm.project.resource.TestProjectContext;
2123

@@ -28,6 +30,7 @@ public class SpringBootDefaultPropertiesFinderTest {
2830
@Test
2931
public void givenAProjectWithDefaultSpringBootProperties_applyFinder_expectPropertyFile(){
3032
ProjectContext projectContext = TestProjectContext.buildProjectContext()
33+
.addRegistrar(new SpringBootApplicationPropertiesRegistrar(new SpringApplicationPropertiesPathMatcher()))
3134
.addProjectResource(Path.of("src","main", "resources", "application.properties"), "foo=bar")
3235
.build();
3336

0 commit comments

Comments
 (0)