hiveserver2-site.xml
<property>
<name>hive.security.authorization.enabled</name>
<value>true</value>
</property>
<property>
<name>hive.security.authorization.manager</name>
<value>org.apache.ranger.authorization.hive.authorizer.RangerHiveAuthorizerFactory</value>
</property>
RangerHiveAuthorizerFactory 实现了 HiveAuthorizerFactory。
public class RangerHiveAuthorizerFactory implements HiveAuthorizerFactory {
@Override
public HiveAuthorizer createHiveAuthorizer(HiveMetastoreClientFactory metastoreClientFactory,
HiveConf conf,
HiveAuthenticationProvider hiveAuthenticator,
HiveAuthzSessionContext sessionContext)
throws HiveAuthzPluginException {
return new RangerHiveAuthorizer(metastoreClientFactory, conf, hiveAuthenticator, sessionContext);
}
}
RangerHiveAuthorizerFactory 的 createHiveAuthorizer
方法返回 HiveAuthorizer,里面定义了Hive 权限的 plugin实现必须实现的方法
public interface HiveAuthorizer {
HiveAuthorizer.VERSION getVersion();
void grantPrivileges(List<HivePrincipal> var1, List<HivePrivilege> var2, HivePrivilegeObject var3, HivePrincipal var4, boolean var5) throws HiveAuthzPluginException, HiveAccessControlException;
void revokePrivileges(List<HivePrincipal> var1, List<HivePrivilege> var2, HivePrivilegeObject var3, HivePrincipal var4, boolean var5) throws HiveAuthzPluginException, HiveAccessControlException;
void createRole(String var1, HivePrincipal var2) throws HiveAuthzPluginException, HiveAccessControlException;
void dropRole(String var1) throws HiveAuthzPluginException, HiveAccessControlException;
List<HiveRoleGrant> getPrincipalGrantInfoForRole(String var1) throws HiveAuthzPluginException, HiveAccessControlException;
List<HiveRoleGrant> getRoleGrantInfoForPrincipal(HivePrincipal var1) throws HiveAuthzPluginException, HiveAccessControlException;
void grantRole(List<HivePrincipal> var1, List<String> var2, boolean var3, HivePrincipal var4) throws HiveAuthzPluginException, HiveAccessControlException;
void revokeRole(List<HivePrincipal> var1, List<String> var2, boolean var3, HivePrincipal var4) throws HiveAuthzPluginException, HiveAccessControlException;
void checkPrivileges(HiveOperationType var1, List<HivePrivilegeObject> var2, List<HivePrivilegeObject> var3, HiveAuthzContext var4) throws HiveAuthzPluginException, HiveAccessControlException;
List<HivePrivilegeObject> filterListCmdObjects(List<HivePrivilegeObject> var1, HiveAuthzContext var2) throws HiveAuthzPluginException, HiveAccessControlException;
List<String> getAllRoles() throws HiveAuthzPluginException, HiveAccessControlException;
List<HivePrivilegeInfo> showPrivileges(HivePrincipal var1, HivePrivilegeObject var2) throws HiveAuthzPluginException, HiveAccessControlException;
void setCurrentRole(String var1) throws HiveAccessControlException, HiveAuthzPluginException;
List<String> getCurrentRoleNames() throws HiveAuthzPluginException;
void applyAuthorizationConfigPolicy(HiveConf var1) throws HiveAuthzPluginException;
Object getHiveAuthorizationTranslator() throws HiveAuthzPluginException;
List<HivePrivilegeObject> applyRowFilterAndColumnMasking(HiveAuthzContext var1, List<HivePrivilegeObject> var2) throws SemanticException;
boolean needTransform();
HivePolicyProvider getHivePolicyProvider() throws HiveAuthzPluginException;
public static enum VERSION {
V1;
private VERSION() {
}
}
}
RangerHiveAuthorizer 的集成关系
RangerHiveAuthorizer 不是直接实现 HiveAuthorizer。RangerHiveAuthorizer 继承RangerHiveAuthorizerBase。RangerHiveAuthorizerBase 继承 AbstractHiveAuthorizer。AbstractHiveAuthorizer 实现 HiveAuthorizer。
AbstractHiveAuthorizer
public abstract class AbstractHiveAuthorizer implements HiveAuthorizer {
public AbstractHiveAuthorizer() {
}
public HiveAuthorizationTranslator getHiveAuthorizationTranslator() throws HiveAuthzPluginException {
return null;
}
public HivePolicyProvider getHivePolicyProvider() throws HiveAuthzPluginException {
return null;
}
}
RangerHiveAuthorizerBase
RangerHiveAuthorizerBase 实现了 3 个方法,更主要的是把构造参数存储在变量里,并提供公有的方法来获取。
public abstract class RangerHiveAuthorizerBase extends AbstractHiveAuthorizer {
private static final Log LOG = LogFactory.getLog(RangerHiveAuthorizerBase.class);
private HiveMetastoreClientFactory mMetastoreClientFactory;
private HiveConf mHiveConf;
private HiveAuthenticationProvider mHiveAuthenticator;
private HiveAuthzSessionContext mSessionContext;
private UserGroupInformation mUgi;
public RangerHiveAuthorizerBase(HiveMetastoreClientFactory metastoreClientFactory,
HiveConf hiveConf,
HiveAuthenticationProvider hiveAuthenticator,
HiveAuthzSessionContext context) {
mMetastoreClientFactory = metastoreClientFactory;
mHiveConf = hiveConf;
mHiveAuthenticator = hiveAuthenticator;
mSessionContext = context;
String userName = mHiveAuthenticator == null ? null : mHiveAuthenticator.getUserName();
mUgi = userName == null ? null : UserGroupInformation.createRemoteUser(userName);
if(mHiveAuthenticator == null) {
LOG.warn("RangerHiveAuthorizerBase.RangerHiveAuthorizerBase(): hiveAuthenticator is null");
} else if(StringUtil.isEmpty(userName)) {
LOG.warn("RangerHiveAuthorizerBase.RangerHiveAuthorizerBase(): hiveAuthenticator.getUserName() returned null/empty");
} else if(mUgi == null) {
LOG.warn(String.format("RangerHiveAuthorizerBase.RangerHiveAuthorizerBase(): UserGroupInformation.createRemoteUser(%s) returned null", userName));
}
}
public HiveMetastoreClientFactory getMetastoreClientFactory() {
return mMetastoreClientFactory;
}
public HiveConf getHiveConf() {
return mHiveConf;
}
public HiveAuthenticationProvider getHiveAuthenticator() {
return mHiveAuthenticator;
}
public HiveAuthzSessionContext getHiveAuthzSessionContext() {
return mSessionContext;
}
public UserGroupInformation getCurrentUserGroupInfo() {
return mUgi;
}
@Override
public void applyAuthorizationConfigPolicy(HiveConf hiveConf) throws HiveAuthzPluginException {
LOG.debug("RangerHiveAuthorizerBase.applyAuthorizationConfigPolicy()");
// from SQLStdHiveAccessController.applyAuthorizationConfigPolicy()
if (mSessionContext != null && mSessionContext.getClientType() == CLIENT_TYPE.HIVESERVER2) {
// Configure PREEXECHOOKS with DisallowTransformHook to disallow transform queries
String hooks = hiveConf.getVar(ConfVars.PREEXECHOOKS).trim();
if (hooks.isEmpty()) {
hooks = DisallowTransformHook.class.getName();
} else {
hooks = hooks + "," + DisallowTransformHook.class.getName();
}
hiveConf.setVar(ConfVars.PREEXECHOOKS, hooks);
SettableConfigUpdater.setHiveConfWhiteList(hiveConf);
}
}
/**
* Show privileges for given principal on given object
* @param principal
* @param privObj
* @return
* @throws HiveAuthzPluginException
* @throws HiveAccessControlException
*/
@Override
public List<HivePrivilegeInfo> showPrivileges(HivePrincipal principal, HivePrivilegeObject privObj)
throws HiveAuthzPluginException, HiveAccessControlException {
LOG.debug("RangerHiveAuthorizerBase.showPrivileges()");
throwNotImplementedException("showPrivileges");
return null;
}
@Override
public VERSION getVersion() {
return VERSION.V1;
}
private void throwNotImplementedException(String method) throws HiveAuthzPluginException {
throw new HiveAuthzPluginException(method + "() not implemented in Ranger AbstractHiveAuthorizer");
}
@Override
public HivePolicyProvider getHivePolicyProvider() throws HiveAuthzPluginException {
// TODO Auto-generated method stub
return null;
}
}
RangerHiveAuthorizer
RangerHiveAuthorizer 创建一个静态的变量 RangerHivePlugin hivePlugin, 并且把请求转到 plugin 的相应方法处理,如 grantPrivileges
方法调用 hivePlugin.grantAccess(request, auditHandler);
。
@Override
public void grantPrivileges(List<HivePrincipal> hivePrincipals,
List<HivePrivilege> hivePrivileges,
HivePrivilegeObject hivePrivObject,
HivePrincipal grantorPrincipal,
boolean grantOption)
throws HiveAuthzPluginException, HiveAccessControlException {
if (LOG.isDebugEnabled()) {
LOG.debug("grantPrivileges() => HivePrivilegeObject:" + toString(hivePrivObject, new StringBuilder()) + "grantorPrincipal: " + grantorPrincipal + "hivePrincipals" + hivePrincipals + "hivePrivileges" + hivePrivileges);
}
if(! RangerHivePlugin.UpdateXaPoliciesOnGrantRevoke) {
throw new HiveAuthzPluginException("GRANT/REVOKE not supported in Ranger HiveAuthorizer. Please use Ranger Security Admin to setup access control.");
}
RangerHiveAuditHandler auditHandler = new RangerHiveAuditHandler();
try {
List<HivePrivilegeObject> outputs = new ArrayList<>(Arrays.asList(hivePrivObject));
RangerHiveResource resource = getHiveResource(HiveOperationType.GRANT_PRIVILEGE, hivePrivObject, null, outputs);
GrantRevokeRequest request = createGrantRevokeData(resource, hivePrincipals, hivePrivileges, grantorPrincipal, grantOption);
LOG.info("grantPrivileges(): " + request);
if(LOG.isDebugEnabled()) {
LOG.debug("grantPrivileges(): " + request);
}
hivePlugin.grantAccess(request, auditHandler);
} catch(Exception excp) {
throw new HiveAccessControlException(excp);
} finally {
auditHandler.flushAudit();
}
}
RangerHivePlugin
RangerHivePlugin 的初始化参数 appType,代表那个 app,如 HiveServer2 的 appType 为 “hiveServer2”。RangerBasePlugin 继承 RangerBasePlugin
public RangerHivePlugin(String appType) {
super("hive", appType);
}
RangerBasePlugin
RangerBasePlugin 所有种类的 plugin 都继承 RangerBasePlugin,如 RangerHdfsPlugin,RangerHivePlugin
RangerBasePlugin 的构造方法,如 serviceType = “hive”, appId = “hiveServer2”
public RangerBasePlugin(String serviceType, String appId) {
this(new RangerPluginConfig(serviceType, null, appId, null, null, null));
}
RangerPluginConfig
serviceType = “hive”, appId = “hiveServer2”
public RangerPluginConfig(String serviceType, String serviceName, String appId, String clusterName, String clusterType, RangerPolicyEngineOptions policyEngineOptions) {
super();
addResourcesForServiceType(serviceType);
addResourcesForServiceName(this.serviceType, this.serviceName);
if (policyEngineOptions == null) {
policyEngineOptions = new RangerPolicyEngineOptions();
policyEngineOptions.configureForPlugin(this, propertyPrefix);
}
this.policyEngineOptions = policyEngineOptions;
LOG.info(policyEngineOptions);
}
addResourcesForServiceType, serviceType = “hive”
private void addResourcesForServiceType(String serviceType) {
String auditCfg = "ranger-" + serviceType + "-audit.xml";
String securityCfg = "ranger-" + serviceType + "-security.xml";
String sslCfg = "ranger-" + serviceType + "-policymgr-ssl.xml";
if (!addResourceIfReadable(auditCfg)) {
addAuditResource(serviceType);
}
if (!addResourceIfReadable(securityCfg)) {
addSecurityResource(serviceType);
}
if (!addResourceIfReadable(sslCfg)) {
addSslConfigResource(serviceType);
}
}
addResourcesForServiceName
serviceType = “hive”, serviceName = null,所以不加载任何文件。
private void addResourcesForServiceName(String serviceType, String serviceName) {
if (StringUtils.isNotBlank(serviceType) && StringUtils.isNotBlank(serviceName)) {
String serviceAuditCfg = "ranger-" + serviceType + "-" + serviceName + "-audit.xml";
String serviceSecurityCfg = "ranger-" + serviceType + "-" + serviceName + "-security.xml";
String serviceSslCfg = "ranger-" + serviceType + "-" + serviceName + "-policymgr-ssl.xml";
addResourceIfReadable(serviceAuditCfg);
addResourceIfReadable(serviceSecurityCfg);
addResourceIfReadable(serviceSslCfg);
}
}
RangerBasePlugin 的构造方法
public RangerBasePlugin(RangerPluginConfig pluginConfig) {
this.pluginConfig = pluginConfig;
this.pluginContext = new RangerPluginContext(pluginConfig);
Set<String> superUsers = toSet(pluginConfig.get(pluginConfig.getPropertyPrefix() + ".super.users"));
Set<String> superGroups = toSet(pluginConfig.get(pluginConfig.getPropertyPrefix() + ".super.groups"));
Set<String> auditExcludeUsers = toSet(pluginConfig.get(pluginConfig.getPropertyPrefix() + ".audit.exclude.users"));
Set<String> auditExcludeGroups = toSet(pluginConfig.get(pluginConfig.getPropertyPrefix() + ".audit.exclude.groups"));
Set<String> auditExcludeRoles = toSet(pluginConfig.get(pluginConfig.getPropertyPrefix() + ".audit.exclude.roles"));
Set<String> serviceAdmins = toSet(pluginConfig.get(pluginConfig.getPropertyPrefix() + ".service.admins"));
setSuperUsersAndGroups(superUsers, superGroups);
setAuditExcludedUsersGroupsRoles(auditExcludeUsers, auditExcludeGroups, auditExcludeRoles);
setIsFallbackSupported(pluginConfig.getBoolean(pluginConfig.getPropertyPrefix() + ".is.fallback.supported", false));
setServiceAdmins(serviceAdmins);
RangerScriptExecutionContext.init(pluginConfig);
this.chainedPlugins = initChainedPlugins();
}
## RangerBasePlugin#init
RangerBasePlugin 的 init 里构建PolicyRefresher,PolicyRefresher 是一个线程,
public void init() {
cleanup();
AuditProviderFactory providerFactory = AuditProviderFactory.getInstance();
if (!providerFactory.isInitDone()) {
if (pluginConfig.getProperties() != null) {
providerFactory.init(pluginConfig.getProperties(), getAppId());
} else {
LOG.error("Audit subsystem is not initialized correctly. Please check audit configuration. ");
LOG.error("No authorization audits will be generated. ");
}
}
if (!pluginConfig.getPolicyEngineOptions().disablePolicyRefresher) {
refresher = new PolicyRefresher(this);
LOG.info("Created PolicyRefresher Thread(" + refresher.getName() + ")");
refresher.setDaemon(true);
refresher.startRefresher();
}
for (RangerChainedPlugin chainedPlugin : chainedPlugins) {
chainedPlugin.init();
}
}
RangerBasePlugin#grantAccess
public void grantAccess(GrantRevokeRequest request, RangerAccessResultProcessor resultProcessor) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerBasePlugin.grantAccess(" + request + ")");
}
boolean isSuccess = false;
try {
RangerPolicyEngine policyEngine = this.policyEngine;
if (policyEngine != null) {
request.setZoneName(policyEngine.getUniquelyMatchedZoneName(request));
}
getAdminClient().grantAccess(request);
isSuccess = true;
} finally {
auditGrantRevoke(request, "grant", isSuccess, resultProcessor);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerBasePlugin.grantAccess(" + request + ")");
}
}
PolicyRefresher 的构造方法
public PolicyRefresher(RangerBasePlugin plugIn) {
RangerPluginConfig pluginConfig = plugIn.getConfig();
String propertyPrefix = pluginConfig.getPropertyPrefix();
this.plugIn = plugIn;
this.serviceType = plugIn.getServiceType();
this.serviceName = plugIn.getServiceName();
this.cacheDir = pluginConfig.get(propertyPrefix + ".policy.cache.dir");
String appId = StringUtils.isEmpty(plugIn.getAppId()) ? serviceType : plugIn.getAppId();
String cacheFilename = String.format("%s_%s.json", appId, serviceName);
cacheFilename = cacheFilename.replace(File.separatorChar, '_');
cacheFilename = cacheFilename.replace(File.pathSeparatorChar, '_');
this.cacheFileName = cacheFilename;
Gson gson = null;
try {
gson = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSS-Z").create();
} catch(Throwable excp) {
LOG.fatal("PolicyRefresher(): failed to create GsonBuilder object", excp);
}
RangerPluginContext pluginContext = plugIn.getPluginContext();
RangerAdminClient adminClient = pluginContext.getAdminClient();
this.rangerAdmin = (adminClient != null) ? adminClient : pluginContext.createAdminClient(pluginConfig);
this.gson = gson;
this.rolesProvider = new RangerRolesProvider(getServiceType(), appId, getServiceName(), rangerAdmin, cacheDir, pluginConfig);
this.pollingIntervalMs = pluginConfig.getLong(propertyPrefix + ".policy.pollIntervalMs", 30 * 1000);
setName("PolicyRefresher(serviceName=" + serviceName + ")-" + getId());
}
特别注意
RangerAdminClient adminClient = pluginContext.getAdminClient();
this.rangerAdmin = (adminClient != null) ? adminClient : pluginContext.createAdminClient(pluginConfig);
RangerPluginContext#createAdminClient
使用反射的方法创建 adminClient
public RangerAdminClient createAdminClient(RangerPluginConfig pluginConfig) {
RangerAdminClient ret = null;
String propertyName = pluginConfig.getPropertyPrefix() + ".policy.source.impl";
String policySourceImpl = pluginConfig.get(propertyName);
try {
@SuppressWarnings("unchecked")
Class<RangerAdminClient> adminClass = (Class<RangerAdminClient>)Class.forName(policySourceImpl);
ret = adminClass.newInstance();
} catch (Exception excp) {
LOG.error("failed to instantiate policy source of type '" + policySourceImpl + "'. Will use policy source of type '" + RangerAdminRESTClient.class.getName() + "'", excp);
}
if(ret == null) {
ret = new RangerAdminRESTClient();
}
ret.init(pluginConfig.getServiceName(), pluginConfig.getAppId(), pluginConfig.getPropertyPrefix(), pluginConfig);
if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerBasePlugin.createAdminClient(" + pluginConfig.getServiceName() + ", " + pluginConfig.getAppId() + ", " + pluginConfig.getPropertyPrefix() + "): policySourceImpl=" + policySourceImpl + ", client=" + ret);
}
setAdminClient(ret);
return ret;
}
ranger-hive-security.xml
<configuration xmlns:xi="http://www.w3.org/2001/XInclude">
<property>
<name>ranger.plugin.hive.policy.cache.dir</name>
<value>/etc/ranger/${CLUSTER_ID}_hive/policycache</value>
</property>
<property>
<name>ranger.plugin.hive.policy.pollIntervalMs</name>
<value>30000</value>
</property>
<property>
<name>ranger.plugin.hive.policy.rest.ssl.config.file</name>
<value>/etc/hive/conf/ranger-policymgr-ssl.xml</value>
</property>
<property>
<name>ranger.plugin.hive.policy.rest.url</name>
<value>http://ranger-master:6080</value>
</property>
<property>
<name>ranger.plugin.hive.policy.source.impl</name>
<value>org.apache.ranger.admin.client.RangerAdminRESTClient</value>
</property>
<property>
<name>ranger.plugin.hive.service.name</name>
<value>${CLUSTER_ID}_hive</value>
</property>
<property>
<name>ranger.plugin.hive.urlauth.filesystem.schemes</name>
<value>hdfs:,file:,wasb:,adl:</value>
</property>
<property>
<name>xasecure.hive.update.xapolicies.on.grant.revoke</name>
<value>true</value>
</property>
可以看到,配置的是 RangerAdminRESTClient。
RangerAdminRESTClient#init
@Override
public void init(String serviceName, String appId, String propertyPrefix, Configuration config) {
super.init(serviceName, appId, propertyPrefix, config);
this.serviceName = serviceName;
this.pluginId = restUtils.getPluginId(serviceName, appId);
String url = "";
String tmpUrl = config.get(propertyPrefix + ".policy.rest.url");
String sslConfigFileName = config.get(propertyPrefix + ".policy.rest.ssl.config.file");
clusterName = config.get(propertyPrefix + ".access.cluster.name", "");
if(StringUtil.isEmpty(clusterName)){
clusterName =config.get(propertyPrefix + ".ambari.cluster.name", "");
if (StringUtil.isEmpty(clusterName)) {
if (config instanceof RangerPluginConfig) {
clusterName = ((RangerPluginConfig)config).getClusterName();
}
}
}
int restClientConnTimeOutMs = config.getInt(propertyPrefix + ".policy.rest.client.connection.timeoutMs", 120 * 1000);
int restClientReadTimeOutMs = config.getInt(propertyPrefix + ".policy.rest.client.read.timeoutMs", 30 * 1000);
supportsPolicyDeltas = config.getBoolean(propertyPrefix + RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_POLICY_DELTA, RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_POLICY_DELTA_DEFAULT);
supportsTagDeltas = config.getBoolean(propertyPrefix + RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_TAG_DELTA, RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_TAG_DELTA_DEFAULT);
isRangerCookieEnabled = config.getBoolean(propertyPrefix + ".policy.rest.client.cookie.enabled", RangerCommonConstants.POLICY_REST_CLIENT_SESSION_COOKIE_ENABLED);
rangerAdminCookieName = config.get(propertyPrefix + ".policy.rest.client.session.cookie.name", RangerCommonConstants.DEFAULT_COOKIE_NAME);
if (!StringUtil.isEmpty(tmpUrl)) {
url = tmpUrl.trim();
}
if (url.endsWith("/")) {
url = url.substring(0, url.length() - 1);
}
init(url, sslConfigFileName, restClientConnTimeOutMs , restClientReadTimeOutMs, config);
try {
this.serviceNameUrlParam = URLEncoderUtil.encodeURIParam(serviceName);
} catch (UnsupportedEncodingException e) {
LOG.warn("Unsupported encoding, serviceName=" + serviceName);
this.serviceNameUrlParam = serviceName;
}
}
RangerAdminRESTClient#init
在此方法里,创建了和 Ranger Server 的 HTTP 连接。
private void init(String url, String sslConfigFileName, int restClientConnTimeOutMs , int restClientReadTimeOutMs, Configuration config) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerAdminRESTClient.init(" + url + ", " + sslConfigFileName + ")");
}
restClient = new RangerRESTClient(url, sslConfigFileName, config);
restClient.setRestClientConnTimeOutMs(restClientConnTimeOutMs);
restClient.setRestClientReadTimeOutMs(restClientReadTimeOutMs);
if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerAdminRESTClient.init(" + url + ", " + sslConfigFileName + ")");
}
}
PolicyRefresher#run 方法
先从 policyDownloadQueue 去出一个元素,执行一次 loadRoles()
和 loadPolicy()
public void run() {
if(LOG.isDebugEnabled()) {
LOG.debug("==> PolicyRefresher(serviceName=" + serviceName + ").run()");
}
while(true) {
DownloadTrigger trigger = null;
try {
trigger = policyDownloadQueue.take();
loadRoles();
loadPolicy();
} catch(InterruptedException excp) {
LOG.info("PolicyRefresher(serviceName=" + serviceName + ").run(): interrupted! Exiting thread", excp);
break;
} finally {
if (trigger != null) {
trigger.signalCompletion();
}
}
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== PolicyRefresher(serviceName=" + serviceName + ").run()");
}
}
PolicyRefresher#startRefresher
在此方法里,另启动一个 Timer, 定期(默认 30 秒)向 policyDownloadQueue 里放一个 Object。也代表 PolicyRefresher 线程定期执行一次 loadRoles()
和 loadPolicy()
。
public void startRefresher() {
loadRoles();
loadPolicy();
super.start();
policyDownloadTimer = new Timer("policyDownloadTimer", true);
try {
policyDownloadTimer.schedule(new DownloaderTask(policyDownloadQueue), pollingIntervalMs, pollingIntervalMs);
if (LOG.isDebugEnabled()) {
LOG.debug("Scheduled policyDownloadRefresher to download policies every " + pollingIntervalMs + " milliseconds");
}
} catch (IllegalStateException exception) {
LOG.error("Error scheduling policyDownloadTimer:", exception);
LOG.error("*** Policies will NOT be downloaded every " + pollingIntervalMs + " milliseconds ***");
policyDownloadTimer = null;
}
}
PolicyRefresher#loadRoles
plugIn 是
private void loadRoles() {
if(LOG.isDebugEnabled()) {
LOG.debug("==> PolicyRefresher(serviceName=" + serviceName + ").loadRoles()");
}
//Load the Ranger UserGroup Roles
rolesProvider.loadUserGroupRoles(plugIn);
if(LOG.isDebugEnabled()) {
LOG.debug("<== PolicyRefresher(serviceName=" + serviceName + ").loadRoles()");
}
}
PolicyRefresher#loadUserGroupRoles
public void loadUserGroupRoles(RangerBasePlugin plugIn) {
RangerRoles roles = loadUserGroupRolesFromAdmin();
plugIn.setRoles(null);
}
RangerRolesProvider#loadUserGroupRolesFromAdmin
private RangerRoles loadUserGroupRolesFromAdmin() throws RangerServiceNotFoundException {
roles = rangerAdmin.getRolesIfUpdated(lastKnownRoleVersion, lastActivationTimeInMillis);
return roles;
}