Skip to content

Commit b240aef

Browse files
authored
feat: add OpenRewrite module for migrations and recipe for 5.3.0 (#3236)
1 parent 5daec11 commit b240aef

8 files changed

Lines changed: 780 additions & 2 deletions

File tree

.github/workflows/pr.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
uses: actions/setup-java@v5
2323
with:
2424
distribution: temurin
25-
java-version: 25
25+
java-version: 17
2626
cache: 'maven'
2727
- name: Check code format
2828
run: |

docs/content/en/blog/releases/v5-3-release.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,11 @@ checks.
220220

221221
`reconciliationFinished(..)` is extended with `RetryInfo`. `monitorSizeOf(..)` is removed.
222222

223+
### `ResourceAction` relocated
224+
225+
`ResourceAction` in `io.javaoperatorsdk.operator.processing.event.source.controller` has been
226+
removed. Use `io.javaoperatorsdk.operator.processing.event.source.ResourceAction` instead.
227+
223228
See the full [migration guide](/docs/migration/v5-3-migration) for details.
224229

225230
## Getting Started

docs/content/en/docs/migration/v5-3-migration.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,30 @@ title: Migrating from v5.2 to v5.3
33
description: Migrating from v5.2 to v5.3
44
---
55

6+
## Automated Migration with OpenRewrite
7+
8+
You can automatically apply all the migration changes described below using [OpenRewrite](https://docs.openrewrite.org/).
9+
Add the following to your `pom.xml` and run `mvn rewrite:run`:
10+
11+
```xml
12+
<plugin>
13+
<groupId>org.openrewrite.maven</groupId>
14+
<artifactId>rewrite-maven-plugin</artifactId>
15+
<version>6.33.0</version>
16+
<configuration>
17+
<activeRecipes>
18+
<recipe>io.javaoperatorsdk.operator.migration.V5_3Migration</recipe>
19+
</activeRecipes>
20+
</configuration>
21+
<dependencies>
22+
<dependency>
23+
<groupId>io.javaoperatorsdk</groupId>
24+
<artifactId>migration</artifactId>
25+
<version>5.3.1</version>
26+
</dependency>
27+
</dependencies>
28+
</plugin>
29+
```
630

731
## Rename of JUnit module
832

@@ -48,4 +72,10 @@ The following table shows the relevant method renames:
4872

4973
Other changes:
5074
- `reconciliationFinished(..)` method is extended with `RetryInfo`
51-
- `monitorSizeOf(..)` method is removed.
75+
- `monitorSizeOf(..)` method is removed.
76+
77+
## ResourceAction relocation
78+
79+
The `ResourceAction` enum has been removed from
80+
`io.javaoperatorsdk.operator.processing.event.source.controller` use the one in package
81+
`io.javaoperatorsdk.operator.processing.event.source.ResourceAction`; thus update your imports accordingly.

migration/pom.xml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
Copyright Java Operator SDK Authors
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
18+
-->
19+
<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">
20+
<modelVersion>4.0.0</modelVersion>
21+
<parent>
22+
<groupId>io.javaoperatorsdk</groupId>
23+
<artifactId>java-operator-sdk</artifactId>
24+
<version>5.3.1-SNAPSHOT</version>
25+
</parent>
26+
27+
<artifactId>migration</artifactId>
28+
<name>Operator SDK - Migration Recipes</name>
29+
<description>OpenRewrite migration recipes for Java Operator SDK</description>
30+
31+
<properties>
32+
<openrewrite.version>8.46.1</openrewrite.version>
33+
</properties>
34+
35+
<dependencies>
36+
<dependency>
37+
<groupId>org.openrewrite</groupId>
38+
<artifactId>rewrite-java</artifactId>
39+
<version>${openrewrite.version}</version>
40+
</dependency>
41+
<dependency>
42+
<groupId>org.openrewrite</groupId>
43+
<artifactId>rewrite-maven</artifactId>
44+
<version>${openrewrite.version}</version>
45+
</dependency>
46+
<dependency>
47+
<groupId>org.openrewrite</groupId>
48+
<artifactId>rewrite-test</artifactId>
49+
<version>${openrewrite.version}</version>
50+
<scope>test</scope>
51+
</dependency>
52+
<dependency>
53+
<groupId>org.openrewrite</groupId>
54+
<artifactId>rewrite-java-17</artifactId>
55+
<version>${openrewrite.version}</version>
56+
<scope>test</scope>
57+
</dependency>
58+
<dependency>
59+
<groupId>org.junit.jupiter</groupId>
60+
<artifactId>junit-jupiter-api</artifactId>
61+
<scope>test</scope>
62+
</dependency>
63+
<dependency>
64+
<groupId>org.junit.jupiter</groupId>
65+
<artifactId>junit-jupiter-engine</artifactId>
66+
<scope>test</scope>
67+
</dependency>
68+
<dependency>
69+
<groupId>org.assertj</groupId>
70+
<artifactId>assertj-core</artifactId>
71+
<scope>test</scope>
72+
</dependency>
73+
</dependencies>
74+
75+
</project>
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* Copyright Java Operator SDK Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.javaoperatorsdk.operator.migration;
17+
18+
import java.util.Objects;
19+
20+
import org.openrewrite.ExecutionContext;
21+
import org.openrewrite.NlsRewrite;
22+
import org.openrewrite.Option;
23+
import org.openrewrite.Recipe;
24+
import org.openrewrite.TreeVisitor;
25+
import org.openrewrite.java.JavaIsoVisitor;
26+
import org.openrewrite.java.tree.J;
27+
import org.openrewrite.java.tree.JavaType;
28+
29+
public class RemoveMethodDeclaration extends Recipe {
30+
31+
@Option(
32+
displayName = "Interface name",
33+
description = "Fully qualified or simple name of the interface.",
34+
example = "com.example.YourInterface")
35+
String interfaceName;
36+
37+
@Option(
38+
displayName = "Method name",
39+
description = "Name of the method to remove.",
40+
example = "removedMethod")
41+
String methodName;
42+
43+
@Override
44+
public String getDisplayName() {
45+
return "Remove obsolete method from implementing classes";
46+
}
47+
48+
@Override
49+
public @NlsRewrite.Description String getDescription() {
50+
return "Remove obsolete method from implementing classes";
51+
}
52+
53+
@Override
54+
public TreeVisitor<?, ExecutionContext> getVisitor() {
55+
return new JavaIsoVisitor<ExecutionContext>() {
56+
57+
@Override
58+
public J.ClassDeclaration visitClassDeclaration(
59+
J.ClassDeclaration classDecl, ExecutionContext ctx) {
60+
J.ClassDeclaration cd = super.visitClassDeclaration(classDecl, ctx);
61+
62+
if (cd.getType() == null || !typeMatchesOrImplements(cd.getType())) {
63+
return cd;
64+
}
65+
66+
// Mutate the type info in place to remove the method from the declared methods list,
67+
// so all AST nodes sharing this type reference stay consistent.
68+
var type = cd.getType();
69+
if (type instanceof JavaType.Class classType) {
70+
var updatedMethods =
71+
classType.getMethods().stream().filter(m -> !m.getName().equals(methodName)).toList();
72+
classType.unsafeSet(
73+
classType.getTypeParameters(),
74+
classType.getSupertype(),
75+
classType.getOwningClass(),
76+
classType.getAnnotations(),
77+
classType.getInterfaces(),
78+
classType.getMembers(),
79+
updatedMethods);
80+
}
81+
82+
return cd;
83+
}
84+
85+
@Override
86+
public J.MethodDeclaration visitMethodDeclaration(
87+
J.MethodDeclaration method, ExecutionContext ctx) {
88+
if (!method.getSimpleName().equals(methodName)) {
89+
return super.visitMethodDeclaration(method, ctx);
90+
}
91+
92+
J.ClassDeclaration classDecl = getCursor().firstEnclosing(J.ClassDeclaration.class);
93+
if (classDecl == null || classDecl.getType() == null) {
94+
return super.visitMethodDeclaration(method, ctx);
95+
}
96+
97+
if (typeMatchesOrImplements(classDecl.getType())) {
98+
//noinspection DataFlowIssue
99+
return null;
100+
}
101+
102+
return super.visitMethodDeclaration(method, ctx);
103+
}
104+
105+
private boolean typeMatchesOrImplements(JavaType.FullyQualified type) {
106+
for (var iface : type.getInterfaces()) {
107+
if (iface.getFullyQualifiedName().equals(interfaceName)
108+
|| typeMatchesOrImplements(iface)) {
109+
return true;
110+
}
111+
}
112+
var supertype = type.getSupertype();
113+
if (supertype != null && !supertype.getFullyQualifiedName().equals("java.lang.Object")) {
114+
return typeMatchesOrImplements(supertype);
115+
}
116+
return false;
117+
}
118+
};
119+
}
120+
121+
public String getInterfaceName() {
122+
return interfaceName;
123+
}
124+
125+
public void setInterfaceName(String interfaceName) {
126+
this.interfaceName = interfaceName;
127+
}
128+
129+
public String getMethodName() {
130+
return methodName;
131+
}
132+
133+
public void setMethodName(String methodName) {
134+
this.methodName = methodName;
135+
}
136+
137+
@Override
138+
public boolean equals(Object o) {
139+
if (o == null || getClass() != o.getClass()) return false;
140+
if (!super.equals(o)) return false;
141+
RemoveMethodDeclaration that = (RemoveMethodDeclaration) o;
142+
return Objects.equals(interfaceName, that.interfaceName)
143+
&& Objects.equals(methodName, that.methodName);
144+
}
145+
146+
@Override
147+
public int hashCode() {
148+
return Objects.hash(super.hashCode(), interfaceName, methodName);
149+
}
150+
}

0 commit comments

Comments
 (0)