From 1856ed92b6e768219272dbc88a560faaf4afc78f Mon Sep 17 00:00:00 2001 From: Hesam Rahimi Date: Thu, 27 Oct 2016 18:46:42 -0400 Subject: [PATCH] Adding code in order to register the default codec with YMS in restconf client. Change-Id: Id7fd2af7b1a4b4ae58aca9e75084c223045c6953 --- protocols/restconf/client/ctl/BUCK | 2 + protocols/restconf/client/ctl/pom.xml | 11 ++ .../protocol/restconf/ctl/JsonYdtCodec.java | 123 ++++++++++++++++++ .../ctl/RestConfSBControllerImpl.java | 12 ++ 4 files changed, 148 insertions(+) create mode 100644 protocols/restconf/client/ctl/src/main/java/org/onosproject/protocol/restconf/ctl/JsonYdtCodec.java diff --git a/protocols/restconf/client/ctl/BUCK b/protocols/restconf/client/ctl/BUCK index ce0292e783..0a78565ad3 100644 --- a/protocols/restconf/client/ctl/BUCK +++ b/protocols/restconf/client/ctl/BUCK @@ -11,6 +11,8 @@ COMPILE_DEPS = [ '//lib:javax.inject', '//protocols/restconf/client/api:onos-protocols-restconf-client-api', '//protocols/rest/api:onos-protocols-rest-api', + '//apps/yms/api:onos-apps-yms-api', + '//protocols/restconf/server/utils:onos-protocols-restconf-server-utils', ] osgi_jar_with_tests ( diff --git a/protocols/restconf/client/ctl/pom.xml b/protocols/restconf/client/ctl/pom.xml index 68781514c8..d33c967606 100644 --- a/protocols/restconf/client/ctl/pom.xml +++ b/protocols/restconf/client/ctl/pom.xml @@ -67,6 +67,17 @@ ${project.version} bundle + + org.onosproject + onos-restconf-server-utils + ${project.version} + + + org.onosproject + onos-app-yms-api + ${project.version} + bundle + diff --git a/protocols/restconf/client/ctl/src/main/java/org/onosproject/protocol/restconf/ctl/JsonYdtCodec.java b/protocols/restconf/client/ctl/src/main/java/org/onosproject/protocol/restconf/ctl/JsonYdtCodec.java new file mode 100644 index 0000000000..2b900a63a2 --- /dev/null +++ b/protocols/restconf/client/ctl/src/main/java/org/onosproject/protocol/restconf/ctl/JsonYdtCodec.java @@ -0,0 +1,123 @@ +/* + * Copyright 2016 Open Networking Laboratory + * + * 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.protocol.restconf.ctl; + +import static org.onosproject.yms.ydt.YdtContextOperationType.NONE; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.io.IOUtils; +import org.onosproject.protocol.restconf.server.utils.parser.json.ParserUtils; +import org.onosproject.yms.ych.YangCompositeEncoding; +import org.onosproject.yms.ych.YangDataTreeCodec; +import org.onosproject.yms.ydt.YdtBuilder; +import org.onosproject.yms.ydt.YmsOperationType; +import org.onosproject.yms.ymsm.YmsService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + + +/** + * JSON/YDT Codec implementation. + */ +public class JsonYdtCodec implements YangDataTreeCodec { + private static final String RESTCONF_ROOT = "restconf/data"; + + protected final YmsService ymsService; + + private final Logger log = LoggerFactory.getLogger(getClass()); + + public JsonYdtCodec(YmsService service) { + ymsService = service; + } + + @Override + public String encodeYdtToProtocolFormat(YdtBuilder builder, + YmsOperationType protocolOperation) { + String json = ParserUtils.convertYdtToJson(builder.getRootNode().getName(), + builder.getRootNode(), + ymsService.getYdtWalker()) + .textValue(); + return json; + } + + @Override + public YangCompositeEncoding encodeYdtToCompositeProtocolFormat(YdtBuilder builder, + YmsOperationType protocolOperation) { + // Mainly for POST/PUT operation. + // YdtBuilder/YdtContext has YdtContextType NONE for URI, + // YdtContextType CREATE/MERGE/REPLACE for Resource data. + + // TODO: Implement this method in Release Ibis for TE Tunnel. + + return null; + } + + @Override + public YdtBuilder decodeProtocolDataToYdt(String protocolData, + Object schemaRegistryForYdt, + YmsOperationType opType) { + // Get a new builder + YdtBuilder builder = ymsService.getYdtBuilder(RESTCONF_ROOT, + null, + opType, + schemaRegistryForYdt); + ParserUtils.convertJsonToYdt(getObjectNode(protocolData), builder); + return builder; + } + + @Override + public YdtBuilder decodeCompositeProtocolDataToYdt(YangCompositeEncoding protocolData, + Object schemaRegistryForYdt, + YmsOperationType opType) { + // opType should be QUERY_REPLY + // Get a new builder + YdtBuilder builder = ymsService.getYdtBuilder(RESTCONF_ROOT, + null, + opType, + schemaRegistryForYdt); + // Convert the URI to ydtBuilder + + // YdtContextOperationType should be NONE for URI in QUERY_RESPONSE. + ParserUtils.convertUriToYdt(protocolData.getResourceIdentifier(), builder, NONE); + // Set default operation type for the payload node, is this for resource data? + // NULL/EMPTY for Resource data + builder.setDefaultEditOperationType(null); + + // Convert the payload json body to ydt + ParserUtils.convertJsonToYdt(getObjectNode(protocolData.getResourceInformation()), builder); + return builder; + } + + // Returns an ObjectNode from s JSON string. + private ObjectNode getObjectNode(String json) { + InputStream stream = IOUtils.toInputStream(json); + + ObjectNode rootNode; + ObjectMapper mapper = new ObjectMapper(); + try { + rootNode = (ObjectNode) mapper.readTree(stream); + } catch (IOException e) { + log.error("Can't read stream as a JSON ObjectNode: {}", e); + return null; + } + return rootNode; + } +} diff --git a/protocols/restconf/client/ctl/src/main/java/org/onosproject/protocol/restconf/ctl/RestConfSBControllerImpl.java b/protocols/restconf/client/ctl/src/main/java/org/onosproject/protocol/restconf/ctl/RestConfSBControllerImpl.java index ab6c919f09..39347dedf2 100644 --- a/protocols/restconf/client/ctl/src/main/java/org/onosproject/protocol/restconf/ctl/RestConfSBControllerImpl.java +++ b/protocols/restconf/client/ctl/src/main/java/org/onosproject/protocol/restconf/ctl/RestConfSBControllerImpl.java @@ -28,6 +28,8 @@ import javax.ws.rs.core.Response; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; import org.apache.felix.scr.annotations.Service; import org.glassfish.jersey.client.ChunkedInput; import org.onlab.packet.IpAddress; @@ -36,6 +38,8 @@ import org.onosproject.protocol.http.ctl.HttpSBControllerImpl; import org.onosproject.protocol.rest.RestSBDevice; import org.onosproject.protocol.restconf.RestConfNotificationEventListener; import org.onosproject.protocol.restconf.RestConfSBController; +import org.onosproject.yms.ych.YangProtocolEncodingFormat; +import org.onosproject.yms.ymsm.YmsService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -62,11 +66,19 @@ public class RestConfSBControllerImpl extends HttpSBControllerImpl restconfNotificationListenerMap = new ConcurrentHashMap<>(); private Map runnableTable = new ConcurrentHashMap<>(); + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected YmsService ymsService; + ExecutorService executor = Executors.newCachedThreadPool(); @Activate public void activate() { log.info("RESTCONF SBI Started"); + if (ymsService != null) { + ymsService + .registerDefaultCodec(new JsonYdtCodec(ymsService), + YangProtocolEncodingFormat.JSON_ENCODING); + } } @Deactivate