| /* |
| * Copyright 2016-present Open Networking Foundation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.onosproject.yms.app.yab; |
| |
| import org.onosproject.yangutils.datamodel.YangAugment; |
| import org.onosproject.yangutils.datamodel.YangAugmentableNode; |
| import org.onosproject.yangutils.datamodel.YangInput; |
| import org.onosproject.yangutils.datamodel.YangModule; |
| import org.onosproject.yangutils.datamodel.YangNode; |
| import org.onosproject.yangutils.datamodel.YangRpc; |
| import org.onosproject.yangutils.datamodel.YangSchemaNode; |
| import org.onosproject.yms.app.utils.TraversalType; |
| import org.onosproject.yms.app.yab.exceptions.YabException; |
| import org.onosproject.yms.app.ydt.DefaultYdtAppContext; |
| import org.onosproject.yms.app.ydt.YangRequestWorkBench; |
| import org.onosproject.yms.app.ydt.YangResponseWorkBench; |
| import org.onosproject.yms.app.ydt.YdtAppContext; |
| import org.onosproject.yms.app.ydt.YdtExtendedContext; |
| import org.onosproject.yms.app.ydt.YdtMultiInstanceNode; |
| import org.onosproject.yms.app.ydt.YdtNode; |
| import org.onosproject.yms.app.yob.DefaultYobBuilder; |
| import org.onosproject.yms.app.ysr.YangSchemaRegistry; |
| import org.onosproject.yms.app.ytb.DefaultYangTreeBuilder; |
| import org.onosproject.yms.ydt.YdtBuilder; |
| import org.onosproject.yms.ydt.YdtContext; |
| import org.onosproject.yms.ydt.YdtResponse; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Set; |
| |
| import static com.google.common.base.Preconditions.checkNotNull; |
| import static org.onosproject.yms.app.utils.TraversalType.CHILD; |
| import static org.onosproject.yms.app.utils.TraversalType.PARENT; |
| import static org.onosproject.yms.app.utils.TraversalType.ROOT; |
| import static org.onosproject.yms.app.utils.TraversalType.SIBLING; |
| import static org.onosproject.yms.app.ydt.AppNodeFactory.getAppContext; |
| import static org.onosproject.yms.app.ydt.YdtAppNodeOperationType.DELETE_ONLY; |
| import static org.onosproject.yms.app.ydt.YdtAppNodeOperationType.OTHER_EDIT; |
| import static org.onosproject.yms.ydt.YdtContextOperationType.DELETE; |
| import static org.onosproject.yms.ydt.YmsOperationExecutionStatus.EXECUTION_SUCCESS; |
| |
| /** |
| * Represents YANG application broker. It acts as a broker between Protocol and |
| * YANG based application. |
| */ |
| public class YangApplicationBroker { |
| |
| private static final String GET = "get"; |
| private static final String SET = "set"; |
| private static final String AUGMENTED = "Augmented"; |
| private static final String VOID = "void"; |
| private final YangSchemaRegistry schemaRegistry; |
| private Set<String> augGenMethodSet; |
| |
| /** |
| * Creates a new YANG application broker. |
| * |
| * @param schemaRegistry YANG schema registry |
| */ |
| public YangApplicationBroker(YangSchemaRegistry schemaRegistry) { |
| this.schemaRegistry = schemaRegistry; |
| } |
| |
| /** |
| * Processes query request of a NBI protocol. |
| * |
| * @param ydtWorkBench YANG request work bench |
| * @return YANG response data tree node context |
| * @throws YabException violation in execution of YAB |
| */ |
| public YdtResponse processQuery(YdtBuilder ydtWorkBench) |
| throws YabException { |
| List<Object> responseObjects = new LinkedList<>(); |
| YangRequestWorkBench workBench = (YangRequestWorkBench) ydtWorkBench; |
| augGenMethodSet = ((YangRequestWorkBench) ydtWorkBench).getAugGenMethodSet(); |
| |
| for (YdtAppContext appContext = workBench.getAppRootNode().getFirstChild(); |
| appContext != null; appContext = appContext.getNextSibling()) { |
| Object responseObject = processQueryOfApplication(appContext); |
| if (responseObject != null) { |
| responseObjects.add(responseObject); |
| } |
| } |
| |
| YdtContext rootYdtContext = workBench.getRootNode(); |
| YdtBuilder responseYdt = buildResponseYdt(responseObjects, |
| rootYdtContext.getName(), |
| rootYdtContext.getNamespace()); |
| |
| return new YangResponseWorkBench(responseYdt.getRootNode(), |
| EXECUTION_SUCCESS, |
| ydtWorkBench.getYmsOperationType()); |
| } |
| |
| /** |
| * Processes edit request of a NBI protocol. |
| * |
| * @param ydtWorkBench YANG request work bench |
| * @return YANG response data tree node context |
| * @throws YabException violation in execution of YAB |
| * @throws CloneNotSupportedException clone is not supported |
| */ |
| public YdtResponse processEdit(YdtBuilder ydtWorkBench) |
| throws CloneNotSupportedException, YabException { |
| YangRequestWorkBench workBench = (YangRequestWorkBench) ydtWorkBench; |
| augGenMethodSet = ((YangRequestWorkBench) ydtWorkBench).getAugGenMethodSet(); |
| for (YdtAppContext appContext = workBench.getAppRootNode().getFirstChild(); |
| appContext != null; appContext = appContext.getNextSibling()) { |
| processEditOfApplication(appContext); |
| } |
| |
| /* |
| * Since for set operation return type is void, there will not be |
| * response ydt tree so returning null. |
| */ |
| return new YangResponseWorkBench(null, EXECUTION_SUCCESS, |
| workBench.getYmsOperationType()); |
| } |
| |
| /** |
| * Processes operation request of a NBI protocol. |
| * |
| * @param ydtWorkBench YANG request work bench |
| * @return YANG response data tree node context |
| * @throws YabException violation in execution of YAB |
| */ |
| public YdtResponse processOperation(YdtBuilder ydtWorkBench) |
| throws YabException { |
| YangRequestWorkBench workBench = (YangRequestWorkBench) ydtWorkBench; |
| YdtAppContext appContext = workBench.getAppRootNode().getFirstChild(); |
| YdtContext ydtNode = appContext.getModuleContext(); |
| while (ydtNode != null) { |
| YdtContext childYdtNode = ydtNode.getFirstChild(); |
| YangSchemaNode yangNode = ((YdtNode) childYdtNode).getYangSchemaNode(); |
| if (yangNode instanceof YangRpc) { |
| return processRpcOperationOfApplication(childYdtNode, |
| appContext, yangNode, |
| workBench); |
| } |
| ydtNode = ydtNode.getNextSibling(); |
| } |
| return new YangResponseWorkBench(null, EXECUTION_SUCCESS, |
| ydtWorkBench.getYmsOperationType()); |
| } |
| |
| /** |
| * Processes rpc request of an application. |
| * |
| * @param appContext application context |
| * @return response object from application |
| */ |
| private YdtResponse processRpcOperationOfApplication(YdtContext rpcYdt, |
| YdtAppContext appContext, |
| YangSchemaNode yangRpc, |
| YangRequestWorkBench workBench) |
| throws YabException { |
| Object inputObject = null; |
| YdtContext inputYdtNode = getInputYdtNode(rpcYdt); |
| if (inputYdtNode != null) { |
| inputObject = getYangObject(inputYdtNode); |
| } |
| |
| Object appObject = getApplicationObjectForRpc(appContext); |
| |
| String methodName = yangRpc.getJavaClassNameOrBuiltInType(); |
| Object outputObject = invokeRpcApplicationsMethod(appObject, |
| inputObject, |
| methodName); |
| |
| String returnType = getReturnTypeOfRpcResponse(appObject, |
| inputObject, yangRpc); |
| |
| if (!returnType.equals(VOID)) { |
| YdtBuilder responseYdt = buildRpcResponseYdt(outputObject, |
| workBench); |
| return new YangResponseWorkBench(responseYdt.getRootNode(), |
| EXECUTION_SUCCESS, |
| workBench.getYmsOperationType()); |
| } |
| |
| return new YangResponseWorkBench(null, EXECUTION_SUCCESS, |
| workBench.getYmsOperationType()); |
| } |
| |
| /** |
| * Processes query request of an application. |
| * |
| * @param appContext application context |
| * @return response object from application |
| */ |
| private Object processQueryOfApplication(YdtAppContext appContext) |
| throws YabException { |
| YdtContext ydtNode = appContext.getModuleContext(); |
| |
| // Update application context tree if any node is augmented |
| YangNode yangNode = (YangNode) appContext.getYangSchemaNode(); |
| if (yangNode.isDescendantNodeAugmented()) { |
| processAugmentForChildNode(appContext, yangNode); |
| } |
| |
| String appName = getCapitalCase(((YdtNode) appContext.getModuleContext()) |
| .getYangSchemaNode() |
| .getJavaClassNameOrBuiltInType()); |
| |
| // get YangObject of YdtContext from YOB |
| Object outputObject = getYangObject(ydtNode); |
| |
| TraversalType curTraversal = ROOT; |
| do { |
| if (curTraversal != PARENT) { |
| |
| // find application and get application's object using YSR |
| Object appManagerObject = getApplicationObject(appContext); |
| |
| // find which method to invoke |
| String methodName = getApplicationMethodName(appContext, |
| appName, GET); |
| |
| String moduleName = appContext.getAppData() |
| .getRootSchemaNode().getName(); |
| |
| // invoke application's getter method |
| outputObject = invokeApplicationsMethod(appManagerObject, |
| outputObject, |
| methodName, moduleName); |
| } |
| |
| /* |
| * AppContext may contain other nodes if it is augmented, so |
| * traverse the appContext tree |
| */ |
| if (curTraversal != PARENT && appContext.getFirstChild() != null) { |
| curTraversal = CHILD; |
| appContext = appContext.getFirstChild(); |
| } else if (appContext.getNextSibling() != null) { |
| curTraversal = SIBLING; |
| appContext = appContext.getNextSibling(); |
| } else { |
| curTraversal = PARENT; |
| if (appContext.getParent().getParent() != null) { |
| appContext = appContext.getParent(); |
| } |
| } |
| // no need to do any operation for logical root node |
| } while (appContext.getParent().getParent() != null); |
| return outputObject; |
| } |
| |
| /** |
| * Processes edit request of an application. |
| * |
| * @param appContext application context |
| * @throws YabException violation in execution of YAB |
| * @throws CloneNotSupportedException clone is not supported |
| */ |
| private void processEditOfApplication(YdtAppContext appContext) |
| throws CloneNotSupportedException, YabException { |
| |
| // process delete request if operation type is delete and both |
| if (appContext.getOperationType() != OTHER_EDIT) { |
| processDeleteRequestOfApplication(appContext); |
| } |
| |
| // process edit request if operation type is other edit and both |
| if (appContext.getOperationType() != DELETE_ONLY) { |
| YdtContext ydtNode = appContext.getModuleContext(); |
| |
| String appName = getCapitalCase(((YdtNode) appContext.getModuleContext()) |
| .getYangSchemaNode() |
| .getJavaClassNameOrBuiltInType()); |
| |
| // get YO from YOB |
| Object outputObject = getYangObject(ydtNode); |
| |
| TraversalType curTraversal = ROOT; |
| do { |
| if (curTraversal != PARENT) { |
| |
| // find application and get application's object using YSR |
| Object appManagerObject = getApplicationObject(appContext); |
| |
| // find which method to invoke |
| String methodName = getApplicationMethodName(appContext, |
| appName, SET); |
| |
| String moduleName = appContext.getAppData() |
| .getRootSchemaNode().getName(); |
| |
| // invoke application's setter method |
| invokeApplicationsMethod(appManagerObject, outputObject, |
| methodName, moduleName); |
| } |
| |
| /* |
| * AppContext may contain other nodes if it is augmented, |
| * so traverse the appContext tree |
| */ |
| if (curTraversal != PARENT && appContext.getFirstChild() != null) { |
| curTraversal = CHILD; |
| appContext = appContext.getFirstChild(); |
| } else if (appContext.getNextSibling() != null) { |
| curTraversal = SIBLING; |
| appContext = appContext.getNextSibling(); |
| } else { |
| curTraversal = PARENT; |
| if (appContext.getParent().getParent() != null) { |
| appContext = appContext.getParent(); |
| } |
| } |
| // no need to do any operation for logical root node |
| } while (appContext.getParent().getParent() != null); |
| } |
| } |
| |
| /** |
| * Processes delete request of an application. |
| * |
| * @param appContext application context |
| * @throws YabException violation in execution of YAB |
| * @throws CloneNotSupportedException clone is not supported |
| */ |
| private void processDeleteRequestOfApplication(YdtAppContext appContext) |
| throws CloneNotSupportedException, YabException { |
| TraversalType curTraversal = ROOT; |
| List<YdtContext> deleteNodes = appContext.getDeleteNodes(); |
| |
| if (deleteNodes != null && !deleteNodes.isEmpty()) { |
| |
| /* |
| * Split the current Ydt tree into two trees. |
| * Delete Tree with all nodes with delete operation and other |
| * tree with other edit operation |
| */ |
| YdtContext deleteTree = buildDeleteTree(deleteNodes); |
| |
| /* |
| * If any of nodes in ydt delete tree is augmented then add |
| * augmented nodes to current ydt tree |
| */ |
| processAugmentedNodesForDelete(deleteTree.getFirstChild(), appContext); |
| |
| Object inputObject = getYangObject(deleteTree.getFirstChild()); |
| |
| String appName = getCapitalCase(((YdtNode) appContext.getModuleContext()) |
| .getYangSchemaNode() |
| .getJavaClassNameOrBuiltInType()); |
| |
| do { |
| if (curTraversal == ROOT || curTraversal == SIBLING) { |
| while (appContext.getLastChild() != null) { |
| appContext = appContext.getLastChild(); |
| } |
| } |
| |
| // getAugmentApplication manager object |
| Object appManagerObject = getApplicationObject(appContext); |
| |
| // find which method to invoke |
| String methodName = getApplicationMethodName(appContext, |
| appName, SET); |
| |
| String moduleName = appContext.getAppData().getRootSchemaNode() |
| .getName(); |
| |
| // invoke application's setter method |
| invokeApplicationsMethod(appManagerObject, inputObject, |
| methodName, moduleName); |
| |
| if (appContext.getPreviousSibling() != null) { |
| curTraversal = SIBLING; |
| appContext = appContext.getPreviousSibling(); |
| } else if (appContext.getParent() != null) { |
| curTraversal = PARENT; |
| appContext = appContext.getParent(); |
| } |
| } while (appContext.getParent() != null); |
| } |
| } |
| |
| /** |
| * Traverses data model tree and if any node is augmented, then |
| * adds child to current application context. |
| * |
| * @param curAppContext current application context |
| * @param schemaNode YANG data model node, either module or augment |
| */ |
| protected void processAugmentForChildNode(YdtAppContext curAppContext, |
| YangNode schemaNode) { |
| YangNode yangNode = schemaNode.getChild(); |
| if (yangNode == null) { |
| return; |
| } |
| |
| TraversalType curTraversal = CHILD; |
| while (!yangNode.equals(schemaNode)) { |
| if (curTraversal != PARENT && yangNode instanceof YangAugmentableNode |
| && !((YangAugmentableNode) yangNode).getAugmentedInfoList() |
| .isEmpty()) { |
| updateAppTreeWithAugmentNodes(yangNode, curAppContext); |
| } |
| |
| if (curTraversal != PARENT && yangNode.getChild() != null |
| && yangNode.isDescendantNodeAugmented()) { |
| curTraversal = CHILD; |
| yangNode = yangNode.getChild(); |
| } else if (yangNode.getNextSibling() != null) { |
| curTraversal = SIBLING; |
| yangNode = yangNode.getNextSibling(); |
| } else { |
| curTraversal = PARENT; |
| yangNode = yangNode.getParent(); |
| } |
| } |
| } |
| |
| /** |
| * Traverses YDT delete tree and if any YDT node is augmented then |
| * updates the YDT delete tree with augment nodes. |
| * |
| * @param deleteTree YDT delete tree |
| * @param appContext application context |
| */ |
| protected void processAugmentedNodesForDelete(YdtContext deleteTree, |
| YdtAppContext appContext) { |
| TraversalType curTraversal = ROOT; |
| YdtContext ydtContext = deleteTree.getFirstChild(); |
| |
| if (ydtContext == null) { |
| /* |
| * Delete request is for module, so check all the nodes under |
| * module whether it is augmented. |
| */ |
| YangNode yangNode = ((YangNode) ((YdtNode) deleteTree) |
| .getYangSchemaNode()); |
| if (yangNode.isDescendantNodeAugmented()) { |
| processAugmentForChildNode(appContext, yangNode); |
| } |
| return; |
| } |
| |
| while (!ydtContext.equals(deleteTree)) { |
| if (curTraversal != PARENT && ((YdtNode) ydtContext) |
| .getYdtContextOperationType() == DELETE) { |
| YangNode yangNode = ((YangNode) ((YdtNode) ydtContext) |
| .getYangSchemaNode()); |
| if (yangNode instanceof YangAugmentableNode) { |
| updateAppTreeWithAugmentNodes(yangNode, appContext); |
| } |
| if (yangNode.isDescendantNodeAugmented()) { |
| processAugmentForChildNode(appContext, yangNode); |
| } |
| } |
| |
| if (curTraversal != PARENT && ydtContext.getFirstChild() != null) { |
| curTraversal = CHILD; |
| ydtContext = ydtContext.getFirstChild(); |
| } else if (ydtContext.getNextSibling() != null) { |
| curTraversal = SIBLING; |
| ydtContext = ydtContext.getNextSibling(); |
| } else { |
| curTraversal = PARENT; |
| ydtContext = ydtContext.getParent(); |
| } |
| } |
| } |
| |
| /** |
| * Returns response YANG data tree using YTB. |
| * |
| * @param responseObjects list of application's response objects |
| * @param name application YANG name |
| * @param namespace application YANG namespace |
| * @return response YANG data tree |
| */ |
| private YdtBuilder buildResponseYdt(List<Object> responseObjects, |
| String name, String namespace) { |
| DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder(); |
| return treeBuilder.getYdtBuilderForYo(responseObjects, |
| name, namespace, null, schemaRegistry); |
| } |
| |
| private YdtBuilder buildRpcResponseYdt(Object responseObject, |
| YangRequestWorkBench requestWorkBench) { |
| DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder(); |
| return treeBuilder.getYdtForRpcResponse(responseObject, requestWorkBench); |
| } |
| |
| /** |
| * Builds delete tree for list of delete nodes. |
| * |
| * @param deleteNodes list of delete nodes |
| * @return deleteTree YANG data tree for delete operation |
| * @throws CloneNotSupportedException clone is not supported |
| */ |
| protected YdtContext buildDeleteTree(List<YdtContext> deleteNodes) throws |
| CloneNotSupportedException { |
| Iterator<YdtContext> iterator = deleteNodes.iterator(); |
| YdtContext deleteTree = null; |
| while (iterator.hasNext()) { |
| YdtContext deleteNode = iterator.next(); |
| if (((YdtExtendedContext) deleteNode.getParent()) |
| .getYdtContextOperationType() != DELETE) { |
| cloneAncestorsOfDeleteNode(deleteNode); |
| deleteTree = unlinkDeleteNodeFromCurrentTree((YdtNode) deleteNode); |
| } |
| } |
| |
| if (deleteTree != null) { |
| while (deleteTree.getParent() != null) { |
| deleteTree = deleteTree.getParent(); |
| } |
| } |
| return deleteTree; |
| } |
| |
| /** |
| * Clones ancestor nodes of delete node. |
| * |
| * @param deleteNode node to be deleted |
| * @throws CloneNotSupportedException clone not supported |
| */ |
| private void cloneAncestorsOfDeleteNode(YdtContext deleteNode) |
| throws CloneNotSupportedException { |
| YdtNode clonedNode; |
| YdtNode previousNode = null; |
| |
| // Clone the parents of delete node to form delete tree |
| YdtNode nodeToClone = (YdtNode) deleteNode.getParent(); |
| while (nodeToClone != null) { |
| // If node is not cloned yet |
| if (nodeToClone.getClonedNode() == null) { |
| clonedNode = nodeToClone.clone(); |
| unlinkCurrentYdtNode(clonedNode); |
| if (nodeToClone instanceof YdtMultiInstanceNode) { |
| addKeyLeavesToClonedNode(nodeToClone, clonedNode); |
| } |
| nodeToClone.setClonedNode(clonedNode); |
| } else { |
| // already node is cloned |
| clonedNode = (YdtNode) nodeToClone.getClonedNode(); |
| } |
| |
| if (previousNode != null) { |
| /* |
| * add previous cloned node as child of current cloned node |
| * so that tree will be formed from delete node parent to |
| * logical root node. |
| */ |
| clonedNode.addChild(previousNode, false); |
| } |
| previousNode = clonedNode; |
| nodeToClone = nodeToClone.getParent(); |
| } |
| } |
| |
| /** |
| * Unlinks delete node from current YANG data tree of application |
| * and links it to cloned delete tree. |
| * |
| * @param deleteNode node to be unlinked |
| * @return deleteNode delete node linked to cloned delete tree |
| */ |
| private YdtNode unlinkDeleteNodeFromCurrentTree(YdtNode deleteNode) { |
| YdtNode parentClonedNode = (YdtNode) deleteNode.getParent().getClonedNode(); |
| unlinkNodeFromParent(deleteNode); |
| unlinkNodeFromSibling(deleteNode); |
| |
| /* |
| * Set all the pointers of node to null before adding as child |
| * to parent's cloned node. |
| */ |
| deleteNode.setParent(null); |
| deleteNode.setPreviousSibling(null); |
| deleteNode.setNextSibling(null); |
| |
| parentClonedNode.addChild(deleteNode, false); |
| return deleteNode; |
| } |
| |
| /** |
| * Adds key leaf nodes to cloned YDT node from current Ydt node. |
| * |
| * @param curNode current YDT node |
| * @param clonedNode cloned YDT node |
| */ |
| private void addKeyLeavesToClonedNode(YdtNode curNode, YdtNode clonedNode) |
| throws CloneNotSupportedException { |
| YdtNode keyClonedLeaf; |
| List<YdtContext> keyList = ((YdtMultiInstanceNode) curNode) |
| .getKeyNodeList(); |
| if (keyList != null && !keyList.isEmpty()) { |
| for (YdtContext keyLeaf : keyList) { |
| keyClonedLeaf = ((YdtNode) keyLeaf).clone(); |
| unlinkCurrentYdtNode(keyClonedLeaf); |
| clonedNode.addChild(keyClonedLeaf, true); |
| } |
| } |
| } |
| |
| /** |
| * Updates application context tree if any of the nodes in current |
| * application context tree is augmented. |
| * |
| * @param yangNode YANG schema node which is augmented |
| * @param curAppContext current application context tree |
| */ |
| private void updateAppTreeWithAugmentNodes(YangNode yangNode, |
| YdtAppContext curAppContext) { |
| YdtAppContext childAppContext; |
| for (YangAugment yangAugment : ((YangAugmentableNode) yangNode) |
| .getAugmentedInfoList()) { |
| Object appManagerObject = schemaRegistry |
| .getRegisteredApplication(yangAugment.getParent()); |
| if (appManagerObject != null |
| && augGenMethodSet.add(yangAugment.getSetterMethodName())) { |
| childAppContext = addChildToYdtAppTree(curAppContext, |
| yangAugment); |
| processAugmentForChildNode(childAppContext, yangAugment); |
| } |
| } |
| } |
| |
| /** |
| * Adds child node to current application context tree. |
| * |
| * @param curAppContext current application context |
| * @param augment augment data model node |
| * @return childAppContext child node added |
| */ |
| private YdtAppContext addChildToYdtAppTree(YdtAppContext curAppContext, |
| YangNode augment) { |
| DefaultYdtAppContext childAppContext = getAppContext(true); |
| childAppContext.setParent(curAppContext); |
| childAppContext.setOperationType(curAppContext.getOperationType()); |
| childAppContext.setAugmentingSchemaNode(augment); |
| curAppContext.addChild(childAppContext); |
| return childAppContext; |
| } |
| |
| /** |
| * Unlinks the current node from its parent. |
| * |
| * @param deleteNode node which should be unlinked from YDT tree |
| */ |
| private void unlinkNodeFromParent(YdtNode deleteNode) { |
| YdtNode parentNode = deleteNode.getParent(); |
| if (parentNode.getFirstChild().equals(deleteNode) |
| && parentNode.getLastChild().equals(deleteNode)) { |
| parentNode.setChild(null); |
| parentNode.setLastChild(null); |
| } else if (parentNode.getFirstChild().equals(deleteNode)) { |
| parentNode.setChild(deleteNode.getNextSibling()); |
| } else if (parentNode.getLastChild().equals(deleteNode)) { |
| parentNode.setLastChild(deleteNode.getPreviousSibling()); |
| } |
| } |
| |
| /** |
| * Unlinks the current node from its sibling. |
| * |
| * @param deleteNode node which should be unlinked from YDT tree |
| */ |
| private void unlinkNodeFromSibling(YdtNode deleteNode) { |
| YdtNode previousSibling = deleteNode.getPreviousSibling(); |
| YdtNode nextSibling = deleteNode.getNextSibling(); |
| if (nextSibling != null && previousSibling != null) { |
| previousSibling.setNextSibling(nextSibling); |
| nextSibling.setPreviousSibling(previousSibling); |
| } else if (nextSibling != null) { |
| nextSibling.setPreviousSibling(null); |
| } else if (previousSibling != null) { |
| previousSibling.setNextSibling(null); |
| } |
| } |
| |
| /** |
| * Unlinks current Ydt node from parent, sibling and child. |
| * |
| * @param ydtNode YANG data tree node |
| */ |
| private void unlinkCurrentYdtNode(YdtNode ydtNode) { |
| ydtNode.setParent(null); |
| ydtNode.setNextSibling(null); |
| ydtNode.setPreviousSibling(null); |
| ydtNode.setChild(null); |
| ydtNode.setLastChild(null); |
| } |
| |
| /** |
| * Returns YANG object for YDT node. |
| * |
| * @param ydtNode YANG data node |
| * @return YANG object for YDT node |
| */ |
| private Object getYangObject(YdtContext ydtNode) { |
| checkNotNull(ydtNode); |
| DefaultYobBuilder yobBuilder = new DefaultYobBuilder(); |
| return yobBuilder.getYangObject((YdtExtendedContext) ydtNode, |
| schemaRegistry); |
| } |
| |
| /** |
| * Returns application manager object for YDT node. |
| * |
| * @param appContext YDT application context |
| * @return application manager object |
| */ |
| private Object getApplicationObjectForRpc(YdtAppContext appContext) { |
| checkNotNull(appContext); |
| while (appContext.getFirstChild() != null) { |
| appContext = appContext.getFirstChild(); |
| } |
| return schemaRegistry.getRegisteredApplication(appContext.getAppData() |
| .getRootSchemaNode()); |
| } |
| |
| /** |
| * Returns application manager object of application. |
| * |
| * @param appContext application context |
| * @return application manager object |
| */ |
| private Object getApplicationObject(YdtAppContext appContext) { |
| return schemaRegistry.getRegisteredApplication(appContext.getAppData() |
| .getRootSchemaNode()); |
| } |
| |
| /** |
| * Converts name to capital case. |
| * |
| * @param yangIdentifier identifier |
| * @return name to capital case |
| */ |
| private String getCapitalCase(String yangIdentifier) { |
| return yangIdentifier.substring(0, 1).toUpperCase() + |
| yangIdentifier.substring(1); |
| } |
| |
| /** |
| * Returns get/set method name for application's request. |
| * |
| * @param appContext application context |
| * @return get/set method name for application's query request |
| */ |
| private String getApplicationMethodName(YdtAppContext appContext, |
| String appName, |
| String operation) { |
| if (appContext.getYangSchemaNode() instanceof YangModule) { |
| return operation + appName; |
| } |
| |
| String augment = ((YangAugment) appContext |
| .getAugmentingSchemaNode()).getTargetNode().get(0) |
| .getResolvedNode().getJavaClassNameOrBuiltInType(); |
| return new StringBuilder().append(operation).append(AUGMENTED) |
| .append(appName).append(getCapitalCase(augment)).toString(); |
| } |
| |
| /** |
| * Returns rpc's input schema node. |
| * |
| * @param rpcNode rpc schema node |
| * @return rpc's input YDT node |
| */ |
| private YdtContext getInputYdtNode(YdtContext rpcNode) { |
| YdtContext inputNode = rpcNode.getFirstChild(); |
| while (inputNode != null) { |
| YangSchemaNode yangInputNode = ((YdtNode) inputNode) |
| .getYangSchemaNode(); |
| if (yangInputNode instanceof YangInput) { |
| return inputNode; |
| } |
| inputNode = rpcNode.getNextSibling(); |
| } |
| return null; |
| } |
| |
| /** |
| * Invokes application method for RPC request. |
| * |
| * @param appManagerObject application manager object |
| * @param inputObject input parameter object of method |
| * @param methodName method name which should be invoked |
| * @return response object from application |
| * @throws YabException violation in execution of YAB |
| */ |
| private Object invokeApplicationsMethod(Object appManagerObject, |
| Object inputObject, |
| String methodName, String appName) |
| throws YabException { |
| checkNotNull(appManagerObject); |
| Class<?> appClass = appManagerObject.getClass(); |
| try { |
| Method methodObject = appClass.getDeclaredMethod(methodName, |
| inputObject.getClass()); |
| if (methodObject != null) { |
| return methodObject.invoke(appManagerObject, inputObject); |
| } |
| throw new YabException("No such method in application"); |
| } catch (IllegalAccessException | NoSuchMethodException e) { |
| throw new YabException(e); |
| } catch (InvocationTargetException e) { |
| throw new YabException("Invocation exception in service " + appName, |
| e.getCause()); |
| } |
| } |
| |
| /** |
| * Invokes application method for RPC request. |
| * |
| * @param appObject application manager object |
| * @param inputObject input parameter object of method |
| * @param yangNode method name which should be invoked |
| * @return response object from application |
| * @throws YabException violation in execution of YAB |
| */ |
| private String getReturnTypeOfRpcResponse(Object appObject, |
| Object inputObject, YangSchemaNode |
| yangNode) throws YabException { |
| Method methodObject = null; |
| try { |
| if (inputObject == null) { |
| methodObject = appObject.getClass() |
| .getDeclaredMethod(yangNode.getJavaClassNameOrBuiltInType(), |
| null); |
| } else { |
| methodObject = appObject.getClass() |
| .getDeclaredMethod(yangNode.getJavaClassNameOrBuiltInType(), |
| inputObject.getClass().getInterfaces()); |
| } |
| if (methodObject != null) { |
| return methodObject.getReturnType().getSimpleName(); |
| } |
| throw new YabException("No such method in application"); |
| } catch (NoSuchMethodException e) { |
| throw new YabException(e); |
| } |
| } |
| |
| /** |
| * Invokes application method for RPC request. |
| * |
| * @param appManagerObject application manager object |
| * @param inputParamObject input parameter object of method |
| * @param methodName method name which should be invoked |
| * @return response object from application |
| * @throws YabException violation in execution of YAB |
| */ |
| private Object invokeRpcApplicationsMethod(Object appManagerObject, |
| Object inputParamObject, |
| String methodName) throws YabException { |
| checkNotNull(appManagerObject); |
| Class<?> appClass = appManagerObject.getClass(); |
| try { |
| Method methodObject; |
| if (inputParamObject == null) { |
| methodObject = appClass.getDeclaredMethod(methodName, null); |
| if (methodObject != null) { |
| return methodObject.invoke(appManagerObject); |
| } |
| } else { |
| methodObject = appClass.getDeclaredMethod(methodName, |
| inputParamObject |
| .getClass() |
| .getInterfaces()); |
| if (methodObject != null) { |
| return methodObject.invoke(appManagerObject, inputParamObject); |
| } |
| } |
| throw new YabException("No such method in application"); |
| } catch (IllegalAccessException | NoSuchMethodException | |
| InvocationTargetException e) { |
| throw new YabException(e); |
| } |
| } |
| |
| /** |
| * Sets the augment setter method name. |
| * |
| * @param augGenMethodSet augment setter method name |
| */ |
| public void setAugGenMethodSet(Set<String> augGenMethodSet) { |
| this.augGenMethodSet = augGenMethodSet; |
| } |
| } |