| /* |
| * 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.services.atlas; |
| |
| import java.security.PrivilegedAction; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import com.google.gson.Gson; |
| import com.sun.jersey.api.client.Client; |
| import com.sun.jersey.api.client.ClientResponse; |
| import com.sun.jersey.api.client.WebResource; |
| import com.sun.jersey.core.util.MultivaluedMapImpl; |
| import org.apache.atlas.model.discovery.AtlasSearchResult; |
| import org.apache.atlas.model.instance.AtlasEntityHeader; |
| import org.apache.commons.io.FilenameUtils; |
| import org.apache.commons.io.IOCase; |
| import org.apache.commons.lang.StringUtils; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.ranger.plugin.client.BaseClient; |
| import org.apache.ranger.plugin.client.HadoopException; |
| import org.apache.ranger.plugin.model.RangerPolicy; |
| import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem; |
| import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess; |
| import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; |
| import org.apache.ranger.plugin.model.RangerService; |
| import org.apache.ranger.plugin.model.RangerServiceDef; |
| import org.apache.ranger.plugin.policyengine.RangerPolicyEngine; |
| import org.apache.ranger.plugin.service.RangerBaseService; |
| import org.apache.ranger.plugin.service.ResourceLookupContext; |
| import org.apache.ranger.plugin.util.PasswordUtils; |
| import javax.security.auth.Subject; |
| import javax.ws.rs.core.MultivaluedMap; |
| import javax.ws.rs.core.NewCookie; |
| |
| public class RangerServiceAtlas extends RangerBaseService { |
| private static final Log LOG = LogFactory.getLog(RangerServiceAtlas.class); |
| |
| public static final String RESOURCE_SERVICE = "atlas-service"; |
| public static final String RESOURCE_TYPE_CATEGORY = "type-category"; |
| public static final String RESOURCE_TYPE_NAME = "type"; |
| public static final String RESOURCE_ENTITY_TYPE = "entity-type"; |
| public static final String RESOURCE_ENTITY_CLASSIFICATION = "entity-classification"; |
| public static final String RESOURCE_ENTITY_ID = "entity"; |
| public static final String RESOURCE_ENTITY_OWNER = "owner"; |
| public static final String RESOURCE_RELATIONSHIP_TYPE = "relationship-type"; |
| public static final String RESOURCE_END_ONE_ENTITY_TYPE = "end-one-entity-type"; |
| public static final String RESOURCE_END_ONE_ENTITY_CLASSIFICATION = "end-one-entity-classification"; |
| public static final String RESOURCE_END_ONE_ENTITY_ID = "end-one-entity"; |
| public static final String RESOURCE_END_TWO_ENTITY_TYPE = "end-two-entity-type"; |
| public static final String RESOURCE_END_TWO_ENTITY_CLASSIFICATION = "end-two-entity-classification"; |
| public static final String RESOURCE_END_TWO_ENTITY_ID = "end-two-entity"; |
| public static final String SEARCH_FEATURE_POLICY_NAME = "Allow users to manage favorite searches"; |
| |
| public static final String ACCESS_TYPE_ENTITY_READ = "entity-read"; |
| public static final String ACCESS_TYPE_ENTITY_CREATE = "entity-create"; |
| public static final String ACCESS_TYPE_ENTITY_UPDATE = "entity-update"; |
| public static final String ACCESS_TYPE_ENTITY_DELETE = "entity-delete"; |
| public static final String ADMIN_USERNAME_DEFAULT = "admin"; |
| public static final String TAGSYNC_USERNAME_DEFAULT = "rangertagsync"; |
| public static final String ENTITY_TYPE_USER_PROFILE = "__AtlasUserProfile"; |
| public static final String ENTITY_TYPE_SAVED_SEARCH = "__AtlasUserSavedSearch"; |
| public static final String ENTITY_ID_USER_PROFILE = RangerPolicyEngine.USER_CURRENT; |
| public static final String ENTITY_ID_USER_SAVED_SEARCH= RangerPolicyEngine.USER_CURRENT + ":*"; |
| |
| |
| public static final String CONFIG_REST_ADDRESS = "atlas.rest.address"; |
| public static final String CONFIG_USERNAME = "username"; |
| public static final String CONFIG_PASSWORD = "password"; |
| public static final String ENTITY_NOT_CLASSIFIED = "_NOT_CLASSIFIED"; |
| |
| private static final String TYPE_ENTITY = "entity"; |
| private static final String TYPE_CLASSIFICATION = "classification"; |
| private static final String TYPE_STRUCT = "struct"; |
| private static final String TYPE_ENUM = "enum"; |
| private static final String TYPE_RELATIONSHIP = "relationship"; |
| |
| private static final String URL_LOGIN = "/j_spring_security_check"; |
| private static final String URL_GET_TYPESDEF_HEADERS = "/api/atlas/v2/types/typedefs/headers"; |
| private static final String URl_ENTITY_SEARCH = "v2/search/attribute?attrName=qualifiedName"; |
| |
| private static final String WEB_RESOURCE_CONTENT_TYPE = "application/x-www-form-urlencoded"; |
| private static final String CONNECTION_ERROR_MSG = " You can still save the repository and start creating" |
| + " policies, but you would not be able to use autocomplete for" |
| + " resource names. Check ranger_admin.log for more info."; |
| |
| public RangerServiceAtlas() { |
| super(); |
| } |
| |
| @Override |
| public void init(RangerServiceDef serviceDef, RangerService service) { |
| super.init(serviceDef, service); |
| } |
| |
| @Override |
| public Map<String, Object> validateConfig() throws Exception { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("==> RangerServiceAtlas.validateConfig()"); |
| } |
| |
| AtlasServiceClient client = new AtlasServiceClient(getServiceName(), configs); |
| Map<String, Object> ret = client.validateConfig(); |
| |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("<== RangerServiceAtlas.validateConfig(): " + ret ); |
| } |
| |
| return ret; |
| } |
| |
| @Override |
| public List<String> lookupResource(ResourceLookupContext context)throws Exception { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("==> RangerServiceAtlas.lookupResource(" + context + ")"); |
| } |
| |
| AtlasServiceClient client = new AtlasServiceClient(getServiceName(), configs); |
| List<String> ret = client.lookupResource(context); |
| |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("<== RangerServiceAtlas.lookupResource("+ context + "): " + ret); |
| } |
| |
| return ret; |
| } |
| |
| @Override |
| public List<RangerPolicy> getDefaultRangerPolicies() throws Exception { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("==> RangerServiceAtlas.getDefaultRangerPolicies()"); |
| } |
| |
| List<RangerPolicy> ret = super.getDefaultRangerPolicies(); |
| String adminUser = getStringConfig("atlas.admin.user", ADMIN_USERNAME_DEFAULT); |
| String tagSyncUser = getStringConfig("atlas.rangertagsync.user", TAGSYNC_USERNAME_DEFAULT); |
| |
| boolean relationshipTypeAllowPublic = getBooleanConfig("atlas.default-policy.relationship-type.allow.public", true); |
| |
| |
| for (RangerPolicy defaultPolicy : ret) { |
| final Map<String, RangerPolicyResource> policyResources = defaultPolicy.getResources(); |
| |
| // 1. add adminUser to every policyItem |
| for (RangerPolicyItem defaultPolicyItem : defaultPolicy.getPolicyItems()) { |
| defaultPolicyItem.getUsers().add(adminUser); |
| } |
| |
| // 2. add a policy-item for rangertagsync user with 'entity-read' permission in the policy for 'entity-type' |
| if (policyResources.containsKey(RangerServiceAtlas.RESOURCE_ENTITY_TYPE)) { |
| RangerPolicyItem policyItemForTagSyncUser = new RangerPolicyItem(); |
| |
| policyItemForTagSyncUser.setUsers(Collections.singletonList(tagSyncUser)); |
| policyItemForTagSyncUser.setGroups(Collections.singletonList(RangerPolicyEngine.GROUP_PUBLIC)); |
| policyItemForTagSyncUser.setAccesses(Collections.singletonList(new RangerPolicyItemAccess(ACCESS_TYPE_ENTITY_READ))); |
| |
| defaultPolicy.getPolicyItems().add(policyItemForTagSyncUser); |
| } |
| |
| if (relationshipTypeAllowPublic) { |
| // 3. add 'public' group in the policy for 'relationship-type', |
| if (policyResources.containsKey(RangerServiceAtlas.RESOURCE_RELATIONSHIP_TYPE)) { |
| for (RangerPolicyItem defaultPolicyItem : defaultPolicy.getPolicyItems()) { |
| defaultPolicyItem.getGroups().add(RangerPolicyEngine.GROUP_PUBLIC); |
| } |
| } |
| } |
| |
| if (defaultPolicy.getName().contains("all") |
| && policyResources.containsKey(RangerServiceAtlas.RESOURCE_ENTITY_TYPE) |
| && StringUtils.isNotBlank(lookUpUser)) { |
| RangerPolicyItem policyItemForLookupUser = new RangerPolicyItem(); |
| policyItemForLookupUser.setUsers(Collections.singletonList(lookUpUser)); |
| policyItemForLookupUser.setAccesses(Collections.singletonList(new RangerPolicyItemAccess(ACCESS_TYPE_ENTITY_READ))); |
| policyItemForLookupUser.setDelegateAdmin(false); |
| defaultPolicy.getPolicyItems().add(policyItemForLookupUser); |
| } |
| } |
| |
| //4.add new policy for public group with entity-read, entity-create, entity-update, entity-delete for __AtlasUserProfile, __AtlasUserSavedSearch entity type |
| RangerPolicy searchFeaturePolicy = getSearchFeaturePolicy(); |
| ret.add(searchFeaturePolicy); |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("<== RangerServiceAtlas.getDefaultRangerPolicies()"); |
| } |
| |
| return ret; |
| } |
| |
| private RangerPolicy getSearchFeaturePolicy() { |
| RangerPolicy searchFeaturePolicy = new RangerPolicy(); |
| |
| searchFeaturePolicy.setName(SEARCH_FEATURE_POLICY_NAME); |
| searchFeaturePolicy.setService(serviceName); |
| searchFeaturePolicy.setResources(getSearchFeaturePolicyResource()); |
| searchFeaturePolicy.setPolicyItems(getSearchFeaturePolicyItem()); |
| |
| return searchFeaturePolicy; |
| } |
| |
| private List<RangerPolicyItem> getSearchFeaturePolicyItem() { |
| List<RangerPolicyItemAccess> accesses = new ArrayList<RangerPolicyItemAccess>(); |
| |
| accesses.add(new RangerPolicyItemAccess(ACCESS_TYPE_ENTITY_READ)); |
| accesses.add(new RangerPolicyItemAccess(ACCESS_TYPE_ENTITY_CREATE)); |
| accesses.add(new RangerPolicyItemAccess(ACCESS_TYPE_ENTITY_UPDATE)); |
| accesses.add(new RangerPolicyItemAccess(ACCESS_TYPE_ENTITY_DELETE)); |
| |
| RangerPolicyItem item = new RangerPolicyItem(accesses, Arrays.asList(RangerPolicyEngine.USER_CURRENT), null, null, null, false); |
| |
| return Collections.singletonList(item); |
| } |
| |
| private Map<String, RangerPolicyResource> getSearchFeaturePolicyResource() { |
| Map<String, RangerPolicyResource> resources = new HashMap<>(); |
| |
| resources.put(RESOURCE_ENTITY_TYPE, new RangerPolicyResource(Arrays.asList(ENTITY_TYPE_USER_PROFILE, ENTITY_TYPE_SAVED_SEARCH), false, false)); |
| resources.put(RESOURCE_ENTITY_CLASSIFICATION, new RangerPolicyResource("*")); |
| resources.put(RESOURCE_ENTITY_ID, new RangerPolicyResource(Arrays.asList(ENTITY_ID_USER_PROFILE, ENTITY_ID_USER_SAVED_SEARCH), false, false)); |
| |
| return resources; |
| } |
| |
| private static class AtlasServiceClient extends BaseClient { |
| private static final String[] TYPE_CATEGORIES = new String[] { "classification", "enum", "entity", "relationship", "struct" }; |
| |
| Map<String, List<String>> typesDef = new HashMap<>(); |
| |
| public AtlasServiceClient(String serviceName, Map<String, String> serviceConfig) { |
| super(serviceName, serviceConfig); |
| } |
| |
| public Map<String, Object> validateConfig() { |
| Map<String, Object> ret = new HashMap<>(); |
| |
| loginToAtlas(Client.create()); |
| |
| BaseClient.generateResponseDataMap(true, "ConnectionTest Successful", "ConnectionTest Successful", null, null, ret); |
| |
| return ret; |
| } |
| |
| public List<String> lookupResource(ResourceLookupContext lookupContext) { |
| final List<String> ret = new ArrayList<>(); |
| final String userInput = lookupContext.getUserInput(); |
| final List<String> currentValues = lookupContext.getResources().get(lookupContext.getResourceName()); |
| |
| switch(lookupContext.getResourceName()) { |
| case RESOURCE_TYPE_CATEGORY: { |
| for (String typeCategory : TYPE_CATEGORIES) { |
| addIfStartsWithAndNotExcluded(ret, typeCategory, userInput, currentValues); |
| } |
| } |
| break; |
| |
| case RESOURCE_TYPE_NAME: { |
| refreshTypesDefs(); |
| |
| final List<String> typeCategories = lookupContext.getResources().get(RESOURCE_TYPE_CATEGORY); |
| |
| if (emptyOrContainsMatch(typeCategories, TYPE_CLASSIFICATION)) { |
| addIfStartsWithAndNotExcluded(ret, typesDef.get(TYPE_CLASSIFICATION), userInput, currentValues); |
| } |
| |
| if (emptyOrContainsMatch(typeCategories, TYPE_ENTITY)) { |
| addIfStartsWithAndNotExcluded(ret, typesDef.get(TYPE_ENTITY), userInput, currentValues); |
| } |
| |
| if (emptyOrContainsMatch(typeCategories, TYPE_ENUM)) { |
| addIfStartsWithAndNotExcluded(ret, typesDef.get(TYPE_ENUM), userInput, currentValues); |
| } |
| |
| if (emptyOrContainsMatch(typeCategories, TYPE_STRUCT)) { |
| addIfStartsWithAndNotExcluded(ret, typesDef.get(TYPE_STRUCT), userInput, currentValues); |
| } |
| |
| if (emptyOrContainsMatch(typeCategories, TYPE_RELATIONSHIP)) { |
| addIfStartsWithAndNotExcluded(ret, typesDef.get(TYPE_RELATIONSHIP), userInput, currentValues); |
| } |
| } |
| break; |
| |
| case RESOURCE_END_ONE_ENTITY_TYPE: |
| case RESOURCE_END_TWO_ENTITY_TYPE: |
| case RESOURCE_ENTITY_TYPE: { |
| refreshTypesDefs(); |
| |
| addIfStartsWithAndNotExcluded(ret, typesDef.get(TYPE_ENTITY), userInput, currentValues); |
| } |
| break; |
| |
| case RESOURCE_END_ONE_ENTITY_CLASSIFICATION: |
| case RESOURCE_END_TWO_ENTITY_CLASSIFICATION: |
| case RESOURCE_ENTITY_CLASSIFICATION: { |
| refreshTypesDefs(); |
| |
| addIfStartsWithAndNotExcluded(ret, typesDef.get(TYPE_CLASSIFICATION), userInput, currentValues); |
| } |
| break; |
| |
| case RESOURCE_ENTITY_ID: { |
| List<String> searchTypes = lookupContext.getResources().get("entity-type"); |
| |
| if (searchTypes != null && searchTypes.size() == 1) { |
| List<String> values = searchEntities(userInput, searchTypes.get(0)); |
| |
| addIfStartsWithAndNotExcluded(ret, values, userInput, currentValues); |
| } |
| } |
| break; |
| |
| case RESOURCE_RELATIONSHIP_TYPE: { |
| refreshTypesDefs(); |
| addIfStartsWithAndNotExcluded(ret, typesDef.get(TYPE_RELATIONSHIP), userInput, currentValues); |
| |
| } |
| break; |
| |
| case RESOURCE_END_ONE_ENTITY_ID: { |
| |
| List<String> searchTypes = lookupContext.getResources().get(RESOURCE_END_ONE_ENTITY_TYPE); |
| |
| if (searchTypes != null && searchTypes.size() == 1) { |
| List<String> values = searchEntities(userInput, searchTypes.get(0)); |
| |
| addIfStartsWithAndNotExcluded(ret, values, userInput, currentValues); |
| } |
| |
| } |
| break; |
| |
| case RESOURCE_END_TWO_ENTITY_ID: { |
| List<String> searchTypes = lookupContext.getResources().get(RESOURCE_END_TWO_ENTITY_TYPE); |
| |
| if (searchTypes != null && searchTypes.size() == 1) { |
| List<String> values = searchEntities(userInput, searchTypes.get(0)); |
| |
| addIfStartsWithAndNotExcluded(ret, values, userInput, currentValues); |
| } |
| } |
| break; |
| |
| default: { |
| ret.add(lookupContext.getResourceName()); |
| } |
| } |
| |
| return ret; |
| } |
| |
| private ClientResponse loginToAtlas(Client client) { |
| ClientResponse ret = null; |
| HadoopException excp = null; |
| String loginUrl = null; |
| |
| for (String atlasUrl : getAtlasUrls()) { |
| try { |
| loginUrl = atlasUrl + URL_LOGIN; |
| |
| WebResource webResource = client.resource(loginUrl); |
| MultivaluedMap<String, String> formData = new MultivaluedMapImpl(); |
| String password = null; |
| |
| try { |
| password = PasswordUtils.decryptPassword(getPassword()); |
| } catch (Exception ex) { |
| LOG.info("Password decryption failed; trying Atlas connection with received password string"); |
| } |
| |
| if (password == null) { |
| password = getPassword(); |
| } |
| |
| formData.add("j_username", getUserName()); |
| formData.add("j_password", password); |
| |
| try { |
| ret = webResource.type(WEB_RESOURCE_CONTENT_TYPE).post(ClientResponse.class, formData); |
| } catch (Exception e) { |
| LOG.error("failed to login to Atlas at " + loginUrl, e); |
| } |
| |
| if (ret != null) { |
| break; |
| } |
| } catch (Throwable t) { |
| String msgDesc = "Exception while login to Atlas at : " + loginUrl; |
| |
| LOG.error(msgDesc, t); |
| |
| excp = new HadoopException(msgDesc, t); |
| |
| excp.generateResponseDataMap(false, BaseClient.getMessage(t), msgDesc + CONNECTION_ERROR_MSG, null, null); |
| } |
| } |
| |
| if (ret == null) { |
| if (excp == null) { |
| String msgDesc = "Exception while login to Atlas at : " + loginUrl; |
| |
| excp = new HadoopException(msgDesc); |
| |
| excp.generateResponseDataMap(false, "", msgDesc + CONNECTION_ERROR_MSG, null, null); |
| } |
| |
| throw excp; |
| } |
| |
| return ret; |
| } |
| |
| private boolean refreshTypesDefs() { |
| boolean ret = false; |
| Subject subj = getLoginSubject(); |
| |
| if (subj == null) { |
| return ret; |
| } |
| |
| Map<String, List<String>> typesDef = Subject.doAs(subj, new PrivilegedAction<Map<String, List<String>>>() { |
| @Override |
| public Map<String, List<String>> run() { |
| Map<String, List<String>> ret = null; |
| |
| for (String atlasUrl : getAtlasUrls()) { |
| Client client = null; |
| |
| try { |
| client = Client.create(); |
| |
| ClientResponse loginResponse = loginToAtlas(client); |
| WebResource webResource = client.resource(atlasUrl + URL_GET_TYPESDEF_HEADERS); |
| WebResource.Builder builder = webResource.getRequestBuilder(); |
| |
| for (NewCookie cook : loginResponse.getCookies()) { |
| builder = builder.cookie(cook); |
| } |
| |
| ClientResponse response = builder.get(ClientResponse.class); |
| |
| if (response != null) { |
| String jsonString = response.getEntity(String.class); |
| Gson gson = new Gson(); |
| List types = gson.fromJson(jsonString, List.class); |
| |
| ret = new HashMap<>(); |
| |
| for (Object type : types) { |
| if (type instanceof Map) { |
| Map typeDef = (Map) type; |
| Object name = typeDef.get("name"); |
| Object category = typeDef.get("category"); |
| |
| if (name != null && category != null) { |
| String strCategory = category.toString().toLowerCase(); |
| List<String> categoryList = ret.get(strCategory); |
| |
| if (categoryList == null) { |
| categoryList = new ArrayList<>(); |
| |
| ret.put(strCategory, categoryList); |
| } |
| |
| categoryList.add(name.toString()); |
| } |
| } |
| } |
| |
| break; |
| } |
| } catch (Throwable t) { |
| String msgDesc = "Exception while getting Atlas Resource List."; |
| |
| LOG.error(msgDesc, t); |
| } finally { |
| if (client != null) { |
| client.destroy(); |
| } |
| } |
| } |
| |
| return ret; |
| } |
| }); |
| |
| if (typesDef != null) { |
| this.typesDef = typesDef; |
| |
| ret = true; |
| } |
| |
| return ret; |
| } |
| |
| private List<String> searchEntities(String userInput, String entityType) { |
| if( LOG.isDebugEnabled()) { |
| LOG.debug("==> RangerServiceAtlas.searchEntities(userInput=" + userInput + ", entityType=" + entityType + ")"); |
| } |
| |
| Subject subj = getLoginSubject(); |
| |
| if (subj == null) { |
| return null; |
| } |
| |
| List<String> list = Subject.doAs(subj, new PrivilegedAction<List<String>>() { |
| @Override |
| public List<String> run() { |
| List<String> ret = null; |
| |
| for (String atlasUrl : getAtlasUrls()) { |
| Client client = null; |
| |
| try { |
| client = Client.create(); |
| |
| ClientResponse loginResponse = loginToAtlas(client); |
| String entitySearcApiUrl = atlasUrl + "/api/atlas/" + URl_ENTITY_SEARCH; |
| StringBuilder searchUrl = new StringBuilder(); |
| |
| searchUrl.append(entitySearcApiUrl) |
| .append("&typeName=") |
| .append(entityType) |
| .append("&attrValuePrefix=" + userInput + "&limit=25"); |
| |
| |
| WebResource webResource = client.resource(searchUrl.toString()); |
| WebResource.Builder builder = webResource.getRequestBuilder(); |
| |
| for (NewCookie cook : loginResponse.getCookies()) { |
| builder = builder.cookie(cook); |
| } |
| |
| ClientResponse response = builder.get(ClientResponse.class); |
| |
| if (response != null) { |
| String jsonString = response.getEntity(String.class); |
| Gson gson = new Gson(); |
| AtlasSearchResult searchResult = gson.fromJson(jsonString, AtlasSearchResult.class); |
| |
| ret = new ArrayList<>(); |
| |
| if (searchResult != null) { |
| List<AtlasEntityHeader> entityHeaderList = searchResult.getEntities(); |
| |
| for (AtlasEntityHeader entity : entityHeaderList) { |
| ret.add((String) entity.getAttribute("qualifiedName")); |
| } |
| } |
| } |
| } catch (Throwable t) { |
| String msgDesc = "Exception while getting Atlas Entity Resource List."; |
| |
| LOG.error(msgDesc, t); |
| } finally { |
| if (client != null) { |
| client.destroy(); |
| } |
| } |
| } |
| |
| return ret; |
| } |
| }); |
| |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("<== RangerServiceAtlas.searchEntities(userInput=" + userInput + ", entityType=" + entityType + "): " + list); |
| } |
| |
| return list; |
| } |
| |
| String[] getAtlasUrls() { |
| String urlString = connectionProperties.get(CONFIG_REST_ADDRESS); |
| String[] ret = urlString == null ? new String[0] : urlString.split(","); |
| |
| // remove separator at the end |
| for (int i = 0; i < ret.length; i++) { |
| String url = ret[i]; |
| |
| while (url.length() > 0 && url.charAt(url.length() - 1) == '/') { |
| url = url.substring(0, url.length() - 1); |
| } |
| |
| ret[i] = url; |
| } |
| |
| return ret; |
| } |
| |
| String getUserName() { |
| return connectionProperties.get(CONFIG_USERNAME); |
| } |
| |
| String getPassword() { |
| return connectionProperties.get(CONFIG_PASSWORD); |
| } |
| |
| boolean emptyOrContainsMatch(List<String> list, String value) { |
| if (list == null || list.isEmpty()) { |
| return true; |
| } |
| |
| for (String item : list) { |
| if (StringUtils.equalsIgnoreCase(item, value) || FilenameUtils.wildcardMatch(value, item, IOCase.INSENSITIVE)) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| void addIfStartsWithAndNotExcluded(List<String> list, List<String> values, String prefix, List<String> excludeList) { |
| if (list == null) { |
| return; |
| } |
| |
| if (values == null) { |
| addIfStartsWithAndNotExcluded(list, ENTITY_NOT_CLASSIFIED, prefix, excludeList); |
| } else { |
| for (String value : values) { |
| addIfStartsWithAndNotExcluded(list, value, prefix, excludeList); |
| } |
| } |
| } |
| |
| void addIfStartsWithAndNotExcluded(List<String> list, String value, String prefix, List<String> excludeList) { |
| if (value == null || list == null) { |
| return; |
| } |
| |
| if (prefix != null && !value.startsWith(prefix)) { |
| return; |
| } |
| |
| if (excludeList != null && excludeList.contains(value)) { |
| return; |
| } |
| |
| list.add(value); |
| } |
| } |
| |
| String getStringConfig(String configName, String defaultValue) { |
| String val = service.getConfigs().get(configName); |
| |
| return StringUtils.isBlank(val) ? defaultValue : val; |
| } |
| |
| boolean getBooleanConfig(String configName, boolean defaultValue) { |
| String val = service.getConfigs().get(configName); |
| |
| return StringUtils.isBlank(val) ? defaultValue : Boolean.parseBoolean(val); |
| } |
| } |