blob: e90c58a418a4d04abe946b97c66335ea57173bad [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.ranger.biz;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.security.SecureClientLogin;
import org.apache.ranger.common.PropertiesUtil;
import org.apache.ranger.common.TimedExecutor;
import org.apache.ranger.db.XXGroupUserDao;
import org.apache.ranger.entity.XXGroupUser;
import org.apache.ranger.plugin.client.HadoopConfigHolder;
import org.apache.ranger.plugin.client.HadoopException;
import org.apache.ranger.plugin.model.RangerSecurityZone;
import org.apache.ranger.plugin.model.RangerService;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.service.RangerBaseService;
import org.apache.ranger.plugin.service.RangerDefaultService;
import org.apache.ranger.plugin.service.ResourceLookupContext;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.store.ServiceStore;
import org.apache.ranger.plugin.util.RangerRoles;
import org.apache.ranger.plugin.util.RangerRolesUtil;
import org.apache.ranger.service.RangerServiceService;
import org.apache.ranger.services.tag.RangerServiceTag;
import org.apache.ranger.view.VXMessage;
import org.apache.ranger.view.VXResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import static org.apache.ranger.plugin.policyengine.RangerPolicyEngine.GROUP_PUBLIC;
@Component
public class ServiceMgr {
private static final Logger LOG = LoggerFactory.getLogger(ServiceMgr.class);
private static final String LOOKUP_PRINCIPAL = "ranger.lookup.kerberos.principal";
private static final String LOOKUP_KEYTAB = "ranger.lookup.kerberos.keytab";
private static final String ADMIN_USER_PRINCIPAL = "ranger.admin.kerberos.principal";
private static final String ADMIN_USER_KEYTAB = "ranger.admin.kerberos.keytab";
private static final String AUTHENTICATION_TYPE = "hadoop.security.authentication";
private static final String KERBEROS_TYPE = "kerberos";
private static final String NAME_RULES = "hadoop.security.auth_to_local";
private static final String HOST_NAME = "ranger.service.host";
private static final long _DefaultTimeoutValue_Lookp = 1000; // 1 s
private static final long _DefaultTimeoutValue_ValidateConfig = 10000; // 10 s
private static final Map<String, Class<? extends RangerBaseService>> serviceTypeClassMap = new HashMap<>();
@Autowired
RangerServiceService rangerSvcService;
@Autowired
ServiceDBStore svcDBStore;
@Autowired
TagDBStore tagStore;
@Autowired
RoleDBStore rolesStore;
@Autowired
TimedExecutor timedExecutor;
@Autowired
RangerBizUtil rangerBizUtil;
@Autowired
SecurityZoneDBStore zoneStore;
@Autowired
XXGroupUserDao groupUserDao;
public List<String> lookupResource(String serviceName, ResourceLookupContext context, ServiceStore svcStore) throws Exception {
List<String> ret = null;
RangerService service = svcDBStore.getServiceByName(serviceName);
String authType = PropertiesUtil.getProperty(AUTHENTICATION_TYPE);
String lookupPrincipal = SecureClientLogin.getPrincipal(PropertiesUtil.getProperty(LOOKUP_PRINCIPAL), PropertiesUtil.getProperty(HOST_NAME));
String lookupKeytab = PropertiesUtil.getProperty(LOOKUP_KEYTAB);
String nameRules = PropertiesUtil.getProperty(NAME_RULES);
String rangerPrincipal = SecureClientLogin.getPrincipal(PropertiesUtil.getProperty(ADMIN_USER_PRINCIPAL), PropertiesUtil.getProperty(HOST_NAME));
String rangerkeytab = PropertiesUtil.getProperty(ADMIN_USER_KEYTAB);
if (!StringUtils.isEmpty(authType) && KERBEROS_TYPE.equalsIgnoreCase(authType.trim()) && SecureClientLogin.isKerberosCredentialExists(lookupPrincipal, lookupKeytab)) {
if (service != null && service.getConfigs() != null) {
service.getConfigs().put(HadoopConfigHolder.RANGER_LOOKUP_PRINCIPAL, lookupPrincipal);
service.getConfigs().put(HadoopConfigHolder.RANGER_LOOKUP_KEYTAB, lookupKeytab);
service.getConfigs().put(HadoopConfigHolder.RANGER_NAME_RULES, nameRules);
service.getConfigs().put(HadoopConfigHolder.RANGER_AUTH_TYPE, authType);
}
}
if (!StringUtils.isEmpty(authType) && KERBEROS_TYPE.equalsIgnoreCase(authType.trim()) && SecureClientLogin.isKerberosCredentialExists(rangerPrincipal, rangerkeytab)) {
if (service != null && service.getConfigs() != null) {
service.getConfigs().put(HadoopConfigHolder.RANGER_PRINCIPAL, rangerPrincipal);
service.getConfigs().put(HadoopConfigHolder.RANGER_KEYTAB, rangerkeytab);
service.getConfigs().put(HadoopConfigHolder.RANGER_NAME_RULES, nameRules);
service.getConfigs().put(HadoopConfigHolder.RANGER_AUTH_TYPE, authType);
}
}
RangerBaseService svc = null;
if (service != null) {
Map<String, String> newConfigs = rangerSvcService.getConfigsWithDecryptedPassword(service);
service.setConfigs(newConfigs);
svc = getRangerServiceByService(service, svcStore);
}
LOG.debug("==> ServiceMgr.lookupResource for Service: ({}Context: {})", svc, context);
if (svc != null) {
if (StringUtils.equals(svc.getServiceDef().getName(), EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME)) {
ret = svc.lookupResource(context);
} else {
LookupCallable callable = new LookupCallable(svc, context);
long time = getTimeoutValueForLookupInMilliSeconds(svc);
ret = timedExecutor.timedTask(callable, time, TimeUnit.MILLISECONDS);
}
}
LOG.debug("==> ServiceMgr.lookupResource for Response: ({})", ret);
return ret;
}
public VXResponse validateConfig(RangerService service, ServiceStore svcStore) throws Exception {
VXResponse ret = new VXResponse();
String authType = PropertiesUtil.getProperty(AUTHENTICATION_TYPE);
String lookupPrincipal = SecureClientLogin.getPrincipal(PropertiesUtil.getProperty(LOOKUP_PRINCIPAL), PropertiesUtil.getProperty(HOST_NAME));
String lookupKeytab = PropertiesUtil.getProperty(LOOKUP_KEYTAB);
String nameRules = PropertiesUtil.getProperty(NAME_RULES);
String rangerPrincipal = SecureClientLogin.getPrincipal(PropertiesUtil.getProperty(ADMIN_USER_PRINCIPAL), PropertiesUtil.getProperty(HOST_NAME));
String rangerkeytab = PropertiesUtil.getProperty(ADMIN_USER_KEYTAB);
if (!StringUtils.isEmpty(authType) && KERBEROS_TYPE.equalsIgnoreCase(authType.trim()) && SecureClientLogin.isKerberosCredentialExists(lookupPrincipal, lookupKeytab)) {
if (service != null && service.getConfigs() != null) {
service.getConfigs().put(HadoopConfigHolder.RANGER_LOOKUP_PRINCIPAL, lookupPrincipal);
service.getConfigs().put(HadoopConfigHolder.RANGER_LOOKUP_KEYTAB, lookupKeytab);
service.getConfigs().put(HadoopConfigHolder.RANGER_NAME_RULES, nameRules);
service.getConfigs().put(HadoopConfigHolder.RANGER_AUTH_TYPE, authType);
}
}
if (!StringUtils.isEmpty(authType) && KERBEROS_TYPE.equalsIgnoreCase(authType.trim()) && SecureClientLogin.isKerberosCredentialExists(rangerPrincipal, rangerkeytab)) {
if (service != null && service.getConfigs() != null) {
service.getConfigs().put(HadoopConfigHolder.RANGER_PRINCIPAL, rangerPrincipal);
service.getConfigs().put(HadoopConfigHolder.RANGER_KEYTAB, rangerkeytab);
service.getConfigs().put(HadoopConfigHolder.RANGER_NAME_RULES, nameRules);
service.getConfigs().put(HadoopConfigHolder.RANGER_AUTH_TYPE, authType);
}
}
RangerBaseService svc = null;
if (service != null) {
Map<String, String> newConfigs = rangerSvcService.getConfigsWithDecryptedPassword(service);
service.setConfigs(newConfigs);
svc = getRangerServiceByService(service, svcStore);
}
LOG.debug("==> ServiceMgr.validateConfig for Service: ({})", svc);
// check if service configs contains localhost/127.0.0.1
if (service != null && service.getConfigs() != null) {
for (Map.Entry<String, String> entry : service.getConfigs().entrySet()) {
if (entry.getValue() != null && StringUtils.containsIgnoreCase(entry.getValue(), "localhost") || StringUtils.containsIgnoreCase(entry.getValue(), "127.0.0.1")) {
URL url = getValidURL(entry.getValue());
if ((url != null) && (url.getHost().equalsIgnoreCase("localhost") || url.getHost().equals("127.0.0.1"))) {
throw new Exception("Invalid value for configuration " + entry.getKey() + ": host " + url.getHost() + " is not allowed");
}
}
}
}
if (svc != null) {
try {
// Timeout value use during validate config is 10 times that used during lookup
long time = getTimeoutValueForValidateConfigInMilliSeconds(svc);
ValidateCallable callable = new ValidateCallable(svc);
Map<String, Object> responseData = timedExecutor.timedTask(callable, time, TimeUnit.MILLISECONDS);
ret = generateResponseForTestConn(responseData, "");
} catch (Exception e) {
Map<String, Object> respData = (e instanceof HadoopException) ? ((HadoopException) e).getResponseData() : new HashMap<>();
String msg;
if (StringUtils.contains(e.getMessage(), RangerDefaultService.ERROR_MSG_VALIDATE_CONFIG_NOT_IMPLEMENTED)) {
msg = RangerDefaultService.ERROR_MSG_VALIDATE_CONFIG_NOT_IMPLEMENTED + " for " + svc.getServiceType();
} else {
msg = "Unable to connect repository with given config for " + svc.getServiceName();
}
ret = generateResponseForTestConn(respData, msg);
LOG.error("==> ServiceMgr.validateConfig Error:{}", String.valueOf(e));
}
}
LOG.debug("==> ServiceMgr.validateConfig for Response: ({})", ret);
return ret;
}
public boolean isZoneAdmin(String zoneName) {
boolean isZoneAdmin = false;
RangerSecurityZone securityZone = null;
try {
securityZone = zoneStore.getSecurityZoneByName(zoneName);
} catch (Exception e) {
LOG.error("Unexpected error when fetching security zone with name:[{}] from database", zoneName, e);
}
if (securityZone != null) {
String userId = rangerBizUtil.getCurrentUserLoginId();
if (securityZone.getAdminUsers() != null && securityZone.getAdminUsers().contains(userId)) {
isZoneAdmin = true;
}
Set<String> loggedInUsersGroups = Collections.emptySet();
if (!isZoneAdmin && securityZone.getAdminUserGroups() != null) {
List<XXGroupUser> groupUsers = groupUserDao.findByUserId(rangerBizUtil.getXUserId());
loggedInUsersGroups = new HashSet<>();
loggedInUsersGroups.add(GROUP_PUBLIC);
if (groupUsers != null) {
for (XXGroupUser groupUser : groupUsers) {
loggedInUsersGroups.add(groupUser.getName());
}
}
isZoneAdmin = CollectionUtils.containsAny(securityZone.getAdminUserGroups(), loggedInUsersGroups);
}
if (!isZoneAdmin && securityZone.getAdminRoles() != null) {
isZoneAdmin = isUserOrUserGroupsInRole(userId, loggedInUsersGroups, securityZone.getAdminRoles());
}
}
return isZoneAdmin;
}
public boolean isZoneAuditor(String zoneName) {
boolean isZoneAuditor = false;
RangerSecurityZone securityZone = null;
try {
securityZone = zoneStore.getSecurityZoneByName(zoneName);
} catch (Exception e) {
LOG.error("Unexpected error when fetching security zone with name:[{}] from database", zoneName, e);
}
if (securityZone != null) {
String userId = rangerBizUtil.getCurrentUserLoginId();
if (securityZone.getAuditUsers() != null && securityZone.getAuditUsers().contains(userId)) {
isZoneAuditor = true;
}
Set<String> loggedInUsersGroups = Collections.emptySet();
if (!isZoneAuditor && securityZone.getAuditUserGroups() != null) {
List<XXGroupUser> groupUsers = groupUserDao.findByUserId(rangerBizUtil.getXUserId());
loggedInUsersGroups = new HashSet<>();
loggedInUsersGroups.add(GROUP_PUBLIC);
if (groupUsers != null) {
for (XXGroupUser groupUser : groupUsers) {
loggedInUsersGroups.add(groupUser.getName());
}
}
isZoneAuditor = CollectionUtils.containsAny(securityZone.getAuditUserGroups(), loggedInUsersGroups);
}
if (!isZoneAuditor && securityZone.getAuditRoles() != null) {
isZoneAuditor = isUserOrUserGroupsInRole(userId, loggedInUsersGroups, securityZone.getAuditRoles());
}
}
return isZoneAuditor;
}
public RangerBaseService getRangerServiceByName(String serviceName, ServiceStore svcStore) throws Exception {
LOG.debug("==> ServiceMgr.getRangerServiceByName({})", serviceName);
RangerBaseService ret = null;
RangerService service = svcStore == null ? null : svcStore.getServiceByName(serviceName);
if (service != null) {
ret = getRangerServiceByService(service, svcStore);
} else {
LOG.warn("ServiceMgr.getRangerServiceByName({}): could not find the service", serviceName);
}
LOG.debug("<== ServiceMgr.getRangerServiceByName({}): {}", serviceName, ret);
return ret;
}
public RangerBaseService getRangerServiceByService(RangerService service, ServiceStore svcStore) throws Exception {
LOG.debug("==> ServiceMgr.getRangerServiceByService({})", service);
RangerBaseService ret = null;
String serviceType = service == null ? null : service.getType();
if (!StringUtils.isEmpty(serviceType)) {
RangerServiceDef serviceDef = svcStore == null ? null : svcStore.getServiceDefByName(serviceType);
if (serviceDef != null) {
Class<? extends RangerBaseService> cls = getClassForServiceType(serviceDef);
if (cls != null) {
ret = cls.newInstance();
ret.init(serviceDef, service);
if (ret instanceof RangerServiceTag) {
((RangerServiceTag) ret).setTagStore(tagStore);
}
} else {
LOG.warn("ServiceMgr.getRangerServiceByService({}): could not find service class '{}' for the service type '{}'", service, serviceDef.getImplClass(), serviceType);
}
} else {
LOG.warn("ServiceMgr.getRangerServiceByService({}): could not find the service-def for the service type '{}'", service, serviceType);
}
} else {
LOG.warn("ServiceMgr.getRangerServiceByService({}): could not find the service-type '{}'", service, serviceType);
}
LOG.debug("<== ServiceMgr.getRangerServiceByService({}): {}", service, ret);
return ret;
}
long getTimeoutValueForLookupInMilliSeconds(RangerBaseService svc) {
return getTimeoutValueInMilliSeconds("resource.lookup", svc, _DefaultTimeoutValue_Lookp);
}
long getTimeoutValueForValidateConfigInMilliSeconds(RangerBaseService svc) {
return getTimeoutValueInMilliSeconds("validate.config", svc, _DefaultTimeoutValue_ValidateConfig);
}
long getTimeoutValueInMilliSeconds(final String type, RangerBaseService svc, long defaultValue) {
LOG.debug("==> ServiceMgr.getTimeoutValueInMilliSeconds ({}, {})", type, svc);
String propertyName = type + ".timeout.value.in.ms"; // type == "lookup" || type == "validate-config"
Long result = null;
Map<String, String> config = svc.getConfigs();
if (config != null && config.containsKey(propertyName)) {
result = parseLong(config.get(propertyName));
}
if (result != null) {
LOG.debug("Found override in service config!");
} else {
String[] keys = new String[] {
"ranger.service." + svc.getServiceName() + "." + propertyName,
"ranger.servicetype." + svc.getServiceType() + "." + propertyName,
"ranger." + propertyName
};
for (String key : keys) {
String value = PropertiesUtil.getProperty(key);
if (value != null) {
result = parseLong(value);
if (result != null) {
LOG.debug("Using the value[{}] found in property[{}]", value, key);
break;
}
}
}
}
if (result == null) {
LOG.debug("No overrides found in service config of properties file. Using supplied default of[{}]!", defaultValue);
result = defaultValue;
}
LOG.debug("<== ServiceMgr.getTimeoutValueInMilliSeconds ({}, {}): {}", type, svc, result);
return result;
}
Long parseLong(String str) {
try {
return Long.valueOf(str);
} catch (NumberFormatException e) {
LOG.debug("ServiceMgr.parseLong: could not parse [{}] as Long! Returning null", str);
return null;
}
}
private static URL getValidURL(String urlString) {
try {
return new URL(urlString);
} catch (Exception e) {
return null;
}
}
@SuppressWarnings("unchecked")
private Class<? extends RangerBaseService> getClassForServiceType(RangerServiceDef serviceDef) {
LOG.debug("==> ServiceMgr.getClassForServiceType({})", serviceDef);
Class<? extends RangerBaseService> ret = null;
if (serviceDef != null) {
String serviceType = serviceDef.getName();
ret = serviceTypeClassMap.get(serviceType);
if (ret == null) {
synchronized (serviceTypeClassMap) {
ret = serviceTypeClassMap.get(serviceType);
if (ret == null) {
String clsName = serviceDef.getImplClass();
LOG.debug("ServiceMgr.getClassForServiceType({}): service-class {} not found in cache", serviceType, clsName);
try {
if (StringUtils.isEmpty(clsName)) {
LOG.debug("No service-class configured for service-type:[{}], using RangerDefaultService", serviceType);
ret = RangerDefaultService.class;
} else {
URL[] pluginFiles = getPluginFilesForServiceType(serviceType);
URLClassLoader clsLoader = new URLClassLoader(pluginFiles, Thread.currentThread().getContextClassLoader());
Class<?> cls = Class.forName(clsName, true, clsLoader);
ret = (Class<? extends RangerBaseService>) cls;
}
} catch (Exception excp) {
LOG.warn("ServiceMgr.getClassForServiceType({}): failed to find service-class '{}'. Resource lookup will not be available. Using RangerDefaultService", serviceType, clsName, excp);
ret = RangerDefaultService.class;
}
serviceTypeClassMap.put(serviceType, ret);
LOG.debug("ServiceMgr.getClassForServiceType({}): service-class {} added to cache", serviceType, ret.getCanonicalName());
} else {
LOG.debug("ServiceMgr.getClassForServiceType({}): service-class {} found in cache", serviceType, ret.getCanonicalName());
}
}
} else {
LOG.debug("ServiceMgr.getClassForServiceType({}): service-class {} found in cache", serviceType, ret.getCanonicalName());
}
}
LOG.debug("<== ServiceMgr.getClassForServiceType({}): {}", serviceDef, ret);
return ret;
}
private URL[] getPluginFilesForServiceType(String serviceType) {
LOG.debug("==> ServiceMgr.getPluginFilesForServiceType({})", serviceType);
List<URL> ret = new ArrayList<>();
getFilesInDirectory("ranger-plugins/" + serviceType, ret);
LOG.debug("<== ServiceMgr.getPluginFilesForServiceType({}): {} files", serviceType, ret.size());
return ret.toArray(new URL[] {});
}
private void getFilesInDirectory(String dirPath, List<URL> files) {
LOG.debug("==> ServiceMgr.getFilesInDirectory({})", dirPath);
URL pluginJarPath = getClass().getClassLoader().getResource(dirPath);
if (pluginJarPath != null && "file".equals(pluginJarPath.getProtocol())) {
try {
File[] dirFiles = new File(pluginJarPath.toURI()).listFiles();
if (dirFiles != null) {
for (File dirFile : dirFiles) {
try {
URL jarPath = dirFile.toURI().toURL();
LOG.debug("getFilesInDirectory('{}'): adding {}", dirPath, dirFile.getAbsolutePath());
files.add(jarPath);
} catch (Exception excp) {
LOG.warn("getFilesInDirectory('{}'): failed to get URI for file {}", dirPath, dirFile.getAbsolutePath(), excp);
}
}
}
} catch (Exception excp) {
LOG.warn("getFilesInDirectory('{}'): error", dirPath, excp);
}
} else {
LOG.debug("getFilesInDirectory('{}'): could not find directory in CLASSPATH", dirPath);
}
LOG.debug("<== ServiceMgr.getFilesInDirectory({})", dirPath);
}
private VXResponse generateResponseForTestConn(Map<String, Object> responseData, String msg) {
VXResponse vXResponse = new VXResponse();
Long objId = null;
boolean connectivityStatus = false;
int statusCode = VXResponse.STATUS_ERROR;
String message = msg;
String description = msg;
String fieldName = null;
if (responseData != null) {
if (responseData.get("objectId") != null) {
objId = Long.parseLong(responseData.get("objectId").toString());
}
if (responseData.get("connectivityStatus") != null) {
connectivityStatus = Boolean.parseBoolean(responseData.get("connectivityStatus").toString());
}
if (connectivityStatus) {
statusCode = VXResponse.STATUS_SUCCESS;
}
if (responseData.get("message") != null) {
message = responseData.get("message").toString();
}
if (responseData.get("description") != null) {
description = responseData.get("description").toString();
}
if (responseData.get("fieldName") != null) {
fieldName = responseData.get("fieldName").toString();
}
}
VXMessage vXMsg = new VXMessage();
List<VXMessage> vXMsgList = new ArrayList<>();
vXMsg.setFieldName(fieldName);
vXMsg.setMessage(message);
vXMsg.setObjectId(objId);
vXMsgList.add(vXMsg);
vXResponse.setMessageList(vXMsgList);
vXResponse.setMsgDesc(description);
vXResponse.setStatusCode(statusCode);
return vXResponse;
}
private boolean isUserOrUserGroupsInRole(String userId, Set<String> userGroups, List<String> roles) {
boolean ret = false;
RangerRoles rangerRoles = null;
try {
rangerRoles = rolesStore.getRoles("", -1L);
} catch (Exception excp) {
LOG.error("Unexpected error when fetching roles from database", excp);
}
if (rangerRoles != null) {
RangerRolesUtil rolesUtil = new RangerRolesUtil(rangerRoles);
Set<String> userRoles = rolesUtil.getUserRoleMapping().get(userId);
ret = userRoles != null && CollectionUtils.containsAny(roles, userRoles);
if (!ret && userGroups != null) {
for (String userGroup : userGroups) {
Set<String> groupRoles = rolesUtil.getGroupRoleMapping().get(userGroup);
ret = groupRoles != null && CollectionUtils.containsAny(roles, groupRoles);
if (ret) {
break;
}
}
}
}
return ret;
}
abstract static class TimedCallable<T> implements Callable<T> {
final RangerBaseService svc;
final Date creation; // NOTE: This would be different from when the callable was actually offered to the executor
public TimedCallable(RangerBaseService svc) {
this.svc = svc;
this.creation = new Date();
}
@Override
public T call() throws Exception {
Date start = null;
if (LOG.isDebugEnabled()) {
start = new Date();
LOG.debug("==> TimedCallable: {}", this);
}
ClassLoader clsLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(svc.getClass().getClassLoader());
return actualCall();
} catch (Exception e) {
LOG.error("TimedCallable.call: Error:{}", String.valueOf(e));
throw e;
} finally {
Thread.currentThread().setContextClassLoader(clsLoader);
if (start != null) {
Date finish = new Date();
long waitTime = start.getTime() - creation.getTime();
long executionTime = finish.getTime() - start.getTime();
LOG.debug("<== TimedCallable: {}: wait time[{} ms], execution time [{} ms]", this, waitTime, executionTime);
}
}
}
abstract T actualCall() throws Exception;
}
static class LookupCallable extends TimedCallable<List<String>> {
final ResourceLookupContext context;
public LookupCallable(final RangerBaseService svc, final ResourceLookupContext context) {
super(svc);
this.context = context;
}
@Override
public String toString() {
return String.format("lookup resource[%s] for service[%s], ", context.toString(), svc.getServiceName());
}
@Override
public List<String> actualCall() throws Exception {
return svc.lookupResource(context);
}
}
static class ValidateCallable extends TimedCallable<Map<String, Object>> {
public ValidateCallable(RangerBaseService svc) {
super(svc);
}
@Override
public String toString() {
return String.format("validate config for service[%s]", svc.getServiceName());
}
@Override
public Map<String, Object> actualCall() throws Exception {
return svc.validateConfig();
}
}
}