001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.client; 019 020import java.io.IOException; 021import org.apache.hadoop.conf.Configuration; 022import org.apache.hadoop.hbase.HConstants; 023import org.apache.hadoop.hbase.TableName; 024import org.apache.hadoop.hbase.master.RegionState; 025import org.apache.hadoop.hbase.util.Bytes; 026import org.apache.yetus.audience.InterfaceAudience; 027 028/** 029 * Utility used composing RegionInfo for 'display'; e.g. on the web UI 030 */ 031@InterfaceAudience.Private 032public class RegionInfoDisplay { 033 public final static String DISPLAY_KEYS_KEY = "hbase.display.keys"; 034 public final static byte[] HIDDEN_END_KEY = Bytes.toBytes("hidden-end-key"); 035 public final static byte[] HIDDEN_START_KEY = Bytes.toBytes("hidden-start-key"); 036 037 /** 038 * Get the descriptive name as {@link RegionState} does it but with hidden startkey optionally 039 * @return descriptive string 040 */ 041 public static String getDescriptiveNameFromRegionStateForDisplay(RegionState state, 042 Configuration conf) { 043 if (conf.getBoolean(DISPLAY_KEYS_KEY, true)) return state.toDescriptiveString(); 044 String descriptiveStringFromState = state.toDescriptiveString(); 045 int idx = descriptiveStringFromState.lastIndexOf(" state="); 046 String regionName = getRegionNameAsStringForDisplay( 047 RegionInfoBuilder.newBuilder(state.getRegion()).build(), conf); 048 return regionName + descriptiveStringFromState.substring(idx); 049 } 050 051 /** 052 * Get the end key for display. Optionally hide the real end key. 053 * @return the endkey 054 */ 055 public static byte[] getEndKeyForDisplay(RegionInfo ri, Configuration conf) { 056 boolean displayKey = conf.getBoolean(DISPLAY_KEYS_KEY, true); 057 if (displayKey) return ri.getEndKey(); 058 return HIDDEN_END_KEY; 059 } 060 061 /** 062 * Get the start key for display. Optionally hide the real start key. 063 * @return the startkey 064 */ 065 public static byte[] getStartKeyForDisplay(RegionInfo ri, Configuration conf) { 066 boolean displayKey = conf.getBoolean(DISPLAY_KEYS_KEY, true); 067 if (displayKey) return ri.getStartKey(); 068 return HIDDEN_START_KEY; 069 } 070 071 /** 072 * Get the region name for display. Optionally hide the start key. 073 * @return region name as String 074 */ 075 public static String getRegionNameAsStringForDisplay(RegionInfo ri, Configuration conf) { 076 return Bytes.toStringBinary(getRegionNameForDisplay(ri, conf)); 077 } 078 079 /** 080 * Get the region name for display. Optionally hide the start key. 081 * @return region name bytes 082 */ 083 public static byte[] getRegionNameForDisplay(RegionInfo ri, Configuration conf) { 084 boolean displayKey = conf.getBoolean(DISPLAY_KEYS_KEY, true); 085 if (displayKey || ri.getTable().equals(TableName.META_TABLE_NAME)) { 086 return ri.getRegionName(); 087 } else { 088 // create a modified regionname with the startkey replaced but preserving 089 // the other parts including the encodedname. 090 try { 091 byte[][] regionNameParts = RegionInfo.parseRegionName(ri.getRegionName()); 092 regionNameParts[1] = HIDDEN_START_KEY; // replace the real startkey 093 int len = 0; 094 // get the total length 095 for (byte[] b : regionNameParts) { 096 len += b.length; 097 } 098 byte[] encodedRegionName = Bytes.toBytes(RegionInfo.encodeRegionName(ri.getRegionName())); 099 len += encodedRegionName.length; 100 // allocate some extra bytes for the delimiters and the last '.' 101 byte[] modifiedName = new byte[len + regionNameParts.length + 1]; 102 int lengthSoFar = 0; 103 int loopCount = 0; 104 for (byte[] b : regionNameParts) { 105 System.arraycopy(b, 0, modifiedName, lengthSoFar, b.length); 106 lengthSoFar += b.length; 107 if (loopCount++ == 2) modifiedName[lengthSoFar++] = RegionInfo.REPLICA_ID_DELIMITER; 108 else modifiedName[lengthSoFar++] = HConstants.DELIMITER; 109 } 110 // replace the last comma with '.' 111 modifiedName[lengthSoFar - 1] = RegionInfo.ENC_SEPARATOR; 112 System.arraycopy(encodedRegionName, 0, modifiedName, lengthSoFar, encodedRegionName.length); 113 lengthSoFar += encodedRegionName.length; 114 modifiedName[lengthSoFar] = RegionInfo.ENC_SEPARATOR; 115 return modifiedName; 116 } catch (IOException e) { 117 // LOG.warn("Encountered exception " + e); 118 throw new RuntimeException(e); 119 } 120 } 121 } 122}