|
21 | 21 | import static org.apache.accumulo.harness.AccumuloITBase.SUNNY_DAY; |
22 | 22 | import static org.junit.jupiter.api.Assertions.assertEquals; |
23 | 23 |
|
| 24 | +import java.io.IOException; |
24 | 25 | import java.time.Duration; |
25 | 26 | import java.util.ArrayList; |
26 | 27 | import java.util.Collections; |
| 28 | +import java.util.EnumSet; |
27 | 29 | import java.util.HashSet; |
28 | 30 | import java.util.Map; |
29 | 31 | import java.util.Map.Entry; |
| 32 | +import java.util.Objects; |
30 | 33 |
|
31 | 34 | import org.apache.accumulo.cluster.ClusterUser; |
32 | 35 | import org.apache.accumulo.core.client.Accumulo; |
|
38 | 41 | import org.apache.accumulo.core.client.Scanner; |
39 | 42 | import org.apache.accumulo.core.client.ScannerBase; |
40 | 43 | import org.apache.accumulo.core.client.TableNotFoundException; |
| 44 | +import org.apache.accumulo.core.client.admin.CompactionConfig; |
| 45 | +import org.apache.accumulo.core.client.admin.NewTableConfiguration; |
41 | 46 | import org.apache.accumulo.core.client.security.tokens.PasswordToken; |
42 | 47 | import org.apache.accumulo.core.data.Key; |
43 | 48 | import org.apache.accumulo.core.data.Mutation; |
44 | 49 | import org.apache.accumulo.core.data.Range; |
45 | 50 | import org.apache.accumulo.core.data.Value; |
| 51 | +import org.apache.accumulo.core.iterators.IteratorEnvironment; |
| 52 | +import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope; |
| 53 | +import org.apache.accumulo.core.iterators.SortedKeyValueIterator; |
| 54 | +import org.apache.accumulo.core.iterators.WrappingIterator; |
46 | 55 | import org.apache.accumulo.core.security.Authorizations; |
47 | 56 | import org.apache.accumulo.core.security.TablePermission; |
48 | 57 | import org.apache.accumulo.harness.AccumuloClusterHarness; |
@@ -250,4 +259,62 @@ private void writeTestMutation(AccumuloClient userC) |
250 | 259 | batchWriter.flush(); |
251 | 260 | } |
252 | 261 | } |
| 262 | + |
| 263 | + public static class AppendingIterator extends WrappingIterator { |
| 264 | + |
| 265 | + private String append; |
| 266 | + |
| 267 | + @Override |
| 268 | + public void init(SortedKeyValueIterator<Key,Value> source, Map<String,String> options, |
| 269 | + IteratorEnvironment env) throws IOException { |
| 270 | + super.init(source, options, env); |
| 271 | + append = Objects.requireNonNull(options.get("append")); |
| 272 | + } |
| 273 | + |
| 274 | + @Override |
| 275 | + public Value getTopValue() { |
| 276 | + var val = super.getTopValue(); |
| 277 | + return new Value(val.toString() + append); |
| 278 | + } |
| 279 | + |
| 280 | + public static IteratorSetting configure(int prio, String append) { |
| 281 | + IteratorSetting iter = new IteratorSetting(prio, "append_" + append, AppendingIterator.class); |
| 282 | + iter.addOption("append", append); |
| 283 | + return iter; |
| 284 | + } |
| 285 | + } |
| 286 | + |
| 287 | + // Ensures scan iterators run in the expected order |
| 288 | + @Test |
| 289 | + public void testIteratorOrder() throws Exception { |
| 290 | + |
| 291 | + String tableName = getUniqueNames(2)[1]; |
| 292 | + try (AccumuloClient c = Accumulo.newClient().from(getClientProps()).build()) { |
| 293 | + var scopes = EnumSet.of(IteratorScope.scan); |
| 294 | + NewTableConfiguration ntc = |
| 295 | + new NewTableConfiguration().attachIterator(AppendingIterator.configure(50, "x"), scopes) |
| 296 | + .attachIterator(AppendingIterator.configure(100, "a"), scopes); |
| 297 | + c.tableOperations().create(tableName, ntc); |
| 298 | + |
| 299 | + try (var writer = c.createBatchWriter(tableName)) { |
| 300 | + Mutation m = new Mutation("r1"); |
| 301 | + m.put("", "", "base:"); |
| 302 | + writer.addMutation(m); |
| 303 | + } |
| 304 | + |
| 305 | + try (var scanner = c.createScanner(tableName)) { |
| 306 | + assertEquals("base:xa", scanner.iterator().next().getValue().toString()); |
| 307 | + scanner.addScanIterator(AppendingIterator.configure(70, "m")); |
| 308 | + assertEquals("base:xma", scanner.iterator().next().getValue().toString()); |
| 309 | + // These have the same priority as a table iterator so the iterators should be ordered by |
| 310 | + // their name in that case |
| 311 | + scanner.addScanIterator(AppendingIterator.configure(50, "b")); |
| 312 | + scanner.addScanIterator(AppendingIterator.configure(100, "c")); |
| 313 | + assertEquals("base:bxmac", scanner.iterator().next().getValue().toString()); |
| 314 | + // There are no compaction iterators, so this should not change value |
| 315 | + c.tableOperations().compact(tableName, new CompactionConfig().setWait(true)); |
| 316 | + assertEquals("base:bxmac", scanner.iterator().next().getValue().toString()); |
| 317 | + } |
| 318 | + } |
| 319 | + } |
253 | 320 | } |
0 commit comments