All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fabric3.policy.DefaultPolicyAttacher Maven / Gradle / Ivy

The newest version!
/*
 * Fabric3
 * Copyright (c) 2009-2015 Metaform Systems
 *
 * 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.
 * Portions originally based on Apache Tuscany 2007
 * licensed under the Apache 2.0 license.
 */
package org.fabric3.policy;

import javax.xml.namespace.QName;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;

import org.fabric3.api.model.type.definitions.ExternalAttachment;
import org.fabric3.api.model.type.definitions.Intent;
import org.fabric3.api.model.type.definitions.PolicySet;
import org.fabric3.policy.infoset.PolicyEvaluationException;
import org.fabric3.policy.infoset.PolicyEvaluator;
import org.fabric3.spi.domain.generator.policy.PolicyAttacher;
import org.fabric3.spi.domain.generator.policy.PolicyRegistry;
import org.fabric3.spi.model.instance.LogicalAttachPoint;
import org.fabric3.spi.model.instance.LogicalBinding;
import org.fabric3.spi.model.instance.LogicalComponent;
import org.fabric3.spi.model.instance.LogicalOperation;
import org.fabric3.spi.model.instance.LogicalReference;
import org.fabric3.spi.model.instance.LogicalScaArtifact;
import org.fabric3.spi.model.instance.LogicalService;
import org.fabric3.spi.model.instance.LogicalState;
import org.fabric3.spi.model.instance.LogicalWire;
import org.oasisopen.sca.annotation.Reference;

/**
 *
 */
public class DefaultPolicyAttacher implements PolicyAttacher {
    private PolicyEvaluator policyEvaluator;
    private PolicyRegistry policyRegistry;

    public DefaultPolicyAttacher(@Reference PolicyEvaluator policyEvaluator, @Reference PolicyRegistry policyRegistry) {
        this.policyEvaluator = policyEvaluator;
        this.policyRegistry = policyRegistry;
    }

    public void attachPolicies(LogicalComponent component, boolean incremental) throws PolicyEvaluationException {
        Collection externalAttachments = policyRegistry.getAllDefinitions(ExternalAttachment.class);
        if (!externalAttachments.isEmpty()) {

            for (ExternalAttachment externalAttachment : externalAttachments) {
                for (QName name : externalAttachment.getPolicySets()) {
                    PolicySet policySet = policyRegistry.getDefinition(name, PolicySet.class);
                    if (policySet == null) {
                        throw new PolicyEvaluationException("Policy set referenced in external attachment not found: " + name);
                    }
                    attachPolicy(component, policySet, externalAttachment.getAttachTo(), incremental);
                }
                for (QName name : externalAttachment.getIntents()) {
                    Intent intent = policyRegistry.getDefinition(name, Intent.class);
                    if (intent == null) {
                        throw new PolicyEvaluationException("Intent referenced in external attachment not found: " + name);
                    }
                    //intentMap.put(intent, externalAttachment.getAttachTo());
                }
            }

        }
        Set policySets = policyRegistry.getExternalAttachmentPolicies();
        attachPolicies(policySets, component, incremental);
    }

    public void attachPolicies(Set policySets, LogicalComponent component, boolean incremental) throws PolicyEvaluationException {
        for (PolicySet policySet : policySets) {
            attachPolicy(component, policySet, policySet.getAttachTo(), incremental);
        }
    }

    public void detachPolicies(Set policySets, LogicalComponent component) throws PolicyEvaluationException {
        for (PolicySet policySet : policySets) {
            Collection> results = policyEvaluator.evaluate(policySet.getAttachTo(), component);

            for (Iterator> iterator = results.iterator(); iterator.hasNext(); ) {
                LogicalScaArtifact result = iterator.next();
                String appliesTo = policySet.getAppliesTo();
                if (appliesTo != null && !policyEvaluator.doesApply(appliesTo, result)) {
                    iterator.remove();
                }
            }

            // detach policy sets
            for (LogicalScaArtifact result : results) {
                detach(policySet.getName(), result);
            }
        }
    }

    /**
     * Performs the actual attachment on the target artifact.
     *
     * @param policySet   the PolicySet to attach
     * @param target      the target to attach to
     * @param incremental if the attachment is being performed as part of an incremental deployment. If true, the state of the target is set to NEW.
     * @throws PolicyEvaluationException if an error occurs performing the attachment
     */
    void attach(QName policySet, LogicalScaArtifact target, boolean incremental) throws PolicyEvaluationException {
        if (target instanceof LogicalComponent) {
            LogicalComponent component = (LogicalComponent) target;
            if (component.getPolicySets().contains(policySet)) {
                return;
            }
            if (incremental && !component.getPolicySets().contains(policySet)) {
                component.addPolicySet(policySet);
                processComponent(component, policySet, incremental);
            } else if (!incremental) {
                component.addPolicySet(policySet);
            }
        } else if (target instanceof LogicalService) {
            LogicalService service = (LogicalService) target;
            // add the policy to the service but mark bindings as NEW for (re)provisioning
            if (service.getPolicySets().contains(policySet) && incremental) {
                return;
            }
            service.addPolicySet(policySet);
            processService(service, policySet, incremental);
        } else if (target instanceof LogicalReference) {
            LogicalReference reference = (LogicalReference) target;
            if (reference.getPolicySets().contains(policySet)) {
                return;
            }
            reference.addPolicySet(policySet);
            processReference(reference, policySet, incremental);

        } else if (target instanceof LogicalOperation) {
            LogicalOperation operation = (LogicalOperation) target;
            if (operation.getPolicySets().contains(policySet)) {
                return;
            }
            operation.addPolicySet(policySet);
            LogicalAttachPoint attachPoint = operation.getParent();
            if (attachPoint instanceof LogicalReference) {
                processReference((LogicalReference) attachPoint, policySet, incremental);
            } else if (attachPoint instanceof LogicalService) {
                processService((LogicalService) attachPoint, policySet, incremental);
            } else {
                throw new PolicyEvaluationException("Invalid policy attachment type: " + target.getClass());
            }
        } else if (target instanceof LogicalBinding) {
            LogicalBinding binding = (LogicalBinding) target;
            if (binding.getPolicySets().contains(policySet)) {
                return;
            }
            binding.addPolicySet(policySet);
            binding.setState(LogicalState.NEW);
        } else {
            throw new PolicyEvaluationException("Invalid policy attachment type: " + target.getClass());
        }
    }

    /**
     * Performs the actual detachment on the target artifact.
     *
     * @param policySet the PolicySet to attach
     * @param target    the target to attach to
     * @throws PolicyEvaluationException if an error occurs performing the attachment
     */
    void detach(QName policySet, LogicalScaArtifact target) throws PolicyEvaluationException {
        if (target instanceof LogicalComponent) {
            LogicalComponent component = (LogicalComponent) target;
            if (!component.getPolicySets().contains(policySet)) {
                return;
            }
            if (component.getPolicySets().contains(policySet)) {
                component.removePolicySet(policySet);
                processDetachComponent(component, policySet, true);
            }
        } else if (target instanceof LogicalService) {
            LogicalService service = (LogicalService) target;
            // remove the policy to the service but mark bindings as NEW for (re)provisioning
            if (!service.getPolicySets().contains(policySet)) {
                return;
            }
            service.removePolicySet(policySet);
            processDetachService(service, policySet, true);
        } else if (target instanceof LogicalReference) {
            LogicalReference reference = (LogicalReference) target;
            if (!reference.getPolicySets().contains(policySet)) {
                return;
            }
            reference.removePolicySet(policySet);
            processDetachReference(reference, policySet, true);

        } else if (target instanceof LogicalOperation) {
            LogicalOperation operation = (LogicalOperation) target;
            if (!operation.getPolicySets().contains(policySet)) {
                return;
            }
            operation.removePolicySet(policySet);
            LogicalAttachPoint attachPoint = operation.getParent();
            if (attachPoint instanceof LogicalReference) {
                processDetachReference((LogicalReference) attachPoint, policySet, true);
            } else if (attachPoint instanceof LogicalService) {
                processDetachService((LogicalService) attachPoint, policySet, true);
            } else {
                throw new PolicyEvaluationException("Invalid policy attachment type: " + target.getClass());
            }
        } else if (target instanceof LogicalBinding) {
            LogicalBinding binding = (LogicalBinding) target;
            if (!binding.getPolicySets().contains(policySet)) {
                return;
            }
            binding.removePolicySet(policySet);
            binding.setState(LogicalState.NEW);
        } else {
            throw new PolicyEvaluationException("Invalid policy attachment type: " + target.getClass());
        }
    }

    private void attachPolicy(LogicalComponent component, PolicySet policySet, String attachTo, boolean incremental) throws PolicyEvaluationException {
        Collection> results = policyEvaluator.evaluate(attachTo, component);

        for (Iterator> iterator = results.iterator(); iterator.hasNext(); ) {
            LogicalScaArtifact result = iterator.next();
            String appliesTo = policySet.getAppliesTo();
            if (appliesTo != null && !policyEvaluator.doesApply(appliesTo, result)) {
                iterator.remove();
            }
        }

        // attach policy sets
        for (LogicalScaArtifact result : results) {
            attach(policySet.getName(), result, incremental);
        }
    }

    private void processComponent(LogicalComponent component, QName policySet, boolean incremental) {
        // do not mark the component as new, just the wires since the implementation does not need to be reprovisioned
        for (LogicalReference reference : component.getReferences()) {
            processReference(reference, policySet, incremental);
        }
        for (LogicalService service : component.getServices()) {
            processService(service, policySet, incremental);
        }
    }

    private void processService(LogicalService service, QName policySet, boolean incremental) {
        for (LogicalBinding binding : service.getBindings()) {
            if (incremental && binding.getPolicySets().contains(policySet)) {
                continue;
            }
            binding.setState(LogicalState.NEW);
        }
        // TODO check collocated wires, i.e. references attached directly to the service so they can be reprovisioned
    }

    private void processReference(LogicalReference reference, QName policySet, boolean incremental) {
        for (LogicalWire wire : reference.getWires()) {
            wire.setState(LogicalState.NEW);
        }
        for (LogicalBinding binding : reference.getBindings()) {
            if (incremental && binding.getPolicySets().contains(policySet)) {
                continue;
            }
            binding.setState(LogicalState.NEW);
        }
    }

    private void processDetachComponent(LogicalComponent component, QName policySet, boolean incremental) {
        // do not mark the component as new, just the wires since the implementation does not need to be reprovisioned
        for (LogicalReference reference : component.getReferences()) {
            processDetachReference(reference, policySet, incremental);
        }
        for (LogicalService service : component.getServices()) {
            processDetachService(service, policySet, incremental);
        }
    }

    private void processDetachService(LogicalService service, QName policySet, boolean incremental) {
        for (LogicalBinding binding : service.getBindings()) {
            if (incremental && !binding.getPolicySets().contains(policySet)) {
                continue;
            }
            binding.setState(LogicalState.NEW);
        }
        // TODO check collocated wires, i.e. references attached directly to the service so they can be reprovisioned
    }

    private void processDetachReference(LogicalReference reference, QName policySet, boolean incremental) {
        for (LogicalWire wire : reference.getWires()) {
            wire.setState(LogicalState.NEW);
        }
        for (LogicalBinding binding : reference.getBindings()) {
            if (incremental && !binding.getPolicySets().contains(policySet)) {
                continue;
            }
            binding.setState(LogicalState.NEW);
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy