org.opendaylight.sfc.provider.validators.ServiceFunctionPathCohort.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.sfc.provider.validators.ServiceFunctionPathCohort.java

Source

/*
 * Copyright (c) 2017 Ericsson Spain and others. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.sfc.provider.validators;

import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.Futures;
import java.util.Collection;
import java.util.Iterator;
import javassist.ClassPool;
import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
import org.opendaylight.mdsal.binding.generator.util.JavassistUtils;
import org.opendaylight.mdsal.common.api.DataValidationFailedException;
import org.opendaylight.mdsal.common.api.PostCanCommitStep;
import org.opendaylight.mdsal.dom.api.DOMDataTreeCandidate;
import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohort;
import org.opendaylight.sfc.provider.validators.util.ValidationConstants;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Pre-commit semantic validation for service function path datastore objects
 *
 * <p>
 * After registration, the canCommit() method will be invoked in order to
 * validate SFP object creations / modifications. This validation will check
 * coherence with referenced SF, SFC type definitions
 */
public class ServiceFunctionPathCohort implements DOMDataTreeCommitCohort {

    private static final Logger LOG = LoggerFactory.getLogger(ServiceFunctionPathCohort.class);
    ModuleInfoBackedContext moduleContext = ModuleInfoBackedContext.create();
    ImmutableSet<YangModuleInfo> infos = BindingReflections.loadModuleInfos();
    BindingRuntimeContext bindingContext;
    BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(
            StreamWriterGenerator.create(JavassistUtils.forClassPool(ClassPool.getDefault())));
    ServiceFunctionPathValidator sfpv;

    public ServiceFunctionPathCohort(ServiceFunctionPathValidator sfpv) {
        this.sfpv = sfpv;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public CheckedFuture<PostCanCommitStep, DataValidationFailedException> canCommit(Object txId,
            DOMDataTreeCandidate candidate, SchemaContext ctx) {

        LOG.debug("canCommit:called! txId={}, candidate={}, context={} ", txId, candidate, ctx);

        DataTreeCandidateNode candidateRoot = candidate.getRootNode();
        NormalizedNode nn = candidateRoot.getDataAfter().orNull();
        if (nn == null) {
            LOG.debug("canCommit:no sfp after the change");
            return ValidationConstants.SUCCESS_CAN_COMMIT_FUTURE;
        }

        LOG.debug("canCommit:updating codec contexts");
        moduleContext.addModuleInfos(infos);
        bindingContext = BindingRuntimeContext.create(moduleContext, ctx);
        codecRegistry.onBindingRuntimeContextUpdated(bindingContext);

        LOG.debug("canCommit:Mapping service ready");

        LOG.debug("canCommit:before deserializing:  {}", nn);
        // (nn is an immutableMapNode). Contains an unmodifiable collection
        // reference of all this thing
        // https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Design:Normalized_DOM_Model
        Collection collection = (Collection<MapEntryNode>) nn.getValue();
        LOG.debug("canCommit:collection containing the sfs:  {}", collection);
        Iterator<MapEntryNode> menIter = collection.iterator();
        while (menIter.hasNext()) {
            MapEntryNode meNode = menIter.next();
            LOG.debug("canCommit:sfp to process: {}", meNode);
            NormalizedNode sfpAsNormalizedNode = meNode;
            LOG.debug("canCommit:the first SF (as nn):  {}", sfpAsNormalizedNode);
            DataObject dobj = codecRegistry
                    .fromNormalizedNode(ValidationConstants.SFP_PATH_YII, sfpAsNormalizedNode).getValue();
            LOG.debug("canCommit:registerValidationCohorts:the first SFP (as dataobject):  {}", dobj);
            ServiceFunctionPath sfp = (ServiceFunctionPath) dobj;
            LOG.debug("canCommit:registerValidationCohorts:the implemented interface: {}",
                    dobj.getImplementedInterface());
            LOG.debug("canCommit:the first SF (as binding representation):  {}", sfp);
            try {
                if (!sfpv.validateServiceFunctionPath(sfp)) {
                    return ValidationConstants.FAILED_CAN_COMMIT_SFP_FUTURE;
                }
            } catch (DataValidationFailedException dvfe) {
                return Futures.immediateFailedCheckedFuture(dvfe);
            }
        }
        return ValidationConstants.SUCCESS_CAN_COMMIT_FUTURE;
    }
}