org.opendaylight.topoprocessing.impl.rpc.OverlayRpcImplementation.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.topoprocessing.impl.rpc.OverlayRpcImplementation.java

Source

/*
 * Copyright (c) 2015 Pantheon Technologies s.r.o. 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.topoprocessing.impl.rpc;

import java.util.Collection;

import com.google.common.util.concurrent.Futures;

import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier;
import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation;
import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
import org.opendaylight.controller.md.sal.dom.broker.spi.rpc.RpcRoutingStrategy;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.util.concurrent.CheckedFuture;

/**
 * Used for delegation of RPC calls.
 * Topoprocessing project exposes RPCs of underlay items and republishes them
 * as {@link OverlayRpcImplementation} which stores original underlay item
 * to invoke received RPC on
 * @author michal.polkorab
 */
public class OverlayRpcImplementation implements DOMRpcImplementation {

    private static final Logger LOGGER = LoggerFactory.getLogger(OverlayRpcImplementation.class);
    private DOMRpcService rpcService;
    private SchemaContext schemaContext;
    private YangInstanceIdentifier underlayItemIdentifier;

    /**
     * Default constructor
     * @param rpcService used to reinvoked RPC at correct place
     * @param schemaContext used to get {@link RpcDefinition} {@link RpcRoutingStrategy}
     * @param underlayNodeIdentifier identifies node which the RPC should be really invoked on
     */
    public OverlayRpcImplementation(DOMRpcService rpcService, SchemaContext schemaContext,
            YangInstanceIdentifier underlayNodeIdentifier) {
        this.rpcService = rpcService;
        this.schemaContext = schemaContext;
        this.underlayItemIdentifier = underlayNodeIdentifier;
    }

    @Override
    public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(DOMRpcIdentifier rpc,
            NormalizedNode<?, ?> input) {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Invoked rpc: " + rpc);
        }
        RpcDefinition rpcDefinition = findRpcDefinition(schemaContext, rpc.getType());
        if (null == rpcDefinition) {
            return Futures.immediateFailedCheckedFuture(
                    (DOMRpcException) new DOMRpcException("Rpc definition not found") {
                    });
        }
        RpcRoutingStrategy routingStrategy = RpcRoutingStrategy.from(rpcDefinition);
        DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> containerBuilder = ImmutableContainerNodeBuilder
                .create(ImmutableNodes.containerNode(input.getNodeType()));
        Collection<DataContainerChild<? extends PathArgument, ?>> inputChilds = ((ContainerNode) input).getValue();
        for (DataContainerChild<? extends PathArgument, ?> child : inputChilds) {
            if (!(child instanceof AugmentationNode)) {
                if (child.getNodeType().equals(routingStrategy.getLeaf())) {
                    containerBuilder.addChild(ImmutableNodes.leafNode(child.getNodeType(), underlayItemIdentifier));
                } else {
                    containerBuilder.addChild(child);
                }
            } else {
                containerBuilder.addChild(child);
            }
        }
        ContainerNode underlayRpcInput = containerBuilder.build();
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Reinvoking RPC at: {} with input: {}", underlayItemIdentifier, underlayRpcInput);
        }
        return rpcService.invokeRpc(rpc.getType(), underlayRpcInput);
    }

    private static RpcDefinition findRpcDefinition(final SchemaContext context, final SchemaPath schemaPath) {
        if (context != null) {
            final QName qname = schemaPath.getPathFromRoot().iterator().next();
            final Module module = context.findModuleByNamespaceAndRevision(qname.getNamespace(),
                    qname.getRevision());
            if (module != null && module.getRpcs() != null) {
                for (RpcDefinition rpc : module.getRpcs()) {
                    if (qname.equals(rpc.getQName())) {
                        return rpc;
                    }
                }
            }
        }
        LOGGER.debug("RpcDefinition not found");
        return null;
    }
}