Skip to content

Commit e3d4516

Browse files
authored
refactor(templates): introduce @ApplyTemplate and @RollbackTemplate annotations (#862)
- Create **@ApplyTemplate** and **@RollbackTemplate** as template-specific annotations, mirroring `@Apply` and `@Rollback` but dedicated to `@ChangeTemplate` classes
1 parent 574a275 commit e3d4516

File tree

12 files changed

+144
-63
lines changed

12 files changed

+144
-63
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2026 Flamingock (https://www.flamingock.io)
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.flamingock.api.annotations;
17+
18+
import java.lang.annotation.ElementType;
19+
import java.lang.annotation.Retention;
20+
import java.lang.annotation.RetentionPolicy;
21+
import java.lang.annotation.Target;
22+
23+
/**
24+
* Marks the method that applies a template-based change to the target system.
25+
* This method contains the forward change logic that evolves your system state.
26+
*
27+
* <p>The method can accept dependency-injected parameters from the Flamingock context,
28+
* including database connections, repositories, and custom dependencies.
29+
*
30+
* <p>This annotation is specifically for use in {@link ChangeTemplate} classes.
31+
* For code-based {@link Change} classes, use {@link Apply} instead.
32+
*
33+
* @see ChangeTemplate
34+
* @see RollbackTemplate
35+
*/
36+
@Target(ElementType.METHOD)
37+
@Retention(RetentionPolicy.RUNTIME)
38+
public @interface ApplyTemplate {
39+
40+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2026 Flamingock (https://www.flamingock.io)
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.flamingock.api.annotations;
17+
18+
import java.lang.annotation.ElementType;
19+
import java.lang.annotation.Retention;
20+
import java.lang.annotation.RetentionPolicy;
21+
import java.lang.annotation.Target;
22+
23+
/**
24+
* Marks the method that rolls back a template-based change in case of failure or manual reversion.
25+
* This method should undo the operations performed by the corresponding {@link ApplyTemplate} method.
26+
*
27+
* <p>Rollback methods are optional but recommended for production systems to ensure
28+
* safe change reversibility. They receive the same dependency injection as ApplyTemplate methods.
29+
*
30+
* <p>This annotation is specifically for use in {@link ChangeTemplate} classes.
31+
* For code-based {@link Change} classes, use {@link Rollback} instead.
32+
*
33+
* @see ChangeTemplate
34+
* @see ApplyTemplate
35+
*/
36+
@Target(ElementType.METHOD)
37+
@Retention(RetentionPolicy.RUNTIME)
38+
public @interface RollbackTemplate {
39+
40+
}

core/flamingock-core-api/src/test/java/io/flamingock/api/template/AbstractChangeTemplateReflectiveClassesTest.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
*/
1616
package io.flamingock.api.template;
1717

18-
import io.flamingock.api.annotations.Apply;
18+
import io.flamingock.api.annotations.ApplyTemplate;
1919
import io.flamingock.api.annotations.ChangeTemplate;
20-
import io.flamingock.api.annotations.Rollback;
20+
import io.flamingock.api.annotations.RollbackTemplate;
2121
import io.flamingock.api.template.wrappers.TemplateString;
2222
import io.flamingock.api.template.wrappers.TemplateVoid;
2323
import org.junit.jupiter.api.DisplayName;
@@ -95,12 +95,12 @@ public TestTemplateWithCustomTypes() {
9595
super();
9696
}
9797

98-
@Apply
98+
@ApplyTemplate
9999
public void apply() {
100100
// Test implementation
101101
}
102102

103-
@Rollback
103+
@RollbackTemplate
104104
public void rollback() {
105105
}
106106
}
@@ -114,12 +114,12 @@ public TestTemplateWithAdditionalClasses() {
114114
super(AdditionalClass.class, AnotherAdditionalClass.class);
115115
}
116116

117-
@Apply
117+
@ApplyTemplate
118118
public void apply() {
119119
// Test implementation
120120
}
121121

122-
@Rollback
122+
@RollbackTemplate
123123
public void rollback() {
124124
}
125125
}
@@ -133,12 +133,12 @@ public TestTemplateWithVoidConfig() {
133133
super();
134134
}
135135

136-
@Apply
136+
@ApplyTemplate
137137
public void apply() {
138138
// Test implementation
139139
}
140140

141-
@Rollback
141+
@RollbackTemplate
142142
public void rollback() {
143143
}
144144
}

core/flamingock-core-commons/src/main/java/io/flamingock/internal/common/core/template/ChangeTemplateManager.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
package io.flamingock.internal.common.core.template;
1717

18-
import io.flamingock.api.annotations.Rollback;
18+
import io.flamingock.api.annotations.RollbackTemplate;
1919
import io.flamingock.api.template.ChangeTemplate;
2020
import io.flamingock.internal.common.core.error.FlamingockException;
2121
import io.flamingock.internal.util.ReflectionUtil;
@@ -179,9 +179,9 @@ private static ChangeTemplateDefinition buildDefinition(Class<? extends ChangeTe
179179
"Template class '%s' has a blank @ChangeTemplate id. The id must be a non-empty string",
180180
templateClass.getSimpleName()));
181181
}
182-
if (!ReflectionUtil.findFirstAnnotatedMethod(templateClass, Rollback.class).isPresent()) {
182+
if (!ReflectionUtil.findFirstAnnotatedMethod(templateClass, RollbackTemplate.class).isPresent()) {
183183
throw new FlamingockException(String.format(
184-
"Template class '%s' is missing required @Rollback method",
184+
"Template class '%s' is missing required @RollbackTemplate method",
185185
templateClass.getSimpleName()));
186186
}
187187
return new ChangeTemplateDefinition(id, templateClass, annotation.multiStep(), annotation.rollbackPayloadRequired());

core/flamingock-core-commons/src/test/java/io/flamingock/internal/common/core/template/ChangeTemplateManagerTest.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
*/
1616
package io.flamingock.internal.common.core.template;
1717

18-
import io.flamingock.api.annotations.Apply;
18+
import io.flamingock.api.annotations.ApplyTemplate;
1919
import io.flamingock.api.annotations.ChangeTemplate;
20-
import io.flamingock.api.annotations.Rollback;
20+
import io.flamingock.api.annotations.RollbackTemplate;
2121
import io.flamingock.api.template.AbstractChangeTemplate;
2222
import io.flamingock.api.template.wrappers.TemplateString;
2323
import io.flamingock.api.template.wrappers.TemplateVoid;
@@ -37,11 +37,11 @@ public AnnotatedSimpleTemplate() {
3737
super();
3838
}
3939

40-
@Apply
40+
@ApplyTemplate
4141
public void apply() {
4242
}
4343

44-
@Rollback
44+
@RollbackTemplate
4545
public void rollback() {
4646
}
4747
}
@@ -52,11 +52,11 @@ public AnnotatedSteppableTemplate() {
5252
super();
5353
}
5454

55-
@Apply
55+
@ApplyTemplate
5656
public void apply() {
5757
}
5858

59-
@Rollback
59+
@RollbackTemplate
6060
public void rollback() {
6161
}
6262
}
@@ -66,7 +66,7 @@ public UnannotatedTemplate() {
6666
super();
6767
}
6868

69-
@Apply
69+
@ApplyTemplate
7070
public void apply() {
7171
}
7272
}
@@ -120,11 +120,11 @@ public TemplateWithRollbackNotRequired() {
120120
super();
121121
}
122122

123-
@Apply
123+
@ApplyTemplate
124124
public void apply() {
125125
}
126126

127-
@Rollback
127+
@RollbackTemplate
128128
public void rollback() {
129129
}
130130
}
@@ -147,18 +147,18 @@ public TemplateWithoutRollback() {
147147
super();
148148
}
149149

150-
@Apply
150+
@ApplyTemplate
151151
public void apply() {
152152
}
153153
}
154154

155155
@Test
156-
@DisplayName("addTemplate with class missing @Rollback method should throw FlamingockException")
156+
@DisplayName("addTemplate with class missing @RollbackTemplate method should throw FlamingockException")
157157
void addTemplateWithMissingRollbackMethodShouldThrow() {
158158
FlamingockException exception = assertThrows(FlamingockException.class,
159159
() -> ChangeTemplateManager.addTemplate(TemplateWithoutRollback.class));
160160

161-
assertTrue(exception.getMessage().contains("missing required @Rollback method"));
161+
assertTrue(exception.getMessage().contains("missing required @RollbackTemplate method"));
162162
assertTrue(exception.getMessage().contains("TemplateWithoutRollback"));
163163
}
164164
}

core/flamingock-core-commons/src/test/java/io/flamingock/internal/common/core/template/TemplateValidatorTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
*/
1616
package io.flamingock.internal.common.core.template;
1717

18-
import io.flamingock.api.annotations.Apply;
18+
import io.flamingock.api.annotations.ApplyTemplate;
1919
import io.flamingock.api.annotations.ChangeTemplate;
20-
import io.flamingock.api.annotations.Rollback;
20+
import io.flamingock.api.annotations.RollbackTemplate;
2121
import io.flamingock.api.template.AbstractChangeTemplate;
2222
import io.flamingock.api.template.wrappers.TemplateString;
2323
import io.flamingock.api.template.wrappers.TemplateVoid;
@@ -47,12 +47,12 @@ public TestSimpleTemplate() {
4747
super();
4848
}
4949

50-
@Apply
50+
@ApplyTemplate
5151
public void apply() {
5252
// Test implementation
5353
}
5454

55-
@Rollback
55+
@RollbackTemplate
5656
public void rollback() {
5757
}
5858
}
@@ -64,12 +64,12 @@ public TestSteppableTemplate() {
6464
super();
6565
}
6666

67-
@Apply
67+
@ApplyTemplate
6868
public void apply() {
6969
// Test implementation
7070
}
7171

72-
@Rollback
72+
@RollbackTemplate
7373
public void rollback() {
7474
}
7575
}

core/flamingock-core/src/main/java/io/flamingock/internal/core/task/loaded/AbstractTemplateLoadedChange.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
*/
1616
package io.flamingock.internal.core.task.loaded;
1717

18-
import io.flamingock.api.annotations.Apply;
19-
import io.flamingock.api.annotations.Rollback;
18+
import io.flamingock.api.annotations.ApplyTemplate;
19+
import io.flamingock.api.annotations.RollbackTemplate;
2020
import io.flamingock.api.template.ChangeTemplate;
2121
import io.flamingock.api.template.TemplateField;
2222
import io.flamingock.api.template.TemplatePayload;
@@ -89,16 +89,16 @@ public Class<? extends ChangeTemplate<CONFIG, APPLY, ROLLBACK>> getTemplateClass
8989

9090
@Override
9191
public Method getApplyMethod() {
92-
return ReflectionUtil.findFirstAnnotatedMethod(getImplementationClass(), Apply.class)
92+
return ReflectionUtil.findFirstAnnotatedMethod(getImplementationClass(), ApplyTemplate.class)
9393
.orElseThrow(() -> new IllegalArgumentException(String.format(
9494
"Templated[%s] without %s method",
9595
getSource(),
96-
Apply.class.getSimpleName())));
96+
ApplyTemplate.class.getSimpleName())));
9797
}
9898

9999
@Override
100100
public Optional<Method> getRollbackMethod() {
101-
return ReflectionUtil.findFirstAnnotatedMethod(getImplementationClass(), Rollback.class);
101+
return ReflectionUtil.findFirstAnnotatedMethod(getImplementationClass(), RollbackTemplate.class);
102102
}
103103

104104
@Override

core/flamingock-core/src/test/java/io/flamingock/internal/core/task/executable/SteppableTemplateExecutableTaskTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
*/
1616
package io.flamingock.internal.core.task.executable;
1717

18-
import io.flamingock.api.annotations.Apply;
18+
import io.flamingock.api.annotations.ApplyTemplate;
1919
import io.flamingock.api.annotations.ChangeTemplate;
20-
import io.flamingock.api.annotations.Rollback;
20+
import io.flamingock.api.annotations.RollbackTemplate;
2121
import io.flamingock.api.template.AbstractChangeTemplate;
2222
import io.flamingock.api.template.TemplateStep;
2323
import io.flamingock.api.template.wrappers.TemplateString;
@@ -67,15 +67,15 @@ public TestSteppableTemplate() {
6767
super();
6868
}
6969

70-
@Apply
70+
@ApplyTemplate
7171
public void apply() {
7272
if (shouldFailOnApply && appliedPayloads.size() == failAtStep) {
7373
throw new RuntimeException("Simulated apply failure at step " + failAtStep);
7474
}
7575
appliedPayloads.add(applyPayload.getValue());
7676
}
7777

78-
@Rollback
78+
@RollbackTemplate
7979
public void rollback() {
8080
if (shouldFailOnRollback) {
8181
throw new RuntimeException("Simulated rollback failure");
@@ -94,15 +94,15 @@ public TestTemplateWithNullRollbackMethod() {
9494
super();
9595
}
9696

97-
@Apply
97+
@ApplyTemplate
9898
public void apply() {
9999
if (shouldFailOnApply && appliedPayloads.size() == failAtStep) {
100100
throw new RuntimeException("Simulated apply failure at step " + failAtStep);
101101
}
102102
appliedPayloads.add(applyPayload.getValue());
103103
}
104104

105-
@Rollback
105+
@RollbackTemplate
106106
public void rollback() {
107107
}
108108
}

core/flamingock-core/src/test/java/io/flamingock/internal/core/task/loaded/PayloadTransactionSupportValidationTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
*/
1616
package io.flamingock.internal.core.task.loaded;
1717

18-
import io.flamingock.api.annotations.Apply;
19-
import io.flamingock.api.annotations.Rollback;
18+
import io.flamingock.api.annotations.ApplyTemplate;
19+
import io.flamingock.api.annotations.RollbackTemplate;
2020
import io.flamingock.api.template.AbstractChangeTemplate;
2121
import io.flamingock.api.template.TemplatePayload;
2222
import io.flamingock.api.template.TemplatePayloadInfo;
@@ -88,11 +88,11 @@ public TemplatePayloadInfo getInfo() {
8888
// ── Dummy template (never instantiated — only .class is used) ───────
8989

9090
static class DummyTemplate extends AbstractChangeTemplate<TemplateVoid, TemplateString, TemplateString> {
91-
@Apply
91+
@ApplyTemplate
9292
public void apply() {
9393
}
9494

95-
@Rollback
95+
@RollbackTemplate
9696
public void rollback() {
9797
}
9898
}

0 commit comments

Comments
 (0)