2 * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved.
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
8 package org.opendaylight.netconf.test.tool;
10 import com.google.common.collect.ImmutableList;
11 import com.google.gson.stream.JsonWriter;
12 import java.io.IOException;
13 import java.io.StringWriter;
14 import java.util.List;
15 import org.opendaylight.mdsal.binding.runtime.spi.BindingRuntimeHelpers;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.$YangModuleInfoImpl;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeFields;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials;
19 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
20 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
21 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
22 import org.opendaylight.yangtools.yang.common.QName;
23 import org.opendaylight.yangtools.yang.common.Uint16;
24 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
25 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
26 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
27 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
28 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
29 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
30 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
31 import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactory;
32 import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier;
33 import org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter;
34 import org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory;
35 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
36 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
37 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
41 final class PayloadCreator {
42 private static final Logger LOG = LoggerFactory.getLogger(PayloadCreator.class);
44 private static final EffectiveModelContext NETWORK_TOPOLOGY_SCHEMA_CONTEXT = BindingRuntimeHelpers
45 .createEffectiveModel(ImmutableList.of($YangModuleInfoImpl.getInstance()));
46 private static final JSONCodecFactory NETWORK_TOPOLOGY_JSON_CODEC_FACTORY = JSONCodecFactorySupplier
47 .DRAFT_LHOTKA_NETMOD_YANG_JSON_02.getShared(NETWORK_TOPOLOGY_SCHEMA_CONTEXT);
49 private static final QName TOPOLOGY_ID_QNAME = QName.create(Topology.QNAME, "topology-id").intern();
50 private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "node-id").intern();
52 private static final NodeIdentifier PORT_NODE_IDENTIFIER = NodeIdentifier
53 .create(QName.create(NetconfNodeFields.QNAME, "port"));
54 private static final NodeIdentifier HOST_NODE_IDENTIFIER = NodeIdentifier
55 .create(QName.create(NetconfNodeFields.QNAME,"host"));
56 private static final NodeIdentifier USERNAME_NODE_IDENTIFIER = NodeIdentifier
57 .create(QName.create(NetconfNodeFields.QNAME,"username"));
58 private static final NodeIdentifier PASSWORD_NODE_IDENTIFIER = NodeIdentifier
59 .create(QName.create(NetconfNodeFields.QNAME, "password"));
60 private static final NodeIdentifier CREDENTIALS_NODE_IDENTIFIER = NodeIdentifier.create(Credentials.QNAME);
61 private static final NodeIdentifier TCP_ONLY_NODE_IDENTIFIER = NodeIdentifier
62 .create(QName.create(NetconfNodeFields.QNAME, "tcp-only"));
63 private static final NodeIdentifier KEEPALIVE_DELAY_NODE_IDENTIFIER = NodeIdentifier
64 .create(QName.create(NetconfNodeFields.QNAME, "keepalive-delay"));
65 private static final NodeIdentifier SCHEMALESS_NODE_IDENTIFIER = NodeIdentifier
66 .create(QName.create(NetconfNodeFields.QNAME, "schemaless"));
67 private static final String DEFAULT_TOPOLOGY_ID = "topology-netconf";
68 private static final String DEFAULT_NODE_PASSWORD = "admin";
69 private static final String DEFAULT_NODE_USERNAME = "admin";
71 private static final boolean DEFAULT_NODE_SCHEMALESS = false;
72 private static final int DEFAULT_NODE_KEEPALIVE_DELAY = 0;
73 private static final int DEFAULT_REQUEST_PAYLOAD_INDENTATION = 2;
75 private PayloadCreator() {
79 static String createStringPayload(final List<Integer> devices, final TesttoolParameters parameters) {
80 return normalizedNodeToString(createNormalizedNodePayload(devices, parameters));
83 private static String normalizedNodeToString(final NormalizedNode node) {
84 final StringWriter writer = new StringWriter();
85 final JsonWriter jsonWriter = JsonWriterFactory.createJsonWriter(writer, DEFAULT_REQUEST_PAYLOAD_INDENTATION);
86 final NormalizedNodeStreamWriter jsonStream = JSONNormalizedNodeStreamWriter.createExclusiveWriter(
87 NETWORK_TOPOLOGY_JSON_CODEC_FACTORY, SchemaPath.create(true, NetworkTopology.QNAME),
89 try (NormalizedNodeWriter nodeWriter = NormalizedNodeWriter.forStreamWriter(jsonStream)) {
90 nodeWriter.write(node);
91 } catch (final IOException e) {
92 LOG.error("Failed to serialize node: {} to JSON", node, e);
93 throw new IllegalStateException("Failed to serialize node to JSON", e);
95 return writer.toString();
98 private static NormalizedNode createNormalizedNodePayload(final List<Integer> devices,
99 final TesttoolParameters parameters) {
100 final var nodeBuilder = Builders.mapBuilder().withNodeIdentifier(NodeIdentifier.create(Node.QNAME));
101 for (final Integer device : devices) {
102 nodeBuilder.withChild(Builders.mapEntryBuilder()
103 .withNodeIdentifier(NodeIdentifierWithPredicates.of(Node.QNAME, NODE_ID_QNAME,
104 createNodeID(device)))
105 .withChild(leafPort(device))
106 .withChild(leafHost(parameters.generateConfigsAddress))
107 .withChild(containerCredentials(DEFAULT_NODE_USERNAME, DEFAULT_NODE_PASSWORD))
108 .withChild(leafTcpOnly(!parameters.ssh))
109 .withChild(leafKeepaliveDelay(DEFAULT_NODE_KEEPALIVE_DELAY))
110 .withChild(leafSchemaless(DEFAULT_NODE_SCHEMALESS))
114 return Builders.mapBuilder()
115 .withNodeIdentifier(NodeIdentifier.create(Topology.QNAME))
116 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(NodeIdentifierWithPredicates
117 .of(Topology.QNAME, TOPOLOGY_ID_QNAME, DEFAULT_TOPOLOGY_ID))
118 .withChild(nodeBuilder.build())
123 private static String createNodeID(final Integer port) {
124 return String.format("%d-sim-device", port);
127 private static LeafNode<Uint16> leafPort(final int port) {
128 return Builders.<Uint16>leafBuilder()
129 .withNodeIdentifier(PORT_NODE_IDENTIFIER)
130 .withValue(Uint16.valueOf(port))
134 private static LeafNode<String> leafHost(final String host) {
135 return Builders.<String>leafBuilder()
136 .withNodeIdentifier(HOST_NODE_IDENTIFIER)
141 private static ChoiceNode containerCredentials(final String username, final String password) {
142 return Builders.choiceBuilder().withNodeIdentifier(CREDENTIALS_NODE_IDENTIFIER)
143 .withChild(Builders.<String>leafBuilder()
144 .withNodeIdentifier(USERNAME_NODE_IDENTIFIER)
147 .withChild(Builders.<String>leafBuilder()
148 .withNodeIdentifier(PASSWORD_NODE_IDENTIFIER)
154 private static LeafNode<Boolean> leafTcpOnly(final Boolean tcpOnly) {
155 return Builders.<Boolean>leafBuilder()
156 .withNodeIdentifier(TCP_ONLY_NODE_IDENTIFIER)
161 private static LeafNode<Integer> leafKeepaliveDelay(final Integer keepaliveDelay) {
162 return Builders.<Integer>leafBuilder()
163 .withNodeIdentifier(KEEPALIVE_DELAY_NODE_IDENTIFIER)
164 .withValue(keepaliveDelay)
168 private static LeafNode<Boolean> leafSchemaless(final Boolean schemaless) {
169 return Builders.<Boolean>leafBuilder()
170 .withNodeIdentifier(SCHEMALESS_NODE_IDENTIFIER)
171 .withValue(schemaless)