Skip to content

Spring Boot 3 Upgrade Report Contribution Guideline

Fabian Krüger edited this page Jun 13, 2023 · 4 revisions

Spring Boot Migrator introduced a "Spring Boot 3 Upgrade Report". This HTML report is generated by SBM and presented to users. It should show all changes affecting a 2.7.x Spring Boot application. For all changes that do or might affect the application, there should be a detailed description of why and how the application is affected and how to remediate. When a migration recipe exists, this recipe should be linked from inside the report. If no recipe exists but the migration can be automated, the recipe should either be implemented in SBM using plain OpenRewrite API to contribute the recipe to OpenRewrite later on. Or it can be implemented in OpenRewrite’s rewrite-spring project right away and later be integrated into SBM.

This document describes the process of creating a report and automated migrations for upgrading a Spring Boot 2.7 application to 3.0. It is meant to be used as a reference to contributing a detailed section in the upgrade report and an automated migration recipe to remediate a change, where possible.

Concept

Spring Boot Migrator aims to provide a report for Spring Boot 2.7 applications describing all (boot, data, security for now) required changes to upgrade a scanned application to 3.0.

Every change is described in a separate section of the report. When a migration recipe exists that can automatically remediate the change in the scanned application it should be executable from within the report.

The report sections should provide guidance and additional information on why this change applies to a scanned application and what needs to be done to remediate the change.

Providing detailed steps for issues labeled upgrade:boot-report should always be done before implementing matching issues labeled upgrade:boot-recipe.

Report Section

A report section is a single section in the Upgrade Report. These sections describe a single change that was introduced with Spring Boot 3.0. Providing detailed information about every change and how to remediate it is a natural first step before attempting to provide an automated recipe. Issues related to a report section are labeled with upgrade:boot-report.

YAML

Every report section is provided in YAML syntax in the sbu30-report.yaml file. This file contains all changes and their description and information on how to remediate the change.

Title

Every section consists of a title of the section. This should be the same as used in the Release Notes

- title: Add the title from the Release Notes section

Helper

To define if the section is applicable and shown or hidden a helper must be declared for every section. Two flavors exist, one that takes a condition to show or hide a section by applying a (potentially) exisiting Condition. In this case ConditionOnlyHelper should be used which evaluates the declared Condition.

  helper:
    type: org.springframework.sbm.boot.upgrade_27_30.report.helper.ConditionOnlyHelper
    condition:
      type: org.springframework.sbm.build.migration.conditions.AnyDependencyExistMatchingRegex
      dependencies:
        - 'org\.springframework\..*'

If more details should be provided in the rendered report of why a section was found to be applicable, the helper must extend SpringBootUpgradeReportSectionHelper<SomeType>. This requires an implementation of the evaluate method from Condition

public boolean evaluate(ProjectContext context) {
  // implement condition
  // and keep matches used in the report
}

and a getData method which returns a map that will be provided to render the section with freemarker. This way data from the scan (matches) can be used to render the section and provide additonal contextual information related to the scanned application, such as file names that contain code that made the condition applicable to the scanned application.

public Map<String, SomeType> getData() {
  // Create map with keys of String that return (here) SomeType
  return map;
}

This custom helper must then be provided as a fully qualified class name.

Note
Helper should be placed in org.springframework.sbm.boot.upgrade_27_30.report.helper package
  helper: org.springframework.sbm.boot.upgrade_27_30.report.helper.MyHelperImpl

Change

Change describes the change and contains the information from the Release Notes.

  change: |-
    Add the description from the Release Notes section
    This can be multiline, ident (two spaces) is important

Sources

Sources can be used to provide a list of links to resources that provide additional information or to link the Release Note itself.

  sources:
    - https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/html/howto.html#howto.actuator.sanitize-sensitive-values[Sanitize Sensitive Values^, role="ext-link"]
    - http://some-link-to-some-other-relase-note.html

Affected

Affected describes why a change is applicable to the scanned application. This section can contain freemarker syntax which uses the data provided by the Helper’s getData method.

  affected: |-
    Why is the scanned application affected?
    Describes the matches of the `Finder` that made the condition for this section apply
    <#list matches as match>
      * file://${match.absolutePath}[`${match.relativePath}`]<#lt>
      <#list match.propertiesFound as property>
      ** `${property}`<#lt>
      </#list>
    </#list>

Remediation(s)

Remediation provides the

  remediation:
    description: |-
      Describe what the user needs to do to remediate this change in the scanned application.
      This should be as descriptive as possible and can potentially serve as the requirement
      for a later migration recipe that migrates the steps.
      Different ways may exist, in this case, use this format
    possibilities:
      - title: The title of this remediation
        description:  |-
          A detailed description of this approach and what the implications are
          Use checkboxes if there's a sequence of steps
          - [ ] Step 1
          - [ ] Step 2
        recipe: Name of the migration recipe for this remediation, if any
        resources:
          - Optional List of further resources like
          - blog.spring.io/some-blog-article
      - title: Title of the next remediation
        description:
          A detailed description of this approach and what the implications are
          ````java
          code blocks can be used here, even containing code blocks with freemarker template code
          like ${className}
          ````

GitHub Issue

  gitHubIssue: add the id of this issue, like 123

Projects

  projects:
    - spring-boot
    - [Some other project]http://link-to-some-other.project

Contributors

  contributors:
    - Fabian Krüger[@fabapp2]
    - Displayed Name[@GitHubName]

Testing

TODO

Migration Recipe

This section describes how to provide a migration recipe to automatically mitigate a change described in the Upgrade Report. Not every change can be automatically migrated. There are cases where a user decision is required or a migration is too complex to justify the effort of providing an automated recipe. But some can certainly be automated. Issues related to an automated migration of a change are labeled with upgrade:boot-report.

Note
Spring Boot Migrator uses Open Rewrite to a large extent and we want to contribute migration recipes back to Open Rewrite. Therefore it’s important that migration recipes are using plain Open Rewrite Recipes/Visitors whenever possible.

Many migration recipes already exist in OpenRewrite, so the first step is always to look at OpenRewrite’s repositories to see if the required migration already exists.