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  package org.apache.hadoop.hbase.protobuf;
19  
20  import java.io.IOException;
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import org.apache.hadoop.classification.InterfaceAudience;
25  import org.apache.hadoop.hbase.CellScanner;
26  import org.apache.hadoop.hbase.HRegionInfo;
27  import org.apache.hadoop.hbase.ServerName;
28  import org.apache.hadoop.hbase.client.Result;
29  import org.apache.hadoop.hbase.ipc.ServerRpcController;
30  import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.UserPermissionsResponse;
31  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CloseRegionResponse;
32  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetOnlineRegionResponse;
33  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetServerInfoResponse;
34  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionResponse;
35  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.RollWALWriterResponse;
36  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.ServerInfo;
37  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
38  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ActionResult;
39  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanResponse;
40  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.NameBytesPair;
41  import org.apache.hadoop.hbase.protobuf.generated.MasterAdminProtos.CatalogScanResponse;
42  import org.apache.hadoop.hbase.protobuf.generated.MasterAdminProtos.EnableCatalogJanitorResponse;
43  import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.GetLastFlushedSequenceIdResponse;
44  import org.apache.hadoop.hbase.regionserver.RegionOpeningState;
45  import org.apache.hadoop.hbase.security.access.UserPermission;
46  import org.apache.hadoop.util.StringUtils;
47  
48  import com.google.protobuf.ByteString;
49  import com.google.protobuf.RpcController;
50  
51  /**
52   * Helper utility to build protocol buffer responses,
53   * or retrieve data from protocol buffer responses.
54   */
55  @InterfaceAudience.Private
56  public final class ResponseConverter {
57  
58    private ResponseConverter() {
59    }
60  
61  // Start utilities for Client
62  
63    /**
64     * Get the client Results from a protocol buffer ScanResponse
65     *
66     * @param response the protocol buffer ScanResponse
67     * @return the client Results in the response
68     */
69    public static Result[] getResults(final ScanResponse response) {
70      if (response == null) return null;
71      int count = response.getResultCount();
72      Result[] results = new Result[count];
73      for (int i = 0; i < count; i++) {
74        results[i] = ProtobufUtil.toResult(response.getResult(i));
75      }
76      return results;
77    }
78  
79    /**
80     * Get the results from a protocol buffer MultiResponse
81     *
82     * @param proto the protocol buffer MultiResponse to convert
83     * @param cells Cells to go with the passed in <code>proto</code>.  Can be null.
84     * @return the results that were in the MultiResponse (a Result or an Exception).
85     * @throws IOException
86     */
87    public static List<Object> getResults(final ClientProtos.MultiResponse proto,
88        final CellScanner cells)
89    throws IOException {
90      List<Object> results = new ArrayList<Object>();
91      List<ActionResult> resultList = proto.getResultList();
92      for (int i = 0, n = resultList.size(); i < n; i++) {
93        ActionResult result = resultList.get(i);
94        if (result.hasException()) {
95          results.add(ProtobufUtil.toException(result.getException()));
96        } else if (result.hasValue()) {
97          ClientProtos.Result value = result.getValue();
98          results.add(ProtobufUtil.toResult(value, cells));
99        } else {
100         results.add(new Result());
101       }
102     }
103     return results;
104   }
105 
106   /**
107    * Wrap a throwable to an action result.
108    *
109    * @param t
110    * @return an action result
111    */
112   public static ActionResult buildActionResult(final Throwable t) {
113     ActionResult.Builder builder = ActionResult.newBuilder();
114     NameBytesPair.Builder parameterBuilder = NameBytesPair.newBuilder();
115     parameterBuilder.setName(t.getClass().getName());
116     parameterBuilder.setValue(
117       ByteString.copyFromUtf8(StringUtils.stringifyException(t)));
118     builder.setException(parameterBuilder.build());
119     return builder.build();
120   }
121 
122   /**
123    * Converts the permissions list into a protocol buffer UserPermissionsResponse
124    */
125   public static UserPermissionsResponse buildUserPermissionsResponse(
126       final List<UserPermission> permissions) {
127     UserPermissionsResponse.Builder builder = UserPermissionsResponse.newBuilder();
128     for (UserPermission perm : permissions) {
129       builder.addPermission(ProtobufUtil.toUserPermission(perm));
130     }
131     return builder.build();
132   }
133 
134 // End utilities for Client
135 // Start utilities for Admin
136 
137   /**
138    * Get the list of regions to flush from a RollLogWriterResponse
139    *
140    * @param proto the RollLogWriterResponse
141    * @return the the list of regions to flush
142    */
143   public static byte[][] getRegions(final RollWALWriterResponse proto) {
144     if (proto == null || proto.getRegionToFlushCount() == 0) return null;
145     List<byte[]> regions = new ArrayList<byte[]>();
146     for (ByteString region: proto.getRegionToFlushList()) {
147       regions.add(region.toByteArray());
148     }
149     return (byte[][])regions.toArray();
150   }
151 
152   /**
153    * Get the list of region info from a GetOnlineRegionResponse
154    *
155    * @param proto the GetOnlineRegionResponse
156    * @return the list of region info
157    */
158   public static List<HRegionInfo> getRegionInfos(final GetOnlineRegionResponse proto) {
159     if (proto == null || proto.getRegionInfoCount() == 0) return null;
160     return ProtobufUtil.getRegionInfos(proto);
161   }
162 
163   /**
164    * Get the region opening state from a OpenRegionResponse
165    *
166    * @param proto the OpenRegionResponse
167    * @return the region opening state
168    */
169   public static RegionOpeningState getRegionOpeningState
170       (final OpenRegionResponse proto) {
171     if (proto == null || proto.getOpeningStateCount() != 1) return null;
172     return RegionOpeningState.valueOf(
173       proto.getOpeningState(0).name());
174   }
175 
176   /**
177    * Get a list of region opening state from a OpenRegionResponse
178    * 
179    * @param proto the OpenRegionResponse
180    * @return the list of region opening state
181    */
182   public static List<RegionOpeningState> getRegionOpeningStateList(
183       final OpenRegionResponse proto) {
184     if (proto == null) return null;
185     List<RegionOpeningState> regionOpeningStates = new ArrayList<RegionOpeningState>();
186     for (int i = 0; i < proto.getOpeningStateCount(); i++) {
187       regionOpeningStates.add(RegionOpeningState.valueOf(
188           proto.getOpeningState(i).name()));
189     }
190     return regionOpeningStates;
191   }
192 
193   /**
194    * Check if the region is closed from a CloseRegionResponse
195    *
196    * @param proto the CloseRegionResponse
197    * @return the region close state
198    */
199   public static boolean isClosed
200       (final CloseRegionResponse proto) {
201     if (proto == null || !proto.hasClosed()) return false;
202     return proto.getClosed();
203   }
204 
205   /**
206    * A utility to build a GetServerInfoResponse.
207    *
208    * @param serverName
209    * @param webuiPort
210    * @return the response
211    */
212   public static GetServerInfoResponse buildGetServerInfoResponse(
213       final ServerName serverName, final int webuiPort) {
214     GetServerInfoResponse.Builder builder = GetServerInfoResponse.newBuilder();
215     ServerInfo.Builder serverInfoBuilder = ServerInfo.newBuilder();
216     serverInfoBuilder.setServerName(ProtobufUtil.toServerName(serverName));
217     if (webuiPort >= 0) {
218       serverInfoBuilder.setWebuiPort(webuiPort);
219     }
220     builder.setServerInfo(serverInfoBuilder.build());
221     return builder.build();
222   }
223 
224   /**
225    * A utility to build a GetOnlineRegionResponse.
226    *
227    * @param regions
228    * @return the response
229    */
230   public static GetOnlineRegionResponse buildGetOnlineRegionResponse(
231       final List<HRegionInfo> regions) {
232     GetOnlineRegionResponse.Builder builder = GetOnlineRegionResponse.newBuilder();
233     for (HRegionInfo region: regions) {
234       builder.addRegionInfo(HRegionInfo.convert(region));
235     }
236     return builder.build();
237   }
238 
239   /**
240    * Creates a response for the catalog scan request
241    * @return A CatalogScanResponse
242    */
243   public static CatalogScanResponse buildCatalogScanResponse(int numCleaned) {
244     return CatalogScanResponse.newBuilder().setScanResult(numCleaned).build();
245   }
246 
247   /**
248    * Creates a response for the catalog scan request
249    * @return A EnableCatalogJanitorResponse
250    */
251   public static EnableCatalogJanitorResponse buildEnableCatalogJanitorResponse(boolean prevValue) {
252     return EnableCatalogJanitorResponse.newBuilder().setPrevValue(prevValue).build();
253   }
254 
255 // End utilities for Admin
256 
257   /**
258    * Creates a response for the last flushed sequence Id request
259    * @return A GetLastFlushedSequenceIdResponse
260    */
261   public static GetLastFlushedSequenceIdResponse buildGetLastFlushedSequenceIdResponse(
262       long seqId) {
263     return GetLastFlushedSequenceIdResponse.newBuilder().setLastFlushedSequenceId(seqId).build();
264   }
265 
266   /**
267    * Stores an exception encountered during RPC invocation so it can be passed back
268    * through to the client.
269    * @param controller the controller instance provided by the client when calling the service
270    * @param ioe the exception encountered
271    */
272   public static void setControllerException(RpcController controller, IOException ioe) {
273     if (controller != null) {
274       if (controller instanceof ServerRpcController) {
275         ((ServerRpcController)controller).setFailedOn(ioe);
276       } else {
277         controller.setFailed(StringUtils.stringifyException(ioe));
278       }
279     }
280   }
281 }