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