Package org.glite.authz.pap.distribution

Source Code of org.glite.authz.pap.distribution.DistributionModule

/**
* Copyright (c) Members of the EGEE Collaboration. 2006-2009.
* See http://www.eu-egee.org/partners/ for details on the copyright holders.
*
* Licensed 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.glite.authz.pap.distribution;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.rpc.ServiceException;

import org.glite.authz.pap.common.Pap;
import org.glite.authz.pap.common.xacml.impl.TypeStringUtils;
import org.glite.authz.pap.papmanagement.PapContainer;
import org.glite.authz.pap.papmanagement.PapManager;
import org.opensaml.xacml.XACMLObject;
import org.opensaml.xacml.policy.PolicySetType;
import org.opensaml.xacml.policy.PolicyType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* This class implements the distribution module, that means running a thread which regularly polls
* remote paps to fetch policies.
* <p>
* Start the thread that polls remote paps by calling the
* {@link DistributionModule#startDistributionModule()} method and stop it by calling the
* {@link DistributionModule#stopDistributionModule()} method.
* <p>
* The {@link DistributionModule#refreshCache(Pap)} method can be used to force a refresh of the
* remote paps cache asynchronously.
*/
public class DistributionModule extends Thread {

    /** lock used when the cache of a pap is refreshed. */
    public static final Object storePoliciesLock = new Object();

    private static final Logger log = LoggerFactory.getLogger(DistributionModule.class);
    private static DistributionModule instance = null;

    private long sleepTime;

    private boolean stayRunning = true;

    private DistributionModule() {
        initialize();
    }

    public static DistributionModule getInstance() {
        if (instance == null)
            instance = new DistributionModule();
        return instance;
    }

    /**
     * Refreshes the policies of a pap, that means fetching the policies and storing them in the
     * repository. If the given pap is not remote then nothing happens.
     *
     * @param pap
     *
     * @throws RemoteException
     * @throws ServiceException
     */
    public static void refreshCache(Pap pap) throws RemoteException, ServiceException {
        log.info("Refreshing cache of remote PAP " + pap.getAlias());
        List<XACMLObject> papPolicies = getPoliciesFromPap(pap);
        log.info(String.format("Retrieved %d XACML objects from PAP %s (%s)",
                               papPolicies.size(),
                               pap.getAlias(),
                               pap.getEndpoint()));
        storePapPolicies(pap, papPolicies);
    }

    /**
     * Fetches policies from a remote pap.
     *
     * @param remotePap the remote pap to fetch policies from.
     * @return the list of policy sets and policies of the pap. The first element is the root policy
     *         set of the pap. Returns an empty list if the pap wasn't a remote pap.
     *
     * @throws RemoteException
     * @throws ServiceException
     */
    private static List<XACMLObject> getPoliciesFromPap(Pap remotePap) throws RemoteException,
            ServiceException {

        if (!remotePap.isRemote()) {
            log.error("Attempting to fetch policies from the local pap: " + remotePap.getAlias());
            return new ArrayList<XACMLObject>(0);
        }

        PAPClient client = new PAPClient(remotePap.getEndpoint());

        List<XACMLObject> papPolicies = client.retrievePolicies();

        return papPolicies;
    }

    /**
     * Replace the policy cache of the given pap with the given policies.
     *
     * @param pap
     * @param papPolicies
     */
    private static void storePapPolicies(Pap pap, List<XACMLObject> papPolicies) {

        if (papPolicies.isEmpty()) {
            return;
        }

        log.debug(String.format("Storing policies for PAP %s (id=%s)", pap.getAlias(), pap.getId()));

        PapManager papManager = PapManager.getInstance();
        PapContainer papContainer = papManager.getPapContainer(pap.getAlias());

        synchronized (storePoliciesLock) {

            papContainer.deleteAllPolicies();
            papContainer.deleteAllPolicySets();

            XACMLObject papRoot = papPolicies.get(0);

            if (papRoot instanceof PolicySetType) {

                ((PolicySetType) papRoot).setPolicySetId(papContainer.getPap().getId());

                for (XACMLObject xacmlObject : papPolicies) {

                    if (xacmlObject instanceof PolicySetType) {
                        PolicySetType policySet = (PolicySetType) xacmlObject;
                        papContainer.storePolicySet(policySet);

                        log.debug(String.format("Stored PolicySet \"%s\" into pap \"%s\"",
                                                policySet.getPolicySetId(),
                                                pap.getAlias()));
                    } else if (xacmlObject instanceof PolicyType) {

                        PolicyType policy = (PolicyType) xacmlObject;
                        papContainer.storePolicy(policy);

                        log.debug(String.format("Stored Policy \"%s\" into pap \"%s\"",
                                                policy.getPolicyId(),
                                                pap.getAlias()));
                    } else {

                        log.error(String.format("Invalid object (not a Policy or PolicySet) received from PAP %s (%s)",
                                                pap.getAlias(),
                                                pap.getEndpoint()));
                    }
                    TypeStringUtils.releaseUnneededMemory(xacmlObject);
                }
            } else {
                log.error(String.format("The root of the policy tree is not a PolicySet (papAlias=%s, endpoint=%s)",
                                        pap.getAlias(),
                                        pap.getEndpoint()));
            }
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Thread#run()
     */
    public void run() {

        while (stayRunning) {
            try {
                while (!this.isInterrupted()) {

                    log.info("Starting refresh cache thread...");

                    for (Pap pap : PapManager.getInstance().getRemotePaps()) {

                        if (this.isInterrupted())
                            break;

                        try {
                            refreshCache(pap);
                        } catch (RemoteException e) {
                            log.error(String.format("Error connecting to %s (%s): %s",
                                                    pap.getAlias(),
                                                    pap.getEndpoint(),
                                                    e.getMessage()));
                        } catch (ServiceException e) {
                            log.error(String.format("Cannot connect to: %s (%s)",
                                                    pap.getAlias(),
                                                    pap.getEndpoint(),
                                                    e.getMessage()));
                        }
                    }

                    log.info("Refresh cache thread done.");

                    sleep(sleepTime);
                }
            } catch (InterruptedException e) {}
        }
    }

    public void startDistributionModule() {
        this.start();
    }

    public void setSleepTime(long seconds) {
        sleepTime = seconds * 1000;
        this.interrupt();
    }

    public void stopDistributionModule() {

        stayRunning = false;
       
        this.interrupt();

        while (this.isAlive());
    }

    protected void initialize() {
        log.info("Initilizing distribution module...");
        sleepTime = DistributionConfiguration.getInstance().getPollIntervall() * 1000;
    }
}
TOP

Related Classes of org.glite.authz.pap.distribution.DistributionModule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.