Skip to content

Commit 6a6688e

Browse files
sanagaraj-pivotalashakirin
authored andcommitted
Improved error processing for OpenRewrite Adapter actions(#306)
Co-authored-by: Andrei Shakirin <[email protected]>
1 parent 9e0d24b commit 6a6688e

File tree

5 files changed

+149
-13
lines changed

5 files changed

+149
-13
lines changed

components/sbm-core/src/main/java/org/springframework/sbm/engine/recipe/Action.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@ default void applyWithStatusEvent(ProjectContext context) {
3636
try {
3737
apply(context);
3838
} catch(Exception e) {
39-
throw new ActionFailedException("'"+this.getDescription()+"' failed: " + e.getMessage(), e);
39+
String message = "'" + this.getDescription() + "' failed: " + e.getMessage();
40+
if (eventPublisher != null) {
41+
eventPublisher.publishEvent(new ActionFailedEvent(message));
42+
}
43+
throw new ActionFailedException(message, e);
4044
}
4145
if (eventPublisher != null) {
4246
eventPublisher.publishEvent(new ActionFinishedEvent(getDescription()));

components/sbm-core/src/main/java/org/springframework/sbm/engine/recipe/OpenRewriteDeclarativeRecipeAdapter.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import com.fasterxml.jackson.annotation.JsonIgnore;
2020
import lombok.*;
21+
import org.openrewrite.InMemoryExecutionContext;
2122
import org.openrewrite.Recipe;
2223
import org.openrewrite.Result;
2324
import org.openrewrite.SourceFile;
@@ -71,7 +72,9 @@ public void apply(ProjectContext context) {
7172
}
7273
Recipe recipe = rewriteYamlRecipe.iterator().next();
7374
List<? extends SourceFile> rewriteSourceFiles = context.search(new OpenRewriteSourceFilesFinder());
74-
List<Result> results = recipe.run(rewriteSourceFiles);
75+
List<Result> results = recipe.run(rewriteSourceFiles, new InMemoryExecutionContext((t) -> {
76+
throw new RuntimeException(t);
77+
}));
7578
resultMerger.mergeResults(context, results);
7679
}
7780

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package org.springframework.sbm.engine.recipe;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.junit.jupiter.api.extension.ExtendWith;
5+
import org.mockito.InjectMocks;
6+
import org.mockito.Mock;
7+
import org.mockito.Mockito;
8+
import org.mockito.Spy;
9+
import org.mockito.junit.jupiter.MockitoExtension;
10+
import org.springframework.context.ApplicationEventPublisher;
11+
import org.springframework.sbm.engine.context.ProjectContext;
12+
import org.springframework.sbm.engine.events.ActionFailedEvent;
13+
import org.springframework.sbm.engine.events.ActionStartedEvent;
14+
15+
import static org.junit.jupiter.api.Assertions.assertThrows;
16+
import static org.mockito.ArgumentMatchers.any;
17+
18+
@ExtendWith(MockitoExtension.class)
19+
class ActionTest {
20+
21+
@Spy
22+
private ApplicationEventPublisher publisher;
23+
24+
@Mock
25+
ProjectContext projectContext;
26+
27+
@InjectMocks
28+
private TestActionImpl testAction;
29+
30+
static class TestActionImpl implements Action {
31+
private final ApplicationEventPublisher publisher;
32+
33+
TestActionImpl(ApplicationEventPublisher publisher) {
34+
this.publisher = publisher;
35+
}
36+
37+
@Override
38+
public String getDescription() {
39+
return "Test failing action";
40+
}
41+
42+
@Override
43+
public String getDetailedDescription() {
44+
return null;
45+
}
46+
47+
@Override
48+
public Condition getCondition() {
49+
return null;
50+
}
51+
52+
@Override
53+
public void apply(ProjectContext context) {
54+
throw new RuntimeException("my exception");
55+
}
56+
57+
@Override
58+
public ApplicationEventPublisher getEventPublisher() {
59+
return publisher;
60+
}
61+
62+
@Override
63+
public boolean isAutomated() {
64+
return false;
65+
}
66+
}
67+
68+
@Test
69+
void applyWithStatusEvent() {
70+
assertThrows(RuntimeException.class, () -> testAction.applyWithStatusEvent(projectContext));
71+
72+
Mockito.verify(publisher).publishEvent(any(ActionStartedEvent.class));
73+
Mockito.verify(publisher).publishEvent(any(ActionFailedEvent.class));
74+
}
75+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.springframework.sbm.engine.recipe;
2+
3+
import org.openrewrite.ExecutionContext;
4+
import org.openrewrite.SourceFile;
5+
6+
import java.util.List;
7+
8+
public class ErrorClass extends org.openrewrite.Recipe {
9+
10+
@Override
11+
public String getDisplayName() {
12+
return "NAME";
13+
}
14+
15+
@Override
16+
protected List<SourceFile> visit(List<SourceFile> before, ExecutionContext ctx) {
17+
ctx.getOnError().accept(new RuntimeException("A problem happened whilst visiting"));
18+
return super.visit(before, ctx);
19+
}
20+
}

components/sbm-core/src/test/java/org/springframework/sbm/engine/recipe/OpenRewriteDeclarativeRecipeAdapterTest.java

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,23 @@
1616

1717
package org.springframework.sbm.engine.recipe;
1818

19+
import com.fasterxml.jackson.annotation.JsonIgnore;
20+
import lombok.Getter;
1921
import org.junit.jupiter.api.Test;
20-
import org.openrewrite.Result;
21-
import org.openrewrite.config.YamlResourceLoader;
2222
import org.springframework.beans.factory.annotation.Autowired;
2323
import org.springframework.boot.test.context.SpringBootTest;
24+
import org.springframework.context.ApplicationEventPublisher;
2425
import org.springframework.sbm.engine.context.ProjectContext;
25-
import org.springframework.sbm.java.api.JavaSource;
2626
import org.springframework.sbm.project.RewriteSourceFileWrapper;
2727
import org.springframework.sbm.project.resource.ResourceHelper;
2828
import org.springframework.sbm.project.resource.TestProjectContext;
29+
import org.springframework.stereotype.Component;
2930
import org.springframework.validation.beanvalidation.CustomValidatorBean;
3031

31-
import java.io.ByteArrayInputStream;
3232
import java.io.IOException;
33-
import java.net.URI;
34-
import java.nio.charset.StandardCharsets;
35-
import java.util.Collection;
36-
import java.util.List;
37-
import java.util.Properties;
3833

3934
import static org.assertj.core.api.Assertions.assertThat;
35+
import static org.junit.jupiter.api.Assertions.assertThrows;
4036

4137
@SpringBootTest(classes = {
4238
RecipeParser.class,
@@ -56,7 +52,7 @@ class OpenRewriteDeclarativeRecipeAdapterTest {
5652
@Test
5753
void recipeFromYaml() throws IOException {
5854
String yaml =
59-
"- name: test-recipe\n" +
55+
"- name: test-recipe\n" +
6056
" description: Replace deprecated spring.datasource.* properties\n" +
6157
" condition:\n" +
6258
" type: org.springframework.sbm.common.migration.conditions.TrueCondition\n" +
@@ -91,4 +87,42 @@ void recipeFromYaml() throws IOException {
9187
"}"
9288
);
9389
}
94-
}
90+
91+
92+
@Test
93+
public void propagateExceptionFromOpenRewriteRecipe() throws IOException {
94+
95+
String actionDescription =
96+
"- name: test-recipe\n" +
97+
" description: Replace deprecated spring.datasource.* properties\n" +
98+
" condition:\n" +
99+
" type: org.springframework.sbm.common.migration.conditions.TrueCondition\n" +
100+
" actions:\n" +
101+
" - type: org.springframework.sbm.engine.recipe.OpenRewriteDeclarativeRecipeAdapter\n" +
102+
" condition:\n" +
103+
" type: org.springframework.sbm.common.migration.conditions.TrueCondition\n" +
104+
" versionStartingWith: \"2.7.\"\n" +
105+
" description: Add Spring Milestone Repository and bump parent pom to 3.0.0-M3\n" +
106+
"\n" +
107+
" openRewriteRecipe: |-\n" +
108+
" type: specs.openrewrite.org/v1beta/recipe\n" +
109+
" name: org.openrewrite.java.spring.boot3.data.UpgradeSpringData30\n" +
110+
" displayName: Upgrade to Spring Data 3.0\n" +
111+
" description: 'Upgrade to Spring Data to 3.0 from any prior version.'\n" +
112+
" recipeList:\n" +
113+
" - org.springframework.sbm.engine.recipe.ErrorClass\n";
114+
115+
Recipe[] recipes = recipeParser.parseRecipe(actionDescription);
116+
assertThat(recipes[0].getActions().get(0)).isInstanceOf(OpenRewriteDeclarativeRecipeAdapter.class);
117+
OpenRewriteDeclarativeRecipeAdapter recipeAdapter = (OpenRewriteDeclarativeRecipeAdapter) recipes[0].getActions().get(0);
118+
119+
String javaSource = "@java.lang.Deprecated\n" +
120+
"public class Foo {}";
121+
122+
ProjectContext context = TestProjectContext.buildProjectContext()
123+
.addJavaSource("src/main/java", javaSource)
124+
.build();
125+
126+
assertThrows(RuntimeException.class, () -> recipeAdapter.apply(context));
127+
}
128+
}

0 commit comments

Comments
 (0)