org.apache.ranger.common.RangerSearchUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.ranger.common.RangerSearchUtil.java

Source

/*
 * 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.common;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.ranger.plugin.util.SearchFilter;
import org.springframework.stereotype.Component;

@Component
public class RangerSearchUtil extends SearchUtil {
    final static Logger logger = Logger.getLogger(RangerSearchUtil.class);

    public SearchFilter getSearchFilter(HttpServletRequest request, List<SortField> sortFields) {
        if (request == null) {
            return null;
        }

        SearchFilter ret = new SearchFilter();

        if (MapUtils.isEmpty(request.getParameterMap())) {
            ret.setParams(new HashMap<String, String>());
        }

        ret.setParam(SearchFilter.SERVICE_TYPE, request.getParameter(SearchFilter.SERVICE_TYPE));
        ret.setParam(SearchFilter.SERVICE_TYPE_ID, request.getParameter(SearchFilter.SERVICE_TYPE_ID));
        ret.setParam(SearchFilter.SERVICE_NAME, request.getParameter(SearchFilter.SERVICE_NAME));
        ret.setParam(SearchFilter.SERVICE_NAME_PARTIAL, request.getParameter(SearchFilter.SERVICE_NAME_PARTIAL));
        ret.setParam(SearchFilter.SERVICE_ID, request.getParameter(SearchFilter.SERVICE_ID));
        ret.setParam(SearchFilter.POLICY_NAME, request.getParameter(SearchFilter.POLICY_NAME));
        ret.setParam(SearchFilter.POLICY_NAME_PARTIAL, request.getParameter(SearchFilter.POLICY_NAME_PARTIAL));
        ret.setParam(SearchFilter.POLICY_ID, request.getParameter(SearchFilter.POLICY_ID));
        ret.setParam(SearchFilter.IS_ENABLED, request.getParameter(SearchFilter.IS_ENABLED));
        ret.setParam(SearchFilter.IS_RECURSIVE, request.getParameter(SearchFilter.IS_RECURSIVE));
        ret.setParam(SearchFilter.USER, request.getParameter(SearchFilter.USER));
        ret.setParam(SearchFilter.GROUP, request.getParameter(SearchFilter.GROUP));
        ret.setParam(SearchFilter.POL_RESOURCE, request.getParameter(SearchFilter.POL_RESOURCE));
        ret.setParam(SearchFilter.RESOURCE_SIGNATURE, request.getParameter(SearchFilter.RESOURCE_SIGNATURE));
        ret.setParam(SearchFilter.POLICY_TYPE, request.getParameter(SearchFilter.POLICY_TYPE));

        ret.setParam(SearchFilter.PLUGIN_HOST_NAME, request.getParameter(SearchFilter.PLUGIN_HOST_NAME));
        ret.setParam(SearchFilter.PLUGIN_APP_TYPE, request.getParameter(SearchFilter.PLUGIN_APP_TYPE));
        ret.setParam(SearchFilter.PLUGIN_ENTITY_TYPE, request.getParameter(SearchFilter.PLUGIN_ENTITY_TYPE));
        ret.setParam(SearchFilter.PLUGIN_IP_ADDRESS, request.getParameter(SearchFilter.PLUGIN_IP_ADDRESS));

        for (Map.Entry<String, String[]> e : request.getParameterMap().entrySet()) {
            String name = e.getKey();
            String[] values = e.getValue();

            if (!StringUtils.isEmpty(name) && !ArrayUtils.isEmpty(values)
                    && name.startsWith(SearchFilter.RESOURCE_PREFIX)) {
                ret.setParam(name, values[0]);
            }
        }

        extractCommonCriteriasForFilter(request, ret, sortFields);

        return ret;
    }

    public SearchFilter getSearchFilterFromLegacyRequestForRepositorySearch(HttpServletRequest request,
            List<SortField> sortFields) {
        if (request == null) {
            return null;
        }

        SearchFilter ret = new SearchFilter();

        if (MapUtils.isEmpty(request.getParameterMap())) {
            ret.setParams(new HashMap<String, String>());
        }

        ret.setParam(SearchFilter.SERVICE_NAME, request.getParameter("name"));
        ret.setParam(SearchFilter.IS_ENABLED, request.getParameter("status"));
        String serviceType = request.getParameter("type");
        if (serviceType != null) {
            serviceType = serviceType.toLowerCase();
        }
        ret.setParam(SearchFilter.SERVICE_TYPE, serviceType);
        extractCommonCriteriasForFilter(request, ret, sortFields);

        return ret;
    }

    public SearchFilter getSearchFilterFromLegacyRequest(HttpServletRequest request, List<SortField> sortFields) {
        if (request == null) {
            return null;
        }

        SearchFilter ret = new SearchFilter();

        if (MapUtils.isEmpty(request.getParameterMap())) {
            ret.setParams(new HashMap<String, String>());
        }

        String repositoryType = request.getParameter("repositoryType");

        if (repositoryType != null) {
            repositoryType = repositoryType.toLowerCase();
        }

        String repositoryId = request.getParameter("repositoryId");
        if (repositoryId == null) {
            repositoryId = request.getParameter("assetId");
        }

        ret.setParam(SearchFilter.SERVICE_TYPE, repositoryType);
        ret.setParam(SearchFilter.SERVICE_NAME, request.getParameter("repositoryName"));
        ret.setParam(SearchFilter.SERVICE_ID, repositoryId);
        ret.setParam(SearchFilter.POLICY_NAME, request.getParameter("policyName"));
        ret.setParam(SearchFilter.USER, request.getParameter("userName"));
        ret.setParam(SearchFilter.GROUP, request.getParameter("groupName"));
        ret.setParam(SearchFilter.IS_ENABLED, request.getParameter("isEnabled"));
        ret.setParam(SearchFilter.IS_RECURSIVE, request.getParameter("isRecursive"));
        ret.setParam(SearchFilter.POL_RESOURCE, request.getParameter(SearchFilter.POL_RESOURCE));
        ret.setParam(SearchFilter.RESOURCE_PREFIX + "path", request.getParameter("resourceName"));
        ret.setParam(SearchFilter.RESOURCE_PREFIX + "database", request.getParameter("databases"));
        ret.setParam(SearchFilter.RESOURCE_PREFIX + "table", request.getParameter("tables"));
        ret.setParam(SearchFilter.RESOURCE_PREFIX + "udf", request.getParameter("udfs"));
        ret.setParam(SearchFilter.RESOURCE_PREFIX + "column", request.getParameter("columns"));
        ret.setParam(SearchFilter.RESOURCE_PREFIX + "column-family", request.getParameter("columnFamilies"));
        ret.setParam(SearchFilter.RESOURCE_PREFIX + "topology", request.getParameter("topologies"));
        ret.setParam(SearchFilter.RESOURCE_PREFIX + "service", request.getParameter("services"));

        extractCommonCriteriasForFilter(request, ret, sortFields);

        return ret;
    }

    public SearchFilter extractCommonCriteriasForFilter(HttpServletRequest request, SearchFilter ret,
            List<SortField> sortFields) {
        int startIndex = restErrorUtil.parseInt(request.getParameter(SearchFilter.START_INDEX), 0,
                "Invalid value for parameter startIndex", MessageEnums.INVALID_INPUT_DATA, null,
                SearchFilter.START_INDEX);
        startIndex = startIndex < 0 ? 0 : startIndex;
        ret.setStartIndex(startIndex);

        int pageSize = restErrorUtil.parseInt(request.getParameter(SearchFilter.PAGE_SIZE),
                configUtil.getDefaultMaxRows(), "Invalid value for parameter pageSize",
                MessageEnums.INVALID_INPUT_DATA, null, SearchFilter.PAGE_SIZE);
        ret.setMaxRows(validatePageSize(pageSize));

        ret.setGetCount(restErrorUtil.parseBoolean(request.getParameter("getCount"), true));
        String sortBy = restErrorUtil.validateString(request.getParameter(SearchFilter.SORT_BY),
                StringUtil.VALIDATION_ALPHA, "Invalid value for parameter sortBy", MessageEnums.INVALID_INPUT_DATA,
                null, SearchFilter.SORT_BY);

        boolean sortSet = false;
        if (!StringUtils.isEmpty(sortBy)) {
            for (SortField sortField : sortFields) {
                if (sortField.getParamName().equalsIgnoreCase(sortBy)) {
                    ret.setSortBy(sortField.getParamName());
                    String sortType = restErrorUtil.validateString(request.getParameter("sortType"),
                            StringUtil.VALIDATION_ALPHA, "Invalid value for parameter sortType",
                            MessageEnums.INVALID_INPUT_DATA, null, "sortType");
                    ret.setSortType(sortType);
                    sortSet = true;
                    break;
                }
            }
        }

        if (!sortSet && !StringUtils.isEmpty(sortBy)) {
            logger.info("Invalid or unsupported sortBy field passed. sortBy=" + sortBy, new Throwable());
        }

        if (ret.getParams() == null) {
            ret.setParams(new HashMap<String, String>());
        }
        return ret;
    }

    public Query createSearchQuery(EntityManager em, String queryStr, String sortClause,
            SearchFilter searchCriteria, List<SearchField> searchFields, boolean isCountQuery) {
        return createSearchQuery(em, queryStr, sortClause, searchCriteria, searchFields, -1, false, isCountQuery);
    }

    public Query createSearchQuery(EntityManager em, String queryStr, String sortClause,
            SearchFilter searchCriteria, List<SearchField> searchFields, int objectClassType, boolean hasAttributes,
            boolean isCountQuery) {

        StringBuilder queryClause = buildWhereClause(searchCriteria, searchFields);

        super.addOrderByClause(queryClause, sortClause);

        Query query = em.createQuery(queryStr + queryClause);

        resolveQueryParams(query, searchCriteria, searchFields);

        if (!isCountQuery) {
            query.setFirstResult(searchCriteria.getStartIndex());
            updateQueryPageSize(query, searchCriteria);
        }

        return query;
    }

    private StringBuilder buildWhereClause(SearchFilter searchCriteria, List<SearchField> searchFields) {
        return buildWhereClause(searchCriteria, searchFields, false);
    }

    private StringBuilder buildWhereClause(SearchFilter searchCriteria, List<SearchField> searchFields,
            boolean excludeWhereKeyword) {

        StringBuilder whereClause = new StringBuilder(excludeWhereKeyword ? "" : "WHERE 1 = 1 ");

        List<String> joinTableList = new ArrayList<String>();

        for (SearchField searchField : searchFields) {
            int startWhereLen = whereClause.length();

            if (searchField.getFieldName() == null && searchField.getCustomCondition() == null) {
                continue;
            }

            if (searchField.getDataType() == SearchField.DATA_TYPE.INTEGER) {
                Integer paramVal = restErrorUtil.parseInt(searchCriteria.getParam(searchField.getClientFieldName()),
                        "Invalid value for " + searchField.getClientFieldName(), MessageEnums.INVALID_INPUT_DATA,
                        null, searchField.getClientFieldName());

                Number intFieldValue = paramVal != null ? (Number) paramVal : null;
                if (intFieldValue != null) {
                    if (searchField.getCustomCondition() == null) {
                        whereClause.append(" and ").append(searchField.getFieldName()).append("=:")
                                .append(searchField.getClientFieldName());
                    } else {
                        whereClause.append(" and ").append(searchField.getCustomCondition());
                    }
                }
            } else if (searchField.getDataType() == SearchField.DATA_TYPE.STRING) {
                String strFieldValue = searchCriteria.getParam(searchField.getClientFieldName());
                if (strFieldValue != null) {
                    if (searchField.getCustomCondition() == null) {
                        whereClause.append(" and ").append("LOWER(").append(searchField.getFieldName()).append(")");
                        if (searchField.getSearchType() == SearchField.SEARCH_TYPE.FULL) {
                            whereClause.append("= :").append(searchField.getClientFieldName());
                        } else {
                            whereClause.append("like :").append(searchField.getClientFieldName());
                        }
                    } else {
                        whereClause.append(" and ").append(searchField.getCustomCondition());
                    }
                }
            } else if (searchField.getDataType() == SearchField.DATA_TYPE.BOOLEAN) {
                Boolean boolFieldValue = restErrorUtil.parseBoolean(
                        searchCriteria.getParam(searchField.getClientFieldName()),
                        "Invalid value for " + searchField.getClientFieldName(), MessageEnums.INVALID_INPUT_DATA,
                        null, searchField.getClientFieldName());

                if (boolFieldValue != null) {
                    if (searchField.getCustomCondition() == null) {
                        whereClause.append(" and ").append(searchField.getFieldName()).append("=:")
                                .append(searchField.getClientFieldName());
                    } else {
                        whereClause.append(" and ").append(searchField.getCustomCondition());
                    }
                }
            } else if (searchField.getDataType() == SearchField.DATA_TYPE.DATE) {
                Date fieldValue = restErrorUtil.parseDate(searchCriteria.getParam(searchField.getClientFieldName()),
                        "Invalid value for " + searchField.getClientFieldName(), MessageEnums.INVALID_INPUT_DATA,
                        null, searchField.getClientFieldName(), null);
                if (fieldValue != null) {
                    if (searchField.getCustomCondition() == null) {
                        whereClause.append(" and ").append(searchField.getFieldName());
                        if (searchField.getSearchType().equals(SearchField.SEARCH_TYPE.LESS_THAN)) {
                            whereClause.append("< :");
                        } else if (searchField.getSearchType().equals(SearchField.SEARCH_TYPE.LESS_EQUAL_THAN)) {
                            whereClause.append("<= :");
                        } else if (searchField.getSearchType().equals(SearchField.SEARCH_TYPE.GREATER_THAN)) {
                            whereClause.append("> :");
                        } else if (searchField.getSearchType().equals(SearchField.SEARCH_TYPE.GREATER_EQUAL_THAN)) {
                            whereClause.append(">= :");
                        }
                        whereClause.append(searchField.getClientFieldName());
                    } else {
                        whereClause.append(" and ").append(searchField.getCustomCondition());
                    }
                }
            }

            if (whereClause.length() > startWhereLen && searchField.getJoinTables() != null) {
                for (String table : searchField.getJoinTables()) {
                    if (!joinTableList.contains(table)) {
                        joinTableList.add(table);
                    }
                }
                whereClause.append(" and (").append(searchField.getJoinCriteria()).append(")");
            }
        }
        for (String joinTable : joinTableList) {
            whereClause.insert(0, ", " + joinTable + " ");
        }

        return whereClause;
    }

    protected void resolveQueryParams(Query query, SearchFilter searchCriteria, List<SearchField> searchFields) {

        for (SearchField searchField : searchFields) {

            if (searchField.getDataType() == SearchField.DATA_TYPE.INTEGER) {
                Integer paramVal = restErrorUtil.parseInt(searchCriteria.getParam(searchField.getClientFieldName()),
                        "Invalid value for " + searchField.getClientFieldName(), MessageEnums.INVALID_INPUT_DATA,
                        null, searchField.getClientFieldName());

                Number intFieldValue = paramVal != null ? (Number) paramVal : null;
                if (intFieldValue != null) {
                    query.setParameter(searchField.getClientFieldName(), intFieldValue);
                }
            } else if (searchField.getDataType() == SearchField.DATA_TYPE.STRING) {
                String strFieldValue = searchCriteria.getParam(searchField.getClientFieldName());
                if (strFieldValue != null) {
                    if (searchField.getSearchType() == SearchField.SEARCH_TYPE.FULL) {
                        query.setParameter(searchField.getClientFieldName(), strFieldValue.trim().toLowerCase());
                    } else {
                        query.setParameter(searchField.getClientFieldName(),
                                "%" + strFieldValue.trim().toLowerCase() + "%");
                    }
                }
            } else if (searchField.getDataType() == SearchField.DATA_TYPE.BOOLEAN) {
                Boolean boolFieldValue = restErrorUtil.parseBoolean(
                        searchCriteria.getParam(searchField.getClientFieldName()),
                        "Invalid value for " + searchField.getClientFieldName(), MessageEnums.INVALID_INPUT_DATA,
                        null, searchField.getClientFieldName());

                if (boolFieldValue != null) {
                    query.setParameter(searchField.getClientFieldName(), boolFieldValue);
                }
            } else if (searchField.getDataType() == SearchField.DATA_TYPE.DATE) {
                Date fieldValue = restErrorUtil.parseDate(searchCriteria.getParam(searchField.getClientFieldName()),
                        "Invalid value for " + searchField.getClientFieldName(), MessageEnums.INVALID_INPUT_DATA,
                        null, searchField.getClientFieldName(), null);
                if (fieldValue != null) {
                    query.setParameter(searchField.getClientFieldName(), fieldValue);
                }
            }
        }
    }

    public void updateQueryPageSize(Query query, SearchFilter searchCriteria) {
        int pageSize = super.validatePageSize(searchCriteria.getMaxRows());
        query.setMaxResults(pageSize);

        query.setHint("eclipselink.jdbc.max-rows", "" + pageSize);
    }

    public String constructSortClause(SearchFilter searchCriteria, List<SortField> sortFields) {
        String sortBy = searchCriteria.getSortBy();
        String querySortBy = null;

        if (!stringUtil.isEmpty(sortBy)) {
            sortBy = sortBy.trim();
            for (SortField sortField : sortFields) {
                if (sortBy.equalsIgnoreCase(sortField.getParamName())) {
                    querySortBy = sortField.getFieldName();
                    // Override the sortBy using the normalized value
                    searchCriteria.setSortBy(sortField.getParamName());
                    break;
                }
            }
        }

        if (querySortBy == null) {
            for (SortField sortField : sortFields) {
                if (sortField.isDefault()) {
                    querySortBy = sortField.getFieldName();
                    // Override the sortBy using the default value
                    searchCriteria.setSortBy(sortField.getParamName());
                    searchCriteria.setSortType(sortField.getDefaultOrder().name());
                    break;
                }
            }
        }

        if (querySortBy != null) {
            String sortType = searchCriteria.getSortType();
            String querySortType = "asc";
            if (sortType != null) {
                if (sortType.equalsIgnoreCase("asc") || sortType.equalsIgnoreCase("desc")) {
                    querySortType = sortType;
                } else {
                    logger.error("Invalid sortType. sortType=" + sortType);
                }
            }

            if (querySortType != null) {
                searchCriteria.setSortType(querySortType.toLowerCase());
            }
            String sortClause = " ORDER BY " + querySortBy + " " + querySortType;

            return sortClause;
        }
        return null;
    }

}