Package org.wso2.carbon.identity.entitlement.pdp

Source Code of org.wso2.carbon.identity.entitlement.pdp.EntitlementEngine

/*
*  Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
*  WSO2 Inc. 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.wso2.carbon.identity.entitlement.pdp;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Element;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.identity.base.IdentityException;
import org.wso2.carbon.identity.entitlement.pip.CarbonAttributeFinder;
import org.wso2.carbon.identity.entitlement.policy.PolicyReader;
import org.wso2.carbon.identity.entitlement.policy.PolicyStoreReader;
import org.wso2.carbon.identity.entitlement.policy.PolicyStore;
import org.wso2.carbon.identity.entitlement.policy.finder.RegistryBasedPolicyFinder;

import com.sun.xacml.PDP;
import com.sun.xacml.PDPConfig;
import com.sun.xacml.ParsingException;
import com.sun.xacml.ctx.RequestCtx;
import com.sun.xacml.ctx.ResponseCtx;
import com.sun.xacml.finder.AttributeFinder;
import com.sun.xacml.finder.PolicyFinder;
import com.sun.xacml.finder.PolicyFinderModule;
import com.sun.xacml.finder.impl.CurrentEnvModule;
import com.sun.xacml.finder.impl.SelectorModule;
import org.wso2.carbon.registry.core.Registry;

public class EntitlementEngine {

    private RegistryBasedPolicyFinder registryModule;
    private PDP pdp;
    private static volatile EntitlementEngine engine;
    private static final Object lock = new Object();
    private static final String PDP_DECISION_CACHING_INTERVAL = "pdpDecisionCachingInterval";
    private int pdpDecisionCachingInterval = -1;
    private Map<String, PolicyDecision> decisionCache = new ConcurrentHashMap<String, PolicyDecision>();
    private static ConcurrentHashMap<String, EntitlementEngine> entitlementEngines =
                new ConcurrentHashMap<String, EntitlementEngine>();
    private static Log log = LogFactory.getLog(EntitlementEngine.class);

     /**
     * Get a EntitlementEngine instance for that tenant. This method will return an EntitlementEngine
     * instance if exists, or creates a new one
     * @param registry Governance Registry instance of the corresponding tenant
     * @param tenantId Tenant ID of corresponding tenant
     * @return  EntitlementEngine instance for that tenant
     * @throws org.wso2.carbon.identity.base.IdentityException throws IdentityException
     */
    public static EntitlementEngine getInstance(Registry registry, int tenantId)
            throws IdentityException {
        if (!entitlementEngines.containsKey(Integer.toString(tenantId))) {
            entitlementEngines.put(Integer.toString(tenantId), new EntitlementEngine(registry, tenantId));
        }
        return entitlementEngines.get(Integer.toString(tenantId));
    }

    private EntitlementEngine(Registry registry, int tenantId) throws IdentityException {

        PolicyFinder policyFinder = null;
        Set<PolicyFinderModule> policyModules = null;
        // Setup the PolicyFinder that the EntitlementEngine will use
        policyFinder = new PolicyFinder();

        registryModule = new RegistryBasedPolicyFinder(new PolicyStoreReader(new PolicyStore(
                registry)), tenantId);

        policyModules = new HashSet<PolicyFinderModule>();
        // Add all policy finders - we only have RegistryBasedPolicyFinder
        policyModules.add(registryModule);

        policyFinder.setModules(policyModules);

        // init policy reader 
        PolicyReader.getInstance(null, policyFinder);

        // Now setup attribute finder modules for the current date/time and
        // AttributeSelectors (selectors are optional, but this project does
        // support a basic implementation)
        CurrentEnvModule envAttributeModule = new CurrentEnvModule();
        SelectorModule selectorAttributeModule = new SelectorModule();

        // Setup the AttributeFinder just like we setup the PolicyFinder. Note
        // that unlike with the policy finder, the order matters here.
        AttributeFinder attributeFinder = new AttributeFinder();
        List<Object> attributeModules = new ArrayList<Object>();
        attributeModules.add(envAttributeModule);
        attributeModules.add(selectorAttributeModule);
        attributeModules.add(new CarbonAttributeFinder());
        attributeFinder.setModules(attributeModules);

        String cacheInterval = ServerConfiguration.getInstance().getFirstProperty(
                PDP_DECISION_CACHING_INTERVAL);

        if (cacheInterval != null) {
            pdpDecisionCachingInterval = Integer.parseInt(cacheInterval);
        }

        // Finally, initialize
        pdp = new PDP(new PDPConfig(attributeFinder, policyFinder, null));
    }

    /**
     * Evaluates the given XACML request and returns the Response that the EntitlementEngine will
     * hand back to the PEP. PEP needs construct the XACML request before sending it to the
     * EntitlementEngine
     *
     * @param xamlRequest
     *            XACML request as an Element
     * @return Response
     * @throws com.sun.xacml.ParsingException
     * @throws java.io.IOException
     */
    public ResponseCtx evaluate(Element xamlRequest) throws IOException, ParsingException {
        RequestCtx request = RequestCtx.getInstance(xamlRequest);
        ResponseCtx response = null;

        if ((response = getFromCache(request)) != null) {
            return response;
        }

        // evaluate the request
        response = pdp.evaluate(request);
        addToCache(request, response);
        return response;
    }

    /**
     * Evaluates the given XACML request and returns the Response that the EntitlementEngine will
     * hand back to the PEP. PEP needs construct the XACML request before sending it to the
     * EntitlementEngine
     *
     * @param request
     * @return
     * @throws IOException
     * @throws ParsingException
     */
    public ResponseCtx evaluate(RequestCtx request) throws IOException, ParsingException {
        ResponseCtx response = null;
        if ((response = getFromCache(request)) != null) {
            return response;
        }
        // evaluate the request
        response = pdp.evaluate(request);
        addToCache(request, response);
        return response;
    }

    /**
     * This method is returns the registry based policy finder for current tenant
     *
     * @return RegistryBasedPolicyFinder
     */
    public RegistryBasedPolicyFinder getRegistryModule() {
        return registryModule;
    }

    private ResponseCtx getFromCache(RequestCtx request) {
        if (pdpDecisionCachingInterval > 0) {
            OutputStream xml = new ByteArrayOutputStream();
            request.encode(xml);
            PolicyDecision decision = decisionCache.get(xml.toString());
            if (decision != null
                    && (decision.getCachedTime() + new Long(pdpDecisionCachingInterval).longValue() > Calendar
                            .getInstance().getTimeInMillis())) {
                if (log.isDebugEnabled()) {
                    log.debug("PDP Decision Cache Hit");
                }
                return decision.getResponse();
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("PDP Decision Cache Miss");
                }
                decisionCache.remove(xml.toString());
                return null;
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("PDP Decision Caching Disabled");
        }
        return null;
    }

    private void addToCache(RequestCtx request, ResponseCtx response) {
        if (pdpDecisionCachingInterval > 0) {
            PolicyDecision decision = new PolicyDecision();
            OutputStream xml = new ByteArrayOutputStream();
            request.encode(xml);
            decision.setCachedTime(Calendar.getInstance().getTimeInMillis());
            decision.setResponse(response);
            decisionCache.put(xml.toString(), decision);
            if (log.isDebugEnabled()) {
                log.debug("PDP Decision Cache Updated");
            }
        } else {
            if (log.isDebugEnabled()) {
                log.debug("PDP Decision Caching Disabled");
            }
        }
    }

    /**
     * Clears the decision cache.
     */
    public void clearDecisionCache() {
        decisionCache.clear();
    }
}
TOP

Related Classes of org.wso2.carbon.identity.entitlement.pdp.EntitlementEngine

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.