1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.client.coprocessor;
20
21 import com.google.protobuf.ByteString;
22 import org.apache.hadoop.fs.Path;
23 import org.apache.hadoop.hbase.HConstants;
24 import org.apache.hadoop.hbase.client.HTable;
25 import org.apache.hadoop.hbase.ipc.BlockingRpcCallback;
26 import org.apache.hadoop.hbase.ipc.ServerRpcController;
27 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
28 import org.apache.hadoop.hbase.protobuf.generated.SecureBulkLoadProtos;
29 import org.apache.hadoop.hbase.security.SecureBulkLoadUtil;
30 import org.apache.hadoop.hbase.util.Pair;
31 import org.apache.hadoop.security.token.Token;
32
33 import java.io.IOException;
34 import java.util.ArrayList;
35 import java.util.List;
36
37
38
39
40
41 public class SecureBulkLoadClient {
42 private HTable table;
43
44 public SecureBulkLoadClient(HTable table) {
45 this.table = table;
46 }
47
48 public String prepareBulkLoad(final byte[] tableName) throws IOException {
49 try {
50 return
51 table.coprocessorService(SecureBulkLoadProtos.SecureBulkLoadService.class,
52 HConstants.EMPTY_START_ROW,
53 HConstants.EMPTY_START_ROW,
54 new Batch.Call<SecureBulkLoadProtos.SecureBulkLoadService,String>() {
55 @Override
56 public String call(SecureBulkLoadProtos.SecureBulkLoadService instance) throws IOException {
57 ServerRpcController controller = new ServerRpcController();
58
59 BlockingRpcCallback<SecureBulkLoadProtos.PrepareBulkLoadResponse> rpcCallback =
60 new BlockingRpcCallback<SecureBulkLoadProtos.PrepareBulkLoadResponse>();
61
62 SecureBulkLoadProtos.PrepareBulkLoadRequest request =
63 SecureBulkLoadProtos.PrepareBulkLoadRequest.newBuilder()
64 .setTableName(com.google.protobuf.ByteString.copyFrom(tableName)).build();
65
66 instance.prepareBulkLoad(controller,
67 request,
68 rpcCallback);
69
70 SecureBulkLoadProtos.PrepareBulkLoadResponse response = rpcCallback.get();
71 if (controller.failedOnException()) {
72 throw controller.getFailedOn();
73 }
74 return response.getBulkToken();
75 }
76 }).entrySet().iterator().next().getValue();
77 } catch (Throwable throwable) {
78 throw new IOException(throwable);
79 }
80 }
81
82 public void cleanupBulkLoad(final String bulkToken) throws IOException {
83 try {
84 table.coprocessorService(SecureBulkLoadProtos.SecureBulkLoadService.class,
85 HConstants.EMPTY_START_ROW,
86 HConstants.EMPTY_START_ROW,
87 new Batch.Call<SecureBulkLoadProtos.SecureBulkLoadService, String>() {
88
89 @Override
90 public String call(SecureBulkLoadProtos.SecureBulkLoadService instance) throws IOException {
91 ServerRpcController controller = new ServerRpcController();
92
93 BlockingRpcCallback<SecureBulkLoadProtos.CleanupBulkLoadResponse> rpcCallback =
94 new BlockingRpcCallback<SecureBulkLoadProtos.CleanupBulkLoadResponse>();
95
96 SecureBulkLoadProtos.CleanupBulkLoadRequest request =
97 SecureBulkLoadProtos.CleanupBulkLoadRequest.newBuilder()
98 .setBulkToken(bulkToken).build();
99
100 instance.cleanupBulkLoad(controller,
101 request,
102 rpcCallback);
103
104 if (controller.failedOnException()) {
105 throw controller.getFailedOn();
106 }
107 return null;
108 }
109 });
110 } catch (Throwable throwable) {
111 throw new IOException(throwable);
112 }
113 }
114
115 public boolean bulkLoadHFiles(final List<Pair<byte[], String>> familyPaths,
116 final Token<?> userToken,
117 final String bulkToken,
118 final byte[] startRow) throws IOException {
119 try {
120 return
121 table.coprocessorService(SecureBulkLoadProtos.SecureBulkLoadService.class,
122 startRow,
123 startRow,
124 new Batch.Call<SecureBulkLoadProtos.SecureBulkLoadService,Boolean>() {
125
126 @Override
127 public Boolean call(SecureBulkLoadProtos.SecureBulkLoadService instance) throws IOException {
128 SecureBulkLoadProtos.DelegationTokenProto protoDT =
129 SecureBulkLoadProtos.DelegationTokenProto.newBuilder().build();
130 if(userToken != null) {
131 protoDT =
132 SecureBulkLoadProtos.DelegationTokenProto.newBuilder()
133 .setIdentifier(ByteString.copyFrom(userToken.getIdentifier()))
134 .setPassword(ByteString.copyFrom(userToken.getPassword()))
135 .setKind(userToken.getKind().toString())
136 .setService(userToken.getService().toString()).build();
137 }
138
139 List<ClientProtos.BulkLoadHFileRequest.FamilyPath> protoFamilyPaths =
140 new ArrayList<ClientProtos.BulkLoadHFileRequest.FamilyPath>();
141 for(Pair<byte[], String> el: familyPaths) {
142 protoFamilyPaths.add(ClientProtos.BulkLoadHFileRequest.FamilyPath.newBuilder()
143 .setFamily(ByteString.copyFrom(el.getFirst()))
144 .setPath(el.getSecond()).build());
145 }
146
147 SecureBulkLoadProtos.SecureBulkLoadHFilesRequest request =
148 SecureBulkLoadProtos.SecureBulkLoadHFilesRequest.newBuilder()
149 .setFsToken(protoDT)
150 .addAllFamilyPath(protoFamilyPaths)
151 .setBulkToken(bulkToken).build();
152
153 ServerRpcController controller = new ServerRpcController();
154 BlockingRpcCallback<SecureBulkLoadProtos.SecureBulkLoadHFilesResponse> rpcCallback =
155 new BlockingRpcCallback<SecureBulkLoadProtos.SecureBulkLoadHFilesResponse>();
156 instance.secureBulkLoadHFiles(controller,
157 request,
158 rpcCallback);
159
160 SecureBulkLoadProtos.SecureBulkLoadHFilesResponse response = rpcCallback.get();
161 if (controller.failedOnException()) {
162 throw controller.getFailedOn();
163 }
164 return response.getLoaded();
165 }
166 }).entrySet().iterator().next().getValue();
167 } catch (Throwable throwable) {
168 throw new IOException(throwable);
169 }
170 }
171
172 public Path getStagingPath(String bulkToken, byte[] family) throws IOException {
173 return SecureBulkLoadUtil.getStagingPath(table.getConfiguration(), bulkToken, family);
174 }
175 }