Skip to content

3.0.0-M3 Logging Date Format #296

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Aug 23, 2022
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.springframework.sbm.boot.upgrade_27_30.actions;

import org.springframework.sbm.boot.properties.finder.SpringBootDefaultPropertiesFinder;
import org.springframework.sbm.engine.context.ProjectContext;
import org.springframework.sbm.engine.recipe.AbstractAction;

import java.util.Optional;

public class Boot_27_30_AddLoggingDateFormat extends AbstractAction {

public static final String LOGGING_PATTERN_DATEFORMAT = "logging.pattern.dateformat";

@Override
public void apply(ProjectContext context) {
SpringBootDefaultPropertiesFinder springBootDefaultPropertiesFinder = new SpringBootDefaultPropertiesFinder();

context.getApplicationModules()
.getTopmostApplicationModules()
.stream()
.map(m -> m.searchMainResources(springBootDefaultPropertiesFinder))
.filter(Optional::isPresent)
.map(Optional::get)
.forEach(p -> {
if(!p.getProperty(LOGGING_PATTERN_DATEFORMAT).isPresent()) {
p.setProperty(LOGGING_PATTERN_DATEFORMAT, "yyyy-MM-dd HH:mm:ss.SSS");
}
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.springframework.sbm.boot.upgrade_27_30.checks;

import org.springframework.sbm.boot.asciidoctor.ChangeSection;
import org.springframework.sbm.boot.asciidoctor.Section;
import org.springframework.sbm.boot.asciidoctor.TodoList;
import org.springframework.sbm.boot.upgrade_27_30.Sbu30_PreconditionCheck;
import org.springframework.sbm.boot.upgrade_27_30.Sbu30_PreconditionCheckResult;
import org.springframework.sbm.boot.upgrade_27_30.Sbu30_UpgradeSectionBuilder;
import org.springframework.sbm.boot.upgrade_27_30.filter.LoggingDateFormatPropertyFinder;
import org.springframework.sbm.engine.context.ProjectContext;

import static org.springframework.sbm.engine.precondition.PreconditionCheck.ResultState.PASSED;

public class LoggingDateFormatOverrideSectionBuilder implements Sbu30_PreconditionCheck, Sbu30_UpgradeSectionBuilder {

@Override
public boolean isApplicable(ProjectContext projectContext) {
return projectContext
.search(new LoggingDateFormatPropertyFinder())
.isEmpty();
}

@Override
public Section build(ProjectContext projectContext) {
return ChangeSection.RelevantChangeSection.builder()
.title("Changes in logging date format of log messages to align with the ISO-8601")
.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. ")
.relevanceSection()
.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")
.todoSection()
.todoList(
TodoList.builder()
.todo(
TodoList.Todo.builder()
.text("If you wish to continue using new style remove the logging.pattern.dateformat from the applications.properties file.")
.build()
)
.build()
)
.build();
}

@Override
public Sbu30_PreconditionCheckResult run(ProjectContext context) {
return isApplicable(context) ? new Sbu30_PreconditionCheckResult(PASSED, "Override logging date format to yyyy-MM-dd HH:mm:ss.SSSXXX")
: new Sbu30_PreconditionCheckResult(PASSED, "Already logging format provided. No overrides required.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.springframework.sbm.boot.upgrade_27_30.conditions;

import org.springframework.sbm.boot.upgrade_27_30.filter.LoggingDateFormatPropertyFinder;
import org.springframework.sbm.engine.context.ProjectContext;
import org.springframework.sbm.engine.recipe.Condition;

import java.util.List;

public class LoggingDateFormatCondition implements Condition {

@Override
public String getDescription() {
return null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a description "Check if 'logging.pattern.dateformat' is declared."

}

@Override
public boolean evaluate(ProjectContext context) {
return context.search(new LoggingDateFormatPropertyFinder()).isEmpty();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.springframework.sbm.boot.upgrade_27_30.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.sbm.boot.properties.api.SpringBootApplicationProperties;
import org.springframework.sbm.boot.properties.search.SpringBootApplicationPropertiesResourceListFilter;
import org.springframework.sbm.common.filter.PathPatternMatchingProjectResourceFinder;
import org.springframework.sbm.project.resource.ProjectResource;
import org.springframework.sbm.project.resource.ProjectResourceSet;
import org.springframework.sbm.project.resource.filter.ProjectResourceFinder;
import org.springframework.sbm.properties.api.PropertiesSource;

import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;

@Slf4j
public class LoggingDateFormatPropertyFinder implements ProjectResourceFinder<List<? extends PropertiesSource>> {

private static final String LOGGING_DATE_FORMAT_KEY = "logging.pattern.dateformat";

@Override
public List<? extends PropertiesSource> apply(ProjectResourceSet projectResourceSet) {
List<SpringBootApplicationProperties> springBootApplicationProperties = new SpringBootApplicationPropertiesResourceListFilter().apply(projectResourceSet);

return springBootApplicationProperties.stream()
.filter(x -> x.getProperty(LOGGING_DATE_FORMAT_KEY).isPresent())
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,13 @@
- type: org.springframework.sbm.boot.upgrade_27_30.SpringBoot30UpgradeReport
description: "Create report"
condition:
type: org.springframework.sbm.common.migration.conditions.TrueCondition
type: org.springframework.sbm.common.migration.conditions.TrueCondition
- type: org.springframework.sbm.boot.properties.actions.AddSpringBootApplicationPropertiesAction
description: "Adds default spring boot properties to project. For multi-module project, adds default spring boot properties to every module with jar packaging"
condition:
type: org.springframework.sbm.boot.upgrade_27_30.conditions.LoggingDateFormatCondition
addDefaultPropertiesFileToTopModules: true
- type: org.springframework.sbm.boot.upgrade_27_30.actions.Boot_27_30_AddLoggingDateFormat
description: "Sets logging date format to yyyy-MM-dd HH:mm:ss.SSS"
condition:
type: org.springframework.sbm.boot.upgrade_27_30.conditions.LoggingDateFormatCondition
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.springframework.sbm.boot.upgrade_27_30.actions;

import org.junit.jupiter.api.Test;
import org.springframework.sbm.boot.properties.SpringApplicationPropertiesPathMatcher;
import org.springframework.sbm.boot.properties.SpringBootApplicationPropertiesRegistrar;
import org.springframework.sbm.boot.properties.api.SpringBootApplicationProperties;
import org.springframework.sbm.boot.properties.search.SpringBootApplicationPropertiesResourceListFilter;
import org.springframework.sbm.engine.context.ProjectContext;
import org.springframework.sbm.project.resource.TestProjectContext;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

public class Boot_27_30_AddLoggingDateFormatTest {

private static final String DUMMY_PROPERTY_FILE = "foo=bar\n" +
"defaultBasePackage=org.springframework.sbm";

@Test
public void givenAProjectWithoutLoggingDateFormatOverride_andSpringBootProperties_applyAction_expectPropertyAdded(){
ProjectContext projectContext = TestProjectContext.buildProjectContext()
.addRegistrar(new SpringBootApplicationPropertiesRegistrar(new SpringApplicationPropertiesPathMatcher()))
.addProjectResource("src/main/resources/application.properties", DUMMY_PROPERTY_FILE)
.build();

Boot_27_30_AddLoggingDateFormat action = new Boot_27_30_AddLoggingDateFormat();
action.apply(projectContext);

List<SpringBootApplicationProperties> bootApplicationProperties = new SpringBootApplicationPropertiesResourceListFilter().apply(projectContext.getProjectResources());
assertThat(bootApplicationProperties.size()).isEqualTo(1);
assertThat(bootApplicationProperties.get(0).getProperty("logging.pattern.dateformat").isPresent()).isTrue();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.springframework.sbm.boot.upgrade_27_30.confitions;

import org.junit.jupiter.api.Test;
import org.springframework.sbm.boot.properties.SpringApplicationPropertiesPathMatcher;
import org.springframework.sbm.boot.properties.SpringBootApplicationPropertiesRegistrar;
import org.springframework.sbm.boot.upgrade_27_30.conditions.LoggingDateFormatCondition;
import org.springframework.sbm.engine.context.ProjectContext;
import org.springframework.sbm.project.resource.TestProjectContext;

import java.nio.file.Path;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

public class LoggingDateFormatConditionTest {

private static final String APPLICATION_PROPERTIES_WITH_LOG_DATE_FORMAT = "foo=bar\n" +
"migrate=true\n" +
"logging.pattern.dateformat=xyz\n";

private static final String APPLICATION_PROPERTIES_WITHOUT_LOG_DATE_FORMAT = "foo=bar\n" +
"migrate=true\n";


@Test
public void givenProjectWithLogDateFormatCustomization_evaluateCondition_expectFalse(){
ProjectContext projectContext = TestProjectContext.buildProjectContext()
.addRegistrar(new SpringBootApplicationPropertiesRegistrar(new SpringApplicationPropertiesPathMatcher()))
.addProjectResource(Path.of("src", "main", "resources", "application.properties"), APPLICATION_PROPERTIES_WITH_LOG_DATE_FORMAT)
.build();

LoggingDateFormatCondition condition = new LoggingDateFormatCondition();

assertThat(condition.evaluate(projectContext)).isFalse();
}

@Test
public void givenProjectWithoutLogDateFormatCustomization_evaluateCondition_expectTrue(){
ProjectContext projectContext = TestProjectContext.buildProjectContext()
.addRegistrar(new SpringBootApplicationPropertiesRegistrar(new SpringApplicationPropertiesPathMatcher()))
.addProjectResource(Path.of("src", "main", "resources", "application.properties"), APPLICATION_PROPERTIES_WITHOUT_LOG_DATE_FORMAT)
.build();

LoggingDateFormatCondition condition = new LoggingDateFormatCondition();

assertThat(condition.evaluate(projectContext)).isTrue();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package org.springframework.sbm.boot.upgrade_27_30.filter;

import org.junit.jupiter.api.Test;
import org.openrewrite.SourceFile;
import org.springframework.sbm.boot.properties.SpringApplicationPropertiesPathMatcher;
import org.springframework.sbm.boot.properties.SpringBootApplicationPropertiesRegistrar;
import org.springframework.sbm.boot.upgrade_27_30.filter.LoggingDateFormatPropertyFinder;
import org.springframework.sbm.build.api.BuildFile;
import org.springframework.sbm.build.impl.OpenRewriteMavenBuildFile;
import org.springframework.sbm.engine.context.ProjectContext;
import org.springframework.sbm.project.resource.*;
import org.springframework.sbm.properties.api.PropertiesSource;

import java.nio.file.Path;
import java.util.List;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

public class LoggingDateFormatPropertyFinderTest {

private static final String APPLICATION_PROPERTIES_WITH_LOG_DATE_FORMAT = "foo=bar\n" +
"migrate=true\n" +
"logging.pattern.dateformat=xyz\n";

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\" " +
"xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n" +
" <modelVersion>4.0.0</modelVersion>\n" +
"\n" +
" <groupId>org.springframework.sbm</groupId>\n" +
" <artifactId>spring-boot-migrator</artifactId>\n" +
" <version>0.11.2-SNAPSHOT</version>\n" +
" <packaging>pom</packaging>\n" +
" <modules>\n" +
" <module>module1</module>\n" +
" <module>module2</module>\n" +
" </modules>\n" +
"</project>";

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\" " +
"xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n" +
" <parent>\n" +
" <artifactId>spring-boot-migrator</artifactId>\n" +
" <groupId>org.springframework.sbm</groupId>\n" +
" <version>0.11.2-SNAPSHOT</version>\n" +
" <relativePath>../../pom.xml</relativePath>\n" +
" </parent>\n" +
" <modelVersion>4.0.0</modelVersion>\n" +
"\n" +
" <artifactId>{{module}}</artifactId>\n" +
"</project>";

@Test
public void givenProjectWithLogDateFormatCustomization_findResources_returnResource(){
ProjectContext projectContext = TestProjectContext.buildProjectContext()
.addRegistrar(new SpringBootApplicationPropertiesRegistrar(new SpringApplicationPropertiesPathMatcher()))
.addProjectResource(Path.of("src", "main", "resources", "application.properties"), APPLICATION_PROPERTIES_WITH_LOG_DATE_FORMAT)
.build();

LoggingDateFormatPropertyFinder loggingDateFormatPropertyFinder = new LoggingDateFormatPropertyFinder();
List<? extends PropertiesSource> propertiesSources = loggingDateFormatPropertyFinder.apply(projectContext.getProjectResources());

assertThat(propertiesSources.size()).isEqualTo(1);
assertThat(propertiesSources.get(0).getProperty("logging.pattern.dateformat").isPresent()).isTrue();
}

@Test
public void givenMultiModuleProjectWithLogDateFormatCustomization_findResources_returnResource(){
ProjectContext projectContext = TestProjectContext.buildProjectContext()
.withMavenRootBuildFileSource(MULTI_MODULE_POM_XML)
.addProjectResource(Path.of("module1","pom.xml"),SUB_MODULE_POM_XML.replace("{{module}}", "module1"))
.addProjectResource(Path.of("module2","pom.xml"),SUB_MODULE_POM_XML.replace("{{module}}", "module2"))
.addRegistrar(new SpringBootApplicationPropertiesRegistrar(new SpringApplicationPropertiesPathMatcher()))
.addProjectResource(Path.of("module1","src", "main", "resources", "application.properties"), APPLICATION_PROPERTIES_WITH_LOG_DATE_FORMAT)
.addProjectResource(Path.of("module2","src", "main", "resources", "application.properties"), APPLICATION_PROPERTIES_WITH_LOG_DATE_FORMAT)
.build();

LoggingDateFormatPropertyFinder loggingDateFormatPropertyFinder = new LoggingDateFormatPropertyFinder();
List<? extends PropertiesSource> propertiesSources = loggingDateFormatPropertyFinder.apply(projectContext.getProjectResources());

assertThat(propertiesSources.size()).isEqualTo(2);
assertThat(propertiesSources.get(0).getProperty("logging.pattern.dateformat").isPresent()).isTrue();
assertThat(propertiesSources.get(1).getProperty("logging.pattern.dateformat").isPresent()).isTrue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package org.springframework.sbm.boot.properties.actions;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.springframework.sbm.boot.properties.api.SpringBootApplicationProperties;
import org.springframework.sbm.boot.properties.search.SpringBootApplicationPropertiesResourceListFilter;
import org.springframework.sbm.build.api.ApplicationModule;
Expand All @@ -23,16 +25,27 @@

import java.nio.file.Path;

@NoArgsConstructor
@AllArgsConstructor
public class AddSpringBootApplicationPropertiesAction extends AbstractAction {

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

private Boolean addDefaultPropertiesFileToTopModules = Boolean.FALSE;

@Override
public void apply(ProjectContext context) {
SpringBootApplicationProperties springBootApplicationProperties =
SpringBootApplicationProperties.newApplicationProperties(
context.getProjectRootDirectory(), APPLICATION_PROPERTIES_PATH);
context.getProjectResources().add(springBootApplicationProperties);
if(addDefaultPropertiesFileToTopModules){
context.getApplicationModules()
.getTopmostApplicationModules()
.stream()
.forEach(this::apply);
} else {
SpringBootApplicationProperties springBootApplicationProperties =
SpringBootApplicationProperties.newApplicationProperties(
context.getProjectRootDirectory(), APPLICATION_PROPERTIES_PATH);
context.getProjectResources().add(springBootApplicationProperties);
}
}

public void apply(ApplicationModule module) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ public class SpringBootDefaultPropertiesFinder implements ProjectResourceFinder<
@Override
public Optional<SpringBootApplicationProperties> apply(ProjectResourceSet projectResourceSet) {
return projectResourceSet.stream()
.filter(r -> r.getSourceFile() instanceof Properties.File)
.map(r -> new SpringBootApplicationProperties(r.getAbsoluteProjectDir(), (Properties.File) r.getSourceFile()))
.filter(r -> r instanceof SpringBootApplicationProperties)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be filter(SpringBootApplicationProperties.class::isInstance)

.map(SpringBootApplicationProperties.class::cast)
.filter(SpringBootApplicationProperties::isDefaultProperties)
.findFirst();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package org.springframework.sbm.boot.properties.finder;

import org.junit.jupiter.api.Test;
import org.springframework.sbm.boot.properties.SpringApplicationPropertiesPathMatcher;
import org.springframework.sbm.boot.properties.SpringBootApplicationPropertiesRegistrar;
import org.springframework.sbm.engine.context.ProjectContext;
import org.springframework.sbm.project.resource.TestProjectContext;

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

Expand Down