9bca8bba77cd784e54775b11239c479f024f2549
[netconf.git] / netconf / tools / netconf-testtool / src / main / java / org / opendaylight / netconf / test / tool / PayloadCreator.java
1 /*
2  * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.netconf.test.tool;
9
10 import static org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
11 import static org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
12
13 import com.google.common.collect.ImmutableList;
14 import com.google.gson.stream.JsonWriter;
15 import java.io.IOException;
16 import java.io.StringWriter;
17 import java.util.List;
18 import org.opendaylight.mdsal.binding.runtime.spi.BindingRuntimeHelpers;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.$YangModuleInfoImpl;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeFields;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials;
22 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
23 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
24 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
25 import org.opendaylight.yangtools.yang.common.QName;
26 import org.opendaylight.yangtools.yang.common.Uint16;
27 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
28 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
29 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
30 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
31 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
32 import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactory;
33 import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier;
34 import org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter;
35 import org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory;
36 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
37 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
38 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 final class PayloadCreator {
43     private static final Logger LOG = LoggerFactory.getLogger(PayloadCreator.class);
44
45     private static final EffectiveModelContext NETWORK_TOPOLOGY_SCHEMA_CONTEXT = BindingRuntimeHelpers
46             .createEffectiveModel(ImmutableList.of($YangModuleInfoImpl.getInstance()));
47     private static final JSONCodecFactory NETWORK_TOPOLOGY_JSON_CODEC_FACTORY = JSONCodecFactorySupplier
48             .DRAFT_LHOTKA_NETMOD_YANG_JSON_02.getShared(NETWORK_TOPOLOGY_SCHEMA_CONTEXT);
49
50     private static final QName TOPOLOGY_ID_QNAME = QName.create(Topology.QNAME, "topology-id").intern();
51     private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "node-id").intern();
52
53     private static final NodeIdentifier PORT_NODE_IDENTIFIER = NodeIdentifier
54             .create(QName.create(NetconfNodeFields.QNAME, "port"));
55     private static final NodeIdentifier HOST_NODE_IDENTIFIER = NodeIdentifier
56             .create(QName.create(NetconfNodeFields.QNAME,"host"));
57     private static final NodeIdentifier USERNAME_NODE_IDENTIFIER = NodeIdentifier
58             .create(QName.create(NetconfNodeFields.QNAME,"username"));
59     private static final NodeIdentifier PASSWORD_NODE_IDENTIFIER = NodeIdentifier
60             .create(QName.create(NetconfNodeFields.QNAME, "password"));
61     private static final NodeIdentifier CREDENTIALS_NODE_IDENTIFIER = NodeIdentifier.create(Credentials.QNAME);
62     private static final NodeIdentifier TCP_ONLY_NODE_IDENTIFIER = NodeIdentifier
63             .create(QName.create(NetconfNodeFields.QNAME, "tcp-only"));
64     private static final NodeIdentifier KEEPALIVE_DELAY_NODE_IDENTIFIER = NodeIdentifier
65             .create(QName.create(NetconfNodeFields.QNAME, "keepalive-delay"));
66     private static final NodeIdentifier SCHEMALESS_NODE_IDENTIFIER = NodeIdentifier
67             .create(QName.create(NetconfNodeFields.QNAME, "schemaless"));
68     private static final String DEFAULT_TOPOLOGY_ID = "topology-netconf";
69     private static final String DEFAULT_NODE_PASSWORD = "admin";
70     private static final String DEFAULT_NODE_USERNAME = "admin";
71
72     private static final boolean DEFAULT_NODE_SCHEMALESS = false;
73     private static final int DEFAULT_NODE_KEEPALIVE_DELAY = 0;
74     private static final int DEFAULT_REQUEST_PAYLOAD_INDENTATION = 2;
75
76     private PayloadCreator() {
77         // hidden on purpose
78     }
79
80     static String createStringPayload(final List<Integer> devices, final TesttoolParameters parameters) {
81         return normalizedNodeToString(createNormalizedNodePayload(devices, parameters));
82     }
83
84     private static String normalizedNodeToString(final NormalizedNode node) {
85         final StringWriter writer = new StringWriter();
86         final JsonWriter jsonWriter = JsonWriterFactory.createJsonWriter(writer, DEFAULT_REQUEST_PAYLOAD_INDENTATION);
87         final NormalizedNodeStreamWriter jsonStream = JSONNormalizedNodeStreamWriter.createExclusiveWriter(
88                 NETWORK_TOPOLOGY_JSON_CODEC_FACTORY, SchemaPath.create(true, NetworkTopology.QNAME),
89                 null, jsonWriter);
90         try (NormalizedNodeWriter nodeWriter = NormalizedNodeWriter.forStreamWriter(jsonStream)) {
91             nodeWriter.write(node);
92         } catch (final IOException e) {
93             LOG.error("Failed to serialize node: {} to JSON", node, e);
94             throw new RuntimeException("Failed to serialize node to JSON", e);
95         }
96         return writer.toString();
97     }
98
99     private static NormalizedNode createNormalizedNodePayload(final List<Integer> devices,
100             final TesttoolParameters parameters) {
101         final var nodeBuilder = Builders.mapBuilder().withNodeIdentifier(NodeIdentifier.create(Node.QNAME));
102         for (final Integer device : devices) {
103             nodeBuilder.withChild(Builders.mapEntryBuilder()
104                     .withNodeIdentifier(NodeIdentifierWithPredicates.of(Node.QNAME, NODE_ID_QNAME,
105                             createNodeID(device)))
106                     .withChild(leafPort(device))
107                     .withChild(leafHost(parameters.generateConfigsAddress))
108                     .withChild(containerCredentials(DEFAULT_NODE_USERNAME, DEFAULT_NODE_PASSWORD))
109                     .withChild(leafTcpOnly(!parameters.ssh))
110                     .withChild(leafKeepaliveDelay(DEFAULT_NODE_KEEPALIVE_DELAY))
111                     .withChild(leafSchemaless(DEFAULT_NODE_SCHEMALESS))
112                     .build());
113         }
114
115         return Builders.mapBuilder()
116                 .withNodeIdentifier(NodeIdentifier.create(Topology.QNAME))
117                 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(NodeIdentifierWithPredicates
118                         .of(Topology.QNAME, TOPOLOGY_ID_QNAME, DEFAULT_TOPOLOGY_ID))
119                         .withChild(nodeBuilder.build())
120                         .build())
121                 .build();
122     }
123
124     private static String createNodeID(final Integer port) {
125         return String.format("%d-sim-device", port);
126     }
127
128     private static LeafNode<Uint16> leafPort(final int port) {
129         return Builders.<Uint16>leafBuilder()
130                 .withNodeIdentifier(PORT_NODE_IDENTIFIER)
131                 .withValue(Uint16.valueOf(port))
132                 .build();
133     }
134
135     private static LeafNode<String> leafHost(final String host) {
136         return Builders.<String>leafBuilder()
137                 .withNodeIdentifier(HOST_NODE_IDENTIFIER)
138                 .withValue(host)
139                 .build();
140     }
141
142     private static ChoiceNode containerCredentials(final String username, final String password) {
143         return Builders.choiceBuilder().withNodeIdentifier(CREDENTIALS_NODE_IDENTIFIER)
144                 .withChild(Builders.<String>leafBuilder()
145                         .withNodeIdentifier(USERNAME_NODE_IDENTIFIER)
146                         .withValue(username)
147                         .build())
148                 .withChild(Builders.<String>leafBuilder()
149                         .withNodeIdentifier(PASSWORD_NODE_IDENTIFIER)
150                         .withValue(password)
151                         .build())
152                 .build();
153     }
154
155     private static LeafNode<Boolean> leafTcpOnly(final Boolean tcpOnly) {
156         return Builders.<Boolean>leafBuilder()
157                 .withNodeIdentifier(TCP_ONLY_NODE_IDENTIFIER)
158                 .withValue(tcpOnly)
159                 .build();
160     }
161
162     private static LeafNode<Integer> leafKeepaliveDelay(final Integer keepaliveDelay) {
163         return Builders.<Integer>leafBuilder()
164                 .withNodeIdentifier(KEEPALIVE_DELAY_NODE_IDENTIFIER)
165                 .withValue(keepaliveDelay)
166                 .build();
167     }
168
169     private static LeafNode<Boolean> leafSchemaless(final Boolean schemaless) {
170         return Builders.<Boolean>leafBuilder()
171                 .withNodeIdentifier(SCHEMALESS_NODE_IDENTIFIER)
172                 .withValue(schemaless)
173                 .build();
174     }
175 }