2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
7 * Modifications Copyright © 2018 IBM.
8 * Modifications Copyright (c) 2021 AT&T
9 * ================================================================================
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 * ============LICENSE_END=========================================================
24 package org.onap.ccsdk.sli.plugins.restconfapicall;
26 import static org.onap.ccsdk.sli.plugins.restapicall.RestapiCallNode.getParameters;
27 import static org.onap.ccsdk.sli.plugins.restapicall.RestapiCallNode.parseParam;
28 import static org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource.forFile;
30 import java.io.IOException;
32 import java.net.URISyntaxException;
33 import java.nio.file.Path;
34 import java.nio.file.Paths;
35 import java.util.LinkedList;
36 import java.util.List;
38 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
39 import org.onap.ccsdk.sli.plugins.restapicall.HttpMethod;
40 import org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.YangParameters;
41 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
42 import org.opendaylight.yangtools.yang.model.parser.api.YangParser;
43 import org.opendaylight.yangtools.yang.model.parser.api.YangParserException;
44 import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory;
45 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
48 * Utilities for restconf api call node.
50 public final class RestconfApiUtils {
52 static final String RES_CODE = "response-code";
54 static final String HTTP_REQ ="httpRequest";
56 static final String RES_PRE = "responsePrefix";
58 static final String RES_MSG = "response-message";
60 static final String HEADER = "header.";
62 static final String COMMA = ",";
64 static final String COLON = ":";
66 static final String HTTP_RES = "httpResponse";
68 static final String REST_API_URL = "restapiUrl";
70 static final String UPDATED_URL = "URL was set to";
72 static final String COMM_FAIL = "Failed to communicate with host %s." +
73 "Request will be re-attempted using the host %s.";
75 static final String RETRY_COUNT = "This is retry attempt %d out of %d";
77 static final String RETRY_FAIL = "Retry attempt has failed. No further " +
78 "retry shall be attempted, calling setFailureResponseStatus";
80 static final String NO_MORE_RETRY = "Could not attempt retry";
82 static final String MAX_RETRY_ERR = "Maximum retries reached, calling " +
83 "setFailureResponseStatus";
85 static final String ATTEMPTS_MSG = "%d attempts were made out of %d " +
88 static final String REQ_ERR = "Error sending the request: ";
90 private static final String SLASH = "/";
92 private static final String DIR_PATH = "dirPath";
94 private static final String URL_SYNTAX = "The following URL cannot be " +
97 private static final String YANG = ".yang";
99 private static final String YANG_FILE_ERR = "Unable to parse the YANG " +
103 private RestconfApiUtils() {
107 * Returns the YANG parameters after parsing it from the map.
109 * @param paramMap parameters map
110 * @return YANG parameters
111 * @throws SvcLogicException when parsing of parameters map fail
113 static YangParameters getYangParameters(Map<String, String> paramMap)
114 throws SvcLogicException {
115 YangParameters param = (YangParameters) getParameters(
116 paramMap, new YangParameters());
117 param.dirPath = parseParam(paramMap, DIR_PATH, false, null);
122 * Parses the restconf URL and gives the YANG path from it, which can be
123 * used to get schema node. If it is a PUT operation, then a node must be
124 * reduced from the url to make it always point to the parent.
126 * @param url restconf URL
127 * @param method HTTP operation
128 * @return YANG path pointing to parent
129 * @throws SvcLogicException when parsing the URL fails
131 public static String parseUrl(String url, HttpMethod method)
132 throws SvcLogicException {
136 } catch (URISyntaxException e) {
137 throw new SvcLogicException(URL_SYNTAX + url, e);
140 String path = uri.getPath();
141 path = getParsedPath(path);
146 * Returns the path which contains only the schema nodes.
149 * @return path representing schema
151 private static String getParsedPath(String path) {
154 if (path.contains(COLON)) {
155 String[] p = path.split(COLON);
156 if (p[0].contains(SLASH)) {
157 int slash = p[0].lastIndexOf(SLASH);
158 firstHalf = p[0].substring(slash + 1);
162 secondHalf = path.substring(p[0].length() + 1);
163 return firstHalf + COLON + secondHalf;
164 } else if (path.contains(SLASH)) {
165 String[] p = path.split(SLASH);
167 String actual = p[3] + COLON + p[4];
169 secondHalf = path.substring(
170 p[1].length() + p[2].length() + actual.length() + 3);
171 path = actual + secondHalf;
181 * Returns the schema context of the YANG files present in a directory.
183 * @param di directory path
184 * @return YANG schema context
185 * @throws SvcLogicException when YANG file reading fails
187 static EffectiveModelContext getSchemaCtxFromDir(YangParserFactory parserFactory, String di)
188 throws SvcLogicException {
189 Path d = Paths.get(di);
190 File dir = d.toFile();
191 List<File> yangFiles = new LinkedList<>();
192 getYangFiles(dir, yangFiles);
193 YangParser parser = parserFactory.createParser();
194 for (File file : yangFiles) {
196 parser.addSource(forFile(file));
197 } catch (IOException | YangSyntaxErrorException e) {
198 throw new SvcLogicException(YANG_FILE_ERR + e.getMessage(), e);
203 return parser.buildEffectiveModel();
204 } catch (YangParserException e) {
205 throw new SvcLogicException(YANG_FILE_ERR + e.getMessage(), e);
210 * Returns all the YANG files present in a directory recursively.
212 * @param dir path of the directory
213 * @param yangFiles list of YANG files
215 private static void getYangFiles(File dir, List<File> yangFiles) {
217 File[] files = dir.listFiles();
219 processFiles(files, yangFiles);
225 * Processes all the obtained files by isolating all the YANG files from
226 * all the directory of the given path recursively.
228 * @param files files in the given path
229 * @param yangFiles YANG files list
231 private static void processFiles(File[] files, List<File> yangFiles) {
232 for (File file : files) {
233 if (file.isFile() && file.getName().endsWith(YANG)) {
235 } else if (file.isDirectory()) {
236 getYangFiles(file, yangFiles);
242 * Returns the updated XML request message by adding root node to it.
244 * @param req XML request
245 * @param nodeName root node name
246 * @param modNs module namespace of the root node
247 * @return updated XML request message
249 static String getUpdatedXmlReq(String req, String nodeName, String modNs) {
250 String rootNode = "\n<" + nodeName + " xmlns=\"" + modNs +
252 req = req.replaceFirst("\n", rootNode);
253 req = req + "</" + nodeName + ">";
254 return req.replaceAll(">\\s+<", "><");