2 * Copyright 2017 Huawei Technologies Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.onap.cli.fw.utils;
19 import com.fasterxml.jackson.databind.ObjectMapper;
20 import com.jayway.jsonpath.JsonPath;
21 import net.minidev.json.JSONArray;
23 import org.onap.cli.fw.OnapCommand;
24 import org.onap.cli.fw.ad.OnapCredentials;
25 import org.onap.cli.fw.ad.OnapService;
26 import org.onap.cli.fw.cmd.OnapHttpCommand;
27 import org.onap.cli.fw.cmd.OnapSwaggerCommand;
28 import org.onap.cli.fw.conf.Constants;
29 import org.onap.cli.fw.error.OnapCommandDiscoveryFailed;
30 import org.onap.cli.fw.error.OnapCommandException;
31 import org.onap.cli.fw.error.OnapCommandHelpFailed;
32 import org.onap.cli.fw.error.OnapCommandHttpHeaderNotFound;
33 import org.onap.cli.fw.error.OnapCommandHttpInvalidResponseBody;
34 import org.onap.cli.fw.error.OnapCommandInvalidParameterType;
35 import org.onap.cli.fw.error.OnapCommandInvalidParameterValue;
36 import org.onap.cli.fw.error.OnapCommandInvalidPrintDirection;
37 import org.onap.cli.fw.error.OnapCommandInvalidResultAttributeScope;
38 import org.onap.cli.fw.error.OnapCommandInvalidSchema;
39 import org.onap.cli.fw.error.OnapCommandInvalidSchemaVersion;
40 import org.onap.cli.fw.error.OnapCommandParameterNameConflict;
41 import org.onap.cli.fw.error.OnapCommandParameterNotFound;
42 import org.onap.cli.fw.error.OnapCommandParameterOptionConflict;
43 import org.onap.cli.fw.error.OnapCommandResultEmpty;
44 import org.onap.cli.fw.error.OnapCommandResultMapProcessingFailed;
45 import org.onap.cli.fw.error.OnapCommandSchemaNotFound;
46 import org.onap.cli.fw.http.HttpInput;
47 import org.onap.cli.fw.http.HttpResult;
48 import org.onap.cli.fw.input.OnapCommandParameter;
49 import org.onap.cli.fw.input.ParameterType;
50 import org.onap.cli.fw.output.OnapCommandResult;
51 import org.onap.cli.fw.output.OnapCommandResultAttribute;
52 import org.onap.cli.fw.output.OnapCommandResultAttributeScope;
53 import org.onap.cli.fw.output.PrintDirection;
54 import org.onap.cli.fw.output.ResultType;
55 import org.onap.cli.fw.run.OnapCommandExecutor;
56 import org.springframework.core.io.Resource;
57 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
58 import org.springframework.core.io.support.ResourcePatternResolver;
59 import org.yaml.snakeyaml.Yaml;
62 import java.io.IOException;
63 import java.io.InputStream;
64 import java.util.ArrayList;
65 import java.util.Arrays;
66 import java.util.Collections;
67 import java.util.HashMap;
68 import java.util.List;
70 import java.util.Map.Entry;
71 import java.util.ServiceLoader;
75 * Provides helper method to parse Yaml files and produce required objects.
78 public class OnapCommandUtils {
81 * Private constructor.
83 private OnapCommandUtils() {
88 * Validates schema version.
95 * @throws OnapCommandInvalidSchemaVersion
96 * invalid schema version exception
97 * @throws OnapCommandInvalidSchema
99 * @throws OnapCommandSchemaNotFound
102 public static Map<String, ?> validateSchemaVersion(String schemaName, String version) throws OnapCommandException {
103 InputStream inputStream = OnapCommandUtils.class.getClassLoader().getResourceAsStream(schemaName);
106 Resource resource = getExternalResource(schemaName, Constants.EXTERNAL_SCHEMA_PATH_PATERN);
108 if (resource != null) {
109 inputStream = resource.getInputStream();
112 } catch (IOException e) {
113 throw new OnapCommandSchemaNotFound(schemaName, e);
115 if (inputStream == null) {
116 throw new OnapCommandSchemaNotFound(schemaName);
119 Map<String, ?> values = null;
121 values = (Map<String, ?>) new Yaml().load(inputStream);
122 } catch (Exception e) {
123 throw new OnapCommandInvalidSchema(schemaName, e);
125 String schemaVersion = "";
126 if (values.keySet().contains(Constants.ONAP_CMD_SCHEMA_VERSION)) {
127 Object obj = values.get(Constants.ONAP_CMD_SCHEMA_VERSION);
128 schemaVersion = obj.toString();
131 if (!version.equals(schemaVersion)) {
132 throw new OnapCommandInvalidSchemaVersion(schemaVersion);
139 * Retrieve OnapCommand from schema.
145 * @param includeDefault
147 * @throws OnapCommandParameterNameConflict
148 * param name conflict exception
149 * @throws OnapCommandParameterOptionConflict
150 * param option conflict exception
151 * @throws OnapCommandInvalidParameterType
152 * invalid param type exception
153 * @throws OnapCommandInvalidPrintDirection
154 * invalid print direction exception
155 * @throws OnapCommandInvalidResultAttributeScope
156 * invalid scope exception
157 * @throws OnapCommandSchemaNotFound
159 * @throws OnapCommandInvalidSchema
161 * @throws OnapCommandInvalidSchemaVersion
162 * invalid schema version
164 public static void loadSchema(OnapCommand cmd, String schemaName, boolean includeDefault)
165 throws OnapCommandException {
166 List<String> shortOptions = new ArrayList<>();
167 List<String> longOptions = new ArrayList<>();
168 List<String> names = new ArrayList<>();
170 if (includeDefault) {
171 loadSchema(cmd, Constants.DEFAULT_PARAMETER_FILE_NAME, shortOptions, longOptions, names);
174 loadSchema(cmd, schemaName, shortOptions, longOptions, names);
178 private static void loadSchema(OnapCommand cmd, String schemaName, List<String> shortOptions,
179 List<String> longOptions, List<String> names) throws OnapCommandException {
181 Map<String, ?> values = validateSchemaVersion(schemaName, cmd.getSchemaVersion());
183 for (Map.Entry<String, ?> entry : values.entrySet()) {
184 String key = entry.getKey();
186 if (Constants.NAME.equals(key)) {
187 Object val = values.get(key);
188 cmd.setName(val.toString());
189 } else if (Constants.DESCRIPTION.equals(key)) {
190 Object val = values.get(key);
191 cmd.setDescription(val.toString());
192 } else if (Constants.SERVICE.equals(key)) {
193 Map<String, String> map = (Map<String, String>) values.get(key);
194 OnapService srv = new OnapService();
196 for (Map.Entry<String, String> entry1 : map.entrySet()) {
197 String key1 = entry1.getKey();
199 if (Constants.NAME.equals(key1)) {
200 srv.setName(map.get(key1));
201 } else if (Constants.VERSION.equals(key1)) {
202 srv.setVersion(map.get(key1));
203 } else if (Constants.NO_AUTH.equals(key1)) {
204 Object obj = map.get(key1);
205 srv.setNoAuth("true".equalsIgnoreCase(obj.toString()));
210 } else if (Constants.PARAMETERS.equals(key)) {
211 List<Map<String, String>> list = (ArrayList) values.get(key);
213 for (Map<String, String> map : list) {
214 OnapCommandParameter param = new OnapCommandParameter();
216 for (Map.Entry<String, String> entry1 : map.entrySet()) {
217 String key2 = entry1.getKey();
219 if (Constants.NAME.equals(key2)) {
220 if (names.contains(map.get(key2))) {
221 throw new OnapCommandParameterNameConflict(map.get(key2));
223 names.add(map.get(key2));
224 param.setName(map.get(key2));
225 } else if (Constants.DESCRIPTION.equals(key2)) {
226 param.setDescription(map.get(key2));
227 } else if (Constants.SHORT_OPTION.equals(key2)) {
228 if (shortOptions.contains(map.get(key2))) {
229 throw new OnapCommandParameterOptionConflict(map.get(key2));
231 shortOptions.add(map.get(key2));
232 param.setShortOption(map.get(key2));
233 } else if (Constants.LONG_OPTION.equals(key2)) {
234 if (longOptions.contains(map.get(key2))) {
235 throw new OnapCommandParameterOptionConflict(map.get(key2));
237 longOptions.add(map.get(key2));
238 param.setLongOption(map.get(key2));
239 } else if (Constants.DEFAULT_VALUE.equals(key2)) {
240 Object obj = map.get(key2);
241 param.setDefaultValue(obj.toString());
242 } else if (Constants.TYPE.equals(key2)) {
243 param.setParameterType(ParameterType.get(map.get(key2)));
244 } else if (Constants.IS_OPTIONAL.equals(key2)) {
245 if ("true".equalsIgnoreCase(String.valueOf(map.get(key2)))) {
246 param.setOptional(true);
248 param.setOptional(false);
250 } else if (Constants.IS_SECURED.equals(key2)) {
251 if ("true".equalsIgnoreCase(String.valueOf(map.get(key2)))) {
252 param.setSecured(true);
254 param.setSecured(false);
258 cmd.getParameters().add(param);
261 } else if (Constants.RESULTS.equals(key)) {
262 Map<String, ?> valueMap = (Map<String, ?>) values.get(key);
263 OnapCommandResult result = new OnapCommandResult();
264 for (Map.Entry<String, ?> entry1 : valueMap.entrySet()) {
265 String key3 = entry1.getKey();
267 if (Constants.DIRECTION.equals(key3)) {
268 result.setPrintDirection(PrintDirection.get((String) valueMap.get(key3)));
269 } else if (Constants.ATTRIBUTES.equals(key3)) {
270 List<Map<String, String>> attrs = (ArrayList) valueMap.get(key3);
272 for (Map<String, String> map : attrs) {
273 OnapCommandResultAttribute attr = new OnapCommandResultAttribute();
274 for (Map.Entry<String, String> entry4 : map.entrySet()) {
275 String key4 = entry4.getKey();
277 if (Constants.NAME.equals(key4)) {
278 attr.setName(map.get(key4));
279 } else if (Constants.DESCRIPTION.equals(key4)) {
280 attr.setDescription(map.get(key4));
281 } else if (Constants.SCOPE.equals(key4)) {
282 attr.setScope(OnapCommandResultAttributeScope.get(map.get(key4)));
283 } else if (Constants.TYPE.equals(key4)) {
284 attr.setType(ParameterType.get(map.get(key4)));
285 } else if (Constants.IS_SECURED.equals(key4)) {
286 if ("true".equals(String.valueOf(map.get(key4)))) {
287 attr.setSecured(true);
289 attr.setSecured(false);
294 result.getRecords().add(attr);
298 cmd.setResult(result);
301 } catch (OnapCommandException e) {
303 } catch (Exception e) {
304 throw new OnapCommandInvalidSchema(schemaName, e);
312 * OnapSwaggerBasedCommand
315 * @throws OnapCommandParameterNameConflict
316 * param name conflict exception
317 * @throws OnapCommandParameterOptionConflict
318 * param option conflict exception
319 * @throws OnapCommandInvalidParameterType
320 * invalid param type exception
321 * @throws OnapCommandInvalidPrintDirection
322 * invalid print direction exception
323 * @throws OnapCommandInvalidResultAttributeScope
324 * invalid scope exception
325 * @throws OnapCommandSchemaNotFound
327 * @throws OnapCommandInvalidSchema
329 * @throws OnapCommandInvalidSchemaVersion
330 * invalid schema version
332 public static void loadSchema(OnapSwaggerCommand cmd, String schemaName) throws OnapCommandException {
334 Map<String, ?> values = (Map<String, ?>) validateSchemaVersion(schemaName, cmd.getSchemaVersion());
335 Map<String, String> valueMap = (Map<String, String>) values.get(Constants.EXECUTOR);
336 OnapCommandExecutor exec = new OnapCommandExecutor();
338 for (Map.Entry<String, String> entry1 : valueMap.entrySet()) {
339 String key1 = entry1.getKey();
341 if (Constants.API.equals(key1)) {
342 exec.setApi(valueMap.get(key1));
343 } else if (Constants.CLIENT.equals(key1)) {
344 exec.setClient(valueMap.get(key1));
345 } else if (Constants.ENTITY.equals(key1)) {
346 exec.setEntity(valueMap.get(key1));
347 } else if (Constants.EXCEPTION.equals(key1)) {
348 exec.setException(valueMap.get(key1));
349 } else if (Constants.METHOD.equals(key1)) {
350 exec.setMethod(valueMap.get(key1));
354 cmd.setExecutor(exec);
355 } catch (OnapCommandException e) {
357 } catch (Exception e) {
358 throw new OnapCommandInvalidSchema(schemaName, e);
369 * @throws OnapCommandParameterNameConflict
370 * param name conflict exception
371 * @throws OnapCommandParameterOptionConflict
372 * param option conflict exception
373 * @throws OnapCommandInvalidParameterType
374 * invalid param type exception
375 * @throws OnapCommandInvalidPrintDirection
376 * invalid print direction exception
377 * @throws OnapCommandInvalidResultAttributeScope
378 * invalid scope exception
379 * @throws OnapCommandSchemaNotFound
381 * @throws OnapCommandInvalidSchema
383 * @throws OnapCommandInvalidSchemaVersion
384 * invalid schema version
386 public static void loadSchema(OnapHttpCommand cmd, String schemaName) throws OnapCommandException {
388 Map<String, ?> values = (Map<String, ?>) validateSchemaVersion(schemaName, cmd.getSchemaVersion());
389 Map<String, ?> valMap = (Map<String, ?>) values.get(Constants.HTTP);
391 for (Map.Entry<String, ?> entry1 : valMap.entrySet()) {
392 String key1 = entry1.getKey();
393 if (Constants.REQUEST.equals(key1)) {
394 Map<String, ?> map = (Map<String, ?>) valMap.get(key1);
396 for (Map.Entry<String, ?> entry2 : map.entrySet()) {
397 String key2 = entry2.getKey();
399 if (Constants.URI.equals(key2)) {
400 Object obj = map.get(key2);
401 cmd.getInput().setUri(obj.toString());
402 } else if (Constants.MERHOD.equals(key2)) {
403 Object obj = map.get(key2);
404 cmd.getInput().setMethod(obj.toString());
405 } else if (Constants.BODY.equals(key2)) {
406 Object obj = map.get(key2);
407 cmd.getInput().setBody(obj.toString());
408 } else if (Constants.HEADERS.equals(key2)) {
409 Map<String, String> head = (Map<String, String>) map.get(key2);
410 cmd.getInput().setReqHeaders(head);
411 } else if (Constants.QUERIES.equals(key2)) {
412 Map<String, String> query = (Map<String, String>) map.get(key2);
414 cmd.getInput().setReqQueries(query);
417 } else if (Constants.SUCCESS_CODES.equals(key1)) {
418 cmd.setSuccessStatusCodes((ArrayList) valMap.get(key1));
419 } else if (Constants.RESULT_MAP.equals(key1)) {
420 cmd.setResultMap((Map<String, String>) valMap.get(key1));
421 } else if (Constants.SAMPLE_RESPONSE.equals(key1)) {
422 // (mrkanag) implement sample response handling
426 } catch (OnapCommandException e) {
428 } catch (Exception e) {
429 throw new OnapCommandInvalidSchema(schemaName, e);
438 * @return help string
439 * @throws OnapCommandHelpFailed
440 * help failed exception
442 public static String help(OnapCommand cmd) throws OnapCommandHelpFailed {
443 String help = "usage: onap " + cmd.getName();
446 help += "\n\n" + cmd.getDescription();
449 help += "\n\nOnap service: " + cmd.getService();
452 String commandOptions = "";
455 OnapCommandResult paramTable = new OnapCommandResult();
456 paramTable.setPrintDirection(PrintDirection.LANDSCAPE);
457 paramTable.setType(ResultType.TABLE);
458 paramTable.setIncludeTitle(false);
459 paramTable.setIncludeSeparator(false);
461 OnapCommandResultAttribute attrName = new OnapCommandResultAttribute();
462 attrName.setName(Constants.NAME);
463 attrName.setDescription(Constants.NAME);
464 attrName.setScope(OnapCommandResultAttributeScope.SHORT);
465 paramTable.getRecords().add(attrName);
467 OnapCommandResultAttribute attrDescription = new OnapCommandResultAttribute();
468 attrDescription.setName(Constants.DESCRIPTION);
469 attrDescription.setDescription(Constants.DESCRIPTION);
470 attrDescription.setScope(OnapCommandResultAttributeScope.SHORT);
471 paramTable.getRecords().add(attrDescription);
473 int newLineOptions = 0;
474 for (OnapCommandParameter param : cmd.getParameters()) {
475 // First column Option or positional args
477 if (newLineOptions == 3) {
479 commandOptions += "\n";
482 if (param.getShortOption() != null || param.getLongOption() != null) {
483 optFirstCol = OnapCommandParameter.printShortOption(param.getShortOption()) + " | "
484 + OnapCommandParameter.printLongOption(param.getLongOption());
485 commandOptions += "[" + optFirstCol + "] ";
487 optFirstCol = param.getName();
488 commandOptions += "<" + optFirstCol + "> ";
493 attrName.getValues().add(optFirstCol);
495 // Second column description
496 String optSecondCol = param.getDescription().trim();
497 if (!optSecondCol.endsWith(".")) {
500 optSecondCol += " It is of type " + param.getParameterType().name() + ".";
502 if (param.getParameterType().equals(ParameterType.JSON)
503 || param.getParameterType().equals(ParameterType.YAML)) {
504 optSecondCol += " It's recommended to input the complete path of the file, which is having the value for it.";
506 if (param.isOptional()) {
507 optSecondCol += " It is optional.";
510 String defaultMsg = " By default, it is ";
511 if (param.isDefaultValueAnEnv()) {
512 optSecondCol += defaultMsg + "read from environment variable " + param.getEnvVarNameFromDefaultValue()
514 } else if (param.getDefaultValue() != null && !param.getDefaultValue().isEmpty()) {
515 optSecondCol += defaultMsg + param.getDefaultValue() + ".";
518 if (param.isSecured()) {
519 optSecondCol += " Secured.";
521 // (mrkanag) Add help msg for reading default value from env
522 attrDescription.getValues().add(optSecondCol);
526 help += "\n\nOptions:\n" + commandOptions + "\nwhere,\n" + paramTable.print();
527 } catch (OnapCommandException e) {
528 throw new OnapCommandHelpFailed(e);
532 OnapCommandResult resultTable = new OnapCommandResult();
533 resultTable.setPrintDirection(PrintDirection.PORTRAIT);
534 resultTable.setType(ResultType.TABLE);
535 resultTable.setIncludeTitle(false);
536 resultTable.setIncludeSeparator(false);
538 for (OnapCommandResultAttribute attr : cmd.getResult().getRecords()) {
539 OnapCommandResultAttribute attrHelp = new OnapCommandResultAttribute();
540 attrHelp.setName(attr.getName());
541 attrHelp.setDescription(attr.getDescription());
542 String msg = attr.getDescription() + " and is of type " + attr.getType().name() + ".";
543 if (attr.isSecured()) {
544 msg += " It is secured.";
546 attrHelp.getValues().add(msg);
547 attrHelp.setType(attr.getType());
548 resultTable.getRecords().add(attrHelp);
551 help += "\n\nResults:\n" + resultTable.print();
552 } catch (OnapCommandException e) {
553 throw new OnapCommandHelpFailed(e);
557 help += "\n\nError:\nOn error, it prints <HTTP STATUS CODE>::<ERROR CODE>::<ERROR MESSAGE>\n";
562 * Helps to create OnapCredentials from default params.
566 * @return OnapCredentials
567 * @throws OnapCommandInvalidParameterValue
570 public static OnapCredentials fromParameters(List<OnapCommandParameter> params)
571 throws OnapCommandInvalidParameterValue {
572 Map<String, String> paramMap = new HashMap<>();
574 for (OnapCommandParameter param : params) {
575 paramMap.put(param.getName(), param.getValue().toString());
578 return new OnapCredentials(paramMap.get(Constants.DEAFULT_PARAMETER_USERNAME),
579 paramMap.get(Constants.DEAFULT_PARAMETER_PASS_WORD),
580 paramMap.get(Constants.DEAFULT_PARAMETER_MSB_URL));
584 * Create Dict from list of Parameters.
590 public static Map<String, OnapCommandParameter> getInputMap(List<OnapCommandParameter> inputs) {
591 Map<String, OnapCommandParameter> map = new HashMap<>();
592 for (OnapCommandParameter param : inputs) {
593 map.put(param.getName(), param);
599 * Discover the Onap commands.
603 public static List<Class<OnapCommand>> findOnapCommands() {
604 ServiceLoader<OnapCommand> loader = ServiceLoader.load(OnapCommand.class);
605 List<Class<OnapCommand>> clss = new ArrayList<>();
606 for (OnapCommand implClass : loader) {
607 clss.add((Class<OnapCommand>) implClass.getClass());
620 public static List<String> sort(Set<String> col) {
621 List<String> results = new ArrayList<>();
623 Collections.sort(results);
628 * Flatten the json list.
634 public static List<String> jsonFlatten(List<String> jsons) {
635 List<String> results = new ArrayList<>();
636 for (String json : jsons) {
638 results.add(JsonPath.parse(json).jsonString());
639 } catch (Exception e) { // NOSONAR
648 * Construct method name.
656 public static String formMethodNameFromAttributeName(String name, String prefix) {
657 if (name == null || name.isEmpty()) {
661 String methodName = prefix;
662 for (String tk : name.split("-")) {
663 methodName += Character.toString(tk.charAt(0)).toUpperCase();
664 methodName += tk.substring(1);
669 private static String replaceLineFromInputParameters(String line, Map<String, OnapCommandParameter> params)
670 throws OnapCommandException {
673 if (!line.contains("${")) {
678 while (currentIdx < line.length()) {
679 int idxS = line.indexOf("${", currentIdx);
681 result += line.substring(currentIdx);
684 int idxE = line.indexOf("}", idxS);
685 String paramName = line.substring(idxS + 2, idxE);
686 paramName = paramName.trim();
687 if (!params.containsKey(paramName)) {
688 throw new OnapCommandParameterNotFound(paramName);
691 String value = params.get(paramName).getValue().toString();
693 OnapCommandParameter param = params.get(paramName);
694 if (ParameterType.ARRAY.equals(param.getParameterType())
695 || ParameterType.MAP.equals(param.getParameterType())
696 || ParameterType.JSON.equals(param.getParameterType())
697 || ParameterType.YAML.equals(param.getParameterType())) {
698 // ignore the front and back double quotes in json body
699 result += line.substring(currentIdx, idxS - 1) + value;
700 currentIdx = idxE + 2;
702 result += line.substring(currentIdx, idxS) + value;
703 currentIdx = idxE + 1;
710 private static ArrayList<String> replaceLineFromOutputResults(String line, HttpResult resultHttp)
711 throws OnapCommandHttpHeaderNotFound, OnapCommandHttpInvalidResponseBody,
712 OnapCommandResultMapProcessingFailed, OnapCommandResultEmpty {
713 String headerProcessedLine = "";
715 ArrayList<String> result = new ArrayList<>();
716 if (!line.contains("$b{") && !line.contains("$h{")) {
722 * In case of empty response body [] or {}
724 if (resultHttp.getBody().length() <= 2) {
729 * Process headers macros : line: $h{abc}-$b{$.[*].xyz} , After processing line will be [abc's
730 * value]-$b{$.[*].xyz}
733 while (currentIdx < line.length()) {
734 int idxS = line.indexOf("$h{", currentIdx);
736 headerProcessedLine += line.substring(currentIdx);
739 int idxE = line.indexOf("}", idxS);
740 String headerName = line.substring(idxS + 3, idxE);
741 headerName = headerName.trim();
742 if (!resultHttp.getRespHeaders().containsKey(headerName)) {
743 throw new OnapCommandHttpHeaderNotFound(headerName);
745 String value = resultHttp.getRespHeaders().get(headerName);
747 headerProcessedLine += line.substring(currentIdx, idxS) + value;
748 currentIdx = idxE + 1;
751 // Process body jsonpath macros
752 List<Object> values = new ArrayList<>();
753 String bodyProcessedPattern = "";
755 int maxRows = 1; // in normal case, only one row will be there
756 while (currentIdx < headerProcessedLine.length()) {
757 int idxS = headerProcessedLine.indexOf("$b{", currentIdx);
759 bodyProcessedPattern += headerProcessedLine.substring(currentIdx);
762 int idxE = headerProcessedLine.indexOf("}", idxS);
763 String jsonPath = headerProcessedLine.substring(idxS + 3, idxE);
764 jsonPath = jsonPath.trim();
766 // JSONArray or String
767 Object value = JsonPath.read(resultHttp.getBody(), jsonPath);
768 if (value instanceof JSONArray) {
769 JSONArray arr = (JSONArray) value;
770 if (arr.size() > maxRows) {
771 maxRows = arr.size();
774 bodyProcessedPattern += headerProcessedLine.substring(currentIdx, idxS) + "%s";
776 currentIdx = idxE + 1;
777 } catch (Exception e) {
778 throw new OnapCommandHttpInvalidResponseBody(jsonPath, e);
782 if (bodyProcessedPattern.isEmpty()) {
783 result.add(headerProcessedLine);
786 for (int i = 0; i < maxRows; i++) {
788 String bodyProcessedLine = "";
789 int positionalIdx = 0; // %s positional idx
790 while (currentIdx < bodyProcessedPattern.length()) {
791 int idxS = bodyProcessedPattern.indexOf("%s", currentIdx);
793 bodyProcessedLine += bodyProcessedPattern.substring(currentIdx);
796 int idxE = idxS + 2; // %s
798 Object value = values.get(positionalIdx);
799 String valueS = String.valueOf(value);
800 if (value instanceof JSONArray) {
801 JSONArray arr = (JSONArray) value;
802 if (!arr.isEmpty()) {
803 valueS = arr.get(i).toString();
805 throw new OnapCommandResultEmpty();
809 bodyProcessedLine += bodyProcessedPattern.substring(currentIdx, idxS) + valueS;
812 } catch (OnapCommandResultEmpty e) {
814 } catch (Exception e) {
815 throw new OnapCommandResultMapProcessingFailed(line, e);
818 result.add(bodyProcessedLine);
826 * Set argument to param value.
833 * @throws OnapCommandParameterNotFound
835 * @throws OnapCommandInvalidParameterValue
838 public static HttpInput populateParameters(Map<String, OnapCommandParameter> params, HttpInput input)
839 throws OnapCommandException {
840 HttpInput inp = new HttpInput();
841 for (OnapCommandParameter param : params.values()) {
842 if (ParameterType.BINARY.equals(param.getParameterType())) {
843 inp.setBinaryData(true);
847 inp.setBody(replaceLineFromInputParameters(input.getBody(), params));
848 inp.setUri(replaceLineFromInputParameters(input.getUri(), params));
849 inp.setMethod(input.getMethod().toLowerCase());
850 for (String h : input.getReqHeaders().keySet()) {
851 String value = input.getReqHeaders().get(h);
852 inp.getReqHeaders().put(h, replaceLineFromInputParameters(value, params));
855 for (String h : input.getReqQueries().keySet()) {
856 String value = input.getReqQueries().get(h);
857 inp.getReqQueries().put(h, replaceLineFromInputParameters(value, params));
871 * @throws OnapCommandHttpHeaderNotFound
872 * header not found exception
873 * @throws OnapCommandHttpInvalidResponseBody
874 * invalid response body exception
875 * @throws OnapCommandResultMapProcessingFailed
876 * map processing failed exception
878 public static Map<String, ArrayList<String>> populateOutputs(Map<String, String> resultMap, HttpResult resultHttp)
879 throws OnapCommandException {
880 Map<String, ArrayList<String>> resultsProcessed = new HashMap<>();
882 for (Entry<String, String> entry : resultMap.entrySet()) {
883 String key = entry.getKey();
884 resultsProcessed.put(key, replaceLineFromOutputResults(resultMap.get(key), resultHttp));
887 return resultsProcessed;
891 * Find external schema files.
893 * @return list ExternalSchema
894 * @throws OnapCommandDiscoveryFailed
896 * @throws OnapCommandInvalidSchema
899 public static List<ExternalSchema> findAllExternalSchemas() throws OnapCommandException {
900 List<ExternalSchema> extSchemas = new ArrayList<>();
902 Resource[] res = getExternalResources(Constants.EXTERNAL_SCHEMA_PATH_PATERN);
903 if (res != null && res.length > 0) {
904 Map<String, ?> resourceMap;
905 for (Resource resource : res) {
906 resourceMap = getExternalSchemaMap(resource);
907 if (resourceMap != null && resourceMap.size() > 0) {
908 ExternalSchema schema = new ExternalSchema();
909 schema.setSchemaName(resource.getFilename());
910 schema.setCmdName((String) resourceMap.get(Constants.NAME));
911 Object obj = resourceMap.get(Constants.ONAP_CMD_SCHEMA_VERSION);
912 schema.setVersion(obj.toString());
913 extSchemas.add(schema);
917 } catch (IOException e) {
918 throw new OnapCommandDiscoveryFailed(Constants.EXTERNAL_SCHEMA_DIRECTORY, e);
925 * Returns all resources available under certain directory in class-path.
929 * @return resources found resources
930 * @throws IOException
933 public static Resource[] getExternalResources(String pattern) throws IOException {
934 ClassLoader cl = OnapCommandUtils.class.getClassLoader();
935 ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);
936 return resolver.getResources("classpath*:" + pattern);
940 * Returns a resource available under certain directory in class-path.
944 * @return found resource
945 * @throws IOException
948 public static Resource getExternalResource(String fileName, String pattern) throws IOException {
949 Resource[] resources = getExternalResources(pattern);
950 if (resources != null && resources.length > 0) {
951 for (Resource res : resources) {
952 if (res.getFilename().equals(fileName)) {
967 * @throws OnapCommandInvalidSchema
970 public static Map<String, ?> getExternalSchemaMap(Resource resource) throws OnapCommandInvalidSchema {
971 Map<String, ?> values = null;
973 values = (Map<String, ?>) new Yaml().load(resource.getInputStream());
974 } catch (Exception e) {
975 throw new OnapCommandInvalidSchema(resource.getFilename(), e);
981 * Persist the external schema details.
985 * @throws OnapCommandDiscoveryFailed
988 public static void persist(List<ExternalSchema> schemas) throws OnapCommandDiscoveryFailed {
989 if (schemas != null) {
991 Resource[] resources = getExternalResources(Constants.EXTERNAL_DISCOVERY_DIRECTORY);
992 if (resources != null && resources.length == 1) {
993 String path = resources[0].getURI().getPath();
994 File file = new File(path + File.separator + Constants.EXTERNAL_DISCOVERY_FILE);
995 ObjectMapper mapper = new ObjectMapper();
996 mapper.writerWithDefaultPrettyPrinter().writeValue(file, schemas);
998 } catch (IOException e1) {
999 throw new OnapCommandDiscoveryFailed(Constants.EXTERNAL_DISCOVERY_DIRECTORY,
1000 Constants.EXTERNAL_DISCOVERY_FILE, e1);
1006 * Check if json file discovered or not.
1009 * @throws OnapCommandDiscoveryFailed
1012 public static boolean isJsonFileDiscovered() throws OnapCommandDiscoveryFailed {
1013 Resource resource = null;
1015 resource = getExternalResource(Constants.EXTERNAL_DISCOVERY_FILE,
1016 Constants.EXTERNAL_DISCOVERY_DIRECTORY_PATTERN);
1017 if (resource != null) {
1020 } catch (IOException e) {
1021 throw new OnapCommandDiscoveryFailed(Constants.EXTERNAL_DISCOVERY_DIRECTORY,
1022 Constants.EXTERNAL_DISCOVERY_FILE, e);
1029 * Load the previous discovered json file.
1032 * @throws OnapCommandInvalidSchema
1034 * @throws OnapCommandDiscoveryFailed
1037 public static List<ExternalSchema> loadExternalSchemasFromJson() throws OnapCommandException {
1038 List<ExternalSchema> schemas = new ArrayList<>();
1039 if (!isJsonFileDiscovered()) {
1040 schemas = findAllExternalSchemas();
1041 if (!schemas.isEmpty()) {
1046 Resource resource = getExternalResource(Constants.EXTERNAL_DISCOVERY_FILE,
1047 Constants.EXTERNAL_DISCOVERY_DIRECTORY_PATTERN);
1048 if (resource != null) {
1049 File file = new File(resource.getURI().getPath());
1050 ObjectMapper mapper = new ObjectMapper();
1051 ExternalSchema[] list = mapper.readValue(file, ExternalSchema[].class);
1052 schemas.addAll(Arrays.asList(list));
1054 } catch (IOException e) {
1055 throw new OnapCommandDiscoveryFailed(Constants.EXTERNAL_DISCOVERY_DIRECTORY,
1056 Constants.EXTERNAL_DISCOVERY_FILE, e);
1064 * Fetch a particular schema details.
1068 * @return ExternalSchema obj
1069 * @throws OnapCommandInvalidSchema
1071 * @throws OnapCommandDiscoveryFailed
1074 public static ExternalSchema loadExternalSchemaFromJson(String cmd) throws OnapCommandException {
1075 List<ExternalSchema> list = loadExternalSchemasFromJson();
1076 ExternalSchema schemaStr = null;
1078 for (ExternalSchema schema : list) {
1079 if (cmd.equals(schema.getCmdName())) {