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.util; 019 020import java.nio.ByteBuffer; 021import java.util.HashMap; 022import java.util.Map; 023import java.util.TreeMap; 024import javax.security.auth.Subject; 025import javax.security.auth.login.AppConfigurationEntry; 026import javax.security.auth.login.Configuration; 027import javax.security.auth.login.LoginContext; 028import javax.security.auth.login.LoginException; 029import org.apache.commons.lang3.StringUtils; 030import org.apache.hadoop.hbase.thrift.generated.TCell; 031import org.apache.hadoop.hbase.thrift.generated.TRowResult; 032import org.apache.yetus.audience.InterfaceAudience; 033 034/** 035 * Common Utility class for clients 036 */ 037@InterfaceAudience.Private 038public final class ClientUtils { 039 040 private ClientUtils() { 041 // Empty block 042 } 043 044 /** 045 * To authenticate the demo client, kinit should be invoked ahead. Here we try to get the Kerberos 046 * credential from the ticket cache 047 * @return LoginContext Object 048 * @throws LoginException Exception thrown if unable to get LoginContext 049 */ 050 public static LoginContext getLoginContext() throws LoginException { 051 052 return new LoginContext(StringUtils.EMPTY, new Subject(), null, new Configuration() { 053 @Override 054 public AppConfigurationEntry[] getAppConfigurationEntry(String name) { 055 Map<String, String> options = new HashMap<>(); 056 options.put("useKeyTab", "false"); 057 options.put("storeKey", "false"); 058 options.put("doNotPrompt", "true"); 059 options.put("useTicketCache", "true"); 060 options.put("renewTGT", "true"); 061 options.put("refreshKrb5Config", "true"); 062 options.put("isInitiator", "true"); 063 String ticketCache = System.getenv("KRB5CCNAME"); 064 if (ticketCache != null) { 065 options.put("ticketCache", ticketCache); 066 } 067 options.put("debug", "true"); 068 069 return new AppConfigurationEntry[] { 070 new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule", 071 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options) }; 072 } 073 }); 074 075 } 076 077 /** 078 * copy values into a TreeMap to get them in sorted order and print it 079 * @param rowResult Holds row name and then a map of columns to cells 080 */ 081 public static void printRow(final TRowResult rowResult) { 082 083 TreeMap<String, TCell> sorted = new TreeMap<>(); 084 for (Map.Entry<ByteBuffer, TCell> column : rowResult.columns.entrySet()) { 085 sorted.put(utf8(column.getKey().array()), column.getValue()); 086 } 087 088 StringBuilder rowStr = new StringBuilder(); 089 for (Map.Entry<String, TCell> entry : sorted.entrySet()) { 090 rowStr.append(entry.getKey()); 091 rowStr.append(" => "); 092 rowStr.append(utf8(entry.getValue().value.array())); 093 rowStr.append("; "); 094 } 095 System.out.println("row: " + utf8(rowResult.row.array()) + ", cols: " + rowStr); 096 097 } 098 099 /** 100 * Helper to translate byte[]s to UTF8 strings 101 * @param buf byte array 102 * @return UTF8 decoded string value 103 */ 104 public static String utf8(final byte[] buf) { 105 try { 106 return Bytes.toString(buf); 107 } catch (IllegalArgumentException e) { 108 return "[INVALID UTF-8]"; 109 } 110 } 111 112 /** 113 * Helper to translate a byte buffer to UTF8 strings 114 * @param bb byte buffer 115 * @return UTF8 decoded string value 116 */ 117 public static String utf8(final ByteBuffer bb) { 118 // performance is not very critical here so we always copy the BB to a byte array 119 byte[] buf = new byte[bb.remaining()]; 120 // duplicate so the get will not change the position of the original bb 121 bb.duplicate().get(buf); 122 return utf8(buf); 123 } 124 125}