aboutsummaryrefslogtreecommitdiffstats
path: root/restconf-client/provider/src/main
diff options
context:
space:
mode:
authorjanani b <janani.b@huawei.com>2018-08-29 11:52:41 +0530
committerjanani b <janani.b@huawei.com>2018-08-29 11:52:41 +0530
commitc8a20b7cdc2b563e1ea86a9e25f4ac0e748995f9 (patch)
tree8c61702c516711b75f6ce4eae05c16a203b6b339 /restconf-client/provider/src/main
parent5c41b487a093174b89f3a66806f115c4459c5065 (diff)
Implementation for Restconf api call node
Restconf Api Call Node Issue-ID: CCSDK-372 Change-Id: I1820e97d54e734ccf73c6f48a9afcc4b59dff549 Signed-off-by: janani b <janani.b@huawei.com>
Diffstat (limited to 'restconf-client/provider/src/main')
-rw-r--r--restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiCallNode.java362
-rw-r--r--restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiUtils.java213
-rw-r--r--restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfapiCallNode.java65
-rw-r--r--restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/RestconfDiscoveryNode.java14
-rw-r--r--restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/MdsalSerializerHelper.java4
-rw-r--r--restconf-client/provider/src/main/resources/META-INF/spring/restconf-client-context.xml4
-rw-r--r--restconf-client/provider/src/main/resources/META-INF/spring/restconf-client-osgi-context.xml2
-rwxr-xr-xrestconf-client/provider/src/main/resources/org/opendaylight/blueprint/restconf-client-blueprint.xml4
8 files changed, 589 insertions, 79 deletions
diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiCallNode.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiCallNode.java
new file mode 100644
index 00000000..c5f73305
--- /dev/null
+++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiCallNode.java
@@ -0,0 +1,362 @@
+/*-
+ * ============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 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.HttpResponse;
+import org.onap.ccsdk.sli.plugins.restapicall.RestapiCallNode;
+import org.onap.ccsdk.sli.plugins.restapicall.RetryException;
+import org.onap.ccsdk.sli.plugins.restapicall.RetryPolicy;
+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.PropertiesNodeSerializer;
+import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
+import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.core.UriBuilder;
+import java.net.SocketException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static java.lang.String.format;
+import static org.apache.commons.lang3.StringUtils.join;
+import static org.onap.ccsdk.sli.plugins.restapicall.HttpMethod.POST;
+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.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.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.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);
+
+ /**
+ * Creates an instance of restconf api call node.
+ */
+ public RestconfApiCallNode() {
+ }
+
+ /**
+ * 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 = new RestapiCallNode();
+ RetryPolicy retryPolicy = null;
+ HttpResponse r = new HttpResponse();
+ try {
+ YangParameters p = getYangParameters(paramMap);
+ if (p.partner != null) {
+ retryPolicy = rest.getRetryPolicyStore()
+ .getRetryPolicy(p.partner);
+ }
+
+ 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 == POST || p.httpMethod == PUT) {
+ req = serializeRequest(props, p, uri, 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) {
+ 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) {
+ 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);
+ if (retryPolicy == null || shouldRetry == false) {
+ setFailureResponseStatus(ctx, prefix, e.getMessage(), r);
+ } else {
+ if (retryCount == null) {
+ retryCount = 0;
+ }
+ log.debug(format(ATTEMPTS_MSG, retryCount,
+ retryPolicy.getMaximumRetries()));
+ try {
+ retryCount = retryCount + 1;
+ if (retryCount < retryPolicy.getMaximumRetries() + 1) {
+ setRetryUri(paramMap, retryPolicy);
+ log.debug(format(RETRY_COUNT, retryCount, retryPolicy
+ .getMaximumRetries()));
+ sendRequest(paramMap, ctx, retryCount);
+ } else {
+ log.debug(MAX_RETRY_ERR);
+ setFailureResponseStatus(ctx, prefix,
+ e.getMessage(), r);
+ }
+ } catch (Exception ex) {
+ log.error(NO_MORE_RETRY, ex);
+ setFailureResponseStatus(ctx, prefix, RETRY_FAIL, r);
+ }
+ }
+ }
+
+ if (r != null && r.code >= 300) {
+ throw new SvcLogicException(
+ String.valueOf(r.code) + ": " + r.message);
+ }
+ }
+
+ /**
+ * 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
+ */
+ protected 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
+ */
+ protected 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);
+ ControllerContext contCtx = ControllerContext.getInstance();
+ contCtx.onGlobalContextUpdated(context);
+ return contCtx.toInstanceIdentifier(uri);
+ }
+
+ /**
+ * 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
+ */
+ private String getResponse(SvcLogicContext ctx, YangParameters params,
+ String pre, HttpResponse res) {
+ ctx.setAttribute(pre + RES_CODE, String.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
+ * @param res http response
+ */
+ private void setFailureResponseStatus(SvcLogicContext ctx, String prefix,
+ String errMsg, HttpResponse res) {
+ res = new HttpResponse();
+ res.code = 500;
+ res.message = errMsg;
+ ctx.setAttribute(prefix + RES_CODE, String.valueOf(res.code));
+ ctx.setAttribute(prefix + RES_MSG, res.message);
+ }
+
+ /**
+ * Sets the retry URI to the param map from the retry policies different
+ * host.
+ *
+ * @param paramMap parameter map
+ * @param retryPolicy retry policy
+ * @throws URISyntaxException when new URI creation fails
+ * @throws RetryException when retry policy cannot give another host
+ */
+ private void setRetryUri(Map<String, String> paramMap,
+ RetryPolicy retryPolicy)
+ throws URISyntaxException, RetryException {
+ URI uri = new URI(paramMap.get(REST_API_URL));
+ String hostName = uri.getHost();
+ String retryString = retryPolicy.getNextHostName(uri.toString());
+
+ URI uriTwo = new URI(retryString);
+ URI retryUri = UriBuilder.fromUri(uri).host(uriTwo.getHost()).port(
+ uriTwo.getPort()).scheme(uriTwo.getScheme()).build();
+
+ paramMap.put(REST_API_URL, retryUri.toString());
+ log.debug(UPDATED_URL + retryUri.toString());
+ log.debug(format(COMM_FAIL, hostName, retryString));
+ }
+}
diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiUtils.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiUtils.java
new file mode 100644
index 00000000..e066671b
--- /dev/null
+++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiUtils.java
@@ -0,0 +1,213 @@
+/*-
+ * ============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 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 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 static org.onap.ccsdk.sli.plugins.restapicall.HttpMethod.PUT;
+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 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 RESTCONF_PATH = "/restconf/operations/";
+
+ private static final String PUT_NODE_ERR = "The following URL does not " +
+ "contain minimum two nodes for PUT operation.";
+
+ 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
+ */
+ 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();
+ if (path.contains(RESTCONF_PATH)) {
+ path = path.replaceFirst(RESTCONF_PATH, "");
+ }
+ if (method == PUT) {
+ if (!path.contains(SLASH)) {
+ throw new SvcLogicException(PUT_NODE_ERR + url);
+ }
+ path = path.substring(0, path.lastIndexOf(SLASH));
+ }
+ 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) {
+ for (File file : files) {
+ if (file.isFile() && file.getName().endsWith(YANG)) {
+ yangFiles.add(file);
+ } else if (file.isDirectory()) {
+ getYangFiles(file, yangFiles);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfapiCallNode.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfapiCallNode.java
deleted file mode 100644
index 87cb92bc..00000000
--- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfapiCallNode.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-
- * ============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 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;
-
-/**
- * Representation of a plugin to enable RESTCONF based CRUD operations from DG.
- */
-public class RestconfapiCallNode implements SvcLogicJavaPlugin {
-
- public RestconfapiCallNode() {
- }
-
- /**
- * Allows Directed Graphs the ability to interact with RESTCONF APIs.
- * @param parameters 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>templateFileName</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>restapiUrl</td><td>Mandatory</td><td>url to send the request to</td><td>https://sdncodl:8543/restconf/operations/L3VNF-API:create-update-vnf-request</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>httpMethod</td><td>Optional</td><td>http method to use when sending the request</td><td>get post put delete patch</td></tr>
- * <tr><td>responsePrefix</td><td>Optional</td><td>location the response will be written to in context memory</td><td>tmp.resconftapi.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)
- */
- public void sendRequest(Map<String, String> paramMap, SvcLogicContext ctx) throws SvcLogicException {
- //TODO
- }
-
-}
diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/RestconfDiscoveryNode.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/RestconfDiscoveryNode.java
index 34bb2ee6..0490b3a5 100644
--- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/RestconfDiscoveryNode.java
+++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfdiscovery/RestconfDiscoveryNode.java
@@ -24,7 +24,7 @@ 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.restconfapicall.RestconfapiCallNode;
+import org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiCallNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -46,7 +46,7 @@ public class RestconfDiscoveryNode implements SvcLogicDiscoveryPlugin {
private ExecutorService executor = Executors.newCachedThreadPool();
private Map<String, PersistentConnection> runnableInfo = new ConcurrentHashMap<>();
- private RestconfapiCallNode restconfapiCallNode;
+ private RestconfApiCallNode restconfApiCallNode;
private volatile Map<String, SubscriptionInfo> subscriptionInfoMap = new ConcurrentHashMap<>();
private volatile LinkedBlockingQueue<String> eventQueue = new LinkedBlockingQueue<>();
@@ -78,7 +78,7 @@ public class RestconfDiscoveryNode implements SvcLogicDiscoveryPlugin {
throw new SvcLogicException("Subscriber Id is null");
}
- restconfapiCallNode.sendRequest(paramMap, ctx);
+ restconfApiCallNode.sendRequest(paramMap, ctx);
if (getResponseCode(paramMap.get(RESPONSE_PREFIX), ctx).equals(RESPONSE_CODE_200)) {
// TODO: save subscription id and subscriber in MYSQL
@@ -207,8 +207,8 @@ public class RestconfDiscoveryNode implements SvcLogicDiscoveryPlugin {
*
* @return restconfApiCallNode
*/
- protected RestconfapiCallNode restconfapiCallNode() {
- return restconfapiCallNode;
+ protected RestconfApiCallNode restconfapiCallNode() {
+ return restconfApiCallNode;
}
/**
@@ -216,8 +216,8 @@ public class RestconfDiscoveryNode implements SvcLogicDiscoveryPlugin {
*
* @param node restconfApiCallNode
*/
- void restconfapiCallNode(RestconfapiCallNode node) {
- restconfapiCallNode = node;
+ void restconfapiCallNode(RestconfApiCallNode node) {
+ restconfApiCallNode = node;
}
Map<String, SubscriptionInfo> subscriptionInfoMap() {
diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/MdsalSerializerHelper.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/MdsalSerializerHelper.java
index a3e30c4b..5a898dfc 100644
--- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/MdsalSerializerHelper.java
+++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/MdsalSerializerHelper.java
@@ -76,8 +76,8 @@ public class MdsalSerializerHelper extends SerializerHelper<SchemaNode, SchemaCo
* @param c schema context
* @param u URI of the request
*/
- protected MdsalSerializerHelper(SchemaNode n, SchemaContext c,
- String u) {
+ public MdsalSerializerHelper(SchemaNode n, SchemaContext c,
+ String u) {
super(n, c, u);
Namespace ns = new Namespace(n.getQName().getLocalName(),
n.getQName().getNamespace(),
diff --git a/restconf-client/provider/src/main/resources/META-INF/spring/restconf-client-context.xml b/restconf-client/provider/src/main/resources/META-INF/spring/restconf-client-context.xml
index 34344fe0..f99f4f84 100644
--- a/restconf-client/provider/src/main/resources/META-INF/spring/restconf-client-context.xml
+++ b/restconf-client/provider/src/main/resources/META-INF/spring/restconf-client-context.xml
@@ -37,12 +37,12 @@
<!-- context:property-placeholder location="file:${SDNC_CONFIG_DIR}/ueb.properties" /-->
- <bean id="restconfapiCallNode" class="org.onap.ccsdk.sli.plugins.restconfapicall.RestconfapiCallNode">
+ <bean id="restconfApiCallNode" class="org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiCallNode">
<property name="uebServers" value="${servers}" />
</bean>
<bean id="restconfDiscoveryNode" class="org.onap.ccsdk.sli.plugins.restconfdiscovery.RestconfDiscoveryNode">
- <property name="restconfapiCallNode" ref="restconfapiCallNode" />
+ <property name="restconfApiCallNode" ref="restconfApiCallNode" />
</bean>
</beans>
diff --git a/restconf-client/provider/src/main/resources/META-INF/spring/restconf-client-osgi-context.xml b/restconf-client/provider/src/main/resources/META-INF/spring/restconf-client-osgi-context.xml
index d56e2fc1..5a9f22be 100644
--- a/restconf-client/provider/src/main/resources/META-INF/spring/restconf-client-osgi-context.xml
+++ b/restconf-client/provider/src/main/resources/META-INF/spring/restconf-client-osgi-context.xml
@@ -26,7 +26,7 @@
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
- <service ref="restconfapiCallNode" interface="org.onap.ccsdk.sli.plugins.restconfapicall.RestconfapiCallNode" />
+ <service ref="restconfApiCallNode" interface="org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiCallNode" />
<service ref="restconfDiscoveryNode" interface="org.onap.ccsdk.sli.plugins.restconfdiscovery.RestconfDiscoveryNode" />
</beans:beans>
diff --git a/restconf-client/provider/src/main/resources/org/opendaylight/blueprint/restconf-client-blueprint.xml b/restconf-client/provider/src/main/resources/org/opendaylight/blueprint/restconf-client-blueprint.xml
index 149ed9fc..91c31efc 100755
--- a/restconf-client/provider/src/main/resources/org/opendaylight/blueprint/restconf-client-blueprint.xml
+++ b/restconf-client/provider/src/main/resources/org/opendaylight/blueprint/restconf-client-blueprint.xml
@@ -23,12 +23,12 @@
xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
odl:use-default-for-reference-types="true">
- <bean id="restconfapiCallNodeProvider" class="org.onap.ccsdk.sli.plugins.restconfapicall.RestconfapiCallNode" />
+ <bean id="restconfapiCallNodeProvider" class="org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiCallNode" />
<bean id="restconfDiscoveryNodeProvider" class="org.onap.ccsdk.sli.plugins.restconfdiscovery.RestconfDiscoveryNode" />
<service ref="restconfapiCallNodeProvider">
<interfaces>
- <value>org.onap.ccsdk.sli.plugins.restconfapicall.RestconfapiCallNode</value>
+ <value>org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiCallNode</value>
</interfaces>
</service>