blob: cb6f7d7d793bd9ae031c0037ba404cba45088fde [file] [log] [blame]
Vidyashree Rama76faccc2016-10-17 22:06:52 +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.yab;
18
19import org.onosproject.yangutils.datamodel.YangAugment;
20import org.onosproject.yangutils.datamodel.YangAugmentableNode;
21import org.onosproject.yangutils.datamodel.YangInput;
22import org.onosproject.yangutils.datamodel.YangModule;
23import org.onosproject.yangutils.datamodel.YangNode;
24import org.onosproject.yangutils.datamodel.YangRpc;
25import org.onosproject.yangutils.datamodel.YangSchemaNode;
26import org.onosproject.yms.app.utils.TraversalType;
27import org.onosproject.yms.app.yab.exceptions.YabException;
28import org.onosproject.yms.app.ydt.DefaultYdtAppContext;
29import org.onosproject.yms.app.ydt.YangRequestWorkBench;
30import org.onosproject.yms.app.ydt.YangResponseWorkBench;
31import org.onosproject.yms.app.ydt.YdtAppContext;
32import org.onosproject.yms.app.ydt.YdtExtendedContext;
33import org.onosproject.yms.app.ydt.YdtMultiInstanceNode;
34import org.onosproject.yms.app.ydt.YdtNode;
35import org.onosproject.yms.app.yob.DefaultYobBuilder;
36import org.onosproject.yms.app.ysr.YangSchemaRegistry;
37import org.onosproject.yms.app.ytb.DefaultYangTreeBuilder;
38import org.onosproject.yms.ydt.YdtBuilder;
39import org.onosproject.yms.ydt.YdtContext;
40import org.onosproject.yms.ydt.YdtResponse;
41
42import java.lang.reflect.InvocationTargetException;
43import java.lang.reflect.Method;
44import java.util.Iterator;
45import java.util.LinkedList;
46import java.util.List;
47
48import static com.google.common.base.Preconditions.checkNotNull;
49import static org.onosproject.yms.app.utils.TraversalType.CHILD;
50import static org.onosproject.yms.app.utils.TraversalType.PARENT;
51import static org.onosproject.yms.app.utils.TraversalType.ROOT;
52import static org.onosproject.yms.app.utils.TraversalType.SIBLING;
53import static org.onosproject.yms.app.ydt.AppNodeFactory.getAppContext;
54import static org.onosproject.yms.app.ydt.YdtAppNodeOperationType.DELETE_ONLY;
55import static org.onosproject.yms.app.ydt.YdtAppNodeOperationType.OTHER_EDIT;
56import static org.onosproject.yms.ydt.YdtContextOperationType.DELETE;
57import static org.onosproject.yms.ydt.YmsOperationExecutionStatus.EXECUTION_SUCCESS;
58
59/**
60 * Represents YANG application broker. It acts as a broker between Protocol and
61 * YANG based application.
62 */
63public class YangApplicationBroker {
64
65 private static final String GET = "get";
66 private static final String SET = "set";
67 private static final String AUGMENTED = "Augmented";
68 private static final String VOID = "void";
69 private final YangSchemaRegistry schemaRegistry;
70
71 /**
72 * Creates a new YANG application broker.
73 *
74 * @param schemaRegistry YANG schema registry
75 */
76 public YangApplicationBroker(YangSchemaRegistry schemaRegistry) {
77 this.schemaRegistry = schemaRegistry;
78 }
79
80 /**
81 * Processes query request of a NBI protocol.
82 *
83 * @param ydtWorkBench YANG request work bench
84 * @return YANG response data tree node context
85 * @throws YabException violation in execution of YAB
86 */
87 public YdtResponse processQuery(YdtBuilder ydtWorkBench)
88 throws YabException {
89 List<Object> responseObjects = new LinkedList<>();
90 YangRequestWorkBench workBench = (YangRequestWorkBench) ydtWorkBench;
91
92 for (YdtAppContext appContext = workBench.getAppRootNode().getFirstChild();
93 appContext != null; appContext = appContext.getNextSibling()) {
94 Object responseObject = processQueryOfApplication(appContext);
95 responseObjects.add(responseObject);
96 }
97
98 YdtContext rootYdtContext = workBench.getRootNode();
99 YdtBuilder responseYdt = buildResponseYdt(responseObjects,
100 rootYdtContext.getName(),
101 rootYdtContext.getNamespace());
102
103 return new YangResponseWorkBench(responseYdt.getRootNode(),
104 EXECUTION_SUCCESS,
105 ydtWorkBench.getYmsOperationType());
106 }
107
108 /**
109 * Processes edit request of a NBI protocol.
110 *
111 * @param ydtWorkBench YANG request work bench
112 * @return YANG response data tree node context
113 * @throws YabException violation in execution of YAB
114 * @throws CloneNotSupportedException clone is not supported
115 */
116 public YdtResponse processEdit(YdtBuilder ydtWorkBench)
117 throws CloneNotSupportedException, YabException {
118 YangRequestWorkBench workBench = (YangRequestWorkBench) ydtWorkBench;
119
120 for (YdtAppContext appContext = workBench.getAppRootNode().getFirstChild();
121 appContext != null; appContext = appContext.getNextSibling()) {
122 processEditOfApplication(appContext);
123 }
124
125 /*
126 * Since for set operation return type is void, there will not be
127 * response ydt tree so returning null.
128 */
129 return new YangResponseWorkBench(null, EXECUTION_SUCCESS,
130 workBench.getYmsOperationType());
131 }
132
133 /**
134 * Processes operation request of a NBI protocol.
135 *
136 * @param ydtWorkBench YANG request work bench
137 * @return YANG response data tree node context
138 * @throws YabException violation in execution of YAB
139 */
140 public YdtResponse processOperation(YdtBuilder ydtWorkBench)
141 throws YabException {
142 YangRequestWorkBench workBench = (YangRequestWorkBench) ydtWorkBench;
143 YdtAppContext appContext = workBench.getAppRootNode().getFirstChild();
144 YdtContext ydtNode = appContext.getModuleContext();
145 while (ydtNode != null) {
146 YdtContext childYdtNode = ydtNode.getFirstChild();
147 YangSchemaNode yangNode = ((YdtNode) childYdtNode).getYangSchemaNode();
148 if (yangNode instanceof YangRpc) {
149 return processRpcOperationOfApplication(childYdtNode,
150 appContext, yangNode,
151 workBench);
152 }
153 ydtNode = ydtNode.getNextSibling();
154 }
155 return new YangResponseWorkBench(null, EXECUTION_SUCCESS,
156 ydtWorkBench.getYmsOperationType());
157 }
158
159 /**
160 * Processes rpc request of an application.
161 *
162 * @param appContext application context
163 * @return response object from application
164 */
165 private YdtResponse processRpcOperationOfApplication(YdtContext rpcYdt,
166 YdtAppContext appContext,
167 YangSchemaNode yangRpc,
168 YangRequestWorkBench workBench)
169 throws YabException {
170 Object inputObject = null;
171 YdtContext inputYdtNode = getInputYdtNode(rpcYdt);
172 if (inputYdtNode != null) {
173 inputObject = getYangObject(inputYdtNode);
174 }
175
176 Object appObject = getApplicationObjectForRpc(appContext);
177
178 String methodName = yangRpc.getJavaClassNameOrBuiltInType();
179 Object outputObject = invokeRpcApplicationsMethod(appObject,
180 inputObject,
181 methodName);
182
183 String returnType = getReturnTypeOfRpcResponse(appObject,
184 inputObject, yangRpc);
185
186 if (!returnType.equals(VOID)) {
187 YdtBuilder responseYdt = buildRpcResponseYdt(outputObject,
188 workBench);
189 return new YangResponseWorkBench(responseYdt.getRootNode(),
190 EXECUTION_SUCCESS,
191 workBench.getYmsOperationType());
192 }
193
194 return new YangResponseWorkBench(null, EXECUTION_SUCCESS,
195 workBench.getYmsOperationType());
196 }
197
198 /**
199 * Processes query request of an application.
200 *
201 * @param appContext application context
202 * @return response object from application
203 */
204 private Object processQueryOfApplication(YdtAppContext appContext)
205 throws YabException {
206 YdtContext ydtNode = appContext.getModuleContext();
207
208 // Update application context tree if any node is augmented
209 YangNode yangNode = (YangNode) appContext.getYangSchemaNode();
210 if (yangNode.isDescendantNodeAugmented()) {
211 processAugmentForChildNode(appContext, yangNode);
212 }
213
214 String appName = getCapitalCase(((YdtNode) appContext.getModuleContext())
215 .getYangSchemaNode()
216 .getJavaClassNameOrBuiltInType());
217
218 // get YangObject of YdtContext from YOB
219 Object outputObject = getYangObject(ydtNode);
220
221 TraversalType curTraversal = ROOT;
222 do {
223 if (curTraversal != PARENT) {
224
225 // find application and get application's object using YSR
226 Object appManagerObject = getApplicationObject(appContext);
227
228 // find which method to invoke
229 String methodName = getApplicationMethodName(appContext,
230 appName, GET);
231
232 // invoke application's getter method
233 outputObject = invokeApplicationsMethod(appManagerObject,
234 outputObject,
235 methodName);
236 }
237
238 /*
239 * AppContext may contain other nodes if it is augmented, so
240 * traverse the appContext tree
241 */
242 if (curTraversal != PARENT && appContext.getFirstChild() != null) {
243 curTraversal = CHILD;
244 appContext = appContext.getFirstChild();
245 } else if (appContext.getNextSibling() != null) {
246 curTraversal = SIBLING;
247 appContext = appContext.getNextSibling();
248 } else {
249 curTraversal = PARENT;
250 if (appContext.getParent().getParent() != null) {
251 appContext = appContext.getParent();
252 }
253 }
254 // no need to do any operation for logical root node
255 } while (appContext.getParent().getParent() != null);
256 return outputObject;
257 }
258
259 /**
260 * Processes edit request of an application.
261 *
262 * @param appContext application context
263 * @throws YabException violation in execution of YAB
264 * @throws CloneNotSupportedException clone is not supported
265 */
266 private void processEditOfApplication(YdtAppContext appContext)
267 throws CloneNotSupportedException, YabException {
268
269 // process delete request if operation type is delete and both
270 if (appContext.getOperationType() != OTHER_EDIT) {
271 processDeleteRequestOfApplication(appContext);
272 }
273
274 // process edit request if operation type is other edit and both
275 if (appContext.getOperationType() != DELETE_ONLY) {
276 YdtContext ydtNode = appContext.getModuleContext();
277
278 String appName = getCapitalCase(((YdtNode) appContext.getModuleContext())
279 .getYangSchemaNode()
280 .getJavaClassNameOrBuiltInType());
281
282 // get YO from YOB
283 Object outputObject = getYangObject(ydtNode);
284
285 TraversalType curTraversal = ROOT;
286 do {
287 if (curTraversal != PARENT) {
288
289 // find application and get application's object using YSR
290 Object appManagerObject = getApplicationObject(appContext);
291
292 // find which method to invoke
293 String methodName = getApplicationMethodName(appContext,
294 appName, SET);
295
296 // invoke application's setter method
297 invokeApplicationsMethod(appManagerObject, outputObject,
298 methodName);
299 }
300
301 /*
302 * AppContext may contain other nodes if it is augmented,
303 * so traverse the appContext tree
304 */
305 if (curTraversal != PARENT && appContext.getFirstChild() != null) {
306 curTraversal = CHILD;
307 appContext = appContext.getFirstChild();
308 } else if (appContext.getNextSibling() != null) {
309 curTraversal = SIBLING;
310 appContext = appContext.getNextSibling();
311 } else {
312 curTraversal = PARENT;
313 if (appContext.getParent().getParent() != null) {
314 appContext = appContext.getParent();
315 }
316 }
317 // no need to do any operation for logical root node
318 } while (appContext.getParent().getParent() != null);
319 }
320 }
321
322 /**
323 * Processes delete request of an application.
324 *
325 * @param appContext application context
326 * @throws YabException violation in execution of YAB
327 * @throws CloneNotSupportedException clone is not supported
328 */
329 private void processDeleteRequestOfApplication(YdtAppContext appContext)
330 throws CloneNotSupportedException, YabException {
331 TraversalType curTraversal = ROOT;
332 List<YdtContext> deleteNodes = appContext.getDeleteNodes();
333
334 if (deleteNodes != null && !deleteNodes.isEmpty()) {
335
336 /*
337 * Split the current Ydt tree into two trees.
338 * Delete Tree with all nodes with delete operation and other
339 * tree with other edit operation
340 */
341 YdtContext deleteTree = buildDeleteTree(deleteNodes);
342
343 /*
344 * If any of nodes in ydt delete tree is augmented then add
345 * augmented nodes to current ydt tree
346 */
347 processAugmentedNodesForDelete(deleteTree.getFirstChild(), appContext);
348
349 Object inputObject = getYangObject(deleteTree.getFirstChild());
350
351 String appName = getCapitalCase(((YdtNode) appContext.getModuleContext())
352 .getYangSchemaNode()
353 .getJavaClassNameOrBuiltInType());
354
355 do {
356 if (curTraversal == ROOT || curTraversal == SIBLING) {
357 while (appContext.getLastChild() != null) {
358 appContext = appContext.getLastChild();
359 }
360 }
361
362 // getAugmentApplication manager object
363 Object appManagerObject = getApplicationObject(appContext);
364
365 // find which method to invoke
366 String methodName = getApplicationMethodName(appContext,
367 appName, SET);
368
369 // invoke application's setter method
370 invokeApplicationsMethod(appManagerObject, inputObject, methodName);
371
372 if (appContext.getPreviousSibling() != null) {
373 curTraversal = SIBLING;
374 appContext = appContext.getPreviousSibling();
375 } else if (appContext.getParent() != null) {
376 curTraversal = PARENT;
377 appContext = appContext.getParent();
378 }
379 } while (appContext.getParent() != null);
380 }
381 }
382
383 /**
384 * Traverses data model tree and if any node is augmented, then
385 * adds child to current application context.
386 *
387 * @param curAppContext current application context
388 * @param schemaNode YANG data model node, either module or augment
389 */
390 protected void processAugmentForChildNode(YdtAppContext curAppContext,
391 YangNode schemaNode) {
392 YangNode yangNode = schemaNode.getChild();
393 if (yangNode == null) {
394 return;
395 }
396
397 TraversalType curTraversal = CHILD;
398 while (!yangNode.equals(schemaNode)) {
399 if (curTraversal != PARENT && yangNode instanceof YangAugmentableNode
400 && !((YangAugmentableNode) yangNode).getAugmentedInfoList()
401 .isEmpty()) {
402 updateAppTreeWithAugmentNodes(yangNode, curAppContext);
403 }
404
405 if (curTraversal != PARENT && yangNode.getChild() != null
406 && yangNode.isDescendantNodeAugmented()) {
407 curTraversal = CHILD;
408 yangNode = yangNode.getChild();
409 } else if (yangNode.getNextSibling() != null) {
410 curTraversal = SIBLING;
411 yangNode = yangNode.getNextSibling();
412 } else {
413 curTraversal = PARENT;
414 yangNode = yangNode.getParent();
415 }
416 }
417 }
418
419 /**
420 * Traverses YDT delete tree and if any YDT node is augmented then
421 * updates the YDT delete tree with augment nodes.
422 *
423 * @param deleteTree YDT delete tree
424 * @param appContext application context
425 */
426 protected void processAugmentedNodesForDelete(YdtContext deleteTree,
427 YdtAppContext appContext) {
428 TraversalType curTraversal = ROOT;
429 YdtContext ydtContext = deleteTree.getFirstChild();
430
431 if (ydtContext == null) {
432 /*
433 * Delete request is for module, so check all the nodes under
434 * module whether it is augmented.
435 */
436 YangNode yangNode = ((YangNode) ((YdtNode) deleteTree)
437 .getYangSchemaNode());
438 if (yangNode.isDescendantNodeAugmented()) {
439 processAugmentForChildNode(appContext, yangNode);
440 }
441 return;
442 }
443
444 while (!ydtContext.equals(deleteTree)) {
445 if (curTraversal != PARENT && ((YdtNode) ydtContext)
446 .getYdtContextOperationType() == DELETE) {
447 YangNode yangNode = ((YangNode) ((YdtNode) ydtContext)
448 .getYangSchemaNode());
449 if (yangNode instanceof YangAugmentableNode) {
450 updateAppTreeWithAugmentNodes(yangNode, appContext);
451 }
452 if (yangNode.isDescendantNodeAugmented()) {
453 processAugmentForChildNode(appContext, yangNode);
454 }
455 }
456
457 if (curTraversal != PARENT && ydtContext.getFirstChild() != null) {
458 curTraversal = CHILD;
459 ydtContext = ydtContext.getFirstChild();
460 } else if (ydtContext.getNextSibling() != null) {
461 curTraversal = SIBLING;
462 ydtContext = ydtContext.getNextSibling();
463 } else {
464 curTraversal = PARENT;
465 ydtContext = ydtContext.getParent();
466 }
467 }
468 }
469
470 /**
471 * Returns response YANG data tree using YTB.
472 *
473 * @param responseObjects list of application's response objects
474 * @param name application YANG name
475 * @param namespace application YANG namespace
476 * @return response YANG data tree
477 */
478 private YdtBuilder buildResponseYdt(List<Object> responseObjects,
479 String name, String namespace) {
480 DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
481 return treeBuilder.getYdtBuilderForYo(responseObjects,
482 name, namespace, null, schemaRegistry);
483 }
484
485 private YdtBuilder buildRpcResponseYdt(Object responseObject,
486 YangRequestWorkBench requestWorkBench) {
487 DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
488 return treeBuilder.getYdtForRpcResponse(responseObject, requestWorkBench);
489 }
490
491 /**
492 * Builds delete tree for list of delete nodes.
493 *
494 * @param deleteNodes list of delete nodes
495 * @return deleteTree YANG data tree for delete operation
496 * @throws CloneNotSupportedException clone is not supported
497 */
498 protected YdtContext buildDeleteTree(List<YdtContext> deleteNodes) throws
499 CloneNotSupportedException {
500 Iterator<YdtContext> iterator = deleteNodes.iterator();
501 YdtContext deleteTree = null;
502 while (iterator.hasNext()) {
503 YdtContext deleteNode = iterator.next();
504 if (((YdtExtendedContext) deleteNode.getParent())
505 .getYdtContextOperationType() != DELETE) {
506 cloneAncestorsOfDeleteNode(deleteNode);
507 deleteTree = unlinkDeleteNodeFromCurrentTree((YdtNode) deleteNode);
508 }
509 }
510
511 if (deleteTree != null) {
512 while (deleteTree.getParent() != null) {
513 deleteTree = deleteTree.getParent();
514 }
515 }
516 return deleteTree;
517 }
518
519 /**
520 * Clones ancestor nodes of delete node.
521 *
522 * @param deleteNode node to be deleted
523 * @throws CloneNotSupportedException clone not supported
524 */
525 private void cloneAncestorsOfDeleteNode(YdtContext deleteNode)
526 throws CloneNotSupportedException {
527 YdtNode clonedNode;
528 YdtNode previousNode = null;
529
530 // Clone the parents of delete node to form delete tree
531 YdtNode nodeToClone = (YdtNode) deleteNode.getParent();
532 while (nodeToClone != null) {
533 // If node is not cloned yet
534 if (nodeToClone.getClonedNode() == null) {
535 clonedNode = nodeToClone.clone();
536 unlinkCurrentYdtNode(clonedNode);
537 if (nodeToClone instanceof YdtMultiInstanceNode) {
538 addKeyLeavesToClonedNode(nodeToClone, clonedNode);
539 }
540 nodeToClone.setClonedNode(clonedNode);
541 } else {
542 // already node is cloned
543 clonedNode = (YdtNode) nodeToClone.getClonedNode();
544 }
545
546 if (previousNode != null) {
547 /*
548 * add previous cloned node as child of current cloned node
549 * so that tree will be formed from delete node parent to
550 * logical root node.
551 */
552 clonedNode.addChild(previousNode, false);
553 }
554 previousNode = clonedNode;
555 nodeToClone = nodeToClone.getParent();
556 }
557 }
558
559 /**
560 * Unlinks delete node from current YANG data tree of application
561 * and links it to cloned delete tree.
562 *
563 * @param deleteNode node to be unlinked
564 * @return deleteNode delete node linked to cloned delete tree
565 */
566 private YdtNode unlinkDeleteNodeFromCurrentTree(YdtNode deleteNode) {
567 YdtNode parentClonedNode = (YdtNode) deleteNode.getParent().getClonedNode();
568 unlinkNodeFromParent(deleteNode);
569 unlinkNodeFromSibling(deleteNode);
570
571 /*
572 * Set all the pointers of node to null before adding as child
573 * to parent's cloned node.
574 */
575 deleteNode.setParent(null);
576 deleteNode.setPreviousSibling(null);
577 deleteNode.setNextSibling(null);
578
579 parentClonedNode.addChild(deleteNode, false);
580 return deleteNode;
581 }
582
583 /**
584 * Adds key leaf nodes to cloned YDT node from current Ydt node.
585 *
586 * @param curNode current YDT node
587 * @param clonedNode cloned YDT node
588 */
589 private void addKeyLeavesToClonedNode(YdtNode curNode, YdtNode clonedNode)
590 throws CloneNotSupportedException {
591 YdtNode keyClonedLeaf;
592 List<YdtContext> keyList = ((YdtMultiInstanceNode) curNode)
593 .getKeyNodeList();
594 if (keyList != null && !keyList.isEmpty()) {
595 for (YdtContext keyLeaf : keyList) {
596 keyClonedLeaf = ((YdtNode) keyLeaf).clone();
597 unlinkCurrentYdtNode(keyClonedLeaf);
598 clonedNode.addChild(keyClonedLeaf, true);
599 }
600 }
601 }
602
603 /**
604 * Updates application context tree if any of the nodes in current
605 * application context tree is augmented.
606 *
607 * @param yangNode YANG schema node which is augmented
608 * @param curAppContext current application context tree
609 */
610 private void updateAppTreeWithAugmentNodes(YangNode yangNode,
611 YdtAppContext curAppContext) {
612 YdtAppContext childAppContext;
613 for (YangAugment yangAugment : ((YangAugmentableNode) yangNode)
614 .getAugmentedInfoList()) {
615 Object appManagerObject = schemaRegistry
616 .getRegisteredApplication(yangAugment.getParent());
617 if (appManagerObject != null) {
618 childAppContext = addChildToYdtAppTree(curAppContext,
619 yangAugment);
620 processAugmentForChildNode(childAppContext, yangAugment);
621 }
622 }
623 }
624
625 /**
626 * Adds child node to current application context tree.
627 *
628 * @param curAppContext current application context
629 * @param augment augment data model node
630 * @return childAppContext child node added
631 */
632 private YdtAppContext addChildToYdtAppTree(YdtAppContext curAppContext,
633 YangNode augment) {
634 DefaultYdtAppContext childAppContext = getAppContext(true);
635 childAppContext.setParent(curAppContext);
636 childAppContext.setOperationType(curAppContext.getOperationType());
637 childAppContext.setAugmentingSchemaNode(augment);
638 curAppContext.addChild(childAppContext);
639 return childAppContext;
640 }
641
642 /**
643 * Unlinks the current node from its parent.
644 *
645 * @param deleteNode node which should be unlinked from YDT tree
646 */
647 private void unlinkNodeFromParent(YdtNode deleteNode) {
648 YdtNode parentNode = deleteNode.getParent();
649 if (parentNode.getFirstChild().equals(deleteNode)
650 && parentNode.getLastChild().equals(deleteNode)) {
651 parentNode.setChild(null);
652 parentNode.setLastChild(null);
653 } else if (parentNode.getFirstChild().equals(deleteNode)) {
654 parentNode.setChild(deleteNode.getNextSibling());
655 } else if (parentNode.getLastChild().equals(deleteNode)) {
656 parentNode.setLastChild(deleteNode.getPreviousSibling());
657 }
658 }
659
660 /**
661 * Unlinks the current node from its sibling.
662 *
663 * @param deleteNode node which should be unlinked from YDT tree
664 */
665 private void unlinkNodeFromSibling(YdtNode deleteNode) {
666 YdtNode previousSibling = deleteNode.getPreviousSibling();
667 YdtNode nextSibling = deleteNode.getNextSibling();
668 if (nextSibling != null && previousSibling != null) {
669 previousSibling.setNextSibling(nextSibling);
670 nextSibling.setPreviousSibling(previousSibling);
671 } else if (nextSibling != null) {
672 nextSibling.setPreviousSibling(null);
673 } else if (previousSibling != null) {
674 previousSibling.setNextSibling(null);
675 }
676 }
677
678 /**
679 * Unlinks current Ydt node from parent, sibling and child.
680 *
681 * @param ydtNode YANG data tree node
682 */
683 private void unlinkCurrentYdtNode(YdtNode ydtNode) {
684 ydtNode.setParent(null);
685 ydtNode.setNextSibling(null);
686 ydtNode.setPreviousSibling(null);
687 ydtNode.setChild(null);
688 ydtNode.setLastChild(null);
689 }
690
691 /**
692 * Returns YANG object for YDT node.
693 *
694 * @param ydtNode YANG data node
695 * @return YANG object for YDT node
696 */
697 private Object getYangObject(YdtContext ydtNode) {
698 checkNotNull(ydtNode);
699 DefaultYobBuilder yobBuilder = new DefaultYobBuilder();
700 return yobBuilder.getYangObject((YdtExtendedContext) ydtNode,
701 schemaRegistry);
702 }
703
704 /**
705 * Returns application manager object for YDT node.
706 *
707 * @param appContext YDT application context
708 * @return application manager object
709 */
710 private Object getApplicationObjectForRpc(YdtAppContext appContext) {
711 checkNotNull(appContext);
712 while (appContext.getFirstChild() != null) {
713 appContext = appContext.getFirstChild();
714 }
715 return schemaRegistry.getRegisteredApplication(appContext.getAppData()
716 .getRootSchemaNode());
717 }
718
719 /**
720 * Returns application manager object of application.
721 *
722 * @param appContext application context
723 * @return application manager object
724 */
725 private Object getApplicationObject(YdtAppContext appContext) {
726 return schemaRegistry.getRegisteredApplication(appContext.getAppData()
727 .getRootSchemaNode());
728 }
729
730 /**
731 * Converts name to capital case.
732 *
733 * @param yangIdentifier identifier
734 * @return name to capital case
735 */
736 private String getCapitalCase(String yangIdentifier) {
737 return yangIdentifier.substring(0, 1).toUpperCase() +
738 yangIdentifier.substring(1);
739 }
740
741 /**
742 * Returns get/set method name for application's request.
743 *
744 * @param appContext application context
745 * @return get/set method name for application's query request
746 */
747 private String getApplicationMethodName(YdtAppContext appContext,
748 String appName,
749 String operation) {
750 if (appContext.getYangSchemaNode() instanceof YangModule) {
751 return operation + appName;
752 }
753
754 String augment = ((YangAugment) appContext
755 .getAugmentingSchemaNode()).getTargetNode().get(0)
756 .getResolvedNode().getJavaClassNameOrBuiltInType();
757 return new StringBuilder().append(operation).append(AUGMENTED)
758 .append(appName).append(getCapitalCase(augment)).toString();
759 }
760
761 /**
762 * Returns rpc's input schema node.
763 *
764 * @param rpcNode rpc schema node
765 * @return rpc's input YDT node
766 */
767 private YdtContext getInputYdtNode(YdtContext rpcNode) {
768 YdtContext inputNode = rpcNode.getFirstChild();
769 while (inputNode != null) {
770 YangSchemaNode yangInputNode = ((YdtNode) inputNode)
771 .getYangSchemaNode();
772 if (yangInputNode instanceof YangInput) {
773 return inputNode;
774 }
775 inputNode = rpcNode.getNextSibling();
776 }
777 return null;
778 }
779
780 /**
781 * Invokes application method for RPC request.
782 *
783 * @param appManagerObject application manager object
784 * @param inputObject input parameter object of method
785 * @param methodName method name which should be invoked
786 * @return response object from application
787 * @throws YabException violation in execution of YAB
788 */
789 private Object invokeApplicationsMethod(Object appManagerObject,
790 Object inputObject,
791 String methodName) throws YabException {
792 checkNotNull(appManagerObject);
793 Class<?> appClass = appManagerObject.getClass();
794 try {
795 Method methodObject = appClass.getDeclaredMethod(methodName,
796 inputObject.getClass());
797 if (methodObject != null) {
798 return methodObject.invoke(appManagerObject, inputObject);
799 }
800 throw new YabException("No such method in application");
801 } catch (IllegalAccessException | NoSuchMethodException |
802 InvocationTargetException e) {
803 throw new YabException(e);
804 }
805 }
806
807 /**
808 * Invokes application method for RPC request.
809 *
810 * @param appObject application manager object
811 * @param inputObject input parameter object of method
812 * @param yangNode method name which should be invoked
813 * @return response object from application
814 * @throws YabException violation in execution of YAB
815 */
816 private String getReturnTypeOfRpcResponse(Object appObject,
817 Object inputObject, YangSchemaNode
818 yangNode) throws YabException {
819 Method methodObject = null;
820 try {
821 if (inputObject == null) {
822 methodObject = appObject.getClass()
823 .getDeclaredMethod(yangNode.getJavaClassNameOrBuiltInType(),
824 null);
825 } else {
826 methodObject = appObject.getClass()
827 .getDeclaredMethod(yangNode.getJavaClassNameOrBuiltInType(),
828 inputObject.getClass().getInterfaces());
829 }
830 } catch (NoSuchMethodException e) {
831 new YabException(e);
832 }
833 return methodObject.getReturnType().getSimpleName();
834 }
835
836 /**
837 * Invokes application method for RPC request.
838 *
839 * @param appManagerObject application manager object
840 * @param inputParamObject input parameter object of method
841 * @param methodName method name which should be invoked
842 * @return response object from application
843 * @throws YabException violation in execution of YAB
844 */
845 private Object invokeRpcApplicationsMethod(Object appManagerObject,
846 Object inputParamObject,
847 String methodName) throws YabException {
848 checkNotNull(appManagerObject);
849 Class<?> appClass = appManagerObject.getClass();
850 try {
851 Method methodObject;
852 if (inputParamObject == null) {
853 methodObject = appClass.getDeclaredMethod(methodName, null);
854 if (methodObject != null) {
855 return methodObject.invoke(appManagerObject);
856 }
857 } else {
858 methodObject = appClass.getDeclaredMethod(methodName,
859 inputParamObject
860 .getClass()
861 .getInterfaces());
862 if (methodObject != null) {
863 return methodObject.invoke(appManagerObject, inputParamObject);
864 }
865 }
866 throw new YabException("No such method in application");
867 } catch (IllegalAccessException | NoSuchMethodException |
868 InvocationTargetException e) {
869 throw new YabException(e);
870 }
871 }
872}