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