|
10 | 10 | package org.elasticsearch.cluster.metadata; |
11 | 11 |
|
12 | 12 | import org.elasticsearch.ElasticsearchParseException; |
13 | | -import org.elasticsearch.action.support.IndicesOptions; |
14 | | -import org.elasticsearch.cluster.ClusterName; |
15 | | -import org.elasticsearch.cluster.ClusterState; |
16 | | -import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.Context; |
17 | 13 | import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.DateMathExpressionResolver; |
18 | | -import org.elasticsearch.indices.SystemIndices.SystemIndexAccessLevel; |
19 | 14 | import org.elasticsearch.test.ESTestCase; |
20 | | -import org.hamcrest.Matchers; |
21 | 15 |
|
22 | 16 | import java.time.Instant; |
23 | 17 | import java.time.ZoneId; |
24 | 18 | import java.time.ZoneOffset; |
25 | 19 | import java.time.ZonedDateTime; |
26 | 20 | import java.time.format.DateTimeFormatter; |
27 | | -import java.util.ArrayList; |
28 | | -import java.util.Arrays; |
29 | | -import java.util.Collections; |
30 | | -import java.util.List; |
31 | 21 | import java.util.Locale; |
| 22 | +import java.util.function.LongSupplier; |
32 | 23 |
|
33 | 24 | import static org.hamcrest.Matchers.containsString; |
34 | 25 | import static org.hamcrest.Matchers.equalTo; |
35 | 26 |
|
36 | 27 | public class DateMathExpressionResolverTests extends ESTestCase { |
37 | 28 |
|
38 | | - private final Context context = new Context( |
39 | | - ClusterState.builder(new ClusterName("_name")).build(), |
40 | | - IndicesOptions.strictExpand(), |
41 | | - SystemIndexAccessLevel.NONE |
42 | | - ); |
| 29 | + private final long now = randomMillisUpToYear9999(); |
| 30 | + private final LongSupplier getTime = () -> now; |
43 | 31 |
|
44 | | - private static ZonedDateTime dateFromMillis(long millis) { |
45 | | - return ZonedDateTime.ofInstant(Instant.ofEpochMilli(millis), ZoneOffset.UTC); |
46 | | - } |
| 32 | + public void testNoDateMathExpression() { |
| 33 | + String expression = randomAlphaOfLength(10); |
| 34 | + assertThat(DateMathExpressionResolver.resolveExpression(expression, getTime), equalTo(expression)); |
47 | 35 |
|
48 | | - private static String formatDate(String pattern, ZonedDateTime zonedDateTime) { |
49 | | - DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(pattern, Locale.ROOT); |
50 | | - return dateFormatter.format(zonedDateTime); |
| 36 | + expression = "*"; |
| 37 | + assertThat(DateMathExpressionResolver.resolveExpression(expression, getTime), equalTo(expression)); |
51 | 38 | } |
52 | 39 |
|
53 | | - public void testNormal() throws Exception { |
54 | | - int numIndexExpressions = randomIntBetween(1, 9); |
55 | | - List<String> indexExpressions = new ArrayList<>(numIndexExpressions); |
56 | | - for (int i = 0; i < numIndexExpressions; i++) { |
57 | | - indexExpressions.add(randomAlphaOfLength(10)); |
58 | | - } |
59 | | - List<String> result = DateMathExpressionResolver.resolve(context, indexExpressions); |
60 | | - assertThat(result.size(), equalTo(indexExpressions.size())); |
61 | | - for (int i = 0; i < indexExpressions.size(); i++) { |
62 | | - assertThat(result.get(i), equalTo(indexExpressions.get(i))); |
63 | | - } |
64 | | - } |
| 40 | + public void testExpression() { |
| 41 | + String result = DateMathExpressionResolver.resolveExpression("<.marvel-{now}>", getTime); |
| 42 | + assertThat(result, equalTo(".marvel-" + formatDate("uuuu.MM.dd", dateFromMillis(now)))); |
65 | 43 |
|
66 | | - public void testExpression() throws Exception { |
67 | | - List<String> indexExpressions = Arrays.asList("<.marvel-{now}>", "<.watch_history-{now}>", "<logstash-{now}>"); |
68 | | - List<String> result = DateMathExpressionResolver.resolve(context, indexExpressions); |
69 | | - assertThat(result.size(), equalTo(3)); |
70 | | - assertThat(result.get(0), equalTo(".marvel-" + formatDate("uuuu.MM.dd", dateFromMillis(context.getStartTime())))); |
71 | | - assertThat(result.get(1), equalTo(".watch_history-" + formatDate("uuuu.MM.dd", dateFromMillis(context.getStartTime())))); |
72 | | - assertThat(result.get(2), equalTo("logstash-" + formatDate("uuuu.MM.dd", dateFromMillis(context.getStartTime())))); |
| 44 | + result = DateMathExpressionResolver.resolveExpression("<.watch_history-{now}>", getTime); |
| 45 | + assertThat(result, equalTo(".watch_history-" + formatDate("uuuu.MM.dd", dateFromMillis(now)))); |
| 46 | + |
| 47 | + result = DateMathExpressionResolver.resolveExpression("<logstash-{now}>", getTime); |
| 48 | + assertThat(result, equalTo("logstash-" + formatDate("uuuu.MM.dd", dateFromMillis(now)))); |
73 | 49 | } |
74 | 50 |
|
75 | 51 | public void testExpressionWithWildcardAndExclusions() { |
76 | | - List<String> indexExpressions = Arrays.asList( |
77 | | - "<-before-inner-{now}>", |
78 | | - "-<before-outer-{now}>", |
79 | | - "<wild*card-{now}*>", |
80 | | - "<-after-inner-{now}>", |
81 | | - "-<after-outer-{now}>" |
82 | | - ); |
83 | | - List<String> result = DateMathExpressionResolver.resolve(context, indexExpressions); |
84 | | - assertThat( |
85 | | - result, |
86 | | - Matchers.contains( |
87 | | - equalTo("-before-inner-" + formatDate("uuuu.MM.dd", dateFromMillis(context.getStartTime()))), |
88 | | - equalTo("-<before-outer-{now}>"), // doesn't evaluate because it doesn't start with "<" and it is not an exclusion |
89 | | - equalTo("wild*card-" + formatDate("uuuu.MM.dd", dateFromMillis(context.getStartTime())) + "*"), |
90 | | - equalTo("-after-inner-" + formatDate("uuuu.MM.dd", dateFromMillis(context.getStartTime()))), |
91 | | - equalTo("-after-outer-" + formatDate("uuuu.MM.dd", dateFromMillis(context.getStartTime()))) |
92 | | - ) |
93 | | - ); |
94 | | - Context noWildcardExpandContext = new Context( |
95 | | - ClusterState.builder(new ClusterName("_name")).build(), |
96 | | - IndicesOptions.strictSingleIndexNoExpandForbidClosed(), |
97 | | - SystemIndexAccessLevel.NONE |
98 | | - ); |
99 | | - result = DateMathExpressionResolver.resolve(noWildcardExpandContext, indexExpressions); |
100 | | - assertThat( |
101 | | - result, |
102 | | - Matchers.contains( |
103 | | - equalTo("-before-inner-" + formatDate("uuuu.MM.dd", dateFromMillis(context.getStartTime()))), |
104 | | - // doesn't evaluate because it doesn't start with "<" and there can't be exclusions without wildcard expansion |
105 | | - equalTo("-<before-outer-{now}>"), |
106 | | - equalTo("wild*card-" + formatDate("uuuu.MM.dd", dateFromMillis(context.getStartTime())) + "*"), |
107 | | - equalTo("-after-inner-" + formatDate("uuuu.MM.dd", dateFromMillis(context.getStartTime()))), |
108 | | - // doesn't evaluate because it doesn't start with "<" and there can't be exclusions without wildcard expansion |
109 | | - equalTo("-<after-outer-{now}>") |
110 | | - ) |
111 | | - ); |
112 | | - } |
| 52 | + String result = DateMathExpressionResolver.resolveExpression("<-before-inner-{now}>", getTime); |
| 53 | + assertThat(result, equalTo("-before-inner-" + formatDate("uuuu.MM.dd", dateFromMillis(now)))); |
| 54 | + |
| 55 | + result = DateMathExpressionResolver.resolveExpression("<wild*card-{now}*>", getTime); |
| 56 | + assertThat(result, equalTo("wild*card-" + formatDate("uuuu.MM.dd", dateFromMillis(now)) + "*")); |
| 57 | + |
| 58 | + result = DateMathExpressionResolver.resolveExpression("<-after-inner-{now}>", getTime); |
| 59 | + assertThat(result, equalTo("-after-inner-" + formatDate("uuuu.MM.dd", dateFromMillis(now)))); |
113 | 60 |
|
114 | | - public void testEmpty() throws Exception { |
115 | | - List<String> result = DateMathExpressionResolver.resolve(context, Collections.<String>emptyList()); |
116 | | - assertThat(result.size(), equalTo(0)); |
117 | 61 | } |
118 | 62 |
|
119 | | - public void testExpression_Static() throws Exception { |
120 | | - List<String> result = DateMathExpressionResolver.resolve(context, Arrays.asList("<.marvel-test>")); |
121 | | - assertThat(result.size(), equalTo(1)); |
122 | | - assertThat(result.get(0), equalTo(".marvel-test")); |
| 63 | + public void testExpression_Static() { |
| 64 | + String result = DateMathExpressionResolver.resolveExpression("<.marvel-test>", getTime); |
| 65 | + assertThat(result, equalTo(".marvel-test")); |
123 | 66 | } |
124 | 67 |
|
125 | | - public void testExpression_MultiParts() throws Exception { |
126 | | - List<String> result = DateMathExpressionResolver.resolve(context, Arrays.asList("<.text1-{now/d}-text2-{now/M}>")); |
127 | | - assertThat(result.size(), equalTo(1)); |
| 68 | + public void testExpression_MultiParts() { |
| 69 | + String result = DateMathExpressionResolver.resolveExpression("<.text1-{now/d}-text2-{now/M}>", getTime); |
128 | 70 | assertThat( |
129 | | - result.get(0), |
| 71 | + result, |
130 | 72 | equalTo( |
131 | 73 | ".text1-" |
132 | | - + formatDate("uuuu.MM.dd", dateFromMillis(context.getStartTime())) |
| 74 | + + formatDate("uuuu.MM.dd", dateFromMillis(now)) |
133 | 75 | + "-text2-" |
134 | | - + formatDate("uuuu.MM.dd", dateFromMillis(context.getStartTime()).withDayOfMonth(1)) |
| 76 | + + formatDate("uuuu.MM.dd", dateFromMillis(now).withDayOfMonth(1)) |
135 | 77 | ) |
136 | 78 | ); |
137 | 79 | } |
138 | 80 |
|
139 | | - public void testExpression_CustomFormat() throws Exception { |
140 | | - List<String> results = DateMathExpressionResolver.resolve(context, Arrays.asList("<.marvel-{now/d{yyyy.MM.dd}}>")); |
141 | | - assertThat(results.size(), equalTo(1)); |
142 | | - assertThat(results.get(0), equalTo(".marvel-" + formatDate("uuuu.MM.dd", dateFromMillis(context.getStartTime())))); |
143 | | - } |
144 | | - |
145 | | - public void testExpression_EscapeStatic() throws Exception { |
146 | | - List<String> result = DateMathExpressionResolver.resolve(context, Arrays.asList("<.mar\\{v\\}el-{now/d}>")); |
147 | | - assertThat(result.size(), equalTo(1)); |
148 | | - assertThat(result.get(0), equalTo(".mar{v}el-" + formatDate("uuuu.MM.dd", dateFromMillis(context.getStartTime())))); |
| 81 | + public void testExpression_CustomFormat() { |
| 82 | + String result = DateMathExpressionResolver.resolveExpression("<.marvel-{now/d{yyyy.MM.dd}}>", getTime); |
| 83 | + assertThat(result, equalTo(".marvel-" + formatDate("uuuu.MM.dd", dateFromMillis(now)))); |
149 | 84 | } |
150 | 85 |
|
151 | | - public void testExpression_EscapeDateFormat() throws Exception { |
152 | | - List<String> result = DateMathExpressionResolver.resolve(context, Arrays.asList("<.marvel-{now/d{'\\{year\\}'yyyy}}>")); |
153 | | - assertThat(result.size(), equalTo(1)); |
154 | | - assertThat(result.get(0), equalTo(".marvel-" + formatDate("'{year}'yyyy", dateFromMillis(context.getStartTime())))); |
| 86 | + public void testExpression_EscapeStatic() { |
| 87 | + String result = DateMathExpressionResolver.resolveExpression("<.mar\\{v\\}el-{now/d}>", getTime); |
| 88 | + assertThat(result, equalTo(".mar{v}el-" + formatDate("uuuu.MM.dd", dateFromMillis(now)))); |
155 | 89 | } |
156 | 90 |
|
157 | | - public void testExpression_MixedArray() throws Exception { |
158 | | - List<String> result = DateMathExpressionResolver.resolve( |
159 | | - context, |
160 | | - Arrays.asList("name1", "<.marvel-{now/d}>", "name2", "<.logstash-{now/M{uuuu.MM}}>") |
161 | | - ); |
162 | | - assertThat(result.size(), equalTo(4)); |
163 | | - assertThat(result.get(0), equalTo("name1")); |
164 | | - assertThat(result.get(1), equalTo(".marvel-" + formatDate("uuuu.MM.dd", dateFromMillis(context.getStartTime())))); |
165 | | - assertThat(result.get(2), equalTo("name2")); |
166 | | - assertThat(result.get(3), equalTo(".logstash-" + formatDate("uuuu.MM", dateFromMillis(context.getStartTime()).withDayOfMonth(1)))); |
| 91 | + public void testExpression_EscapeDateFormat() { |
| 92 | + String result = DateMathExpressionResolver.resolveExpression("<.marvel-{now/d{'\\{year\\}'yyyy}}>", getTime); |
| 93 | + assertThat(result, equalTo(".marvel-" + formatDate("'{year}'yyyy", dateFromMillis(now)))); |
167 | 94 | } |
168 | 95 |
|
169 | | - public void testExpression_CustomTimeZoneInIndexName() throws Exception { |
| 96 | + public void testExpression_CustomTimeZoneInIndexName() { |
170 | 97 | ZoneId timeZone; |
171 | 98 | int hoursOffset; |
172 | 99 | int minutesOffset = 0; |
@@ -194,57 +121,57 @@ public void testExpression_CustomTimeZoneInIndexName() throws Exception { |
194 | 121 | // rounding to today 00:00 |
195 | 122 | now = ZonedDateTime.now(ZoneOffset.UTC).withHour(0).withMinute(0).withSecond(0); |
196 | 123 | } |
197 | | - Context context = new Context( |
198 | | - this.context.getState(), |
199 | | - this.context.getOptions(), |
200 | | - now.toInstant().toEpochMilli(), |
201 | | - SystemIndexAccessLevel.NONE, |
202 | | - name -> false, |
203 | | - name -> false |
204 | | - ); |
205 | | - List<String> results = DateMathExpressionResolver.resolve( |
206 | | - context, |
207 | | - Arrays.asList("<.marvel-{now/d{yyyy.MM.dd|" + timeZone.getId() + "}}>") |
| 124 | + |
| 125 | + String result = DateMathExpressionResolver.resolveExpression( |
| 126 | + "<.marvel-{now/d{yyyy.MM.dd|" + timeZone.getId() + "}}>", |
| 127 | + () -> now.toInstant().toEpochMilli() |
208 | 128 | ); |
209 | | - assertThat(results.size(), equalTo(1)); |
210 | | - logger.info("timezone: [{}], now [{}], name: [{}]", timeZone, now, results.get(0)); |
211 | | - assertThat(results.get(0), equalTo(".marvel-" + formatDate("uuuu.MM.dd", now.withZoneSameInstant(timeZone)))); |
| 129 | + logger.info("timezone: [{}], now [{}], name: [{}]", timeZone, now, result); |
| 130 | + assertThat(result, equalTo(".marvel-" + formatDate("uuuu.MM.dd", now.withZoneSameInstant(timeZone)))); |
212 | 131 | } |
213 | 132 |
|
214 | | - public void testExpressionInvalidUnescaped() throws Exception { |
| 133 | + public void testExpressionInvalidUnescaped() { |
215 | 134 | Exception e = expectThrows( |
216 | 135 | ElasticsearchParseException.class, |
217 | | - () -> DateMathExpressionResolver.resolve(context, Arrays.asList("<.mar}vel-{now/d}>")) |
| 136 | + () -> DateMathExpressionResolver.resolveExpression("<.mar}vel-{now/d}>", getTime) |
218 | 137 | ); |
219 | 138 | assertThat(e.getMessage(), containsString("invalid dynamic name expression")); |
220 | 139 | assertThat(e.getMessage(), containsString("invalid character at position [")); |
221 | 140 | } |
222 | 141 |
|
223 | | - public void testExpressionInvalidDateMathFormat() throws Exception { |
| 142 | + public void testExpressionInvalidDateMathFormat() { |
224 | 143 | Exception e = expectThrows( |
225 | 144 | ElasticsearchParseException.class, |
226 | | - () -> DateMathExpressionResolver.resolve(context, Arrays.asList("<.marvel-{now/d{}>")) |
| 145 | + () -> DateMathExpressionResolver.resolveExpression("<.marvel-{now/d{}>", getTime) |
227 | 146 | ); |
228 | 147 | assertThat(e.getMessage(), containsString("invalid dynamic name expression")); |
229 | 148 | assertThat(e.getMessage(), containsString("date math placeholder is open ended")); |
230 | 149 | } |
231 | 150 |
|
232 | | - public void testExpressionInvalidEmptyDateMathFormat() throws Exception { |
| 151 | + public void testExpressionInvalidEmptyDateMathFormat() { |
233 | 152 | Exception e = expectThrows( |
234 | 153 | ElasticsearchParseException.class, |
235 | | - () -> DateMathExpressionResolver.resolve(context, Arrays.asList("<.marvel-{now/d{}}>")) |
| 154 | + () -> DateMathExpressionResolver.resolveExpression("<.marvel-{now/d{}}>", getTime) |
236 | 155 | ); |
237 | 156 | assertThat(e.getMessage(), containsString("invalid dynamic name expression")); |
238 | 157 | assertThat(e.getMessage(), containsString("missing date format")); |
239 | 158 | } |
240 | 159 |
|
241 | | - public void testExpressionInvalidOpenEnded() throws Exception { |
| 160 | + public void testExpressionInvalidOpenEnded() { |
242 | 161 | Exception e = expectThrows( |
243 | 162 | ElasticsearchParseException.class, |
244 | | - () -> DateMathExpressionResolver.resolve(context, Arrays.asList("<.marvel-{now/d>")) |
| 163 | + () -> DateMathExpressionResolver.resolveExpression("<.marvel-{now/d>", getTime) |
245 | 164 | ); |
246 | 165 | assertThat(e.getMessage(), containsString("invalid dynamic name expression")); |
247 | 166 | assertThat(e.getMessage(), containsString("date math placeholder is open ended")); |
248 | 167 | } |
249 | 168 |
|
| 169 | + static ZonedDateTime dateFromMillis(long millis) { |
| 170 | + return ZonedDateTime.ofInstant(Instant.ofEpochMilli(millis), ZoneOffset.UTC); |
| 171 | + } |
| 172 | + |
| 173 | + static String formatDate(String pattern, ZonedDateTime zonedDateTime) { |
| 174 | + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(pattern, Locale.ROOT); |
| 175 | + return dateFormatter.format(zonedDateTime); |
| 176 | + } |
250 | 177 | } |
0 commit comments