1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.accumulo.core.iterators.user;
18
19 import java.io.IOException;
20 import java.util.Map;
21
22 import org.apache.accumulo.core.Constants;
23 import org.apache.accumulo.core.client.IteratorSetting;
24 import org.apache.accumulo.core.data.Key;
25 import org.apache.accumulo.core.data.Value;
26 import org.apache.accumulo.core.iterators.IteratorEnvironment;
27 import org.apache.accumulo.core.iterators.OptionDescriber;
28 import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
29 import org.apache.accumulo.core.security.Authorizations;
30 import org.apache.accumulo.core.security.ColumnVisibility;
31 import org.apache.accumulo.core.security.VisibilityEvaluator;
32 import org.apache.accumulo.core.util.BadArgumentException;
33 import org.apache.commons.collections.map.LRUMap;
34 import org.apache.hadoop.io.Text;
35
36 /**
37 *
38 */
39 public class VisibilityFilter extends org.apache.accumulo.core.iterators.system.VisibilityFilter implements OptionDescriber {
40
41 private static final String AUTHS = "auths";
42 private static final String FILTER_INVALID_ONLY = "filterInvalid";
43
44 private boolean filterInvalid;
45
46 /**
47 *
48 */
49 public VisibilityFilter() {
50 super();
51 }
52
53 @Override
54 public void init(SortedKeyValueIterator<Key,Value> source, Map<String,String> options, IteratorEnvironment env) throws IOException {
55 super.init(source, options, env);
56 validateOptions(options);
57 this.filterInvalid = Boolean.parseBoolean(options.get(FILTER_INVALID_ONLY));
58
59 if (!filterInvalid) {
60 String auths = options.get(AUTHS);
61 Authorizations authObj = auths == null || auths.isEmpty() ? new Authorizations() : new Authorizations(auths.getBytes(Constants.UTF8));
62 this.ve = new VisibilityEvaluator(authObj);
63 this.defaultVisibility = new Text();
64 }
65 this.cache = new LRUMap(1000);
66 this.tmpVis = new Text();
67 }
68
69 @Override
70 public boolean accept(Key k, Value v) {
71 if (filterInvalid) {
72 Text testVis = k.getColumnVisibility(tmpVis);
73 Boolean b = (Boolean) cache.get(testVis);
74 if (b != null)
75 return b;
76 try {
77 new ColumnVisibility(testVis);
78 cache.put(new Text(testVis), true);
79 return true;
80 } catch (BadArgumentException e) {
81 cache.put(new Text(testVis), false);
82 return false;
83 }
84 } else {
85 return super.accept(k, v);
86 }
87 }
88
89 @Override
90 public IteratorOptions describeOptions() {
91 IteratorOptions io = super.describeOptions();
92 io.setName("visibilityFilter");
93 io.setDescription("The VisibilityFilter allows you to filter for key/value pairs by a set of authorizations or filter invalid labels from corrupt files.");
94 io.addNamedOption(FILTER_INVALID_ONLY,
95 "if 'true', the iterator is instructed to ignore the authorizations and only filter invalid visibility labels (default: false)");
96 io.addNamedOption(AUTHS, "the serialized set of authorizations to filter against (default: empty string, accepts only entries visible by all)");
97 return io;
98 }
99
100 @Override
101 public boolean validateOptions(Map<String,String> options) {
102
103 return super.validateOptions(options);
104 }
105
106 public static void setAuthorizations(IteratorSetting setting, Authorizations auths) {
107 setting.addOption(AUTHS, auths.serialize());
108 }
109
110 public static void filterInvalidLabelsOnly(IteratorSetting setting, boolean featureEnabled) {
111 setting.addOption(FILTER_INVALID_ONLY, Boolean.toString(featureEnabled));
112 }
113
114 }