public void setPolicies()

in agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java [442:621]


    public void setPolicies(ServicePolicies policies) {
        LOG.debug("==> setPolicies({})", policies);

        this.serviceConfigs = (policies != null && policies.getServiceConfig() != null) ? policies.getServiceConfig() : new HashMap<>();

        if (pluginConfig.isEnableImplicitUserStoreEnricher() && policies != null && !ServiceDefUtil.isUserStoreEnricherPresent(policies)) {
            String retrieverClassName = pluginConfig.get(RangerUserStoreEnricher.USERSTORE_RETRIEVER_CLASSNAME_OPTION, RangerAdminUserStoreRetriever.class.getCanonicalName());
            String retrieverPollIntMs = pluginConfig.get(RangerUserStoreEnricher.USERSTORE_REFRESHER_POLLINGINTERVAL_OPTION, Integer.toString(60 * 1000));

            // in case of delta, policies will only have changes; hence add userStoreEnricher if it was implicitly added previous calls to setPolicies()
            if (RangerPolicyDeltaUtil.hasPolicyDeltas(policies) == Boolean.TRUE && isUserStoreEnricherAddedImplcitly) {
                ServiceDefUtil.addUserStoreEnricher(policies, retrieverClassName, retrieverPollIntMs);
            } else if (pluginConfig.isUseRangerGroups() || pluginConfig.isConvertEmailToUsername()) {
                isUserStoreEnricherAddedImplcitly = ServiceDefUtil.addUserStoreEnricher(policies, retrieverClassName, retrieverPollIntMs);
            } else {
                isUserStoreEnricherAddedImplcitly = ServiceDefUtil.addUserStoreEnricherIfNeeded(policies, retrieverClassName, retrieverPollIntMs);
            }
        }

        if (pluginConfig.isEnableImplicitGdsInfoEnricher() && policies != null && !ServiceDefUtil.isGdsInfoEnricherPresent(policies)) {
            String retrieverClassName = pluginConfig.get(RangerGdsEnricher.RETRIEVER_CLASSNAME_OPTION, RangerAdminGdsInfoRetriever.class.getCanonicalName());
            String retrieverPollIntMs = pluginConfig.get(RangerGdsEnricher.REFRESHER_POLLINGINTERVAL_OPTION, Integer.toString(60 * 1000));

            ServiceDefUtil.addGdsInfoEnricher(policies, retrieverClassName, retrieverPollIntMs);
        }

        // guard against catastrophic failure during policy engine Initialization or
        try {
            RangerPolicyEngine oldPolicyEngine   = this.policyEngine;
            ServicePolicies    servicePolicies   = null;
            boolean            isNewEngineNeeded = true;
            boolean            usePolicyDeltas   = false;

            if (policies == null) {
                policies = getDefaultSvcPolicies();

                if (policies == null) {
                    LOG.error("Could not get default Service Policies. Keeping old policy-engine!");

                    isNewEngineNeeded = false;
                }
            } else {
                if (dedupStrings) {
                    policies.dedupStrings();
                }

                Boolean hasPolicyDeltas = RangerPolicyDeltaUtil.hasPolicyDeltas(policies);

                if (hasPolicyDeltas == null) {
                    LOG.info("Downloaded policies do not require policy change !! [{}]", policies);

                    if (this.policyEngine == null) {
                        LOG.info("There are no material changes, and current policy-engine is null! Creating a policy-engine with default service policies");

                        ServicePolicies defaultSvcPolicies = getDefaultSvcPolicies();

                        if (defaultSvcPolicies == null) {
                            LOG.error("Could not get default Service Policies. Keeping old policy-engine! This is a FATAL error as the old policy-engine is null!");

                            isNewEngineNeeded = false;
                        } else {
                            defaultSvcPolicies.setPolicyVersion(policies.getPolicyVersion());
                            policies          = defaultSvcPolicies;
                            isNewEngineNeeded = true;
                        }
                    } else {
                        LOG.info("Keeping old policy-engine!");

                        isNewEngineNeeded = false;
                    }
                } else {
                    if (hasPolicyDeltas.equals(Boolean.TRUE)) {
                        // Rebuild policies from deltas
                        RangerPolicyEngineImpl policyEngine = (RangerPolicyEngineImpl) oldPolicyEngine;

                        servicePolicies = ServicePolicies.applyDelta(policies, policyEngine);

                        if (servicePolicies != null) {
                            usePolicyDeltas = true;
                        } else {
                            LOG.error("Could not apply deltas={}", Arrays.toString(policies.getPolicyDeltas().toArray()));
                            LOG.warn("Keeping old policy-engine!");
                            isNewEngineNeeded = false;
                        }
                    } else {
                        if (policies.getPolicies() == null) {
                            policies.setPolicies(new ArrayList<>());
                        }
                        if (MapUtils.isNotEmpty(policies.getSecurityZones())) {
                            for (ServicePolicies.SecurityZoneInfo element : policies.getSecurityZones().values()) {
                                if (element.getPolicies() == null) {
                                    element.setPolicies(new ArrayList<>());
                                }
                            }
                        }
                    }
                }
            }

            if (isNewEngineNeeded) {
                RangerPolicyEngine newPolicyEngine      = null;
                boolean            isPolicyEngineShared = false;

                if (!usePolicyDeltas) {
                    LOG.debug("Creating engine from policies");

                    newPolicyEngine = new RangerPolicyEngineImpl(policies, pluginContext, roles);
                } else {
                    LOG.debug("policy-deltas are not null");

                    if (CollectionUtils.isNotEmpty(policies.getPolicyDeltas()) || MapUtils.isNotEmpty(policies.getSecurityZones())) {
                        LOG.debug("Non empty policy-deltas found. Cloning engine using policy-deltas");

                        if (oldPolicyEngine != null) {
                            RangerPolicyEngineImpl oldPolicyEngineImpl = (RangerPolicyEngineImpl) oldPolicyEngine;

                            newPolicyEngine = RangerPolicyEngineImpl.getPolicyEngine(oldPolicyEngineImpl, policies);
                        }

                        if (newPolicyEngine != null) {
                            if (LOG.isDebugEnabled()) {
                                LOG.debug("Applied policyDeltas={})", Arrays.toString(policies.getPolicyDeltas().toArray()));
                            }

                            isPolicyEngineShared = true;
                        } else {
                            if (LOG.isDebugEnabled()) {
                                LOG.debug("Failed to apply policyDeltas={}), Creating engine from policies", Arrays.toString(policies.getPolicyDeltas().toArray()));
                                LOG.debug("Creating new engine from servicePolicies:[{}]", servicePolicies);
                            }

                            newPolicyEngine = new RangerPolicyEngineImpl(servicePolicies, pluginContext, roles);
                        }
                    } else {
                        LOG.debug("Empty policy-deltas. No need to change policy engine");
                    }
                }

                if (newPolicyEngine != null) {
                    if (!isPolicyEngineShared) {
                        newPolicyEngine.setUseForwardedIPAddress(pluginConfig.isUseForwardedIPAddress());
                        newPolicyEngine.setTrustedProxyAddresses(pluginConfig.getTrustedProxyAddresses());
                    }

                    LOG.info("Switching policy engine from [{}]", getPolicyVersion());
                    this.policyEngine = newPolicyEngine;
                    LOG.info("Switched policy engine to [{}]", getPolicyVersion());
                    this.currentAuthContext = pluginContext.getAuthContext();

                    pluginContext.notifyAuthContextChanged();

                    if (oldPolicyEngine != null && oldPolicyEngine != newPolicyEngine) {
                        ((RangerPolicyEngineImpl) oldPolicyEngine).releaseResources(!isPolicyEngineShared);
                    }

                    if (this.refresher != null) {
                        boolean doPreserveDeltas = pluginConfig.getBoolean(pluginConfig.getPropertyPrefix() + ".preserve.deltas", false);
                        if (!doPreserveDeltas) {
                            this.refresher.saveToCache(usePolicyDeltas ? servicePolicies : policies);
                        } else {
                            // Save both deltas and all policies to cache for verification
                            this.refresher.saveToCache(policies);

                            if (usePolicyDeltas) {
                                this.refresher.saveToCache(servicePolicies);
                            }
                        }
                    }
                }
            } else {
                LOG.warn("Leaving current policy engine as-is");
                LOG.warn("Policies are not saved to cache. policyVersion in the policy-cache may be different than in Ranger-admin, even though the policies are the same!");
                LOG.warn("Ranger-PolicyVersion:[{}], Cached-PolicyVersion:[{}]", policies != null ? policies.getPolicyVersion() : -1L, getPoliciesVersion());
            }
        } catch (Exception e) {
            LOG.error("setPolicies: policy engine initialization failed!  Leaving current policy engine as-is. Exception : ", e);
        }

        LOG.debug("<== setPolicies({})", policies);
    }