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 * n * @return singleton instance of {@link VisibilityLabelService}. The FQCN of the 052 * implementation class can be specified using 053 * "hbase.regionserver.visibility.label.service.class". 054 * @throws IOException When VLS implementation, as specified in conf, can not be loaded. 055 */ 056 public VisibilityLabelService getVisibilityLabelService(Configuration conf) throws IOException { 057 String vlsClassName = conf.get(VISIBILITY_LABEL_SERVICE_CLASS, 058 DefaultVisibilityLabelServiceImpl.class.getCanonicalName()).trim(); 059 if (this.visibilityLabelService != null) { 060 checkForClusterLevelSingleConf(vlsClassName); 061 return this.visibilityLabelService; 062 } 063 synchronized (this) { 064 if (this.visibilityLabelService != null) { 065 checkForClusterLevelSingleConf(vlsClassName); 066 return this.visibilityLabelService; 067 } 068 this.vlsClazzName = vlsClassName; 069 try { 070 this.visibilityLabelService = 071 (VisibilityLabelService) ReflectionUtils.newInstance(Class.forName(vlsClassName), conf); 072 } catch (ClassNotFoundException e) { 073 throw new IOException(e); 074 } 075 return this.visibilityLabelService; 076 } 077 } 078 079 private void checkForClusterLevelSingleConf(String vlsClassName) { 080 assert this.vlsClazzName != null; 081 if (!this.vlsClazzName.equals(vlsClassName)) { 082 LOG.warn("Trying to use table specific value for config " 083 + "'hbase.regionserver.visibility.label.service.class' which is not supported." 084 + " Will use the cluster level VisibilityLabelService class " + this.vlsClazzName); 085 } 086 } 087 088 /** 089 * @return singleton instance of {@link VisibilityLabelService}. 090 * @throws IllegalStateException if this called before initialization of singleton instance. 091 */ 092 public VisibilityLabelService getVisibilityLabelService() { 093 // By the time this method is called, the singleton instance of visibilityLabelService should 094 // have been created. And it will be created as getVisibilityLabelService(Configuration conf) 095 // is called from VC#start() and that will be the 1st thing core code do with any CP. 096 if (this.visibilityLabelService == null) { 097 throw new IllegalStateException("VisibilityLabelService not yet instantiated"); 098 } 099 return this.visibilityLabelService; 100 } 101}