blob: cd37eeaf5a373c55698cb67b51d3dbc9a850669d [file] [log] [blame]
sonu gupta1bb37b82016-11-11 16:51:18 +05301/*
2 * Copyright 2016-present 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
17package org.onosproject.yms.app.ydt;
18
19import com.google.common.collect.ImmutableMap;
sonu guptaeff184b2016-11-24 12:43:49 +053020import org.onosproject.yangutils.datamodel.YangAugment;
21import org.onosproject.yangutils.datamodel.YangLeaf;
sonu gupta1bb37b82016-11-11 16:51:18 +053022import org.onosproject.yangutils.datamodel.YangList;
23import org.onosproject.yangutils.datamodel.YangSchemaNode;
24import org.onosproject.yangutils.datamodel.YangSchemaNodeContextInfo;
25import org.onosproject.yangutils.datamodel.YangSchemaNodeIdentifier;
sonu guptaeff184b2016-11-24 12:43:49 +053026import org.onosproject.yms.app.ydt.exceptions.YdtException;
sonu gupta1bb37b82016-11-11 16:51:18 +053027import org.onosproject.yms.app.ysr.YangSchemaRegistry;
sonu gupta1bb37b82016-11-11 16:51:18 +053028import org.onosproject.yms.ydt.YdtContextOperationType;
29import org.onosproject.yms.ydt.YdtType;
30import org.onosproject.yms.ydt.YmsOperationType;
31
sonu guptaeff184b2016-11-24 12:43:49 +053032import java.util.HashSet;
sonu gupta1bb37b82016-11-11 16:51:18 +053033import java.util.Iterator;
34import java.util.List;
35import java.util.Map;
36import java.util.Set;
37
sonu gupta1bb37b82016-11-11 16:51:18 +053038import static org.onosproject.yms.app.ydt.AppNodeFactory.getAppContext;
39import static org.onosproject.yms.app.ydt.RequestedCallType.LEAF;
sonu guptaeff184b2016-11-24 12:43:49 +053040import static org.onosproject.yms.app.ydt.RequestedCallType.NON_LEAF;
sonu gupta1bb37b82016-11-11 16:51:18 +053041import static org.onosproject.yms.app.ydt.RequestedCardinality.MULTI_INSTANCE;
42import static org.onosproject.yms.app.ydt.RequestedCardinality.MULTI_INSTANCE_LEAF;
43import static org.onosproject.yms.app.ydt.RequestedCardinality.SINGLE_INSTANCE;
44import static org.onosproject.yms.app.ydt.RequestedCardinality.UNKNOWN;
45import static org.onosproject.yms.app.ydt.YdtConstants.errorMsg;
sonu guptaeff184b2016-11-24 12:43:49 +053046import static org.onosproject.yms.app.ydt.YdtNodeFactory.getNode;
47import static org.onosproject.yms.app.ydt.YdtNodeFactory.getYangSchemaNodeTypeSpecificContext;
48import static org.onosproject.yms.app.ydt.YdtUtils.checkElementCount;
49import static org.onosproject.yms.app.ydt.YdtUtils.freeRestResources;
50import static org.onosproject.yms.app.ydt.YdtUtils.getAppOpTypeFromYdtOpType;
51import static org.onosproject.yms.app.ydt.YdtUtils.getAugmentingSchemaNode;
52import static org.onosproject.yms.app.ydt.YdtUtils.getNodeIdentifier;
53import static org.onosproject.yms.app.ydt.YdtUtils.getValidOpType;
sonu gupta1bb37b82016-11-11 16:51:18 +053054import static org.onosproject.yms.ydt.YdtContextOperationType.DELETE;
sonu gupta1bb37b82016-11-11 16:51:18 +053055import static org.onosproject.yms.ydt.YdtContextOperationType.REMOVE;
56import static org.onosproject.yms.ydt.YdtType.MULTI_INSTANCE_LEAF_VALUE_NODE;
57import static org.onosproject.yms.ydt.YdtType.MULTI_INSTANCE_NODE;
58
59/**
60 * Represents YANG request work bench which contains all parameters for
61 * request handling and methods to build and obtain YANG data tree
62 * which is data (sub)instance representation, abstract of protocol.
63 */
64public class YangRequestWorkBench implements YdtExtendedBuilder {
65
sonu guptaeff184b2016-11-24 12:43:49 +053066 // Ydt formatted error string
sonu gupta1bb37b82016-11-11 16:51:18 +053067 private static final String FMT_NOT_EXIST =
68 "Application with name \"%s\" doesn't exist.";
sonu guptaeff184b2016-11-24 12:43:49 +053069
70 // Ydt error strings.
71 private static final String E_USE_ADD_LEAF =
72 "Requested Node should be created using addLeaf interface.";
73
sonu gupta1bb37b82016-11-11 16:51:18 +053074 private static final String E_INVOKE_PARENT =
sonu guptaeff184b2016-11-24 12:43:49 +053075 "Can't invoke get parent at logical root node.";
sonu gupta1bb37b82016-11-11 16:51:18 +053076
77 /*
sonu guptaeff184b2016-11-24 12:43:49 +053078 * Reference for the current context node in YANG data tree.
sonu gupta1bb37b82016-11-11 16:51:18 +053079 */
80 private YdtNode curNode;
81
82 /*
sonu guptaeff184b2016-11-24 12:43:49 +053083 * Reference for the logical root node in YANG data tree.
sonu gupta1bb37b82016-11-11 16:51:18 +053084 */
85 private YdtNode rootNode;
86
87 /*
sonu guptaeff184b2016-11-24 12:43:49 +053088 * Reference for the current context in ydt application tree.
sonu gupta1bb37b82016-11-11 16:51:18 +053089 */
90 private YdtAppContext appCurNode;
91
92 /*
sonu guptaeff184b2016-11-24 12:43:49 +053093 * Reference for the logical root node context in ydt application tree.
sonu gupta1bb37b82016-11-11 16:51:18 +053094 */
95 private YdtAppContext appRootNode;
96
97 /**
98 * Root Node Tag attribute in YANG data tree, kept to maintain the root
99 * tag attributes in YDT.
100 * <p>
101 * First key param of map represent tagName name of tag attribute.
102 * Second param of map represent tagValue value of tag attribute
103 */
104 private Map<String, String> rootTagAttributeMap;
105
106 /*
107 * YANG schema registry reference.
108 */
109 private YangSchemaRegistry registry = null;
110
111 /*
112 * YMS operation type.
113 */
114 private final YmsOperationType ymsOperationType;
115
116 /*
117 * YDT default operation type.
118 */
119 private YdtContextOperationType ydtDefaultOpType;
120
121 /*
122 * Flag to identify data validation need to be done by YDT or not.
123 */
Vidyashree Rama76faccc2016-10-17 22:06:52 +0530124 private boolean validate = false;
sonu gupta1bb37b82016-11-11 16:51:18 +0530125 // TODO validate need to be handle later with interaction type basis in
126 // future when it will be supported
127
sonu guptaeff184b2016-11-24 12:43:49 +0530128 /*
129 * Reference for application tree node set.
130 * This set contains the method name's generated for an augmented
131 * target node to avoid the duplicate entries in YDT application tree for
132 * multiple augmented nodes under a single XPATH.
133 */
134 private Set<String> augGenMethodSet;
sonu gupta1bb37b82016-11-11 16:51:18 +0530135
136 /**
137 * Creates an instance of YANG request work bench which is use to initialize
138 * logical rootNode and and schema registry.
139 *
140 * @param name name of logical container of a protocol
141 * which is a holder of the complete tree
142 * @param namespace namespace of logical container
143 * @param opType type of operation done by using YANG
144 * interface
sonu guptaeff184b2016-11-24 12:43:49 +0530145 * @param reg Yang schema registry
sonu gupta1bb37b82016-11-11 16:51:18 +0530146 * @param isValidate Flag to identify data validation need to be
147 * done by YDT or not
148 */
149 public YangRequestWorkBench(String name, String namespace,
150 YmsOperationType opType,
sonu guptaeff184b2016-11-24 12:43:49 +0530151 YangSchemaRegistry reg,
sonu gupta1bb37b82016-11-11 16:51:18 +0530152 boolean isValidate) {
sonu guptaeff184b2016-11-24 12:43:49 +0530153
154 setRootNode(new YdtLogicalNode(name, namespace));
155 registry = reg;
sonu gupta1bb37b82016-11-11 16:51:18 +0530156 ymsOperationType = opType;
157 validate = isValidate;
sonu gupta1bb37b82016-11-11 16:51:18 +0530158
sonu guptaeff184b2016-11-24 12:43:49 +0530159 setAppRootNode(getAppContext(true));
sonu gupta1bb37b82016-11-11 16:51:18 +0530160 }
161
162 /**
sonu guptaeff184b2016-11-24 12:43:49 +0530163 * Sets the logical root node for ydt.
Vidyashree Rama76faccc2016-10-17 22:06:52 +0530164 *
sonu guptaeff184b2016-11-24 12:43:49 +0530165 * @param node ydt logical root node
sonu gupta1bb37b82016-11-11 16:51:18 +0530166 */
167 private void setRootNode(YdtNode node) {
168 rootNode = node;
169 curNode = node;
170 }
171
172 /**
sonu guptaeff184b2016-11-24 12:43:49 +0530173 * Sets the logical root node for ydt application tree.
sonu gupta1bb37b82016-11-11 16:51:18 +0530174 *
sonu guptaeff184b2016-11-24 12:43:49 +0530175 * @param node ydt application context logical root node
sonu gupta1bb37b82016-11-11 16:51:18 +0530176 */
177 private void setAppRootNode(YdtAppContext node) {
178 appRootNode = node;
179 appCurNode = node;
180 }
181
182 /**
183 * Returns the YANG schema registry of Ydt.
184 * This method will be used by ytb.
185 *
186 * @return YANG schema registry
187 */
188 public YangSchemaRegistry getYangSchemaRegistry() {
189 return registry;
190 }
191
192 /**
sonu guptaeff184b2016-11-24 12:43:49 +0530193 * Returns the ydt app context tree logical root node.
194 * This method will be used by yab and ytb.
sonu gupta1bb37b82016-11-11 16:51:18 +0530195 *
sonu guptaeff184b2016-11-24 12:43:49 +0530196 * @return YdtAppContext app tree logical root node
sonu gupta1bb37b82016-11-11 16:51:18 +0530197 */
198 public YdtAppContext getAppRootNode() {
199 return appRootNode;
200 }
201
202 /**
sonu guptaeff184b2016-11-24 12:43:49 +0530203 * Returns the ydt module node with requested node identifier.
sonu gupta1bb37b82016-11-11 16:51:18 +0530204 *
sonu guptaeff184b2016-11-24 12:43:49 +0530205 * @param id module/application node identifier
sonu gupta1bb37b82016-11-11 16:51:18 +0530206 * @return YANG data tree node
sonu guptaeff184b2016-11-24 12:43:49 +0530207 * @throws YdtException when user requested node schema doesn't exist or
208 * requested node is already part of the tree
sonu gupta1bb37b82016-11-11 16:51:18 +0530209 */
sonu guptaeff184b2016-11-24 12:43:49 +0530210 private YdtNode moduleHandler(YangSchemaNodeIdentifier id)
211 throws YdtException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530212
sonu guptaeff184b2016-11-24 12:43:49 +0530213 YangSchemaNode node =
214 registry.getYangSchemaNodeUsingSchemaName(id.getName());
sonu gupta1bb37b82016-11-11 16:51:18 +0530215
sonu guptaeff184b2016-11-24 12:43:49 +0530216 String namespace = id.getNameSpace().getModuleNamespace();
217
218 /*
219 * Checking received schema node is having same namespace as
220 * requested by user or not.
221 */
222 if (node == null || namespace != null &&
223 !namespace.equals(node.getYangSchemaNodeIdentifier()
224 .getNameSpace()
225 .getModuleNamespace())) {
226 throw new YdtException(errorMsg(FMT_NOT_EXIST, id.getName()));
sonu gupta1bb37b82016-11-11 16:51:18 +0530227 }
228
sonu guptaeff184b2016-11-24 12:43:49 +0530229 /*
230 * If yms operation is for query then no validation need to be
231 * performed.
232 */
233 if (ymsOperationType != YmsOperationType.QUERY_REQUEST) {
234 // Checking whether module node is already exits in YDT or not.
235 try {
236 curNode.getCollidingChild(id);
237 } catch (YdtException e) {
238 throw new YdtException(e.getLocalizedMessage());
239 }
240 }
241
242 YdtNode newNode = new YdtSingleInstanceNode(node);
sonu gupta1bb37b82016-11-11 16:51:18 +0530243 newNode.setYangSchemaNode(node);
sonu gupta1bb37b82016-11-11 16:51:18 +0530244 return newNode;
245 }
246
247 @Override
248 public void setRootTagAttributeMap(Map<String, String> attributeTag) {
249 rootTagAttributeMap = attributeTag;
250 }
251
252 @Override
253 public Map<String, String> getRootTagAttributeMap() {
254 if (rootTagAttributeMap != null) {
255 return ImmutableMap.copyOf(rootTagAttributeMap);
256 }
257 return null;
258 }
259
260 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530261 public void addChild(String name, String namespace)
262 throws IllegalArgumentException {
263 addChild(name, namespace, UNKNOWN, null, NON_LEAF);
sonu gupta1bb37b82016-11-11 16:51:18 +0530264 }
265
266 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530267 public void addChild(String name, String namespace, YdtType ydtType)
268 throws IllegalArgumentException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530269 addChild(name, namespace, ydtType, null);
270 }
271
272 @Override
273 public void addChild(String name, String namespace,
sonu guptaeff184b2016-11-24 12:43:49 +0530274 YdtContextOperationType opType)
275 throws IllegalArgumentException {
276 addChild(name, namespace, UNKNOWN, opType, NON_LEAF);
sonu gupta1bb37b82016-11-11 16:51:18 +0530277 }
278
279 @Override
280 public void addChild(String name, String namespace, YdtType ydtType,
sonu guptaeff184b2016-11-24 12:43:49 +0530281 YdtContextOperationType opType)
282 throws IllegalArgumentException {
283 RequestedCardinality cardinality;
sonu gupta1bb37b82016-11-11 16:51:18 +0530284 switch (ydtType) {
285 case MULTI_INSTANCE_NODE:
286 cardinality = MULTI_INSTANCE;
287 break;
288 case SINGLE_INSTANCE_NODE:
289 cardinality = SINGLE_INSTANCE;
290 break;
291 default:
sonu guptaeff184b2016-11-24 12:43:49 +0530292 throw new IllegalArgumentException(E_USE_ADD_LEAF);
sonu gupta1bb37b82016-11-11 16:51:18 +0530293 }
sonu guptaeff184b2016-11-24 12:43:49 +0530294 addChild(name, namespace, cardinality, opType, NON_LEAF);
sonu gupta1bb37b82016-11-11 16:51:18 +0530295 }
296
297 /**
298 * Adds a last child to YANG data tree; this method is to be used by all
299 * protocols internally which are aware or unaware of the nature
300 * (single/multiple) of node.
301 *
302 * @param name name of child to be added
303 * @param namespace namespace of child to be added
304 * @param cardinality type of YANG data tree node operation
305 * @param opType type of requested operation over a node
306 * @param callType to identify the whether its a leaf or other node
sonu guptaeff184b2016-11-24 12:43:49 +0530307 * @throws IllegalArgumentException when method has been passed an illegal
308 * or inappropriate argument.
sonu gupta1bb37b82016-11-11 16:51:18 +0530309 */
310 private void addChild(String name, String namespace,
311 RequestedCardinality cardinality,
312 YdtContextOperationType opType,
sonu guptaeff184b2016-11-24 12:43:49 +0530313 RequestedCallType callType)
314 throws IllegalArgumentException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530315
sonu guptaeff184b2016-11-24 12:43:49 +0530316 YdtNode newNode;
317 boolean contextSwitch = false;
sonu gupta1bb37b82016-11-11 16:51:18 +0530318 YangSchemaNode augmentingSchema = null;
sonu guptaeff184b2016-11-24 12:43:49 +0530319 YangSchemaNodeIdentifier id = getNodeIdentifier(name, namespace);
Vidyashree Ramac8489702016-12-19 09:38:31 +0530320 if (name == null) {
321 if (!curNode.equals(rootNode)) {
322 throw new YdtException("Name is null for node other than module");
323 }
324
325 /*
326 * Since XML will not have module name, id.name will be null. In
327 * that case get schema node by using namespace. In NBI flow,
328 * name will never be null.
329 */
330 YangSchemaNode node = registry
331 .getSchemaWrtNameSpace(id.getNameSpace().getModuleNamespace());
332 id.setName(node.getName());
333 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530334
sonu guptaeff184b2016-11-24 12:43:49 +0530335 try {
336 // Module/sub-module node handler.
337 if (curNode.equals(rootNode)) {
338 newNode = moduleHandler(id);
sonu gupta1bb37b82016-11-11 16:51:18 +0530339 } else {
sonu guptaeff184b2016-11-24 12:43:49 +0530340
341 YangSchemaNode schemaNode;
342 YangSchemaNodeContextInfo contextInfo;
343
344 // If namespace given by user null, then take namespace from parent.
345 if (namespace == null) {
346 id.setNameSpace(curNode.getYangSchemaNode().getNameSpace());
sonu gupta1bb37b82016-11-11 16:51:18 +0530347 }
sonu guptaeff184b2016-11-24 12:43:49 +0530348
349 /*
350 * Get the already exiting YDT node in YDT tree with same
351 * nodeIdentifier
352 */
353 newNode = curNode.getCollidingChild(id);
354
355 /*
356 * If colliding child doesn't exist ,
357 * then query yang data model for schema of given node.
358 */
359 if (newNode == null) {
360 /*
361 * Get Yang Schema node context info which is having
362 * YangSchemaNode and ContextSwitchedNode.
363 */
364 contextInfo = curNode.getSchemaNodeContextInfo(id);
365
366 if (contextInfo.getContextSwitchedNode() != null) {
367 augmentingSchema = getAugmentingSchemaNode(
368 id, contextInfo);
369 if (augmentingSchema != null) {
370 /*
371 * As two tree(YDT and YDT Application Tree) are getting
372 * prepared in parallel, So setting context switch
373 * flag it will help ydt to keep the track whether
374 * ydtApp tree also need to be traversed back to parent
375 * or not with YDT tree traverse to parent call.
376 */
377 contextSwitch = true;
378 }
379 }
380 schemaNode = contextInfo.getSchemaNode();
381 } else {
382 /*
383 * If colliding child exist , then it will be leaf-list or list.
384 * If its leaf-list then return and add new requested
385 * value/valueSet in same node else take yang data model
386 * information from colliding child.
387 */
388 if (newNode.getYdtType() == MULTI_INSTANCE_LEAF_VALUE_NODE) {
389 curNode = newNode;
390 return;
391 }
392 schemaNode = newNode.getYangSchemaNode();
393 }
394
395 /*
396 * For yms query request node specific validation are not
397 * required as rest-conf can call addChild api for leaf/leaf-list
398 * node addition also in ydt.
399 */
400 if (ymsOperationType == YmsOperationType.QUERY_REQUEST) {
401 newNode = getYangSchemaNodeTypeSpecificContext(schemaNode);
402 } else {
403 newNode = getNode(schemaNode, cardinality, callType);
404 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530405 }
sonu guptaeff184b2016-11-24 12:43:49 +0530406
407 opType = getValidOpType(opType, ydtDefaultOpType, newNode, curNode);
408
409 newNode.setYdtContextOperationType(opType);
410
411 curNode.addChild(newNode, true);
412 } catch (YdtException e) {
413 freeRestResources(rootNode);
414 throw new IllegalArgumentException(e.getLocalizedMessage());
sonu gupta1bb37b82016-11-11 16:51:18 +0530415 }
416
sonu gupta1bb37b82016-11-11 16:51:18 +0530417 // Update parent ydt node map.
sonu guptaeff184b2016-11-24 12:43:49 +0530418 curNode.updateYdtMap(newNode);
sonu gupta1bb37b82016-11-11 16:51:18 +0530419
sonu guptaeff184b2016-11-24 12:43:49 +0530420 processAppTree(opType, newNode, augmentingSchema, contextSwitch);
sonu gupta1bb37b82016-11-11 16:51:18 +0530421
sonu guptaeff184b2016-11-24 12:43:49 +0530422 curNode = newNode;
sonu gupta1bb37b82016-11-11 16:51:18 +0530423 }
424
425 /**
426 * Processes application tree on the bases of requested ydt node.
427 *
428 * @param opType user requested operation type
429 * @param childNode requested ydt node
430 * @param augmentingSchema schema of last augmenting node
sonu guptaeff184b2016-11-24 12:43:49 +0530431 * @param contextSwitch true, for module node call; false for modules
sonu gupta1bb37b82016-11-11 16:51:18 +0530432 * sub-node calls
433 */
434 private void processAppTree(
435 YdtContextOperationType opType, YdtNode childNode,
sonu guptaeff184b2016-11-24 12:43:49 +0530436 YangSchemaNode augmentingSchema, boolean contextSwitch) {
sonu gupta1bb37b82016-11-11 16:51:18 +0530437
sonu guptaeff184b2016-11-24 12:43:49 +0530438 if (curNode == rootNode) {
439 augGenMethodSet = new HashSet<>();
sonu gupta1bb37b82016-11-11 16:51:18 +0530440 }
sonu guptaeff184b2016-11-24 12:43:49 +0530441
sonu gupta1bb37b82016-11-11 16:51:18 +0530442 if (opType == null) {
443 opType = curNode.getYdtContextOperationType();
444 } else {
445 // Updating operation type for parent nodes
446 appCurNode.updateAppOperationType(opType);
447 }
448
449 /*
sonu guptaeff184b2016-11-24 12:43:49 +0530450 * This is to avoid multiple entries of single augmented target.
sonu gupta1bb37b82016-11-11 16:51:18 +0530451 */
sonu guptaeff184b2016-11-24 12:43:49 +0530452 if (augmentingSchema != null) {
453 if (!augGenMethodSet.add(((YangAugment) augmentingSchema)
454 .getSetterMethodName())) {
455 return;
456 }
457 }
458
459 /*
460 * Create entry of module node in ydt app tree.
461 * Or if context switch happened then also add entry for same
462 * augmented ydt node in the ydt application tree.
463 */
464 if (curNode.equals(rootNode) || contextSwitch) {
sonu gupta1bb37b82016-11-11 16:51:18 +0530465 addChildInAppTree(childNode, augmentingSchema, opType,
sonu guptaeff184b2016-11-24 12:43:49 +0530466 contextSwitch);
sonu gupta1bb37b82016-11-11 16:51:18 +0530467
468 // Setting app tree node operation.
469 appCurNode.setOperationType(getAppOpTypeFromYdtOpType(opType));
470 }
471
472 // Updating the delete operation list in app tree.
473 if (opType == DELETE || opType == REMOVE) {
474 appCurNode.addDeleteNode(childNode);
475 }
476 }
477
sonu gupta1bb37b82016-11-11 16:51:18 +0530478
479 /**
480 * Adds a last child to YANG app data tree.this method is to be used
481 * internally by other ydt interfaces.
482 *
483 * @param childNode node to be added in tree
484 * @param schemaNode last augmenting module node
485 * @param childOpType operation type of node
486 * @param isContextSwitch true, for module node call; false for modules
487 * sub-node calls
488 */
489 private void addChildInAppTree(YdtNode childNode,
490 YangSchemaNode schemaNode,
491 YdtContextOperationType childOpType,
492 boolean isContextSwitch) {
493
494 YdtAppNodeOperationType opType;
495
496 DefaultYdtAppContext appContext = getAppContext(isContextSwitch);
497
498 // Add context switched child in ydt App tree.
499 appCurNode.addChild(appContext);
sonu guptaeff184b2016-11-24 12:43:49 +0530500
sonu gupta1bb37b82016-11-11 16:51:18 +0530501 appCurNode = appContext;
502
sonu gupta1bb37b82016-11-11 16:51:18 +0530503 opType = getAppOpTypeFromYdtOpType(childOpType);
504
505 appCurNode.setAppData(childNode, schemaNode);
506
507 appCurNode.setOperationType(opType);
508
509 childNode.setAppContextSwitch();
510 }
511
sonu gupta1bb37b82016-11-11 16:51:18 +0530512 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530513 public void addLeaf(String name, String namespace, String value)
514 throws IllegalArgumentException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530515 addLeaf(name, namespace, value, null, UNKNOWN);
516 }
517
518 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530519 public void addLeaf(String name, String namespace, Set<String> valueSet)
520 throws IllegalArgumentException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530521 addLeaf(name, namespace, null, valueSet, MULTI_INSTANCE_LEAF);
522 }
523
524 /**
525 * Adds a last leaf with list of values/single value to YANG data tree.
526 * This method is used by all protocols which knows the nature
527 * (single/multiple) or not.
528 * Value of leaf can be null which indicates selection node in get
529 * operation.
530 *
531 * @param name name of child to be added
532 * @param namespace namespace of child to be added, if it's
533 * null, parent's
534 * namespace will be applied to child
535 * @param value value of the child
536 * @param valueSet list of value of the child
537 * @param cardinality type of YANG data tree node operation
sonu guptaeff184b2016-11-24 12:43:49 +0530538 * @throws IllegalArgumentException when method has been passed an illegal
539 * or inappropriate argument.
sonu gupta1bb37b82016-11-11 16:51:18 +0530540 */
541 private void addLeaf(String name, String namespace, String value,
542 Set<String> valueSet,
sonu guptaeff184b2016-11-24 12:43:49 +0530543 RequestedCardinality cardinality)
544 throws IllegalArgumentException {
545 try {
546 addChild(name, namespace, cardinality, null, LEAF);
sonu gupta1bb37b82016-11-11 16:51:18 +0530547
sonu guptaeff184b2016-11-24 12:43:49 +0530548 // After successful addition of child node updating the values in same.
549 if (value != null) {
550 curNode.addValue(value);
551 } else if (valueSet != null) {
552 curNode.addValueSet(valueSet);
553 }
554 } catch (YdtException e) {
555 freeRestResources(rootNode);
556 throw new IllegalArgumentException(e.getLocalizedMessage());
sonu gupta1bb37b82016-11-11 16:51:18 +0530557 }
558 }
559
560 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530561 public void traverseToParent() throws IllegalStateException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530562 // If traverse back to parent for logical root node comes
563 if (curNode.equals(rootNode)) {
sonu guptaeff184b2016-11-24 12:43:49 +0530564 freeRestResources(rootNode);
565 throw new IllegalStateException(E_INVOKE_PARENT);
sonu gupta1bb37b82016-11-11 16:51:18 +0530566 }
567
sonu guptaeff184b2016-11-24 12:43:49 +0530568 try {
sonu gupta1bb37b82016-11-11 16:51:18 +0530569
sonu guptaeff184b2016-11-24 12:43:49 +0530570 // If node is of multiInstanceNode type then check key uniqueness.
571 if (curNode.getYdtType() == MULTI_INSTANCE_NODE) {
572 curNode.createKeyNodeList();
573 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530574
sonu guptaeff184b2016-11-24 12:43:49 +0530575 /*
576 * Check application switch for curNode if set,
577 * then traverseToParent in YDT application tree.
578 */
579 if (curNode.getParent().equals(rootNode) ||
580 curNode.getAppContextSwitch()) {
581 traverseToAppTreeParent();
582 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530583
sonu guptaeff184b2016-11-24 12:43:49 +0530584 /*
585 * Validate all multi Instance inside current context,
586 * This is not valid for leaf and leaf-list node.
587 */
588 if (curNode instanceof YdtMultiInstanceNode ||
589 curNode instanceof YdtSingleInstanceNode) {
590 curNode.validateMultiInstanceNode();
591 }
592
593 curNode = curNode.getParent();
594 } catch (YdtException e) {
595 freeRestResources(rootNode);
596 throw new IllegalStateException(e.getLocalizedMessage());
597 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530598 }
599
600 /**
601 * Traverses up in YANG application tree to the parent node,
602 * This will be used when Ydt current context switch flag is set.
603 */
604 private void traverseToAppTreeParent() {
605 appCurNode = appCurNode.getParent();
606 }
607
608 @Override
janani b9069eb42016-11-24 17:50:08 +0530609 public YdtExtendedContext getCurNode() {
sonu gupta1bb37b82016-11-11 16:51:18 +0530610 return curNode;
611 }
612
613 @Override
614 public void setDefaultEditOperationType(
615 YdtContextOperationType opType) {
616 ydtDefaultOpType = opType;
617 }
618
619 @Override
620 public YdtExtendedContext getRootNode() {
621 return rootNode;
622 }
623
624 @Override
625 public YmsOperationType getYmsOperationType() {
626 return ymsOperationType;
627 }
628
629 @Override
630 public void addMultiInstanceChild(String name, String namespace,
631 List<String> keysValueList,
sonu guptaeff184b2016-11-24 12:43:49 +0530632 YdtContextOperationType opType)
633 throws IllegalArgumentException {
634
sonu gupta1bb37b82016-11-11 16:51:18 +0530635 addChild(name, namespace, UNKNOWN, opType,
636 RequestedCallType.MULTI_INSTANCE);
637 int inputCount = keysValueList.size();
sonu gupta1bb37b82016-11-11 16:51:18 +0530638
sonu guptaeff184b2016-11-24 12:43:49 +0530639 try {
640 if (curNode.getYdtType() == MULTI_INSTANCE_LEAF_VALUE_NODE) {
641
642 /*
643 * Calculating the current leaf-list node array size by adding
644 * existing elements count and new supplied elements by user for
645 * the same.
646 */
647 // TODO instance count for leaf list need to be handled.
648// if (curNode.getValueSet().size() + inputCount > expectedCount) {
649// curNode.errorHandler(
650// errorMsg(FMT_MANY_INS, name, expectedCount), rootNode);
651// }
652
653 /*
654 * After successful addition of child node updating
655 * the values in same.
656 */
657 for (String value : keysValueList) {
658 curNode.addValue(value);
sonu gupta1bb37b82016-11-11 16:51:18 +0530659 }
sonu guptaeff184b2016-11-24 12:43:49 +0530660 } else if (curNode.getYdtType() == MULTI_INSTANCE_NODE) {
sonu gupta1bb37b82016-11-11 16:51:18 +0530661
sonu guptaeff184b2016-11-24 12:43:49 +0530662 YangList yangListHolder = (YangList) curNode.getYangSchemaNode();
663 List<String> schemaKeyList = yangListHolder.getKeyList();
664 int expectedCount = schemaKeyList.size();
665 checkElementCount(name, expectedCount, inputCount);
666
667 //After validation adding the key nodes under the list node.
668 Iterator<String> sklIter = schemaKeyList.iterator();
669 Iterator<String> kvlIter = keysValueList.iterator();
670 String keyEleName;
671
672 while (kvlIter.hasNext()) {
673 String value = kvlIter.next();
674 keyEleName = sklIter.next();
675 addLeaf(keyEleName, namespace, value);
676 if (kvlIter.hasNext()) {
677 traverseToParentWithoutValidation();
678 }
679 }
680
681 curNode = curNode.getParent();
682 }
683 } catch (YdtException e) {
684 freeRestResources(rootNode);
685 throw new IllegalArgumentException(e.getLocalizedMessage());
sonu gupta1bb37b82016-11-11 16:51:18 +0530686 }
687 }
688
689 /**
690 * Adds a last child to YANG data tree, this method is to be used by
691 * YANG object builder sub-calls internally.
692 *
693 * @param opType type of requested operation over a node
694 * @return returns added ydt node in YDT tree
695 */
696 private YdtNode addExtendedChildNode(YdtContextOperationType opType,
697 YangSchemaNode schemaNode) {
698
sonu guptaeff184b2016-11-24 12:43:49 +0530699 YdtNode childNode = getYangSchemaNodeTypeSpecificContext(schemaNode);
sonu gupta1bb37b82016-11-11 16:51:18 +0530700
701 childNode.setYangSchemaNode(schemaNode);
702
703 childNode.setYdtContextOperationType(opType);
704
705 curNode.addChild(childNode, true);
706
707 curNode = childNode;
708
709 return childNode;
710 }
711
712 @Override
713 public YdtExtendedContext addChild(YdtContextOperationType opType,
714 YangSchemaNode schemaNode) {
715 return addExtendedChildNode(opType, schemaNode);
716 }
717
718 @Override
719 public YdtExtendedContext addLeafList(Set<String> valueSet,
720 YangSchemaNode schemaNode) {
721 YdtNode childNode = addExtendedChildNode(null, schemaNode);
722
sonu guptaeff184b2016-11-24 12:43:49 +0530723 /*
724 * After successful addition of child node updating the values in
725 * valueSet.
726 */
sonu gupta1bb37b82016-11-11 16:51:18 +0530727 childNode.addValueSetWithoutValidation(valueSet);
728 return childNode;
729 }
730
731 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530732 public YdtExtendedContext addLeaf(String value, YangSchemaNode schemaNode) {
733
sonu gupta1bb37b82016-11-11 16:51:18 +0530734 YdtNode childNode = addExtendedChildNode(null, schemaNode);
735
736 // After successful addition of child node updating the values in same.
sonu guptaeff184b2016-11-24 12:43:49 +0530737 childNode.addValueWithoutValidation(value, ((YangLeaf) schemaNode)
738 .isKeyLeaf());
sonu gupta1bb37b82016-11-11 16:51:18 +0530739 return childNode;
740 }
741
742 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530743 public void traverseToParentWithoutValidation()
744 throws IllegalStateException {
745 // If traverse back to parent for logical root node comes.
sonu gupta1bb37b82016-11-11 16:51:18 +0530746 if (curNode.equals(rootNode)) {
sonu guptaeff184b2016-11-24 12:43:49 +0530747 freeRestResources(rootNode);
748 throw new IllegalStateException(E_INVOKE_PARENT);
sonu gupta1bb37b82016-11-11 16:51:18 +0530749 }
750 curNode = curNode.getParent();
751 }
sonu guptaeff184b2016-11-24 12:43:49 +0530752
753 /**
754 * Returns the method name's set for an augmented target node in an
755 * application tree.
756 *
757 * @return augGenMethodSet set of method name's
758 */
759 public Set<String> getAugGenMethodSet() {
760 return augGenMethodSet;
761 }
762
763 /**
764 * Sets the method name's set for an augmented target node in an
765 * application tree.
766 *
767 * @param augGenMethodSet set of method name's
768 */
769 public void setAugGenMethodSet(Set<String> augGenMethodSet) {
770 this.augGenMethodSet = augGenMethodSet;
771 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530772}