Andrea Campanella
Committed by Gerrit Code Review

[Goldeneye] ONOS-3939 Implementing Yang Sb XML utils

Change-Id: Ibf435f4c8e967ab793ec4a6d882df82b790f554f
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.drivers.utilities;
18 +
19 +import com.google.common.base.MoreObjects;
20 +
21 +import java.util.Map;
22 +import java.util.Objects;
23 +
24 +/**
25 + * Class that contains the element base key and a map with all the values to
26 + * set or retrieved with their relative key.
27 + */
28 +public class YangElement {
29 +
30 + private final String baseKey;
31 + private final Map<String, String> keysAndValues;
32 +
33 + public YangElement(String baseKey, Map<String, String> keysAndValues) {
34 + this.baseKey = baseKey;
35 + this.keysAndValues = keysAndValues;
36 + }
37 +
38 + public Map<String, String> getKeysAndValues() {
39 + return keysAndValues;
40 + }
41 +
42 + public String getBaseKey() {
43 + return baseKey;
44 + }
45 +
46 +
47 + @Override
48 + public String toString() {
49 + return MoreObjects.toStringHelper(this)
50 + .add("baseKey", baseKey)
51 + .add("keysAndValues", keysAndValues)
52 + .toString();
53 + }
54 +
55 + @Override
56 + public boolean equals(Object o) {
57 + if (this == o) {
58 + return true;
59 + }
60 + if (o == null || getClass() != o.getClass()) {
61 + return false;
62 + }
63 +
64 + YangElement element = (YangElement) o;
65 +
66 + if (baseKey != null ? !baseKey.equals(element.baseKey) : element.baseKey != null) {
67 + return false;
68 + }
69 + return (keysAndValues == null ? element.keysAndValues == null :
70 + keysAndValues.equals(element.keysAndValues));
71 +
72 + }
73 +
74 + @Override
75 + public int hashCode() {
76 + return Objects.hash(baseKey, keysAndValues);
77 + }
78 +}
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.drivers.utilities;
18 +
19 +import com.google.common.collect.ArrayListMultimap;
20 +import com.google.common.collect.ImmutableList;
21 +import com.google.common.collect.Multimap;
22 +import org.apache.commons.configuration.ConfigurationException;
23 +import org.apache.commons.configuration.HierarchicalConfiguration;
24 +import org.apache.commons.configuration.XMLConfiguration;
25 +import org.apache.commons.configuration.tree.ConfigurationNode;
26 +import org.slf4j.Logger;
27 +import org.slf4j.LoggerFactory;
28 +
29 +import java.io.InputStream;
30 +import java.io.StringWriter;
31 +import java.util.ArrayList;
32 +import java.util.Collections;
33 +import java.util.Comparator;
34 +import java.util.HashMap;
35 +import java.util.Iterator;
36 +import java.util.List;
37 +import java.util.Map;
38 +
39 +import static org.onlab.util.Tools.nullIsNotFound;
40 +
41 +/**
42 + * Util CLass for Yang models.
43 + * Clean abstraction to read, obtain and populate
44 + * XML from Yang models translated into XML skeletons.
45 + */
46 +public class YangXmlUtils {
47 +
48 + public final Logger log = LoggerFactory
49 + .getLogger(getClass());
50 +
51 + private static YangXmlUtils instance = null;
52 +
53 + //no instantiation, single instance.
54 + protected YangXmlUtils() {
55 +
56 + }
57 +
58 + /**
59 + * Retrieves a valid XML configuration for a specific XML path for a single
60 + * instance of the Map specified key-value pairs.
61 + *
62 + * @param file path of the file to be used.
63 + * @param values map of key and values to set under the generic path.
64 + * @return Hierarchical configuration containing XML with values.
65 + */
66 + public XMLConfiguration getXmlConfiguration(String file, Map<String, String> values) {
67 + InputStream stream = getCfgInputStream(file);
68 + XMLConfiguration cfg = loadXml(stream);
69 + XMLConfiguration complete = new XMLConfiguration();
70 + List<String> paths = new ArrayList<>();
71 + Map<String, String> valuesWithKey = new HashMap<>();
72 + values.keySet().stream().forEach(path -> {
73 + List<String> allPaths = findPaths(cfg, path);
74 + String key = nullIsNotFound(allPaths.isEmpty() ? null : allPaths.get(0),
75 + "Yang model does not contain desired path");
76 + paths.add(key);
77 + valuesWithKey.put(key, values.get(path));
78 + });
79 + Collections.sort(paths, new StringLengthComparator());
80 + paths.forEach(key -> complete.setProperty(key, valuesWithKey.get(key)));
81 + addProperties(cfg, complete);
82 + return complete;
83 + }
84 +
85 +
86 + /**
87 + * Retrieves a valid XML configuration for a specific XML path for multiple
88 + * instance of YangElements objects.
89 + *
90 + * @param file path of the file to be used.
91 + * @param elements List of YangElements that are to be set.
92 + * @return Hierachical configuration containing XML with values.
93 + */
94 + public XMLConfiguration getXmlConfiguration(String file, List<YangElement> elements) {
95 + InputStream stream = getCfgInputStream(file);
96 + HierarchicalConfiguration cfg = loadXml(stream);
97 + XMLConfiguration complete = new XMLConfiguration();
98 + Multimap<String, YangElement> commonElements = ArrayListMultimap.create();
99 +
100 + //saves the elements in a Multimap based on the computed key.
101 + elements.forEach(element -> {
102 + String completeKey = nullIsNotFound(findPath(cfg, element.getBaseKey()),
103 + "Yang model does not contain desired path");
104 + commonElements.put(completeKey, element);
105 + });
106 +
107 + //iterates over the elements and constructs the configuration
108 + commonElements.keySet().forEach(key -> {
109 + // if there is more than one element for a given path
110 + if (commonElements.get(key).size() > 1) {
111 + //creates a list of nodes that have to be added for that specific path
112 + ArrayList<ConfigurationNode> nodes = new ArrayList<>();
113 + //creates the nodes
114 + commonElements.get(key).forEach(element -> nodes.add(getInnerNode(element).getRootNode()));
115 + //computes the parent path
116 + String parentPath = key.substring(0, key.lastIndexOf("."));
117 + //adds the nodes to the complete configuration
118 + complete.addNodes(parentPath, nodes);
119 + } else {
120 + //since there is only a single element we can assume it's the first one.
121 + Map<String, String> keysAndValues = commonElements.get(key).stream().
122 + findFirst().get().getKeysAndValues();
123 + keysAndValues.forEach((k, v) -> complete.setProperty(key + "." + k, v));
124 + }
125 + });
126 + addProperties(cfg, complete);
127 + return complete;
128 + }
129 +
130 + //Adds all the properties of the original configuration to the new one.
131 + private void addProperties(HierarchicalConfiguration cfg, HierarchicalConfiguration complete) {
132 + cfg.getKeys().forEachRemaining(key -> {
133 + String property = (String) cfg.getProperty(key);
134 + if (!property.equals("")) {
135 + complete.setProperty(key, property);
136 + }
137 + });
138 + }
139 +
140 + protected InputStream getCfgInputStream(String file) {
141 + return getClass().getResourceAsStream(file);
142 + }
143 +
144 + /**
145 + * Reads a valid XML configuration and returns a Map containing XML field name.
146 + * and value contained for every subpath.
147 + *
148 + * @param cfg the Configuration to read.
149 + * @param path path of the information to be read.
150 + * @return list of elements containing baskey and map of key value pairs.
151 + */
152 + public List<YangElement> readXmlConfiguration(HierarchicalConfiguration cfg, String path) {
153 + List<YangElement> elements = new ArrayList<>();
154 +
155 + String key = nullIsNotFound(findPath(cfg, path), "Configuration does not contain desired path");
156 +
157 + getElements(cfg.configurationsAt(key), elements, key, cfg, path, key);
158 + return ImmutableList.copyOf(elements);
159 + }
160 +
161 + private void getElements(List<HierarchicalConfiguration> configurations,
162 + List<YangElement> elements, String basekey,
163 + HierarchicalConfiguration originalCfg, String path,
164 + String originalKey) {
165 + //consider each sub configuration
166 + configurations.stream().forEach(config -> {
167 +
168 + YangElement element = new YangElement(path, new HashMap<>());
169 + //for each of the keys of the sub configuration
170 + config.getKeys().forEachRemaining(key -> {
171 + //considers only one step ahead
172 + //if one step ahead has other steps calls self to analize them
173 + //else adds to yang element.
174 + if (key.split("\\.").length > 1) {
175 + getElements(originalCfg.configurationsAt(basekey + "." + key.split("\\.")[0]),
176 + elements, basekey + "." + key.split("\\.")[0], originalCfg, path,
177 + originalKey);
178 + } else {
179 + String replaced = basekey.replace(originalKey, "");
180 + String partialKey = replaced.isEmpty() ? key : replaced.substring(1) + "." + key;
181 + partialKey = partialKey.isEmpty() ? originalKey : partialKey;
182 + //Adds values to the element with a subkey starting from the requeste path onwards
183 + element.getKeysAndValues().put(partialKey, config.getProperty(key).toString());
184 + }
185 + });
186 + //if the element doesnt already exist
187 + if (!elements.contains(element) && !element.getKeysAndValues().isEmpty()) {
188 + elements.add(element);
189 + }
190 + });
191 + }
192 +
193 + /**
194 + * Single Instance of Yang utilities retriever.
195 + *
196 + * @return instance of YangXmlUtils
197 + */
198 + public static YangXmlUtils getInstance() {
199 + if (instance == null) {
200 + instance = new YangXmlUtils();
201 + }
202 + return instance;
203 + }
204 +
205 + /**
206 + * Return the string representation of the XMLConfig without header
207 + * and configuration element.
208 + *
209 + * @param cfg the XML to convert
210 + * @return the cfg string.
211 + */
212 + public String getString(XMLConfiguration cfg) {
213 + StringWriter stringWriter = new StringWriter();
214 + try {
215 + cfg.save(stringWriter);
216 + } catch (ConfigurationException e) {
217 + log.error("Cannot convert configuration", e.getMessage());
218 + }
219 + String xml = stringWriter.toString();
220 + xml = xml.substring(xml.indexOf("\n"));
221 + xml = xml.substring(xml.indexOf(">") + 1);
222 + return xml;
223 + }
224 +
225 + /**
226 + * Method to read an input stream into a XMLConfiguration.
227 + * @param xmlStream inputstream containing XML description
228 + * @return the XMLConfiguration object
229 + */
230 + public XMLConfiguration loadXml(InputStream xmlStream) {
231 + XMLConfiguration cfg = new XMLConfiguration();
232 + try {
233 + cfg.load(xmlStream);
234 + return cfg;
235 + } catch (ConfigurationException e) {
236 + throw new IllegalArgumentException("Cannot load xml from Stream", e);
237 + }
238 + }
239 +
240 + //Finds all paths for a corresponding element
241 + private List<String> findPaths(HierarchicalConfiguration cfg, String path) {
242 + List<String> paths = new ArrayList<>();
243 + cfg.getKeys().forEachRemaining(key -> {
244 + if (key.equals(path)) {
245 + paths.add(key);
246 + }
247 + if (key.contains("." + path)) {
248 + paths.add(key);
249 + }
250 + });
251 + return paths;
252 + }
253 +
254 + //Finds the first parent path corresponding to an element.
255 + private String findPath(HierarchicalConfiguration cfg, String element) {
256 + Iterator<String> it = cfg.getKeys();
257 + while (it.hasNext()) {
258 + String key = it.next();
259 + String[] arr = key.split("\\.");
260 + for (int i = 0; i < arr.length; i++) {
261 + if (element.equals(arr[i])) {
262 + String completeKey = "";
263 + for (int j = 0; j <= i; j++) {
264 + completeKey = completeKey + "." + arr[j];
265 + }
266 + return completeKey.substring(1);
267 + }
268 + }
269 + }
270 + return null;
271 + }
272 +
273 + //creates a node based on a single Yang element.
274 + private HierarchicalConfiguration getInnerNode(YangElement element) {
275 + HierarchicalConfiguration node = new HierarchicalConfiguration();
276 + node.setRoot(new HierarchicalConfiguration.Node(element.getBaseKey()));
277 + element.getKeysAndValues().forEach(node::setProperty);
278 + return node;
279 + }
280 +
281 + //String lenght comparator
282 + private class StringLengthComparator implements Comparator<String> {
283 +
284 + public int compare(String o1, String o2) {
285 + if (o2 == null && o1 == null) {
286 + return 0;
287 + }
288 +
289 + if (o1 == null) {
290 + return o2.length();
291 + }
292 +
293 + if (o2 == null) {
294 + return o1.length();
295 + }
296 +
297 + if (o1.length() != o2.length()) {
298 + return o1.length() - o2.length(); //overflow impossible since lengths are non-negative
299 + }
300 + return o1.compareTo(o2);
301 + }
302 + }
303 +
304 +}
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.drivers.utilities;
18 +
19 +import com.google.common.collect.ImmutableList;
20 +import com.google.common.collect.ImmutableMap;
21 +import org.apache.commons.collections.IteratorUtils;
22 +import org.apache.commons.configuration.ConfigurationException;
23 +import org.apache.commons.configuration.XMLConfiguration;
24 +import org.junit.Before;
25 +import org.junit.Test;
26 +import org.onlab.packet.IpAddress;
27 +import org.onosproject.net.behaviour.ControllerInfo;
28 +
29 +import java.io.InputStream;
30 +import java.util.ArrayList;
31 +import java.util.HashMap;
32 +import java.util.List;
33 +import java.util.Map;
34 +
35 +import static org.junit.Assert.*;
36 +
37 +/**
38 + * Tests for the XMLYangUtils.
39 + */
40 +public class YangXmlUtilsTest {
41 + public static final String OF_CONFIG_XML_PATH = "/of-config/of-config.xml";
42 + private YangXmlUtilsAdap utils;
43 + private XMLConfiguration testCreateConfig;
44 +
45 + @Before
46 + public void setUp() throws Exception {
47 + assertTrue("No resource for test", YangXmlUtilsTest.class.
48 + getResourceAsStream("/of-config/of-config.xml") != null);
49 + utils = new YangXmlUtilsAdap();
50 +
51 + testCreateConfig = new XMLConfiguration();
52 + }
53 +
54 + /**
55 + * Tests getting a single object configuration via passing the path and the map of the desired values.
56 + *
57 + * @throws ConfigurationException if the testing xml file is not there.
58 + */
59 + @Test
60 + public void testGetXmlUtilsInstance() throws ConfigurationException {
61 +
62 + YangXmlUtils instance1 = YangXmlUtils.getInstance();
63 + YangXmlUtils instance2 = YangXmlUtils.getInstance();
64 +
65 + assertEquals("Duplicate instance", instance1, instance2);
66 +
67 + }
68 +
69 + /**
70 + * Tests getting a single object configuration via passing the path and the map of the desired values.
71 + *
72 + * @throws ConfigurationException if the testing xml file is not there.
73 + */
74 + @Test
75 + public void testGetXmlConfigurationFromMap() throws ConfigurationException {
76 + Map<String, String> pathAndValues = new HashMap<>();
77 + pathAndValues.put("capable-switch.id", "openvswitch");
78 + pathAndValues.put("switch.id", "ofc-bridge");
79 + pathAndValues.put("controller.id", "tcp:1.1.1.1:1");
80 + pathAndValues.put("controller.ip-address", "1.1.1.1");
81 + XMLConfiguration cfg = utils.getXmlConfiguration(OF_CONFIG_XML_PATH, pathAndValues);
82 + testCreateConfig.load(getClass().getResourceAsStream("/testCreateSingleYangConfig.xml"));
83 + assertNotEquals("Null testConfiguration", new XMLConfiguration(), testCreateConfig);
84 +
85 + assertEquals("Wrong configuaration", IteratorUtils.toList(testCreateConfig.getKeys()),
86 + IteratorUtils.toList(cfg.getKeys()));
87 +
88 + assertEquals("Wrong string configuaration", utils.getString(testCreateConfig),
89 + utils.getString(cfg));
90 + }
91 +
92 + /**
93 + * Tests getting a multiple object nested configuration via passing the path
94 + * and a list of YangElements containing with the element and desired value.
95 + *
96 + * @throws ConfigurationException
97 + */
98 + @Test
99 + public void getXmlConfigurationFromYangElements() throws ConfigurationException {
100 +
101 + assertNotEquals("Null testConfiguration", new XMLConfiguration(), testCreateConfig);
102 + testCreateConfig.load(getClass().getResourceAsStream("/testYangConfig.xml"));
103 + List<YangElement> elements = new ArrayList<>();
104 + elements.add(new YangElement("capable-switch", ImmutableMap.of("id", "openvswitch")));
105 + elements.add(new YangElement("switch", ImmutableMap.of("id", "ofc-bridge")));
106 + List<ControllerInfo> controllers =
107 + ImmutableList.of(new ControllerInfo(IpAddress.valueOf("1.1.1.1"), 1, "tcp"),
108 + new ControllerInfo(IpAddress.valueOf("2.2.2.2"), 2, "tcp"));
109 + controllers.stream().forEach(cInfo -> {
110 + elements.add(new YangElement("controller", ImmutableMap.of("id", cInfo.target(),
111 + "ip-address", cInfo.ip().toString())));
112 + });
113 + XMLConfiguration cfg =
114 + new XMLConfiguration(YangXmlUtils.getInstance()
115 + .getXmlConfiguration(OF_CONFIG_XML_PATH, elements));
116 + assertEquals("Wrong configuaration", IteratorUtils.toList(testCreateConfig.getKeys()),
117 + IteratorUtils.toList(cfg.getKeys()));
118 + assertEquals("Wrong string configuaration", utils.getString(testCreateConfig),
119 + utils.getString(cfg));
120 + }
121 +
122 + /**
123 + * Test reading an XML configuration and retrieving the requested elements.
124 + *
125 + * @throws ConfigurationException
126 + */
127 + @Test
128 + public void testReadLastXmlConfiguration() throws ConfigurationException {
129 + testCreateConfig.load(getClass().getResourceAsStream("/testYangConfig.xml"));
130 + List<YangElement> elements = utils.readXmlConfiguration(testCreateConfig,
131 + "controller");
132 + List<YangElement> expected = ImmutableList.of(
133 + new YangElement("controller", ImmutableMap.of("id", "tcp:1.1.1.1:1",
134 + "ip-address", "1.1.1.1")),
135 + new YangElement("controller", ImmutableMap.of("id", "tcp:2.2.2.2:2",
136 + "ip-address", "2.2.2.2")));
137 + assertEquals("Wrong elements collected", expected, elements);
138 + }
139 +
140 + /**
141 + * Test reading an XML configuration and retrieving the requested elements.
142 + *
143 + * @throws ConfigurationException
144 + */
145 + @Test
146 + public void testReadNestedXmlConfiguration() throws ConfigurationException {
147 + testCreateConfig.load(getClass().getResourceAsStream("/testYangConfig.xml"));
148 + List<YangElement> elements = utils.readXmlConfiguration(testCreateConfig, "controllers");
149 + List<YangElement> expected = ImmutableList.of(
150 + new YangElement("controllers", ImmutableMap.of("controller.id", "tcp:1.1.1.1:1",
151 + "controller.ip-address", "1.1.1.1")),
152 + new YangElement("controllers", ImmutableMap.of("controller.id", "tcp:2.2.2.2:2",
153 + "controller.ip-address", "2.2.2.2")));
154 + assertEquals("Wrong elements collected", expected, elements);
155 + }
156 +
157 + //enables to change the path to the resources directory.
158 + private class YangXmlUtilsAdap extends YangXmlUtils {
159 +
160 + @Override
161 + protected InputStream getCfgInputStream(String file) {
162 + return YangXmlUtilsAdap.class.getResourceAsStream(file);
163 + }
164 + }
165 +}
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version='1.0' encoding='UTF-8'?>
2 +<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" />
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version='1.0' encoding='UTF-8'?>
2 +<!--
3 + ~ Copyright 2016 Open Networking Laboratory
4 + ~
5 + ~ Licensed under the Apache License, Version 2.0 (the "License");
6 + ~ you may not use this file except in compliance with the License.
7 + ~ You may obtain a copy of the License at
8 + ~
9 + ~ http://www.apache.org/licenses/LICENSE-2.0
10 + ~
11 + ~ Unless required by applicable law or agreed to in writing, software
12 + ~ distributed under the License is distributed on an "AS IS" BASIS,
13 + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 + ~ See the License for the specific language governing permissions and
15 + ~ limitations under the License.
16 + -->
17 +
18 +<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
19 + <capable-switch xmlns="urn:onf:config:yang">
20 + <id/>
21 + <config-version/>
22 + <resources>
23 + <port>
24 + <name/>
25 + <number/>
26 + <requested-number/>
27 + <current-rate/>
28 + <max-rate/>
29 + <configuration/>
30 + <state>
31 + <oper-state/>
32 + <blocked/>
33 + <live/>
34 + </state>
35 + <features>
36 + <current>
37 + <rate/>
38 + <auto-negotiate/>
39 + <medium/>
40 + <pause/>
41 + </current>
42 + <advertised>
43 + <rate/>
44 + <medium/>
45 + <pause/>
46 + </advertised>
47 + <supported>
48 + <rate/>
49 + <medium/>
50 + <pause/>
51 + </supported>
52 + <advertised-peer>
53 + <rate/>
54 + <medium/>
55 + <pause/>
56 + </advertised-peer>
57 + </features>
58 + <tunnel>
59 + <local-endpoint-ipv4-adress/>
60 + <remote-endpoint-ipv4-adress/>
61 + </tunnel>
62 + <ipgre-tunnel>
63 + <local-endpoint-ipv4-adress/>
64 + <remote-endpoint-ipv4-adress/>
65 + <key/>
66 + </ipgre-tunnel>
67 + <vxlan-tunnel>
68 + <local-endpoint-ipv4-adress/>
69 + <remote-endpoint-ipv4-adress/>
70 + <vni/>
71 + </vxlan-tunnel>
72 + </port>
73 + <queue>
74 + <resource-id/>
75 + <id/>
76 + <port/>
77 + <properties>
78 + <min-rate/>
79 + <max-rate/>
80 + <experimenter-id/>
81 + <experimenter-data/>
82 + </properties>
83 + </queue>
84 + <owned-certificate>
85 + <resource-id/>
86 + <certificate/>
87 + <private-key>
88 + <key-type/>
89 + <key-data/>
90 + </private-key>
91 + </owned-certificate>
92 + <external-certificate>
93 + <resource-id/>
94 + <certificate/>
95 + </external-certificate>
96 + <flow-table>
97 + <resource-id/>
98 + <table-id/>
99 + <name/>
100 + <max-entries/>
101 + </flow-table>
102 + </resources>
103 + <logical-switches>
104 + <switch>
105 + <id/>
106 + <capabilities>
107 + <max-buffered-packets/>
108 + <max-tables/>
109 + <max-ports/>
110 + <reserved-port-types>
111 + <type/>
112 + </reserved-port-types>
113 + <group-types>
114 + <type/>
115 + </group-types>
116 + <group-capabilities>
117 + <capability/>
118 + </group-capabilities>
119 + <action-types>
120 + <type/>
121 + </action-types>
122 + <instruction-types>
123 + <type/>
124 + </instruction-types>
125 + </capabilities>
126 + <datapath-id/>
127 + <controllers>
128 + <controller>
129 + <id/>
130 + <ip-address/>
131 + <local-ip-address/>
132 + <state>
133 + <connection-state/>
134 + <local-ip-address-in-use/>
135 + <local-port-in-use/>
136 + </state>
137 + </controller>
138 + </controllers>
139 + <resources>
140 + <port/>
141 + <queue/>
142 + <certificate/>
143 + <flow-table/>
144 + </resources>
145 + </switch>
146 + </logical-switches>
147 + </capable-switch>
148 +</data>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 +<configuration xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
3 +<capable-switch xmlns="urn:onf:config:yang">
4 +<id>openvswitch</id>
5 +<logical-switches>
6 +<switch>
7 +<id>ofc-bridge</id>
8 +<controllers>
9 +<controller>
10 +<id>tcp:1.1.1.1:1</id>
11 +<ip-address>1.1.1.1</ip-address>
12 +</controller>
13 +</controllers>
14 +</switch>
15 +</logical-switches>
16 +</capable-switch>
17 +</configuration>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 +<configuration xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
3 +<capable-switch xmlns="urn:onf:config:yang">
4 +<id>openvswitch</id>
5 +<logical-switches>
6 +<switch>
7 +<id>ofc-bridge</id>
8 +<controllers>
9 +<controller>
10 +<id>tcp:1.1.1.1:1</id>
11 +<ip-address>1.1.1.1</ip-address>
12 +</controller>
13 +<controller>
14 +<id>tcp:2.2.2.2:2</id>
15 +<ip-address>2.2.2.2</ip-address>
16 +</controller>
17 +</controllers>
18 +</switch>
19 +</logical-switches>
20 +</capable-switch>
21 +</configuration>
...\ No newline at end of file ...\ No newline at end of file
1 +#!/bin/bash
2 +# -----------------------------------------------------------------------------
3 +# ONOS YANG to XML skeleton convert via pyang
4 +# -----------------------------------------------------------------------------
5 +
6 +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
7 +. $ONOS_ROOT/tools/build/envDefaults
8 +
9 +aux=/tmp/pyangversion
10 +pyang -v $cmd > $aux
11 +errorstring="Pyang no installed, please download and intall from https://github.com/mbj4668/pyang"
12 +cat $aux
13 +grep -q "pyang: command not found" $aux && echo $errorString && exit 1
14 +
15 +grep -q "pyang 1" $aux
16 +
17 +if ! [ -e "$1" ]; then
18 + echo "$1 input directory not found" >&2
19 + exit 1
20 +fi
21 +if ! [ -d "$1" ]; then
22 + echo "$1 not a directory for output" >&2
23 + exit 1
24 +fi
25 +cd $1
26 +find . -name '*.yang' | while read file; do f=$(basename $file ".yang"); \
27 +directory=$ONOS_ROOT/drivers/utilities/src/main/resources/${PWD##*/}; \
28 +if [ ! -d "$directory" ]; then
29 + mkdir $directory; \
30 +fi
31 +echo $directory/$f.xml
32 +pyang -f sample-xml-skeleton $f.yang > $directory/$f.xml; done
33 +exit 0
...\ No newline at end of file ...\ No newline at end of file