summaryrefslogtreecommitdiffstats
path: root/infra/test-utils/test-tools/src/main/java/io/fd/honeycomb/test/tools/YangDataProcessor.java
blob: 7c6e3753c3ece92f3526c9493580313983ccd4c6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * Copyright (c) 2017 Cisco and/or its affiliates.
 *
 * 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.
 */

package io.fd.honeycomb.test.tools;

import java.util.AbstractMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opendaylight.mdsal.binding.dom.adapter.BindingToNormalizedNodeCodec;
import org.opendaylight.mdsal.binding.generator.impl.BindingSchemaContextUtils;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.slf4j.Logger;

interface YangDataProcessor {

    /**
     * Attempts to find data in file specified by <b>resourcePath</b>,<br>
     * and translate it to BA object
     *
     * @param yangInstanceIdentifier identifier of path to read
     * @param resourcePath           path of resource file to load
     */
    @Nonnull
    DataObject getNodeData(@Nonnull final YangInstanceIdentifier yangInstanceIdentifier,
                           @Nonnull final String resourcePath);

    /**
     * Verifies if provided identifier is identifying node processed by this processor
     *
     * @param identifier node identifier
     */
    boolean canProcess(@Nonnull final YangInstanceIdentifier identifier);

    default boolean isRoot(@Nonnull final YangInstanceIdentifier identifier) {
        return identifier.getPathArguments().isEmpty();
    }

    @Nonnull
    default Optional<YangInstanceIdentifier> getNodeParent(@Nonnull final YangInstanceIdentifier identifier) {
        return Optional.ofNullable(identifier.getParent());
    }

    @Nonnull
    default SchemaNode parentSchema(@Nonnull final SchemaContext schemaContext,
                                    @Nonnull final BindingToNormalizedNodeCodec serializer,
                                    @Nullable final YangInstanceIdentifier parentYangId,
                                    @Nonnull final Logger logger) {
        // null or root
        if (parentYangId == null || parentYangId.getPathArguments().size() == 0) {
            // no parent == use schema context as root context
            logger.info("Parent is null, providing schema context as parent node");
            return schemaContext;
        }

        final Optional<InstanceIdentifier<? extends DataObject>> parentInstanceId;
        try {
            parentInstanceId = serializer.toBinding(parentYangId);
        } catch (DeserializationException e) {
            throw new IllegalArgumentException(String.format("Unable to deserialize %s", parentYangId), e);
        }

        if (!parentInstanceId.isPresent()) {
            throw new IllegalStateException(String.format("Unable to resolve %s to instance identifier", parentYangId));
        }

        final Optional<DataNodeContainer> dataNodeContainerOptional =
                BindingSchemaContextUtils.findDataNodeContainer(schemaContext, parentInstanceId.get());


        if (!dataNodeContainerOptional.isPresent()) {
            throw new IllegalArgumentException(
                    String.format("Error finding DataNodeContainer for %s", parentInstanceId.get()));
        }

        final DataNodeContainer parentNode = dataNodeContainerOptional.get();
        logger.info("Parent schema node resolved as {}", parentNode);
        return (SchemaNode) parentNode;
    }

    @Nonnull
    default Map.Entry<InstanceIdentifier<? extends DataObject>, DataObject> nodeBinding(
            @Nonnull final BindingToNormalizedNodeCodec serializer,
            @Nonnull final YangInstanceIdentifier identifier,
            @Nonnull final NormalizedNode<?, ?> data) throws IllegalArgumentException {
        try {
            return serializer.toBinding(new AbstractMap.SimpleImmutableEntry<>(identifier, data))
                    .orElseThrow(new Supplier<RuntimeException>() {
                        @Override
                        public RuntimeException get() {
                            throw new IllegalArgumentException(
                                    String.format("Unable to create node binding  for %s|%s", identifier, data));
                        }
                    });
        } catch (DeserializationException e) {
            throw new IllegalArgumentException(String.format("Unable to deserialize node %s|%s", identifier, data), e);
        }
    }

    @Nonnull
    default InstanceIdentifier<? extends DataObject> identifierBinding(
            @Nonnull final BindingToNormalizedNodeCodec serializer,
            @Nonnull final YangInstanceIdentifier identifier) throws IllegalArgumentException{
        try {
            return serializer.toBinding(identifier)
                    .orElseThrow(new Supplier<RuntimeException>() {
                        @Override
                        public RuntimeException get() {
                            throw new IllegalArgumentException(
                                    String.format("Unable convert %s to binding", identifier));
                        }
                    });
        } catch (DeserializationException e) {
            throw new IllegalArgumentException(String.format("Unable to deserialize %s", identifier), e);
        }
    }
}