Java tutorial
/* * 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.plugin.util; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.Reader; import java.io.Writer; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.ranger.admin.client.RangerAdminClient; import org.apache.ranger.plugin.service.RangerBasePlugin; import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class PolicyRefresher extends Thread { private static final Log LOG = LogFactory.getLog(PolicyRefresher.class); private static final Log PERF_POLICYENGINE_INIT_LOG = RangerPerfTracer.getPerfLogger("policyengine.init"); private final RangerBasePlugin plugIn; private final String serviceType; private final String serviceName; private final RangerAdminClient rangerAdmin; private final String cacheFileName; private final String cacheDir; private final Gson gson; private long pollingIntervalMs = 30 * 1000; private long lastKnownVersion = -1L; private long lastActivationTimeInMillis = 0L; private boolean policiesSetInPlugin = false; public PolicyRefresher(RangerBasePlugin plugIn, String serviceType, String appId, String serviceName, RangerAdminClient rangerAdmin, long pollingIntervalMs, String cacheDir) { if (LOG.isDebugEnabled()) { LOG.debug("==> PolicyRefresher(serviceName=" + serviceName + ").PolicyRefresher()"); } this.plugIn = plugIn; this.serviceType = serviceType; this.serviceName = serviceName; this.rangerAdmin = rangerAdmin; this.pollingIntervalMs = pollingIntervalMs; if (StringUtils.isEmpty(appId)) { appId = serviceType; } String cacheFilename = String.format("%s_%s.json", appId, serviceName); cacheFilename = cacheFilename.replace(File.separatorChar, '_'); cacheFilename = cacheFilename.replace(File.pathSeparatorChar, '_'); this.cacheFileName = cacheFilename; this.cacheDir = cacheDir; Gson gson = null; try { gson = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSS-Z").setPrettyPrinting().create(); } catch (Throwable excp) { LOG.fatal("PolicyRefresher(): failed to create GsonBuilder object", excp); } this.gson = gson; if (LOG.isDebugEnabled()) { LOG.debug("<== PolicyRefresher(serviceName=" + serviceName + ").PolicyRefresher()"); } } /** * @return the plugIn */ public RangerBasePlugin getPlugin() { return plugIn; } /** * @return the serviceType */ public String getServiceType() { return serviceType; } /** * @return the serviceName */ public String getServiceName() { return serviceName; } /** * @return the rangerAdmin */ public RangerAdminClient getRangerAdminClient() { return rangerAdmin; } /** * @return the pollingIntervalMilliSeconds */ public long getPollingIntervalMs() { return pollingIntervalMs; } /** * @param pollingIntervalMilliSeconds the pollingIntervalMilliSeconds to set */ public void setPollingIntervalMilliSeconds(long pollingIntervalMilliSeconds) { this.pollingIntervalMs = pollingIntervalMilliSeconds; } public long getLastActivationTimeInMillis() { return lastActivationTimeInMillis; } public void setLastActivationTimeInMillis(long lastActivationTimeInMillis) { this.lastActivationTimeInMillis = lastActivationTimeInMillis; } public void startRefresher() { loadPolicy(); super.start(); } public void stopRefresher() { super.interrupt(); try { super.join(); } catch (InterruptedException excp) { LOG.warn("PolicyRefresher(serviceName=" + serviceName + "): error while waiting for thread to exit", excp); } } public void run() { if (LOG.isDebugEnabled()) { LOG.debug("==> PolicyRefresher(serviceName=" + serviceName + ").run()"); } while (true) { loadPolicy(); try { Thread.sleep(pollingIntervalMs); } catch (InterruptedException excp) { LOG.info("PolicyRefresher(serviceName=" + serviceName + ").run(): interrupted! Exiting thread", excp); break; } } if (LOG.isDebugEnabled()) { LOG.debug("<== PolicyRefresher(serviceName=" + serviceName + ").run()"); } } private void loadPolicy() { if (LOG.isDebugEnabled()) { LOG.debug("==> PolicyRefresher(serviceName=" + serviceName + ").loadPolicy()"); } RangerPerfTracer perf = null; if (RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_INIT_LOG)) { perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_INIT_LOG, "PolicyRefresher.loadPolicy(serviceName=" + serviceName + ")"); long freeMemory = Runtime.getRuntime().freeMemory(); long totalMemory = Runtime.getRuntime().totalMemory(); PERF_POLICYENGINE_INIT_LOG .debug("In-Use memory: " + (totalMemory - freeMemory) + ", Free memory:" + freeMemory); } //load policy from PolicyAdmin ServicePolicies svcPolicies = loadPolicyfromPolicyAdmin(); if (svcPolicies == null) { //if Policy fetch from Policy Admin Fails, load from cache if (!policiesSetInPlugin) { svcPolicies = loadFromCache(); } } else { saveToCache(svcPolicies); } RangerPerfTracer.log(perf); if (PERF_POLICYENGINE_INIT_LOG.isDebugEnabled()) { long freeMemory = Runtime.getRuntime().freeMemory(); long totalMemory = Runtime.getRuntime().totalMemory(); PERF_POLICYENGINE_INIT_LOG .debug("In-Use memory: " + (totalMemory - freeMemory) + ", Free memory:" + freeMemory); } if (svcPolicies != null) { plugIn.setPolicies(svcPolicies); policiesSetInPlugin = true; setLastActivationTimeInMillis(System.currentTimeMillis()); lastKnownVersion = svcPolicies.getPolicyVersion(); } if (LOG.isDebugEnabled()) { LOG.debug("<== PolicyRefresher(serviceName=" + serviceName + ").loadPolicy()"); } } private ServicePolicies loadPolicyfromPolicyAdmin() { if (LOG.isDebugEnabled()) { LOG.debug("==> PolicyRefresher(serviceName=" + serviceName + ").loadPolicyfromPolicyAdmin()"); } ServicePolicies svcPolicies = null; RangerPerfTracer perf = null; if (RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_INIT_LOG)) { perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_INIT_LOG, "PolicyRefresher.loadPolicyFromPolicyAdmin(serviceName=" + serviceName + ")"); } try { svcPolicies = rangerAdmin.getServicePoliciesIfUpdated(lastKnownVersion, lastActivationTimeInMillis); boolean isUpdated = svcPolicies != null; if (isUpdated) { long newVersion = svcPolicies.getPolicyVersion() == null ? -1 : svcPolicies.getPolicyVersion().longValue(); if (!StringUtils.equals(serviceName, svcPolicies.getServiceName())) { LOG.warn("PolicyRefresher(serviceName=" + serviceName + "): ignoring unexpected serviceName '" + svcPolicies.getServiceName() + "' in service-store"); svcPolicies.setServiceName(serviceName); } LOG.info( "PolicyRefresher(serviceName=" + serviceName + "): found updated version. lastKnownVersion=" + lastKnownVersion + "; newVersion=" + newVersion); } else { if (LOG.isDebugEnabled()) { LOG.debug("PolicyRefresher(serviceName=" + serviceName + ").run(): no update found. lastKnownVersion=" + lastKnownVersion); } } } catch (Exception excp) { LOG.error("PolicyRefresher(serviceName=" + serviceName + "): failed to refresh policies. Will continue to use last known version of policies (" + lastKnownVersion + ")", excp); } RangerPerfTracer.log(perf); if (LOG.isDebugEnabled()) { LOG.debug("<== PolicyRefresher(serviceName=" + serviceName + ").loadPolicyfromPolicyAdmin()"); } return svcPolicies; } private ServicePolicies loadFromCache() { ServicePolicies policies = null; if (LOG.isDebugEnabled()) { LOG.debug("==> PolicyRefresher(serviceName=" + serviceName + ").loadFromCache()"); } File cacheFile = cacheDir == null ? null : new File(cacheDir + File.separator + cacheFileName); if (cacheFile != null && cacheFile.isFile() && cacheFile.canRead()) { Reader reader = null; RangerPerfTracer perf = null; if (RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_INIT_LOG)) { perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_INIT_LOG, "PolicyRefresher.loadFromCache(serviceName=" + serviceName + ")"); } try { reader = new FileReader(cacheFile); policies = gson.fromJson(reader, ServicePolicies.class); if (policies != null) { if (!StringUtils.equals(serviceName, policies.getServiceName())) { LOG.warn("ignoring unexpected serviceName '" + policies.getServiceName() + "' in cache file '" + cacheFile.getAbsolutePath() + "'"); policies.setServiceName(serviceName); } lastKnownVersion = policies.getPolicyVersion() == null ? -1 : policies.getPolicyVersion().longValue(); } } catch (Exception excp) { LOG.error("failed to load policies from cache file " + cacheFile.getAbsolutePath(), excp); } finally { RangerPerfTracer.log(perf); if (reader != null) { try { reader.close(); } catch (Exception excp) { LOG.error("error while closing opened cache file " + cacheFile.getAbsolutePath(), excp); } } } } else { LOG.warn("cache file does not exist or not readable '" + (cacheFile == null ? null : cacheFile.getAbsolutePath()) + "'"); } if (LOG.isDebugEnabled()) { LOG.debug("<== PolicyRefresher(serviceName=" + serviceName + ").loadFromCache()"); } return policies; } private void saveToCache(ServicePolicies policies) { if (LOG.isDebugEnabled()) { LOG.debug("==> PolicyRefresher(serviceName=" + serviceName + ").saveToCache()"); } if (policies != null) { File cacheFile = null; if (cacheDir != null) { // Create the cacheDir if it doesn't already exist File cacheDirTmp = new File(cacheDir); if (cacheDirTmp.exists()) { cacheFile = new File(cacheDir + File.separator + cacheFileName); } else { try { cacheDirTmp.mkdirs(); cacheFile = new File(cacheDir + File.separator + cacheFileName); } catch (SecurityException ex) { LOG.error("Cannot create cache directory", ex); } } } if (cacheFile != null) { RangerPerfTracer perf = null; if (RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_INIT_LOG)) { perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_INIT_LOG, "PolicyRefresher.saveToCache(serviceName=" + serviceName + ")"); } Writer writer = null; try { writer = new FileWriter(cacheFile); gson.toJson(policies, writer); } catch (Exception excp) { LOG.error("failed to save policies to cache file '" + cacheFile.getAbsolutePath() + "'", excp); } finally { if (writer != null) { try { writer.close(); } catch (Exception excp) { LOG.error("error while closing opened cache file '" + cacheFile.getAbsolutePath() + "'", excp); } } } RangerPerfTracer.log(perf); } } else { LOG.info("policies is null. Nothing to save in cache"); } if (LOG.isDebugEnabled()) { LOG.debug("<== PolicyRefresher(serviceName=" + serviceName + ").saveToCache()"); } } }