ddf.security.pdp.xacml.processor.PollingPolicyFinderModule.java Source code

Java tutorial

Introduction

Here is the source code for ddf.security.pdp.xacml.processor.PollingPolicyFinderModule.java

Source

/**
 * Copyright (c) Codice Foundation
 * 
 * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser
 * General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or any later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details. A copy of the GNU Lesser General Public License
 * is distributed along with this program and can be found at
 * <http://www.gnu.org/licenses/lgpl.html>.
 * 
 **/
package ddf.security.pdp.xacml.processor;

import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Iterator;
import java.util.Set;

import org.apache.commons.io.monitor.FileAlterationListener;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wso2.balana.finder.impl.FileBasedPolicyFinderModule;

/**
 * 
 * @author Dan Figliola
 * @author Shaun Morris
 * @author ddf.isgs@lmco.com
 * 
 *         This class Polls Directories for policies. It is used with the PDP to poll directories
 *         for changes to polices or the policy set in the directories.
 * 
 */
public class PollingPolicyFinderModule extends FileBasedPolicyFinderModule implements FileAlterationListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(PollingPolicyFinderModule.class);

    private static final int MULTIPLIER = 1000;

    private FileAlterationMonitor monitor;

    private Set<String> xacmlPolicyDirectories;

    /**
     * 
     * @param xacmlPolicyDirectories
     *            - to search for policies
     * @param pollingInterval
     *            - in seconds
     */
    public PollingPolicyFinderModule(Set<String> xacmlPolicyDirectories, long pollingInterval) {
        super(xacmlPolicyDirectories);
        this.xacmlPolicyDirectories = xacmlPolicyDirectories;
        initialize(xacmlPolicyDirectories, pollingInterval);
    }

    private void initialize(Set<String> xacmlPolicyDirectories, long pollingInterval) {
        LOGGER.debug("initializing polling: {}, every {}", xacmlPolicyDirectories, pollingInterval);
        monitor = new FileAlterationMonitor(pollingInterval * MULTIPLIER);

        Iterator<String> iterator = xacmlPolicyDirectories.iterator();

        while (iterator.hasNext()) {
            File directoryToMonitor = new File(iterator.next());
            FileAlterationObserver observer = new FileAlterationObserver(directoryToMonitor, getXmlFileFilter());
            observer.addListener(this);
            monitor.addObserver(observer);
            LOGGER.debug("Monitoring directory: " + directoryToMonitor);
        }
    }

    public void start() {
        try {
            monitor.start();
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

    public void onDirectoryChange(File changedDir) {
        try {
            LOGGER.debug("Directory " + changedDir.getCanonicalPath() + " changed.");
        } catch (IOException e) {
            LOGGER.error(e.getMessage(), e);
        }

        reloadPolicies();
    }

    public void onDirectoryCreate(File createdDir) {
        try {
            LOGGER.debug("Directory " + createdDir.getCanonicalPath() + " was created.");
        } catch (IOException e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

    public void onDirectoryDelete(File deletedDir) {
        try {
            LOGGER.debug("Directory " + deletedDir.getCanonicalPath() + " was deleted.");
        } catch (IOException e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

    public void onFileChange(File changedFile) {
        try {
            LOGGER.debug("File " + changedFile.getCanonicalPath() + " changed.");
        } catch (IOException e) {
            LOGGER.error(e.getMessage(), e);
        }

        reloadPolicies();
    }

    public void onFileCreate(File createdFile) {
        try {
            LOGGER.debug("File " + createdFile.getCanonicalPath() + " was created.");
        } catch (IOException e) {
            LOGGER.error(e.getMessage(), e);
        }

        reloadPolicies();
    }

    public void onFileDelete(File deleteFile) {
        try {
            LOGGER.debug("File " + deleteFile.getCanonicalPath() + " was deleted.");
        } catch (IOException e) {
            LOGGER.error(e.getMessage(), e);
        }

        reloadPolicies();
    }

    public void onStart(FileAlterationObserver observer) {
        try {
            String directoryPath = observer.getDirectory().getCanonicalPath();
            LOGGER.trace("starting to check directory for xacml policy update(s) " + directoryPath);

            if (!xacmlPolicyDirectories.isEmpty()
                    && isXacmlPoliciesDirectoryEmpty(xacmlPolicyDirectories.iterator().next())) {
                LOGGER.warn("No XACML Policies found in: {}", directoryPath);
            }
        } catch (IOException e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

    public void onStop(FileAlterationObserver observer) {
        try {
            LOGGER.trace("Done checking directory " + observer.getDirectory().getCanonicalPath());
        } catch (IOException e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

    /**
     * Checks if the XACML policy directory is empty.
     * 
     * @param xacmlPoliciesDirectory
     *            The directory containing the XACML policy.
     * @return true if the directory is empty and false otherwise.
     */
    private boolean isXacmlPoliciesDirectoryEmpty(File xacmlPoliciesDirectory) {
        return xacmlPoliciesDirectory.isDirectory()
                && xacmlPoliciesDirectory.listFiles(getXmlFilenameFilter()).length == 0;

    }

    /**
     * Checks if the XACML policy directory is empty.
     * 
     * @param xacmlPoliciesDirectory
     *            The directory containing the XACML policy.
     * @return true if the directory is empty and false otherwise.
     */
    private boolean isXacmlPoliciesDirectoryEmpty(String xacmlPoliciesDirectory) {
        return isXacmlPoliciesDirectoryEmpty(new File(xacmlPoliciesDirectory));

    }

    /**
     * Checks if the XACML policy directory is empty.
     * 
     * @param xacmlPoliciesDirectory
     *            The directory containing the XACML policy.
     * @return true if the directory is empty and false otherwise.
     */
    private boolean isXacmlPoliciesDirectoriesEmpty(Set<String> xacmlPoliciesDirectories) {

        // This method is currently not called, but remains in case
        // multiple directories are supported
        for (String xacmlPolicyDirectory : xacmlPoliciesDirectories) {
            if (!isXacmlPoliciesDirectoryEmpty(xacmlPolicyDirectory)) {
                return false;
            }
        }
        return true;
    }

    private FileFilter getXmlFileFilter() {
        FileFilter xmlFileFilter = new FileFilter() {
            public boolean accept(File pathName) {
                return pathName.getName().toLowerCase().endsWith(".xml");
            }

        };

        return xmlFileFilter;
    }

    private FilenameFilter getXmlFilenameFilter() {
        FilenameFilter filter = new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.toLowerCase().endsWith(".xml");
            }
        };

        return filter;
    }

    public void setPollingInterval(long pollingInterval) {
        initialize(xacmlPolicyDirectories, pollingInterval);
    }

    private void reloadPolicies() {
        LOGGER.debug("Reloading XACML policies");
        this.loadPolicies();
    }

}