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