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

io.lighty.gnmi.southbound.mountpoint.codecs.YangInstanceIdentifierToPathCodec Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2021 PANTHEON.tech s.r.o. 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 https://www.eclipse.org/legal/epl-v10.html
 */

package io.lighty.gnmi.southbound.mountpoint.codecs;

import com.google.common.collect.Iterators;
import com.google.common.collect.PeekingIterator;
import gnmi.Gnmi;
import io.lighty.gnmi.southbound.schema.provider.SchemaContextProvider;
import java.util.Map;
import java.util.Optional;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class YangInstanceIdentifierToPathCodec implements Codec {
    private static final Logger LOG = LoggerFactory.getLogger(YangInstanceIdentifierToPathCodec.class);

    private final SchemaContextProvider schemaContextProvider;
    /**
     * If the resulting path should contain module identifier in first element.
     * (e.g interfaces -> openconfig-interfaces:interfaces).
     * This approach for example is required in SONIC device.
     */
    private final boolean prefixFirstElement;

    public YangInstanceIdentifierToPathCodec(final SchemaContextProvider schemaContextProvider,
                                             final boolean prefixFirstElement) {
        this.schemaContextProvider = schemaContextProvider;
        this.prefixFirstElement = prefixFirstElement;
    }

    public Gnmi.Path apply(final YangInstanceIdentifier path) {
        final Gnmi.Path.Builder pathBuilder = Gnmi.Path.newBuilder();
        final PeekingIterator iterator =
                Iterators.peekingIterator(path.getPathArguments().iterator());
        Gnmi.PathElem.Builder previousElemBuilder = Gnmi.PathElem.newBuilder();

        while (iterator.hasNext()) {
            final Gnmi.PathElem.Builder currentElemBuilder = Gnmi.PathElem.newBuilder();
            final YangInstanceIdentifier.PathArgument arg = iterator.next();
            if (doesDefineKeys(arg)) {
                addKeysDefinitionNode((YangInstanceIdentifier.NodeIdentifierWithPredicates) arg,
                        previousElemBuilder);
                pathBuilder.addElem(previousElemBuilder.build());
            } else {
                addNonKeyDefinitionNode(arg, currentElemBuilder);
                if ((!iterator.hasNext() || !doesDefineKeys(iterator.peek()))) {
                    /* Add this PathElem only when current path arg is not augment identifier and
                       next arg does not define key and value pairs */
                    pathBuilder.addElem(currentElemBuilder.build());
                }
            }
            previousElemBuilder = currentElemBuilder;
        }

        // Add prefix to first path element, if requested
        if (pathBuilder.getElemCount() > 0 && prefixFirstElement) {
            final Gnmi.PathElem firstElement = pathBuilder.getElem(0);
            final QName nodeType = path.getPathArguments().get(0).getNodeType();

            final Optional firstElemModule = schemaContextProvider
                    .getSchemaContext().findModule(nodeType.getNamespace(), nodeType.getRevision());
            firstElemModule.ifPresent(module -> pathBuilder.setElem(0, firstElement.toBuilder()
                    .setName(String.format("%s:%s", module.getName(), firstElement.getName()))));
        }
        final Gnmi.Path resultingPath = pathBuilder.build();
        LOG.debug("Resulting gNMI Path of identifier {} is {}", path, resultingPath);
        return resultingPath;
    }

    private static void addNonKeyDefinitionNode(final YangInstanceIdentifier.PathArgument identifier,
                                                final Gnmi.PathElem.Builder builder) {
        if (identifier instanceof YangInstanceIdentifier.NodeIdentifier) {
            // In case of container or leaf
            builder.setName(identifier.getNodeType().getLocalName());
        } else if (identifier instanceof YangInstanceIdentifier.NodeWithValue) {
            // In case of leaf-list entry
            final YangInstanceIdentifier.NodeWithValue valueNode = (YangInstanceIdentifier.NodeWithValue) identifier;
            builder.setName(valueNode.getValue().toString());
        }
    }

    private static void addKeysDefinitionNode(final YangInstanceIdentifier.NodeIdentifierWithPredicates identifier,
                                              final Gnmi.PathElem.Builder builder) {
        for (Map.Entry entry : identifier.entrySet()) {
            builder.putKey(entry.getKey().getLocalName(), entry.getValue().toString());
        }

    }

    private static boolean doesDefineKeys(final YangInstanceIdentifier.PathArgument pathArgument) {
        return pathArgument instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy