Skip to content
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

Add migration tests and recipes for Spring Batch #686

Merged
merged 20 commits into from
Apr 8, 2025

Conversation

qwtfps
Copy link
Contributor

@qwtfps qwtfps commented Mar 12, 2025

What's changed?

Add corresponding migration recipes:

  • JobParameterToString: Migrate JobParameter.toString() to JobParameter.getValue().toString().
  • MigrateMethodAnnotatedByBatchAPI: Update methods annotated by Spring Batch API.
  • MigrateJobParameter: Ensure job parameters are parameterized.
  • ConvertReceiveTypeWhenCallStepExecutionMethod: Convert receive types in StepExecution method calls.

What's your motivation?

Anything in particular you'd like reviewers to focus on?

Anyone you would like to review specifically?

Have you considered any alternatives or workarounds?

Any additional context

Checklist

  • I've added unit tests to cover both positive and negative cases
  • I've read and applied the recipe conventions and best practices
  • I've used the IntelliJ IDEA auto-formatter on affected files

qwtfps added 2 commits March 12, 2025 17:52
main - Add migration tests and recipes for Spring Batch

Add tests and migration recipes to support Spring Batch 5 updates:

- Implement `MigrateJobParameterToStringTest` to verify migration of
  `JobParameter.toString()` to `JobParameter.getValue().toString()`.
- Implement `MigrateMethodAnnotatedByBatchAPITest` to test migration
  of methods annotated by Spring Batch API.
- Add `MigrateJobParameterTest` to ensure job parameters are correctly
  parameterized.
- Create `ConvertReceiveTypeWhenCallStepExecutionMethodTest` to test
  conversion of receive types in StepExecution method calls.

Add corresponding migration recipes:

- `JobParameterToString`: Migrate `JobParameter.toString()` to
  `JobParameter.getValue().toString()`.
- `MigrateMethodAnnotatedByBatchAPI`: Update methods annotated by
  Spring Batch API.
- `MigrateJobParameter`: Ensure job parameters are parameterized.
- `ConvertReceiveTypeWhenCallStepExecutionMethod`: Convert receive
  types in StepExecution method calls.
```
Add new migration recipes to the Spring Batch 5.0 configuration:

- ConvertReceiveTypeWhenCallStepExecutionMethod
- JobParameterToString
- MigrateJobParameter
- MigrateMethodAnnotatedByBatchAPI

These updates enhance the migration process by ensuring compatibility
with the latest Spring Batch API changes.
@github-project-automation github-project-automation bot moved this to In Progress in OpenRewrite Mar 12, 2025
timtebeek and others added 3 commits March 12, 2025 16:49
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Correct inconsistencies in the use of context parameters across
Spring Batch migration recipes. Ensure uniformity by replacing
`executionContext` with `ctx` where applicable. This change
improves code readability and maintains consistency in method
signatures, facilitating easier maintenance and understanding
of the migration logic.
@timtebeek timtebeek self-requested a review March 14, 2025 18:32
@qwtfps
Copy link
Contributor Author

qwtfps commented Mar 18, 2025

hi @timtebeek , do you know why ci build failed ? I can build in my local with the latest commit. I check the log , most likely it is not relevant to the new recipe.

@timtebeek
Copy link
Contributor

It looks like this test failed in a way I hadn't see before 🤔

MigrateJobParameterTest > test1() FAILED
    java.io.UncheckedIOException: java.io.IOException: Failed to create directory /home/runner/.rewrite/classpath/.tt/org/springframework/batch/spring-batch-core
        at org.openrewrite.java.internal.parser.TypeTable$Reader.lambda$writeClassesDir$4(TypeTable.java:247)
        at org.openrewrite.java.internal.parser.TypeTable$Reader$$Lambda$483/0x00007fdfac17b4c8.accept(Unknown Source)
        at java.base/java.util.HashMap$Values.forEach(HashMap.java:1065)
        at org.openrewrite.java.internal.parser.TypeTable$Reader.writeClassesDir(TypeTable.java:244)
        at org.openrewrite.java.internal.parser.TypeTable$Reader.lambda$read$3(TypeTable.java:185)
        at org.openrewrite.java.internal.parser.TypeTable$Reader$$Lambda$480/0x00007fdfac17a098.accept(Unknown Source)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
        at java.base/java.util.stream.SliceOps$1$1.accept(SliceOps.java:200)
        at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
        at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1845)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
        at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
        at org.openrewrite.java.internal.parser.TypeTable$Reader.read(TypeTable.java:180)
        at org.openrewrite.java.internal.parser.TypeTable.read(TypeTable.java:123)
        at org.openrewrite.java.internal.parser.TypeTable.<init>(TypeTable.java:111)
        at org.openrewrite.java.internal.parser.TypeTable.fromClasspath(TypeTable.java:97)
        at org.openrewrite.java.JavaParser.dependenciesFromResources(JavaParser.java:128)
        at org.openrewrite.java.JavaParser$Builder.classpathFromResources(JavaParser.java:324)
        at org.openrewrite.java.spring.batch.MigrateJobParameterTest.defaults(MigrateJobParameterTest.java:32)
        at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:138)
        at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:130)
        at org.openrewrite.java.spring.batch.MigrateJobParameterTest.test1(MigrateJobParameterTest.java:40)

        Caused by:
        java.io.IOException: Failed to create directory /home/runner/.rewrite/classpath/.tt/org/springframework/batch/spring-batch-core
            at org.openrewrite.java.internal.parser.TypeTable$Reader.lambda$writeClassesDir$4(TypeTable.java:247)
            ... 25 more

@qwtfps
Copy link
Contributor Author

qwtfps commented Mar 26, 2025

@timtebeek How to try rerun the CI. I push the fix commit.

@timtebeek
Copy link
Contributor

Thanks! I've triggered the CI builds again; that should only be an issue for your first contribution; after that they should start automatically.

@qwtfps
Copy link
Contributor Author

qwtfps commented Apr 2, 2025

Thanks @timtebeek . I saw your commit which helped me refine the code. I check the CI log info summary is below. I think it was irrelevant to this PR . Is it helpful if i sync the code with master ?

208 tests completed, 2 failed, 1 skipped

Detail

MigrateResponseStatusExceptionTest > migrateResponseStatusExceptionGetRawStatusCodeMethod() FAILED
    java.lang.AssertionError: [Recipe validation must have no failures] 
    Expecting empty but was: [[Invalid{property='initialization', value='[]', message='DeclarativeRecipe must not contain uninitialized recipes. Be sure to call .initialize() on DeclarativeRecipe.'},
        Invalid{property='org.openrewrite.java.spring.framework.MigrateResponseStatusException.recipeList[0] (in file:///home/runner/work/rewrite-spring/rewrite-spring/build/resources/main/META-INF/rewrite/spring-framework-60.yml)', value='org.openrewrite.java.spring.framework.MigrateResponseStatusExceptionGetRawStatusCodeMethod', message='recipe 'org.openrewrite.java.spring.framework.MigrateResponseStatusExceptionGetRawStatusCodeMethod' does not exist.'},
        Invalid{property='org.openrewrite.java.spring.framework.MigrateResponseStatusException.recipeList[1] (in file:///home/runner/work/rewrite-spring/rewrite-spring/build/resources/main/META-INF/rewrite/spring-framework-60.yml)', value='org.openrewrite.java.spring.framework.MigrateResponseStatusExceptionGetStatusCodeMethod', message='recipe 'org.openrewrite.java.spring.framework.MigrateResponseStatusExceptionGetStatusCodeMethod' does not exist.'}]]
        at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:222)
        at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:130)
        at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:125)
        at org.openrewrite.java.spring.framework.MigrateResponseStatusExceptionTest.migrateResponseStatusExceptionGetRawStatusCodeMethod(MigrateResponseStatusExceptionTest.java:91)

MigrateResponseStatusExceptionTest > migrateResponseStatusExceptionGetStatusMethod() FAILED
    java.lang.AssertionError: [Recipe validation must have no failures] 
    Expecting empty but was: [[Invalid{property='initialization', value='[]', message='DeclarativeRecipe must not contain uninitialized recipes. Be sure to call .initialize() on DeclarativeRecipe.'},
        Invalid{property='org.openrewrite.java.spring.framework.MigrateResponseStatusException.recipeList[0] (in file:///home/runner/work/rewrite-spring/rewrite-spring/build/resources/main/META-INF/rewrite/spring-framework-60.yml)', value='org.openrewrite.java.spring.framework.MigrateResponseStatusExceptionGetRawStatusCodeMethod', message='recipe 'org.openrewrite.java.spring.framework.MigrateResponseStatusExceptionGetRawStatusCodeMethod' does not exist.'},
        Invalid{property='org.openrewrite.java.spring.framework.MigrateResponseStatusException.recipeList[1] (in file:///home/runner/work/rewrite-spring/rewrite-spring/build/resources/main/META-INF/rewrite/spring-framework-60.yml)', value='org.openrewrite.java.spring.framework.MigrateResponseStatusExceptionGetStatusCodeMethod', message='recipe 'org.openrewrite.java.spring.framework.MigrateResponseStatusExceptionGetStatusCodeMethod' does not exist.'}]]
        at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:222)
        at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:130)
        at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:125)
        at org.openrewrite.java.spring.framework.MigrateResponseStatusExceptionTest.migrateResponseStatusExceptionGetStatusMethod(MigrateResponseStatusExceptionTest.java:61)

@timtebeek
Copy link
Contributor

Thanks for the ping @qwtfps ! I was out for a few days, but trying to catch up now. The latest failures now are:

MigrateJobParameterTest > addStringClassArguments() FAILED
    org.opentest4j.AssertionFailedError: [Expected recipe to complete in 1 cycle, but took at least one more cycle. Between the last two executed cycles there were changes to "test/PointsReconFileWriterTest.java"] 
    expected: 
      "package test;
      import org.springframework.batch.core.JobParameter;
      import org.springframework.batch.core.JobParameters;
      import java.util.Date;
      import java.util.Map;
      import java.util.HashMap;
      import java.util.UUID;
      public class PointsReconFileWriterTest {
  
          @Test
          public void shouldUpdateMemberStatusWhenDecisionCodeIsA() throws Exception {
              String from = UUID.randomUUID().toString();
              Map<String,JobParameter<?>> parameters = new HashMap<>();
              parameters.put("sellerId", new JobParameter<>(from, String.class));
              parameters.put("smtpHost", new JobParameter<>("localhost", String.class));
  
              JobParameters jobParameters = new JobParameters(parameters);
          }
  
      }"
     but was: 
      "package test;
      import org.springframework.batch.core.JobParameter;
      import org.springframework.batch.core.JobParameters;
      import java.util.Date;
      import java.util.Map;
      import java.util.HashMap;
      import java.util.UUID;
      public class PointsReconFileWriterTest {
  
          @Test
          public void shouldUpdateMemberStatusWhenDecisionCodeIsA() throws Exception {
              String from = UUID.randomUUID().toString();
              Map<String,JobParameter<?>> parameters = new HashMap<>();
              parameters.put("sellerId", new JobParameter<>(from, String.class));
              parameters.put("smtpHost", new JobParameter<>("localhost", String.class, String.class));
  
              JobParameters jobParameters = new JobParameters(parameters);
          }
  
      }"
        at app//org.openrewrite.test.LargeSourceSetCheckingExpectedCycles.afterCycle(LargeSourceSetCheckingExpectedCycles.java:97)
        at app//org.openrewrite.RecipeScheduler.runRecipeCycles(RecipeScheduler.java:98)
        at app//org.openrewrite.RecipeScheduler.scheduleRun(RecipeScheduler.java:41)
        at app//org.openrewrite.Recipe.run(Recipe.java:438)
        at app//org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:377)
        at app//org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:130)
        at app//org.openrewrite.java.spring.batch.MigrateJobParameterTest.addStringClassArguments(MigrateJobParameterTest.java:90)

MigrateJobParameterTest > test3() FAILED
    org.opentest4j.AssertionFailedError: [Expected recipe to complete in 1 cycle, but took at least one more cycle. Between the last two executed cycles there were changes to "test/PointsReconFileWriterTest.java"] 
    expected: 
      "package test;
      import org.springframework.batch.core.JobParameter;
      import org.springframework.batch.core.JobParameters;
      import java.util.Date;
      import java.util.HashMap;
      import java.util.Map;
      import java.util.UUID;
      public class PointsReconFileWriterTest {
  
          @Test
          public void shouldUpdateMemberStatusWhenDecisionCodeIsA() throws Exception {
              final Map<String,JobParameter<?>> paramMap = new HashMap<>() {{
                          put("Target", new JobParameter<>("JOB_NAME", String.class));
              }};
          }
  
      }"
     but was: 
      "package test;
      import org.springframework.batch.core.JobParameter;
      import org.springframework.batch.core.JobParameters;
      import java.util.Date;
      import java.util.HashMap;
      import java.util.Map;
      import java.util.UUID;
      public class PointsReconFileWriterTest {
  
          @Test
          public void shouldUpdateMemberStatusWhenDecisionCodeIsA() throws Exception {
              final Map<String,JobParameter<?>> paramMap = new HashMap<>() {{
                          put("Target", new JobParameter<>("JOB_NAME", String.class, String.class));
              }};
          }
  
      }"
        at app//org.openrewrite.test.LargeSourceSetCheckingExpectedCycles.afterCycle(LargeSourceSetCheckingExpectedCycles.java:97)
        at app//org.openrewrite.RecipeScheduler.runRecipeCycles(RecipeScheduler.java:98)
        at app//org.openrewrite.RecipeScheduler.scheduleRun(RecipeScheduler.java:41)
        at app//org.openrewrite.Recipe.run(Recipe.java:438)
        at app//org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:377)
        at app//org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:130)
        at app//org.openrewrite.java.spring.batch.MigrateJobParameterTest.test3(MigrateJobParameterTest.java:144)

MigrateJobParameterTest > addClassArguments() FAILED
    org.opentest4j.AssertionFailedError: [Expected recipe to complete in 1 cycle, but took at least one more cycle. Between the last two executed cycles there were changes to "test/PointsReconFileWriterTest.java"] 
    expected: 
      "package test;
      import org.springframework.batch.core.JobParameter;
      import org.springframework.batch.core.JobParameters;
      import java.util.Date;
      import java.util.Map;
  
      public class PointsReconFileWriterTest {
  
          @Test
          public void shouldUpdateMemberStatusWhenDecisionCodeIsA() throws Exception {
              JobParameters jobParameters = new JobParameters(Map.of(
                      "inputFile", new JobParameter<>("TEST_INPUT_FILE", String.class),
                      "emailId", new JobParameter<>(new Date(), Date.class),
                      "pgpKey", new JobParameter<>(new Integer[]{1}, java.lang.Integer[].class)
              ));
          }
  
      }"
     but was: 
      "package test;
      import org.springframework.batch.core.JobParameter;
      import org.springframework.batch.core.JobParameters;
      import java.util.Date;
      import java.util.Map;
  
      public class PointsReconFileWriterTest {
  
          @Test
          public void shouldUpdateMemberStatusWhenDecisionCodeIsA() throws Exception {
              JobParameters jobParameters = new JobParameters(Map.of(
                      "inputFile", new JobParameter<>("TEST_INPUT_FILE", String.class, String.class),
                      "emailId", new JobParameter<>(new Date(), Date.class),
                      "pgpKey", new JobParameter<>(new Integer[]{1}, java.lang.Integer[].class, java.lang.Integer[].class)
              ));
          }
  
      }"
        at app//org.openrewrite.test.LargeSourceSetCheckingExpectedCycles.afterCycle(LargeSourceSetCheckingExpectedCycles.java:97)
        at app//org.openrewrite.RecipeScheduler.runRecipeCycles(RecipeScheduler.java:98)
        at app//org.openrewrite.RecipeScheduler.scheduleRun(RecipeScheduler.java:41)
        at app//org.openrewrite.Recipe.run(Recipe.java:438)
        at app//org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:377)
        at app//org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:130)
        at app//org.openrewrite.java.spring.batch.MigrateJobParameterTest.addClassArguments(MigrateJobParameterTest.java:40)

Copy link
Contributor

@timtebeek timtebeek left a comment

Choose a reason for hiding this comment

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

Great to see these! I've pushed some minor polish already, but need to find time to rework the missing types before we can confidently merge these recipes.

Copy link
Contributor

@timtebeek timtebeek left a comment

Choose a reason for hiding this comment

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

Great to have these additional steps covered for Spring Batch; I hope they help you migrate there!

@github-project-automation github-project-automation bot moved this from In Progress to Ready to Review in OpenRewrite Apr 8, 2025
…tch/MigrateMethodAnnotatedByBatchAPITest.java

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@timtebeek timtebeek merged commit 4d76e3e into openrewrite:main Apr 8, 2025
@github-project-automation github-project-automation bot moved this from Ready to Review to Done in OpenRewrite Apr 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

2 participants