0
# Duration Validation
1
2
Specialized validation annotations and validators for Dropwizard Duration objects, supporting minimum, maximum, and range constraints with configurable time units. These annotations work specifically with `io.dropwizard.util.Duration` instances and provide flexible time-based validation.
3
4
## Capabilities
5
6
### Duration Range Validation
7
8
Validates that a Duration falls within a specified range, combining minimum and maximum constraints.
9
10
```java { .api }
11
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
12
@Retention(RUNTIME)
13
@Constraint(validatedBy = {})
14
@MinDuration(0)
15
@MaxDuration(value = Long.MAX_VALUE, unit = TimeUnit.DAYS)
16
@ReportAsSingleViolation
17
public @interface DurationRange {
18
/**
19
* The minimum value of the range the validated Duration must be in.
20
*
21
* @return the minimum value
22
*/
23
long min() default 0;
24
25
/**
26
* The maximum value of the range the validated Duration must be in.
27
*
28
* @return the maximum value
29
*/
30
long max() default Long.MAX_VALUE;
31
32
/**
33
* The unit of the validated range.
34
*
35
* @return the TimeUnit
36
*/
37
TimeUnit unit() default TimeUnit.SECONDS;
38
39
/**
40
* The validation message for this constraint.
41
*
42
* @return the message
43
*/
44
String message() default "must be between {min} {unit} and {max} {unit}";
45
46
/**
47
* The groups the constraint belongs to.
48
*
49
* @return an array of classes representing the groups
50
*/
51
Class<?>[] groups() default {};
52
53
/**
54
* The payloads of this constraint.
55
*
56
* @return the array of payload classes
57
*/
58
Class<? extends Payload>[] payload() default {};
59
60
/**
61
* Defines several @DurationRange annotations on the same element.
62
*/
63
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
64
@Retention(RUNTIME)
65
@Documented
66
@interface List {
67
DurationRange[] value();
68
}
69
}
70
```
71
72
**Usage Example:**
73
74
```java
75
import io.dropwizard.validation.DurationRange;
76
import io.dropwizard.util.Duration;
77
import java.util.concurrent.TimeUnit;
78
79
public class ServiceConfig {
80
// Connection timeout between 1 and 30 seconds
81
@DurationRange(min = 1, max = 30, unit = TimeUnit.SECONDS)
82
private Duration connectionTimeout;
83
84
// Retry delay between 100ms and 5 seconds
85
@DurationRange(min = 100, max = 5000, unit = TimeUnit.MILLISECONDS)
86
private Duration retryDelay;
87
88
// Session timeout between 1 minute and 24 hours
89
@DurationRange(min = 1, max = 24, unit = TimeUnit.HOURS)
90
private Duration sessionTimeout;
91
}
92
```
93
94
### Minimum Duration Validation
95
96
Validates that a Duration meets or exceeds a minimum threshold.
97
98
```java { .api }
99
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
100
@Retention(RUNTIME)
101
@Constraint(validatedBy = MinDurationValidator.class)
102
public @interface MinDuration {
103
/**
104
* The annotation's value.
105
*
106
* @return value the element must be higher or equal to
107
*/
108
long value();
109
110
/**
111
* The unit of the annotation.
112
*
113
* @return unit of the value the element must be higher or equal to
114
*/
115
TimeUnit unit() default TimeUnit.SECONDS;
116
117
/**
118
* If the boundary value is inclusive or not.
119
*
120
* @return true if the validation is to allow values equal to value().
121
* False if the validation is to be exclusive.
122
* Defaults to true.
123
*/
124
boolean inclusive() default true;
125
126
/**
127
* The validation message for this constraint.
128
*
129
* @return the message
130
*/
131
String message() default "must be greater than ${inclusive == true ? 'or equal to ' : ''}{value} {unit}";
132
133
/**
134
* The groups the constraint belongs to.
135
*
136
* @return an array of classes representing the groups
137
*/
138
Class<?>[] groups() default {};
139
140
/**
141
* The payloads of this constraint.
142
*
143
* @return the array of payload classes
144
*/
145
Class<? extends Payload>[] payload() default {};
146
}
147
```
148
149
**Usage Example:**
150
151
```java
152
import io.dropwizard.validation.MinDuration;
153
import io.dropwizard.util.Duration;
154
import java.util.concurrent.TimeUnit;
155
156
public class DatabaseConfig {
157
// Connection timeout must be at least 5 seconds
158
@MinDuration(value = 5, unit = TimeUnit.SECONDS)
159
private Duration connectionTimeout;
160
161
// Query timeout must be greater than 100ms (exclusive)
162
@MinDuration(value = 100, unit = TimeUnit.MILLISECONDS, inclusive = false)
163
private Duration queryTimeout;
164
165
// Health check interval must be at least 30 seconds
166
@MinDuration(value = 30, unit = TimeUnit.SECONDS)
167
private Duration healthCheckInterval;
168
}
169
```
170
171
### Maximum Duration Validation
172
173
Validates that a Duration does not exceed a maximum threshold.
174
175
```java { .api }
176
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
177
@Retention(RUNTIME)
178
@Constraint(validatedBy = MaxDurationValidator.class)
179
public @interface MaxDuration {
180
/**
181
* The annotation's value.
182
*
183
* @return value the element must be less than or equal to
184
*/
185
long value();
186
187
/**
188
* The unit of the annotation.
189
*
190
* @return unit of the value the element must be higher or equal to
191
*/
192
TimeUnit unit() default TimeUnit.SECONDS;
193
194
/**
195
* If the boundary value is inclusive or not.
196
*
197
* @return true if the validation is to allow values equal to value().
198
* False if the validation is to be exclusive.
199
* Defaults to true.
200
*/
201
boolean inclusive() default true;
202
203
/**
204
* The validation message for this constraint.
205
*
206
* @return the message
207
*/
208
String message() default "must be less than ${inclusive == true ? 'or equal to ' : ''}{value} {unit}";
209
210
/**
211
* The groups the constraint belongs to.
212
*
213
* @return an array of classes representing the groups
214
*/
215
Class<?>[] groups() default {};
216
217
/**
218
* The payloads of this constraint.
219
*
220
* @return the array of payload classes
221
*/
222
Class<? extends Payload>[] payload() default {};
223
}
224
```
225
226
**Usage Example:**
227
228
```java
229
import io.dropwizard.validation.MaxDuration;
230
import io.dropwizard.util.Duration;
231
import java.util.concurrent.TimeUnit;
232
233
public class RequestConfig {
234
// Request timeout cannot exceed 60 seconds
235
@MaxDuration(value = 60, unit = TimeUnit.SECONDS)
236
private Duration requestTimeout;
237
238
// Cache TTL must be less than 1 day (exclusive)
239
@MaxDuration(value = 1, unit = TimeUnit.DAYS, inclusive = false)
240
private Duration cacheTtl;
241
242
// Lock timeout cannot exceed 10 minutes
243
@MaxDuration(value = 10, unit = TimeUnit.MINUTES)
244
private Duration lockTimeout;
245
}
246
```
247
248
## Advanced Usage
249
250
### Combining Multiple Duration Constraints
251
252
```java
253
import io.dropwizard.validation.*;
254
import io.dropwizard.util.Duration;
255
import java.util.concurrent.TimeUnit;
256
257
public class AdvancedConfig {
258
// Multiple constraints on the same field
259
@MinDuration(value = 1, unit = TimeUnit.SECONDS)
260
@MaxDuration(value = 300, unit = TimeUnit.SECONDS)
261
private Duration operationTimeout;
262
263
// Using DurationRange is equivalent and more concise
264
@DurationRange(min = 1, max = 300, unit = TimeUnit.SECONDS)
265
private Duration alternativeTimeout;
266
267
// Complex validation with custom message
268
@DurationRange(
269
min = 500,
270
max = 30000,
271
unit = TimeUnit.MILLISECONDS,
272
message = "Response timeout must be between 500ms and 30 seconds"
273
)
274
private Duration responseTimeout;
275
}
276
```
277
278
### Validation Groups
279
280
```java
281
import io.dropwizard.validation.DurationRange;
282
import io.dropwizard.util.Duration;
283
import java.util.concurrent.TimeUnit;
284
285
public interface Development {}
286
public interface Production {}
287
288
public class EnvironmentConfig {
289
// Different constraints for different environments
290
@DurationRange(min = 1, max = 10, unit = TimeUnit.SECONDS, groups = Development.class)
291
@DurationRange(min = 5, max = 60, unit = TimeUnit.SECONDS, groups = Production.class)
292
private Duration timeout;
293
}
294
295
// Validate with specific group
296
Validator validator = BaseValidator.newValidator();
297
Set<ConstraintViolation<EnvironmentConfig>> violations =
298
validator.validate(config, Production.class);
299
```
300
301
## Integration Notes
302
303
- All duration validators work exclusively with `io.dropwizard.util.Duration` objects
304
- `null` values are considered valid (use `@NotNull` to reject null values)
305
- Validators handle all standard `TimeUnit` values (NANOSECONDS through DAYS)
306
- Duration constraints integrate seamlessly with Dropwizard configuration validation
307
- Use `@DurationRange` for most cases; use individual `@MinDuration`/`@MaxDuration` when you need different time units or inclusive/exclusive boundaries