View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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.TableName;
24  import org.apache.hadoop.hbase.HConstants;
25  import org.apache.hadoop.hbase.client.HTable;
26  import org.apache.hadoop.hbase.ipc.BlockingRpcCallback;
27  import org.apache.hadoop.hbase.ipc.ServerRpcController;
28  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
29  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
30  import org.apache.hadoop.hbase.protobuf.generated.SecureBulkLoadProtos;
31  import org.apache.hadoop.hbase.security.SecureBulkLoadUtil;
32  import org.apache.hadoop.hbase.util.Pair;
33  import org.apache.hadoop.security.token.Token;
34  
35  import java.io.IOException;
36  import java.util.ArrayList;
37  import java.util.List;
38  
39  /**
40   * Client proxy for SecureBulkLoadProtocol
41   * used in conjunction with SecureBulkLoadEndpoint
42   */
43  public class SecureBulkLoadClient {
44    private HTable table;
45  
46    public SecureBulkLoadClient(HTable table) {
47      this.table = table;
48    }
49  
50    public String prepareBulkLoad(final TableName tableName) throws IOException {
51      try {
52        return
53          table.coprocessorService(SecureBulkLoadProtos.SecureBulkLoadService.class,
54            HConstants.EMPTY_START_ROW,
55            HConstants.EMPTY_START_ROW,
56            new Batch.Call<SecureBulkLoadProtos.SecureBulkLoadService,String>() {
57              @Override
58              public String call(SecureBulkLoadProtos.SecureBulkLoadService instance) throws IOException {
59                ServerRpcController controller = new ServerRpcController();
60  
61                BlockingRpcCallback<SecureBulkLoadProtos.PrepareBulkLoadResponse> rpcCallback =
62                    new BlockingRpcCallback<SecureBulkLoadProtos.PrepareBulkLoadResponse>();
63  
64                SecureBulkLoadProtos.PrepareBulkLoadRequest request =
65                    SecureBulkLoadProtos.PrepareBulkLoadRequest.newBuilder()
66                    .setTableName(ProtobufUtil.toProtoTableName(tableName)).build();
67  
68                instance.prepareBulkLoad(controller,
69                    request,
70                    rpcCallback);
71  
72                SecureBulkLoadProtos.PrepareBulkLoadResponse response = rpcCallback.get();
73                if (controller.failedOnException()) {
74                  throw controller.getFailedOn();
75                }
76                return response.getBulkToken();
77              }
78            }).entrySet().iterator().next().getValue();
79      } catch (Throwable throwable) {
80        throw new IOException(throwable);
81      }
82    }
83  
84    public void cleanupBulkLoad(final String bulkToken) throws IOException {
85      try {
86          table.coprocessorService(SecureBulkLoadProtos.SecureBulkLoadService.class,
87              HConstants.EMPTY_START_ROW,
88              HConstants.EMPTY_START_ROW,
89              new Batch.Call<SecureBulkLoadProtos.SecureBulkLoadService, String>() {
90  
91                @Override
92                public String call(SecureBulkLoadProtos.SecureBulkLoadService instance) throws IOException {
93                  ServerRpcController controller = new ServerRpcController();
94  
95                  BlockingRpcCallback<SecureBulkLoadProtos.CleanupBulkLoadResponse> rpcCallback =
96                      new BlockingRpcCallback<SecureBulkLoadProtos.CleanupBulkLoadResponse>();
97  
98                  SecureBulkLoadProtos.CleanupBulkLoadRequest request =
99                      SecureBulkLoadProtos.CleanupBulkLoadRequest.newBuilder()
100                         .setBulkToken(bulkToken).build();
101 
102                 instance.cleanupBulkLoad(controller,
103                     request,
104                     rpcCallback);
105 
106                 if (controller.failedOnException()) {
107                   throw controller.getFailedOn();
108                 }
109                 return null;
110               }
111             });
112     } catch (Throwable throwable) {
113       throw new IOException(throwable);
114     }
115   }
116 
117   public boolean bulkLoadHFiles(final List<Pair<byte[], String>> familyPaths,
118                          final Token<?> userToken,
119                          final String bulkToken,
120                          final byte[] startRow) throws IOException {
121     try {
122       return
123         table.coprocessorService(SecureBulkLoadProtos.SecureBulkLoadService.class,
124           startRow,
125           startRow,
126           new Batch.Call<SecureBulkLoadProtos.SecureBulkLoadService,Boolean>() {
127 
128             @Override
129             public Boolean call(SecureBulkLoadProtos.SecureBulkLoadService instance) throws IOException {
130               SecureBulkLoadProtos.DelegationTokenProto protoDT =
131                   SecureBulkLoadProtos.DelegationTokenProto.newBuilder().build();
132               if(userToken != null) {
133                 protoDT =
134                   SecureBulkLoadProtos.DelegationTokenProto.newBuilder()
135                      .setIdentifier(ByteString.copyFrom(userToken.getIdentifier()))
136                      .setPassword(ByteString.copyFrom(userToken.getPassword()))
137                      .setKind(userToken.getKind().toString())
138                      .setService(userToken.getService().toString()).build();
139               }
140 
141               List<ClientProtos.BulkLoadHFileRequest.FamilyPath> protoFamilyPaths =
142                   new ArrayList<ClientProtos.BulkLoadHFileRequest.FamilyPath>();
143               for(Pair<byte[], String> el: familyPaths) {
144                 protoFamilyPaths.add(ClientProtos.BulkLoadHFileRequest.FamilyPath.newBuilder()
145                     .setFamily(ByteString.copyFrom(el.getFirst()))
146                     .setPath(el.getSecond()).build());
147               }
148 
149               SecureBulkLoadProtos.SecureBulkLoadHFilesRequest request =
150                   SecureBulkLoadProtos.SecureBulkLoadHFilesRequest.newBuilder()
151                       .setFsToken(protoDT)
152                       .addAllFamilyPath(protoFamilyPaths)
153                       .setBulkToken(bulkToken).build();
154 
155               ServerRpcController controller = new ServerRpcController();
156               BlockingRpcCallback<SecureBulkLoadProtos.SecureBulkLoadHFilesResponse> rpcCallback =
157                   new BlockingRpcCallback<SecureBulkLoadProtos.SecureBulkLoadHFilesResponse>();
158               instance.secureBulkLoadHFiles(controller,
159                   request,
160                   rpcCallback);
161 
162               SecureBulkLoadProtos.SecureBulkLoadHFilesResponse response = rpcCallback.get();
163               if (controller.failedOnException()) {
164                 throw controller.getFailedOn();
165               }
166               return response.getLoaded();
167             }
168           }).entrySet().iterator().next().getValue();
169     } catch (Throwable throwable) {
170       throw new IOException(throwable);
171     }
172   }
173 
174   public Path getStagingPath(String bulkToken, byte[] family) throws IOException {
175     return SecureBulkLoadUtil.getStagingPath(table.getConfiguration(), bulkToken, family);
176   }
177 }