summaryrefslogtreecommitdiffstats
path: root/plugins/restconf-client/provider/src/main/java
diff options
context:
space:
mode:
authorJessica Wagantall <jwagantall@linuxfoundation.org>2020-12-01 11:33:35 -0800
committerJessica Wagantall <jwagantall@linuxfoundation.org>2020-12-01 11:33:35 -0800
commit96a9aafdff7813324bc8a8ba1e743683e251dde6 (patch)
tree644c6837ab58ed21fb05f4bf988dc392875b9f8d /plugins/restconf-client/provider/src/main/java
parenta0e97e71a49a8b54fddf8fb004b32f202f114011 (diff)
Migrate files from sli-plugins
Migrate sli-plugins repo into new directory "plugins". Signed-off-by: Jessica Wagantall <jwagantall@linuxfoundation.org>
Diffstat (limited to 'plugins/restconf-client/provider/src/main/java')
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiCallNode.java484
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiUtils.java265
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/AdditionalHeaderWebTarget.java166
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/EventHandler.java46
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/EventProcessor.java76
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/RestconfDiscoveryNode.java310
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/SubscriptionInfo.java122
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/SvcLogicDiscoveryPlugin.java110
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/SvcLogicGraphInfo.java178
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/Annotation.java66
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormat.java37
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatSerializer.java94
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatSerializerContext.java104
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultJsonListener.java145
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultJsonWalker.java141
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultXmlListener.java120
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultXmlWalker.java48
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DfListenerFactory.java87
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DfSerializerFactory.java87
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DfSerializerUtil.java231
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/JsonListener.java55
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/JsonSerializer.java91
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/JsonWalker.java44
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/Listener.java34
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/MdsalSerializerHelper.java297
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/PropertiesNodeJsonListener.java233
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/PropertiesNodeXmlListener.java246
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/SerializerHelper.java116
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/XmlListener.java53
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/XmlNodeType.java37
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/XmlSerializer.java104
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/XmlWalker.java44
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/YangParameters.java42
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/DataNodeChild.java27
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/DefaultPropertiesNodeListener.java105
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/DefaultPropertiesNodeWalker.java119
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/HolderNode.java59
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/InnerNode.java215
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafListHolderChild.java28
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafListHolderNode.java93
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafNode.java122
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/ListHolderChild.java28
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/ListHolderNode.java73
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java227
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeUtils.java578
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MultiInstanceNode.java32
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/Namespace.java100
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/NodeChild.java28
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/NodeType.java34
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesNode.java280
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesNodeListener.java61
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesNodeSerializer.java112
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesNodeWalker.java38
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/RootNode.java212
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/SchemaPathHolder.java77
-rw-r--r--plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/SingleInstanceNode.java33
56 files changed, 6994 insertions, 0 deletions
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiCallNode.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiCallNode.java
new file mode 100644
index 000000000..620df282f
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiCallNode.java
@@ -0,0 +1,484 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.restconfapicall;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.gson.stream.JsonWriter;
+
+import javax.ws.rs.core.UriBuilder;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.net.SocketException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.DocumentHelper;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+import org.onap.ccsdk.sli.plugins.restapicall.Format;
+import org.onap.ccsdk.sli.plugins.restapicall.HttpResponse;
+import org.onap.ccsdk.sli.plugins.restapicall.RestapiCallNode;
+import org.onap.ccsdk.sli.plugins.restapicall.XmlParser;
+import org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatSerializer;
+import org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatSerializerContext;
+import org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerFactory;
+import org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.Listener;
+import org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.MdsalSerializerHelper;
+import org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.SerializerHelper;
+import org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.YangParameters;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeSerializer;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.Namespace;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNodeSerializer;
+import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
+import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.google.common.base.Strings.repeat;
+import static java.lang.String.format;
+import static java.lang.String.valueOf;
+import static org.apache.commons.lang3.StringUtils.join;
+import static org.onap.ccsdk.sli.plugins.restapicall.HttpMethod.DELETE;
+import static org.onap.ccsdk.sli.plugins.restapicall.HttpMethod.GET;
+import static org.onap.ccsdk.sli.plugins.restapicall.HttpMethod.PATCH;
+import static org.onap.ccsdk.sli.plugins.restapicall.HttpMethod.PUT;
+import static org.onap.ccsdk.sli.plugins.restapicall.RestapiCallNode.parseParam;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.ATTEMPTS_MSG;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.COLON;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.COMMA;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.COMM_FAIL;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.HEADER;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.HTTP_REQ;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.HTTP_RES;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.MAX_RETRY_ERR;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.NO_MORE_RETRY;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.REQ_ERR;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.REST_API_URL;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.RES_CODE;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.RES_MSG;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.RES_PRE;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.RETRY_COUNT;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.RETRY_FAIL;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.UPDATED_URL;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.getSchemaCtxFromDir;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.getUpdatedXmlReq;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.getYangParameters;
+import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.parseUrl;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfListenerFactory.instance;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.FORMAT_ERR;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.UTF_HEADER;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.XML_TREE_ERR;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.getXmlWriter;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getModuleNamespace;
+import static org.osgi.framework.FrameworkUtil.getBundle;
+
+/**
+ * Representation of a plugin to enable RESTCONF based CRUD operations from DG.
+ */
+public class RestconfApiCallNode implements SvcLogicJavaPlugin {
+
+ /**
+ * Logger for the restconf api call node class.
+ */
+ private static final Logger log = LoggerFactory.getLogger(
+ RestconfApiCallNode.class);
+
+ /**
+ * Rest api call node service instance
+ */
+ private RestapiCallNode restapiCallNode;
+
+ /**
+ * Creates an instance of restconf api call node with restapi call node.
+ *
+ * @param r restapi call node
+ */
+ public RestconfApiCallNode(RestapiCallNode r) {
+ this.restapiCallNode = r;
+ }
+
+ /**
+ * Returns the restapi call node instance.
+ * @return
+ */
+ public RestapiCallNode getRestapiCallNode() {
+ return restapiCallNode;
+ }
+
+ /**
+ * Sends the restconf request using the parameters map and the memory
+ * context. And this method allows the directed graphs to interact with
+ * the restconf api call node
+ *
+ * @param paramMap parameters map
+ * @param ctx service logic context
+ * @throws SvcLogicException when svc logic exception occurs
+ */
+ public void sendRequest(Map<String, String> paramMap, SvcLogicContext ctx)
+ throws SvcLogicException {
+ sendRequest(paramMap, ctx, 0);
+ }
+
+ /**
+ * Sends the restconf request using the parameters map and the memory
+ * context along with the retry count.
+ *
+ * @param paramMap parameters map
+ * @param ctx service logic context
+ * @param retryCount number of retry counts
+ * @throws SvcLogicException when svc logic exception occurs
+ */
+ public void sendRequest(Map<String, String> paramMap, SvcLogicContext ctx,
+ Integer retryCount) throws SvcLogicException {
+ RestapiCallNode rest = getRestapiCallNode();
+ HttpResponse r = new HttpResponse();
+ try {
+ YangParameters p = getYangParameters(paramMap);
+
+ String pp = p.responsePrefix != null ? p.responsePrefix + '.' : "";
+ Map<String, String> props = new HashMap<>((Map)ctx.toProperties());
+ String uri = parseUrl(p.restapiUrl, p.httpMethod);
+ InstanceIdentifierContext<?> insIdCtx = getInsIdCtx(p, uri);
+
+ String req = null;
+ if (p.httpMethod != GET && p.httpMethod != DELETE) {
+ req = serializeRequest(props, p, uri, insIdCtx);
+ if (p.httpMethod == PUT || p.httpMethod == PATCH) {
+ updateReq(req, p, insIdCtx);
+ }
+ }
+ if (req == null && p.requestBody != null) {
+ req = p.requestBody;
+ }
+
+ r = rest.sendHttpRequest(req, p);
+ if (p.returnRequestPayload && req != null) {
+ ctx.setAttribute(pp + HTTP_REQ, req);
+ }
+
+ String response = getResponse(ctx, p, pp, r);
+ if (response != null) {
+ try {
+ Map<String, String> resProp = serializeResponse(
+ p, uri, response, insIdCtx);
+ for (Map.Entry<String, String> pro : resProp.entrySet()) {
+ ctx.setAttribute(pro.getKey(), pro.getValue());
+ }
+ } catch (SvcLogicException e) {
+ convertToNormalRes(ctx, p, pp, response);
+ }
+ }
+ } catch (SvcLogicException e) {
+ boolean shouldRetry = false;
+ if (e.getCause().getCause() instanceof SocketException) {
+ shouldRetry = true;
+ }
+
+ log.error(REQ_ERR + e.getMessage(), e);
+ String prefix = parseParam(paramMap, RES_PRE, false, null);
+ setFailureResponseStatus(ctx, prefix, e.getMessage());
+ }
+
+ if (r != null && r.code >= 300) {
+ throw new SvcLogicException(valueOf(r.code) +
+ COLON + " " + r.message);
+ }
+ }
+
+ private void convertToNormalRes(SvcLogicContext ctx ,
+ YangParameters p, String pp, String body)
+ throws SvcLogicException {
+ if (p.convertResponse) {
+ Map<String, String> mm = null;
+ if (p.format == Format.XML) {
+ mm = XmlParser.convertToProperties(body, p.listNameList);
+ } else if (p.format == Format.JSON) {
+ mm = org.onap.ccsdk.sli.plugins.restapicall.JsonParser
+ .convertToProperties(body);
+ }
+
+ if (mm != null) {
+ for (Map.Entry<String, String> entry : mm.entrySet()) {
+ ctx.setAttribute(pp + entry.getKey(),
+ entry.getValue());
+ }
+ }
+ }
+ }
+
+ /**
+ * Serializes the request message to JSON or XML from the properties.
+ *
+ * @param properties properties
+ * @param params YANG parameters
+ * @param uri URI
+ * @param insIdCtx instance identifier context
+ * @return JSON or XML message to be sent
+ * @throws SvcLogicException when serializing the request fails
+ */
+ public String serializeRequest(Map<String, String> properties,
+ YangParameters params, String uri,
+ InstanceIdentifierContext insIdCtx)
+ throws SvcLogicException {
+ PropertiesNodeSerializer propSer = new MdsalPropertiesNodeSerializer(
+ insIdCtx.getSchemaNode(), insIdCtx.getSchemaContext(), uri);
+ DataFormatSerializerContext serCtx = new DataFormatSerializerContext(
+ null, uri, null, propSer);
+ DataFormatSerializer ser = DfSerializerFactory.instance()
+ .getSerializer(serCtx, params);
+ //TODO: Handling of XML annotations
+ return ser.encode(properties, null);
+ }
+
+ /**
+ * Serializes the response message from JSON or XML to the properties.
+ *
+ * @param params YANG parameters
+ * @param uri URI
+ * @param response response message
+ * @param insIdCtx instance identifier context
+ * @return response message as properties
+ * @throws SvcLogicException when serializing the response fails
+ */
+ public Map<String, String> serializeResponse(YangParameters params,
+ String uri, String response,
+ InstanceIdentifierContext insIdCtx)
+ throws SvcLogicException {
+ PropertiesNodeSerializer propSer = new MdsalPropertiesNodeSerializer(
+ insIdCtx.getSchemaNode(), insIdCtx.getSchemaContext(), uri);
+ SerializerHelper helper = new MdsalSerializerHelper(
+ insIdCtx.getSchemaNode(), insIdCtx.getSchemaContext(), uri);
+ Listener listener = instance().getListener(helper, params);
+ DataFormatSerializerContext serCtx = new DataFormatSerializerContext(
+ listener, uri, null, propSer);
+ DataFormatSerializer ser = DfSerializerFactory.instance()
+ .getSerializer(serCtx, params);
+ return ser.decode(response);
+ }
+
+ /**
+ * Returns instance identifier context for a uri using the schema context.
+ *
+ * @param params YANG parameters
+ * @param uri URI
+ * @return instance identifier context
+ * @throws SvcLogicException when getting schema context fails
+ */
+ private InstanceIdentifierContext<?> getInsIdCtx(YangParameters params,
+ String uri)
+ throws SvcLogicException {
+ SchemaContext context = getSchemaContext(params);
+ return ParserIdentifier.toInstanceIdentifier(uri, context, null);
+ }
+
+ /**
+ * Returns the global schema context or schema context of particular YANG
+ * files present in a directory path.
+ *
+ * @param params YANG parameters
+ * @return schema context
+ * @throws SvcLogicException when schema context fetching fails
+ */
+ private SchemaContext getSchemaContext(YangParameters params)
+ throws SvcLogicException {
+ if (params.dirPath != null) {
+ return getSchemaCtxFromDir(params.dirPath);
+ }
+ BundleContext bc = getBundle(SchemaContext.class).getBundleContext();
+ SchemaContext schemaContext = null;
+ if (bc != null) {
+ ServiceReference reference = bc.getServiceReference(
+ SchemaContext.class);
+ if (reference != null) {
+ schemaContext = (SchemaContext) bc.getService(reference);
+ }
+ }
+ return schemaContext;
+ }
+
+ /**
+ * Returns the response message body of a http response message.
+ *
+ * @param ctx svc logic context
+ * @param params parameters
+ * @param pre prefix to be appended
+ * @param res http response
+ * @return response message body
+ */
+ public String getResponse(SvcLogicContext ctx, YangParameters params,
+ String pre, HttpResponse res) {
+ ctx.setAttribute(pre + RES_CODE, valueOf(res.code));
+ ctx.setAttribute(pre + RES_MSG, res.message);
+
+ if (params.dumpHeaders && res.headers != null) {
+ for (Map.Entry<String, List<String>> a : res.headers.entrySet()) {
+ ctx.setAttribute(pre + HEADER + a.getKey(),
+ join(a.getValue(), COMMA));
+ }
+ }
+
+ if (res.body != null && res.body.trim().length() > 0) {
+ ctx.setAttribute(pre + HTTP_RES, res.body);
+ return res.body;
+ }
+ return null;
+ }
+
+ /**
+ * Sets the failure response status in the context memory.
+ *
+ * @param ctx service logic context
+ * @param prefix prefix to be added
+ * @param errMsg error message
+ */
+ private void setFailureResponseStatus(SvcLogicContext ctx, String prefix,
+ String errMsg) {
+ HttpResponse res = new HttpResponse();
+ res.code = 500;
+ res.message = errMsg;
+ ctx.setAttribute(prefix + RES_CODE, valueOf(res.code));
+ ctx.setAttribute(prefix + RES_MSG, res.message);
+ }
+
+ /**
+ * Updates request message for JSON and XML data format, when the HTTP
+ * method points it as PUT or PATCH.
+ *
+ * @param req current request message
+ * @param p YANG parameters
+ * @param insIdCtx instance identifier context
+ * @return update request message
+ * @throws SvcLogicException when the data format type is wrong
+ */
+ public String updateReq(String req, YangParameters p,
+ InstanceIdentifierContext<?> insIdCtx)
+ throws SvcLogicException {
+
+ SchemaNode schemaNode = insIdCtx.getSchemaNode();
+ Namespace modNs = getModuleNamespace(schemaNode.getQName(),
+ insIdCtx.getSchemaContext());
+ String nodeName = schemaNode.getQName().getLocalName();
+
+ switch (p.format) {
+ case JSON:
+ return getUpdatedJsonReq(req, nodeName, modNs.moduleName());
+
+ case XML:
+ return getXmlReqForPutOp(req, nodeName, modNs.moduleNs());
+
+ default:
+ throw new SvcLogicException(format(FORMAT_ERR, p.format));
+ }
+ }
+
+ /**
+ * Returns the updated JSON request message, when the HTTP method
+ * points to PUT or PATCH.
+ *
+ * @param req current JSON request message
+ * @param nodeName root node name
+ * @param modName module name of the root node
+ * @return update JSON request message
+ */
+ private String getUpdatedJsonReq(String req, String nodeName,
+ String modName) {
+ Writer writer = new StringWriter();
+ JsonWriter jsonWriter = new JsonWriter(writer);
+ jsonWriter.setIndent(repeat(" ", 4));
+
+ JsonParser jsonParser = new JsonParser();
+ JsonObject oldJson = (JsonObject)jsonParser.parse(req);
+ oldJson = remChildModName(oldJson, modName);
+ JsonObject newJson = new JsonObject();
+ newJson.add(modName + COLON + nodeName, oldJson.deepCopy());
+
+ Gson gson= new Gson();
+ gson.toJson(newJson, jsonWriter);
+ return writer.toString();
+ }
+
+ /**
+ * Removes module name from all the updated first level child node, if it
+ * is same as the root node added.
+ *
+ * @param oldJson JSON object for old request
+ * @param modName module name of root node
+ * @return JSON object for old request with updated child module name
+ */
+ private JsonObject remChildModName(JsonObject oldJson, String modName) {
+ Iterator<Map.Entry<String, JsonElement>> it = oldJson.entrySet().iterator();
+ Map<String, JsonElement> m = new HashMap<>();
+ while (it.hasNext()) {
+ Map.Entry<String, JsonElement> jNode = it.next();
+ if (jNode.getKey().contains(COLON)) {
+ String[] modArr = jNode.getKey().split(COLON);
+ if (modArr[0].equals(modName)) {
+ it.remove();
+ m.put(modArr[1], jNode.getValue());
+ }
+ }
+ }
+ if (!m.isEmpty()) {
+ for (Map.Entry<String, JsonElement> element : m.entrySet()) {
+ oldJson.add(element.getKey(), element.getValue());
+ }
+ }
+ return oldJson;
+ }
+
+ /**
+ * Returns the updated XML request message, when the HTTP method points
+ * to PUT or PATCH.
+ *
+ * @param req current JSON request message
+ * @param nodeName root node name
+ * @param modNs module namespace of the root node
+ * @return update JSON request message
+ * @throws SvcLogicException when XML parsing fails
+ */
+ private String getXmlReqForPutOp(String req, String nodeName,
+ URI modNs) throws SvcLogicException {
+ req = getUpdatedXmlReq(req, nodeName, modNs.toString());
+ Document oldDoc;
+ try {
+ oldDoc = DocumentHelper.parseText(req);
+ } catch (DocumentException e) {
+ throw new SvcLogicException(XML_TREE_ERR, e);
+ }
+ Writer writer = getXmlWriter(
+ UTF_HEADER + oldDoc.getRootElement().asXML(), "4");
+ return writer.toString();
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiUtils.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiUtils.java
new file mode 100644
index 000000000..1309102b3
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiUtils.java
@@ -0,0 +1,265 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Modifications Copyright © 2018 IBM.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.restconfapicall;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.plugins.restapicall.HttpMethod;
+import org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.YangParameters;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangStatementStreamSource;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
+
+import static org.onap.ccsdk.sli.plugins.restapicall.RestapiCallNode.getParameters;
+import static org.onap.ccsdk.sli.plugins.restapicall.RestapiCallNode.parseParam;
+import static org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode.DEFAULT_MODE;
+import static org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource.forFile;
+import static org.opendaylight.yangtools.yang.parser.rfc7950.reactor.RFC7950Reactors.defaultReactor;
+import static org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangStatementStreamSource.create;
+
+/**
+ * Utilities for restconf api call node.
+ */
+public final class RestconfApiUtils {
+
+ static final String RES_CODE = "response-code";
+
+ static final String HTTP_REQ ="httpRequest";
+
+ static final String RES_PRE = "responsePrefix";
+
+ static final String RES_MSG = "response-message";
+
+ static final String HEADER = "header.";
+
+ static final String COMMA = ",";
+
+ static final String COLON = ":";
+
+ static final String HTTP_RES = "httpResponse";
+
+ static final String REST_API_URL = "restapiUrl";
+
+ static final String UPDATED_URL = "URL was set to";
+
+ static final String COMM_FAIL = "Failed to communicate with host %s." +
+ "Request will be re-attempted using the host %s.";
+
+ static final String RETRY_COUNT = "This is retry attempt %d out of %d";
+
+ static final String RETRY_FAIL = "Retry attempt has failed. No further " +
+ "retry shall be attempted, calling setFailureResponseStatus";
+
+ static final String NO_MORE_RETRY = "Could not attempt retry";
+
+ static final String MAX_RETRY_ERR = "Maximum retries reached, calling " +
+ "setFailureResponseStatus";
+
+ static final String ATTEMPTS_MSG = "%d attempts were made out of %d " +
+ "maximum retries";
+
+ static final String REQ_ERR = "Error sending the request: ";
+
+ private static final String SLASH = "/";
+
+ private static final String DIR_PATH = "dirPath";
+
+ private static final String URL_SYNTAX = "The following URL cannot be " +
+ "parsed into URI : ";
+
+ private static final String YANG = ".yang";
+
+ private static final String YANG_FILE_ERR = "Unable to parse the YANG " +
+ "file provided";
+
+ //No instantiation.
+ private RestconfApiUtils() {
+ }
+
+ /**
+ * Returns the YANG parameters after parsing it from the map.
+ *
+ * @param paramMap parameters map
+ * @return YANG parameters
+ * @throws SvcLogicException when parsing of parameters map fail
+ */
+ static YangParameters getYangParameters(Map<String, String> paramMap)
+ throws SvcLogicException {
+ YangParameters param = (YangParameters) getParameters(
+ paramMap, new YangParameters());
+ param.dirPath = parseParam(paramMap, DIR_PATH, false, null);
+ return param;
+ }
+
+ /**
+ * Parses the restconf URL and gives the YANG path from it, which can be
+ * used to get schema node. If it is a PUT operation, then a node must be
+ * reduced from the url to make it always point to the parent.
+ *
+ * @param url restconf URL
+ * @param method HTTP operation
+ * @return YANG path pointing to parent
+ * @throws SvcLogicException when parsing the URL fails
+ */
+ public static String parseUrl(String url, HttpMethod method)
+ throws SvcLogicException {
+ URI uri;
+ try {
+ uri = new URI(url);
+ } catch (URISyntaxException e) {
+ throw new SvcLogicException(URL_SYNTAX + url, e);
+ }
+
+ String path = uri.getPath();
+ path = getParsedPath(path);
+ return path;
+ }
+
+ /**
+ * Returns the path which contains only the schema nodes.
+ *
+ * @param path path
+ * @return path representing schema
+ */
+ private static String getParsedPath(String path) {
+ String firstHalf;
+ String secondHalf;
+ if (path.contains(COLON)) {
+ String[] p = path.split(COLON);
+ if (p[0].contains(SLASH)) {
+ int slash = p[0].lastIndexOf(SLASH);
+ firstHalf = p[0].substring(slash + 1);
+ } else {
+ firstHalf = p[0];
+ }
+ secondHalf = path.substring(p[0].length() + 1);
+ return firstHalf + COLON + secondHalf;
+ } else if (path.contains(SLASH)) {
+ String[] p = path.split(SLASH);
+ if (p.length > 4) {
+ String actual = p[3] + COLON + p[4];
+ if (p.length > 5) {
+ secondHalf = path.substring(
+ p[1].length() + p[2].length() + actual.length() + 3);
+ path = actual + secondHalf;
+ } else {
+ path = actual;
+ }
+ }
+ }
+ return path;
+ }
+
+ /**
+ * Returns the schema context of the YANG files present in a directory.
+ *
+ * @param di directory path
+ * @return YANG schema context
+ * @throws SvcLogicException when YANG file reading fails
+ */
+ static SchemaContext getSchemaCtxFromDir(String di)
+ throws SvcLogicException {
+ Path d = Paths.get(di);
+ File dir = d.toFile();
+ List<File> yangFiles = new LinkedList<>();
+ getYangFiles(dir, yangFiles);
+ final Collection<YangStatementStreamSource> sources =
+ new ArrayList<>(yangFiles.size());
+ for (File file : yangFiles) {
+ try {
+ sources.add(create(forFile(file)));
+ } catch (IOException | YangSyntaxErrorException e) {
+ throw new SvcLogicException(YANG_FILE_ERR + e.getMessage(), e);
+ }
+ }
+
+ final CrossSourceStatementReactor.BuildAction reactor = defaultReactor()
+ .newBuild(DEFAULT_MODE).addSources(sources);
+ try {
+ return reactor.buildEffective();
+ } catch (ReactorException e) {
+ throw new SvcLogicException(YANG_FILE_ERR + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Returns all the YANG files present in a directory recursively.
+ *
+ * @param dir path of the directory
+ * @param yangFiles list of YANG files
+ */
+ private static void getYangFiles(File dir, List<File> yangFiles) {
+ if (dir.exists()) {
+ File[] files = dir.listFiles();
+ if (files != null) {
+ processFiles(files, yangFiles);
+ }
+ }
+ }
+
+ /**
+ * Processes all the obtained files by isolating all the YANG files from
+ * all the directory of the given path recursively.
+ *
+ * @param files files in the given path
+ * @param yangFiles YANG files list
+ */
+ private static void processFiles(File[] files, List<File> yangFiles) {
+ for (File file : files) {
+ if (file.isFile() && file.getName().endsWith(YANG)) {
+ yangFiles.add(file);
+ } else if (file.isDirectory()) {
+ getYangFiles(file, yangFiles);
+ }
+ }
+ }
+
+ /**
+ * Returns the updated XML request message by adding root node to it.
+ *
+ * @param req XML request
+ * @param nodeName root node name
+ * @param modNs module namespace of the root node
+ * @return updated XML request message
+ */
+ static String getUpdatedXmlReq(String req, String nodeName, String modNs) {
+ String rootNode = "\n<" + nodeName + " xmlns=\"" + modNs +
+ "\">\n";
+ req = req.replaceFirst("\n", rootNode);
+ req = req + "</" + nodeName + ">";
+ return req.replaceAll(">\\s+<", "><");
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/AdditionalHeaderWebTarget.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/AdditionalHeaderWebTarget.java
new file mode 100644
index 000000000..3213cae15
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/AdditionalHeaderWebTarget.java
@@ -0,0 +1,166 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Modifications Copyright © 2018 IBM
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.restconfdiscovery;
+
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Configuration;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriBuilder;
+import java.net.URI;
+import java.util.Map;
+
+/**
+ * Adds additional headers for SSE request.
+ */
+class AdditionalHeaderWebTarget implements WebTarget {
+ private WebTarget base;
+ private String token;
+
+ private String accessToken = "X-ACCESS-TOKEN";
+
+ public AdditionalHeaderWebTarget(WebTarget target, String token) {
+ base = target;
+ this.token = token;
+ }
+
+ @Override
+ public Invocation.Builder request() {
+ return base.request().header(accessToken, token);
+ }
+
+ @Override
+ public Invocation.Builder request(String... acceptedResponseTypes) {
+ return base.request().header(accessToken, token);
+ }
+
+ @Override
+ public Invocation.Builder request(MediaType... acceptedResponseTypes) {
+ return base.request().header(accessToken, token);
+ }
+
+ @Override
+ public Configuration getConfiguration() {
+ return base.getConfiguration();
+ }
+
+ @Override
+ public URI getUri() {
+ return base.getUri();
+ }
+
+ @Override
+ public UriBuilder getUriBuilder() {
+ return base.getUriBuilder();
+ }
+
+ @Override
+ public WebTarget path(String path) {
+ return base.path(path);
+ }
+
+ @Override
+ public WebTarget resolveTemplate(String name, Object value) {
+ return base.resolveTemplate(name, value);
+ }
+
+ @Override
+ public WebTarget resolveTemplate(String name, Object value, boolean encodeSlashInPath) {
+ return base.resolveTemplate(name, value, encodeSlashInPath);
+ }
+
+ @Override
+ public WebTarget resolveTemplateFromEncoded(String name, Object value) {
+ return base.resolveTemplateFromEncoded(name, value);
+ }
+
+ @Override
+ public WebTarget resolveTemplates(Map<String, Object> templateValues) {
+ return base.resolveTemplates(templateValues);
+ }
+
+ @Override
+ public WebTarget resolveTemplates(Map<String, Object> templateValues, boolean encodeSlashInPath) {
+ return base.resolveTemplates(templateValues, encodeSlashInPath);
+ }
+
+ @Override
+ public WebTarget resolveTemplatesFromEncoded(Map<String, Object> templateValues) {
+ return base.resolveTemplatesFromEncoded(templateValues);
+ }
+
+ @Override
+ public WebTarget matrixParam(String name, Object... values) {
+ return base.matrixParam(name, values);
+ }
+
+ @Override
+ public WebTarget queryParam(String name, Object... values) {
+ return base.queryParam(name, values);
+ }
+
+ @Override
+ public WebTarget property(String name, Object value) {
+ return base.property(name, value);
+ }
+
+ @Override
+ public WebTarget register(Class<?> componentClass) {
+ return base.register(componentClass);
+ }
+
+ @Override
+ public WebTarget register(Class<?> componentClass, int priority) {
+ return base.register(componentClass, priority);
+ }
+
+ @Override
+ public WebTarget register(Class<?> componentClass, Class<?>... contracts) {
+ return base.register(componentClass, contracts);
+ }
+
+ @Override
+ public WebTarget register(Class<?> componentClass, Map<Class<?>, Integer> contracts) {
+ return base.register(componentClass, contracts);
+ }
+
+ @Override
+ public WebTarget register(Object component) {
+ return base.register(component);
+ }
+
+ @Override
+ public WebTarget register(Object component, int priority) {
+ return base.register(component, priority);
+ }
+
+ @Override
+ public WebTarget register(Object component, Class<?>... contracts) {
+ return base.register(component, contracts);
+ }
+
+ @Override
+ public WebTarget register(Object component, Map<Class<?>, Integer> contracts) {
+ return base.register(component, contracts);
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/EventHandler.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/EventHandler.java
new file mode 100644
index 000000000..a76554d5a
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/EventHandler.java
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.restconfdiscovery;
+
+import org.glassfish.jersey.media.sse.InboundEvent;
+import org.glassfish.jersey.media.sse.EventListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Listener that can be registered to listen for notifications.
+ */
+class EventHandler implements EventListener {
+ private static final Logger log = LoggerFactory.getLogger(EventListener.class);
+ private RestconfDiscoveryNode node;
+
+ public EventHandler(RestconfDiscoveryNode node) {
+ this.node = node;
+ }
+
+ @Override
+ public void onEvent(InboundEvent event) {
+ String payload = event.readData();
+ if (!node.eventQueue().offer(payload)) {
+ log.error("Unable to process event {} as processing queue is full", payload);
+ }
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/EventProcessor.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/EventProcessor.java
new file mode 100644
index 000000000..4f28072d3
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/EventProcessor.java
@@ -0,0 +1,76 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Modifications Copyright © 2018 IBM
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.restconfdiscovery;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.slf4j.Logger;
+
+import java.util.Map;
+
+import static org.onap.ccsdk.sli.plugins.restapicall.JsonParser.convertToProperties;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Processes the events from event queue and executes callback DG.
+ */
+class EventProcessor implements Runnable {
+
+ private static final Logger log = getLogger(EventProcessor.class);
+ private RestconfDiscoveryNode node;
+
+ private static final String EVENT_SUBSCRIPTION_ID = "notification." +
+ "push-change-update.subscription-id";
+
+ public EventProcessor(RestconfDiscoveryNode node) {
+ this.node = node;
+ }
+
+ @Override
+ public void run() {
+ while(true) {
+ try {
+ String payload = node.eventQueue().take();
+ Map<String, String> param = convertToProperties(payload);
+ String id = param.get(EVENT_SUBSCRIPTION_ID);
+ SubscriptionInfo info = node.subscriptionInfoMap().get(id);
+ if (info != null) {
+ SvcLogicContext ctx = setContext(param);
+ SvcLogicGraphInfo callbackDG = info.callBackDG();
+ callbackDG.executeGraph(ctx);
+ }
+ } catch (InterruptedException | SvcLogicException e) {
+ log.error("Interrupted!", e);
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
+ private SvcLogicContext setContext(Map<String, String> param) {
+ SvcLogicContext ctx = new SvcLogicContext();
+ for (Map.Entry<String, String> entry : param.entrySet()) {
+ ctx.setAttribute(entry.getKey(), entry.getValue());
+ }
+ return ctx;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/RestconfDiscoveryNode.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/RestconfDiscoveryNode.java
new file mode 100644
index 000000000..cf69d7a3c
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/RestconfDiscoveryNode.java
@@ -0,0 +1,310 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.restconfdiscovery;
+
+import org.glassfish.jersey.media.sse.EventSource;
+import org.glassfish.jersey.media.sse.SseFeature;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.plugins.restapicall.Parameters;
+import org.onap.ccsdk.sli.plugins.restapicall.RestapiCallNode;
+import org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiCallNode;
+import org.slf4j.Logger;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Representation of a plugin to subscribe for notification and then
+ * to handle the received notifications.
+ */
+public class RestconfDiscoveryNode implements SvcLogicDiscoveryPlugin {
+
+ private static final Logger log = getLogger(RestconfDiscoveryNode.class);
+
+ private ExecutorService executor = Executors.newCachedThreadPool();
+ private Map<String, PersistentConnection> runnableInfo = new ConcurrentHashMap<>();
+ private RestconfApiCallNode restconfApiCallNode;
+
+ private volatile Map<String, SubscriptionInfo> subscriptionInfoMap = new ConcurrentHashMap<>();
+ private volatile LinkedBlockingQueue<String> eventQueue = new LinkedBlockingQueue<>();
+
+ private static final String SUBSCRIBER_ID = "subscriberId";
+ private static final String RESPONSE_CODE = "response-code";
+ private static final String RESPONSE_PREFIX = "responsePrefix";
+ private static final String OUTPUT_IDENTIFIER = "ietf-subscribed-notif" +
+ "ications:establish-subscription.output.identifier";
+ private static final String RESPONSE_CODE_200 = "200";
+ private static final String SSE_URL = "sseConnectURL";
+
+ /**
+ * Creates an instance of RestconfDiscoveryNode and starts processing of
+ * event.
+ *
+ * @param r restconf api call node
+ */
+ public RestconfDiscoveryNode(RestconfApiCallNode r) {
+ this.restconfApiCallNode = r;
+ ExecutorService e = Executors.newFixedThreadPool(20);
+ EventProcessor p = new EventProcessor(this);
+ for (int i = 0; i < 20; ++i) {
+ e.execute(p);
+ }
+ }
+
+ @Override
+ public void establishSubscription(Map<String, String> paramMap,
+ SvcLogicContext ctx) throws SvcLogicException {
+ String subscriberId = paramMap.get(SUBSCRIBER_ID);
+ if (subscriberId == null) {
+ throw new SvcLogicException("Subscriber Id is null");
+ }
+
+ restconfApiCallNode.sendRequest(paramMap, ctx);
+
+ if (getResponseCode(paramMap.get(RESPONSE_PREFIX), ctx).equals(RESPONSE_CODE_200)) {
+ // TODO: save subscription id and subscriber in MYSQL
+
+ establishPersistentConnection(paramMap, ctx, subscriberId);
+ } else {
+ log.info("Failed to subscribe {}", subscriberId);
+ throw new SvcLogicException(ctx.getAttribute(RESPONSE_CODE));
+ }
+ }
+
+ @Override
+ public void modifySubscription(Map<String, String> paramMap, SvcLogicContext ctx) {
+ // TODO: to be implemented
+ }
+
+ @Override
+ public void deleteSubscription(Map<String, String> paramMap, SvcLogicContext ctx) {
+ String id = getSubscriptionId(paramMap.get(SUBSCRIBER_ID));
+ if (id != null) {
+ PersistentConnection conn = runnableInfo.get(id);
+ conn.terminate();
+ runnableInfo.remove(id);
+ subscriptionInfoMap.remove(id);
+ }
+ }
+
+ class PersistentConnection implements Runnable {
+ private String url;
+ private volatile boolean running = true;
+ private Map<String, String> paramMap;
+
+ PersistentConnection(String url, Map<String, String> paramMap) {
+ this.url = url;
+ this.paramMap = paramMap;
+ }
+
+ private void terminate() {
+ running = false;
+ }
+
+ @Override
+ public void run() {
+ Parameters p;
+ WebTarget target = null;
+ try {
+ RestapiCallNode restapi = restconfApiCallNode.getRestapiCallNode();
+ p = RestapiCallNode.getParameters(paramMap, new Parameters());
+ Client client = ignoreSslClient().register(SseFeature.class);
+ target = restapi.addAuthType(client, p).target(url);
+ } catch (SvcLogicException e) {
+ log.error("Exception occured!", e);
+ Thread.currentThread().interrupt();
+ }
+
+ target = addToken(target, paramMap.get("customHttpHeaders"));
+ EventSource eventSource = EventSource.target(target).build();
+ eventSource.register(new EventHandler(RestconfDiscoveryNode.this));
+ eventSource.open();
+ log.info("Connected to SSE source");
+ while (running) {
+ try {
+ log.info("SSE state " + eventSource.isOpen());
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ log.error("Interrupted!", e);
+ Thread.currentThread().interrupt();
+ }
+ }
+ eventSource.close();
+ log.info("Closed connection to SSE source");
+ }
+
+ private Client ignoreSslClient() {
+ SSLContext sslcontext = null;
+
+ try {
+ sslcontext = SSLContext.getInstance("TLS");
+ sslcontext.init(null, new TrustManager[]{new X509TrustManager() {
+ @Override
+ public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return new X509Certificate[0];
+ }
+ } }, new java.security.SecureRandom());
+ } catch (NoSuchAlgorithmException | KeyManagementException e) {
+ throw new IllegalStateException(e);
+ }
+
+ return ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier((s1, s2) -> true).build();
+ }
+ }
+
+ protected String getTokenId(String customHttpHeaders) {
+ if (customHttpHeaders.contains("=")) {
+ String[] s = customHttpHeaders.split("=");
+ return s[1];
+ }
+ return customHttpHeaders;
+ }
+
+ protected WebTarget addToken(WebTarget target, String customHttpHeaders) {
+ if (customHttpHeaders == null) {
+ return target;
+ }
+
+ return new AdditionalHeaderWebTarget(
+ target, getTokenId(customHttpHeaders));
+ }
+
+ /**
+ * Establishes a persistent between the client and server.
+ *
+ * @param paramMap input paramter map
+ * @param ctx service logic context
+ * @param subscriberId subscriber identifier
+ */
+ void establishPersistentConnection(Map<String, String> paramMap, SvcLogicContext ctx,
+ String subscriberId) {
+ String id = getOutputIdentifier(paramMap.get(RESPONSE_PREFIX), ctx);
+ SvcLogicGraphInfo callbackDG = new SvcLogicGraphInfo(paramMap.get("module"),
+ paramMap.get("rpc"),
+ paramMap.get("version"),
+ paramMap.get("mode"));
+ SubscriptionInfo info = new SubscriptionInfo();
+ info.callBackDG(callbackDG);
+ info.subscriptionId(id);
+ info.subscriberId(subscriberId);
+ subscriptionInfoMap.put(id, info);
+
+ String url = paramMap.get(SSE_URL);
+ PersistentConnection connection = new PersistentConnection(url, paramMap);
+ runnableInfo.put(id, connection);
+ executor.execute(connection);
+ }
+
+ /**
+ * Returns response code.
+ *
+ * @param prefix prefix given in input parameter
+ * @param ctx service logic context
+ * @return response code
+ */
+ String getResponseCode(String prefix, SvcLogicContext ctx) {
+ return ctx.getAttribute(getPrefix(prefix) + RESPONSE_CODE);
+ }
+
+ /**
+ * Returns subscription id from event.
+ *
+ * @param prefix prefix given in input parameter
+ * @param ctx service logic context
+ * @return subscription id from event
+ */
+ String getOutputIdentifier(String prefix, SvcLogicContext ctx) {
+ return ctx.getAttribute(getPrefix(prefix) + OUTPUT_IDENTIFIER);
+ }
+
+ private String getPrefix(String prefix) {
+ return prefix != null ? prefix + "." : "";
+ }
+
+ private String getSubscriptionId(String subscriberId) {
+ for (Map.Entry<String,SubscriptionInfo> entry
+ : subscriptionInfoMap.entrySet()) {
+ if (entry.getValue().subscriberId()
+ .equals(subscriberId)) {
+ return entry.getKey();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns restconfApiCallNode.
+ *
+ * @return restconfApiCallNode
+ */
+ protected RestconfApiCallNode restconfapiCallNode() {
+ return restconfApiCallNode;
+ }
+
+ /**
+ * Sets restconfApiCallNode.
+ *
+ * @param node restconfApiCallNode
+ */
+ void restconfapiCallNode(RestconfApiCallNode node) {
+ restconfApiCallNode = node;
+ }
+
+ Map<String, SubscriptionInfo> subscriptionInfoMap() {
+ return subscriptionInfoMap;
+ }
+
+ void subscriptionInfoMap(Map<String, SubscriptionInfo> subscriptionInfoMap) {
+ this.subscriptionInfoMap = subscriptionInfoMap;
+ }
+
+ LinkedBlockingQueue<String> eventQueue() {
+ return eventQueue;
+ }
+
+ void eventQueue(LinkedBlockingQueue<String> eventQueue) {
+ this.eventQueue = eventQueue;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/SubscriptionInfo.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/SubscriptionInfo.java
new file mode 100644
index 000000000..4ed3660ca
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/SubscriptionInfo.java
@@ -0,0 +1,122 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.restconfdiscovery;
+
+/**
+ * Holder to store information of subscription.
+ */
+public class SubscriptionInfo {
+ private String subscriptionId;
+ private String subscriberId;
+ private SvcLogicGraphInfo callbackDG;
+ private String yangFilePath;
+ private String filterUrl;
+
+ /**
+ * Returns callback DG.
+ *
+ * @return callback DG
+ */
+ public SvcLogicGraphInfo callBackDG() {
+ return callbackDG;
+ }
+
+ /**
+ * Sets callback DG.
+ *
+ * @param callbackDg callback DG
+ */
+ public void callBackDG(SvcLogicGraphInfo callbackDg) {
+ this.callbackDG = callbackDg;
+ }
+
+ /**
+ * Returns YANG file path.
+ *
+ * @return YANG file path
+ */
+ public String yangFilePath() {
+ return yangFilePath;
+ }
+
+ /**
+ * Sets YANG file path.
+ *
+ * @param yangFilePath yang file path
+ */
+ public void yangFilePath(String yangFilePath) {
+ this.yangFilePath = yangFilePath;
+ }
+
+ /**
+ * Returns filter URL.
+ *
+ * @return filter URL
+ */
+ public String filterUrl() {
+ return filterUrl;
+ }
+
+ /**
+ * Sets filter URL.
+ *
+ * @param filterUrl filter URL
+ */
+ public void filterUrl(String filterUrl) {
+ this.filterUrl = filterUrl;
+ }
+
+ /**
+ * Returns subscription Id.
+ *
+ * @return subscription Id
+ */
+ public String subscriptionId() {
+ return subscriptionId;
+ }
+
+ /**
+ * Sets subscription id.
+ *
+ * @param subscriptionId subscription id
+ */
+ public void subscriptionId(String subscriptionId) {
+ this.subscriptionId = subscriptionId;
+ }
+
+ /**
+ * Returns subscription Id.
+ *
+ * @return subscription Id
+ */
+ public String subscriberId() {
+ return subscriberId;
+ }
+
+ /**
+ * Sets subscriber id.
+ *
+ * @param subscriberId subscriber id
+ */
+ public void subscriberId(String subscriberId) {
+ this.subscriberId = subscriberId;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/SvcLogicDiscoveryPlugin.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/SvcLogicDiscoveryPlugin.java
new file mode 100644
index 000000000..dfe8cd5b7
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/SvcLogicDiscoveryPlugin.java
@@ -0,0 +1,110 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.restconfdiscovery;
+
+import java.util.Map;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+
+/**
+ * Abstraction of a plugin to enable discovery from DG.
+ */
+public interface SvcLogicDiscoveryPlugin extends SvcLogicJavaPlugin {
+
+ /**
+ * Allows directed graphs to establish a discovery subscription for a given subscriber.
+ * @param paramMap HashMap<String,String> of parameters passed by the DG to this function
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th><th>example values</th></thead>
+ * <tbody>
+ * <tr><td>templateDirName</td><td>Optional</td><td>full path to YANG directory that can be used to build a request</td><td>/sdncopt/bvc/resconfapi/test</td></tr>
+ * <tr><td>establishSubscriptionURL</td><td>Mandatory</td><td>url to establish connection with server</td><td>https://127.0.0.1:8181/restconf/operations/ietf-subscribed-notifications:establish-subscription</td></tr>
+ * <tr><td>sseConnectURL</td><td>Mandatory</td><td>url to setup SSE connection with server</td><td>https://127.0.0.1:8181/restconf/streams/yang-push-json</td></tr>
+ * <tr><td>callbackDG</td><td>Mandatory</td><td>callback DG to process the received notification</td><td>Resource-Discovery:handleSOTNTopology</td></tr>
+ * <tr><td>filterURL</td><td>Optional</td><td>url which needs to be subscribed, if null subscribe to all</td><td>http://example.com/sample-data/1.0</td></tr>
+ * <tr><td>subscriptionType</td><td>Optional</td><td>type of subscription, periodic or onDataChange</td><td>onDataChange</td></tr>
+ * <tr><td>updateFrequency</td><td>Optional</td><td>update frequency in milli seconds when subscription type is periodic</td><td>1000</td></tr>
+ * <tr><td>restapiUser</td><td>Optional</td><td>user name to use for http basic authentication</td><td>sdnc_ws</td></tr>
+ * <tr><td>restapiPassword</td><td>Optional</td><td>unencrypted password to use for http basic authentication</td><td>plain_password</td></tr>
+ * <tr><td>contentType</td><td>Optional</td><td>http content type to set in the http header</td><td>usually application/json or application/xml</td></tr>
+ * <tr><td>format</td><td>Optional</td><td>should match request body format</td><td>json or xml</td></tr>
+ * <tr><td>responsePrefix</td><td>Optional</td><td>location the notification response will be written to in context memory</td><td>tmp.restconfdiscovery.result</td></tr>
+ * <tr><td>skipSending</td><td>Optional</td><td></td><td>true or false</td></tr>
+ * <tr><td>convertResponse </td><td>Optional</td><td>whether the response should be converted</td><td>true or false</td></tr>
+ * <tr><td>customHttpHeaders</td><td>Optional</td><td>a list additional http headers to be passed in, follow the format in the example</td><td>X-CSI-MessageId=messageId,headerFieldName=headerFieldValue</td></tr>
+ * <tr><td>dumpHeaders</td><td>Optional</td><td>when true writes http header content to context memory</td><td>true or false</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ * @since 11.0.2
+ * @see String#split(String, int)
+ */
+ void establishSubscription(Map<String, String> paramMap, SvcLogicContext ctx) throws SvcLogicException;
+
+ /**
+ * Allows directed graphs to modify a discovery subscription for a given subscriber.
+ * @param paramMap HashMap<String,String> of parameters passed by the DG to this function
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th><th>example values</th></thead>
+ * <tbody>
+ * <tr><td>subscriberId</td><td>Mandatory</td><td>subscription subscriber's identifier</td><td>topologyId/1111</td></tr>
+ * <tr><td>templateDirName</td><td>Optional</td><td>full path to YANG directory that can be used to build a request</td><td>/sdncopt/bvc/resconfapi/test</td></tr>
+ * <tr><td>establishSubscriptionURL</td><td>Mandatory</td><td>url to establish connection with server</td><td>https://127.0.0.1:8181/restconf/operations/ietf-subscribed-notifications:establish-subscription</td></tr>
+ * <tr><td>sseConnectURL</td><td>Mandatory</td><td>url to setup SSE connection with server</td><td>https://127.0.0.1:8181/restconf/streams/yang-push-json</td></tr>
+ * <tr><td>callbackDG</td><td>Mandatory</td><td>callback DG to process the received notification</td><td>Resource-Discovery:handleSOTNTopology</td></tr>
+ * <tr><td>filterURL</td><td>Optional</td><td>url filter list which needs to be subscribed, if null subscribe to all</td><td>http://example.com/sample-data/1.0</td></tr>
+ * <tr><td>subscriptionType</td><td>Optional</td><td>type of subscription, periodic or onDataChange</td><td>onDataChange</td></tr>
+ * <tr><td>updateFrequency</td><td>Optional</td><td>update frequency in milli seconds when subscription type is periodic</td><td>1000</td></tr>
+ * <tr><td>restapiUser</td><td>Optional</td><td>user name to use for http basic authentication</td><td>sdnc_ws</td></tr>
+ * <tr><td>restapiPassword</td><td>Optional</td><td>unencrypted password to use for http basic authentication</td><td>plain_password</td></tr>
+ * <tr><td>contentType</td><td>Optional</td><td>http content type to set in the http header</td><td>usually application/json or application/xml</td></tr>
+ * <tr><td>format</td><td>Optional</td><td>should match request body format</td><td>json or xml</td></tr>
+ * <tr><td>responsePrefix</td><td>Optional</td><td>location the notification response will be written to in context memory</td><td>tmp.restconfdiscovery.result</td></tr>
+ * <tr><td>skipSending</td><td>Optional</td><td></td><td>true or false</td></tr>
+ * <tr><td>convertResponse </td><td>Optional</td><td>whether the response should be converted</td><td>true or false</td></tr>
+ * <tr><td>customHttpHeaders</td><td>Optional</td><td>a list additional http headers to be passed in, follow the format in the example</td><td>X-CSI-MessageId=messageId,headerFieldName=headerFieldValue</td></tr>
+ * <tr><td>dumpHeaders</td><td>Optional</td><td>when true writes http header content to context memory</td><td>true or false</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ * @since 11.0.2
+ * @see String#split(String, int)
+ */
+ void modifySubscription(Map<String, String> paramMap, SvcLogicContext ctx);
+
+ /**
+ * Allows directed graphs to delete the discovery subscription for a given subscriber.
+ * @param paramMap HashMap<String,String> of parameters passed by the DG to this function
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th><th>example values</th></thead>
+ * <tbody>
+ * <tr><td>subscriberId</td><td>Mandatory</td><td>subscription subscriber's identifier</td><td>topologyId/1111</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ */
+ void deleteSubscription(Map<String, String> paramMap, SvcLogicContext ctx);
+
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/SvcLogicGraphInfo.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/SvcLogicGraphInfo.java
new file mode 100644
index 000000000..1cc6261ab
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/SvcLogicGraphInfo.java
@@ -0,0 +1,178 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.restconfdiscovery;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicGraph;
+import org.onap.ccsdk.sli.core.sli.SvcLogicStore;
+import org.onap.ccsdk.sli.core.sli.provider.SvcLogicService;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Holder to store callback directed graph info.
+ */
+class SvcLogicGraphInfo {
+ private String module;
+ private String rpc;
+ private String mode;
+ private String version;
+
+ /**
+ * Creates an instance of SvcLogicGraphInfo.
+ *
+ * @param module module name of callback DG
+ * @param rpc rpc name of callback DG
+ * @param mode mode of callback DG
+ * @param version version of callback DG
+ */
+ public SvcLogicGraphInfo(String module, String rpc, String mode, String version) {
+ this.module = module;
+ this.rpc = rpc;
+ this.mode = mode;
+ this.version = version;
+ }
+
+ public SvcLogicGraphInfo() {}
+
+ /**
+ * Returns module name of callback DG.
+ *
+ * @return module name of callback DG
+ */
+ public String module() {
+ return module;
+ }
+
+ /**
+ * Sets module of callback DG.
+ *
+ * @param module module name of the DG
+ */
+ public void module(String module) {
+ this.module = module;
+ }
+
+ /**
+ * Returns rpc of callback DG.
+ *
+ * @return rpc of callback DG
+ */
+ public String rpc() {
+ return rpc;
+ }
+
+ /**
+ * Sets rpc of callback DG.
+ *
+ * @param rpc rpc attribute of the DG
+ */
+ public void rpc(String rpc) {
+ this.rpc = rpc;
+ }
+
+ /**
+ * Returns mode of callback DG.
+ *
+ * @return mode of callback DG
+ */
+ public String mode() {
+ return mode;
+ }
+
+ /**
+ * Sets mode of DG.
+ *
+ * @param mode mode of the DG
+ */
+ public void mode(String mode) {
+ this.mode = mode;
+ }
+
+ /**
+ * Returns version of callback DG.
+ *
+ * @return version of callback DG
+ */
+ public String version() {
+ return version;
+ }
+
+ /**
+ * Sets version of DG.
+ *
+ * @param version version of the DG
+ */
+ public void version(String version) {
+ this.version = version;
+ }
+
+ /**
+ * Executes call back DG.
+ *
+ * @param ctx service logic context
+ * @throws SvcLogicException service logic error
+ */
+ public void executeGraph(SvcLogicContext ctx) throws SvcLogicException {
+ SvcLogicService service = findSvcLogicService();
+ if (service == null) {
+ throw new SvcLogicException("\"Could not get SvcLogicService reference\"");
+ }
+
+ SvcLogicStore store = service.getStore();
+ if (store != null) {
+ SvcLogicGraph subGraph = store.fetch(module, rpc, mode, version);
+ if (subGraph != null) {
+ ctx.setAttribute("subGraph", subGraph.toString());
+ service.execute(subGraph, ctx);
+ } else {
+ throw new SvcLogicException("Failed to call child [" + module +
+ "," + rpc + "," + version +
+ "," + mode + "] because" +
+ " the" + " graph could" +
+ " not be found");
+ }
+ } else {
+ throw new SvcLogicException("\"Could not get SvcLogicStore reference\"");
+ }
+ }
+
+ private static SvcLogicService findSvcLogicService() throws SvcLogicException {
+ Bundle bundle = FrameworkUtil.getBundle(SvcLogicService.class);
+ if (bundle == null) {
+ throw new SvcLogicException("Cannot find bundle reference for "
+ + SvcLogicService.NAME);
+ }
+
+ BundleContext bctx = bundle.getBundleContext();
+ ServiceReference<SvcLogicService> sref = bctx.getServiceReference(
+ SvcLogicService.class);
+ if (sref != null) {
+ return bctx.getService(sref);
+ } else {
+ throw new SvcLogicException("Cannot find service reference for "
+ + SvcLogicService.NAME);
+ }
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/Annotation.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/Annotation.java
new file mode 100644
index 000000000..185f70ba0
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/Annotation.java
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+/**
+ * Representation of an entity that represents annotated attribute.
+ */
+public class Annotation {
+
+ /**
+ * Name of the annotation.
+ */
+ private String name;
+
+ /**
+ * Value of the annotation.
+ */
+ private String value;
+
+ /**
+ * Creates an instance of annotation.
+ *
+ * @param n annotation name
+ * @param v annotation value
+ */
+ public Annotation(String n, String v) {
+ name = n;
+ value = v;
+ }
+
+ /**
+ * Returns name of annotation.
+ *
+ * @return name of annotation
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Returns value of annotation.
+ *
+ * @return value of annotation
+ */
+ public String value() {
+ return value;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormat.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormat.java
new file mode 100644
index 000000000..c692f1dd2
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormat.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+/**
+ * Representation of data format.
+ */
+public enum DataFormat {
+
+ /**
+ * XML data format.
+ */
+ XML,
+
+ /**
+ * JSON data format.
+ */
+ JSON
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatSerializer.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatSerializer.java
new file mode 100644
index 000000000..cab64391a
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatSerializer.java
@@ -0,0 +1,94 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Abstraction of serializer to encode/decode context memory parameters
+ * to/from specified data format.
+ */
+public abstract class DataFormatSerializer {
+
+ /**
+ * Data format type of the serializer.
+ */
+ private DataFormat dataFormat;
+
+ /**
+ * Data format serializer context.
+ */
+ private DataFormatSerializerContext serializerContext;
+
+ /**
+ * Creates an instance of data format serializer.
+ *
+ * @param d type of data format
+ * @param s data format serializer context
+ */
+ protected DataFormatSerializer(DataFormat d,
+ DataFormatSerializerContext s) {
+ this.dataFormat = d;
+ this.serializerContext = s;
+ }
+
+ /**
+ * Encodes context memory parameters to data format.
+ *
+ * @param param context memory parameter
+ * @param annotations annotations
+ * @return data format body
+ * @throws SvcLogicException when serialization fails
+ */
+ public abstract String encode(Map<String, String> param,
+ Map<String, List<Annotation>> annotations) throws SvcLogicException;
+
+ /**
+ * Decodes data format body to context memory parameters.
+ *
+ * @param dataFormatBody abstract node
+ * @return context memory parameters
+ * @throws SvcLogicException when serialization fails
+ */
+ public abstract Map<String, String> decode(String dataFormatBody)
+ throws SvcLogicException;
+
+ /**
+ * Returns data format serializer context.
+ *
+ * @return data format serializer context
+ */
+ public DataFormatSerializerContext serializerContext() {
+ return serializerContext;
+ }
+
+ /**
+ * Returns supported data format.
+ *
+ * @return supported data format
+ */
+ public DataFormat dataFormat() {
+ return dataFormat;
+ }
+} \ No newline at end of file
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatSerializerContext.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatSerializerContext.java
new file mode 100644
index 000000000..919e82af3
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatSerializerContext.java
@@ -0,0 +1,104 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNodeSerializer;
+
+import java.util.Map;
+
+/**
+ * Abstraction of data format serializer context.
+ */
+public class DataFormatSerializerContext {
+
+ /**
+ * Data format listener.
+ */
+ private Listener listener;
+
+ /**
+ * URI corresponding to the instance identifier.
+ */
+ private String uri;
+
+ /**
+ * Protocol annotation.
+ */
+ private Map<String, String> protocolAnnotation;
+
+ /**
+ * Properties node serializer.
+ */
+ private PropertiesNodeSerializer propNodeSerializer;
+
+ /**
+ * Creates an instance of data format serializer context.
+ *
+ * @param l data format listener
+ * @param u URI corresponding to instance identifier
+ * @param p protocol annotations
+ * @param s properties node serializer
+ */
+ public DataFormatSerializerContext(Listener l, String u,
+ Map<String, String> p,
+ PropertiesNodeSerializer s) {
+ listener = l;
+ uri = u;
+ protocolAnnotation = p;
+ propNodeSerializer = s;
+ }
+
+ /**
+ * Returns the data format listener.
+ *
+ * @return data format listener
+ */
+ public Listener listener() {
+ return listener;
+ }
+
+ /**
+ * Returns the URI.
+ *
+ * @return URI
+ */
+ public String uri() {
+ return uri;
+ }
+
+ /**
+ * Returns the protocol annotations.
+ *
+ * @return protocol annotations
+ */
+ public Map<String, String> getProtocolAnnotation() {
+ return protocolAnnotation;
+ }
+
+ /**
+ * Returns the properties node serializer.
+ *
+ * @return properties node serializer
+ */
+ public PropertiesNodeSerializer getPropNodeSerializer() {
+ return propNodeSerializer;
+ }
+} \ No newline at end of file
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultJsonListener.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultJsonListener.java
new file mode 100644
index 000000000..45317522a
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultJsonListener.java
@@ -0,0 +1,145 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType;
+
+import static java.lang.String.format;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.NODE_TYPE_ERR;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_LEAF_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_NODE;
+
+
+/**
+ * Representation of default implementation of JSON listener.
+ */
+public class DefaultJsonListener implements JsonListener {
+
+ /**
+ * Serializer helper to convert to properties node.
+ */
+ private SerializerHelper serializerHelper;
+
+ /**
+ * Name of the current JSON node.
+ */
+ private String name;
+
+ /**
+ * Module name of the current JSON node.
+ */
+ private String modName;
+
+ /**
+ * Value of the current JSON node.
+ */
+ private String value;
+
+ /**
+ * Value namespace of the current JSON node.
+ */
+ private String valueNs;
+
+ /**
+ * Creates an instance of default json listener with its serializer helper.
+ *
+ * @param serializerHelper serializer helper
+ */
+ public DefaultJsonListener(SerializerHelper serializerHelper) {
+ this.serializerHelper = serializerHelper;
+ }
+
+ @Override
+ public void enterJsonNode(String nodeName, JsonNode node,
+ NodeType nodeType) throws SvcLogicException {
+ getNodeName(nodeName, false);
+
+ switch (nodeType) {
+ case SINGLE_INSTANCE_LEAF_NODE:
+ getNodeName(node.asText(), true);
+ serializerHelper.addNode(name, modName, value, valueNs,
+ SINGLE_INSTANCE_LEAF_NODE);
+ break;
+
+ case MULTI_INSTANCE_LEAF_NODE:
+ getNodeName(node.asText(), true);
+ serializerHelper.addNode(name, modName, value, valueNs,
+ MULTI_INSTANCE_LEAF_NODE);
+ break;
+
+ case SINGLE_INSTANCE_NODE:
+ serializerHelper.addNode(name, modName, null, null,
+ SINGLE_INSTANCE_NODE);
+ break;
+
+ case MULTI_INSTANCE_NODE:
+ serializerHelper.addNode(name, modName, null, null,
+ MULTI_INSTANCE_NODE);
+ break;
+
+ default:
+ throw new SvcLogicException(format(NODE_TYPE_ERR,
+ nodeType.toString()));
+ }
+ }
+
+ @Override
+ public void exitJsonNode(JsonNode node) throws SvcLogicException {
+ serializerHelper.exitNode();
+ }
+
+ @Override
+ public SerializerHelper serializerHelper() {
+ return serializerHelper;
+ }
+
+ /**
+ * Parses the abstract JSON name and fills the node name and node
+ * namespace or value and value namespace of the current JSON node .
+ *
+ * @param abstractName full name value
+ * @param isVal if it is for value parsing
+ */
+ private void getNodeName(String abstractName, boolean isVal) {
+ String[] val = abstractName.split(":");
+ if (val.length == 2) {
+ if (isVal) {
+ valueNs = val[0];
+ value = val[1];
+ } else {
+ modName = val[0];
+ name = val[1];
+ }
+ } else {
+ if (isVal) {
+ value = val[0];
+ valueNs = null;
+ } else {
+ name = val[0];
+ modName = null;
+ }
+ }
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultJsonWalker.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultJsonWalker.java
new file mode 100644
index 000000000..47cb8b292
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultJsonWalker.java
@@ -0,0 +1,141 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeType;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import static com.fasterxml.jackson.databind.node.JsonNodeType.NUMBER;
+import static com.fasterxml.jackson.databind.node.JsonNodeType.STRING;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_LEAF_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_NODE;
+
+/**
+ * Implementation of JSON walker to walk through the nodes and process it.
+ */
+public class DefaultJsonWalker implements JsonWalker {
+
+ @Override
+ public void walk(JsonListener listener, JsonNode jsonNode) throws
+ SvcLogicException {
+ Iterator<Map.Entry<String, JsonNode>> children = jsonNode.fields();
+ while (children.hasNext()) {
+ Map.Entry<String, JsonNode> child = children.next();
+ JsonNode value = child.getValue();
+ String key = child.getKey();
+ if (value.isArray()) {
+ processMultiNodes(key, value, listener);
+ } else {
+ processSingleNode(key, value, listener);
+ }
+ }
+ }
+
+ /**
+ * Processes single instance node or leaf, by adding the node to from
+ * JSON and walking through all its children recursively.
+ *
+ * @param key JSON name
+ * @param value JSON node
+ * @param listener JSON listener
+ * @throws SvcLogicException when processing the node fails
+ */
+ private void processSingleNode(String key, JsonNode value,
+ JsonListener listener)
+ throws SvcLogicException {
+ NodeType nodeType;
+ if (!value.isContainerNode()) {
+ nodeType = SINGLE_INSTANCE_LEAF_NODE;
+ } else {
+ nodeType = SINGLE_INSTANCE_NODE;
+ }
+ processNode(key, value, nodeType, listener);
+ }
+
+ /**
+ * Processes multi instance node or leaf, by adding the node to from JSON
+ * and walking through all its instance recursively.
+ *
+ * @param key JSON name
+ * @param value JSON node
+ * @param listener JSON listener
+ * @throws SvcLogicException when processing a single instance fails
+ */
+ private void processMultiNodes(String key, JsonNode value,
+ JsonListener listener)
+ throws SvcLogicException {
+ NodeType nodeType;
+ Iterator<JsonNode> multiNodes = value.elements();
+ while (multiNodes.hasNext()) {
+ if (isLeafListNode((ArrayNode) value)) {
+ nodeType = MULTI_INSTANCE_LEAF_NODE;
+ } else {
+ nodeType = MULTI_INSTANCE_NODE;
+ }
+ JsonNode multiNode = multiNodes.next();
+ processNode(key, multiNode, nodeType, listener);
+ }
+ }
+
+ /**
+ * Processes each node by first entering the JSON node through JSON
+ * listener, second a call back to walking the rest of the tree of the
+ * node and finally exiting the node.
+ *
+ * @param key JSON name
+ * @param node JSON node
+ * @param nodeType JSON node type
+ * @param listener JSON listener
+ * @throws SvcLogicException when entering a JSON node fails
+ */
+ private void processNode(String key, JsonNode node, NodeType nodeType,
+ JsonListener listener) throws SvcLogicException {
+ listener.enterJsonNode(key, node, nodeType);
+ walk(listener, node);
+ listener.exitJsonNode(node);
+ }
+
+ /**
+ * Returns true if the node corresponds to a leaf-list node; false
+ * otherwise.
+ *
+ * @param node JSON node
+ * @return true if node corresponds to leaf-list node; false otherwise
+ */
+ private boolean isLeafListNode(ArrayNode node) {
+ Iterator<JsonNode> children = node.elements();
+ while (children.hasNext()) {
+ JsonNodeType type = children.next().getNodeType();
+ if (type != STRING && type != NUMBER) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultXmlListener.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultXmlListener.java
new file mode 100644
index 000000000..03abf44fd
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultXmlListener.java
@@ -0,0 +1,120 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import org.dom4j.Element;
+import org.dom4j.Namespace;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import java.util.List;
+
+import static java.lang.String.format;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.NODE_TYPE_ERR;
+
+/**
+ * Representation of default implementation of XML listener.
+ */
+public class DefaultXmlListener implements XmlListener {
+
+ /**
+ * Serializer helper to convert to properties node.
+ */
+ private SerializerHelper serializerHelper;
+
+ /**
+ * Creates an instance of default XML listener with its serializer helper.
+ *
+ * @param serializerHelper serializer helper
+ */
+ public DefaultXmlListener(SerializerHelper serializerHelper) {
+ this.serializerHelper = serializerHelper;
+ }
+
+ @Override
+ public void enterXmlElement(Element element, XmlNodeType nodeType)
+ throws SvcLogicException {
+ switch (nodeType) {
+ case TEXT_NODE:
+ serializerHelper.addNode(element.getName(),
+ element.getNamespace().getURI(),
+ element.getText(), null, null);
+ break;
+
+ case OBJECT_NODE:
+ List cont = element.content();
+ if (cont != null && cont.size() == 2 &&
+ isValueNsForLeaf(cont, element)) {
+ return;
+ }
+ serializerHelper.addNode(element.getName(),
+ element.getNamespace().getURI(),
+ null, null, null);
+ break;
+
+ default:
+ throw new SvcLogicException(format(NODE_TYPE_ERR,
+ nodeType.toString()));
+ }
+ }
+
+ /**
+ * Returns true if element has value namespace and adds the node to
+ * property tree; false otherwise.
+ *
+ * @param cont content of the element
+ * @param element element
+ * @return true if element has value namespace; false otherwise
+ * @throws SvcLogicException
+ */
+ private boolean isValueNsForLeaf(List cont, Element element)
+ throws SvcLogicException {
+ for (Object c : cont) {
+ if (c instanceof Namespace) {
+ String value = element.getText();
+ if (value != null) {
+ String[] val = value.split(":");
+ String valPrefix = val[0];
+ String actVal = val[1];
+ if (valPrefix != null && actVal != null &&
+ valPrefix.equals(((Namespace) c).getPrefix())) {
+ serializerHelper.addNode(
+ element.getName(),
+ element.getNamespace().getURI(),
+ actVal,
+ ((Namespace) c).getURI(), null);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void exitXmlElement(Element element) throws SvcLogicException {
+ serializerHelper.exitNode();
+ }
+
+ @Override
+ public SerializerHelper serializerHelper() {
+ return serializerHelper;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultXmlWalker.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultXmlWalker.java
new file mode 100644
index 000000000..cdc713f31
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultXmlWalker.java
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import org.dom4j.Element;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import java.util.Iterator;
+
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.getXmlNodeType;
+
+/**
+ * Implementation of XML walker to walk through the nodes and process it.
+ */
+public class DefaultXmlWalker implements XmlWalker {
+
+ @Override
+ public void walk(XmlListener listener, Element xmlElement) throws
+ SvcLogicException {
+ listener.enterXmlElement(xmlElement, getXmlNodeType(xmlElement));
+ if (xmlElement.hasContent() && !xmlElement.isTextOnly()) {
+ Iterator i = xmlElement.elementIterator();
+ while (i.hasNext()) {
+ Element childElement = (Element) i.next();
+ walk(listener, childElement);
+ }
+ }
+ listener.exitXmlElement(xmlElement);
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DfListenerFactory.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DfListenerFactory.java
new file mode 100644
index 000000000..06a811e15
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DfListenerFactory.java
@@ -0,0 +1,87 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static java.lang.String.format;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.FORMAT_ERR;
+
+/**
+ * Represents the data format listener factory which will return JSON or XML
+ * listener according to the serializer helper.
+ */
+public final class DfListenerFactory {
+
+ /**
+ * Creates a new DfListenerFactory.
+ */
+ private DfListenerFactory() {
+ }
+
+ /**
+ * Returns the instance of the data format listener factory.
+ *
+ * @return instance of the data format listener factory
+ */
+ public static DfListenerFactory instance() {
+ return DfListenerFactory.LazyHolder.INSTANCE;
+ }
+
+ /**
+ * Bill pugh singleton pattern. Instance will not be instantiated until
+ * the lazy holder class is loaded via a call to the instance of method
+ * below.
+ */
+ private static class LazyHolder {
+ private static final DfListenerFactory INSTANCE =
+ new DfListenerFactory();
+ }
+
+ /**
+ * Returns the data format listener by deciding it based on the format of
+ * the parameter.
+ *
+ * @param serHelper serializer helper
+ * @param params parameters
+ * @return data format listener
+ * @throws SvcLogicException when the data format type is wrong
+ */
+ public Listener getListener(SerializerHelper serHelper,
+ YangParameters params)
+ throws SvcLogicException {
+ Listener listener;
+ switch (params.format) {
+ case JSON:
+ listener = new DefaultJsonListener(serHelper);
+ break;
+
+ case XML:
+ listener = new DefaultXmlListener(serHelper);
+ break;
+
+ default:
+ throw new SvcLogicException(format(FORMAT_ERR,
+ params.format));
+ }
+ return listener;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DfSerializerFactory.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DfSerializerFactory.java
new file mode 100644
index 000000000..4d95235e5
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DfSerializerFactory.java
@@ -0,0 +1,87 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static java.lang.String.format;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.FORMAT_ERR;
+
+/**
+ * Represents the data format serializer factory which will return JSON or XML
+ * serializer according to the serializer context.
+ */
+public final class DfSerializerFactory {
+
+ /**
+ * Creates a new DfSerializerFactory.
+ */
+ private DfSerializerFactory() {
+ }
+
+ /**
+ * Returns the instance of the data format serializer factory.
+ *
+ * @return instance of the data format serializer factory
+ */
+ public static DfSerializerFactory instance() {
+ return DfSerializerFactory.LazyHolder.INSTANCE;
+ }
+
+ /**
+ * Bill pugh singleton pattern. Instance will not be instantiated until
+ * the lazy holder class is loaded via a call to the instance of method
+ * below.
+ */
+ private static class LazyHolder {
+ private static final DfSerializerFactory INSTANCE =
+ new DfSerializerFactory();
+ }
+
+ /**
+ * Returns the data format serializer by deciding it based on the format of
+ * the parameter.
+ *
+ * @param serCtx serializer context
+ * @param params parameters
+ * @return data format serializer
+ * @throws SvcLogicException when the data format type is wrong
+ */
+ public DataFormatSerializer getSerializer(DataFormatSerializerContext serCtx,
+ YangParameters params)
+ throws SvcLogicException {
+ DataFormatSerializer serializer;
+ switch (params.format) {
+ case JSON:
+ serializer = new JsonSerializer(serCtx);
+ break;
+
+ case XML:
+ serializer = new XmlSerializer(serCtx);
+ break;
+
+ default:
+ throw new SvcLogicException(format(FORMAT_ERR,
+ params.format));
+ }
+ return serializer;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DfSerializerUtil.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DfSerializerUtil.java
new file mode 100644
index 000000000..707c29444
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DfSerializerUtil.java
@@ -0,0 +1,231 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import org.dom4j.Element;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.Namespace;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Iterator;
+
+import static javax.xml.transform.OutputKeys.INDENT;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.XmlNodeType.OBJECT_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.XmlNodeType.TEXT_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getRevision;
+
+/**
+ * Utilities for data format serializer.
+ */
+public final class DfSerializerUtil {
+
+ static final String JSON_WRITE_ERR = "Unable to write to JSON from " +
+ "properties.";
+
+ static final String NODE_TYPE_ERR = "The node type %s is not supported.";
+
+ static final String JSON_LIS_ERR = "The JSON serializer doesn't have " +
+ "JSON listener";
+
+ static final String XML_LIS_ERR = "The XML serializer doesn't have XML " +
+ "listener";
+
+ static final String PROP_NODE_ERR = "The property node doesn't have " +
+ "schema node bound to it.";
+
+ static final String DF_ERR = "Type mismatch for the node %s. The schema " +
+ "node does not match with the data format node type %s.";
+
+ static final String XML_PREFIX = "yangid";
+
+ private static final String YES = "yes";
+
+ private static final String INDENT_XMLNS = "{http://xml.apache" +
+ ".org/xslt}indent-amount";
+
+ private static final String XML_PARSE_ERR = "Unable to parse the xml to " +
+ "document : \n";
+
+ private static final String URI_ERR = "Unable to parse the URI";
+
+ /**
+ * Data format error message for unsupported types.
+ */
+ public static final String FORMAT_ERR = "Only JSON and XML formats are " +
+ "supported. %s is not supported";
+
+ /**
+ * UTF header message for XML data format message.
+ */
+ public static final String UTF_HEADER = "<?xml version=\"1.0\" " +
+ "encoding=\"UTF-8\"?>";
+
+ /**
+ * Error message when a JSON tree creation fails.
+ */
+ public static final String JSON_TREE_ERR = "Unable to form JSON tree " +
+ "object from the JSON body provided.";
+
+ /**
+ * Error message when a XML tree creation fails.
+ */
+ public static final String XML_TREE_ERR = "Unable to form XML tree object" +
+ " from the XML body provided.";
+
+ //No instantiation.
+ private DfSerializerUtil() {
+ }
+
+ /**
+ * Returns the writer which contains the pretty formatted XML string.
+ *
+ * @param input input XML
+ * @param indent indentation level
+ * @return writer with XML
+ * @throws SvcLogicException when transformation of source fails
+ */
+ public static Writer getXmlWriter(String input, String indent)
+ throws SvcLogicException {
+ try {
+ Transformer transformer = TransformerFactory.newInstance()
+ .newTransformer();
+ transformer.setOutputProperty(INDENT, YES);
+ transformer.setOutputProperty(INDENT_XMLNS, indent);
+ StreamResult result = new StreamResult(new StringWriter());
+ DOMSource source = new DOMSource(parseXml(input));
+ transformer.transform(source, result);
+ return result.getWriter();
+ } catch (TransformerException e) {
+ throw new SvcLogicException(XML_PARSE_ERR + input, e);
+ }
+ }
+
+ /**
+ * Parses the XML and converts it into dom document which can be used for
+ * formatting the XML.
+ *
+ * @param in input XML
+ * @return dom document of XML
+ * @throws SvcLogicException when document building fails
+ */
+ private static Document parseXml(String in) throws SvcLogicException {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ DocumentBuilder db;
+ try {
+ db = dbf.newDocumentBuilder();
+ InputSource is = new InputSource(new StringReader(in));
+ return db.parse(is);
+ } catch (SAXException | IOException | ParserConfigurationException e) {
+ throw new SvcLogicException(XML_PARSE_ERR + in, e);
+ }
+ }
+
+ /**
+ * Returns the resolved namespace object from the input received from the
+ * abstract data format.
+ *
+ * @param mName module name
+ * @param mUri module URI
+ * @param ctx schema context
+ * @param parent parent properties node
+ * @return namespace
+ * @throws SvcLogicException when resolving namespace fails
+ */
+ static Namespace getResolvedNamespace(String mName, String mUri,
+ SchemaContext ctx,
+ PropertiesNode parent)
+ throws SvcLogicException {
+ if (mName == null && mUri == null) {
+ Namespace parentNs = parent.namespace();
+ return new Namespace(parentNs.moduleName(), parentNs.moduleNs(),
+ parentNs.revision());
+ }
+
+ Iterator<Module> it;
+ Module mod;
+ if (mName != null) {
+ it = ctx.findModules(mName).iterator();
+ } else {
+ URI modUri = null;
+ try {
+ modUri = new URI(mUri);
+ } catch (URISyntaxException e) {
+ throw new SvcLogicException(URI_ERR, e);
+ }
+ it = ctx.findModules(modUri).iterator();
+ }
+
+ if (!it.hasNext()) {
+ return null;
+ }
+ mod = it.next();
+
+ return new Namespace(mod.getName(), mod.getQNameModule().getNamespace(),
+ getRevision(mod.getRevision()));
+ }
+
+ /**
+ * Returns the node type of a XML element.
+ *
+ * @param element XML element
+ * @return node type of the XML element
+ */
+ static XmlNodeType getXmlNodeType(Element element) {
+ Element newElement = element.createCopy();
+ newElement.remove(element.getNamespace());
+ return newElement.hasContent() && newElement.isTextOnly() ?
+ TEXT_NODE : OBJECT_NODE;
+ }
+
+ /**
+ * Resolves the super type to the base type from type definition.
+ *
+ * @param type super type
+ * @return base type definition
+ */
+ static TypeDefinition<?> resolveBaseTypeFrom(TypeDefinition<?> type) {
+ TypeDefinition superType = type;
+ while (superType.getBaseType() != null) {
+ superType = superType.getBaseType();
+ }
+ return superType;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/JsonListener.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/JsonListener.java
new file mode 100644
index 000000000..89fd4c8c8
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/JsonListener.java
@@ -0,0 +1,55 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType;
+
+/**
+ * Abstraction of an entity which provides call back methods, which in turn
+ * are called by JSON walker while walking the JSON tree. This interface
+ * needs to be implemented by protocol, implementing listener based call
+ * while doing JSON walk.
+ */
+public interface JsonListener extends Listener {
+
+ /**
+ * Call back invoked during JSON node entry. All other related
+ * information can be obtained from the JSON node.
+ *
+ * @param nodeName JSON node name
+ * @param node JSON node
+ * @param nodeType JSON node type
+ * @throws SvcLogicException when node type is of wrong format
+ */
+ void enterJsonNode(String nodeName, JsonNode node, NodeType nodeType)
+ throws SvcLogicException;
+
+ /**
+ * Call back invoked during JSON node exit. All the related information
+ * can be obtained from the JSON node.
+ *
+ * @param node JSON node
+ * @throws SvcLogicException when JSON node exit doesn't happen
+ */
+ void exitJsonNode(JsonNode node) throws SvcLogicException;
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/JsonSerializer.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/JsonSerializer.java
new file mode 100644
index 000000000..91adb8126
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/JsonSerializer.java
@@ -0,0 +1,91 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.List;
+import java.util.Map;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.DefaultPropertiesNodeWalker;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNode;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNodeWalker;
+
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormat.JSON;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.JSON_LIS_ERR;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.JSON_TREE_ERR;
+
+/**
+ * Representation of JSON serializer which encodes properties to JSON and
+ * decodes properties from JSON with the data format serializer.
+ */
+public class JsonSerializer extends DataFormatSerializer {
+
+ /**
+ * Creates an instance of data format serializer.
+ *
+ * @param serializerContext data format serializer context
+ */
+ protected JsonSerializer(DataFormatSerializerContext serializerContext) {
+ super(JSON, serializerContext);
+ }
+
+ @Override
+ public String encode(Map<String, String> param,
+ Map<String, List<Annotation>> annotations)
+ throws SvcLogicException {
+ PropertiesNode propNode = serializerContext().getPropNodeSerializer()
+ .encode(param);
+ PropertiesNodeWalker nodeWalker = new DefaultPropertiesNodeWalker<>();
+ PropertiesNodeJsonListener jsonLis = new PropertiesNodeJsonListener();
+ nodeWalker.walk(jsonLis, propNode);
+ Writer writer = jsonLis.getWriter();
+ return writer.toString();
+ }
+
+ @Override
+ public Map<String, String> decode(String dataFormatBody)
+ throws SvcLogicException {
+ if (!(serializerContext().listener() instanceof JsonListener)) {
+ throw new SvcLogicException(JSON_LIS_ERR);
+ }
+
+ JsonListener listener = (JsonListener) serializerContext().listener();
+ JsonWalker walker = new DefaultJsonWalker();
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode jsonNode;
+
+ try {
+ jsonNode = mapper.readTree(dataFormatBody);
+ } catch (IOException e) {
+ throw new SvcLogicException(JSON_TREE_ERR, e);
+ }
+
+ walker.walk(listener, jsonNode);
+
+ return serializerContext().getPropNodeSerializer().decode(
+ listener.serializerHelper().getPropertiesNode());
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/JsonWalker.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/JsonWalker.java
new file mode 100644
index 000000000..588070a12
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/JsonWalker.java
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+/**
+ * Abstraction of an entity which provides interface for JSON walk. This
+ * interface serves as a common tool for anyone who needs to parse the JSON
+ * node with depth-first algorithm.
+ */
+public interface JsonWalker {
+
+ /**
+ * Walks the JSON data tree. Protocols implement JSON listener service
+ * and walks the JSON tree with input as implemented object. JSON walker
+ * provides call back to the implemented methods.
+ *
+ * @param listener JSON listener implemented by the protocol
+ * @param jsonNode root node of the JSON data tree
+ * @throws SvcLogicException when walking the JSON node fails
+ */
+ void walk(JsonListener listener, JsonNode jsonNode)
+ throws SvcLogicException;
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/Listener.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/Listener.java
new file mode 100644
index 000000000..e5812dbb7
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/Listener.java
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+/**
+ * Abstraction of listener.
+ */
+public interface Listener {
+
+ /**
+ * Returns serializer helper for this listener.
+ *
+ * @return serializer helper
+ */
+ SerializerHelper serializerHelper();
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/MdsalSerializerHelper.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/MdsalSerializerHelper.java
new file mode 100644
index 000000000..1fd0d2dee
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/MdsalSerializerHelper.java
@@ -0,0 +1,297 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.Namespace;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNode;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.RootNode;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.Revision;
+import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+
+import java.util.Deque;
+
+import static java.lang.String.format;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.DF_ERR;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.NODE_TYPE_ERR;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.PROP_NODE_ERR;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.getResolvedNamespace;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.resolveBaseTypeFrom;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getRevision;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_HOLDER_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_HOLDER_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_LEAF_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_NODE;
+import static org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils.findDataChildSchemaByQName;
+import static org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils.findSchemaForChild;
+import static org.opendaylight.yangtools.yang.data.util.ParserStreamUtils.findSchemaNodeByNameAndNamespace;
+
+/**
+ * Representation of MDSAL based serializer helper, which adds properties
+ * node to the properties tree based on its types.
+ */
+public class MdsalSerializerHelper extends SerializerHelper<SchemaNode, SchemaContext> {
+
+ /**
+ * Current properties node.
+ */
+ private PropertiesNode propNode;
+
+ /**
+ * Current schema node.
+ */
+ private SchemaNode curSchemaNode;
+
+
+ /**
+ * Creates MDSAL serializer helper with root schema node, schema context
+ * and URI.
+ *
+ * @param n schema node of the URI's last node
+ * @param c schema context
+ * @param u URI of the request
+ */
+ public MdsalSerializerHelper(SchemaNode n, SchemaContext c,
+ String u) {
+ super(n, c, u);
+ Namespace ns = new Namespace(n.getQName().getLocalName(),
+ n.getQName().getNamespace(),
+ getRevision(n.getQName().getRevision()));
+ propNode = new RootNode<>(n.getQName().getLocalName(), ns,
+ getSchemaNode(), u);
+ curSchemaNode = getSchemaNode();
+ }
+
+ @Override
+ protected SchemaNode getSchemaNode() {
+ return schemaNode;
+ }
+
+ @Override
+ protected SchemaContext getSchemaCtx() {
+ return schemaCtx;
+ }
+
+ @Override
+ protected SchemaNode getCurSchema() {
+ return curSchemaNode;
+ }
+
+ @Override
+ protected void addNode(String name, String nameSpace, String value,
+ String valNameSpace, NodeType type)
+ throws SvcLogicException {
+ Namespace ns;
+ if (type == null) {
+ ns = getResolvedNamespace(null, nameSpace,
+ getSchemaCtx(), propNode);
+ } else {
+ ns = getResolvedNamespace(nameSpace, null,
+ getSchemaCtx(), propNode);
+ }
+ if (isChildPresent(name, ns)) {
+ addNodeToProperty(name, ns, value, valNameSpace, type);
+ } else {
+ throw new SvcLogicException(format(
+ "Unable to add the node %s", name));
+ }
+ }
+
+ @Override
+ protected void exitNode() throws SvcLogicException {
+ propNode = propNode.parent();
+ if (propNode != null) {
+ NodeType type = propNode.nodeType();
+ if (type == MULTI_INSTANCE_HOLDER_NODE ||
+ type == MULTI_INSTANCE_LEAF_HOLDER_NODE) {
+ propNode = propNode.parent();
+ }
+ }
+ if (propNode == null || propNode.appInfo() == null
+ || !(propNode.appInfo() instanceof SchemaNode)) {
+ throw new SvcLogicException(PROP_NODE_ERR);
+ }
+ curSchemaNode = (SchemaNode) propNode.appInfo();
+ }
+
+ @Override
+ protected PropertiesNode getPropertiesNode() {
+ return propNode;
+ }
+
+ /**
+ * Adds the node to property node based on the type of the schema node,
+ * which is decided based on the name and namespace of the input
+ * information.
+ *
+ * @param name name of the node
+ * @param ns namespace of the node
+ * @param value value of the node if its a leaf/leaf-list
+ * @param valNamespace namespace of the value
+ * @param type type of the node
+ * @throws SvcLogicException when adding child fails
+ */
+ private void addNodeToProperty(String name, Namespace ns, String value,
+ String valNamespace, NodeType type)
+ throws SvcLogicException {
+ Namespace valueNs;
+ if (type != null) {
+ validateNodeType(type);
+ }
+ if (curSchemaNode instanceof LeafSchemaNode) {
+ valueNs = getValueNs(curSchemaNode, valNamespace, type);
+ propNode = propNode.addChild(name, ns,
+ SINGLE_INSTANCE_LEAF_NODE,
+ value, valueNs, curSchemaNode);
+ } else if (curSchemaNode instanceof LeafListSchemaNode) {
+ valueNs = getValueNs(curSchemaNode, valNamespace, type);
+ propNode = propNode.addChild(null, name, ns,
+ MULTI_INSTANCE_LEAF_NODE, value,
+ valueNs, curSchemaNode);
+ } else if (curSchemaNode instanceof ListSchemaNode) {
+ propNode = propNode.addChild(null, name, ns, MULTI_INSTANCE_NODE,
+ curSchemaNode);
+ } else {
+ propNode = propNode.addChild(name, ns, SINGLE_INSTANCE_NODE,
+ curSchemaNode);
+ }
+ }
+
+ /**
+ * Returns the namespace of the value namespace in case of identity ref.
+ *
+ * @param schemaNode schema node
+ * @param valNs value name space
+ * @param nodeType node type
+ * @return namespace of value namespace
+ * @throws SvcLogicException when namespace resolution fails for identityref
+ */
+ private Namespace getValueNs(SchemaNode schemaNode, String valNs,
+ NodeType nodeType) throws SvcLogicException {
+ Namespace ns = null;
+ if (valNs != null) {
+ TypeDefinition type;
+ if (schemaNode instanceof LeafSchemaNode) {
+ type = ((LeafSchemaNode) schemaNode).getType();
+ } else {
+ type = ((LeafListSchemaNode) schemaNode).getType();
+ }
+ TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
+ if (baseType instanceof IdentityrefTypeDefinition) {
+ if (nodeType == null) {
+ ns = getResolvedNamespace(null, valNs, getSchemaCtx(),
+ propNode);
+ } else {
+ ns = getResolvedNamespace(valNs, null, getSchemaCtx(),
+ propNode);
+ }
+ }
+ }
+ return ns;
+ }
+
+ /**
+ * Validates that the node type from the data format matches with that of
+ * the corresponding schema node.
+ *
+ * @param type node type from the abstract data format
+ * @throws SvcLogicException when the node type is wrong
+ */
+ private void validateNodeType(NodeType type) throws SvcLogicException {
+ boolean verify;
+ switch (type) {
+ case SINGLE_INSTANCE_LEAF_NODE:
+ verify = curSchemaNode instanceof LeafSchemaNode;
+ break;
+
+ case MULTI_INSTANCE_LEAF_NODE:
+ verify = curSchemaNode instanceof LeafListSchemaNode;
+ break;
+
+ case MULTI_INSTANCE_NODE:
+ verify = curSchemaNode instanceof ListSchemaNode;
+ break;
+
+ case SINGLE_INSTANCE_NODE:
+ verify = (!(curSchemaNode instanceof LeafSchemaNode) &&
+ !(curSchemaNode instanceof LeafListSchemaNode) &&
+ !(curSchemaNode instanceof ListSchemaNode));
+ break;
+
+ default:
+ throw new SvcLogicException(format(NODE_TYPE_ERR,
+ type.toString()));
+ }
+ if (!verify) {
+ throw new SvcLogicException(format(DF_ERR, curSchemaNode
+ .getQName().getLocalName(), type.toString()));
+ }
+ }
+
+ /**
+ * Returns true if the child schema is present with the name and
+ * namespace inside the current schema node, if present updates the
+ * current schema node; false otherwise.
+ *
+ * @param name name of the child schema node
+ * @param namespace namespace of the child schema node
+ * @return returns true if the child schema is available; false otherwise
+ */
+ private boolean isChildPresent(String name, Namespace namespace) {
+ QName qname = QName.create(namespace.moduleNs(),
+ Revision.of(namespace.revision()), name);
+ SchemaNode childNode = null;
+ if (curSchemaNode instanceof DataSchemaNode) {
+ Deque<DataSchemaNode> dataSchema = findSchemaNodeByNameAndNamespace(
+ (DataSchemaNode) curSchemaNode, name, namespace.moduleNs());
+
+ if (dataSchema != null && !dataSchema.isEmpty()) {
+ childNode = dataSchema.pop();
+ }
+
+ if (dataSchema != null && !dataSchema.isEmpty()) {
+ childNode = findSchemaForChild(((ChoiceSchemaNode) childNode),
+ qname);
+ }
+
+ } else {
+ childNode = findDataChildSchemaByQName(curSchemaNode, qname);
+ }
+
+ if (childNode != null) {
+ curSchemaNode = childNode;
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/PropertiesNodeJsonListener.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/PropertiesNodeJsonListener.java
new file mode 100644
index 000000000..0f03039e5
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/PropertiesNodeJsonListener.java
@@ -0,0 +1,233 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import com.google.gson.stream.JsonWriter;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Collection;
+import java.util.Map;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.DefaultPropertiesNodeWalker;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.LeafNode;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.Namespace;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNode;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNodeListener;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.RootNode;
+
+import static com.google.common.base.Strings.repeat;
+import static java.lang.String.format;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.JSON_WRITE_ERR;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.NODE_TYPE_ERR;
+
+/**
+ * Representation of JSON implementation of properties node listener.
+ */
+public class PropertiesNodeJsonListener implements PropertiesNodeListener{
+
+ /**
+ * JSON writer to write the JSON data format.
+ */
+ private JsonWriter jsonWriter;
+
+ /**
+ * Writer to write the JSON.
+ */
+ private Writer writer;
+
+ /**
+ * Creates the properties node JSON listener by instantiating and
+ * indenting the writer.
+ */
+ public PropertiesNodeJsonListener() {
+ writer = new StringWriter();
+ jsonWriter = new JsonWriter(writer);
+ jsonWriter.setIndent(repeat(" ", 4));
+ }
+
+ @Override
+ public void start(PropertiesNode node) throws SvcLogicException {
+ try {
+ jsonWriter.beginObject();
+ } catch (IOException e) {
+ throw new SvcLogicException(JSON_WRITE_ERR, e);
+ }
+ }
+
+ @Override
+ public void end(PropertiesNode node) throws SvcLogicException {
+ try {
+ jsonWriter.endObject();
+ jsonWriter.flush();
+ } catch (IOException e) {
+ throw new SvcLogicException(JSON_WRITE_ERR, e);
+ }
+ }
+
+ @Override
+ public void enterPropertiesNode(PropertiesNode node)
+ throws SvcLogicException {
+ String val;
+ String nodeName = getNodeName(node);
+ try {
+ switch (node.nodeType()) {
+ case SINGLE_INSTANCE_NODE:
+ jsonWriter.name(nodeName);
+ jsonWriter.beginObject();
+ break;
+
+ case MULTI_INSTANCE_NODE:
+ jsonWriter.beginObject();
+ break;
+
+ case SINGLE_INSTANCE_LEAF_NODE:
+ val = getValueWithNs((LeafNode) node);
+ jsonWriter.name(nodeName).value(val);
+ break;
+
+ case MULTI_INSTANCE_HOLDER_NODE:
+ case MULTI_INSTANCE_LEAF_HOLDER_NODE:
+ jsonWriter.name(nodeName);
+ jsonWriter.beginArray();
+ break;
+
+ case MULTI_INSTANCE_LEAF_NODE:
+ val = getValueWithNs((LeafNode) node);
+ jsonWriter.value(val);
+ break;
+
+ case ANY_XML_NODE:
+ jsonWriter.name(nodeName);
+ val = ((LeafNode) node).value();
+ try {
+ jsonWriter.jsonValue(val);
+ } catch (IOException e) {
+ throw new SvcLogicException(JSON_WRITE_ERR, e);
+ }
+ break;
+
+ default:
+ throw new SvcLogicException(format(
+ NODE_TYPE_ERR, node.nodeType().toString()));
+
+ }
+ } catch (IOException e) {
+ throw new SvcLogicException(JSON_WRITE_ERR, e);
+ }
+ }
+
+ @Override
+ public void exitPropertiesNode(PropertiesNode node) throws SvcLogicException {
+ walkAugmentationNode(node);
+ try {
+ switch (node.nodeType()) {
+ case SINGLE_INSTANCE_NODE:
+ case MULTI_INSTANCE_NODE:
+ jsonWriter.endObject();
+ break;
+
+ case MULTI_INSTANCE_HOLDER_NODE:
+ case MULTI_INSTANCE_LEAF_HOLDER_NODE:
+ jsonWriter.endArray();
+ break;
+
+ case SINGLE_INSTANCE_LEAF_NODE:
+ case MULTI_INSTANCE_LEAF_NODE:
+ case ANY_XML_NODE:
+ break;
+
+ default:
+ throw new SvcLogicException(format(
+ NODE_TYPE_ERR, node.nodeType().toString()));
+ }
+ } catch (IOException e) {
+ throw new SvcLogicException(JSON_WRITE_ERR, e);
+ }
+ }
+
+ /**
+ * Returns the writer.
+ *
+ * @return writer
+ */
+ public Writer getWriter() {
+ return writer;
+ }
+
+ /**
+ * Returns the abstract JSON node name to be used in JSON data format
+ * from the properties node.
+ *
+ * @param node properties node
+ * @return abstract JSON node
+ */
+ private String getNodeName(PropertiesNode node) {
+ PropertiesNode parent = node.parent();
+ if (parent instanceof RootNode || !parent.namespace().moduleName()
+ .equals(node.namespace().moduleName())) {
+ if (!parent.nonAppend()) {
+ return node.namespace().moduleName() + ":" + node.name();
+ }
+ }
+ return node.name();
+ }
+
+ /**
+ * Returns the value of JSON leaf node with module name if required.
+ *
+ * @param node properties node
+ * @return value with namespace
+ */
+ private String getValueWithNs(LeafNode node) {
+ Namespace valNs = node.valueNs();
+ String modName = (valNs == null) ? null : valNs.moduleName();
+ if (modName != null) {
+ return modName + ":" + node.value();
+ }
+ return node.value();
+ }
+
+ /**
+ * Gets all the augmentation of the given node and walks through it.
+ *
+ * @param node properties node
+ * @throws SvcLogicException when walking the properties node fails
+ */
+ private void walkAugmentationNode(PropertiesNode node)
+ throws SvcLogicException {
+ for (Map.Entry<Object, Collection<PropertiesNode>>
+ augToChild : node.augmentations().asMap().entrySet()) {
+ Collection<PropertiesNode> augChild = augToChild.getValue();
+ if (!augChild.isEmpty()) {
+ DefaultPropertiesNodeWalker walker = new
+ DefaultPropertiesNodeWalker();
+ for (PropertiesNode p : augChild) {
+ enterPropertiesNode(p);
+ walker.walkChildNode(this, p);
+ exitPropertiesNode(p);
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/PropertiesNodeXmlListener.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/PropertiesNodeXmlListener.java
new file mode 100644
index 000000000..f098195e4
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/PropertiesNodeXmlListener.java
@@ -0,0 +1,246 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.DefaultPropertiesNodeWalker;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.LeafNode;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.Namespace;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNode;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNodeListener;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.RootNode;
+
+import java.io.Writer;
+import java.net.URI;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Stack;
+
+import static java.lang.String.format;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.NODE_TYPE_ERR;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.UTF_HEADER;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.XML_PREFIX;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.getXmlWriter;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_HOLDER_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_HOLDER_NODE;
+
+/**
+ * Representation of XML implementation of properties node listener.
+ */
+public class PropertiesNodeXmlListener implements PropertiesNodeListener {
+
+ /**
+ * XML data from the element.
+ */
+ private String xmlData;
+
+ /**
+ * Root element of the XML document.
+ */
+ private Element rootElement;
+
+ /**
+ * Writer to write the XML.
+ */
+ private Writer writer;
+
+ /**
+ * XML element stack to store the elements.
+ */
+ private final Stack<Element> elementStack = new Stack<>();
+
+ /**
+ * Creates the properties node XML listener.
+ */
+ public PropertiesNodeXmlListener() {
+ }
+
+ @Override
+ public void start(PropertiesNode node) {
+ rootElement = addElement(null, node);
+ elementStack.push(rootElement);
+ }
+
+ @Override
+ public void end(PropertiesNode node) throws SvcLogicException {
+ xmlData = rootElement.asXML();
+ xmlData = UTF_HEADER + xmlData;
+ writer = getXmlWriter(xmlData, "4");
+ }
+
+ @Override
+ public void enterPropertiesNode(PropertiesNode node)
+ throws SvcLogicException {
+ Element element = null;
+ String ns = getNodeNamespace(node);
+ switch (node.nodeType()) {
+ case MULTI_INSTANCE_LEAF_HOLDER_NODE:
+ case MULTI_INSTANCE_HOLDER_NODE:
+ break;
+
+ case SINGLE_INSTANCE_NODE:
+ case MULTI_INSTANCE_NODE:
+ element = addElement(ns, node);
+ break;
+
+ case MULTI_INSTANCE_LEAF_NODE:
+ case SINGLE_INSTANCE_LEAF_NODE:
+ element = addElement(ns, node);
+ setValueWithNs(element, (LeafNode) node);
+ break;
+
+ default:
+ throw new SvcLogicException(format(
+ NODE_TYPE_ERR, node.nodeType().toString()));
+ }
+ if (element != null) {
+ elementStack.push(element);
+ }
+ }
+
+ @Override
+ public void exitPropertiesNode(PropertiesNode node)
+ throws SvcLogicException {
+ walkAugmentationNode(node);
+ switch (node.nodeType()) {
+ case MULTI_INSTANCE_LEAF_HOLDER_NODE:
+ case MULTI_INSTANCE_HOLDER_NODE:
+ break;
+
+ case SINGLE_INSTANCE_NODE:
+ case MULTI_INSTANCE_NODE:
+ case MULTI_INSTANCE_LEAF_NODE:
+ case SINGLE_INSTANCE_LEAF_NODE:
+ if (!elementStack.isEmpty()) {
+ elementStack.pop();
+ }
+ break;
+
+ default:
+ throw new SvcLogicException(format(
+ NODE_TYPE_ERR, node.nodeType().toString()));
+ }
+ }
+
+ /**
+ * Returns the writer.
+ *
+ * @return writer
+ */
+ public Writer getWriter() {
+ return writer;
+ }
+
+ /**
+ * Adds an XML element to the stack with namespace if present. If the
+ * stack is empty it creates new document and adds element else adds to
+ * the parent element.
+ *
+ * @param ns namespace of the element
+ * @param node properties node
+ * @return new added element
+ */
+ private Element addElement(String ns, PropertiesNode node) {
+ Element element;
+ if (elementStack.isEmpty()) {
+ Document doc = DocumentHelper.createDocument();
+ if (ns != null) {
+ element = doc.addElement(node.name(), ns);
+ } else {
+ element = doc.addElement(node.name());
+ }
+ } else {
+ element = elementStack.peek();
+ if (ns != null) {
+ element = element.addElement(node.name(), ns);
+ } else {
+ element = element.addElement(node.name());
+ }
+ }
+
+ return element;
+ }
+
+ /**
+ * Returns the abstract XML namespace to be used in XML data format from
+ * the properties node.
+ *
+ * @param node properties node
+ * @return abstract XML namespace
+ */
+ private String getNodeNamespace(PropertiesNode node) {
+ PropertiesNode parent = node.parent();
+ if (parent.nodeType() == MULTI_INSTANCE_HOLDER_NODE ||
+ parent.nodeType() == MULTI_INSTANCE_LEAF_HOLDER_NODE) {
+ parent = parent.parent();
+ }
+ if (parent instanceof RootNode || ! parent.namespace().moduleName()
+ .equals(node.namespace().moduleName())) {
+ return node.namespace().moduleNs().toString();
+ }
+ return null;
+ }
+
+ /**
+ * Sets the value to the element for a leaf node and adds the value
+ * namespace if required.
+ *
+ * @param element XML element
+ * @param node leaf properties node
+ */
+ private void setValueWithNs(Element element, LeafNode node) {
+ Namespace valNs = node.valueNs();
+ URI modNs = (valNs == null) ? null : valNs.moduleNs();
+ String val = node.value();
+ if (modNs != null) {
+ element.addNamespace(XML_PREFIX, modNs.toString());
+ element.setText(XML_PREFIX + ":" + val);
+ } else {
+ element.setText(val);
+ }
+ }
+
+ /**
+ * Gets all the augmentation of the given node and walks through it.
+ *
+ * @param node properties node
+ * @throws SvcLogicException when walking the properties node fails
+ */
+ private void walkAugmentationNode(PropertiesNode node)
+ throws SvcLogicException {
+ for (Map.Entry<Object, Collection<PropertiesNode>>
+ augToChild : node.augmentations().asMap().entrySet()) {
+ Collection<PropertiesNode> augChild = augToChild.getValue();
+ if (!augChild.isEmpty()) {
+ DefaultPropertiesNodeWalker walker = new
+ DefaultPropertiesNodeWalker();
+ for (PropertiesNode p : augChild) {
+ enterPropertiesNode(p);
+ walker.walkChildNode(this, p);
+ exitPropertiesNode(p);
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/SerializerHelper.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/SerializerHelper.java
new file mode 100644
index 000000000..db9befb21
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/SerializerHelper.java
@@ -0,0 +1,116 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNode;
+
+/**
+ * Abstraction of an entity which helps the data format serializers to obtain
+ * schema context details and to build properties from data.
+ *
+ * @param <T> type of schema node
+ * @param <P> type of schema context
+ */
+public abstract class SerializerHelper<T, P> {
+
+ /**
+ * Schema node of the last element in the URI.
+ */
+ protected T schemaNode;
+
+ /**
+ * Root schema context.
+ */
+ protected P schemaCtx;
+
+ /**
+ * Root URI.
+ */
+ protected String rootUri;
+
+ /**
+ * Creates an instance of the serializer helper with the schema node,
+ * schema context and the URI.
+ *
+ * @param t schema node
+ * @param p schema context
+ * @param u root URI
+ */
+ protected SerializerHelper(T t, P p, String u) {
+ schemaNode = t;
+ schemaCtx = p;
+ rootUri = u;
+ }
+
+ /**
+ * Returns schema node of the last element in the URI.
+ *
+ * @return schema node
+ */
+ protected abstract T getSchemaNode();
+
+ /**
+ * Returns the root schema context.
+ *
+ * @return schema context
+ */
+ protected abstract P getSchemaCtx();
+
+ /**
+ * Returns the current schema context node.
+ *
+ * @return current schema context node
+ */
+ protected abstract T getCurSchema();
+
+ /**
+ * Adds a node to the properties node tree.
+ *
+ * @param name name of the node
+ * @param nameSpace name space of the node, it can be either module
+ * name or namespace; null indicates parent namespace
+ * @param value value of the node; applicable for leaf/leaf-list node
+ * @param valNameSpace value namespace for identityref, could be module
+ * name or namespace
+ * @param type type of node if known like in case of JSON
+ * @throws SvcLogicException when adding node fails
+ */
+ protected abstract void addNode(String name, String nameSpace, String value,
+ String valNameSpace, NodeType type)
+ throws SvcLogicException;
+
+ /**
+ * Exits the node, in case if it's leaf node then it adds to the properties
+ * map.
+ *
+ * @throws SvcLogicException when properties node tree is improper
+ */
+ protected abstract void exitNode() throws SvcLogicException;
+
+ /**
+ * Returns the built properties corresponding to the data.
+ *
+ * @return properties node.
+ */
+ protected abstract PropertiesNode getPropertiesNode();
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/XmlListener.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/XmlListener.java
new file mode 100644
index 000000000..784e7af1f
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/XmlListener.java
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import org.dom4j.Element;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+/**
+ * Abstraction of an entity which provides call back methods, which in turn
+ * are called by XML walker while walking the XML tree. This interface needs
+ * to be implemented by protocol implementing listener based call while doing
+ * XML walk.
+ */
+public interface XmlListener extends Listener {
+
+ /**
+ * Callback invoked during a node entry. All the related information
+ * about the node can be obtained from the element.
+ *
+ * @param element current XML element
+ * @param nodeType node type of the element
+ * @throws SvcLogicException when node type is of wrong format
+ */
+ void enterXmlElement(Element element, XmlNodeType nodeType)
+ throws SvcLogicException;
+
+ /**
+ * Callback invoked during a node exit. All the related information about
+ * the node can be obtained from the element.
+ *
+ * @param element current xml element.
+ * @throws SvcLogicException when XML node exit doesn't happen
+ */
+ void exitXmlElement(Element element) throws SvcLogicException;
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/XmlNodeType.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/XmlNodeType.java
new file mode 100644
index 000000000..7a6db3c86
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/XmlNodeType.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+/**
+ * Represents the XML node type.
+ */
+public enum XmlNodeType {
+
+ /**
+ * Object XML node type.
+ */
+ OBJECT_NODE,
+
+ /**
+ * Text XML node type.
+ */
+ TEXT_NODE
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/XmlSerializer.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/XmlSerializer.java
new file mode 100644
index 000000000..f3c6723e1
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/XmlSerializer.java
@@ -0,0 +1,104 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.DocumentHelper;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.DefaultPropertiesNodeWalker;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNode;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNodeWalker;
+
+import java.io.Writer;
+import java.util.List;
+import java.util.Map;
+
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormat.XML;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.XML_LIS_ERR;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.XML_TREE_ERR;
+
+/**
+ * Representation of XML serializer which encodes properties to XML and
+ * decodes properties from XML with the data format serializer.
+ */
+public class XmlSerializer extends DataFormatSerializer {
+
+ /**
+ * Creates an instance of XML serializer.
+ *
+ * @param serializerContext data format serializer context
+ */
+ protected XmlSerializer(DataFormatSerializerContext serializerContext) {
+ super(XML, serializerContext);
+ }
+
+ @Override
+ public String encode(Map<String, String> param,
+ Map<String, List<Annotation>> annotations)
+ throws SvcLogicException {
+ PropertiesNode propNode = serializerContext().getPropNodeSerializer()
+ .encode(param);
+ PropertiesNodeWalker nodeWalker = new DefaultPropertiesNodeWalker<>();
+ PropertiesNodeXmlListener xmlListener = new PropertiesNodeXmlListener();
+ nodeWalker.walk(xmlListener, propNode);
+ Writer writer = xmlListener.getWriter();
+ return removeRootNode(writer.toString(), propNode.name());
+ }
+
+ @Override
+ public Map<String, String> decode(String dataFormatBody)
+ throws SvcLogicException {
+ if (!(serializerContext().listener() instanceof XmlListener)) {
+ throw new SvcLogicException(XML_LIS_ERR);
+ }
+
+ XmlListener listener = (XmlListener) serializerContext().listener();
+ XmlWalker walker = new DefaultXmlWalker();
+ Document document;
+
+ try {
+ document = DocumentHelper.parseText(dataFormatBody);
+ } catch (DocumentException e) {
+ throw new SvcLogicException(XML_TREE_ERR, e);
+ }
+ walker.walk(listener, document.getRootElement());
+
+ return serializerContext().getPropNodeSerializer().decode(
+ listener.serializerHelper().getPropertiesNode());
+ }
+
+ /**
+ * Removes root node from the XML data format message and makes the
+ * string to be pretty print.
+ *
+ * @param xml XML data format message
+ * @param rootName root node name
+ * @return pretty print format XML message
+ */
+ private static String removeRootNode(String xml, String rootName) {
+ xml = xml.replace("\n<" + rootName + ">", "\n");
+ xml = xml.replace("</" + rootName + ">" + "\n", "");
+ xml = xml.replaceAll("\n" + " ", "\n");
+ xml = xml.replaceFirst("\n", "");
+ return xml;
+ }
+} \ No newline at end of file
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/XmlWalker.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/XmlWalker.java
new file mode 100644
index 000000000..3835faa7e
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/XmlWalker.java
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import org.dom4j.Element;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+/**
+ * Abstraction of an entity which provides interface for XML walk. This
+ * interface serves as a common tool for anyone who needs to parse the XML
+ * node with depth-first algorithm.
+ */
+public interface XmlWalker {
+
+ /**
+ * Walks the XML data tree. Protocols implement XML listener service and
+ * walks the XML tree with input as implemented object. XML walker
+ * provides call back to the implemented methods.
+ *
+ * @param listener XML listener implemented by the protocol
+ * @param xmlElement root element of the XML data tree
+ * @throws SvcLogicException when walking the XML node fails
+ */
+ void walk(XmlListener listener, Element xmlElement) throws
+ SvcLogicException;
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/YangParameters.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/YangParameters.java
new file mode 100644
index 000000000..8eb3fb6e8
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/YangParameters.java
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright © 2018 IBM
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
+
+import org.onap.ccsdk.sli.plugins.restapicall.Parameters;
+
+/**
+ * Representation of the YANG parameters for the restconf api call node.
+ */
+public class YangParameters extends Parameters {
+ /**
+ * Directory path of the YANG file.
+ */
+ public String dirPath;
+
+ /**
+ * Creates an instance of the YANG parameters.
+ */
+ public YangParameters() {
+ super();
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/DataNodeChild.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/DataNodeChild.java
new file mode 100644
index 000000000..7be54690a
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/DataNodeChild.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+/**
+ * Abstraction of entity representing child's to data node.
+ */
+public interface DataNodeChild extends NodeChild {
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/DefaultPropertiesNodeListener.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/DefaultPropertiesNodeListener.java
new file mode 100644
index 000000000..2fa00bfb7
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/DefaultPropertiesNodeListener.java
@@ -0,0 +1,105 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.COLON;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.UNDERSCORE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_LEAF_NODE;
+
+/**
+ * Represents implementation of PropertiesNodeListener.
+ */
+public class DefaultPropertiesNodeListener implements PropertiesNodeListener {
+
+ private Map<String, String> params = new HashMap<>();
+
+ @Override
+ public void start(PropertiesNode node) {
+ // do nothing
+ }
+
+ @Override
+ public void end(PropertiesNode node) throws SvcLogicException {
+ exitPropertiesNode(node);
+ }
+
+ @Override
+ public void enterPropertiesNode(PropertiesNode node) {
+ /*
+ * Only if it is leaf node or leaf-list node,
+ * then create a property entry and add to map
+ */
+ if (node.nodeType() == SINGLE_INSTANCE_LEAF_NODE
+ || node.nodeType() == MULTI_INSTANCE_LEAF_NODE) {
+ String val = ((LeafNode) node).value();
+ if (((LeafNode) node).valueNs() != null) {
+ val = ((LeafNode) node).valueNs().moduleName() + COLON + val;
+ }
+ String uri = node.uri().replaceAll(COLON, UNDERSCORE);
+ params.put(uri, val);
+ }
+ }
+
+ @Override
+ public void exitPropertiesNode(PropertiesNode node) throws
+ SvcLogicException {
+ if (!node.augmentations().isEmpty()) {
+ for (Map.Entry<Object, Collection<PropertiesNode>> augmentationTochild
+ : node.augmentations().asMap().entrySet()) {
+ Collection<PropertiesNode> childsFromAugmentations = augmentationTochild
+ .getValue();
+ if (!childsFromAugmentations.isEmpty()) {
+ PropertiesNodeWalker walker = new DefaultPropertiesNodeWalker<>();
+ for (PropertiesNode pNode : childsFromAugmentations) {
+ enterPropertiesNode(pNode);
+ walker.walk(this, pNode);
+ exitPropertiesNode(pNode);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns properties.
+ *
+ * @return properties
+ */
+ public Map<String, String> params() {
+ return params;
+ }
+
+ /**
+ * Sets properties.
+ *
+ * @param params properties
+ */
+ public void params(Map<String, String> params) {
+ this.params = params;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/DefaultPropertiesNodeWalker.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/DefaultPropertiesNodeWalker.java
new file mode 100644
index 000000000..5034530d5
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/DefaultPropertiesNodeWalker.java
@@ -0,0 +1,119 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+/**
+ * Implementation of properties node walker which helps in forming a new tree from properties node.
+ *
+ * @param <T> node child of properties node.
+ */
+public class DefaultPropertiesNodeWalker<T extends NodeChild> implements PropertiesNodeWalker {
+
+ @Override
+ public void walk(PropertiesNodeListener listener,
+ PropertiesNode propertiesNode) throws SvcLogicException {
+ listener.start(propertiesNode);
+ walkChildNode(listener, propertiesNode);
+ listener.end(propertiesNode);
+ }
+
+ /**
+ * Walks the children node from the parent node.
+ *
+ * @param listener properties node listener
+ * @param propertiesNode properties node
+ * @throws SvcLogicException when properties node walking fails
+ */
+ public void walkChildNode(PropertiesNodeListener listener,
+ PropertiesNode propertiesNode)
+ throws SvcLogicException {
+ Map<String, T> children = getChildren(propertiesNode);
+ if (children != null) {
+ for (Map.Entry<String, T> entry : children.entrySet()) {
+ PropertiesNode node = ((PropertiesNode) entry.getValue());
+ listener.enterPropertiesNode(node);
+ walkChildNode(listener, node);
+ listener.exitPropertiesNode(node);
+ }
+ }
+ if (propertiesNode instanceof RootNode) {
+ processAugments(propertiesNode, listener);
+ }
+ }
+
+ /**
+ * Processes the augments present in the root node.
+ *
+ * @param node root node
+ * @param listener properties node listener
+ * @throws SvcLogicException when augment node walking fails
+ */
+ private void processAugments(PropertiesNode node,
+ PropertiesNodeListener listener)
+ throws SvcLogicException {
+ for (Map.Entry<Object, Collection<PropertiesNode>>
+ augToChild : node.augmentations().asMap().entrySet()) {
+ Collection<PropertiesNode> child = augToChild.getValue();
+ if (!child.isEmpty()) {
+ for (PropertiesNode p : child) {
+ listener.enterPropertiesNode(p);
+ walkChildNode(listener, p);
+ listener.exitPropertiesNode(p);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the children node according to the property node type.
+ *
+ * @param value property node
+ * @return property node children
+ */
+ private Map<String,T> getChildren(PropertiesNode value) {
+ if (value instanceof RootNode) {
+ return ((RootNode) value).children();
+ }
+ switch (value.nodeType()) {
+ case SINGLE_INSTANCE_NODE:
+ return ((InnerNode) value).children();
+ case MULTI_INSTANCE_HOLDER_NODE:
+ return ((Map<String, T>) ((ListHolderNode) value).children());
+ case MULTI_INSTANCE_NODE:
+ return ((Map<String, T>) ((MultiInstanceNode) value)
+ .children());
+ case MULTI_INSTANCE_LEAF_HOLDER_NODE:
+ return ((Map<String, T>) ((LeafListHolderNode) value)
+ .children());
+ case SINGLE_INSTANCE_LEAF_NODE:
+ case MULTI_INSTANCE_LEAF_NODE:
+ case ANY_XML_NODE:
+ return null;
+ default:
+ throw new IllegalArgumentException("No more types allowed");
+ }
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/HolderNode.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/HolderNode.java
new file mode 100644
index 000000000..52bec3412
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/HolderNode.java
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Abstraction of an entity that represents holder node to multi instance node
+ * in properties data tree.
+ *
+ * @param <T> type of child
+ */
+public abstract class HolderNode<T extends NodeChild> extends PropertiesNode {
+
+ private Map<String, T> children = new HashMap<>();
+
+ protected HolderNode(String name, Namespace namespace, String uri,
+ PropertiesNode parent, Object appInfo,
+ NodeType nodeType) {
+ super(name, namespace, uri, parent, appInfo, nodeType);
+ }
+
+ /**
+ * Returns children.
+ *
+ * @return children
+ */
+ public Map<String, T> children() {
+ return children;
+ }
+
+ /**
+ * Returns child based on index.
+ *
+ * @return child based on index
+ */
+ public T child(String index) {
+ return children.get(index);
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/InnerNode.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/InnerNode.java
new file mode 100644
index 000000000..1cf99b2d4
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/InnerNode.java
@@ -0,0 +1,215 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.addToAugmentations;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.createNode;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getAugmentationNode;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getUri;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.isNamespaceAsParent;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.resolveName;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_HOLDER_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_HOLDER_NODE;
+import static org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils.findCorrespondingAugment;
+
+/**
+ * Abstraction of an entity that represents an inner node to properties data
+ * tree.
+ *
+ * @param <T> type of child
+ */
+public abstract class InnerNode<T extends NodeChild> extends PropertiesNode {
+
+ private Map<String, T> children = new HashMap<String, T>();
+
+ protected InnerNode(String name, Namespace namespace, String uri,
+ PropertiesNode parent, Object appInfo, NodeType nodeType) {
+ super(name, namespace, uri, parent, appInfo, nodeType);
+ }
+
+ /**
+ * Returns children.
+ *
+ * @return children
+ */
+ public Map<String, T> children() {
+ return children;
+ }
+
+ /**
+ * Sets children.
+ *
+ * @param children child nodes
+ */
+ public void children(Map<String, T> children) {
+ this.children = children;
+ }
+
+ @Override
+ public PropertiesNode addChild(String name, Namespace namespace,
+ NodeType type,
+ Object appInfo) throws SvcLogicException {
+ PropertiesNode node = ((PropertiesNode) children.get(name));
+ if (node != null) {
+ return node;
+ }
+
+ // get augment schema, if it is augmented node
+ AugmentationSchemaNode augSchema = null;
+ if (((DataSchemaNode) appInfo).isAugmenting()) {
+ augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()), ((DataSchemaNode) appInfo));
+ node = getAugmentationNode(augSchema, this, name);
+ }
+
+ // create node based on type
+ if (node == null) {
+ String uri = getUri(this, name, namespace);
+ node = createNode(name, namespace, uri, this, appInfo, type);
+ }
+
+ // If namespace is not same as parent then it is augmented node
+ if (augSchema != null && !isNamespaceAsParent(this, node)) {
+ addToAugmentations(augSchema, this, node);
+ } else {
+ children.put(name, ((T) node));
+ }
+ return node;
+ }
+
+ @Override
+ public PropertiesNode addChild(String name, Namespace namespace,
+ NodeType type, String value,
+ Namespace valueNs,
+ Object appInfo) throws SvcLogicException {
+ LeafNode node = ((LeafNode) children.get(name));
+ if (node != null) {
+ return node;
+ }
+
+ AugmentationSchemaNode augSchema = null;
+ String uri = getUri(this, name, namespace);
+ node = new LeafNode(name, namespace, uri, this,
+ appInfo, type, value);
+
+ if (type != NodeType.ANY_XML_NODE) {
+ if (((DataSchemaNode) appInfo).isAugmenting()) {
+ augSchema = findCorrespondingAugment(
+ ((DataSchemaNode) this.appInfo()),
+ ((DataSchemaNode) appInfo));
+ }
+ node.valueNs(valueNs);
+ }
+
+ if (augSchema != null && !isNamespaceAsParent(this, node)) {
+ addToAugmentations(augSchema, this, node);
+ } else {
+ children.put(name, ((T) node));
+ }
+ return node;
+ }
+
+ @Override
+ public PropertiesNode addChild(String index, String name,
+ Namespace namespace, NodeType type,
+ Object appInfo) throws SvcLogicException {
+ String localname = resolveName(name);
+ PropertiesNode node = ((PropertiesNode) children.get(localname));
+
+ if (node == null) {
+ AugmentationSchemaNode augSchema = null;
+ if (((DataSchemaNode) appInfo).isAugmenting()) {
+ augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()),
+ ((DataSchemaNode) appInfo));
+ node = getAugmentationNode(augSchema, this, localname);
+ }
+
+ if (node == null) {
+ String uri = getUri(this, name, namespace);
+ node = new ListHolderNode(localname, namespace, uri,
+ this, appInfo, MULTI_INSTANCE_HOLDER_NODE);
+ }
+
+ if (augSchema != null && !isNamespaceAsParent(this, node)) {
+ addToAugmentations(augSchema, this, node);
+ } else {
+ children.put(localname, ((T) node));
+ }
+
+ node = node.addChild(index, localname, namespace, type, appInfo);
+ } else if (node instanceof ListHolderNode) {
+ ListHolderChild child = ((ListHolderNode) node).child(index);
+ node = (child != null ? ((MultiInstanceNode) child) :
+ node.addChild(index, localname, namespace, type, appInfo));
+ } else {
+ throw new SvcLogicException("Duplicate node exist with same node");
+ }
+ return node;
+ }
+
+ @Override
+ public PropertiesNode addChild(String index, String name,
+ Namespace namespace, NodeType type,
+ String value, Namespace valueNs,
+ Object appInfo) throws SvcLogicException {
+ String localName = resolveName(name);
+ PropertiesNode node = ((PropertiesNode) children.get(localName));
+
+ if (node == null) {
+
+ AugmentationSchemaNode augSchema = null;
+ if (((DataSchemaNode) appInfo).isAugmenting()) {
+ augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()),
+ ((DataSchemaNode) appInfo));
+ node = getAugmentationNode(augSchema, this, localName);
+ }
+
+ if (node == null) {
+ String uri = getUri(this, name, namespace);
+ node = new LeafListHolderNode(localName, namespace, uri, this,
+ appInfo, MULTI_INSTANCE_LEAF_HOLDER_NODE);
+ }
+
+ if (augSchema != null && !isNamespaceAsParent(this, node)) {
+ addToAugmentations(augSchema, this, node);
+ } else {
+ children.put(localName, ((T) node));
+ }
+
+ node = node.addChild(index, localName, namespace, type, value, valueNs, appInfo);
+ } else if (node instanceof LeafListHolderNode) {
+ LeafNode child = ((LeafNode) ((HolderNode) node).child(index));
+ node = (child != null ? child : node.addChild(index, localName,
+ namespace, type,
+ value, valueNs,
+ appInfo));
+ } else {
+ throw new SvcLogicException("Duplicate node exist with same node");
+ }
+ return node;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafListHolderChild.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafListHolderChild.java
new file mode 100644
index 000000000..e43249a3d
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafListHolderChild.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+/**
+ * Abstraction of entity representing child's to leaf list holder.
+ */
+public interface LeafListHolderChild extends NodeChild {
+
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafListHolderNode.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafListHolderNode.java
new file mode 100644
index 000000000..46ab5bb63
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafListHolderNode.java
@@ -0,0 +1,93 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright © 2018 IBM
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+/**
+ * Representation of leaf list holder node which will hold multi instance leaf
+ * node in properties data tree.
+ */
+public class LeafListHolderNode extends HolderNode<LeafListHolderChild> implements DataNodeChild {
+
+ private static final String node = " holder node";
+
+ /**
+ * Creates an instance of LeafListHolderNode.
+ *
+ * @param name name of the leaf-list node
+ * @param namespace namespace of the leaf-list node
+ * @param uri uri of the leaf-list node
+ * @param parent parent node of the leaf-list
+ * @param appInfo application info
+ * @param nodeType node type
+ */
+ public LeafListHolderNode(String name, Namespace namespace,
+ String uri, PropertiesNode parent,
+ Object appInfo, NodeType nodeType) {
+ super(name, namespace, uri, parent, appInfo, nodeType);
+ }
+
+ @Override
+ public PropertiesNode addChild(String name, Namespace namespace,
+ NodeType type, String value,
+ Namespace valueNs,
+ Object appInfo) throws SvcLogicException {
+ throw new SvcLogicException("Leaf cannot be child of leaf-list" +
+ node);
+ }
+
+ @Override
+ public PropertiesNode addChild(String name, Namespace namespace,
+ NodeType type,
+ Object appInfo) throws SvcLogicException {
+ throw new SvcLogicException("Container cannot be child of leaf-list" +
+ node);
+ }
+
+ @Override
+ public PropertiesNode addChild(String index, String name,
+ Namespace namespace,
+ NodeType type,
+ Object appInfo) throws SvcLogicException {
+ throw new SvcLogicException("List cannot be child of leaf-list" +
+ node);
+ }
+
+ @Override
+ public PropertiesNode addChild(String index, String name,
+ Namespace namespace, NodeType type,
+ String value, Namespace valueNs,
+ Object appInfo) throws SvcLogicException {
+ LeafNode node = ((LeafNode) children().get(index));
+ if (index == null) {
+ index = String.valueOf(children().size());
+ }
+ String uri = this.uri() + "[" + index + "]";
+ node = (node != null) ? node : new LeafNode(name, namespace, uri,
+ this, appInfo, type, value);
+ node.valueNs(valueNs);
+ children().put(index, node);
+ return node;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafNode.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafNode.java
new file mode 100644
index 000000000..041175ca7
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafNode.java
@@ -0,0 +1,122 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Modifications Copyright © 2018 IBM
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+/**
+ * Representation of leaf node in properties data tree.
+ */
+public class LeafNode extends PropertiesNode implements LeafListHolderChild, DataNodeChild {
+
+ private String value;
+ private Namespace valueNs;
+ private static final String svcLogicException = "Leaf cannot hold child nodes";
+
+ /**
+ * Creates an instance of leaf node.
+ *
+ * @param name name of the leaf node
+ * @param namespace namespace of the leaf node
+ * @param uri uri of the leaf node
+ * @param parent parent of the leaf node
+ * @param appInfo application info
+ * @param nodeType node type
+ * @param value value of the leaf
+ */
+ public LeafNode(String name, Namespace namespace,
+ String uri, PropertiesNode parent,
+ Object appInfo, NodeType nodeType,
+ String value) {
+ super(name, namespace, uri, parent, appInfo, nodeType);
+ this.value = value;
+ }
+
+ /**
+ * Returns value of the leaf.
+ *
+ * @return value of the leaf
+ */
+ public String value() {
+ return value;
+ }
+
+ /**
+ * Sets value of the leaf.
+ *
+ * @param value value of the leaf
+ */
+ public void value(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Returns value namespace.
+ *
+ * @return value namespace
+ */
+ public Namespace valueNs() {
+ return valueNs;
+ }
+
+ /**
+ * Sets value namespace.
+ *
+ * @param valueNs value namespace
+ */
+ public void valueNs(Namespace valueNs) {
+ this.valueNs = valueNs;
+ }
+
+ @Override
+ public PropertiesNode addChild(String name, Namespace namespace,
+ NodeType type,
+ Object appInfo) throws SvcLogicException {
+ throw new SvcLogicException(svcLogicException);
+ }
+
+ @Override
+ public PropertiesNode addChild(String name, Namespace namespace,
+ NodeType type, String value,
+ Namespace valueNs,
+ Object appInfo) throws SvcLogicException {
+ throw new SvcLogicException(svcLogicException);
+ }
+
+ @Override
+ public PropertiesNode addChild(String index, String name,
+ Namespace namespace,
+ NodeType type,
+ Object appInfo) throws SvcLogicException {
+ throw new SvcLogicException(svcLogicException);
+ }
+
+ @Override
+ public PropertiesNode addChild(String index, String name,
+ Namespace namespace,
+ NodeType type, String value,
+ Namespace valueNs,
+ Object appInfo) throws SvcLogicException {
+ throw new SvcLogicException("Leaf cannot hold child nodes");
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/ListHolderChild.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/ListHolderChild.java
new file mode 100644
index 000000000..ec9cc2a0f
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/ListHolderChild.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+/**
+ * Abstraction of entity representing child's to list holder.
+ */
+public interface ListHolderChild extends NodeChild {
+
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/ListHolderNode.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/ListHolderNode.java
new file mode 100644
index 000000000..ba9da54cf
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/ListHolderNode.java
@@ -0,0 +1,73 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+/**
+ * Representation of list holder node which will hold multi instance node in
+ * properties data tree.
+ */
+public class ListHolderNode extends HolderNode<ListHolderChild> implements DataNodeChild {
+
+ protected ListHolderNode(String name, Namespace namespace, String uri,
+ PropertiesNode parent, Object appInfo, NodeType nodeType) {
+ super(name, namespace, uri, parent, appInfo, nodeType);
+ }
+
+ @Override
+ public PropertiesNode addChild(String name, Namespace namespace,
+ NodeType type, String value,
+ Namespace valueNs,
+ Object appInfo) throws SvcLogicException {
+ throw new SvcLogicException("Leaf cannot be child of list holder node");
+ }
+
+ @Override
+ public PropertiesNode addChild(String name, Namespace namespace,
+ NodeType type,
+ Object appInfo) throws SvcLogicException {
+ throw new SvcLogicException("Container cannot be child of list holder node");
+ }
+
+ @Override
+ public PropertiesNode addChild(String index, String name,
+ Namespace namespace, NodeType type,
+ Object appInfo) throws SvcLogicException {
+ MultiInstanceNode node = ((MultiInstanceNode) children().get(index));
+ if (index == null) {
+ index = String.valueOf(children().size());
+ }
+ String uri = this.uri() + "[" + index + "]";
+ node = (node != null) ? node : new MultiInstanceNode(name, namespace, uri,
+ this, appInfo, type);
+ children().put(index, node);
+ return node;
+ }
+
+ @Override
+ public PropertiesNode addChild(String index, String name,
+ Namespace namespace, NodeType type,
+ String value, Namespace valueNs,
+ Object appInfo) throws SvcLogicException {
+ throw new SvcLogicException("Leaf-list cannot be child of list holder node");
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java
new file mode 100644
index 000000000..8a6e75668
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java
@@ -0,0 +1,227 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.DOT_REGEX;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.SLASH;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getChildSchemaNode;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getIndex;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getListName;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getNamespace;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getNodeType;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getParsedValue;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getProcessedPath;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getRevision;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getValueNamespace;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.resolveName;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.ANY_XML_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_LEAF_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_NODE;
+
+/**
+ * Representation of mdsal based properties node serializer implementation.
+ */
+public class MdsalPropertiesNodeSerializer extends PropertiesNodeSerializer<SchemaNode, SchemaContext> {
+
+ private static final Logger log = LoggerFactory.getLogger(
+ MdsalPropertiesNodeSerializer.class);
+ private SchemaNode curSchema;
+ private PropertiesNode node;
+
+ /**
+ * Creates the properties node serializer.
+ *
+ * @param schemaNode schema node.
+ * @param schemaCtx schema context
+ * @param uri URL of the request
+ */
+ public MdsalPropertiesNodeSerializer(SchemaNode schemaNode,
+ SchemaContext schemaCtx, String uri) {
+ super(schemaNode, schemaCtx, uri);
+ }
+
+ @Override
+ public PropertiesNode encode(Map<String, String> paramMap) throws SvcLogicException {
+ curSchema = schemaNode();
+ String nodeInUri[] = uri().split("\\/");
+ String lastNodeName = nodeInUri[nodeInUri.length - 1];
+ String rootUri = uri().replaceAll("\\/", "\\.");
+ node = createRootNode(lastNodeName, rootUri);
+
+ paramMap = convertToValidParam(paramMap);
+
+ updateModNameReq(paramMap, rootUri);
+
+ for (Map.Entry<String, String> entry : paramMap.entrySet()) {
+ String[] names = entry.getKey().split("\\.");
+ for (int i = 0; i < names.length; i++) {
+ if (i < nodeInUri.length) {
+ if (!(nodeInUri[i].equals(names[i]))) {
+ break;
+ }
+ } else {
+ createPropertyNode(i, names.length, names[i],
+ entry.getValue());
+ }
+ }
+ }
+ return node;
+ }
+
+ private void updateModNameReq(Map<String, String> paramMap,
+ String rootUri) {
+ String isReqStr = rootUri + "." + "isNonAppend";
+ String val = paramMap.get(isReqStr);
+ if (val != null && val.equals("true")) {
+ node.nonAppend(true);
+ }
+ }
+
+ /**
+ * Converts all the params in the svc logic context into a valid param by
+ * replacing the underscore in module name to colon at necessary places.
+ *
+ * @param paramMap list of invalid parameters
+ * @return list of partially valid parameters
+ */
+ private Map<String, String> convertToValidParam(Map<String, String> paramMap) {
+ Map<String, String> fixedParams = new HashMap<>();
+ for(Map.Entry<String, String> entry : paramMap.entrySet()) {
+ String key = entry.getKey().replaceAll(DOT_REGEX, SLASH);
+ try {
+ SchemaPathHolder fixedUrl = getProcessedPath(key, schemaCtx());
+ String fixedUri = fixedUrl.getUri().replaceAll(
+ SLASH, DOT_REGEX);
+ fixedParams.put(fixedUri, entry.getValue());
+ } catch (IllegalArgumentException | RestconfDocumentedException
+ | NullPointerException e) {
+ log.info("Exception while processing properties by replacing " +
+ "underscore with colon. Process the properties as it is." + e);
+ fixedParams.put(entry.getKey(), entry.getValue());
+ }
+ }
+ return fixedParams;
+ }
+
+ @Override
+ public Map<String, String> decode(PropertiesNode propertiesNode)
+ throws SvcLogicException {
+ PropertiesNodeWalker walker = new DefaultPropertiesNodeWalker<>();
+ DefaultPropertiesNodeListener listener = new DefaultPropertiesNodeListener();
+ walker.walk(listener, propertiesNode);
+ return listener.params();
+ }
+
+ private RootNode createRootNode(String lastNodeName, String rootUri) {
+ Module m = SchemaContextUtil.findParentModule(schemaCtx(), curSchema);
+ Namespace ns = new Namespace(m.getName(), m.getNamespace(),
+ getRevision(m.getRevision()));
+ return new RootNode(lastNodeName, ns, schemaNode(), rootUri);
+ }
+
+ private void createPropertyNode(int index, int length, String name,
+ String value) throws SvcLogicException {
+
+ Namespace ns = getNamespace(getListName(name), schemaCtx(),
+ node, curSchema);
+ String localName = resolveName(ns, name);
+ SchemaNode schema = getChildSchemaNode(curSchema, localName, ns);
+ if (schema == null) {
+ return;
+ }
+
+ switch (getNodeType(index, length, name, schema)) {
+ case SINGLE_INSTANCE_NODE:
+ node = node.addChild(localName, ns,
+ SINGLE_INSTANCE_NODE, schema);
+ curSchema = schema;
+ break;
+
+ case MULTI_INSTANCE_NODE:
+ node = node.addChild(getIndex(name), localName, ns,
+ MULTI_INSTANCE_NODE, schema);
+ curSchema = schema;
+ break;
+
+ case SINGLE_INSTANCE_LEAF_NODE:
+ addLeafNode(value, SINGLE_INSTANCE_LEAF_NODE, localName,
+ ns, schema, name);
+ break;
+
+ case MULTI_INSTANCE_LEAF_NODE:
+ addLeafNode(value, MULTI_INSTANCE_LEAF_NODE, localName,
+ ns, schema, name);
+ break;
+
+ case ANY_XML_NODE:
+ node = node.addChild(localName, ns, ANY_XML_NODE,
+ value, null, schema);
+ node = node.endNode();
+ curSchema = ((SchemaNode) node.appInfo());
+ break;
+
+ default:
+ throw new SvcLogicException("Invalid node type");
+ }
+ }
+
+ /**
+ * Adds leaf property node to the current node.
+ *
+ * @param value value of the leaf node
+ * @param type single instance or multi instance leaf node
+ * @param localName name of the leaf node
+ * @param ns namespace of the leaf node
+ * @param schema schema of the leaf node
+ * @param name name of the leaf in properties
+ * @throws SvcLogicException exception while adding leaf node
+ */
+ private void addLeafNode(String value, NodeType type,
+ String localName, Namespace ns,
+ SchemaNode schema, String name) throws SvcLogicException {
+ Namespace valNs = getValueNamespace(value, schemaCtx());
+ value = getParsedValue(valNs, value);
+ if (SINGLE_INSTANCE_LEAF_NODE == type) {
+ node = node.addChild(localName, ns, SINGLE_INSTANCE_LEAF_NODE,
+ value, valNs, schema);
+ } else {
+ node = node.addChild(getIndex(name), localName, ns,
+ MULTI_INSTANCE_LEAF_NODE, value,
+ valNs, schema);
+ }
+ node = node.endNode();
+ curSchema = ((SchemaNode) node.appInfo());
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeUtils.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeUtils.java
new file mode 100644
index 000000000..e6fa064f5
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeUtils.java
@@ -0,0 +1,578 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+import java.util.Collection;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.Optional;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
+import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.Revision;
+import org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils;
+import org.opendaylight.yangtools.yang.data.util.ParserStreamUtils;
+import org.opendaylight.yangtools.yang.data.util.codec.IdentityCodecUtil;
+import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.lang.String.format;
+import static java.util.regex.Pattern.quote;
+import static org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier.toInstanceIdentifier;
+
+/**
+ * Represents utilities for properties node tree.
+ */
+public final class MdsalPropertiesNodeUtils {
+
+ static final String COLON = ":";
+
+ static final String UNDERSCORE = "_";
+
+ static final String SLASH = "/";
+
+ static final String DOT_REGEX = "\\.";
+
+ private static final String INFO_MSG = "The %s formed is currently not" +
+ " valid";
+
+ private static final String EXC_MSG = "Unable to form a formatted path";
+
+ /**
+ * Logger for the Mdsal properties util class.
+ */
+ private static final Logger log = LoggerFactory.getLogger(
+ MdsalPropertiesNodeUtils.class);
+
+ private MdsalPropertiesNodeUtils() {
+ }
+
+ /**
+ * Returns the index from multi instance property name.
+ *
+ * @param name name of the property
+ * @return index from multi instance property name
+ */
+ public static String getIndex(String name) {
+ return name.substring(name.indexOf("[") + 1,
+ name.indexOf("]"));
+ }
+
+ /**
+ * Returns the multi instance property name.
+ *
+ * @param name name of the property
+ * @return the multi instance property name
+ */
+ public static String getListName(String name) {
+ String[] s = name.split("\\[");
+ return s[0];
+ }
+
+ /**
+ * Returns true if property is multi instance.
+ *
+ * @param name name of the property
+ * @return true if property is multi instance
+ */
+ public static boolean isListEntry(String name) {
+ String s[] = name.split("\\[");
+ return s.length > 1;
+ }
+
+ /**
+ * Returns name of the property after pruning namespace and
+ * index if the property is multi instance.
+ *
+ * @param name name of the property
+ * @return name of the property
+ */
+ static String resolveName(String name) {
+ String localName = getListName(name);
+ final int lastIndexOfColon = localName.lastIndexOf(":");
+ if (lastIndexOfColon != -1) {
+ localName = localName.substring(lastIndexOfColon + 1);
+ }
+ return localName;
+ }
+
+ /**
+ * Returns name of the property after pruning namespace and index if the
+ * property is multi instance by knowing the module name from namespace.
+ *
+ * @param ns namespace
+ * @param name name of the node
+ * @return resolved name
+ */
+ static String resolveName(Namespace ns, String name) {
+ String localName = getListName(name);
+ String modName = ns.moduleName();
+ if ((localName.contains(COLON) || localName.contains(UNDERSCORE))
+ && localName.startsWith(modName)) {
+ localName = localName.substring(modName.length()+1);
+ }
+ return localName;
+ }
+
+ /**
+ * Adds current node to parent's augmentation map.
+ *
+ * @param augSchema augment schema
+ * @param parent parent property node
+ * @param curNode current property node
+ */
+ public static void addToAugmentations(AugmentationSchemaNode augSchema,
+ PropertiesNode parent,
+ PropertiesNode curNode) {
+ Collection<PropertiesNode> childsFromAugmentation = parent
+ .augmentations().get(augSchema);
+ if (!childsFromAugmentation.isEmpty()) {
+ for (PropertiesNode pNode : childsFromAugmentation) {
+ if (pNode.name().equals(curNode.name())) {
+ return;
+ }
+ }
+ }
+ parent.augmentations().put(augSchema, curNode);
+ }
+
+
+ /**
+ * Returns augmented properties node if it is already
+ * added in properties tree.
+ *
+ * @param augSchema augmented schema node
+ * @param parent parent properties node
+ * @param name name of the properties
+ * @return augmented properties node if it is already added
+ */
+ public static PropertiesNode getAugmentationNode(
+ AugmentationSchemaNode augSchema,
+ PropertiesNode parent, String name) {
+ if (augSchema == null) {
+ return null;
+ }
+
+ Collection<PropertiesNode> childsFromAugmentation = parent
+ .augmentations().get(augSchema);
+ if (!childsFromAugmentation.isEmpty()) {
+ for (PropertiesNode pNode : childsFromAugmentation) {
+ if (pNode.name().equals(name)) {
+ return pNode;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Creates uri with specified name and namespace.
+ *
+ * @param parent parent properties node
+ * @param name name of the node
+ * @param ns namespace of the node
+ * @return uri with specified name and namespace
+ */
+ public static String getUri(PropertiesNode parent, String name,
+ Namespace ns) {
+ String uri = name;
+ if (!(parent.namespace().moduleNs().equals(ns.moduleNs()))) {
+ uri = ns.moduleName() + ":" + name;
+ }
+ return parent.uri() + "." + uri;
+ }
+
+ /**
+ * Creates new properties with specified parameters.
+ *
+ * @param name name of the properties node
+ * @param namespace namespace of the properties node
+ * @param uri uri of the properties node
+ * @param parent parent node
+ * @param appInfo application info
+ * @param type node type
+ * @return new properties node
+ * @throws SvcLogicException exception while creating properties node
+ */
+ public static PropertiesNode createNode(String name, Namespace namespace,
+ String uri, PropertiesNode parent,
+ Object appInfo, NodeType type)
+ throws SvcLogicException {
+ switch (type) {
+ case SINGLE_INSTANCE_NODE:
+ return new SingleInstanceNode(name, namespace, uri, parent, appInfo, type);
+ case MULTI_INSTANCE_HOLDER_NODE:
+ return new ListHolderNode(name, namespace, uri, parent, appInfo, type);
+ case MULTI_INSTANCE_LEAF_HOLDER_NODE:
+ return new LeafListHolderNode(name, namespace, uri, parent, appInfo, type);
+ default:
+ throw new SvcLogicException("Invalid node type " + type);
+ }
+ }
+
+ /**
+ * Returns true if namespace is same as parent's namespace.
+ *
+ * @param parent parent property node
+ * @param curNode current property node
+ * @return true if namespace is same as parent namespace
+ */
+ public static boolean isNamespaceAsParent(PropertiesNode parent,
+ PropertiesNode curNode) {
+ return parent.namespace().moduleNs().equals(curNode.namespace().moduleNs());
+ }
+
+ /**
+ * Returns the schema path holder with a formatted url and the instance
+ * identifier context from a given uri or the parameters from svc logic
+ * context.
+ *
+ * @param uri unformatted uri or parameter
+ * @param context schema context
+ * @return schema path holder
+ */
+ public static SchemaPathHolder getProcessedPath(String uri,
+ SchemaContext context) {
+
+ String uri1 = uri.replaceAll(UNDERSCORE, COLON);
+ try {
+ InstanceIdentifierContext<?> id = toInstanceIdentifier(
+ uri1, context, null);
+ return new SchemaPathHolder(id, uri1);
+ } catch (IllegalArgumentException | RestconfDocumentedException
+ | NullPointerException e) {
+ log.info("Exception while converting uri to instance identifier" +
+ " context. Process each node in uri to get instance identifier" +
+ " context " + e);
+ return processNodesAndAppendPath(uri, context);
+ }
+ }
+
+ /**
+ * Processes the nodes in the given uri and finds instance identifier
+ * context till it reaches the last node in uri. If its not able to find
+ * schema for the path, it appends the suffix part and puts it back in
+ * the param list.
+ *
+ * @param uri uri with underscore
+ * @param context schema context
+ * @return schema and path holder
+ */
+ private static SchemaPathHolder processNodesAndAppendPath(String uri,
+ SchemaContext context) {
+
+ String actPath = "";
+ SchemaPathHolder id = new SchemaPathHolder(null, "");
+ String[] uriParts = uri.split(SLASH);
+ String sec = "";
+ if (uri.contains(UNDERSCORE)) {
+ sec = uri.substring(uriParts[0].length()+1);
+ }
+ for (int i = 0; i<uriParts.length; i++) {
+
+ try {
+ id = processIdentifier(uriParts[i], context, actPath);
+ } catch (IllegalArgumentException e) {
+ log.info(format(EXC_MSG, e));
+ id.setUri(actPath+ uriParts[i] + sec);
+ return id;
+ }
+
+ actPath = actPath + id.getUri() + SLASH;
+ if (sec.startsWith(SLASH)) {
+ sec = sec.replaceFirst(SLASH, "");
+ }
+ if (i+1 < uriParts.length) {
+ sec = sec.replaceFirst(quote(uriParts[i + 1]), "");
+ }
+ }
+ id.setUri(actPath.substring(0,actPath.length() - 1));
+ return id;
+ }
+
+ /**
+ * Processes the schema and path holder for a given node in the path. It
+ * figures if the path is valid by replacing underscore in the node
+ * consecutively, till it finds the proper schema for the node.
+ *
+ * @param node node in the path
+ * @param context schema context
+ * @param prefix prefix for the node in the path
+ * @return schema and path holder
+ */
+ private static SchemaPathHolder processIdentifier(String node,
+ SchemaContext context,
+ String prefix) {
+
+ String[] values = node.split(UNDERSCORE);
+ String val = values[0];
+ StringBuilder firstHalf = new StringBuilder();
+ String secondHalf = "";
+ if (node.contains(UNDERSCORE)) {
+ secondHalf = node.substring(values[0].length()+1);
+ }
+ InstanceIdentifierContext<?> id;
+ for (int i = 0; i< values.length-1; i++) {
+ val = values[i];
+ val = firstHalf + val + COLON + secondHalf;
+ try {
+ id = toInstanceIdentifier(prefix + val, context, null);
+ return new SchemaPathHolder(id, val);
+ } catch (IllegalArgumentException | RestconfDocumentedException |
+ NullPointerException e) {
+ log.info(format(INFO_MSG, val, e));
+ }
+ firstHalf.append(values[i]).append(UNDERSCORE);
+ secondHalf = secondHalf.replaceFirst(
+ values[i + 1] + UNDERSCORE,"");
+ }
+ val = val.replace(COLON,UNDERSCORE);
+ try {
+ id = toInstanceIdentifier(prefix + val, context, null);
+ return new SchemaPathHolder(id, val);
+ } catch (IllegalArgumentException | RestconfDocumentedException |
+ NullPointerException e1) {
+ throw new IllegalArgumentException(EXC_MSG, e1);
+ }
+ }
+
+ /**
+ * Returns the namespace of the given node name. If the node name is
+ * separated by colon, the it splits with colon and forms the namespace.
+ * If the node name is formed with underscore, then it splits the node
+ * name consecutively to figure out the proper module name.
+ *
+ * @param childName node name
+ * @param ctx schema context
+ * @param parent parent properties node
+ * @param curSchema current schema
+ * @return namespace of the given node
+ */
+ static Namespace getNamespace(String childName, SchemaContext ctx,
+ PropertiesNode parent, SchemaNode curSchema) {
+
+ Namespace parentNs = parent.namespace();
+ Namespace ns = new Namespace(parentNs.moduleName(),
+ parentNs.moduleNs(), parentNs.revision());
+ int lastIndexOfColon = childName.lastIndexOf(COLON);
+ if (lastIndexOfColon != -1) {
+ String moduleName = childName.substring(0, lastIndexOfColon);
+ childName = childName.substring(lastIndexOfColon+1);
+ Namespace ns1 = getNs(moduleName, ctx);
+ if (ns1 != null) {
+ ns = ns1;
+ }
+ }
+
+ SchemaNode child = getChildSchemaNode(curSchema, childName, ns);
+
+ if (child == null && childName.contains(UNDERSCORE)) {
+ String[] children = childName.split(UNDERSCORE);
+ String second = childName.substring(children[0].length() + 1);
+ StringBuilder first = new StringBuilder();
+
+ for (int i =0; i< children.length; i++) {
+ String moduleName = first + children[i];
+ Namespace newNs = getNs(moduleName, ctx);
+ if (newNs != null) {
+ return newNs;
+ }
+ first.append(children[i]).append(UNDERSCORE);
+ if (i + 1 < children.length) {
+ second = second.replaceFirst(
+ children[i + 1] + UNDERSCORE, "");
+ }
+ }
+ return ns;
+ }
+ return ns;
+ }
+
+ /**
+ * Returns the namespace by finding the given module in the schema context.
+ *
+ * @param modName module name
+ * @param ctx schema context
+ * @return namespace of the given node name
+ */
+ private static Namespace getNs(String modName, SchemaContext ctx) {
+ Iterator<Module> it = ctx.findModules(modName).iterator();
+ if (it.hasNext()) {
+ Module m = it.next();
+ return new Namespace(modName, m.getQNameModule().getNamespace(),
+ getRevision(m.getRevision()));
+ }
+ return null;
+ }
+
+ /**
+ * Returns child schema node.
+ *
+ * @param curSchema current schema node
+ * @param name name of the property
+ * @param namespace namespace of the property
+ * @return child schema node
+ */
+ public static SchemaNode getChildSchemaNode(SchemaNode curSchema,
+ String name,
+ Namespace namespace) {
+ if (namespace == null) {
+ return null;
+ }
+
+ QName qname = QName.create(namespace.moduleNs(),
+ Revision.of(namespace.revision()), name);
+
+ // YANG RPC will not be instance of DataSchemaNode
+ if (curSchema instanceof DataSchemaNode) {
+ Deque<DataSchemaNode> schemaNodeDeque = ParserStreamUtils.
+ findSchemaNodeByNameAndNamespace(((DataSchemaNode)
+ curSchema), name, namespace.moduleNs());
+ if (schemaNodeDeque.isEmpty()) {
+ // could not find schema node
+ return null;
+ }
+
+ DataSchemaNode schemaNode = schemaNodeDeque.pop();
+ if (schemaNodeDeque.isEmpty()){
+ // Simple node
+ return schemaNode;
+ }
+
+ // node is child of Choice/case
+ return SchemaUtils.findSchemaForChild(((ChoiceSchemaNode) schemaNode),
+ qname);
+ } else {
+ return SchemaUtils.findDataChildSchemaByQName(curSchema, qname);
+ }
+ }
+
+ /**
+ * Returns the property node type.
+ *
+ * @param index current index
+ * @param length length of the properties
+ * @param name name of the property
+ * @return the property node type
+ */
+ public static NodeType getNodeType(int index, int length, String name,
+ SchemaNode schema) {
+ if (index == length-1) {
+ if (schema instanceof AnyXmlSchemaNode){
+ return NodeType.ANY_XML_NODE;
+ }
+ return (isListEntry(name) ? NodeType.MULTI_INSTANCE_LEAF_NODE :
+ NodeType.SINGLE_INSTANCE_LEAF_NODE);
+ } else {
+ return (isListEntry(name) ? NodeType.MULTI_INSTANCE_NODE :
+ NodeType.SINGLE_INSTANCE_NODE);
+ }
+ }
+
+ /**
+ * Returns revision in string.
+ *
+ * @param r YANG revision
+ * @return revision in string
+ */
+ public static String getRevision(Optional<Revision> r) {
+ return (r.isPresent()) ? r.get().toString() : null;
+ }
+
+ /**
+ * Returns value namespace for leaf value.
+ *
+ * @param value value of the leaf
+ * @param ctx schema context
+ * @return value namespace
+ * @throws SvcLogicException if identity/module could not be found
+ */
+ static Namespace getValueNamespace(String value,
+ SchemaContext ctx)
+ throws SvcLogicException {
+ String prefix = getPrefixFromValue(value);
+ if (prefix == null) {
+ return null;
+ }
+
+ IdentitySchemaNode id = IdentityCodecUtil.parseIdentity(value,
+ ctx,
+ prefixToModule -> {
+ final Iterator<Module> modules = ctx.findModules(prefix).iterator();
+ checkArgument(modules.hasNext(), "Could not find " +
+ "module %s", prefix);
+ return modules.next().getQNameModule();
+ });
+
+ if (id == null) {
+ throw new SvcLogicException("Could not find identity");
+ }
+
+ return getModuleNamespace(id.getQName(), ctx);
+ }
+
+ private static String getPrefixFromValue(String value) {
+ int lastIndexOfColon = value.lastIndexOf(":");
+ if (lastIndexOfColon != -1) {
+ return value.substring(0, lastIndexOfColon);
+ }
+ return null;
+ }
+
+ /**
+ * Returns module namespace from a given qName.
+ *
+ * @param qName qName of a node
+ * @param ctx schema context
+ * @return module namespace of the node
+ * @throws SvcLogicException when the module is not available
+ */
+ public static Namespace getModuleNamespace(QName qName, SchemaContext ctx)
+ throws SvcLogicException {
+ Optional<Module> module = ctx.findModule(qName.getModule());
+ if (!module.isPresent()) {
+ throw new SvcLogicException("Could not find module node");
+ }
+ Module m = module.get();
+ return new Namespace(m.getName(), m.getQNameModule().getNamespace(),
+ getRevision(m.getRevision()));
+ }
+
+ static String getParsedValue(Namespace valNs, String value) {
+ if (valNs != null && value.contains(":")) {
+ String[] valArr = value.split(":");
+ return valArr[1];
+ }
+ return value;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MultiInstanceNode.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MultiInstanceNode.java
new file mode 100644
index 000000000..c251cdaea
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MultiInstanceNode.java
@@ -0,0 +1,32 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+/**
+ * Representation of multi instance node in properties data tree.
+ */
+public class MultiInstanceNode extends InnerNode<DataNodeChild> implements ListHolderChild {
+
+ public MultiInstanceNode(String name, Namespace namespace, String uri,
+ PropertiesNode parent, Object appinfo, NodeType nodeType) {
+ super(name, namespace, uri, parent, appinfo, nodeType);
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/Namespace.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/Namespace.java
new file mode 100644
index 000000000..4f27ee1e7
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/Namespace.java
@@ -0,0 +1,100 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+import java.net.URI;
+
+/**
+ * Representation of YANG namespace.
+ */
+public class Namespace {
+ private String moduleName;
+ private URI moduleNs;
+ private String revision;
+
+ /**
+ * Creates an instance of namespace with specified module name,
+ * namespace and revision.
+ *
+ * @param modulename module name
+ * @param moduleNs module namespace
+ * @param revision revision
+ */
+ public Namespace(String modulename, URI moduleNs, String revision) {
+ this.moduleName = modulename;
+ this.moduleNs = moduleNs;
+ this.revision = revision;
+ }
+
+ /**
+ * Returns module name.
+ *
+ * @return module name
+ */
+ public String moduleName() {
+ return moduleName;
+ }
+
+ /**
+ * Sets module name.
+ *
+ * @param moduleName module name
+ */
+ public void moduleName(String moduleName) {
+ this.moduleName = moduleName;
+ }
+
+ /**
+ * Sets module namespace.
+ *
+ * @return module namespace
+ */
+ public URI moduleNs() {
+ return moduleNs;
+ }
+
+ /**
+ * Sets module namespace.
+ *
+ * @param moduleNs module namespace
+ */
+ public void moduleNs(URI moduleNs) {
+ this.moduleNs = moduleNs;
+ }
+
+ /**
+ * Returns revision.
+ *
+ * @return revision
+ */
+ public String revision() {
+ return revision;
+ }
+
+ /**
+ * Sets revision.
+ *
+ * @param revision revision
+ */
+ public void revision(String revision) {
+ this.revision = revision;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/NodeChild.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/NodeChild.java
new file mode 100644
index 000000000..d482c6763
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/NodeChild.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+/**
+ * Abstraction of an entity that represents child's of a node.
+ */
+public interface NodeChild {
+
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/NodeType.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/NodeType.java
new file mode 100644
index 000000000..0b6974e3e
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/NodeType.java
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+/**
+ * Representation of types of node in properties node tree.
+ */
+public enum NodeType {
+ SINGLE_INSTANCE_NODE,
+ MULTI_INSTANCE_NODE,
+ SINGLE_INSTANCE_LEAF_NODE,
+ MULTI_INSTANCE_LEAF_NODE,
+ MULTI_INSTANCE_HOLDER_NODE,
+ MULTI_INSTANCE_LEAF_HOLDER_NODE,
+ ANY_XML_NODE
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesNode.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesNode.java
new file mode 100644
index 000000000..7e0ad631e
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesNode.java
@@ -0,0 +1,280 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+/**
+ * Abstraction of properties node data tree. This intermediate representation
+ * will enable data format serializers to be agnostic of DG context memory
+ * nuances and thereby will enable faster development of new data format
+ * serializers.
+ */
+public abstract class PropertiesNode {
+
+ private String name;
+ private Namespace namespace;
+ private String uri;
+ private PropertiesNode parent;
+ private Object appInfo;
+ private NodeType nodeType;
+ private boolean nonAppend;
+ private Multimap<Object, PropertiesNode> augmentations = ArrayListMultimap.create();
+
+ /**
+ * Creates an instance of properties node.
+ *
+ * @param name name of node
+ * @param namespace namespace of node, null indicates parent namespace
+ * @param uri URI of this node, if null its calculated based on parent and
+ * current value of name and namespace
+ * @param parent parent's node
+ * @param appInfo application related information
+ * @param nodeType node type
+ */
+ protected PropertiesNode(String name, Namespace namespace, String uri,
+ PropertiesNode parent, Object appInfo, NodeType nodeType) {
+ this.name = name;
+ this.namespace = namespace;
+ this.uri = uri;
+ this.parent = parent;
+ this.appInfo = appInfo;
+ this.nodeType = nodeType;
+ }
+
+ /**
+ * Sets name.
+ *
+ * @param name name of the node
+ */
+ public void name(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Sets namespace.
+ *
+ * @param namespace namespace of the node
+ */
+ public void namespace(Namespace namespace) {
+ this.namespace = namespace;
+ }
+
+ /**
+ * Sets uri.
+ *
+ * @param uri uri of the node
+ */
+ public void uri(String uri) {
+ this.uri = uri;
+ }
+
+ /**
+ * Sets parent node.
+ *
+ * @param parent parent node
+ */
+ public void parent(PropertiesNode parent) {
+ this.parent = parent;
+ }
+
+ /**
+ * Sets application info.
+ *
+ * @param appInfo application info
+ */
+ public void appInfo(Object appInfo) {
+ this.appInfo = appInfo;
+ }
+
+ /**
+ * Sets to true if module name is required in forming a request; false
+ * otherwise.
+ *
+ * @param isNotReq true if required; false otherwise
+ */
+ public void nonAppend(boolean isNotReq) {
+ this.nonAppend = isNotReq;
+ }
+
+ /**
+ * Returns parent.
+ *
+ * @return parent node
+ */
+ public PropertiesNode parent() {
+ return parent;
+ }
+
+ /**
+ * Returns name.
+ *
+ * @return name of the node
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Returns namespace.
+ *
+ * @return namespace of the node
+ */
+ public Namespace namespace() {
+ return namespace;
+ }
+
+ /**
+ * Returns uri.
+ *
+ * @return uri of the node
+ */
+ public String uri() {
+ return uri;
+ }
+
+ /**
+ * Returns application info.
+ *
+ * @return application info
+ */
+ public Object appInfo() {
+ return appInfo;
+ }
+
+ /**
+ * Returns node type.
+ *
+ * @return node type
+ */
+ public NodeType nodeType() {
+ return nodeType;
+ }
+
+ /**
+ * Returns if module name is required.
+ *
+ * @return status of module name if required
+ */
+ public boolean nonAppend() {
+ return nonAppend;
+ }
+
+ /**
+ * Returns augmentations.
+ *
+ * @return augmentations
+ */
+ public Multimap<Object, PropertiesNode> augmentations() {
+ return augmentations;
+ }
+
+ /**
+ * Sets augmentations.
+ *
+ * @param augmentations augmentations of the node
+ */
+ public void augmentations(Multimap<Object, PropertiesNode> augmentations) {
+ this.augmentations = augmentations;
+ }
+
+ /**
+ * Adds a child to a current node.
+ *
+ * @param name name of child
+ * @param namespace namespace of child, null represents parent namespace
+ * @param type type of node
+ * @param appInfo application info
+ * @return added properties node
+ */
+ public abstract PropertiesNode addChild(String name, Namespace namespace,
+ NodeType type,
+ Object appInfo) throws SvcLogicException;
+
+ /**
+ * Adds a child with value to a current node.
+ *
+ * @param name name of child
+ * @param namespace namespace of child, null represents parent namespace
+ * @param type type of node
+ * @param value value of node
+ * @param valueNs value namespace
+ * @param appInfo application info
+ * @throws SvcLogicException if failed to add child
+ * @return added properties node
+ */
+ public abstract PropertiesNode addChild(String name, Namespace namespace,
+ NodeType type, String value,
+ Namespace valueNs,
+ Object appInfo) throws SvcLogicException;
+
+ /**
+ * Adds a child at a given index to a current node. To be used in case of
+ * leaf holder child's which is multi instance node.
+ *
+ * @param index index at which node is to be added
+ * @param name name of child
+ * @param namespace namespace of child, null represents parent namespace
+ * @param type type of node
+ * @param appInfo application info
+ * @throws SvcLogicException if failed to add child
+ * @return added properties node
+ */
+ public abstract PropertiesNode addChild(String index, String name,
+ Namespace namespace,
+ NodeType type,
+ Object appInfo) throws SvcLogicException;
+
+ /**
+ * Adds a child at a given index to a current node. To be used in case of
+ * leaf holder child's which is multi instance node.
+ *
+ * @param index index at which node is to be added
+ * @param name name of child
+ * @param namespace namespace of child, null represents parent namespace
+ * @param type type of node
+ * @param value value of node
+ * @param valueNs value namespace
+ * @param appInfo application info
+ * @throws SvcLogicException if failed to add child
+ * @return added properties node
+ */
+ public abstract PropertiesNode addChild(String index, String name,
+ Namespace namespace, NodeType type,
+ String value, Namespace valueNs,
+ Object appInfo) throws SvcLogicException;
+
+ /**
+ * Returns root node.
+ *
+ * @return root node
+ */
+ public PropertiesNode endNode() {
+ PropertiesNode node = this;
+ while (node.parent() != null){
+ node = node.parent();
+ }
+ return node;
+ }
+}
+
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesNodeListener.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesNodeListener.java
new file mode 100644
index 000000000..7b97ffaf8
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesNodeListener.java
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+/**
+ * Abstraction of properties node listener.
+ */
+public interface PropertiesNodeListener {
+
+ /**
+ * Pre-configurations required before starting the walking.
+ *
+ * @param node properties node
+ * @throws SvcLogicException when the pre-configuration fails
+ */
+ void start(PropertiesNode node) throws SvcLogicException;
+
+ /**
+ * Post-configurations required after starting the walking.
+ *
+ * @param node properties node
+ * @throws SvcLogicException when the post-configuration fails
+ */
+ void end(PropertiesNode node) throws SvcLogicException;
+
+ /**
+ * Enters the properties node.
+ *
+ * @param node properties node
+ * @throws SvcLogicException when entering the properties node fails
+ */
+ void enterPropertiesNode(PropertiesNode node) throws SvcLogicException;
+
+ /**
+ * Enters the properties node.
+ *
+ * @param node properties node
+ * @throws SvcLogicException when exiting the properties node fails
+ */
+ void exitPropertiesNode(PropertiesNode node) throws SvcLogicException;
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesNodeSerializer.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesNodeSerializer.java
new file mode 100644
index 000000000..fe6fed484
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesNodeSerializer.java
@@ -0,0 +1,112 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import java.util.Map;
+
+/**
+ * Abstraction of an entity to enable encoding and decoding of properties
+ * to an abstract properties node tree using YANG based schema.
+ * This serializer will be used by other data format serializers and will keep
+ * them abstract from properties nuances thereby enabling quick addition of any
+ * new data format serializer.
+ *
+ * @param <T> type of schema node
+ * @param <P> schema context of the model
+ */
+public abstract class PropertiesNodeSerializer<T, P> {
+
+ /**
+ * Schema node from which the property is made.
+ */
+ private T schemaNode;
+
+ /**
+ * Schema context of the model.
+ */
+ private P schemaCtx;
+
+ /**
+ * URL pointing to the schema node.
+ */
+ private String uri;
+
+ /**
+ * Creates the properties node serializer.
+ *
+ * @param schemaNode schema node.
+ * @param schemaCtx schema context
+ * @param uri URL of the request
+ */
+ public PropertiesNodeSerializer(T schemaNode, P schemaCtx, String uri) {
+ this.schemaNode = schemaNode;
+ this.schemaCtx = schemaCtx;
+ this.uri = uri;
+ }
+
+ /**
+ * Encodes from properties to properties-node tree.
+ *
+ * @param paramMap parameter map
+ * @throws SvcLogicException fails to encode properties to properties node
+ * @return properties node
+ */
+ public abstract PropertiesNode encode(Map<String, String> paramMap) throws SvcLogicException;
+
+ /**
+ * Decodes from properties-node to properties map.
+ *
+ * @param propertiesNode properties-node
+ * @return parameter map
+ * @throws SvcLogicException fails to decode properties node to properties
+ */
+ public abstract Map<String, String> decode(PropertiesNode propertiesNode)
+ throws SvcLogicException;
+
+ /**
+ * Returns the schema node of the property
+ *
+ * @return schema node
+ */
+ public T schemaNode(){
+ return schemaNode;
+ }
+
+ /**
+ * Returns the schema context
+ *
+ * @return schema node
+ */
+ public P schemaCtx() {
+ return schemaCtx;
+ }
+
+ /**
+ * Returns the URI.
+ *
+ * @return uri
+ */
+ public String uri() {
+ return uri;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesNodeWalker.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesNodeWalker.java
new file mode 100644
index 000000000..36ee4dd9d
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesNodeWalker.java
@@ -0,0 +1,38 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+/**
+ * Abstraction of properties node walker
+ */
+public interface PropertiesNodeWalker {
+ /**
+ * Walks the properties node with the listener.
+ *
+ * @param listener properties node listener.
+ * @param propertiesNode properties node
+ * @throws SvcLogicException when walking the properties node fails
+ */
+ void walk(PropertiesNodeListener listener, PropertiesNode propertiesNode)
+ throws SvcLogicException;
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/RootNode.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/RootNode.java
new file mode 100644
index 000000000..c7f7340fd
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/RootNode.java
@@ -0,0 +1,212 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.addToAugmentations;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.createNode;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getAugmentationNode;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getUri;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.isNamespaceAsParent;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.resolveName;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_HOLDER_NODE;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_HOLDER_NODE;
+import static org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils.findCorrespondingAugment;
+
+/**
+ * Abstraction of node representing properties data tree.
+ */
+public class RootNode<T extends NodeChild> extends PropertiesNode {
+
+ private Map<String, T> children = new HashMap<String, T>();
+
+ /**
+ * Creates an instance of the root node to build the properties.
+ *
+ * @param name name of the node
+ * @param namespace namespace of the node
+ * @param appInfo application info
+ * @param uri URI of the node
+ */
+ public RootNode(String name, Namespace namespace,
+ Object appInfo, String uri) {
+ super(name, namespace, uri, null, appInfo, null);
+ }
+
+ /**
+ * Returns children.
+ *
+ * @return children
+ */
+ public Map<String, T> children() {
+ return children;
+ }
+
+ /**
+ * Sets children.
+ *
+ * @param children child nodes
+ */
+ public void children(Map<String, T> children) {
+ this.children = children;
+ }
+
+ @Override
+ public PropertiesNode addChild(String name, Namespace namespace,
+ NodeType type,
+ Object appInfo) throws SvcLogicException {
+ PropertiesNode node = ((PropertiesNode) children.get(name));
+ if (node != null) {
+ return node;
+ }
+
+ // get augment schema, if it is augmented node
+ AugmentationSchemaNode augSchema = null;
+ if (((DataSchemaNode) appInfo).isAugmenting()) {
+ augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()),
+ ((DataSchemaNode) appInfo));
+ node = getAugmentationNode(augSchema, this, name);
+ }
+
+ // create node based on type, this api will be invoked only for these three types
+ if (node == null) {
+ String uri = getUri(this, name, namespace);
+ node = createNode(name, namespace, uri, this, appInfo, type);
+ }
+
+ // If namespace is not same as parent then it is augmented node
+ if (augSchema != null && !isNamespaceAsParent(this, node)) {
+ addToAugmentations(augSchema, this, node);
+ } else {
+ children.put(name, ((T) node));
+ }
+ return node;
+ }
+
+ @Override
+ public PropertiesNode addChild(String name, Namespace namespace,
+ NodeType type, String value,
+ Namespace valuens,
+ Object appInfo) throws SvcLogicException {
+ LeafNode node = ((LeafNode) children.get(name));
+ if (node != null) {
+ return node;
+ }
+
+ AugmentationSchemaNode augSchema = null;
+ if (((DataSchemaNode) appInfo).isAugmenting()) {
+ augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()),
+ ((DataSchemaNode) appInfo));
+ }
+
+ String uri = getUri(this, name, namespace);
+ node = new LeafNode(name, namespace, uri, this,
+ appInfo, type, value);
+
+ if (augSchema != null && !isNamespaceAsParent(this, node)) {
+ addToAugmentations(augSchema, this, node);
+ } else {
+ children.put(name, ((T) node));
+ }
+ return node;
+ }
+
+ @Override
+ public PropertiesNode addChild(String index, String name,
+ Namespace namespace, NodeType type,
+ Object appInfo) throws SvcLogicException {
+ String localname = resolveName(name);
+ PropertiesNode node = ((PropertiesNode) children.get(localname));
+ if (node == null) {
+ String uri = getUri(this, name, namespace);
+ AugmentationSchemaNode augSchema = null;
+ if (((DataSchemaNode) appInfo).isAugmenting()) {
+ augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()),
+ ((DataSchemaNode) appInfo));
+ node = getAugmentationNode(augSchema, this, localname);
+ }
+
+ if (node == null) {
+ node = new ListHolderNode(localname, namespace, uri,
+ this, appInfo, MULTI_INSTANCE_HOLDER_NODE);
+ }
+
+ if (augSchema != null && !isNamespaceAsParent(this, node)) {
+ addToAugmentations(augSchema, this, node);
+ } else {
+ children.put(localname, ((T) node));
+ }
+ node = node.addChild(index, localname, namespace, type, appInfo);
+ } else if (node instanceof ListHolderNode) {
+ ListHolderChild child = ((ListHolderNode) node).child(index);
+ node = (child != null ? ((MultiInstanceNode) child) :
+ node.addChild(index, localname, namespace, type, appInfo));
+ } else {
+ throw new SvcLogicException("Duplicate node exist with same node");
+ }
+ return node;
+ }
+
+ @Override
+ public PropertiesNode addChild(String index, String name,
+ Namespace namespace, NodeType type,
+ String value, Namespace valueNs,
+ Object appInfo) throws SvcLogicException {
+ String localName = resolveName(name);
+ PropertiesNode node = ((PropertiesNode) children.get(localName));
+ if (node == null) {
+ String uri = getUri(this, name, namespace);
+ AugmentationSchemaNode augSchema = null;
+ if (((DataSchemaNode) appInfo).isAugmenting()) {
+ augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()),
+ ((DataSchemaNode) appInfo));
+ node = getAugmentationNode(augSchema, this, localName);
+ }
+
+ if (node == null) {
+ node = new LeafListHolderNode(localName, namespace, uri, this,
+ appInfo, MULTI_INSTANCE_LEAF_HOLDER_NODE);
+ }
+
+ if (augSchema != null && !isNamespaceAsParent(this, node)) {
+ addToAugmentations(augSchema, this, node);
+ } else {
+ children.put(localName, ((T) node));
+ }
+ node = node.addChild(index, localName, namespace, type, value, valueNs, appInfo);
+ } else if (node instanceof LeafListHolderNode) {
+ LeafNode child = ((LeafNode) ((HolderNode) node).child(index));
+ node = (child != null ? child : node.addChild(index, localName,
+ namespace, type,
+ value, valueNs,
+ appInfo));
+ } else {
+ throw new SvcLogicException("Duplicate node exist with same node");
+ }
+ return node;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/SchemaPathHolder.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/SchemaPathHolder.java
new file mode 100644
index 000000000..4ef1bc664
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/SchemaPathHolder.java
@@ -0,0 +1,77 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2019 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
+
+/**
+ * Representation of a holder for a proper path and its corresponding schema.
+ */
+public class SchemaPathHolder {
+
+ /**
+ * Schema context for the path.
+ */
+ private InstanceIdentifierContext insId;
+
+ /**
+ * Formatted path.
+ */
+ private String uri;
+
+ /**
+ * Constructs schema path holder with path and its schema.
+ *
+ * @param insId instance identifier context
+ * @param uri path
+ */
+ public SchemaPathHolder(InstanceIdentifierContext insId, String uri) {
+ this.insId = insId;
+ this.uri = uri;
+ }
+
+ /**
+ * Returns the instance identifier context of the path.
+ *
+ * @return schema of the path
+ */
+ public InstanceIdentifierContext getInsId() {
+ return insId;
+ }
+
+ /**
+ * Returns the formatted path.
+ *
+ * @return formatted path
+ */
+ public String getUri() {
+ return uri;
+ }
+
+ /**
+ * Sets the formatted path.
+ *
+ * @param uri formatted path
+ */
+ public void setUri(String uri) {
+ this.uri = uri;
+ }
+}
diff --git a/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/SingleInstanceNode.java b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/SingleInstanceNode.java
new file mode 100644
index 000000000..6eb24c1a4
--- /dev/null
+++ b/plugins/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/SingleInstanceNode.java
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
+
+/**
+ * Representation of single instance node in properties data tree.
+ */
+public class SingleInstanceNode extends InnerNode<DataNodeChild> implements DataNodeChild {
+
+ public SingleInstanceNode(String name, Namespace namespace, String uri,
+ PropertiesNode parent, Object appInfo,
+ NodeType nodeType) {
+ super(name, namespace, uri, parent, appInfo, nodeType);
+ }
+}