1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.security.visibility;
19
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.List;
23 import java.util.UUID;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.hadoop.hbase.Cell;
28 import org.apache.hadoop.hbase.Tag;
29 import org.apache.hadoop.hbase.TagRewriteCell;
30 import org.apache.hadoop.hbase.TagType;
31 import org.apache.hadoop.hbase.classification.InterfaceAudience;
32 import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
33 import org.apache.hadoop.hbase.replication.ReplicationEndpoint;
34 import org.apache.hadoop.hbase.replication.WALEntryFilter;
35 import org.apache.hadoop.hbase.wal.WAL.Entry;
36
37 import com.google.common.util.concurrent.ListenableFuture;
38
39 @InterfaceAudience.Private
40 public class VisibilityReplicationEndpoint implements ReplicationEndpoint {
41
42 private static final Log LOG = LogFactory.getLog(VisibilityReplicationEndpoint.class);
43 private ReplicationEndpoint delegator;
44 private VisibilityLabelService visibilityLabelsService;
45
46 public VisibilityReplicationEndpoint(ReplicationEndpoint endpoint,
47 VisibilityLabelService visibilityLabelsService) {
48 this.delegator = endpoint;
49 this.visibilityLabelsService = visibilityLabelsService;
50 }
51
52 @Override
53 public void init(Context context) throws IOException {
54 delegator.init(context);
55 }
56
57 @Override
58 public boolean replicate(ReplicateContext replicateContext) {
59 if (!delegator.canReplicateToSameCluster()) {
60
61
62 List<Entry> entries = replicateContext.getEntries();
63 List<Tag> visTags = new ArrayList<Tag>();
64 List<Tag> nonVisTags = new ArrayList<Tag>();
65 List<Entry> newEntries = new ArrayList<Entry>(entries.size());
66 for (Entry entry : entries) {
67 WALEdit newEdit = new WALEdit();
68 ArrayList<Cell> cells = entry.getEdit().getCells();
69 for (Cell cell : cells) {
70 if (cell.getTagsLength() > 0) {
71 visTags.clear();
72 nonVisTags.clear();
73 Byte serializationFormat = VisibilityUtils.extractAndPartitionTags(cell, visTags,
74 nonVisTags);
75 if (!visTags.isEmpty()) {
76 try {
77 byte[] modifiedVisExpression = visibilityLabelsService
78 .encodeVisibilityForReplication(visTags, serializationFormat);
79 if (modifiedVisExpression != null) {
80 nonVisTags.add(new Tag(TagType.STRING_VIS_TAG_TYPE, modifiedVisExpression));
81 }
82 } catch (Exception ioe) {
83 LOG.error(
84 "Exception while reading the visibility labels from the cell. The replication "
85 + "would happen as per the existing format and not as string type for the cell "
86 + cell + ".", ioe);
87
88 newEdit.add(cell);
89 continue;
90 }
91
92 Cell newCell = new TagRewriteCell(cell, Tag.fromList(nonVisTags));
93 newEdit.add(newCell);
94 } else {
95 newEdit.add(cell);
96 }
97 } else {
98 newEdit.add(cell);
99 }
100 }
101 newEntries.add(new Entry(entry.getKey(), newEdit));
102 }
103 replicateContext.setEntries(newEntries);
104 return delegator.replicate(replicateContext);
105 } else {
106 return delegator.replicate(replicateContext);
107 }
108 }
109
110 @Override
111 public synchronized UUID getPeerUUID() {
112 return delegator.getPeerUUID();
113 }
114
115 @Override
116 public boolean canReplicateToSameCluster() {
117 return delegator.canReplicateToSameCluster();
118 }
119
120 @Override
121 public WALEntryFilter getWALEntryfilter() {
122 return delegator.getWALEntryfilter();
123 }
124
125 @Override
126 public boolean isRunning() {
127 return delegator.isRunning();
128 }
129
130 @Override
131 public ListenableFuture<State> start() {
132 return delegator.start();
133 }
134
135 @Override
136 public State startAndWait() {
137 return delegator.startAndWait();
138 }
139
140 @Override
141 public State state() {
142 return delegator.state();
143 }
144
145 @Override
146 public ListenableFuture<State> stop() {
147 return delegator.stop();
148 }
149
150 @Override
151 public State stopAndWait() {
152 return delegator.stopAndWait();
153 }
154
155 }