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