| /* |
| * 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.ych; |
| |
| import org.onosproject.yangutils.datamodel.YangSchemaNode; |
| import org.onosproject.yangutils.datamodel.YangSchemaNodeContextInfo; |
| import org.onosproject.yangutils.datamodel.YangSchemaNodeIdentifier; |
| import org.onosproject.yangutils.datamodel.exceptions.DataModelException; |
| import org.onosproject.yms.app.ych.defaultcodecs.YangCodecRegistry; |
| import org.onosproject.yms.app.ydt.YdtExtendedBuilder; |
| import org.onosproject.yms.app.ydt.YdtExtendedContext; |
| 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.app.ytb.YtbException; |
| import org.onosproject.yms.ych.YangCodecHandler; |
| import org.onosproject.yms.ych.YangCompositeEncoding; |
| import org.onosproject.yms.ych.YangDataTreeCodec; |
| import org.onosproject.yms.ych.YangProtocolEncodingFormat; |
| import org.onosproject.yms.ydt.YdtBuilder; |
| import org.onosproject.yms.ydt.YdtContext; |
| import org.onosproject.yms.ydt.YmsOperationType; |
| import org.onosproject.yms.ysr.YangModuleLibrary; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import static org.onosproject.yms.app.yob.YobUtils.createAndSetInEventInstance; |
| import static org.onosproject.yms.app.yob.YobUtils.createAndSetInEventSubjectInstance; |
| |
| /** |
| * Represents implementation of YANG SBI broker interfaces. |
| * YCH acts as a broker between YMS and driver/provider. |
| */ |
| public class DefaultYangCodecHandler implements YangCodecHandler { |
| |
| private static final String E_MODULE_LIST = "The input module or " + |
| "sub-module object list cannot be null."; |
| private static final String E_DATA_TREE_CODEC = "data tree codec handler" + |
| " is null."; |
| private static final String E_DATA_MODEL_CHILD = "Unable to find the " + |
| "child node"; |
| private static final String E_NOTIFICATION_NODE = "Notification node " + |
| "should be the first child of module in YDT"; |
| |
| /** |
| * Schema registry for driver. |
| */ |
| private final YangSchemaRegistry schemaRegistry; |
| private YangModuleLibrary library; |
| |
| /** |
| * Default codecs. |
| */ |
| private final Map<YangProtocolEncodingFormat, YangDataTreeCodec> |
| defaultCodecs = new HashMap<>(); |
| |
| /** |
| * Override codec handler. |
| */ |
| private final Map<YangProtocolEncodingFormat, YangDataTreeCodec> |
| overrideCodecs = new HashMap<>(); |
| |
| /** |
| * Creates a new YANG codec handler. |
| * |
| * @param registry YANG schema registry |
| */ |
| public DefaultYangCodecHandler(YangSchemaRegistry registry) { |
| schemaRegistry = registry; |
| |
| // update the default codecs from codec registry |
| Map<YangProtocolEncodingFormat, YangDataTreeCodec> recvCodec = |
| YangCodecRegistry.getDefaultCodecs(); |
| if (!recvCodec.isEmpty()) { |
| for (Map.Entry<YangProtocolEncodingFormat, YangDataTreeCodec> |
| codecEntry : recvCodec.entrySet()) { |
| defaultCodecs.put(codecEntry.getKey(), codecEntry.getValue()); |
| } |
| } |
| } |
| |
| private YangDataTreeCodec getAppropriateCodec( |
| YangProtocolEncodingFormat dataFormat) { |
| YangDataTreeCodec codec = defaultCodecs.get(dataFormat); |
| |
| int size = overrideCodecs.size(); |
| // Check over ridden codec handler is exist or not. |
| if (size != 0) { |
| YangDataTreeCodec overrideCodec = overrideCodecs.get(dataFormat); |
| if (overrideCodec != null) { |
| codec = overrideCodec; |
| } |
| } |
| return codec; |
| } |
| |
| @Override |
| public void addDeviceSchema(Class<?> yangModule) { |
| schemaRegistry.registerApplication(null, yangModule); |
| schemaRegistry.processModuleLibrary(yangModule.getName(), library); |
| } |
| |
| @Override |
| public String encodeOperation(String rootName, |
| String rootNamespace, |
| Map<String, String> tagAttrMap, |
| List<Object> moduleList, |
| YangProtocolEncodingFormat dataFormat, |
| YmsOperationType opType) { |
| |
| if (moduleList == null || moduleList.isEmpty()) { |
| throw new YchException(E_MODULE_LIST); |
| } |
| |
| // Get the default codec handler. |
| YangDataTreeCodec codec = getAppropriateCodec(dataFormat); |
| if (codec == null) { |
| throw new YchException(E_DATA_TREE_CODEC); |
| } |
| |
| // Get yang data tree from YTB for the received objects. |
| DefaultYangTreeBuilder builder = new DefaultYangTreeBuilder(); |
| YdtExtendedBuilder encodedYdt = |
| builder.getYdtBuilderForYo(moduleList, rootName, |
| rootNamespace, opType, |
| schemaRegistry); |
| |
| encodedYdt.setRootTagAttributeMap(tagAttrMap); |
| |
| // Get the xml string form codec handler. |
| return codec.encodeYdtToProtocolFormat(encodedYdt); |
| } |
| |
| @Override |
| public YangCompositeEncoding encodeCompositeOperation( |
| String rootName, |
| String rootNamespace, |
| Object moduleObject, |
| YangProtocolEncodingFormat dataFormat, |
| YmsOperationType opType) { |
| |
| if (moduleObject == null) { |
| throw new YtbException(E_MODULE_LIST); |
| } |
| |
| // Get the default codec handler. |
| YangDataTreeCodec codec = getAppropriateCodec(dataFormat); |
| if (codec == null) { |
| throw new YchException(E_DATA_TREE_CODEC); |
| } |
| |
| List<Object> yangModuleList = new ArrayList<>(); |
| yangModuleList.add(moduleObject); |
| |
| // Get yang data tree from YTB for the received objects. |
| DefaultYangTreeBuilder builder = new DefaultYangTreeBuilder(); |
| YdtExtendedBuilder extBuilder = |
| builder.getYdtBuilderForYo(yangModuleList, |
| rootName, |
| rootNamespace, |
| opType, |
| schemaRegistry); |
| |
| // Get the composite response from codec handler. |
| return codec.encodeYdtToCompositeProtocolFormat(extBuilder); |
| } |
| |
| @Override |
| public List<Object> decode(String inputString, |
| YangProtocolEncodingFormat dataFormat, |
| YmsOperationType opType) { |
| |
| YdtBuilder ydtBuilder; |
| YangDataTreeCodec codec = getAppropriateCodec(dataFormat); |
| if (codec == null) { |
| throw new YchException(E_DATA_TREE_CODEC); |
| } |
| |
| try { |
| // Get the YANG data tree |
| ydtBuilder = codec.decodeProtocolDataToYdt(inputString, |
| schemaRegistry, |
| opType); |
| } catch (Exception e) { |
| throw new YchException(e.getLocalizedMessage()); |
| } |
| |
| if (ydtBuilder != null) { |
| return getObjectList(ydtBuilder.getRootNode()); |
| } |
| return null; |
| } |
| |
| @Override |
| public Object decode(YangCompositeEncoding protoData, |
| YangProtocolEncodingFormat dataFormat, |
| YmsOperationType opType) { |
| |
| YangDataTreeCodec codec = getAppropriateCodec(dataFormat); |
| if (codec == null) { |
| throw new YchException(E_DATA_TREE_CODEC); |
| } |
| |
| YdtBuilder ydtBuilder = |
| codec.decodeCompositeProtocolDataToYdt(protoData, |
| schemaRegistry, |
| opType); |
| |
| if (ydtBuilder == null) { |
| return null; |
| } |
| |
| YdtExtendedContext rootNode = ((YdtExtendedContext) ydtBuilder |
| .getRootNode()); |
| |
| if (opType == YmsOperationType.NOTIFICATION) { |
| return getNotificationObject(((YdtExtendedContext) rootNode |
| .getFirstChild())); |
| } |
| |
| // Return the module object by using YANG data tree |
| return getObjectList(rootNode); |
| } |
| |
| //returns notification event object |
| private Object getNotificationObject(YdtExtendedContext rootNode) { |
| YangSchemaNode module = rootNode.getYangSchemaNode(); |
| YangSchemaNode childSchema = ((YdtExtendedContext) rootNode |
| .getFirstChild()).getYangSchemaNode(); |
| |
| YangSchemaNodeIdentifier id = new YangSchemaNodeIdentifier(); |
| id.setNameSpace(childSchema.getNameSpace()); |
| id.setName(childSchema.getName()); |
| |
| YangSchemaNodeContextInfo contextInfo; |
| try { |
| contextInfo = module.getChildSchema(id); |
| } catch (DataModelException e) { |
| throw new YchException(E_DATA_MODEL_CHILD); |
| } |
| |
| if (contextInfo == null) { |
| throw new YchException(E_NOTIFICATION_NODE); |
| } |
| |
| DefaultYobBuilder builder = new DefaultYobBuilder(); |
| Object object = builder.getYangObject(((YdtExtendedContext) rootNode |
| .getFirstChild()), |
| schemaRegistry); |
| |
| Object eventSubObj = createAndSetInEventSubjectInstance(object, |
| rootNode, |
| schemaRegistry); |
| return createAndSetInEventInstance(eventSubObj, rootNode, |
| schemaRegistry); |
| } |
| |
| @Override |
| public void registerOverriddenCodec(YangDataTreeCodec overrideCodec, |
| YangProtocolEncodingFormat dataFormat) { |
| overrideCodecs.put(dataFormat, overrideCodec); |
| } |
| |
| /** |
| * Returns the list of objects from YDT data tree. |
| * |
| * @param rootNode YDT root node |
| * @return returns list of objects |
| */ |
| private List<Object> getObjectList(YdtContext rootNode) { |
| |
| if (rootNode == null) { |
| // TODO |
| return null; |
| } |
| |
| if (rootNode.getFirstChild() == null) { |
| // TODO |
| return null; |
| } |
| |
| YdtContext curNode = rootNode.getFirstChild(); |
| DefaultYobBuilder builder = new DefaultYobBuilder(); |
| Object object = builder.getYangObject((YdtExtendedContext) curNode, |
| schemaRegistry); |
| List<Object> objectList = new ArrayList<>(); |
| objectList.add(object); |
| |
| // Check next module is exit or not. If exist get the object for that. |
| while (curNode.getNextSibling() != null) { |
| curNode = curNode.getNextSibling(); |
| object = builder.getYangObject((YdtExtendedContext) curNode, |
| schemaRegistry); |
| objectList.add(object); |
| } |
| |
| return objectList; |
| } |
| |
| /** |
| * Returns module library for YSR. |
| * |
| * @return module library for YSR |
| */ |
| public YangModuleLibrary getLibrary() { |
| return library; |
| } |
| |
| /** |
| * Sets module library for YSR. |
| * |
| * @param library module library for YSR |
| */ |
| public void setLibrary(YangModuleLibrary library) { |
| this.library = library; |
| } |
| } |