FixedIntervalBuilder.java

1
package fr.sii.ogham.core.builder.retry;
2
3
import fr.sii.ogham.core.builder.Builder;
4
import fr.sii.ogham.core.builder.configuration.ConfigurationValueBuilder;
5
import fr.sii.ogham.core.builder.configuration.ConfigurationValueBuilderHelper;
6
import fr.sii.ogham.core.builder.configurer.Configurer;
7
import fr.sii.ogham.core.builder.context.BuildContext;
8
import fr.sii.ogham.core.builder.env.EnvironmentBuilder;
9
import fr.sii.ogham.core.fluent.AbstractParent;
10
import fr.sii.ogham.core.retry.FixedIntervalRetry;
11
import fr.sii.ogham.core.retry.RetryExecutor;
12
import fr.sii.ogham.core.retry.RetryStrategy;
13
import fr.sii.ogham.core.retry.SimpleRetryExecutor;
14
15
/**
16
 * Configures retry handling based on a fixed interval (based on first execution
17
 * start date).
18
 * 
19
 * Retry several times with a fixed interval between each try until the maximum
20
 * attempts is reached. The interval is based on the first execution start date.
21
 * 
22
 * For example:
23
 * 
24
 * <pre>
25
 * .fixedInterval()
26
 *    .interval(500)
27
 *    .maxRetries(5)
28
 * </pre>
29
 * 
30
 * Means that a retry will be attempted every 500ms until 5 attempts are reached
31
 * (inclusive). For example, you want to connect to an external system at t1=0
32
 * and the connection timeout (100ms) is triggered at t2=100ms. Using this retry
33
 * will provide the following behavior:
34
 * 
35
 * 
36
 * <ul>
37
 * <li>0: connect</li>
38
 * <li>100: timeout</li>
39
 * <li>500: connect</li>
40
 * <li>600: timeout</li>
41
 * <li>1000: connect</li>
42
 * <li>1100: timeout</li>
43
 * <li>1500: connect</li>
44
 * <li>1600: timeout</li>
45
 * <li>2000: connect</li>
46
 * <li>2100: timeout</li>
47
 * <li>2500: connect</li>
48
 * <li>2600: timeout</li>
49
 * <li>fail</li>
50
 * </ul>
51
 * 
52
 * 
53
 * <strong>NOTE:</strong> The provided date doesn't take the duration of the
54
 * execution in account. If an execution takes 1s to execute while retry delay
55
 * is set to 500ms, there may have several executions in parallel. However, this
56
 * totally depends on the {@link RetryExecutor} implementation. For example
57
 * {@link SimpleRetryExecutor} won't run several executions in parallel. In this
58
 * case, it will execute the action as soon as the previous one has failed
59
 * therefore the delay may not be complied.
60
 * 
61
 * 
62
 * @author Aurélien Baudet
63
 *
64
 * @param <P>
65
 *            the type of the parent builder (when calling {@link #and()}
66
 *            method)
67
 */
68
public class FixedIntervalBuilder<P> extends AbstractParent<P> implements Builder<RetryStrategy> {
69
	private final BuildContext buildContext;
70
	private final ConfigurationValueBuilderHelper<FixedIntervalBuilder<P>, Integer> maxRetriesValueBuilder;
71
	private final ConfigurationValueBuilderHelper<FixedIntervalBuilder<P>, Long> intervalValueBuilder;
72
73
	/**
74
	 * Initializes the builder with a parent builder. The parent builder is used
75
	 * when calling {@link #and()} method. The {@link EnvironmentBuilder} is
76
	 * used to evaluate properties when {@link #build()} method is called.
77
	 * 
78
	 * @param parent
79
	 *            the parent builder
80
	 * @param buildContext
81
	 *            for registering instances and property evaluation
82
	 */
83
	public FixedIntervalBuilder(P parent, BuildContext buildContext) {
84
		super(parent);
85
		this.buildContext = buildContext;
86
		maxRetriesValueBuilder = buildContext.newConfigurationValueBuilder(this, Integer.class);
87
		intervalValueBuilder = buildContext.newConfigurationValueBuilder(this, Long.class);
88
	}
89
90
	/**
91
	 * Set the maximum number of attempts.
92
	 * 
93
	 * <p>
94
	 * The value set using this method takes precedence over any property and
95
	 * default value configured using {@link #maxRetries()}.
96
	 * 
97
	 * <pre>
98
	 * .maxRetries(10)
99
	 * .maxRetries()
100
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
101
	 *   .defaultValue(5)
102
	 * </pre>
103
	 * 
104
	 * <pre>
105
	 * .maxRetries(10)
106
	 * .maxRetries()
107
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
108
	 *   .defaultValue(5)
109
	 * </pre>
110
	 * 
111
	 * In both cases, {@code maxRetries(10)} is used.
112
	 * 
113
	 * <p>
114
	 * If this method is called several times, only the last value is used.
115
	 * 
116
	 * <p>
117
	 * If {@code null} value is set, it is like not setting a value at all. The
118
	 * property/default value configuration is applied.
119
	 * 
120
	 * @param maxRetries
121
	 *            the maximum number of attempts
122
	 * @return this instance for fluent chaining
123
	 */
124
	public FixedIntervalBuilder<P> maxRetries(Integer maxRetries) {
125 2 1. maxRetries : removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → NO_COVERAGE
2. maxRetries : removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → KILLED
		this.maxRetriesValueBuilder.setValue(maxRetries);
126 2 1. maxRetries : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → NO_COVERAGE
2. maxRetries : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → KILLED
		return this;
127
	}
128
129
	/**
130
	 * Set the maximum number of attempts.
131
	 * 
132
	 * <p>
133
	 * This method is mainly used by {@link Configurer}s to register some
134
	 * property keys and/or a default value. The aim is to let developer be able
135
	 * to externalize its configuration (using system properties, configuration
136
	 * file or anything else). If the developer doesn't configure any value for
137
	 * the registered properties, the default value is used (if set).
138
	 * 
139
	 * <pre>
140
	 * .maxRetries()
141
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
142
	 *   .defaultValue(5)
143
	 * </pre>
144
	 * 
145
	 * <p>
146
	 * Non-null value set using {@link #maxRetries(Integer)} takes precedence
147
	 * over property values and default value.
148
	 * 
149
	 * <pre>
150
	 * .maxRetries(10)
151
	 * .maxRetries()
152
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
153
	 *   .defaultValue(5)
154
	 * </pre>
155
	 * 
156
	 * The value {@code 10} is used regardless of the value of the properties
157
	 * and default value.
158
	 * 
159
	 * <p>
160
	 * See {@link ConfigurationValueBuilder} for more information.
161
	 * 
162
	 * 
163
	 * @return the builder to configure property keys/default value
164
	 */
165
	public ConfigurationValueBuilder<FixedIntervalBuilder<P>, Integer> maxRetries() {
166 8 1. maxRetries : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → NO_COVERAGE
2. maxRetries : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → KILLED
3. maxRetries : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → KILLED
4. maxRetries : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → KILLED
5. maxRetries : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → KILLED
6. maxRetries : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → KILLED
7. maxRetries : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → KILLED
8. maxRetries : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → KILLED
		return maxRetriesValueBuilder;
167
	}
168
169
	/**
170
	 * Set the interval between two executions (in milliseconds).
171
	 * 
172
	 * <p>
173
	 * The value set using this method takes precedence over any property and
174
	 * default value configured using {@link #interval()}.
175
	 * 
176
	 * <pre>
177
	 * .interval(5000L)
178
	 * .interval()
179
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
180
	 *   .defaultValue(10000L)
181
	 * </pre>
182
	 * 
183
	 * <pre>
184
	 * .interval(5000L)
185
	 * .interval()
186
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
187
	 *   .defaultValue(10000L)
188
	 * </pre>
189
	 * 
190
	 * In both cases, {@code interval(5000L)} is used.
191
	 * 
192
	 * <p>
193
	 * If this method is called several times, only the last value is used.
194
	 * 
195
	 * <p>
196
	 * If {@code null} value is set, it is like not setting a value at all. The
197
	 * property/default value configuration is applied.
198
	 * 
199
	 * @param interval
200
	 *            the time between two attempts
201
	 * @return this instance for fluent chaining
202
	 */
203
	public FixedIntervalBuilder<P> interval(Long interval) {
204 2 1. interval : removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → NO_COVERAGE
2. interval : removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → KILLED
		intervalValueBuilder.setValue(interval);
205 2 1. interval : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → NO_COVERAGE
2. interval : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → KILLED
		return this;
206
	}
207
208
	/**
209
	 * Set the interval between two executions (in milliseconds).
210
	 * 
211
	 * <p>
212
	 * This method is mainly used by {@link Configurer}s to register some
213
	 * property keys and/or a default value. The aim is to let developer be able
214
	 * to externalize its configuration (using system properties, configuration
215
	 * file or anything else). If the developer doesn't configure any value for
216
	 * the registered properties, the default value is used (if set).
217
	 * 
218
	 * <pre>
219
	 * .interval()
220
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
221
	 *   .defaultValue(10000L)
222
	 * </pre>
223
	 * 
224
	 * <p>
225
	 * Non-null value set using {@link #interval(Long)} takes precedence over
226
	 * property values and default value.
227
	 * 
228
	 * <pre>
229
	 * .interval(5000L)
230
	 * .interval()
231
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
232
	 *   .defaultValue(10000L)
233
	 * </pre>
234
	 * 
235
	 * The value {@code 5000L} is used regardless of the value of the properties
236
	 * and default value.
237
	 * 
238
	 * <p>
239
	 * See {@link ConfigurationValueBuilder} for more information.
240
	 * 
241
	 * 
242
	 * @return the builder to configure property keys/default value
243
	 */
244
	public ConfigurationValueBuilder<FixedIntervalBuilder<P>, Long> interval() {
245 8 1. interval : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → NO_COVERAGE
2. interval : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → KILLED
3. interval : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → KILLED
4. interval : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → KILLED
5. interval : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → KILLED
6. interval : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → KILLED
7. interval : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → KILLED
8. interval : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → KILLED
		return intervalValueBuilder;
246
	}
247
248
	@Override
249
	public RetryStrategy build() {
250
		int evaluatedMaxRetries = buildMaxRetries();
251
		long evaluatedInterval = buildInterval();
252 6 1. build : negated conditional → SURVIVED
2. build : negated conditional → NO_COVERAGE
3. build : negated conditional → SURVIVED
4. build : negated conditional → NO_COVERAGE
5. build : negated conditional → KILLED
6. build : negated conditional → KILLED
		if (evaluatedMaxRetries == 0 || evaluatedInterval == 0) {
253
			return null;
254
		}
255 2 1. build : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::build → NO_COVERAGE
2. build : replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::build → KILLED
		return buildContext.register(new FixedIntervalRetry(evaluatedMaxRetries, evaluatedInterval));
256
	}
257
258
	private int buildMaxRetries() {
259 3 1. buildMaxRetries : replaced int return with 0 for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::buildMaxRetries → SURVIVED
2. buildMaxRetries : replaced int return with 0 for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::buildMaxRetries → NO_COVERAGE
3. buildMaxRetries : replaced int return with 0 for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::buildMaxRetries → KILLED
		return maxRetriesValueBuilder.getValue(0);
260
	}
261
262
	private long buildInterval() {
263 3 1. buildInterval : replaced long return with 0 for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::buildInterval → SURVIVED
2. buildInterval : replaced long return with 0 for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::buildInterval → NO_COVERAGE
3. buildInterval : replaced long return with 0 for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::buildInterval → KILLED
		return intervalValueBuilder.getValue(0L);
264
	}
265
}

Mutations

125

1.1
Location : maxRetries
Killed by : oghamcore.it.core.builder.retry.RetryBuilderSpec
removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → KILLED

2.2
Location : maxRetries
Killed by : none
removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → NO_COVERAGE

126

1.1
Location : maxRetries
Killed by : oghamcore.it.core.builder.retry.RetryBuilderSpec
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → KILLED

2.2
Location : maxRetries
Killed by : none
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → NO_COVERAGE

166

1.1
Location : maxRetries
Killed by : oghamspringbootv2autoconfigure.it.OghamSpringBoot2JavaMailAutoConfigurationTests.oghamPropertiesWithSpringPropsShouldUseOghamPropertiesPrecedence(oghamspringbootv2autoconfigure.it.OghamSpringBoot2JavaMailAutoConfigurationTests)
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → KILLED

2.2
Location : maxRetries
Killed by : none
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → NO_COVERAGE

3.3
Location : maxRetries
Killed by : oghamspringbootv1autoconfigure.it.OghamSpringBoot1JavaMailAutoConfigurationTests.oghamAloneShouldUseOghamProperties(oghamspringbootv1autoconfigure.it.OghamSpringBoot1JavaMailAutoConfigurationTests)
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → KILLED

4.4
Location : maxRetries
Killed by : oghamcloudhopper.it.AutoRetryExtensionTest.smsNotRetriedDueToCloudhopperError(oghamcloudhopper.it.AutoRetryExtensionTest)
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → KILLED

5.5
Location : maxRetries
Killed by : oghamall.it.html.translator.JsoupInlineCssTranslatorTest.notHtml(oghamall.it.html.translator.JsoupInlineCssTranslatorTest)
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → KILLED

6.6
Location : maxRetries
Killed by : oghamsmsglobal.it.SmsglobalServiceProviderConfigurerSpec
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → KILLED

7.7
Location : maxRetries
Killed by : oghamjavamail.it.UnreadableAttachmentTest.attachmentUnreadable(oghamjavamail.it.UnreadableAttachmentTest)
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → KILLED

8.8
Location : maxRetries
Killed by : oghamcore.it.core.service.CleanupTest.manualCleanupShouldAutomaticallyCleanTheSenders(oghamcore.it.core.service.CleanupTest)
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::maxRetries → KILLED

204

1.1
Location : interval
Killed by : none
removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → NO_COVERAGE

2.2
Location : interval
Killed by : oghamcore.it.core.builder.retry.RetryBuilderSpec
removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → KILLED

205

1.1
Location : interval
Killed by : none
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → NO_COVERAGE

2.2
Location : interval
Killed by : oghamcore.it.core.builder.retry.RetryBuilderSpec
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → KILLED

245

1.1
Location : interval
Killed by : oghamcloudhopper.it.AutoRetryExtensionTest.smsNotRetriedDueToCloudhopperError(oghamcloudhopper.it.AutoRetryExtensionTest)
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → KILLED

2.2
Location : interval
Killed by : oghamjavamail.it.UnreadableAttachmentTest.attachmentUnreadable(oghamjavamail.it.UnreadableAttachmentTest)
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → KILLED

3.3
Location : interval
Killed by : oghamspringbootv2autoconfigure.it.OghamSpringBoot2JavaMailAutoConfigurationTests.oghamPropertiesWithSpringPropsShouldUseOghamPropertiesPrecedence(oghamspringbootv2autoconfigure.it.OghamSpringBoot2JavaMailAutoConfigurationTests)
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → KILLED

4.4
Location : interval
Killed by : oghamcore.it.core.service.CleanupTest.manualCleanupShouldAutomaticallyCleanTheSenders(oghamcore.it.core.service.CleanupTest)
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → KILLED

5.5
Location : interval
Killed by : oghamall.it.html.translator.JsoupInlineCssTranslatorTest.notHtml(oghamall.it.html.translator.JsoupInlineCssTranslatorTest)
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → KILLED

6.6
Location : interval
Killed by : none
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → NO_COVERAGE

7.7
Location : interval
Killed by : oghamsmsglobal.it.SmsglobalServiceProviderConfigurerSpec
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → KILLED

8.8
Location : interval
Killed by : oghamspringbootv1autoconfigure.it.OghamSpringBoot1JavaMailAutoConfigurationTests.oghamAloneShouldUseOghamProperties(oghamspringbootv1autoconfigure.it.OghamSpringBoot1JavaMailAutoConfigurationTests)
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::interval → KILLED

252

1.1
Location : build
Killed by : none
negated conditional → SURVIVED

2.2
Location : build
Killed by : none
negated conditional → NO_COVERAGE

3.3
Location : build
Killed by : oghamcore.it.core.builder.retry.RetryBuilderSpec
negated conditional → KILLED

4.4
Location : build
Killed by : none
negated conditional → SURVIVED

5.5
Location : build
Killed by : none
negated conditional → NO_COVERAGE

6.6
Location : build
Killed by : oghamcore.it.core.builder.retry.RetryBuilderSpec
negated conditional → KILLED

255

1.1
Location : build
Killed by : oghamcore.it.core.builder.retry.RetryBuilderSpec
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::build → KILLED

2.2
Location : build
Killed by : none
replaced return value with null for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::build → NO_COVERAGE

259

1.1
Location : buildMaxRetries
Killed by : oghamcore.it.core.builder.retry.RetryBuilderSpec
replaced int return with 0 for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::buildMaxRetries → KILLED

2.2
Location : buildMaxRetries
Killed by : none
replaced int return with 0 for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::buildMaxRetries → SURVIVED

3.3
Location : buildMaxRetries
Killed by : none
replaced int return with 0 for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::buildMaxRetries → NO_COVERAGE

263

1.1
Location : buildInterval
Killed by : none
replaced long return with 0 for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::buildInterval → SURVIVED

2.2
Location : buildInterval
Killed by : oghamcore.it.core.builder.retry.RetryBuilderSpec
replaced long return with 0 for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::buildInterval → KILLED

3.3
Location : buildInterval
Killed by : none
replaced long return with 0 for fr/sii/ogham/core/builder/retry/FixedIntervalBuilder::buildInterval → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT OGHAM