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 org.apache.hadoop.hbase.client.Table;
22  import org.apache.hadoop.hbase.util.ByteStringer;
23  import java.io.IOException;
24  import java.util.ArrayList;
25  import java.util.List;
26  
27  import org.apache.hadoop.hbase.classification.InterfaceAudience;
28  import org.apache.hadoop.fs.Path;
29  import org.apache.hadoop.hbase.HConstants;
30  import org.apache.hadoop.hbase.TableName;
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   * Client proxy for SecureBulkLoadProtocol
47   * used in conjunction with SecureBulkLoadEndpoint
48   */
49  @InterfaceAudience.Private
50  public class SecureBulkLoadClient {
51    private Table table;
52  
53    public SecureBulkLoadClient(Table table) {
54      this.table = table;
55    }
56  
57    public String prepareBulkLoad(final TableName tableName) throws IOException {
58      try {
59        CoprocessorRpcChannel channel = table.coprocessorService(HConstants.EMPTY_START_ROW);
60        SecureBulkLoadProtos.SecureBulkLoadService instance =
61            ProtobufUtil.newServiceStub(SecureBulkLoadProtos.SecureBulkLoadService.class, channel);
62  
63        ServerRpcController controller = new ServerRpcController();
64  
65        BlockingRpcCallback<SecureBulkLoadProtos.PrepareBulkLoadResponse> rpcCallback =
66            new BlockingRpcCallback<SecureBulkLoadProtos.PrepareBulkLoadResponse>();
67  
68        SecureBulkLoadProtos.PrepareBulkLoadRequest request =
69            SecureBulkLoadProtos.PrepareBulkLoadRequest.newBuilder()
70            .setTableName(ProtobufUtil.toProtoTableName(tableName)).build();
71  
72        instance.prepareBulkLoad(controller,
73            request,
74            rpcCallback);
75  
76        SecureBulkLoadProtos.PrepareBulkLoadResponse response = rpcCallback.get();
77        if (controller.failedOnException()) {
78          throw controller.getFailedOn();
79        }
80  
81        return response.getBulkToken();
82      } catch (Throwable throwable) {
83        if (throwable instanceof IOException) {
84          throw (IOException) throwable;
85        }
86        throw new IOException(throwable);
87      }
88    }
89  
90    public void cleanupBulkLoad(final String bulkToken) throws IOException {
91      try {
92        CoprocessorRpcChannel channel = table.coprocessorService(HConstants.EMPTY_START_ROW);
93        SecureBulkLoadProtos.SecureBulkLoadService instance =
94            ProtobufUtil.newServiceStub(SecureBulkLoadProtos.SecureBulkLoadService.class, channel);
95  
96        ServerRpcController controller = new ServerRpcController();
97  
98        BlockingRpcCallback<SecureBulkLoadProtos.CleanupBulkLoadResponse> rpcCallback =
99            new BlockingRpcCallback<SecureBulkLoadProtos.CleanupBulkLoadResponse>();
100 
101       SecureBulkLoadProtos.CleanupBulkLoadRequest request =
102           SecureBulkLoadProtos.CleanupBulkLoadRequest.newBuilder()
103               .setBulkToken(bulkToken).build();
104 
105       instance.cleanupBulkLoad(controller,
106           request,
107           rpcCallback);
108 
109       if (controller.failedOnException()) {
110         throw controller.getFailedOn();
111       }
112     } catch (Throwable throwable) {
113       if (throwable instanceof IOException) {
114         throw (IOException) throwable;
115       }
116       throw new IOException(throwable);
117     }
118   }
119 
120   /**
121    * @deprecated
122    * @param familyPaths
123    * @param userToken
124    * @param bulkToken
125    * @param startRow
126    * @return
127    * @throws IOException
128    */
129   public boolean bulkLoadHFiles(final List<Pair<byte[], String>> familyPaths,
130     final Token<?> userToken, final String bulkToken,
131     final byte[] startRow) throws IOException {
132     return this.bulkLoadHFiles(familyPaths, userToken, bulkToken, startRow, null);
133   }
134 
135   public boolean bulkLoadHFiles(final List<Pair<byte[], String>> familyPaths,
136     final Token<?> userToken, final String bulkToken,
137     final byte[] startRow, List<String> clusterIds) throws IOException {
138     // we never want to send a batch of HFiles to all regions, thus cannot call
139     // HTable#coprocessorService methods that take start and end rowkeys; see HBASE-9639
140     try {
141       CoprocessorRpcChannel channel = table.coprocessorService(startRow);
142       SecureBulkLoadProtos.SecureBulkLoadService instance =
143           ProtobufUtil.newServiceStub(SecureBulkLoadProtos.SecureBulkLoadService.class, channel);
144 
145       SecureBulkLoadProtos.DelegationToken protoDT =
146           SecureBulkLoadProtos.DelegationToken.newBuilder().build();
147       if(userToken != null) {
148         protoDT =
149             SecureBulkLoadProtos.DelegationToken.newBuilder()
150               .setIdentifier(ByteStringer.wrap(userToken.getIdentifier()))
151               .setPassword(ByteStringer.wrap(userToken.getPassword()))
152               .setKind(userToken.getKind().toString())
153               .setService(userToken.getService().toString()).build();
154       }
155 
156       List<ClientProtos.BulkLoadHFileRequest.FamilyPath> protoFamilyPaths =
157           new ArrayList<ClientProtos.BulkLoadHFileRequest.FamilyPath>();
158       for(Pair<byte[], String> el: familyPaths) {
159         protoFamilyPaths.add(ClientProtos.BulkLoadHFileRequest.FamilyPath.newBuilder()
160           .setFamily(ByteStringer.wrap(el.getFirst()))
161           .setPath(el.getSecond()).build());
162       }
163 
164       SecureBulkLoadProtos.SecureBulkLoadHFilesRequest request =
165           SecureBulkLoadProtos.SecureBulkLoadHFilesRequest.newBuilder()
166             .setFsToken(protoDT)
167             .addAllFamilyPath(protoFamilyPaths)
168             .addAllClusterIds(clusterIds != null ? clusterIds : new ArrayList<String>())
169             .setBulkToken(bulkToken).build();
170 
171       ServerRpcController controller = new ServerRpcController();
172       BlockingRpcCallback<SecureBulkLoadProtos.SecureBulkLoadHFilesResponse> rpcCallback =
173           new BlockingRpcCallback<SecureBulkLoadProtos.SecureBulkLoadHFilesResponse>();
174       instance.secureBulkLoadHFiles(controller,
175         request,
176         rpcCallback);
177 
178       SecureBulkLoadProtos.SecureBulkLoadHFilesResponse response = rpcCallback.get();
179       if (controller.failedOnException()) {
180         throw controller.getFailedOn();
181       }
182       return response.getLoaded();
183     } catch (Throwable throwable) {
184       if (throwable instanceof IOException) {
185         throw (IOException) throwable;
186       }
187       throw new IOException(throwable);
188     }
189   }
190 
191   public Path getStagingPath(String bulkToken, byte[] family) throws IOException {
192     return SecureBulkLoadUtil.getStagingPath(table.getConfiguration(), bulkToken, family);
193   }
194 }