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.security.visibility; 019 020import java.io.IOException; 021 022import org.apache.yetus.audience.InterfaceAudience; 023import org.slf4j.Logger; 024import org.slf4j.LoggerFactory; 025import org.apache.hadoop.conf.Configuration; 026import org.apache.hadoop.util.ReflectionUtils; 027 028/** 029 * Manages singleton instance of {@link VisibilityLabelService} 030 */ 031@InterfaceAudience.Private 032public class VisibilityLabelServiceManager { 033 034 private static final Logger LOG = LoggerFactory.getLogger(VisibilityLabelServiceManager.class); 035 036 public static final String VISIBILITY_LABEL_SERVICE_CLASS = 037 "hbase.regionserver.visibility.label.service.class"; 038 private static final VisibilityLabelServiceManager INSTANCE = new VisibilityLabelServiceManager(); 039 040 private volatile VisibilityLabelService visibilityLabelService = null; 041 private String vlsClazzName = null; 042 043 private VisibilityLabelServiceManager() { 044 045 } 046 047 public static VisibilityLabelServiceManager getInstance() { 048 return INSTANCE; 049 } 050 051 /** 052 * @param conf 053 * @return singleton instance of {@link VisibilityLabelService}. The FQCN of the implementation 054 * class can be specified using "hbase.regionserver.visibility.label.service.class". 055 * @throws IOException When VLS implementation, as specified in conf, can not be loaded. 056 */ 057 public VisibilityLabelService getVisibilityLabelService(Configuration conf) throws IOException { 058 String vlsClassName = conf.get(VISIBILITY_LABEL_SERVICE_CLASS, 059 DefaultVisibilityLabelServiceImpl.class.getCanonicalName()).trim(); 060 if (this.visibilityLabelService != null) { 061 checkForClusterLevelSingleConf(vlsClassName); 062 return this.visibilityLabelService; 063 } 064 synchronized (this) { 065 if (this.visibilityLabelService != null) { 066 checkForClusterLevelSingleConf(vlsClassName); 067 return this.visibilityLabelService; 068 } 069 this.vlsClazzName = vlsClassName; 070 try { 071 this.visibilityLabelService = (VisibilityLabelService) ReflectionUtils.newInstance( 072 Class.forName(vlsClassName), conf); 073 } catch (ClassNotFoundException e) { 074 throw new IOException(e); 075 } 076 return this.visibilityLabelService; 077 } 078 } 079 080 private void checkForClusterLevelSingleConf(String vlsClassName) { 081 assert this.vlsClazzName != null; 082 if (!this.vlsClazzName.equals(vlsClassName)) { 083 LOG.warn("Trying to use table specific value for config " 084 + "'hbase.regionserver.visibility.label.service.class' which is not supported." 085 + " Will use the cluster level VisibilityLabelService class " + this.vlsClazzName); 086 } 087 } 088 089 /** 090 * @return singleton instance of {@link VisibilityLabelService}. 091 * @throws IllegalStateException if this called before initialization of singleton instance. 092 */ 093 public VisibilityLabelService getVisibilityLabelService() { 094 // By the time this method is called, the singleton instance of visibilityLabelService should 095 // have been created. And it will be created as getVisibilityLabelService(Configuration conf) 096 // is called from VC#start() and that will be the 1st thing core code do with any CP. 097 if (this.visibilityLabelService == null) { 098 throw new IllegalStateException("VisibilityLabelService not yet instantiated"); 099 } 100 return this.visibilityLabelService; 101 } 102}