org.apache.ranger.service.RangerBaseModelService.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.ranger.service.RangerBaseModelService.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.service;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ranger.biz.RangerBizUtil;
import org.apache.ranger.common.ContextUtil;
import org.apache.ranger.common.DateUtil;
import org.apache.ranger.common.MessageEnums;
import org.apache.ranger.common.RESTErrorUtil;
import org.apache.ranger.common.RangerSearchUtil;
import org.apache.ranger.common.SearchField;
import org.apache.ranger.common.SortField;
import org.apache.ranger.common.StringUtil;
import org.apache.ranger.common.db.BaseDao;
import org.apache.ranger.common.view.VList;
import org.apache.ranger.db.RangerDaoManager;
import org.apache.ranger.entity.XXAccessTypeDef;
import org.apache.ranger.entity.XXDBBase;
import org.apache.ranger.entity.XXGroup;
import org.apache.ranger.entity.XXPolicyConditionDef;
import org.apache.ranger.entity.XXPortalUser;
import org.apache.ranger.entity.XXResourceDef;
import org.apache.ranger.plugin.model.RangerBaseModelObject;
import org.apache.ranger.plugin.store.PList;
import org.apache.ranger.plugin.util.SearchFilter;
import org.springframework.beans.factory.annotation.Autowired;

public abstract class RangerBaseModelService<T extends XXDBBase, V extends RangerBaseModelObject> {
    private static final Log LOG = LogFactory.getLog(RangerBaseModelService.class);

    @Autowired
    protected RangerDaoManager daoMgr;

    @Autowired
    protected StringUtil stringUtil;

    @Autowired
    protected RESTErrorUtil restErrorUtil;

    @Autowired
    protected RangerSearchUtil searchUtil;

    @Autowired
    RangerBizUtil bizUtil;

    public static final int OPERATION_CREATE_CONTEXT = 1;
    public static final int OPERATION_UPDATE_CONTEXT = 2;
    public static final int OPERATION_DELETE_CONTEXT = 3;

    protected Class<T> tEntityClass;
    protected Class<V> tViewClass;
    private Boolean populateExistingBaseFields;
    protected String tClassName;

    public List<SortField> sortFields = new ArrayList<SortField>();
    public List<SearchField> searchFields = new ArrayList<SearchField>();
    protected final String countQueryStr;
    protected String queryStr;

    BaseDao<T> entityDao;

    @SuppressWarnings("unchecked")
    public RangerBaseModelService() {
        Class klass = getClass();
        ParameterizedType genericSuperclass = (ParameterizedType) klass.getGenericSuperclass();
        TypeVariable<Class<?>> var[] = klass.getTypeParameters();

        if (genericSuperclass.getActualTypeArguments()[0] instanceof Class) {
            tEntityClass = (Class<T>) genericSuperclass.getActualTypeArguments()[0];
            tViewClass = (Class<V>) genericSuperclass.getActualTypeArguments()[1];
        } else if (var.length > 0) {
            tEntityClass = (Class<T>) var[0].getBounds()[0];
            tViewClass = (Class<V>) var[1].getBounds()[0];
        } else {
            LOG.fatal("Cannot find class for template", new Throwable());
        }

        if (tEntityClass != null) {
            tClassName = tEntityClass.getName();
        }

        populateExistingBaseFields = false;

        countQueryStr = "SELECT COUNT(obj) FROM " + tClassName + " obj ";
        queryStr = "SELECT obj FROM " + tClassName + " obj ";
    }

    protected abstract T mapViewToEntityBean(V viewBean, T t, int OPERATION_CONTEXT);

    protected abstract V mapEntityToViewBean(V viewBean, T t);

    protected T createEntityObject() {
        try {
            return tEntityClass.newInstance();
        } catch (Throwable e) {
            LOG.error("Error instantiating entity class. tEntityClass=" + tEntityClass.toString(), e);
        }
        return null;
    }

    protected V createViewObject() {
        try {
            return tViewClass.newInstance();
        } catch (Throwable e) {
            LOG.error("Error instantiating view class. tViewClass=" + tViewClass.toString(), e);
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    protected BaseDao<T> getDao() {
        if (entityDao == null) {
            entityDao = (BaseDao<T>) daoMgr.getDaoForClassName(tEntityClass.getSimpleName());

        }
        return entityDao;
    }

    protected V populateViewBean(T entityObj) {
        V vObj = createViewObject();
        vObj.setId(entityObj.getId());
        vObj.setCreateTime(entityObj.getCreateTime());
        vObj.setUpdateTime(entityObj.getUpdateTime());
        vObj.setCreatedBy(getUserScreenName(entityObj.getAddedByUserId()));
        vObj.setUpdatedBy(getUserScreenName(entityObj.getUpdatedByUserId()));

        return mapEntityToViewBean(vObj, entityObj);
    }

    protected T populateEntityBeanForCreate(T entityObj, V vObj) {
        if (!populateExistingBaseFields) {
            entityObj.setCreateTime(DateUtil.getUTCDate());
            entityObj.setUpdateTime(entityObj.getCreateTime());
            entityObj.setAddedByUserId(ContextUtil.getCurrentUserId());
            entityObj.setUpdatedByUserId(entityObj.getAddedByUserId());
        } else if (populateExistingBaseFields) {
            XXPortalUser createdByUser = daoMgr.getXXPortalUser().findByLoginId(vObj.getCreatedBy());
            XXPortalUser updByUser = daoMgr.getXXPortalUser().findByLoginId(vObj.getUpdatedBy());

            entityObj.setId(vObj.getId());
            entityObj.setCreateTime(vObj.getCreateTime() != null ? vObj.getCreateTime() : DateUtil.getUTCDate());
            entityObj.setUpdateTime(vObj.getUpdateTime() != null ? vObj.getUpdateTime() : DateUtil.getUTCDate());
            entityObj.setAddedByUserId(
                    createdByUser != null ? createdByUser.getId() : ContextUtil.getCurrentUserId());
            entityObj.setUpdatedByUserId(updByUser != null ? updByUser.getId() : ContextUtil.getCurrentUserId());
        }

        return mapViewToEntityBean(vObj, entityObj, OPERATION_CREATE_CONTEXT);
    }

    protected T populateEntityBeanForUpdate(T entityObj, V vObj) {
        if (entityObj == null) {
            throw restErrorUtil.createRESTException("No Object found to update.", MessageEnums.DATA_NOT_FOUND);
        }

        T ret = mapViewToEntityBean(vObj, entityObj, OPERATION_UPDATE_CONTEXT);

        if (ret.getCreateTime() == null) {
            ret.setCreateTime(DateUtil.getUTCDate());
        }

        if (ret.getAddedByUserId() == null) {
            ret.setAddedByUserId(ContextUtil.getCurrentUserId());
        }

        if (!populateExistingBaseFields) {
            ret.setUpdateTime(DateUtil.getUTCDate());
            ret.setUpdatedByUserId(ContextUtil.getCurrentUserId());
        }

        return ret;
    }

    protected abstract void validateForCreate(V vObj);

    protected abstract void validateForUpdate(V vObj, T entityObj);

    public T preCreate(V vObj) {
        validateForCreate(vObj);

        T entityObj = createEntityObject();

        return populateEntityBeanForCreate(entityObj, vObj);
    }

    public V postCreate(T xObj) {
        return populateViewBean(xObj);
    }

    public V create(V vObj) {
        T resource = preCreate(vObj);
        resource = getDao().create(resource);
        vObj = postCreate(resource);
        return vObj;
    }

    public V read(Long id) {
        T resource = getDao().getById(id);
        if (resource == null) {
            throw restErrorUtil.createRESTException(tViewClass.getName() + " :Data Not Found for given Id",
                    MessageEnums.DATA_NOT_FOUND, id, null, "readResource : No Object found with given id.");
        }
        return populateViewBean(resource);
    }

    public V update(V viewBaseBean) {
        T resource = preUpdate(viewBaseBean);
        resource = getDao().update(resource);
        V viewBean = postUpdate(resource);
        return viewBean;
    }

    public V postUpdate(T resource) {
        return populateViewBean(resource);
    }

    public T preUpdate(V viewBaseBean) {
        T resource = getDao().getById(viewBaseBean.getId());
        if (resource == null) {
            throw restErrorUtil.createRESTException(tEntityClass.getSimpleName() + " not found",
                    MessageEnums.DATA_NOT_FOUND, viewBaseBean.getId(), null, "preUpdate: id not found.");
        }
        validateForUpdate(viewBaseBean, resource);
        return populateEntityBeanForUpdate(resource, viewBaseBean);
    }

    public boolean delete(V vObj) {
        boolean result = false;
        Long id = vObj.getId();
        T resource = preDelete(id);
        if (resource == null) {
            throw restErrorUtil.createRESTException(tEntityClass.getSimpleName() + " not found",
                    MessageEnums.DATA_NOT_FOUND, id, null, tEntityClass.getSimpleName() + ":" + id);
        }
        try {
            result = getDao().remove(resource);
        } catch (Exception e) {
            LOG.error("Error deleting " + tEntityClass.getSimpleName() + ". Id=" + id, e);

            throw restErrorUtil.createRESTException(tEntityClass.getSimpleName() + " can't be deleted",
                    MessageEnums.OPER_NOT_ALLOWED_FOR_STATE, id, null, "" + id + ", error=" + e.getMessage());
        }
        return result;
    }

    protected T preDelete(Long id) {
        T resource = getDao().getById(id);
        if (resource == null) {
            // Return without error
            LOG.info("Delete ignored for non-existent Object, id=" + id);
        }
        return resource;
    }

    public Boolean getPopulateExistingBaseFields() {
        return populateExistingBaseFields;
    }

    public void setPopulateExistingBaseFields(Boolean populateExistingBaseFields) {
        this.populateExistingBaseFields = populateExistingBaseFields;
    }

    /*
     * Search Operations
     *
     */

    public List<T> searchResources(SearchFilter searchCriteria, List<SearchField> searchFieldList,
            List<SortField> sortFieldList, VList vList) {

        // Get total count of the rows which meet the search criteria
        long count = -1;
        if (searchCriteria.isGetCount()) {
            count = getCountForSearchQuery(searchCriteria, searchFieldList);
            if (count == 0) {
                return Collections.emptyList();
            }
        }

        String sortClause = searchUtil.constructSortClause(searchCriteria, sortFieldList);

        String q = queryStr;
        Query query = createQuery(q, sortClause, searchCriteria, searchFieldList, false);

        List<T> resultList = getDao().executeQueryInSecurityContext(tEntityClass, query);

        if (vList != null) {
            vList.setResultSize(resultList.size());
            vList.setPageSize(query.getMaxResults());
            vList.setSortBy(searchCriteria.getSortBy());
            vList.setSortType(searchCriteria.getSortType());
            vList.setStartIndex(query.getFirstResult());
            vList.setTotalCount(count);
        }
        return resultList;
    }

    protected List<T> searchRangerObjects(SearchFilter searchCriteria, List<SearchField> searchFieldList,
            List<SortField> sortFieldList, PList<V> pList) {

        // Get total count of the rows which meet the search criteria
        long count = -1;
        if (searchCriteria.isGetCount()) {
            count = getCountForSearchQuery(searchCriteria, searchFieldList);
            if (count == 0) {
                return Collections.emptyList();
            }
        }

        String sortClause = searchUtil.constructSortClause(searchCriteria, sortFieldList);

        String q = queryStr;
        Query query = createQuery(q, sortClause, searchCriteria, searchFieldList, false);

        List<T> resultList = getDao().executeQueryInSecurityContext(tEntityClass, query);

        if (pList != null) {
            pList.setResultSize(resultList.size());
            pList.setPageSize(query.getMaxResults());
            pList.setSortBy(searchCriteria.getSortBy());
            pList.setSortType(searchCriteria.getSortType());
            pList.setStartIndex(query.getFirstResult());
            pList.setTotalCount(count);
        }
        return resultList;
    }

    protected long getCountForSearchQuery(SearchFilter searchCriteria, List<SearchField> searchFieldList) {

        String q = countQueryStr;
        Query query = createQuery(q, null, searchCriteria, searchFieldList, true);
        Long count = getDao().executeCountQueryInSecurityContext(tEntityClass, query);

        if (count == null) {
            return 0;
        }
        return count.longValue();
    }

    protected Query createQuery(String searchString, String sortString, SearchFilter searchCriteria,
            List<SearchField> searchFieldList, boolean isCountQuery) {

        EntityManager em = getDao().getEntityManager();
        Query query = searchUtil.createSearchQuery(em, searchString, sortString, searchCriteria, searchFieldList,
                getClassType(), false, isCountQuery);
        return query;
    }

    protected int getClassType() {
        return bizUtil.getClassType(tEntityClass);
    }

    protected String getUserScreenName(Long userId) {
        String ret = null;

        XXPortalUser xPortalUser = userId == null ? null : daoMgr.getXXPortalUser().getById(userId);

        if (xPortalUser != null) {
            ret = xPortalUser.getPublicScreenName();

            if (stringUtil.isEmpty(ret)) {
                ret = xPortalUser.getFirstName();

                if (stringUtil.isEmpty(ret)) {
                    ret = xPortalUser.getLoginId();
                } else {
                    if (!stringUtil.isEmpty(xPortalUser.getLastName())) {
                        ret += (" " + xPortalUser.getLastName());
                    }
                }
            }
        }

        return ret;
    }

    protected String getUserName(Long userId) {
        String ret = null;

        XXPortalUser xPortalUser = userId == null ? null : daoMgr.getXXPortalUser().getById(userId);

        if (xPortalUser != null) {
            ret = xPortalUser.getLoginId();
        }

        return ret;
    }

    protected String getGroupName(Long groupId) {
        String ret = null;

        XXGroup xGroup = groupId == null ? null : daoMgr.getXXGroup().getById(groupId);

        if (xGroup != null) {
            ret = xGroup.getName();
        }

        return ret;
    }

    protected String getAccessTypeName(Long accessTypeDefId) {
        String ret = null;

        XXAccessTypeDef accessTypeDef = accessTypeDefId == null ? null
                : daoMgr.getXXAccessTypeDef().getById(accessTypeDefId);

        if (accessTypeDef != null) {
            ret = accessTypeDef.getName();
        }

        return ret;
    }

    protected String getConditionName(Long conditionDefId) {
        String ret = null;

        XXPolicyConditionDef conditionDef = conditionDefId == null ? null
                : daoMgr.getXXPolicyConditionDef().getById(conditionDefId);

        if (conditionDef != null) {
            ret = conditionDef.getName();
        }

        return ret;
    }

    protected String getResourceName(Long resourceDefId) {
        String ret = null;

        XXResourceDef resourceDef = resourceDefId == null ? null : daoMgr.getXXResourceDef().getById(resourceDefId);

        if (resourceDef != null) {
            ret = resourceDef.getName();
        }

        return ret;
    }
}