diff options
Diffstat (limited to 'utils/src')
62 files changed, 2587 insertions, 659 deletions
diff --git a/utils/src/main/java/org/onap/policy/common/utils/cmd/CommandLineArgumentsHandler.java b/utils/src/main/java/org/onap/policy/common/utils/cmd/CommandLineArgumentsHandler.java new file mode 100644 index 00000000..970cebfe --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/cmd/CommandLineArgumentsHandler.java @@ -0,0 +1,273 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.cmd; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.lang3.StringUtils; +import org.onap.policy.common.utils.resources.ResourceUtils; + +/** + * Class for command line common processing. + * + * @author Adheli Tavares (adheli.tavares@est.tech) + * + */ +public class CommandLineArgumentsHandler { + private static final String FILE_MESSAGE_PREAMBLE = " file \""; + private static final int HELP_LINE_LENGTH = 120; + + private final Options options; + + private final String helpClassName; + private final String component; + + @Getter + @Setter + private String configurationFilePath = null; + + @Getter + @Setter + private String propertyFilePath = null; + + @Getter + private CommandLine commandLine = null; + + /** + * Construct the options with default values for the CLI editor. + */ + protected CommandLineArgumentsHandler(String helpClassName, String component) { + this.helpClassName = helpClassName; + this.component = component; + //@formatter:off + options = new Options(); + options.addOption(Option.builder("h") + .longOpt("help") + .desc("outputs the usage of this command") + .required(false) + .type(Boolean.class) + .build()); + options.addOption(Option.builder("v") + .longOpt("version") + .desc("outputs the version of " + this.component) + .required(false) + .type(Boolean.class) + .build()); + options.addOption(Option.builder("c") + .longOpt("config-file") + .desc(String.format("the full path to the configuration file to use, " + + "the configuration file must be a Json file containing the %s parameters", this.component)) + .hasArg().argName("CONFIG_FILE") + .required(false) + .type(String.class) + .build()); + //@formatter:on + } + + /** + * Construct the options for the CLI editor with extra options. + */ + public CommandLineArgumentsHandler(String helpClassName, String component, Option... customOptions) { + this(helpClassName, component); + if (customOptions != null) { + for (Option option : customOptions) { + options.addOption(option); + } + } + } + + /** + * Construct the options with brand-new options for the CLI editor. + */ + public CommandLineArgumentsHandler(String helpClassName, String component, Options options) { + this.options = options; + this.helpClassName = helpClassName; + this.component = component; + } + + /** + * Parse the command line options. + * + * @param args The command line arguments + * @return a string with a message for help and version, or null if there is no message + * @throws CommandLineException on command argument errors + */ + public String parse(final String[] args) throws CommandLineException { + // Clear all our arguments + setConfigurationFilePath(null); + setPropertyFilePath(null); + + try { + commandLine = new DefaultParser().parse(options, args); + } catch (final ParseException | NullPointerException e) { + throw new CommandLineException("invalid command line arguments specified", e); + } + + // Arguments left over after Commons CLI does its stuff + final String[] remainingArgs = removeEmptyValues(commandLine.getArgs()); + + if (remainingArgs.length > 0) { + throw new CommandLineException("too many command line arguments specified: " + Arrays.toString(args)); + } + + if (commandLine.hasOption('h')) { + return help(); + } + + if (commandLine.hasOption('v')) { + return version(); + } + + if (commandLine.hasOption('c')) { + setConfigurationFilePath(commandLine.getOptionValue('c')); + } + + if (commandLine.hasOption('p')) { + setPropertyFilePath(commandLine.getOptionValue('p')); + } + + return null; + } + + /** + * Validate the command line options. + * + * @throws CommandLineException on command argument validation errors + */ + public void validate() throws CommandLineException { + validateReadableFile(this.component + " configuration", configurationFilePath); + } + + /** + * Print version information for policy distribution. + * + * @return the version string + */ + public String version() { + return ResourceUtils.getResourceAsString("version.txt"); + } + + /** + * Print help information for policy distribution. + * + * @return the help string + */ + public String help() { + final var helpFormatter = new HelpFormatter(); + final var stringWriter = new StringWriter(); + final var printWriter = new PrintWriter(stringWriter); + final String cmdLineSyntax = this.helpClassName + " [options...]"; + + helpFormatter.printHelp(printWriter, HELP_LINE_LENGTH, cmdLineSyntax, "options", options, 0, 0, ""); + + return stringWriter.toString(); + } + + /** + * Gets the full expanded configuration file path. + * + * @return the configuration file path + */ + public String getFullConfigurationFilePath() { + return ResourceUtils.getFilePath4Resource(getConfigurationFilePath()); + } + + /** + * Check set configuration file path. + * + * @return true, if check set configuration file path + */ + public boolean checkSetConfigurationFilePath() { + return StringUtils.isNotBlank(getConfigurationFilePath()); + } + + /** + * Gets the full expanded property file path. + * + * @return the property file path + */ + public String getFullPropertyFilePath() { + return ResourceUtils.getFilePath4Resource(getPropertyFilePath()); + } + + /** + * Check set property file path. + * + * @return true, if check set property file path + */ + public boolean checkSetPropertyFilePath() { + return StringUtils.isNotBlank(getPropertyFilePath()); + } + + /** + * Validate readable file. + * + * @param fileTag the file tag + * @param fileName the file name + * @throws CommandLineException on the file name passed as a parameter + */ + protected void validateReadableFile(final String fileTag, final String fileName) throws CommandLineException { + if (StringUtils.isBlank(fileName)) { + throw new CommandLineException(fileTag + " file was not specified as an argument"); + } + + // The file name refers to a resource on the local file system + final var fileUrl = ResourceUtils.getUrl4Resource(fileName); + if (fileUrl == null) { + throw new CommandLineException(fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" does not exist"); + } + + try { + var path = Path.of(fileUrl.toURI()); + if (!Files.isRegularFile(path)) { + throw new CommandLineException(fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" is not a normal file"); + } + if (!Files.isReadable(path)) { + throw new CommandLineException(fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" is unreadable"); + } + } catch (URISyntaxException e) { + throw new CommandLineException("Error parsing " + fileUrl.toString(), e); + } + + } + + /** + * Checks if args has any null or empty value after parsing. + * + * @param args remaining args from CLI parse. + */ + private String[] removeEmptyValues(String[] args) { + return Arrays.stream(args).filter(StringUtils::isNotBlank).toArray(String[]::new); + } +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/cmd/CommandLineException.java b/utils/src/main/java/org/onap/policy/common/utils/cmd/CommandLineException.java new file mode 100644 index 00000000..9cdf3d37 --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/cmd/CommandLineException.java @@ -0,0 +1,57 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.cmd; + +import java.io.Serial; + +/** + * Exception used for CommandLineArguments class. + * + * @author Adheli Tavares (adheli.tavares@est.tech) + * + */ +public class CommandLineException extends Exception { + + /** + * Generated serialVersionUID. + */ + @Serial + private static final long serialVersionUID = -1200607308084606425L; + + /** + * Instantiates a new exception with a message. + * + * @param message the message + */ + public CommandLineException(final String message) { + super(message); + } + + /** + * Instantiates a new exception with a message and a caused by exception. + * + * @param message the message + * @param exp the exception that caused this exception to be thrown + */ + public CommandLineException(final String message, final Exception exp) { + super(message, exp); + } +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/coder/Coder.java b/utils/src/main/java/org/onap/policy/common/utils/coder/Coder.java index ec0e5e42..3049a5c2 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/coder/Coder.java +++ b/utils/src/main/java/org/onap/policy/common/utils/coder/Coder.java @@ -32,6 +32,37 @@ import java.io.Writer; public interface Coder { /** + * Converts an object/POJO to an object of the given type. + * + * @param <T> desired type + * @param source source object + * @param clazz class of the desired object type + * @return the converted object + * @throws CoderException if an error occurs + */ + default <S, T> T convert(S source, Class<T> clazz) throws CoderException { + if (source == null) { + return null; + + } else if (clazz == source.getClass()) { + // same class - just cast it + return clazz.cast(source); + + } else if (clazz == String.class) { + // target is a string - just encode the source + return (clazz.cast(encode(source))); + + } else if (source.getClass() == String.class) { + // source is a string - just decode it + return decode(source.toString(), clazz); + + } else { + // do it the long way: encode to a string and then decode the string + return decode(encode(source), clazz); + } + } + + /** * Encodes an object into json. * * @param object object to be encoded @@ -44,7 +75,8 @@ public interface Coder { * Encodes an object into json, optionally making it "pretty". * * @param object object to be encoded - * @param pretty {@code true} if it should be encoded as "pretty" json, {@code false} otherwise + * @param pretty {@code true} if it should be encoded as "pretty" json, {@code false} + * otherwise * @return a json string representing the object * @throws CoderException if an error occurs */ diff --git a/utils/src/main/java/org/onap/policy/common/utils/coder/PropertyCoder.java b/utils/src/main/java/org/onap/policy/common/utils/coder/PropertyCoder.java index 3036d353..daacf479 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/coder/PropertyCoder.java +++ b/utils/src/main/java/org/onap/policy/common/utils/coder/PropertyCoder.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP PAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019, 2021 AT&T Intellectual Property. 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. @@ -55,12 +55,12 @@ public class PropertyCoder { * @return a class T object */ public <T> T decode(String json, String keyProperty, Class<T> clazz) { - JsonElement jsonElement = GSON.fromJson(json, JsonElement.class); + var jsonElement = GSON.fromJson(json, JsonElement.class); return new MyDecoder(jsonElement, keyProperty).decrypt(jsonElement, clazz); } public <T> T decode(Reader reader, String keyProperty, Class<T> clazz) { - JsonElement jsonElement = GSON.fromJson(reader, JsonElement.class); + var jsonElement = GSON.fromJson(reader, JsonElement.class); return new MyDecoder(jsonElement, keyProperty).decrypt(jsonElement, clazz); } @@ -71,9 +71,9 @@ public class PropertyCoder { if (!jsonElement.isJsonObject()) { return; } - JsonObject jsonObject = jsonElement.getAsJsonObject(); + var jsonObject = jsonElement.getAsJsonObject(); // Use keyProperty from input to retrieve secretKey - String secretKey = jsonObject.get(keyProperty).getAsString(); + var secretKey = jsonObject.get(keyProperty).getAsString(); if (!StringUtils.isBlank(secretKey)) { crypto = new CryptoUtils(secretKey); } @@ -97,7 +97,7 @@ public class PropertyCoder { if (!jsonElement.getAsJsonPrimitive().isString()) { return jsonElement; } - String value = jsonElement.getAsString(); + var value = jsonElement.getAsString(); if (!value.startsWith("enc:")) { return jsonElement; } @@ -111,7 +111,7 @@ public class PropertyCoder { if (crypto == null) { return jsonArray; } - JsonArray newArray = new JsonArray(); + var newArray = new JsonArray(); for (JsonElement element: jsonArray) { newArray.add(decrypt(element)); } @@ -122,14 +122,14 @@ public class PropertyCoder { if (crypto == null) { return jsonObject; } - JsonObject newObject = new JsonObject(); + var newObject = new JsonObject(); Set<Entry<String, JsonElement>> entrySet = jsonObject.entrySet(); for (Map.Entry<String, JsonElement> entry : entrySet) { String key = entry.getKey(); - JsonElement jsonElement = decrypt(entry.getValue()); + var jsonElement = decrypt(entry.getValue()); newObject.add(key, jsonElement); } return newObject; } } -}
\ No newline at end of file +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoder.java b/utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoder.java index 13973f1c..d6135afd 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoder.java +++ b/utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoder.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2021 AT&T Intellectual Property. 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. @@ -41,40 +41,82 @@ import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; import lombok.AccessLevel; -import lombok.Getter; +import lombok.AllArgsConstructor; import org.onap.policy.common.gson.DoubleConverter; import org.onap.policy.common.gson.GsonMessageBodyHandler; /** * JSON encoder and decoder using the "standard" mechanism, which is currently gson. */ +@AllArgsConstructor(access = AccessLevel.PROTECTED) public class StandardCoder implements Coder { /** * Gson object used to encode and decode messages. */ - @Getter(AccessLevel.PROTECTED) - private static final Gson GSON; + private static final Gson GSON_STD; /** * Gson object used to encode messages in "pretty" format. */ - @Getter(AccessLevel.PROTECTED) - private static final Gson GSON_PRETTY; + private static final Gson GSON_STD_PRETTY; static { GsonBuilder builder = GsonMessageBodyHandler.configBuilder( new GsonBuilder().registerTypeAdapter(StandardCoderObject.class, new StandardTypeAdapter())); - GSON = builder.create(); - GSON_PRETTY = builder.setPrettyPrinting().create(); + GSON_STD = builder.create(); + GSON_STD_PRETTY = builder.setPrettyPrinting().create(); } /** + * Gson object used to encode and decode messages. + */ + protected final Gson gson; + + /** + * Gson object used to encode messages in "pretty" format. + */ + protected final Gson gsonPretty; + + /** * Constructs the object. */ public StandardCoder() { - super(); + this(GSON_STD, GSON_STD_PRETTY); + } + + @Override + public <S, T> T convert(S source, Class<T> clazz) throws CoderException { + if (source == null) { + return null; + + } else if (clazz == source.getClass()) { + // same class - just cast it + return clazz.cast(source); + + } else if (clazz == String.class) { + // target is a string - just encode the source + return (clazz.cast(encode(source))); + + } else if (source.getClass() == String.class) { + // source is a string - just decode it + return decode(source.toString(), clazz); + + } else { + /* + * Do it the long way: encode to a tree and then decode the tree. This entire + * method could have been left out and the default Coder.convert() used + * instead, but this should perform slightly better as it only uses a + * JsonElement as the intermediate data structure, while Coder.convert() goes + * all the way to a String as the intermediate data structure. + */ + try { + return fromJson(toJsonTree(source), clazz); + } catch (RuntimeException e) { + throw new CoderException(e); + } + } } @Override @@ -110,7 +152,7 @@ public class StandardCoder implements Coder { @Override public void encode(OutputStream target, Object object) throws CoderException { try { - Writer wtr = makeWriter(target); + var wtr = makeWriter(target); toJson(wtr, object); // flush, but don't close @@ -123,7 +165,7 @@ public class StandardCoder implements Coder { @Override public void encode(File target, Object object) throws CoderException { - try (Writer wtr = makeWriter(target)) { + try (var wtr = makeWriter(target)) { toJson(wtr, object); // no need to flush or close here @@ -165,7 +207,7 @@ public class StandardCoder implements Coder { @Override public <T> T decode(File source, Class<T> clazz) throws CoderException { - try (Reader input = makeReader(source)) { + try (var input = makeReader(source)) { return fromJson(input, clazz); } catch (RuntimeException | IOException e) { @@ -180,13 +222,13 @@ public class StandardCoder implements Coder { * @return the encoded object */ protected String toPrettyJson(Object object) { - return GSON_PRETTY.toJson(object); + return gsonPretty.toJson(object); } @Override public StandardCoderObject toStandard(Object object) throws CoderException { try { - return new StandardCoderObject(GSON.toJsonTree(object)); + return new StandardCoderObject(gson.toJsonTree(object)); } catch (RuntimeException e) { throw new CoderException(e); @@ -196,7 +238,7 @@ public class StandardCoder implements Coder { @Override public <T> T fromStandard(StandardCoderObject sco, Class<T> clazz) throws CoderException { try { - return GSON.fromJson(sco.getData(), clazz); + return gson.fromJson(sco.getData(), clazz); } catch (RuntimeException e) { throw new CoderException(e); @@ -254,7 +296,7 @@ public class StandardCoder implements Coder { * @return a json element representing the object */ protected JsonElement toJsonTree(Object object) { - return GSON.toJsonTree(object); + return gson.toJsonTree(object); } /** @@ -264,7 +306,7 @@ public class StandardCoder implements Coder { * @return a json string representing the object */ protected String toJson(Object object) { - return GSON.toJson(object); + return gson.toJson(object); } /** @@ -274,7 +316,7 @@ public class StandardCoder implements Coder { * @param object object to be encoded */ protected void toJson(Writer target, Object object) { - GSON.toJson(object, object.getClass(), target); + gson.toJson(object, object.getClass(), target); } /** @@ -285,7 +327,7 @@ public class StandardCoder implements Coder { * @return the object represented by the given json element */ protected <T> T fromJson(JsonElement json, Class<T> clazz) { - return convertFromDouble(clazz, GSON.fromJson(json, clazz)); + return convertFromDouble(clazz, gson.fromJson(json, clazz)); } /** @@ -296,7 +338,7 @@ public class StandardCoder implements Coder { * @return the object represented by the given json string */ protected <T> T fromJson(String json, Class<T> clazz) { - return convertFromDouble(clazz, GSON.fromJson(json, clazz)); + return convertFromDouble(clazz, gson.fromJson(json, clazz)); } /** @@ -307,7 +349,7 @@ public class StandardCoder implements Coder { * @return the object represented by the given json string */ protected <T> T fromJson(Reader source, Class<T> clazz) { - return convertFromDouble(clazz, GSON.fromJson(source, clazz)); + return convertFromDouble(clazz, gson.fromJson(source, clazz)); } /** @@ -330,20 +372,14 @@ public class StandardCoder implements Coder { /** * Adapter for standard objects. */ - private static class StandardTypeAdapter extends TypeAdapter<StandardCoderObject> { + @AllArgsConstructor + protected static class StandardTypeAdapter extends TypeAdapter<StandardCoderObject> { /** * Used to read/write a JsonElement. */ private static TypeAdapter<JsonElement> elementAdapter = new Gson().getAdapter(JsonElement.class); - /** - * Constructs the object. - */ - public StandardTypeAdapter() { - super(); - } - @Override public void write(JsonWriter out, StandardCoderObject value) throws IOException { elementAdapter.write(out, value.getData()); diff --git a/utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoderInstantAsMillis.java b/utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoderInstantAsMillis.java new file mode 100644 index 00000000..27b239bb --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoderInstantAsMillis.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. 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.policy.common.utils.coder; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.time.Instant; +import org.onap.policy.common.gson.GsonMessageBodyHandler; +import org.onap.policy.common.gson.InstantAsMillisTypeAdapter; + +/** + * JSON encoder and decoder using the "standard" mechanism, but encodes Instant fields as + * Long milliseconds. + */ +public class StandardCoderInstantAsMillis extends StandardCoder { + + /** + * Gson object used to encode and decode messages. + */ + private static final Gson GSON_INSTANT; + + /** + * Gson object used to encode messages in "pretty" format. + */ + private static final Gson GSON_INSTANT_PRETTY; + + static { + GsonBuilder builder = GsonMessageBodyHandler + .configBuilder(new GsonBuilder().registerTypeAdapter(StandardCoderObject.class, + new StandardTypeAdapter())) + .registerTypeAdapter(Instant.class, new InstantAsMillisTypeAdapter()); + + GSON_INSTANT = builder.create(); + GSON_INSTANT_PRETTY = builder.setPrettyPrinting().create(); + } + + /** + * Constructs the object. + */ + public StandardCoderInstantAsMillis() { + super(GSON_INSTANT, GSON_INSTANT_PRETTY); + } +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoderObject.java b/utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoderObject.java index 7f0f0580..55f7f9d7 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoderObject.java +++ b/utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoderObject.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2021 AT&T Intellectual Property. 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. @@ -20,22 +20,30 @@ package org.onap.policy.common.utils.coder; -import com.google.gson.JsonArray; import com.google.gson.JsonElement; import java.io.Serializable; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; /** * Object type used by the {@link StandardCoder}. Different serialization tools have * different "standard objects". For instance, GSON uses {@link JsonElement}. This class * wraps that object so that it can be used without exposing the object, itself. */ +@AllArgsConstructor(access = AccessLevel.PROTECTED) public class StandardCoderObject implements Serializable { private static final long serialVersionUID = 1L; /** * Data wrapped by this. */ - private final JsonElement data; + /* + * this should not be transient, but since it isn't serializable, we're stuck with it + * until there's time to address the issue + */ + @Getter(AccessLevel.PROTECTED) + private final transient JsonElement data; /** * Constructs the object. @@ -45,24 +53,6 @@ public class StandardCoderObject implements Serializable { } /** - * Constructs the object. - * - * @param data data wrapped by this object. - */ - protected StandardCoderObject(JsonElement data) { - this.data = data; - } - - /** - * Gets the data wrapped by this. - * - * @return the data wrapped by this - */ - protected JsonElement getData() { - return data; - } - - /** * Gets a field's value from this object, traversing the object hierarchy. * * @param fields field hierarchy. These may be strings, identifying fields within the @@ -126,7 +116,7 @@ public class StandardCoderObject implements Serializable { return null; } - JsonArray array = element.getAsJsonArray(); + var array = element.getAsJsonArray(); if (index >= array.size()) { return null; diff --git a/utils/src/main/java/org/onap/policy/common/utils/coder/StandardValCoder.java b/utils/src/main/java/org/onap/policy/common/utils/coder/StandardValCoder.java index 6e08e722..4deeba14 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/coder/StandardValCoder.java +++ b/utils/src/main/java/org/onap/policy/common/utils/coder/StandardValCoder.java @@ -1,6 +1,6 @@ -/* +/*-- * ============LICENSE_START======================================================= - * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2020-2021 AT&T Intellectual Property. 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. @@ -36,8 +36,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Extension to the StandardCoder to support streaming validation - * against a Draft-07 Json schema specification. + * Extension to the StandardCoder to support streaming validation against a Draft-07 Json schema specification. */ @ToString @@ -56,43 +55,42 @@ public class StandardValCoder extends StandardCoder { * StandardCoder with validation. */ public StandardValCoder(@NonNull String jsonSchema, @NonNull String name) { - SchemaSource schemaSource = - new StringSchemaSource(jsonSchema, JsonSchemaVersion.DRAFT07, null, name); + SchemaSource schemaSource = new StringSchemaSource(jsonSchema, JsonSchemaVersion.DRAFT07, null, name); this.validator = validatorApi.loadSchema(schemaSource); } @Override protected String toPrettyJson(Object object) { /* - * The validator strips off the "pretty" stuff (i.e., spaces), thus we have to validate - * and generate the pretty JSON in separate steps. + * The validator strips off the "pretty" stuff (i.e., spaces), thus we have to validate and generate the pretty + * JSON in separate steps. */ - getGSON().toJson(object, object.getClass(), validatorApi.createJsonWriter(validator, new StringWriter())); + gson.toJson(object, object.getClass(), validatorApi.createJsonWriter(validator, new StringWriter())); return super.toPrettyJson(object); } @Override protected String toJson(@NonNull Object object) { - StringWriter output = new StringWriter(); + var output = new StringWriter(); toJson(output, object); return output.toString(); } @Override protected void toJson(@NonNull Writer target, @NonNull Object object) { - getGSON().toJson(object, object.getClass(), validatorApi.createJsonWriter(validator, target)); + gson.toJson(object, object.getClass(), validatorApi.createJsonWriter(validator, target)); } @Override protected <T> T fromJson(@NonNull Reader source, @NonNull Class<T> clazz) { - return convertFromDouble(clazz, getGSON().fromJson(validatorApi.createJsonReader(validator, source), clazz)); + return convertFromDouble(clazz, gson.fromJson(validatorApi.createJsonReader(validator, source), clazz)); } @Override protected <T> T fromJson(String json, Class<T> clazz) { - StringReader reader = new StringReader(json); - return convertFromDouble(clazz, getGSON().fromJson(validatorApi.createJsonReader(validator, reader), clazz)); + var reader = new StringReader(json); + return convertFromDouble(clazz, gson.fromJson(validatorApi.createJsonReader(validator, reader), clazz)); } /** @@ -102,7 +100,7 @@ public class StandardValCoder extends StandardCoder { try { conformance(json); } catch (CoderException e) { - logger.info("JSON is not conformant to schema {}", e); + logger.info("JSON is not conformant to schema", e); return false; } return true; diff --git a/utils/src/main/java/org/onap/policy/common/utils/coder/StandardYamlCoder.java b/utils/src/main/java/org/onap/policy/common/utils/coder/StandardYamlCoder.java index 1bcf6ac0..d94ddca4 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/coder/StandardYamlCoder.java +++ b/utils/src/main/java/org/onap/policy/common/utils/coder/StandardYamlCoder.java @@ -34,7 +34,12 @@ public class StandardYamlCoder extends StandardCoder { * Constructs the object. */ public StandardYamlCoder() { - translator = new YamlJsonTranslator(getGSON()); + translator = new YamlJsonTranslator(gson) { + @Override + protected <T> T convertFromDouble(Class<T> clazz, T value) { + return StandardYamlCoder.this.convertFromDouble(clazz, value); + } + }; } @Override diff --git a/utils/src/main/java/org/onap/policy/common/utils/coder/YamlJsonTranslator.java b/utils/src/main/java/org/onap/policy/common/utils/coder/YamlJsonTranslator.java index 906c9fdd..077246bf 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/coder/YamlJsonTranslator.java +++ b/utils/src/main/java/org/onap/policy/common/utils/coder/YamlJsonTranslator.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2021 AT&T Intellectual Property. 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. @@ -21,6 +21,7 @@ package org.onap.policy.common.utils.coder; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonNull; @@ -31,9 +32,12 @@ import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; +import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.Map.Entry; +import lombok.AllArgsConstructor; +import org.onap.policy.common.gson.InstantTypeAdapter; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.emitter.Emitter; @@ -50,7 +54,13 @@ import org.yaml.snakeyaml.serializer.Serializer; /** * YAML-JSON translator. The methods may throw either of the runtime exceptions, * YAMLException or JsonSyntaxException. + * <p/> + * Note: if the invoker wishes Double to be converted to Integer/Long when type + * Object.class is requested, then a Gson object must be used that will perform the + * translation. In addition, the {@link #convertFromDouble(Class, Object)} method should + * be overridden with an appropriate conversion method. */ +@AllArgsConstructor public class YamlJsonTranslator { /** @@ -62,16 +72,9 @@ public class YamlJsonTranslator { * Constructs the object. */ public YamlJsonTranslator() { - this(new Gson()); - } - - /** - * Constructs the object. - * - * @param gson the Gson object to be used to serialize and de-serialize - */ - public YamlJsonTranslator(Gson gson) { - this.gson = gson; + GsonBuilder builder = new GsonBuilder(); + builder.registerTypeAdapter(Instant.class, new InstantTypeAdapter()); + gson = builder.create(); } /** @@ -81,7 +84,7 @@ public class YamlJsonTranslator { * @return YAML representing the original object */ public String toYaml(Object object) { - StringWriter output = new StringWriter(); + var output = new StringWriter(); toYaml(output, object); return output.toString(); } @@ -93,8 +96,8 @@ public class YamlJsonTranslator { * @param object POJO to be translated */ public void toYaml(Writer target, Object object) { - DumperOptions dumper = new DumperOptions(); - Serializer serializer = new Serializer(new Emitter(target, dumper), new Resolver(), dumper, null); + var dumper = new DumperOptions(); + var serializer = new Serializer(new Emitter(target, dumper), new Resolver(), dumper, null); try { serializer.open(); @@ -135,7 +138,7 @@ public class YamlJsonTranslator { * @return a POJO representing the YAML read from the reader */ public <T> T fromYaml(Reader source, Class<T> clazz) { - Node node = new Yaml().compose(source); + var node = new Yaml().compose(source); return fromJson(makeJson(node), clazz); } @@ -147,7 +150,22 @@ public class YamlJsonTranslator { * @return a POJO representing the original element */ protected <T> T fromJson(JsonElement jel, Class<T> clazz) { - return gson.fromJson(jel, clazz); + return convertFromDouble(clazz, gson.fromJson(jel, clazz)); + } + + /** + * Converts a value from Double to Integer/Long, walking the value's contents if it's + * a List/Map. Only applies if the specified class refers to the Object class. + * Otherwise, it leaves the value unchanged. + * <p/> + * The default method simply returns the original value. + * + * @param clazz class of object to be decoded + * @param value value to be converted + * @return the converted value + */ + protected <T> T convertFromDouble(Class<T> clazz, T value) { + return value; } /** @@ -261,7 +279,7 @@ public class YamlJsonTranslator { protected JsonArray makeJsonArray(SequenceNode node) { List<Node> nodes = node.getValue(); - JsonArray array = new JsonArray(nodes.size()); + var array = new JsonArray(nodes.size()); nodes.forEach(subnode -> array.add(makeJson(subnode))); return array; @@ -274,10 +292,10 @@ public class YamlJsonTranslator { * @return a gson element corresponding to the node */ protected JsonObject makeJsonObject(MappingNode node) { - JsonObject obj = new JsonObject(); + var obj = new JsonObject(); for (NodeTuple tuple : node.getValue()) { - Node key = tuple.getKeyNode(); + var key = tuple.getKeyNode(); String skey = ((ScalarNode) key).getValue(); obj.add(skey, makeJson(tuple.getValueNode())); @@ -294,7 +312,7 @@ public class YamlJsonTranslator { */ protected JsonElement makeJsonPrim(ScalarNode node) { try { - Tag tag = node.getTag(); + var tag = node.getTag(); if (tag == Tag.INT) { return new JsonPrimitive(Long.valueOf(node.getValue())); diff --git a/utils/src/main/java/org/onap/policy/common/utils/jpa/EntityMgrCloser.java b/utils/src/main/java/org/onap/policy/common/utils/jpa/EntityMgrCloser.java index 3532002e..f1798516 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/jpa/EntityMgrCloser.java +++ b/utils/src/main/java/org/onap/policy/common/utils/jpa/EntityMgrCloser.java @@ -2,14 +2,15 @@ * ============LICENSE_START======================================================= * Common Utils * ================================================================================ - * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018, 2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023 Nordix Foundation. * ================================================================================ * 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. @@ -20,40 +21,26 @@ package org.onap.policy.common.utils.jpa; -import javax.persistence.EntityManager; +import jakarta.persistence.EntityManager; +import lombok.AllArgsConstructor; +import lombok.Getter; /** * Wrapper for an <i>EntityManager</i>, providing auto-close functionality. This is useful in * try-with-resources statements. */ +@AllArgsConstructor public class EntityMgrCloser implements AutoCloseable { /** * The wrapped manager. */ - private final EntityManager em; - - /** - * Construct an instance with the EntityManager. - * - * @param em manager to be auto-closed - */ - public EntityMgrCloser(EntityManager em) { - this.em = em; - } - - /** - * Gets the EntityManager wrapped within this object. - * - * @return the associated EntityManager - */ - public EntityManager getManager() { - return em; - } + @Getter + private final EntityManager manager; @Override public void close() { - em.close(); + manager.close(); } } diff --git a/utils/src/main/java/org/onap/policy/common/utils/jpa/EntityMgrFactoryCloser.java b/utils/src/main/java/org/onap/policy/common/utils/jpa/EntityMgrFactoryCloser.java index b046cc55..5f3a6ea8 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/jpa/EntityMgrFactoryCloser.java +++ b/utils/src/main/java/org/onap/policy/common/utils/jpa/EntityMgrFactoryCloser.java @@ -2,14 +2,15 @@ * ============LICENSE_START======================================================= * Common Utils * ================================================================================ - * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018, 2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023 Nordix Foundation. * ================================================================================ * 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. @@ -20,40 +21,26 @@ package org.onap.policy.common.utils.jpa; -import javax.persistence.EntityManagerFactory; +import jakarta.persistence.EntityManagerFactory; +import lombok.AllArgsConstructor; +import lombok.Getter; /** * Wrapper for an <i>EntityManagerFactory</i>, providing auto-close functionality. This is useful in * try-with-resources statements. */ +@AllArgsConstructor public class EntityMgrFactoryCloser implements AutoCloseable { /** * The wrapped factory. */ - private final EntityManagerFactory emf; - - /** - * Construct an instance with the given EntityManagerFactory. - * - * @param emf manager to be auto-closed - */ - public EntityMgrFactoryCloser(EntityManagerFactory emf) { - this.emf = emf; - } - - /** - * Gets the EntityManagerFactory wrapped within this object. - * - * @return the associated EntityManagerFactory - */ - public EntityManagerFactory getFactory() { - return emf; - } + @Getter + private final EntityManagerFactory factory; @Override public void close() { - emf.close(); + factory.close(); } } diff --git a/utils/src/main/java/org/onap/policy/common/utils/jpa/EntityTransCloser.java b/utils/src/main/java/org/onap/policy/common/utils/jpa/EntityTransCloser.java index 3552a6fa..131e87a4 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/jpa/EntityTransCloser.java +++ b/utils/src/main/java/org/onap/policy/common/utils/jpa/EntityTransCloser.java @@ -2,14 +2,15 @@ * ============LICENSE_START======================================================= * Common Utils * ================================================================================ - * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018, 2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023 Nordix Foundation. * ================================================================================ * 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. @@ -20,7 +21,8 @@ package org.onap.policy.common.utils.jpa; -import javax.persistence.EntityTransaction; +import jakarta.persistence.EntityTransaction; +import lombok.Getter; /** * Wrapper for an <i>EntityTransaction</i> that is auto-rolled back when closed. This is useful in @@ -31,46 +33,37 @@ public class EntityTransCloser implements AutoCloseable { /** * Transaction to be rolled back. */ - private final EntityTransaction trans; + @Getter + private final EntityTransaction transaction; /** * Begins a transaction. - * + * * @param et transaction to wrap/begin */ public EntityTransCloser(EntityTransaction et) { - trans = et; - trans.begin(); - } - - /** - * Gets the wrapped transaction. - * - * @return the transaction - */ - public EntityTransaction getTransation() { - return trans; + transaction = et; + transaction.begin(); } /** * Commits the transaction. */ public void commit() { - trans.commit(); + transaction.commit(); } /** * Rolls back the transaction. */ public void rollback() { - trans.rollback(); + transaction.rollback(); } @Override public void close() { - if (trans.isActive()) { - trans.rollback(); + if (transaction.isActive()) { + transaction.rollback(); } } - } diff --git a/utils/src/main/java/org/onap/policy/common/utils/logging/LoggerMarkerFilter.java b/utils/src/main/java/org/onap/policy/common/utils/logging/LoggerMarkerFilter.java new file mode 100644 index 00000000..2c9830dc --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/logging/LoggerMarkerFilter.java @@ -0,0 +1,98 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP POLICY + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. All right reserved. + * Modifications Copyright (C) 2023 Nordix Foundation. + * ================================================================================ + * 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.policy.common.utils.logging; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.filter.AbstractMatcherFilter; +import ch.qos.logback.core.spi.FilterReply; +import org.slf4j.Marker; + +public abstract class LoggerMarkerFilter extends AbstractMatcherFilter<ILoggingEvent> { + + protected final Marker marker; + + protected LoggerMarkerFilter(Marker marker) { + this.marker = marker; + } + + @Override + public FilterReply decide(ILoggingEvent event) { + + if (this.marker == null || !isStarted()) { + return FilterReply.DENY; + } + + if (event == null || event.getMarkerList() == null) { + return FilterReply.DENY; + } + + if (event.getMarkerList().stream().anyMatch(mk -> mk.equals(marker))) { + return FilterReply.ACCEPT; + } else { + return FilterReply.DENY; + } + } + + /** + * Metric Logger Marker Filter. + */ + public static class MetricLoggerMarkerFilter extends LoggerMarkerFilter { + + public MetricLoggerMarkerFilter() { + super(LoggerUtils.METRIC_LOG_MARKER); + } + + } + + /** + * Security Logger Marker Filter. + */ + public static class SecurityLoggerMarkerFilter extends LoggerMarkerFilter { + + public SecurityLoggerMarkerFilter() { + super(LoggerUtils.SECURITY_LOG_MARKER); + } + } + + /** + * Audit Logger Marker Filter. + */ + public static class AuditLoggerMarkerFilter extends LoggerMarkerFilter { + + public AuditLoggerMarkerFilter() { + super(LoggerUtils.AUDIT_LOG_MARKER); + } + } + + /** + * Transaction Logger Marker Filter. + */ + public static class TransactionLoggerMarkerFilter extends LoggerMarkerFilter { + + public TransactionLoggerMarkerFilter() { + super(LoggerUtils.TRANSACTION_LOG_MARKER); + } + } + +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/logging/LoggerUtils.java b/utils/src/main/java/org/onap/policy/common/utils/logging/LoggerUtils.java new file mode 100644 index 00000000..89575eb2 --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/logging/LoggerUtils.java @@ -0,0 +1,105 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP POLICY + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. 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.policy.common.utils.logging; + +import ch.qos.logback.classic.LoggerContext; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class LoggerUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(LoggerUtils.class); + + /** + * ROOT logger. + */ + public static final String ROOT_LOGGER = "ROOT"; + /** + * Metric logger. + */ + public static final String METRIC_LOG_MARKER_NAME = "metric"; + /** + * Audit Log Marker Name. + */ + public static final String AUDIT_LOG_MARKER_NAME = "audit"; + /** + * Security Log Marker Name. + */ + public static final String SECURITY_LOG_MARKER_NAME = "security"; + /** + * Transaction Log Marker Name. + */ + public static final String TRANSACTION_LOG_MARKER_NAME = "transaction"; + /** + * Marks a logging record for metric. + */ + public static final Marker METRIC_LOG_MARKER = MarkerFactory.getMarker(METRIC_LOG_MARKER_NAME); + /** + * Marks a logging record for security. + */ + public static final Marker SECURITY_LOG_MARKER = MarkerFactory.getMarker(SECURITY_LOG_MARKER_NAME); + /** + * Marks a logging record for audit. + */ + public static final Marker AUDIT_LOG_MARKER = MarkerFactory.getMarker(AUDIT_LOG_MARKER_NAME); + /** + * Marks a logging record as an end-to-end transaction. + */ + public static final Marker TRANSACTION_LOG_MARKER = MarkerFactory.getMarker(TRANSACTION_LOG_MARKER_NAME); + + + /** + * Set the log level of a logger. + * + * @param loggerName logger name + * @param loggerLevel logger level + */ + public static String setLevel(String loggerName, String loggerLevel) { + if (!(LoggerFactory.getILoggerFactory() instanceof LoggerContext)) { + throw new IllegalStateException("The SLF4J logger factory is not configured for logback"); + } + + final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + final var logger = context.getLogger(loggerName); + if (logger == null) { + throw new IllegalArgumentException("no logger " + loggerName); + } + + LOGGER.warn("setting {} logger to level {}", loggerName, loggerLevel); + + // use the current log level if the string provided cannot be converted to a valid Level. + + // NOSONAR: this method is currently used by the telemetry api (which should be authenticated). + // It is no more or no less dangerous than an admin changing the logback level on the fly. + // This is a controlled admin function that should not cause any risks when the system + // is configured properly. + logger.setLevel(ch.qos.logback.classic.Level.toLevel(loggerLevel, logger.getLevel())); // NOSONAR + + return logger.getLevel().toString(); + } +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/network/NetworkUtil.java b/utils/src/main/java/org/onap/policy/common/utils/network/NetworkUtil.java index 14362627..6698d7cf 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/network/NetworkUtil.java +++ b/utils/src/main/java/org/onap/policy/common/utils/network/NetworkUtil.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2021 AT&T Intellectual Property. 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. @@ -26,16 +26,19 @@ import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; -import java.security.cert.X509Certificate; +import java.util.UUID; import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.apache.commons.net.util.TrustManagerUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Network Utilities. */ -public class NetworkUtil { +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class NetworkUtil { public static final Logger logger = LoggerFactory.getLogger(NetworkUtil.class.getName()); @@ -48,33 +51,7 @@ public class NetworkUtil { /** * A trust manager that always trusts certificates. */ - // @formatter:off - private static final TrustManager[] ALWAYS_TRUST_MANAGER = new TrustManager[] { - new X509TrustManager() { - - @Override - public X509Certificate[] getAcceptedIssuers() { - return new X509Certificate[0]; - } - - @Override - public void checkClientTrusted(final java.security.cert.X509Certificate[] certs, - final String authType) { - // always trust - } - - @Override - public void checkServerTrusted(final java.security.cert.X509Certificate[] certs, - final String authType) { - // always trust - } - } - }; - // @formatter:on - - private NetworkUtil() { - // Empty constructor - } + private static final TrustManager[] ALWAYS_TRUST_MANAGER = { TrustManagerUtils.getAcceptAllTrustManager() }; /** * Allocates an available port on which a server may listen. @@ -105,7 +82,11 @@ public class NetworkUtil { * @throws IOException if a socket cannot be created */ public static int allocPort(InetSocketAddress hostAddr) throws IOException { - try (ServerSocket socket = new ServerSocket()) { + /* + * The socket is only used to find an unused address for a new server. As a + * result, it poses no security risk, thus the sonar issue can be ignored. + */ + try (ServerSocket socket = new ServerSocket()) { // NOSONAR socket.bind(hostAddr); return socket.getLocalPort(); @@ -132,9 +113,13 @@ public class NetworkUtil { */ public static boolean isTcpPortOpen(String host, int port, int retries, long interval) throws InterruptedException { - int retry = 0; + var retry = 0; while (retry < retries) { - try (Socket s = new Socket(host, port)) { + /* + * As with the server socket, this is only used to see if the port is open, + * thus the sonar issue can be ignored. + */ + try (Socket s = new Socket(host, port)) { // NOSONAR logger.debug("{}:{} connected - retries={} interval={}", host, port, retries, interval); return true; } catch (final IOException e) { @@ -186,4 +171,15 @@ public class NetworkUtil { return "127.0.0.1"; } + + /** + * Generates a globally unique name, typically for use in PDP messages, to uniquely + * identify a PDP (or PAP), regardless on what cluster it resides. + * + * @param prefix text to be prepended to the generated value + * @return a globally unique name + */ + public static String genUniqueName(String prefix) { + return prefix + "-" + UUID.randomUUID(); + } } diff --git a/utils/src/main/java/org/onap/policy/common/utils/properties/BeanConfigurator.java b/utils/src/main/java/org/onap/policy/common/utils/properties/BeanConfigurator.java index 2ef91911..f8c52091 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/properties/BeanConfigurator.java +++ b/utils/src/main/java/org/onap/policy/common/utils/properties/BeanConfigurator.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP - Common Modules * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019, 2021 AT&T Intellectual Property. 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. @@ -20,6 +20,7 @@ package org.onap.policy.common.utils.properties; +import com.google.re2j.Pattern; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -45,6 +46,7 @@ import org.onap.policy.common.utils.properties.exception.PropertyMissingExceptio * <i>accept</i> includes the "empty" option. */ public class BeanConfigurator { + private static final Pattern COMMA_PAT = Pattern.compile(","); /** * The "empty" option that may appear within the {@link Property}'s <i>accept</i> @@ -414,7 +416,7 @@ public class BeanConfigurator { * @return {@code true} if the <i>accept</i> attribute includes "empty" */ protected boolean isEmptyOk(Property prop) { - for (String option : prop.accept().split(",")) { + for (String option : COMMA_PAT.split(prop.accept())) { if (ACCEPT_EMPTY.equals(option)) { return true; } @@ -495,7 +497,7 @@ public class BeanConfigurator { * @throws PropertyAccessException if a "get" method cannot be identified */ private Method getGetter(Field field, Property prop) throws PropertyAccessException { - String capnm = StringUtils.capitalize(field.getName()); + var capnm = StringUtils.capitalize(field.getName()); try { return getGetter(field, "get" + capnm); diff --git a/utils/src/main/java/org/onap/policy/common/utils/properties/PropertyObjectUtils.java b/utils/src/main/java/org/onap/policy/common/utils/properties/PropertyObjectUtils.java new file mode 100644 index 00000000..2b6e514f --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/properties/PropertyObjectUtils.java @@ -0,0 +1,242 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019-2021 AT&T Intellectual Property. 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.policy.common.utils.properties; + +import com.google.re2j.Pattern; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Utilities for generating POJOs from Properties. + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class PropertyObjectUtils { + + public static final Logger logger = LoggerFactory.getLogger(PropertyObjectUtils.class); + private static final Pattern NAME_PAT = Pattern.compile("\\[(\\d{1,3})\\]$"); + private static final Pattern DOT_PAT = Pattern.compile("[.]"); + + /** + * Converts a set of properties to a Map. Supports json-path style property names with + * "." separating components, where components may have an optional subscript. + * + * @param properties properties to be converted + * @param prefix properties whose names begin with this prefix are included. The + * prefix is stripped from the name before adding the value to the map + * @return a hierarchical map representing the properties + */ + public static Map<String, Object> toObject(Properties properties, String prefix) { + String dottedPrefix = prefix + (prefix.isEmpty() || prefix.endsWith(".") ? "" : "."); + int pfxlen = dottedPrefix.length(); + + Map<String, Object> map = new LinkedHashMap<>(); + + for (String name : properties.stringPropertyNames()) { + if (name.startsWith(dottedPrefix)) { + String[] components = DOT_PAT.split(name.substring(pfxlen)); + setProperty(map, components, properties.getProperty(name)); + } + } + + return map; + } + + /** + * Sets a property within a hierarchical map. + * + * @param map map into which the value should be placed + * @param names property name components + * @param value value to be placed into the map + */ + private static void setProperty(Map<String, Object> map, String[] names, String value) { + Map<String, Object> node = map; + + final int lastComp = names.length - 1; + + // process all but the final component + for (var comp = 0; comp < lastComp; ++comp) { + node = getNode(node, names[comp]); + } + + // process the final component + String name = names[lastComp]; + var matcher = NAME_PAT.matcher(name); + + if (!matcher.find()) { + // no subscript + node.put(name, value); + return; + } + + // subscripted + List<Object> array = getArray(node, name.substring(0, matcher.start())); + var index = Integer.parseInt(matcher.group(1)); + expand(array, index); + array.set(index, value); + } + + /** + * Gets a node. + * + * @param map map from which to get the object + * @param name name of the element to get from the map, with an optional subscript + * @return a Map + */ + @SuppressWarnings("unchecked") + private static Map<String, Object> getNode(Map<String, Object> map, String name) { + var matcher = NAME_PAT.matcher(name); + + if (!matcher.find()) { + // no subscript + return getObject(map, name); + } + + // subscripted + List<Object> array = getArray(map, name.substring(0, matcher.start())); + var index = Integer.parseInt(matcher.group(1)); + expand(array, index); + + Object item = array.get(index); + if (item instanceof Map) { + return (Map<String, Object>) item; + + } else { + LinkedHashMap<String, Object> result = new LinkedHashMap<>(); + array.set(index, result); + return result; + } + } + + /** + * Ensures that an array's size is large enough to hold the specified element. + * + * @param array array to be expanded + * @param index index of the desired element + */ + private static void expand(List<Object> array, int index) { + while (array.size() <= index) { + array.add(null); + } + } + + /** + * Gets an object (i.e., Map) from a map. If the particular element is not a Map, then + * it is replaced with an empty Map. + * + * @param map map from which to get the object + * @param name name of the element to get from the map, without any subscript + * @return a Map + */ + private static Map<String, Object> getObject(Map<String, Object> map, String name) { + @SuppressWarnings("unchecked") + Map<String, Object> result = (Map<String, Object>) map.compute(name, (key, value) -> { + if (value instanceof Map) { + return value; + } else { + return new LinkedHashMap<>(); + } + }); + + return result; + } + + /** + * Gets an array from a map. If the particular element is not an array, then it is + * replaced with an empty array. + * + * @param map map from which to get the array + * @param name name of the element to get from the map, without any subscript + * @return an array + */ + private static List<Object> getArray(Map<String, Object> map, String name) { + @SuppressWarnings("unchecked") + List<Object> result = (List<Object>) map.compute(name, (key, value) -> { + if (value instanceof List) { + return value; + } else { + return new ArrayList<>(); + } + }); + + return result; + } + + /** + * Compresses lists contained within a generic object, removing all {@code null} + * items. + * + * @param object object to be compressed + * @return the original object, modified in place + */ + public static Object compressLists(Object object) { + if (object instanceof Map) { + @SuppressWarnings("unchecked") + Map<String, Object> asMap = (Map<String, Object>) object; + compressMapValues(asMap); + + } else if (object instanceof List) { + @SuppressWarnings("unchecked") + List<Object> asList = (List<Object>) object; + compressListItems(asList); + } + + // else: ignore anything else + + return object; + } + + /** + * Walks a hierarchical map and removes {@code null} items found in any Lists. + * + * @param map map whose lists are to be compressed + */ + private static void compressMapValues(Map<String, Object> map) { + for (Object value : map.values()) { + compressLists(value); + } + } + + /** + * Removes {@code null} items from the list. In addition, it walks the items within + * the list, compressing them, as well. + * + * @param list the list to be compressed + */ + private static void compressListItems(List<Object> list) { + Iterator<Object> iter = list.iterator(); + while (iter.hasNext()) { + Object item = iter.next(); + if (item == null) { + // null item - remove it + iter.remove(); + + } else { + compressLists(item); + } + } + } +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/properties/SpecProperties.java b/utils/src/main/java/org/onap/policy/common/utils/properties/SpecProperties.java index ec7157d3..2ea94959 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/properties/SpecProperties.java +++ b/utils/src/main/java/org/onap/policy/common/utils/properties/SpecProperties.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2018, 2020 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018, 2020-2021 AT&T Intellectual Property. 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. @@ -21,10 +21,13 @@ package org.onap.policy.common.utils.properties; import java.util.Properties; +import lombok.AccessLevel; +import lombok.Getter; /** * Properties with an optional specialization (e.g., session name, controller name). */ +@Getter(AccessLevel.PROTECTED) public class SpecProperties extends Properties { private static final long serialVersionUID = 1L; @@ -89,7 +92,7 @@ public class SpecProperties extends Properties { return super.getProperty(key); } - String suffix = key.substring(prefix.length()); + var suffix = key.substring(prefix.length()); String val = super.getProperty(specPrefix + suffix); if (val != null) { @@ -99,14 +102,6 @@ public class SpecProperties extends Properties { return super.getProperty(key); } - protected String getPrefix() { - return prefix; - } - - protected String getSpecPrefix() { - return specPrefix; - } - @Override public final synchronized int hashCode() { throw new UnsupportedOperationException("SpecProperties cannot be hashed"); diff --git a/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyException.java b/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyException.java index 44edd428..3c03f38d 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyException.java +++ b/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyException.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP Policy Engine - Common Modules * ================================================================================ - * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018, 2021 AT&T Intellectual Property. 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. @@ -20,9 +20,12 @@ package org.onap.policy.common.utils.properties.exception; +import lombok.Getter; + /** * Exception associated with a Property. */ +@Getter public class PropertyException extends Exception { private static final long serialVersionUID = 1L; @@ -38,7 +41,7 @@ public class PropertyException extends Exception { /** * Constructor. - * + * * @param propName name of the property causing the exception, or {@code null} * @param fieldName name of the field causing the exception, or {@code null} */ @@ -51,7 +54,7 @@ public class PropertyException extends Exception { /** * Constructor. - * + * * @param propnm name of the property causing the exception, or {@code null} * @param fieldName name of the field causing the exception, or {@code null} * @param message error message @@ -65,7 +68,7 @@ public class PropertyException extends Exception { /** * Constructor. - * + * * @param propnm name of the property causing the exception, or {@code null} * @param fieldName name of the field causing the exception, or {@code null} * @param cause cause of the exception @@ -79,7 +82,7 @@ public class PropertyException extends Exception { /** * Constructor. - * + * * @param propnm name of the property causing the exception, or {@code null} * @param fieldName name of the field causing the exception, or {@code null} * @param message error message @@ -93,28 +96,8 @@ public class PropertyException extends Exception { } /** - * Get the property name. - * - * @return name of the property for which the exception was thrown, or {@code null} if - * no name was provided - */ - public String getPropertyName() { - return propertyName; - } - - /** - * Get the field name. - * - * @return name of the field for which the exception was thrown, or {@code null} if no - * field was provided - */ - public String getFieldName() { - return fieldName; - } - - /** * Make the message. - * + * * @param propnm name of the property causing the exception, or {@code null} * @param fieldName name of the field causing the exception, or {@code null} * @param message error message, never {@code null} @@ -126,13 +109,13 @@ public class PropertyException extends Exception { /** * Make the message. - * + * * @param propnm name of the property causing the exception, or {@code null} * @param fieldName name of the field causing the exception, or {@code null} * @return an error message composed of the two items */ private static String makeMessage(String propnm, String fieldName) { - StringBuilder bldr = new StringBuilder(50); + var bldr = new StringBuilder(50); if (propnm == null) { bldr.append("property exception"); diff --git a/utils/src/main/java/org/onap/policy/common/utils/resources/DirectoryUtils.java b/utils/src/main/java/org/onap/policy/common/utils/resources/DirectoryUtils.java new file mode 100644 index 00000000..35a13138 --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/resources/DirectoryUtils.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. 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.policy.common.utils.resources; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Utilities for manipulating directories. + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class DirectoryUtils { + private static final Logger logger = LoggerFactory.getLogger(DirectoryUtils.class); + + /** + * Creates a directory file, only accessible by the owner. + * + * @param prefix file name prefix + * @return a new, temporary directory + * @throws IOException if an error occurs + */ + public static Path createTempDirectory(String prefix) throws IOException { + /* + * Disabling sonar, as the code below sets the permissions, just as sonar + * suggests it be fixed. + */ + var path = Files.createTempDirectory(prefix); // NOSONAR + logger.info("created temporary directory, {}", path); + + var file = path.toFile(); + + TextFileUtils.setDefaultPermissions(file); + + // ensure nothing has been written to it yet + FileUtils.cleanDirectory(file); + + return path; + } +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/resources/MessageConstants.java b/utils/src/main/java/org/onap/policy/common/utils/resources/MessageConstants.java new file mode 100644 index 00000000..ef46fdf5 --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/resources/MessageConstants.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Bell Canada. All rights reserved. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.resources; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +/** + * Common messages to be used by all components. + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class MessageConstants { + + public static final String POLICY_API = "policy-api"; + public static final String POLICY_PAP = "policy-pap"; + public static final String POLICY_APEX_PDP = "policy-apex-pdp"; + public static final String POLICY_DROOLS_PDP = "policy-drools-pdp"; + public static final String POLICY_XACML_PDP = "policy-xacml-pdp"; + public static final String POLICY_DISTRIBUTION = "policy-distribution"; + public static final String POLICY_CLAMP = "policy-clamp"; + + public static final String START_SUCCESS_MSG = "Started %s service successfully."; + public static final String START_FAILURE_MSG = "Start of %s service failed."; +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/resources/PrometheusUtils.java b/utils/src/main/java/org/onap/policy/common/utils/resources/PrometheusUtils.java new file mode 100644 index 00000000..bac65d4e --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/resources/PrometheusUtils.java @@ -0,0 +1,107 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2022 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2022 Bell Canada. 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.policy.common.utils.resources; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * Prometheus constants and utilities. + */ + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class PrometheusUtils { + + /** + * Policy Deployments Metric Name. + */ + public static final String POLICY_DEPLOYMENTS_METRIC = "policy_deployments"; + + /** + * Policy Deployments Metric Help Message. + */ + public static final String POLICY_DEPLOYMENT_HELP = "The total number of policy deployments."; + + /** + * Policy Execution Metric Name. + */ + public static final String POLICY_EXECUTION_METRIC = "policy_executions"; + + /** + * Policy Execution Metric Help Message. + */ + public static final String POLICY_EXECUTION_HELP = "The total number of TOSCA policy executions."; + + /** + * Policy Execution Latency in Seconds Metric Name. + * This metric name is not to be used as a counter. + */ + public static final String POLICY_EXECUTIONS_LATENCY_SECONDS_METRIC = "policy_executions_latency_seconds"; + + /** + * Policy Execution Latency in Seconds Metric Help message. + */ + public static final String POLICY_EXECUTIONS_LATENCY_SECONDS_HELP = + "The latency in seconds of TOSCA policy executions."; + + /** + * Metric label for arbitrary operations (eg. deploy, undeploy, execute). + */ + public static final String OPERATION_METRIC_LABEL = "operation"; + + /** + * Deploy operation value. + */ + public static final String DEPLOY_OPERATION = "deploy"; + + /** + * Undeploy operation value. + */ + public static final String UNDEPLOY_OPERATION = "undeploy"; + + /** + * Metric label for states (ie. PASSIVE, ACTIVE). + */ + public static final String STATE_METRIC_LABEL = "state"; + + /** + * Metric label for status of an operation (ie. SUCCESS or FAILURE). + */ + public static final String STATUS_METRIC_LABEL = "status"; + + /** + * Prometheus namespace values mapping to the supported PDP types. + */ + public enum PdpType { + PDPD("pdpd"), + PDPA("pdpa"), + PDPX("pdpx"); + + @Getter + private final String namespace; + + PdpType(String namespace) { + this.namespace = namespace; + } + } +}
\ No newline at end of file diff --git a/utils/src/main/java/org/onap/policy/common/utils/resources/ResourceUtils.java b/utils/src/main/java/org/onap/policy/common/utils/resources/ResourceUtils.java index 365efabe..3ee062f1 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/resources/ResourceUtils.java +++ b/utils/src/main/java/org/onap/policy/common/utils/resources/ResourceUtils.java @@ -1,7 +1,8 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2018 Ericsson. All rights reserved. - * Modifications Copyright (C) 2020 Nordix Foundation. + * Modifications Copyright (C) 2020, 2023 Nordix Foundation. + * Modifications Copyright (C) 2020-2021 AT&T Intellectual Property. 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. @@ -21,18 +22,22 @@ package org.onap.policy.common.utils.resources; -import java.io.ByteArrayOutputStream; +import com.google.re2j.Pattern; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.Enumeration; +import java.util.Objects; import java.util.Set; import java.util.TreeSet; import java.util.jar.JarEntry; import java.util.jar.JarFile; - +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,25 +45,18 @@ import org.slf4j.LoggerFactory; * This is common utility class with static methods for handling Java resources on the class path. It is an abstract * class to prevent any direct instantiation and private constructor to prevent extending this class. */ -public abstract class ResourceUtils { +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class ResourceUtils { // Get a reference to the logger private static final Logger LOGGER = LoggerFactory.getLogger(ResourceUtils.class); - // The length of byte buffers used to read resources into strings - private static final int BYTE_BUFFER_LENGH = 1024; + private static final Pattern SLASH_PAT = Pattern.compile("/"); // Resource types private static final String FILE_PROTOCOL = "file"; private static final String JAR_PROTOCOL = "jar"; /** - * Private constructor used to prevent sub class instantiation. - */ - private ResourceUtils() { - // Prevent construction of this class - } - - /** * Method to resolve a resource; the local file system is checked first and then the class path is checked. * * @param resourceName The resource name @@ -66,7 +64,7 @@ public abstract class ResourceUtils { */ public static URL getUrl4Resource(final String resourceName) { // Check the local fine system first - final URL urlToResource = getLocalFile(resourceName); + final var urlToResource = getLocalFile(resourceName); // Check if this is a local file if (urlToResource != null) { @@ -86,25 +84,16 @@ public abstract class ResourceUtils { */ public static String getResourceAsString(final String resourceName) { // Get the resource as a stream, we'll convert it to a string then - final InputStream resourceStream = getResourceAsStream(resourceName); - if (resourceStream == null) { - return null; - } - - // Read the stream contents in to an output stream - final ByteArrayOutputStream resourceOutputStreamBuffer = new ByteArrayOutputStream(); - final byte[] resourceBuffer = new byte[BYTE_BUFFER_LENGH]; - int length; - try { - while ((length = resourceStream.read(resourceBuffer)) != -1) { - resourceOutputStreamBuffer.write(resourceBuffer, 0, length); + // Read the stream contents, closing when done + try (var resourceStream = getResourceAsStream(resourceName)) { + if (resourceStream == null) { + return null; } + return IOUtils.toString(resourceStream, StandardCharsets.UTF_8); } catch (final IOException e) { - LOGGER.debug("error reading resource stream \"{}\" : " + e.getMessage(), resourceName, e); + LOGGER.debug("error reading resource stream {}", resourceName, e); return null; } - - return resourceOutputStreamBuffer.toString(); } /** @@ -116,12 +105,12 @@ public abstract class ResourceUtils { */ public static InputStream getResourceAsStream(final String resourceName) { // Find a URL to the resource first - final URL urlToResource = getUrl4Resource(resourceName); + final var urlToResource = getUrl4Resource(resourceName); // Check if the resource exists if (urlToResource == null) { // No resource found - LOGGER.debug("cound not find resource \"{}\" : ", resourceName); + LOGGER.debug("could not find resource \"{}\" : ", resourceName); return null; } @@ -130,7 +119,7 @@ public abstract class ResourceUtils { return urlToResource.openStream(); } catch (final IOException e) { // Any of many IO exceptions such as the resource is a directory - LOGGER.debug("error attaching resource \"{}\" to stream : " + e.getMessage(), resourceName, e); + LOGGER.debug("error attaching resource {}", resourceName, e); return null; } } @@ -143,11 +132,11 @@ public abstract class ResourceUtils { */ public static URL getUrlResource(final String resourceName) { try { - final ClassLoader classLoader = ResourceUtils.class.getClassLoader(); + final var classLoader = ResourceUtils.class.getClassLoader(); - final String[] fileParts = resourceName.split("/"); + final String[] fileParts = SLASH_PAT.split(resourceName); // Read the resource - URL url = classLoader.getResource(resourceName); + var url = classLoader.getResource(resourceName); // Check if the resource is defined if (url != null) { @@ -164,7 +153,7 @@ public abstract class ResourceUtils { return url; } } catch (final Exception e) { - LOGGER.debug("error getting URL resource \"{}\" : " + e.getMessage(), e); + LOGGER.debug("error getting URL resource {}", resourceName, e); return null; } } @@ -178,8 +167,8 @@ public abstract class ResourceUtils { public static URL getLocalFile(final String resourceName) { try { // Input might already be in URL format - final URL ret = new URL(resourceName); - final File f = new File(ret.toURI()); + final var ret = new URL(resourceName); + final var f = new File(ret.toURI()); if (f.exists()) { return ret; } @@ -188,10 +177,10 @@ public abstract class ResourceUtils { } try { - final File f = new File(resourceName); + final var f = new File(resourceName); // Check if the file exists if (f.exists()) { - final URL urlret = f.toURI().toURL(); + final var urlret = f.toURI().toURL(); LOGGER.debug("resource \"{}\" was found on the local file system", f.toURI().toURL()); return urlret; } else { @@ -199,7 +188,7 @@ public abstract class ResourceUtils { return null; } } catch (final Exception e) { - LOGGER.debug("error finding resource \"{}\" : " + e.getMessage(), e); + LOGGER.debug("error finding resource {}", resourceName, e); return null; } } @@ -215,7 +204,7 @@ public abstract class ResourceUtils { return null; } - URL modelFileUrl = getUrl4Resource(resource); + var modelFileUrl = getUrl4Resource(resource); if (modelFileUrl != null) { return modelFileUrl.getPath(); } else { @@ -227,11 +216,11 @@ public abstract class ResourceUtils { * Read the list of entries in a resource directory. * * @param resourceDirectoryName the name of the resource directory - * @return the list of entries + * @return a set of entries */ public static Set<String> getDirectoryContents(final String resourceDirectoryName) { // Find the location of the resource, is it in a Jar or on the local file system? - URL directoryUrl = ResourceUtils.getUrl4Resource(resourceDirectoryName); + var directoryUrl = ResourceUtils.getUrl4Resource(resourceDirectoryName); if (directoryUrl == null) { LOGGER.debug("resource \"{}\" was not found", resourceDirectoryName); @@ -255,11 +244,11 @@ public abstract class ResourceUtils { * * @param localResourceDirectoryUrl the local resource file URL * @param resourceDirectoryName the name of the resource directory - * @return a list of the directory contents + * @return a set of the directory contents */ public static Set<String> getDirectoryContentsLocal(final URL localResourceDirectoryUrl, final String resourceDirectoryName) { - File localDirectory = new File(localResourceDirectoryUrl.getFile()); + var localDirectory = new File(localResourceDirectoryUrl.getFile()); if (!localDirectory.isDirectory()) { LOGGER.debug("resource \"{}\" is not a directory", resourceDirectoryName); @@ -267,7 +256,7 @@ public abstract class ResourceUtils { } Set<String> localDirectorySet = new TreeSet<>(); - for (File localDirectoryEntry : localDirectory.listFiles()) { + for (File localDirectoryEntry : Objects.requireNonNull(localDirectory.listFiles())) { if (localDirectoryEntry.isDirectory()) { localDirectorySet .add(resourceDirectoryName + File.separator + localDirectoryEntry.getName() + File.separator); @@ -284,23 +273,29 @@ public abstract class ResourceUtils { * * @param jarResourceDirectoryUrl the name of the resource directory in the jar * @param resourceDirectoryName the name of the resource directory - * @return a list of the directory contents + * @return a set of the directory contents */ public static Set<String> getDirectoryContentsJar(final URL jarResourceDirectoryUrl, final String resourceDirectoryName) { - File jarResourceDirectory = new File(jarResourceDirectoryUrl.getPath()); + String dirNameWithSlash = resourceDirectoryName + "/"; + int minLength = dirNameWithSlash.length() + 1; + var jarResourceDirectory = new File(jarResourceDirectoryUrl.getPath()); String jarFileName = jarResourceDirectory.getParent().replaceFirst("^file:", "").replaceFirst("!.*$", ""); Set<String> localDirectorySet = new TreeSet<>(); - try (JarFile jarFile = new JarFile(jarFileName)) { - Enumeration<JarEntry> entries = jarFile.entries(); + try (var jarFile = new JarFile(jarFileName)) { + Enumeration<JarEntry> entries = jarFile.entries(); // NOSONAR while (entries.hasMoreElements()) { - JarEntry je = entries.nextElement(); - - if (je.getName().matches("^" + resourceDirectoryName + "\\/.+")) { - localDirectorySet.add(je.getName()); + /* + * Ignore sonar issue, as the entries are not being expanded here. + */ + JarEntry je = entries.nextElement(); // NOSONAR + String jeName = je.getName(); + + if (jeName.length() >= minLength && jeName.startsWith(dirNameWithSlash)) { + localDirectorySet.add(jeName); } } } catch (IOException ioe) { diff --git a/utils/src/main/java/org/onap/policy/common/utils/resources/TextFileUtils.java b/utils/src/main/java/org/onap/policy/common/utils/resources/TextFileUtils.java index 01af7fd8..7701eae9 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/resources/TextFileUtils.java +++ b/utils/src/main/java/org/onap/policy/common/utils/resources/TextFileUtils.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2019 Nordix Foundation. + * Modifications Copyright (C) 2020-2021 AT&T Intellectual Property. 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. @@ -25,7 +26,13 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The Class TextFileUtils is class that provides useful functions for handling text files. Functions to read and write @@ -33,13 +40,9 @@ import java.nio.file.Files; * * @author Liam Fallon (liam.fallon@est.tech) */ -public abstract class TextFileUtils { - private static final String UTF_8 = "UTF-8"; - private static final int READER_CHAR_BUFFER_SIZE_4096 = 4096; - - private TextFileUtils() { - // This class cannot be initialized - } +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class TextFileUtils { + private static final Logger logger = LoggerFactory.getLogger(TextFileUtils.class); /** * Method to return the contents of a text file as a string. @@ -49,8 +52,8 @@ public abstract class TextFileUtils { * @throws IOException on errors reading text from the file */ public static String getTextFileAsString(final String textFilePath) throws IOException { - final File textFile = new File(textFilePath); - return new String(Files.readAllBytes(textFile.toPath()), UTF_8); + final var textFile = new File(textFilePath); + return Files.readString(textFile.toPath()); } /** @@ -61,7 +64,7 @@ public abstract class TextFileUtils { * @throws IOException on errors reading text from the file */ public static void putStringAsTextFile(final String outString, final String textFilePath) throws IOException { - final File textFile = new File(textFilePath); + final var textFile = new File(textFilePath); if (!textFile.getParentFile().exists()) { textFile.getParentFile().mkdirs(); } @@ -77,7 +80,7 @@ public abstract class TextFileUtils { * @throws IOException on errors reading text from the file */ public static void putStringAsFile(final String outString, final File textFile) throws IOException { - Files.write(textFile.toPath(), outString.getBytes(UTF_8)); + Files.writeString(textFile.toPath(), outString); } /** @@ -88,7 +91,7 @@ public abstract class TextFileUtils { * @throws IOException on errors reading text from the file */ public static String getStreamAsString(final InputStream textStream) throws IOException { - return getReaderAsString(new InputStreamReader(textStream, UTF_8)); + return getReaderAsString(new InputStreamReader(textStream, StandardCharsets.UTF_8)); } /** @@ -99,16 +102,37 @@ public abstract class TextFileUtils { * @throws IOException on errors reading text from the file */ public static String getReaderAsString(final Reader textReader) throws IOException { - final StringBuilder builder = new StringBuilder(); - int charsRead = -1; - final char[] chars = new char[READER_CHAR_BUFFER_SIZE_4096]; - do { - charsRead = textReader.read(chars); - if (charsRead > 0) { - builder.append(chars, 0, charsRead); - } + return IOUtils.toString(textReader); + } + + /** + * Creates a temporary file, only accessible by the owner. + * + * @param prefix file name prefix + * @param suffix file name suffix + * @return a new, temporary file + * @throws IOException if an error occurs + */ + public static File createTempFile(String prefix, String suffix) throws IOException { + /* + * Disabling sonar, because setDefaultPermissions() will set the permissions of + * the file. + */ + var file = File.createTempFile(prefix, suffix); // NOSONAR + + setDefaultPermissions(file); + + return file; + } + + /** + * Sets permissions on a file or directory so that only the owner can access it. + * + * @param file file or directory on which permissions are to be set + */ + public static void setDefaultPermissions(File file) { + if (!file.setReadable(true, true) || !file.setWritable(true, true) || !file.setExecutable(true, true)) { + logger.warn("cannot set permissions for {}", file); } - while (charsRead > 0); - return builder.toString(); } } diff --git a/utils/src/main/java/org/onap/policy/common/utils/security/CryptoUtils.java b/utils/src/main/java/org/onap/policy/common/utils/security/CryptoUtils.java index 416c73a6..a974f1e5 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/security/CryptoUtils.java +++ b/utils/src/main/java/org/onap/policy/common/utils/security/CryptoUtils.java @@ -2,7 +2,8 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,12 +21,12 @@ package org.onap.policy.common.utils.security; +import jakarta.xml.bind.DatatypeConverter; import java.nio.charset.StandardCharsets; import java.util.Random; import javax.crypto.Cipher; -import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.SecretKeySpec; -import javax.xml.bind.DatatypeConverter; import org.apache.commons.lang3.ArrayUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,7 +45,9 @@ public class CryptoUtils implements CryptoCoder { /** * Detailed definition of encryption algorithm. */ - private static final String ALGORITHM_DETAILS = ALGORITHM + "/CBC/PKCS5PADDING"; + private static final String ALGORITHM_DETAILS = ALGORITHM + "/GCM/NoPadding"; + + private static final int TAG_SIZE_IN_BITS = 128; private static final int IV_BLOCK_SIZE_IN_BITS = 128; @@ -62,14 +65,14 @@ public class CryptoUtils implements CryptoCoder { /** * Used to generate a random "iv". Strong randomness is not needed, as this is only - * used as a "salt". + * used as a "salt". (Thus sonar is disabled.) */ - private static final Random RANDOM = new Random(); + private static final Random RANDOM = new Random(); // NOSONAR /** * CryptoUtils - encryption tool constructor. * @param secretKeySpec - * AES supports 128, 192 or 256-bit long key size, it can be plain text or generated with key generator + * AES supports 128, 192 or 256-bit long key size, it can be plain text or generated with key generator */ public CryptoUtils(SecretKeySpec secretKeySpec) { this.secretKeySpec = secretKeySpec; @@ -87,7 +90,7 @@ public class CryptoUtils implements CryptoCoder { * <p>Final result is to put in properties file is: IV + Outcome of openssl command * * @param value - * The plain text string + * The plain text string * @return The encrypted String */ @Override @@ -98,13 +101,13 @@ public class CryptoUtils implements CryptoCoder { /** * Encrypt a value based on the Policy Encryption Key. * @param value - * The plain text string + * The plain text string * @param secretKey - * The secret key + * The secret key * @return The encrypted String */ public static String encrypt(String value, String secretKey) { - SecretKeySpec keySpec = readSecretKeySpec(secretKey); + var keySpec = readSecretKeySpec(secretKey); return encryptValue(value, keySpec); } @@ -117,10 +120,10 @@ public class CryptoUtils implements CryptoCoder { return value; } try { - Cipher cipher = Cipher.getInstance(ALGORITHM_DETAILS); - byte[] iv = new byte[IV_BLOCK_SIZE_IN_BYTES]; + var cipher = Cipher.getInstance(ALGORITHM_DETAILS); + var iv = new byte[IV_BLOCK_SIZE_IN_BYTES]; RANDOM.nextBytes(iv); - IvParameterSpec ivspec = new IvParameterSpec(iv); + var ivspec = new GCMParameterSpec(TAG_SIZE_IN_BITS, iv); cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivspec); return "enc:" + DatatypeConverter.printBase64Binary( @@ -137,7 +140,7 @@ public class CryptoUtils implements CryptoCoder { * -K PrivateHexKey -iv 16BytesIVFromEncryptedString * * @param value - * The encrypted string that must be decrypted using the Policy Encryption Key + * The encrypted string that must be decrypted using the Policy Encryption Key * @return The String decrypted if string begin with 'enc:' */ @Override @@ -149,13 +152,13 @@ public class CryptoUtils implements CryptoCoder { * Decrypt a value based on the Policy Encryption Key if string begin with 'enc:'. * * @param value - * The encrypted string that must be decrypted using the Policy Encryption Key + * The encrypted string that must be decrypted using the Policy Encryption Key * @param secretKey - * The secret key + * The secret key * @return The String decrypted if string begin with 'enc:' */ public static String decrypt(String value, String secretKey) { - SecretKeySpec keySpec = readSecretKeySpec(secretKey); + var keySpec = readSecretKeySpec(secretKey); if (keySpec != null) { return decryptValue(value, keySpec); } else { @@ -171,11 +174,11 @@ public class CryptoUtils implements CryptoCoder { throw new IllegalArgumentException("Invalid size on input value"); } try { - String pureValue = value.substring(4); + var pureValue = value.substring(4); byte[] encryptedValue = DatatypeConverter.parseBase64Binary(pureValue); - Cipher cipher = Cipher.getInstance(ALGORITHM_DETAILS); - IvParameterSpec ivspec = new IvParameterSpec( + var cipher = Cipher.getInstance(ALGORITHM_DETAILS); + var ivspec = new GCMParameterSpec(TAG_SIZE_IN_BITS, ArrayUtils.subarray(encryptedValue, 0, IV_BLOCK_SIZE_IN_BYTES)); byte[] realData = ArrayUtils.subarray(encryptedValue, IV_BLOCK_SIZE_IN_BYTES, encryptedValue.length); @@ -225,10 +228,10 @@ public class CryptoUtils implements CryptoCoder { * Check if string is encrypted by verify if string prefix with 'enc:'. * * @param value - * The encrypted string or plain text value + * The encrypted string or plain text value * @return boolean value indicate if string prefix with enc: or not */ - public static Boolean isEncrypted(String value) { + public static boolean isEncrypted(String value) { return (value != null && value.startsWith("enc:")); } diff --git a/utils/src/main/java/org/onap/policy/common/utils/services/FeatureApiUtils.java b/utils/src/main/java/org/onap/policy/common/utils/services/FeatureApiUtils.java index e88361ea..042ee937 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/services/FeatureApiUtils.java +++ b/utils/src/main/java/org/onap/policy/common/utils/services/FeatureApiUtils.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019, 2021 AT&T Intellectual Property. 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. @@ -23,15 +23,14 @@ package org.onap.policy.common.utils.services; import java.util.List; import java.util.function.BiConsumer; import java.util.function.Predicate; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; /** * Utilities for use with "feature APIs". */ -public class FeatureApiUtils { - - private FeatureApiUtils() { - // do nothing - } +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class FeatureApiUtils { /** * Applies a function on each feature provider, stopping as soon as one returns true. @@ -44,7 +43,7 @@ public class FeatureApiUtils { * otherwise */ public static <T> boolean apply(List<T> providers, Predicate<T> predicate, - BiConsumer<T,Exception> handleEx) { + BiConsumer<T, Exception> handleEx) { for (T feature : providers) { try { diff --git a/utils/src/main/java/org/onap/policy/common/utils/services/OrderedServiceImpl.java b/utils/src/main/java/org/onap/policy/common/utils/services/OrderedServiceImpl.java index bbd30220..998d6742 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/services/OrderedServiceImpl.java +++ b/utils/src/main/java/org/onap/policy/common/utils/services/OrderedServiceImpl.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * utils * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 AT&T Intellectual Property. 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. @@ -24,18 +24,18 @@ import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.ServiceLoader; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This class is a template for building a sorted list of service instances, - * which are discovered and created using 'ServiceLoader'. + * which are discovered and created using 'ServiceLoader'. */ public class OrderedServiceImpl<T extends OrderedService> { // logger - private static Logger logger = LoggerFactory.getLogger(OrderedServiceImpl.class); + private static Logger logger = LoggerFactory.getLogger(OrderedServiceImpl.class); // sorted list of instances implementing the service private List<T> implementers = null; @@ -44,8 +44,7 @@ public class OrderedServiceImpl<T extends OrderedService> { private ServiceLoader<T> serviceLoader = null; // use this to ensure that we only use one unique instance of each class - @SuppressWarnings("rawtypes") - private static HashMap<Class,OrderedService> classToSingleton = new HashMap<>(); + private static Map<Class<?>, OrderedService> classToSingleton = new HashMap<>(); /** * Constructor - create the 'ServiceLoader' instance. @@ -60,7 +59,7 @@ public class OrderedServiceImpl<T extends OrderedService> { /** * Get List of implementers. - * + * * @return the sorted list of services implementing interface 'T' discovered * by 'ServiceLoader'. */ @@ -87,7 +86,7 @@ public class OrderedServiceImpl<T extends OrderedService> { // build a list of all of the current implementors List<T> tmp = new LinkedList<>(); for (T service : serviceLoader) { - tmp.add((T)getSingleton(service)); + tmp.add((T) getSingleton(service)); } // Sort the list according to sequence number, and then alphabetically diff --git a/utils/src/main/java/org/onap/policy/common/utils/services/Registry.java b/utils/src/main/java/org/onap/policy/common/utils/services/Registry.java index c3eabe8e..8765ba8b 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/services/Registry.java +++ b/utils/src/main/java/org/onap/policy/common/utils/services/Registry.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019, 2021 AT&T Intellectual Property. 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. @@ -22,6 +22,8 @@ package org.onap.policy.common.utils.services; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,6 +31,7 @@ import org.slf4j.LoggerFactory; * This is a simple object registry, similar in spirit to JNDI, but suitable for use in a * stand-alone JVM. */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) public class Registry { private static final Logger logger = LoggerFactory.getLogger(Registry.class); @@ -40,13 +43,6 @@ public class Registry { private Map<String, Object> name2object = new ConcurrentHashMap<>(); /** - * Constructs the object. - */ - private Registry() { - super(); - } - - /** * Registers an object. * * @param name name by which the object is known diff --git a/utils/src/main/java/org/onap/policy/common/utils/services/ServiceManager.java b/utils/src/main/java/org/onap/policy/common/utils/services/ServiceManager.java index 5c8c01df..08994912 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/services/ServiceManager.java +++ b/utils/src/main/java/org/onap/policy/common/utils/services/ServiceManager.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP PAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2021 AT&T Intellectual Property. 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. @@ -23,6 +23,9 @@ package org.onap.policy.common.utils.services; import java.util.Deque; import java.util.Iterator; import java.util.LinkedList; +import java.util.concurrent.atomic.AtomicBoolean; +import lombok.AllArgsConstructor; +import lombok.Getter; import org.onap.policy.common.capabilities.Startable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,6 +40,7 @@ public class ServiceManager implements Startable { /** * Manager name. */ + @Getter private final String name; /** @@ -47,7 +51,7 @@ public class ServiceManager implements Startable { /** * {@code True} if the services are currently running, {@code false} otherwise. */ - private boolean running; + private final AtomicBoolean running = new AtomicBoolean(false); /** * Constructs the object, with a default name. @@ -58,16 +62,13 @@ public class ServiceManager implements Startable { /** * Constructs the object. + * * @param name the manager's name, used for logging purposes */ public ServiceManager(String name) { this.name = name; } - public String getName() { - return name; - } - /** * Adds a pair of service actions to the manager. * @@ -77,7 +78,7 @@ public class ServiceManager implements Startable { * @return this manager */ public synchronized ServiceManager addAction(String stepName, RunnableWithEx starter, RunnableWithEx stopper) { - if (running) { + if (isAlive()) { throw new IllegalStateException(name + " is already running; cannot add " + stepName); } @@ -94,7 +95,7 @@ public class ServiceManager implements Startable { * @return this manager */ public synchronized ServiceManager addService(String stepName, Startable service) { - if (running) { + if (isAlive()) { throw new IllegalStateException(name + " is already running; cannot add " + stepName); } @@ -103,13 +104,13 @@ public class ServiceManager implements Startable { } @Override - public synchronized boolean isAlive() { - return running; + public boolean isAlive() { + return running.get(); } @Override public synchronized boolean start() { - if (running) { + if (isAlive()) { throw new IllegalStateException(name + " is already running"); } @@ -134,7 +135,7 @@ public class ServiceManager implements Startable { if (ex == null) { logger.info("{} started", name); - running = true; + running.set(true); return true; } @@ -151,11 +152,11 @@ public class ServiceManager implements Startable { @Override public synchronized boolean stop() { - if (!running) { + if (!isAlive()) { throw new IllegalStateException(name + " is not running"); } - running = false; + running.set(false); rewind(items); return true; @@ -203,20 +204,20 @@ public class ServiceManager implements Startable { /** * Service information. */ + @AllArgsConstructor private static class Service { private String stepName; private RunnableWithEx starter; private RunnableWithEx stopper; - - public Service(String stepName, RunnableWithEx starter, RunnableWithEx stopper) { - this.stepName = stepName; - this.starter = starter; - this.stopper = stopper; - } } + /* + * Cannot use a plain Runnable, because it can't throw exceptions. Could use a + * Callable, instead, but then all the lambda expressions become rather messy, thus + * we'll stick with RunnableWithEx, and just disable the sonar warning. + */ @FunctionalInterface public static interface RunnableWithEx { - void run() throws Exception; + void run() throws Exception; // NOSONAR } } diff --git a/utils/src/main/java/org/onap/policy/common/utils/time/CurrentTime.java b/utils/src/main/java/org/onap/policy/common/utils/time/CurrentTime.java index 857b69b6..95f4d69a 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/time/CurrentTime.java +++ b/utils/src/main/java/org/onap/policy/common/utils/time/CurrentTime.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * Common Utils * ================================================================================ - * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018, 2021 AT&T Intellectual Property. 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. @@ -21,24 +21,18 @@ package org.onap.policy.common.utils.time; import java.util.Date; +import lombok.NoArgsConstructor; /** * Methods to access the current time. Classes can use objects of this type to get current * time information, while allowing the objects to be overridden by junit tests. */ +@NoArgsConstructor public class CurrentTime { /** - * Constructor. - * - */ - public CurrentTime() { - super(); - } - - /** * Get the millisecond time. - * + * * @return the current time, in milliseconds */ public long getMillis() { @@ -47,7 +41,7 @@ public class CurrentTime { /** * Get the current date. - * + * * @return the current Date */ public Date getDate() { @@ -56,7 +50,7 @@ public class CurrentTime { /** * Sleeps for a period of time. - * + * * @param sleepMs amount of time to sleep, in milliseconds * @throws InterruptedException can be interrupted */ diff --git a/utils/src/main/java/org/onap/policy/common/utils/validation/Assertions.java b/utils/src/main/java/org/onap/policy/common/utils/validation/Assertions.java index 047989e7..8e474204 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/validation/Assertions.java +++ b/utils/src/main/java/org/onap/policy/common/utils/validation/Assertions.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. - * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019, 2021 AT&T Intellectual Property. 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. @@ -22,6 +22,8 @@ package org.onap.policy.common.utils.validation; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,17 +31,12 @@ import org.slf4j.LoggerFactory; * The Class Assertions is a static class that is used as a shorthand for assertions in the source code. * It throws runtime exceptions on assertion fails. */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class Assertions { // Logger for this class private static final Logger LOGGER = LoggerFactory.getLogger(Assertions.class); /** - * Private constructor used to prevent sub class instantiation. - */ - private Assertions() { - } - - /** * Gets the validation message for a string parameter. * * @param parameterName the string parameter name diff --git a/utils/src/main/java/org/onap/policy/common/utils/validation/ParameterValidationUtils.java b/utils/src/main/java/org/onap/policy/common/utils/validation/ParameterValidationUtils.java index f15d936b..0723242d 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/validation/ParameterValidationUtils.java +++ b/utils/src/main/java/org/onap/policy/common/utils/validation/ParameterValidationUtils.java @@ -1,7 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2018 Ericsson. All rights reserved. - * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019, 2021 AT&T Intellectual Property. 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. @@ -21,17 +21,17 @@ package org.onap.policy.common.utils.validation; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + /** * Class to provide utility methods for common parameter validations. * * @author Ram Krishna Verma (ram.krishna.verma@ericsson.com) */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) public class ParameterValidationUtils { - private ParameterValidationUtils() { - - } - /** * Validates the given string input. * diff --git a/utils/src/main/java/org/onap/policy/common/utils/validation/Version.java b/utils/src/main/java/org/onap/policy/common/utils/validation/Version.java index 41ff832a..46e006bd 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/validation/Version.java +++ b/utils/src/main/java/org/onap/policy/common/utils/validation/Version.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP COMMON * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,8 +21,7 @@ package org.onap.policy.common.utils.validation; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import com.google.re2j.Pattern; import lombok.Data; import lombok.NoArgsConstructor; import lombok.NonNull; @@ -56,14 +55,13 @@ public class Version implements Comparable<Version> { * @param versionString the version string */ public Version(@NonNull final String versionString) { - Version newVersion = makeVersion("String", "constructor", versionString); + var newVersion = makeVersion("String", "constructor", versionString); if (newVersion != null) { this.major = newVersion.major; this.minor = newVersion.minor; this.patch = newVersion.patch; - } - else { + } else { this.major = 0; this.minor = 0; this.patch = 0; @@ -80,7 +78,7 @@ public class Version implements Comparable<Version> { * that does not match the major.minor.patch form) */ public static Version makeVersion(String type, String name, String versionText) { - Matcher matcher = VERSION_PAT.matcher(versionText); + var matcher = VERSION_PAT.matcher(versionText); if (!matcher.matches()) { logger.info("invalid version for {} {}: {}", type, name, versionText); return null; @@ -114,7 +112,7 @@ public class Version implements Comparable<Version> { @Override public int compareTo(Version other) { - int result = Integer.compare(major, other.major); + var result = Integer.compare(major, other.major); if (result != 0) { return result; } diff --git a/utils/src/test/java/org/onap/policy/common/utils/cmd/TestCommandLineArguments.java b/utils/src/test/java/org/onap/policy/common/utils/cmd/TestCommandLineArguments.java new file mode 100644 index 00000000..b45f107d --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/cmd/TestCommandLineArguments.java @@ -0,0 +1,181 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021, 2023 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.cmd; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.junit.Test; + +public class TestCommandLineArguments { + private static final String FAKE_HELP_CLASS = "org.onap.policy.HelpClass"; + private static final String FAKE_COMPONENT = "fake policy cpm"; + private static final String TEST_CONFIG_FILE = "cmdFiles/configuration.json"; + private static final String TEST_PROPERTY_FILE = "cmdFiles/property.json"; + private static final String ERR_MSG_INVALID_ARGS = "invalid command line arguments specified"; + private static final String ERR_MSG_POLICY_CONFIG_FILE = + "fake policy cpm configuration file was not specified as an argument"; + + CommandLineArgumentsHandler testCmd = new CommandLineArgumentsHandler(FAKE_HELP_CLASS, FAKE_COMPONENT); + + @Test + public void testVersion() throws CommandLineException { + String[] version = {"-v"}; + assertThat(testCmd.parse(version)).startsWith("ONAP Version test."); + } + + @Test + public void testHelp() throws CommandLineException { + String[] help = {"-h"}; + assertThat(testCmd.parse(help)).startsWith("usage: org.onap.policy.HelpClass [options...]"); + } + + @Test + public void testParse() throws CommandLineException { + String[] args = {"-c", TEST_CONFIG_FILE}; + testCmd.parse(args); + + assertTrue(testCmd.checkSetConfigurationFilePath()); + assertThat(testCmd.getFullConfigurationFilePath()).contains(TEST_CONFIG_FILE); + } + + @Test + public void testParse_ShouldThrowExceptionWithInvalidArguments() { + String[] invalidArgs = {"-a"}; + assertThatThrownBy(() -> testCmd.parse(invalidArgs)).hasMessage(ERR_MSG_INVALID_ARGS) + .hasRootCauseMessage("Unrecognized option: -a"); + } + + @Test + public void testParse_ShouldThrowExceptionWithExtraArguments() { + String[] remainingArgs = {"-c", TEST_CONFIG_FILE, "extraArgs"}; + String expectedErrorMsg = + "too many command line arguments specified: [-c, cmdFiles/configuration.json, extraArgs]"; + assertThatThrownBy(() -> testCmd.parse(remainingArgs)).hasMessage(expectedErrorMsg); + } + + @Test + public void testParse_ShouldThrowExceptionWhenFileNameNull() { + String[] nullArgs = {"-c", null}; + assertThatThrownBy(() -> testCmd.parse(nullArgs)).hasMessage(ERR_MSG_INVALID_ARGS); + } + + @Test + public void testValidate() throws CommandLineException { + String[] validConfigArgs = {"-c", TEST_CONFIG_FILE}; + testCmd.parse(validConfigArgs); + assertThatCode(() -> testCmd.validate()).doesNotThrowAnyException(); + } + + @Test + public void testValidate_ShouldThrowExceptionWhenConfigFileNotPresent() throws CommandLineException { + String[] versionArgs = {"-v"}; + testCmd.parse(versionArgs); + assertValidate(versionArgs, ERR_MSG_POLICY_CONFIG_FILE); + } + + @Test + public void testValidate_ShouldThrowExceptionWhenFileNameEmpty() { + String[] argsOnlyKeyNoValue = {"-c", ""}; + assertValidate(argsOnlyKeyNoValue, ERR_MSG_POLICY_CONFIG_FILE); + assertFalse(testCmd.checkSetConfigurationFilePath()); + } + + @Test + public void testValidate_ShouldThrowExceptionWhenFileNameEmptySpace() { + String[] argsOnlyKeyNoValue = {"-c", " "}; + assertValidate(argsOnlyKeyNoValue, ERR_MSG_POLICY_CONFIG_FILE); + assertFalse(testCmd.checkSetConfigurationFilePath()); + } + + @Test + public void testValidate_ShouldThrowExceptionWhenFileNameDoesNotExist() { + String[] fileNameNotExistentArgs = {"-c", "someFileName.json"}; + assertValidate(fileNameNotExistentArgs, + "fake policy cpm configuration file \"someFileName.json\" does not exist"); + } + + @Test + public void testValidate_ShouldThrowExceptionWhenFileNameIsNotFile() { + String[] folderAsFileNameArgs = {"-c", "src/test/resources"}; + assertValidate(folderAsFileNameArgs, + "fake policy cpm configuration file \"src/test/resources\" is not a normal file"); + } + + @Test + public void testAddExtraOptions() throws CommandLineException { + Option extra = Option.builder("p").longOpt("property-file") + .desc("the full path to the topic property file to use, the property file contains the " + + FAKE_COMPONENT + " properties") + .hasArg().argName("PROP_FILE").required(false).type(String.class).build(); + + CommandLineArgumentsHandler testCmdExtraOpt = + new CommandLineArgumentsHandler(FAKE_HELP_CLASS, FAKE_COMPONENT, extra); + + String[] args = {"-p", TEST_PROPERTY_FILE}; + testCmdExtraOpt.parse(args); + + assertTrue(testCmdExtraOpt.checkSetPropertyFilePath()); + assertThat(testCmdExtraOpt.getFullPropertyFilePath()).contains(TEST_PROPERTY_FILE); + + String[] argsNoProperty = {"-p", ""}; + testCmdExtraOpt.parse(argsNoProperty); + + assertFalse(testCmdExtraOpt.checkSetPropertyFilePath()); + } + + @Test + public void testNewOptions() throws CommandLineException { + Options newOptions = new Options(); + newOptions.addOption( + Option.builder("a").longOpt("fake-option").desc("the fake property to check command line parse") + .hasArg().argName("FAKE_OPT").required(false).type(String.class).build()); + + CommandLineArgumentsHandler testCmdExtraOpt = + new CommandLineArgumentsHandler(FAKE_HELP_CLASS, FAKE_COMPONENT, newOptions); + + String[] args = {"-a", "aaaa"}; + testCmdExtraOpt.parse(args); + + assertTrue(testCmdExtraOpt.getCommandLine().hasOption("a")); + + // should raise exception as -c is not present on options; + // default options should've been replaced by constructor parameter. + String[] argsError = {"-c", "aaaa.json"}; + assertThatThrownBy(() -> testCmdExtraOpt.parse(argsError)).hasMessage(ERR_MSG_INVALID_ARGS) + .hasRootCauseMessage("Unrecognized option: -c"); + } + + private void assertValidate(String[] testArgs, String expectedErrorMsg) { + try { + testCmd.parse(testArgs); + } catch (CommandLineException e) { + fail(e.getMessage()); + } + assertThatThrownBy(() -> testCmd.validate()).hasMessage(expectedErrorMsg); + } +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/coder/CoderTest.java b/utils/src/test/java/org/onap/policy/common/utils/coder/CoderTest.java new file mode 100644 index 00000000..01821504 --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/coder/CoderTest.java @@ -0,0 +1,129 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. 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.policy.common.utils.coder; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import org.junit.Before; +import org.junit.Test; + +public class CoderTest { + private static final Long LONG = 10L; + private static final Integer INTEGER = 10; + private static final String INT_TEXT = INTEGER.toString(); + private static final String TEXT = "some text"; + private static final String ENCODED = "encoded value"; + private static final String DECODED = "decoded value"; + + private MyCoder coder; + + @Before + public void setUp() { + coder = new MyCoder(); + } + + @Test + public void testConvert() throws CoderException { + assertNull(coder.convert(null, String.class)); + + // same class of object + assertEquals(TEXT, coder.convert(TEXT, String.class)); + assertEquals(INTEGER, coder.convert(INTEGER, Integer.class)); + + // source is a string + assertEquals(INTEGER, coder.convert(TEXT, Integer.class)); + + // target is a string + assertEquals(INT_TEXT, coder.convert(INTEGER, String.class)); + + // source and target are different types, neither is a string + assertEquals(INTEGER, coder.convert(LONG, Integer.class)); + } + + private static class MyCoder implements Coder { + @Override + public String encode(Object object) throws CoderException { + return (object.getClass() == String.class ? ENCODED : INT_TEXT); + } + + @Override + public String encode(Object object, boolean pretty) throws CoderException { + // unused + return null; + } + + @Override + public void encode(Writer target, Object object) throws CoderException { + // unused + } + + @Override + public void encode(OutputStream target, Object object) throws CoderException { + // unused + } + + @Override + public void encode(File target, Object object) throws CoderException { + // unused + } + + @Override + public <T> T decode(String json, Class<T> clazz) throws CoderException { + return (clazz == String.class ? clazz.cast(DECODED) : clazz.cast(INTEGER)); + } + + @Override + public <T> T decode(Reader source, Class<T> clazz) throws CoderException { + // unused + return null; + } + + @Override + public <T> T decode(InputStream source, Class<T> clazz) throws CoderException { + // unused + return null; + } + + @Override + public <T> T decode(File source, Class<T> clazz) throws CoderException { + // unused + return null; + } + + @Override + public StandardCoderObject toStandard(Object object) throws CoderException { + // unused + return null; + } + + @Override + public <T> T fromStandard(StandardCoderObject sco, Class<T> clazz) throws CoderException { + // unused + return null; + } + } +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/coder/PropertyCoderTest.java b/utils/src/test/java/org/onap/policy/common/utils/coder/PropertyCoderTest.java index 83017e70..86f8a1b1 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/coder/PropertyCoderTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/coder/PropertyCoderTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 AT&T Intellectual Property. 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. @@ -23,28 +23,39 @@ package org.onap.policy.common.utils.coder; import static org.junit.Assert.assertEquals; import com.google.gson.annotations.SerializedName; - import java.io.Reader; import java.io.StringReader; import java.util.List; - import lombok.Getter; - import org.junit.Before; import org.junit.Test; public class PropertyCoderTest { private PropertyCoder propertyCoder = null; private static final String AES_ENCRYPTION_KEY = "aes_encryption_key"; + + /* + * Note: to generate the encrypted values, invoke CryptoUtils passing both the value + * to be encrypted and the secret key. + * + * The secret key should typically be 32 characters long, resulting in a 256-bit + * key, and is placed in "aes_encryption_key". + * + * For "xacml.pdp.rest.password", the encrypted value was generated via: + * java org.onap.policy.common.utils.security.CryptoUtils enc alpha abcdefghijklmnopqrstuvwxyzabcdef + * + * For "pass", the encrypted value was generated via: + * java org.onap.policy.common.utils.security.CryptoUtils enc hello abcdefghijklmnopqrstuvwxyzabcdef + */ private static final String json = ("{'aes_encryption_key':'abcdefghijklmnopqrstuvwxyzabcdef'" - + ",'xacml.pdp.rest.password':'enc:YZ8EqzsxIOzIuK416SWAdrv+0cKKkqsQt/NYH9+uxwI='" + + ",'xacml.pdp.rest.password':'enc:FSfOhDygtmnX3gkMSfTFMoBFW+AG5k6goNj2KZgQmeF0DqgcMg=='" + ",'xacml.pdp.rest.user':'testpdp'" + ",'xacml.pdp.rest.client.user':'policy'" + ",'xacml.pdp.rest.client.password':'policy'" + ",'xacml.pdp.rest.environment':'TEST'" + ",'servers':[{'name':'server1','port':'10'," - + "'pass':'enc:KXIY94KcAapOAAeFbtjQL4kBPB4k+NJfwdP+GpG3LWQ='}" + + "'pass':'enc:08Fj6tLhmWjkZkf52O2A2ZNT8PpL80yEOEKXlbV/gnm0lkR9OA=='}" + ",{'name':'server2','port':'20','pass':'plaintext'}]" + "}").replace('\'', '"'); @@ -102,4 +113,4 @@ public class PropertyCoderTest { private String port; private String pass; } -}
\ No newline at end of file +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderInstantAsMillisTest.java b/utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderInstantAsMillisTest.java new file mode 100644 index 00000000..ec977da6 --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderInstantAsMillisTest.java @@ -0,0 +1,160 @@ +/* + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2019-2020 AT&T Intellectual Property. 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.policy.common.utils.coder; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import com.google.gson.JsonElement; +import java.io.StringReader; +import java.io.StringWriter; +import java.time.Instant; +import java.util.LinkedHashMap; +import java.util.Map; +import lombok.ToString; +import org.junit.Before; +import org.junit.Test; + +public class StandardCoderInstantAsMillisTest { + private static final long INSTANT_MILLIS = 1583249713500L; + private static final String INSTANT_TEXT = String.valueOf(INSTANT_MILLIS); + + private StandardCoder coder; + + @Before + public void setUp() { + coder = new StandardCoderInstantAsMillis(); + } + + @Test + public void testConvert() throws CoderException { + MyObject obj = makeObject(); + + @SuppressWarnings("unchecked") + Map<String, Object> map = coder.convert(obj, LinkedHashMap.class); + + assertThat(map.toString()).contains(INSTANT_TEXT); + + MyObject obj2 = coder.convert(map, MyObject.class); + assertEquals(obj.toString(), obj2.toString()); + } + + @Test + public void testEncodeDecode() throws CoderException { + MyObject obj = makeObject(); + assertThat(coder.encode(obj, false)).contains(INSTANT_TEXT); + assertThat(coder.encode(obj, true)).contains(INSTANT_TEXT); + + String json = coder.encode(obj); + MyObject obj2 = coder.decode(json, MyObject.class); + assertEquals(obj.toString(), obj2.toString()); + + StringWriter wtr = new StringWriter(); + coder.encode(wtr, obj); + json = wtr.toString(); + assertThat(json).contains(INSTANT_TEXT); + + StringReader rdr = new StringReader(json); + obj2 = coder.decode(rdr, MyObject.class); + assertEquals(obj.toString(), obj2.toString()); + } + + @Test + public void testJson() { + MyObject obj = makeObject(); + assertThat(coder.toPrettyJson(obj)).contains(INSTANT_TEXT); + } + + @Test + public void testToJsonTree_testFromJsonJsonElementClassT() throws Exception { + MyMap map = new MyMap(); + map.props = new LinkedHashMap<>(); + map.props.put("jel keyA", "jel valueA"); + map.props.put("jel keyB", "jel valueB"); + + JsonElement json = coder.toJsonTree(map); + assertEquals("{'props':{'jel keyA':'jel valueA','jel keyB':'jel valueB'}}".replace('\'', '"'), json.toString()); + + Object result = coder.fromJson(json, MyMap.class); + + assertNotNull(result); + assertEquals("{jel keyA=jel valueA, jel keyB=jel valueB}", result.toString()); + } + + @Test + public void testConvertFromDouble() throws Exception { + String text = "[listA, {keyA=100}, 200]"; + assertEquals(text, coder.decode(text, Object.class).toString()); + + text = "{keyB=200}"; + assertEquals(text, coder.decode(text, Object.class).toString()); + } + + @Test + public void testToStandard() throws Exception { + MyObject obj = makeObject(); + StandardCoderObject sco = coder.toStandard(obj); + assertNotNull(sco.getData()); + assertEquals("{'abc':'xyz','instant':1583249713500}".replace('\'', '"'), sco.getData().toString()); + + // class instead of object -> exception + assertThatThrownBy(() -> coder.toStandard(String.class)).isInstanceOf(CoderException.class); + } + + @Test + public void testFromStandard() throws Exception { + MyObject obj = new MyObject(); + obj.abc = "pdq"; + StandardCoderObject sco = coder.toStandard(obj); + + MyObject obj2 = coder.fromStandard(sco, MyObject.class); + assertEquals(obj.toString(), obj2.toString()); + + // null class -> exception + assertThatThrownBy(() -> coder.fromStandard(sco, null)).isInstanceOf(CoderException.class); + } + + + private MyObject makeObject() { + MyObject obj = new MyObject(); + obj.abc = "xyz"; + obj.instant = Instant.ofEpochMilli(INSTANT_MILLIS); + return obj; + } + + + @ToString + private static class MyObject { + private String abc; + private Instant instant; + } + + public static class MyMap { + private Map<String, Object> props; + + @Override + public String toString() { + return props.toString(); + } + } +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderTest.java b/utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderTest.java index d5cde55a..33c7331e 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP PAP * ================================================================================ - * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2021 AT&T Intellectual Property. 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. @@ -23,12 +23,15 @@ package org.onap.policy.common.utils.coder; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; +import com.google.gson.JsonSyntaxException; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -49,6 +52,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.TreeMap; +import lombok.ToString; import org.junit.Before; import org.junit.Test; @@ -66,6 +70,35 @@ public class StandardCoderTest { } @Test + public void testConvert() throws CoderException { + // null source + assertNull(coder.convert(null, StandardCoderObject.class)); + + // same class of object + StandardCoderObject sco = new StandardCoderObject(); + assertSame(sco, coder.convert(sco, StandardCoderObject.class)); + + // source is a string + assertEquals(Integer.valueOf(10), coder.convert("10", Integer.class)); + + // target is a string + assertEquals("10", coder.convert(10, String.class)); + + // source and target are different types, neither is a string + sco = coder.convert(Map.of("hello", "world"), StandardCoderObject.class); + assertEquals("world", sco.getString("hello")); + + // throw an exeception + coder = new StandardCoder() { + @Override + protected <T> T fromJson(JsonElement json, Class<T> clazz) { + throw jpe; + } + }; + assertThatThrownBy(() -> coder.convert(10, Long.class)).isInstanceOf(CoderException.class).hasCause(jpe); + } + + @Test public void testEncodeObject() throws Exception { List<Integer> arr = Arrays.asList(1100, 1110); assertEquals("[1100,1110]", coder.encode(arr)); @@ -288,7 +321,9 @@ public class StandardCoderTest { assertEquals(json, coder.toJson(sco)); // invalid json -> exception - assertThatThrownBy(() -> coder.fromJson(new StringReader("["), StandardCoderObject.class)); + StringReader rdr = new StringReader("["); + assertThatThrownBy(() -> coder.fromJson(rdr, StandardCoderObject.class)) + .isInstanceOf(JsonSyntaxException.class); } @Test @@ -312,7 +347,7 @@ public class StandardCoderTest { // test when decoding into a map @SuppressWarnings("unchecked") - Map<String,Object> map2 = coder.decode("{'intValue':10, 'dblVal':20.1}", TreeMap.class); + Map<String, Object> map2 = coder.decode("{'intValue':10, 'dblVal':20.1}", TreeMap.class); assertEquals("{dblVal=20.1, intValue=10}", map2.toString()); } @@ -324,13 +359,9 @@ public class StandardCoderTest { } + @ToString private static class MyObject { private String abc; - - @Override - public String toString() { - return "MyObject [abc=" + abc + "]"; - } } public static class MyMap { diff --git a/utils/src/test/java/org/onap/policy/common/utils/coder/StandardYamlCoderTest.java b/utils/src/test/java/org/onap/policy/common/utils/coder/StandardYamlCoderTest.java index c770cd3b..cadeb055 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/coder/StandardYamlCoderTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/coder/StandardYamlCoderTest.java @@ -97,6 +97,12 @@ public class StandardYamlCoderTest { } @Test + public void testFromJsonDoubleToInteger() throws Exception { + Object value = coder.decode("20", Object.class); + assertEquals(Integer.valueOf(20), value); + } + + @Test public void testStandardTypeAdapter() throws Exception { String yaml = "abc: def\n"; StandardCoderObject sco = coder.fromJson(yaml, StandardCoderObject.class); diff --git a/utils/src/test/java/org/onap/policy/common/utils/jpa/EntityMgrCloserTest.java b/utils/src/test/java/org/onap/policy/common/utils/jpa/EntityMgrCloserTest.java index 589d0924..17d7f7ff 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/jpa/EntityMgrCloserTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/jpa/EntityMgrCloserTest.java @@ -2,7 +2,8 @@ * ============LICENSE_START======================================================= * Common Utils * ================================================================================ - * Copyright (C) 2018-2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,8 +26,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; -import javax.persistence.EntityManager; - +import jakarta.persistence.EntityManager; import org.junit.Before; import org.junit.Test; diff --git a/utils/src/test/java/org/onap/policy/common/utils/jpa/EntityMgrFactoryCloserTest.java b/utils/src/test/java/org/onap/policy/common/utils/jpa/EntityMgrFactoryCloserTest.java index ca2b7220..0e8edca2 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/jpa/EntityMgrFactoryCloserTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/jpa/EntityMgrFactoryCloserTest.java @@ -2,7 +2,8 @@ * ============LICENSE_START======================================================= * Common Utils * ================================================================================ - * Copyright (C) 2018-2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,8 +26,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; -import javax.persistence.EntityManagerFactory; - +import jakarta.persistence.EntityManagerFactory; import org.junit.Before; import org.junit.Test; diff --git a/utils/src/test/java/org/onap/policy/common/utils/jpa/EntityTransCloserTest.java b/utils/src/test/java/org/onap/policy/common/utils/jpa/EntityTransCloserTest.java index d764e9d0..dc63c673 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/jpa/EntityTransCloserTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/jpa/EntityTransCloserTest.java @@ -2,7 +2,8 @@ * ============LICENSE_START======================================================= * Common Utils * ================================================================================ - * Copyright (C) 2018-2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,8 +28,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import javax.persistence.EntityTransaction; - +import jakarta.persistence.EntityTransaction; import org.junit.Before; import org.junit.Test; @@ -56,7 +56,7 @@ public class EntityTransCloserTest { public void testEntityTransCloser() { EntityTransCloser entityTransCloser = new EntityTransCloser(trans); - assertEquals(trans, entityTransCloser.getTransation()); + assertEquals(trans, entityTransCloser.getTransaction()); // verify that transaction was started verify(trans).begin(); @@ -73,7 +73,7 @@ public class EntityTransCloserTest { @Test public void testGetTransation() { try (EntityTransCloser t = new EntityTransCloser(trans)) { - assertEquals(trans, t.getTransation()); + assertEquals(trans, t.getTransaction()); } } diff --git a/utils/src/test/java/org/onap/policy/common/utils/logging/LoggerUtilsTest.java b/utils/src/test/java/org/onap/policy/common/utils/logging/LoggerUtilsTest.java new file mode 100644 index 00000000..79db2093 --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/logging/LoggerUtilsTest.java @@ -0,0 +1,53 @@ +/*- +* ============LICENSE_START======================================================= +* ONAP Policy +* ================================================================================ +* Copyright (C) 2021 AT&T Intellectual Property. 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.policy.common.utils.logging; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@RunWith(MockitoJUnitRunner.class) +public class LoggerUtilsTest { + protected static final Logger logger = LoggerFactory.getLogger(LoggerUtilsTest.class); + + @Test + public void testMarker() { + assertTrue(logger.isInfoEnabled()); + logger.info("line 1"); + logger.info(LoggerUtils.METRIC_LOG_MARKER, "line 1 Metric"); + logger.info(LoggerUtils.AUDIT_LOG_MARKER, "line 1 Audit"); + logger.info(LoggerUtils.SECURITY_LOG_MARKER, "line 1 Security"); + logger.info(LoggerUtils.TRANSACTION_LOG_MARKER, "line 1 Transaction"); + LoggerUtils.setLevel(LoggerUtils.ROOT_LOGGER, "debug"); + logger.debug("line 2"); + logger.debug(LoggerUtils.METRIC_LOG_MARKER, "line 2 Metric"); + logger.debug(LoggerUtils.AUDIT_LOG_MARKER, "line 2 Audit"); + logger.debug(LoggerUtils.SECURITY_LOG_MARKER, "line 2 Security"); + logger.info(LoggerUtils.TRANSACTION_LOG_MARKER, "line 2 Transaction"); + assertTrue(logger.isDebugEnabled()); + } +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/network/NetworkUtilTest.java b/utils/src/test/java/org/onap/policy/common/utils/network/NetworkUtilTest.java index a0b8353d..4019ca79 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/network/NetworkUtilTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/network/NetworkUtilTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * policy-utils * ================================================================================ - * Copyright (C) 2018-2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018-2021 AT&T Intellectual Property. 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. @@ -20,8 +20,10 @@ package org.onap.policy.common.utils.network; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -67,7 +69,7 @@ public class NetworkUtilTest { public void testAllocPort_testAllocPortString__testAllocPortInetSocketAddress() throws Exception { // allocate wild-card port int wildCardPort = NetworkUtil.allocPort(); - assertTrue(wildCardPort != 0); + assertNotEquals(0, wildCardPort); // verify that we can listen on the port try (ServerSocket wildSocket = new ServerSocket(wildCardPort)) { @@ -78,10 +80,10 @@ public class NetworkUtilTest { // allocate port using host name int localPort = NetworkUtil.allocPort(LOCALHOST); - assertTrue(localPort != 0); + assertNotEquals(0, localPort); // the OS should have allocated a new port, even though the first has been closed - assertTrue(localPort != wildCardPort); + assertNotEquals(wildCardPort, localPort); try (ServerSocket localSocket = new ServerSocket()) { localSocket.bind(new InetSocketAddress(LOCALHOST, localPort)); @@ -90,6 +92,15 @@ public class NetworkUtilTest { } } + @Test + public void testGenUniqueName() { + String name = NetworkUtil.genUniqueName(LOCALHOST); + assertThat(name).isNotBlank().isNotEqualTo(LOCALHOST); + + // second call should generate a different value + assertThat(NetworkUtil.genUniqueName(LOCALHOST)).isNotEqualTo(name); + } + /** * Thread that accepts a connection on a socket. */ diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/BeanConfiguratorTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/BeanConfiguratorTest.java index 07e0795f..7da4eccd 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/properties/BeanConfiguratorTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/properties/BeanConfiguratorTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP - Common Modules * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 AT&T Intellectual Property. 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. @@ -80,6 +80,10 @@ public class BeanConfiguratorTest { @Test public void testConfigureFromProperties() throws PropertyException { + testStringValueNoDefault(); + } + + private void testStringValueNoDefault() throws PropertyException { props.setProperty(THE_VALUE, STRING_VALUE); PlainStringConfig cfg = new PlainStringConfig(); @@ -177,11 +181,7 @@ public class BeanConfiguratorTest { @Test public void testSetValueObjectFieldProperties_FieldSet() throws PropertyException { - props.setProperty(THE_VALUE, STRING_VALUE); - PlainStringConfig cfg = new PlainStringConfig(); - beancfg.configureFromProperties(cfg, props); - - assertEquals(STRING_VALUE, cfg.value); + testStringValueNoDefault(); } @Test @@ -500,11 +500,7 @@ public class BeanConfiguratorTest { @Test public void testGetStringValue() throws PropertyException { - props.setProperty(THE_VALUE, STRING_VALUE); - PlainStringConfig cfg = new PlainStringConfig(); - beancfg.configureFromProperties(cfg, props); - - assertEquals(STRING_VALUE, cfg.value); + testStringValueNoDefault(); } @Test @@ -721,12 +717,7 @@ public class BeanConfiguratorTest { @Test public void testGetPropValue_Prop_NoDefault() throws PropertyException { - props.setProperty(THE_VALUE, STRING_VALUE); - - PlainStringConfig cfg = new PlainStringConfig(); - beancfg.configureFromProperties(cfg, props); - - assertEquals(STRING_VALUE, cfg.value); + testStringValueNoDefault(); } @Test @@ -960,18 +951,8 @@ public class BeanConfiguratorTest { @Test(expected = PropertyInvalidException.class) public void testCheckDefaultValue_Empty_EmptyOk_Invalid() throws PropertyException { - class Config { - - @Property(name = THE_VALUE, defaultValue = "", accept = "empty") - private long value; - - @SuppressWarnings("unused") - public void setValue(long value) { - this.value = value; - } - } - beancfg.configureFromProperties(new Config(), props); + beancfg.configureFromProperties(new PrimLongDefaultBlankAcceptEmptyConfig(), props); } @Test @@ -1005,18 +986,8 @@ public class BeanConfiguratorTest { @Test(expected = PropertyMissingException.class) public void testIsEmptyOkPropertyString_False() throws PropertyException { - class Config { - - @Property(name = THE_VALUE, defaultValue = "", accept = "") - private long value; - @SuppressWarnings("unused") - public void setValue(long value) { - this.value = value; - } - } - - beancfg.configureFromProperties(new Config(), props); + beancfg.configureFromProperties(new PrimLongDefaultBlankAcceptBlankConfig(), props); } @Test @@ -1040,18 +1011,8 @@ public class BeanConfiguratorTest { @Test(expected = PropertyMissingException.class) public void testIsEmptyOkProperty_False() throws PropertyException { - class Config { - - @Property(name = THE_VALUE, defaultValue = "", accept = "") - private long value; - - @SuppressWarnings("unused") - public void setValue(long value) { - this.value = value; - } - } - beancfg.configureFromProperties(new Config(), props); + beancfg.configureFromProperties(new PrimLongDefaultBlankAcceptBlankConfig(), props); } @Test @@ -1420,6 +1381,26 @@ public class BeanConfiguratorTest { } } + class PrimLongDefaultBlankAcceptEmptyConfig { + + @Property(name = THE_VALUE, defaultValue = "", accept = "empty") + private long value; + + public void setValue(long value) { + this.value = value; + } + } + + class PrimLongDefaultBlankAcceptBlankConfig { + + @Property(name = THE_VALUE, defaultValue = "", accept = "") + private long value; + + public void setValue(long value) { + this.value = value; + } + } + /** * This is just used as a mix-in to ensure that the configuration ignores interfaces. */ diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/PropertyObjectUtilsTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/PropertyObjectUtilsTest.java new file mode 100644 index 00000000..93b30643 --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/properties/PropertyObjectUtilsTest.java @@ -0,0 +1,212 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019-2020 AT&T Intellectual Property. 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.policy.common.utils.properties; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.AbstractSet; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import org.junit.Test; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; + +public class PropertyObjectUtilsTest { + + @Test + public void testToObject() { + Map<String, String> map = Map.of("abc", "def", "ghi", "jkl"); + Properties props = new Properties(); + props.putAll(map); + + // with empty prefix + Map<String, Object> result = PropertyObjectUtils.toObject(props, ""); + assertEquals(map, result); + + // with dotted prefix - other items skipped + map = Map.of("pfx.abc", "def", "ghi", "jkl", "pfx.mno", "pqr", "differentpfx.stu", "vwx"); + props.clear(); + props.putAll(Map.of("pfx.abc", "def", "ghi", "jkl", "pfx.mno", "pqr", "differentpfx.stu", "vwx")); + result = PropertyObjectUtils.toObject(props, "pfx."); + map = Map.of("abc", "def", "mno", "pqr"); + assertEquals(map, result); + + // undotted prefix - still skips other items + result = PropertyObjectUtils.toObject(props, "pfx"); + assertEquals(map, result); + } + + @Test + public void testSetProperty() { + // one, two, and three components in the name, the last two with subscripts + Map<String, Object> map = Map.of("one", "one.abc", "two.def", "two.ghi", "three.jkl.mno[0]", "three.pqr", + "three.jkl.mno[1]", "three.stu"); + Properties props = new Properties(); + props.putAll(map); + + Map<String, Object> result = PropertyObjectUtils.toObject(props, ""); + // @formatter:off + map = Map.of( + "one", "one.abc", + "two", Map.of("def", "two.ghi"), + "three", Map.of("jkl", + Map.of("mno", + List.of("three.pqr", "three.stu")))); + // @formatter:on + assertEquals(map, result); + } + + @Test + public void testGetNode() { + Map<String, Object> map = Map.of("abc[0].def", "node.ghi", "abc[0].jkl", "node.mno", "abc[1].def", "node.pqr"); + Properties props = new Properties(); + props.putAll(map); + + Map<String, Object> result = PropertyObjectUtils.toObject(props, ""); + // @formatter:off + map = Map.of( + "abc", + List.of( + Map.of("def", "node.ghi", "jkl", "node.mno"), + Map.of("def", "node.pqr") + )); + // @formatter:on + assertEquals(map, result); + + } + + @Test + public void testExpand() { + // add subscripts out of order + Properties props = makeProperties("abc[2]", "expand.def", "abc[1]", "expand.ghi"); + + Map<String, Object> result = PropertyObjectUtils.toObject(props, ""); + // @formatter:off + Map<String, Object> map = + Map.of("abc", + Arrays.asList(null, "expand.ghi", "expand.def")); + // @formatter:on + assertEquals(map, result); + + } + + @Test + public void testGetObject() { + // first value is primitive, while second is a map + Properties props = makeProperties("object.abc", "object.def", "object.abc.ghi", "object.jkl"); + + Map<String, Object> result = PropertyObjectUtils.toObject(props, ""); + // @formatter:off + Map<String, Object> map = + Map.of("object", + Map.of("abc", + Map.of("ghi", "object.jkl"))); + // @formatter:on + assertEquals(map, result); + } + + @Test + public void testGetArray() { + // first value is primitive, while second is an array + Properties props = makeProperties("array.abc", "array.def", "array.abc[0].ghi", "array.jkl"); + + Map<String, Object> result = PropertyObjectUtils.toObject(props, ""); + // @formatter:off + Map<String, Object> map = + Map.of("array", + Map.of("abc", + List.of( + Map.of("ghi", "array.jkl")))); + // @formatter:on + assertEquals(map, result); + } + + @Test + @SuppressWarnings("unchecked") + public void testCompressLists() throws IOException, CoderException { + assertEquals("plain-string", PropertyObjectUtils.compressLists("plain-string").toString()); + + // @formatter:off + Map<String, Object> map = + Map.of( + "cmp.abc", "cmp.def", + "cmp.ghi", + Arrays.asList(null, "cmp.list1", null, "cmp.list2", + Map.of("cmp.map", Arrays.asList("cmp.map.list1", "cmp.map1.list2", null)))); + // @formatter:on + + // the data structure needs to be modifiable, so we'll encode/decode it + StandardCoder coder = new StandardCoder(); + map = coder.decode(coder.encode(map), LinkedHashMap.class); + + PropertyObjectUtils.compressLists(map); + + // @formatter:off + Map<String, Object> expected = + Map.of( + "cmp.abc", "cmp.def", + "cmp.ghi", + Arrays.asList("cmp.list1", "cmp.list2", + Map.of("cmp.map", Arrays.asList("cmp.map.list1", "cmp.map1.list2")))); + // @formatter:on + assertEquals(expected, map); + } + + /** + * Makes properties containing the specified key/value pairs. The property set returns + * names in the order listed. + * + * @return a new properties containing the specified key/value pairs + */ + private Properties makeProperties(String key1, String value1, String key2, String value2) { + // control the order in which the names are returned + List<String> keyList = List.of(key1, key2); + + Set<String> keySet = new AbstractSet<>() { + @Override + public Iterator<String> iterator() { + return keyList.iterator(); + } + + @Override + public int size() { + return 2; + } + }; + + Properties props = new Properties() { + private static final long serialVersionUID = 1L; + + @Override + public Set<String> stringPropertyNames() { + return keySet; + } + }; + + props.putAll(Map.of(key1, value1, key2, value2)); + + return props; + } +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyAccessExceptionTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyAccessExceptionTest.java index 190fddd5..ef2051d8 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyAccessExceptionTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyAccessExceptionTest.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP Policy Engine - Common Modules * ================================================================================ - * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018, 2020 AT&T Intellectual Property. 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. @@ -28,46 +28,46 @@ import org.junit.Test; public class PropertyAccessExceptionTest extends SupportBasicPropertyExceptionTester { /** - * Test method for + * Test method for * {@link org.onap.policy.common.utils.properties.exception.PropertyAccessException#PropertyAccessException * (java.lang.String, java.lang.String)}. */ @Test public void testPropertyAccessExceptionStringField() { - doTestPropertyExceptionStringField_AllPopulated( new PropertyAccessException(PROPERTY, FIELD)); - doTestPropertyExceptionStringField_NullProperty( new PropertyAccessException(null, FIELD)); - doTestPropertyExceptionStringField_NullField( new PropertyAccessException(PROPERTY, null)); - doTestPropertyExceptionStringField_BothNull( new PropertyAccessException(null, null)); + verifyPropertyExceptionStringField_AllPopulated(new PropertyAccessException(PROPERTY, FIELD)); + verifyPropertyExceptionStringField_NullProperty(new PropertyAccessException(null, FIELD)); + verifyPropertyExceptionStringField_NullField(new PropertyAccessException(PROPERTY, null)); + verifyPropertyExceptionStringField_BothNull(new PropertyAccessException(null, null)); } /** - * Test method for + * Test method for * {@link org.onap.policy.common.utils.properties.exception.PropertyAccessException#PropertyAccessException * (java.lang.String, java.lang.String, java.lang.String)}. */ @Test public void testPropertyAccessExceptionStringFieldString() { - doTestPropertyExceptionStringFieldString(new PropertyAccessException(PROPERTY, FIELD, MESSAGE)); + verifyPropertyExceptionStringFieldString(new PropertyAccessException(PROPERTY, FIELD, MESSAGE)); } /** - * Test method for + * Test method for * {@link org.onap.policy.common.utils.properties.exception.PropertyAccessException#PropertyAccessException * (java.lang.String, java.lang.String, java.lang.Throwable)}. */ @Test public void testPropertyAccessExceptionStringFieldThrowable() { - doTestPropertyExceptionStringFieldThrowable(new PropertyAccessException(PROPERTY, FIELD, THROWABLE)); + verifyPropertyExceptionStringFieldThrowable(new PropertyAccessException(PROPERTY, FIELD, THROWABLE)); } /** - * Test method for + * Test method for * {@link org.onap.policy.common.utils.properties.exception.PropertyAccessException#PropertyAccessException * (java.lang.String, java.lang.String, java.lang.String, java.lang.Throwable)}. */ @Test public void testPropertyAccessExceptionStringFieldStringThrowable() { - doTestPropertyExceptionStringFieldStringThrowable( + verifyPropertyExceptionStringFieldStringThrowable( new PropertyAccessException(PROPERTY, FIELD, MESSAGE, THROWABLE)); } diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyAnnotationExceptionTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyAnnotationExceptionTest.java index c4803912..91879763 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyAnnotationExceptionTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyAnnotationExceptionTest.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP Policy Engine - Common Modules * ================================================================================ - * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018, 2020 AT&T Intellectual Property. 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. @@ -34,10 +34,10 @@ public class PropertyAnnotationExceptionTest extends SupportBasicPropertyExcepti */ @Test public void testPropertyExceptionStringField() { - doTestPropertyExceptionStringField_AllPopulated(new PropertyAnnotationException(PROPERTY, FIELD)); - doTestPropertyExceptionStringField_NullProperty(new PropertyAnnotationException(null, FIELD)); - doTestPropertyExceptionStringField_NullField(new PropertyAnnotationException(PROPERTY, null)); - doTestPropertyExceptionStringField_BothNull(new PropertyAnnotationException(null, null)); + verifyPropertyExceptionStringField_AllPopulated(new PropertyAnnotationException(PROPERTY, FIELD)); + verifyPropertyExceptionStringField_NullProperty(new PropertyAnnotationException(null, FIELD)); + verifyPropertyExceptionStringField_NullField(new PropertyAnnotationException(PROPERTY, null)); + verifyPropertyExceptionStringField_BothNull(new PropertyAnnotationException(null, null)); } /** @@ -47,7 +47,7 @@ public class PropertyAnnotationExceptionTest extends SupportBasicPropertyExcepti */ @Test public void testPropertyExceptionStringFieldString() { - doTestPropertyExceptionStringFieldString(new PropertyAnnotationException(PROPERTY, FIELD, MESSAGE)); + verifyPropertyExceptionStringFieldString(new PropertyAnnotationException(PROPERTY, FIELD, MESSAGE)); } /** @@ -57,7 +57,7 @@ public class PropertyAnnotationExceptionTest extends SupportBasicPropertyExcepti */ @Test public void testPropertyExceptionStringFieldThrowable() { - doTestPropertyExceptionStringFieldThrowable(new PropertyAnnotationException(PROPERTY, FIELD, THROWABLE)); + verifyPropertyExceptionStringFieldThrowable(new PropertyAnnotationException(PROPERTY, FIELD, THROWABLE)); } /** @@ -67,7 +67,7 @@ public class PropertyAnnotationExceptionTest extends SupportBasicPropertyExcepti */ @Test public void testPropertyExceptionStringFieldStringThrowable() { - doTestPropertyExceptionStringFieldStringThrowable( + verifyPropertyExceptionStringFieldStringThrowable( new PropertyAnnotationException(PROPERTY, FIELD, MESSAGE, THROWABLE)); } diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyExceptionTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyExceptionTest.java index 9055aeb7..9166749b 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyExceptionTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyExceptionTest.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP Policy Engine - Common Modules * ================================================================================ - * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018, 2020 AT&T Intellectual Property. 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. @@ -34,10 +34,10 @@ public class PropertyExceptionTest extends SupportBasicPropertyExceptionTester { */ @Test public void testPropertyExceptionStringField() { - doTestPropertyExceptionStringField_AllPopulated(new PropertyException(PROPERTY, FIELD)); - doTestPropertyExceptionStringField_NullProperty(new PropertyException(null, FIELD)); - doTestPropertyExceptionStringField_NullField(new PropertyException(PROPERTY, null)); - doTestPropertyExceptionStringField_BothNull(new PropertyException(null, null)); + verifyPropertyExceptionStringField_AllPopulated(new PropertyException(PROPERTY, FIELD)); + verifyPropertyExceptionStringField_NullProperty(new PropertyException(null, FIELD)); + verifyPropertyExceptionStringField_NullField(new PropertyException(PROPERTY, null)); + verifyPropertyExceptionStringField_BothNull(new PropertyException(null, null)); } /** @@ -47,7 +47,7 @@ public class PropertyExceptionTest extends SupportBasicPropertyExceptionTester { */ @Test public void testPropertyExceptionStringFieldString() { - doTestPropertyExceptionStringFieldString(new PropertyException(PROPERTY, FIELD, MESSAGE)); + verifyPropertyExceptionStringFieldString(new PropertyException(PROPERTY, FIELD, MESSAGE)); } /** @@ -57,7 +57,7 @@ public class PropertyExceptionTest extends SupportBasicPropertyExceptionTester { */ @Test public void testPropertyExceptionStringFieldThrowable() { - doTestPropertyExceptionStringFieldThrowable(new PropertyException(PROPERTY, FIELD, THROWABLE)); + verifyPropertyExceptionStringFieldThrowable(new PropertyException(PROPERTY, FIELD, THROWABLE)); } /** @@ -67,7 +67,7 @@ public class PropertyExceptionTest extends SupportBasicPropertyExceptionTester { */ @Test public void testPropertyExceptionStringFieldStringThrowable() { - doTestPropertyExceptionStringFieldStringThrowable(new PropertyException(PROPERTY, FIELD, MESSAGE, THROWABLE)); + verifyPropertyExceptionStringFieldStringThrowable(new PropertyException(PROPERTY, FIELD, MESSAGE, THROWABLE)); } } diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyInvalidExceptionTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyInvalidExceptionTest.java index 69ab1bd3..3edd7ff4 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyInvalidExceptionTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyInvalidExceptionTest.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP Policy Engine - Common Modules * ================================================================================ - * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018, 2020 AT&T Intellectual Property. 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. @@ -34,10 +34,10 @@ public class PropertyInvalidExceptionTest extends SupportBasicPropertyExceptionT */ @Test public void testPropertyExceptionStringField() { - doTestPropertyExceptionStringField_AllPopulated(new PropertyInvalidException(PROPERTY, FIELD)); - doTestPropertyExceptionStringField_NullProperty(new PropertyInvalidException(null, FIELD)); - doTestPropertyExceptionStringField_NullField(new PropertyInvalidException(PROPERTY, null)); - doTestPropertyExceptionStringField_BothNull(new PropertyInvalidException(null, null)); + verifyPropertyExceptionStringField_AllPopulated(new PropertyInvalidException(PROPERTY, FIELD)); + verifyPropertyExceptionStringField_NullProperty(new PropertyInvalidException(null, FIELD)); + verifyPropertyExceptionStringField_NullField(new PropertyInvalidException(PROPERTY, null)); + verifyPropertyExceptionStringField_BothNull(new PropertyInvalidException(null, null)); } /** @@ -47,7 +47,7 @@ public class PropertyInvalidExceptionTest extends SupportBasicPropertyExceptionT */ @Test public void testPropertyExceptionStringFieldString() { - doTestPropertyExceptionStringFieldString(new PropertyInvalidException(PROPERTY, FIELD, MESSAGE)); + verifyPropertyExceptionStringFieldString(new PropertyInvalidException(PROPERTY, FIELD, MESSAGE)); } /** @@ -57,7 +57,7 @@ public class PropertyInvalidExceptionTest extends SupportBasicPropertyExceptionT */ @Test public void testPropertyExceptionStringFieldThrowable() { - doTestPropertyExceptionStringFieldThrowable(new PropertyInvalidException(PROPERTY, FIELD, THROWABLE)); + verifyPropertyExceptionStringFieldThrowable(new PropertyInvalidException(PROPERTY, FIELD, THROWABLE)); } /** @@ -67,7 +67,7 @@ public class PropertyInvalidExceptionTest extends SupportBasicPropertyExceptionT */ @Test public void testPropertyExceptionStringFieldStringThrowable() { - doTestPropertyExceptionStringFieldStringThrowable( + verifyPropertyExceptionStringFieldStringThrowable( new PropertyInvalidException(PROPERTY, FIELD, MESSAGE, THROWABLE)); } diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyMissingExceptionTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyMissingExceptionTest.java index 81a7c36a..948bc18e 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyMissingExceptionTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyMissingExceptionTest.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP Policy Engine - Common Modules * ================================================================================ - * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018, 2020 AT&T Intellectual Property. 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. @@ -34,10 +34,10 @@ public class PropertyMissingExceptionTest extends SupportBasicPropertyExceptionT */ @Test public void testPropertyExceptionStringField() { - doTestPropertyExceptionStringField_AllPopulated(new PropertyMissingException(PROPERTY, FIELD)); - doTestPropertyExceptionStringField_NullProperty(new PropertyMissingException(null, FIELD)); - doTestPropertyExceptionStringField_NullField(new PropertyMissingException(PROPERTY, null)); - doTestPropertyExceptionStringField_BothNull(new PropertyMissingException(null, null)); + verifyPropertyExceptionStringField_AllPopulated(new PropertyMissingException(PROPERTY, FIELD)); + verifyPropertyExceptionStringField_NullProperty(new PropertyMissingException(null, FIELD)); + verifyPropertyExceptionStringField_NullField(new PropertyMissingException(PROPERTY, null)); + verifyPropertyExceptionStringField_BothNull(new PropertyMissingException(null, null)); } } diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/SupportBasicPropertyExceptionTester.java b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/SupportBasicPropertyExceptionTester.java index 97503f8c..be3f8183 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/SupportBasicPropertyExceptionTester.java +++ b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/SupportBasicPropertyExceptionTester.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP Policy Engine - Common Modules * ================================================================================ - * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018, 2020 AT&T Intellectual Property. 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. @@ -20,11 +20,9 @@ package org.onap.policy.common.utils.properties.exception; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; - -import org.hamcrest.CoreMatchers; /** * Superclass used to test subclasses of {@link PropertyException}. @@ -52,45 +50,45 @@ public class SupportBasicPropertyExceptionTester { protected static final String FIELD = "PROPERTY"; /* - * Methods to perform various tests on the except subclass. + * Methods to perform various tests on the except subclass. */ - protected void doTestPropertyExceptionStringField_AllPopulated(PropertyException ex) { + protected void verifyPropertyExceptionStringField_AllPopulated(PropertyException ex) { standardTests(ex); } - protected void doTestPropertyExceptionStringField_NullProperty(PropertyException ex) { + protected void verifyPropertyExceptionStringField_NullProperty(PropertyException ex) { assertEquals(null, ex.getPropertyName()); assertEquals(FIELD, ex.getFieldName()); assertNotNull(ex.getMessage()); assertNotNull(ex.toString()); } - protected void doTestPropertyExceptionStringField_NullField(PropertyException ex) { + protected void verifyPropertyExceptionStringField_NullField(PropertyException ex) { assertEquals(PROPERTY, ex.getPropertyName()); assertEquals(null, ex.getFieldName()); assertNotNull(ex.getMessage()); assertNotNull(ex.toString()); } - protected void doTestPropertyExceptionStringField_BothNull(PropertyException ex) { + protected void verifyPropertyExceptionStringField_BothNull(PropertyException ex) { assertEquals(null, ex.getPropertyName()); assertEquals(null, ex.getFieldName()); assertNotNull(ex.getMessage()); assertNotNull(ex.toString()); } - protected void doTestPropertyExceptionStringFieldString(PropertyException ex) { + protected void verifyPropertyExceptionStringFieldString(PropertyException ex) { standardTests(ex); standardMessageTests(ex); } - protected void doTestPropertyExceptionStringFieldThrowable(PropertyException ex) { + protected void verifyPropertyExceptionStringFieldThrowable(PropertyException ex) { standardTests(ex); standardThrowableTests(ex); } - protected void doTestPropertyExceptionStringFieldStringThrowable(PropertyException ex) { + protected void verifyPropertyExceptionStringFieldStringThrowable(PropertyException ex) { standardTests(ex); standardMessageTests(ex); standardThrowableTests(ex); @@ -98,7 +96,7 @@ public class SupportBasicPropertyExceptionTester { /** * Performs standard tests that should apply to all subclasses. - * + * * @param ex exception to test */ protected void standardTests(PropertyException ex) { @@ -111,17 +109,17 @@ public class SupportBasicPropertyExceptionTester { /** * Performs standard tests for exceptions that were provided a message in their * constructor. - * + * * @param ex exception to test */ protected void standardMessageTests(PropertyException ex) { - assertThat(ex.getMessage(), CoreMatchers.endsWith(MESSAGE)); + assertThat(ex.getMessage()).endsWith(MESSAGE); } /** * Performs standard tests for exceptions that were provided a throwable in their * constructor. - * + * * @param ex exception to test */ protected void standardThrowableTests(PropertyException ex) { diff --git a/utils/src/test/java/org/onap/policy/common/utils/resources/DirectoryUtilsTest.java b/utils/src/test/java/org/onap/policy/common/utils/resources/DirectoryUtilsTest.java new file mode 100644 index 00000000..c12ef9f8 --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/resources/DirectoryUtilsTest.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. 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.policy.common.utils.resources; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.nio.file.Path; +import org.apache.commons.io.FileUtils; +import org.junit.Test; + +public class DirectoryUtilsTest { + + @Test + public void testCreateTempDirectory() throws IOException { + Path path = DirectoryUtils.createTempDirectory("directoryUtilsTest"); + + var file = path.toFile(); + FileUtils.forceDeleteOnExit(file); + + assertThat(file).canRead().canWrite().isDirectory(); + assertThat(file.canExecute()).isTrue(); + } +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java b/utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java index 8f714a49..c56409ee 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java @@ -1,8 +1,8 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2018 Ericsson. All rights reserved. - * Modifications Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2020 Nordix Foundation. + * Modifications Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2020-2021, 2023-2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ package org.onap.policy.common.utils.resources; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -30,11 +31,9 @@ import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.Set; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -79,12 +78,12 @@ public class ResourceUtilsTest { } /** - * Cleandown resource utils test. + * Clean resource utils test. */ @After - public void cleandownResourceUtilsTest() { - tmpEmptyFile.delete(); - tmpUsedFile.delete(); + public void cleanDownResourceUtilsTest() { + assertTrue(tmpEmptyFile.delete()); + assertTrue(tmpUsedFile.delete()); } /** @@ -184,45 +183,26 @@ public class ResourceUtilsTest { * Test get resource as stream. */ @Test - public void testGetResourceAsStream() { - InputStream theStream = ResourceUtils.getResourceAsStream(tmpDir.getAbsolutePath()); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(tmpEmptyFile.getAbsolutePath()); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(tmpUsedFile.getAbsolutePath()); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(jarDirResource); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(jarFileResource); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(PATH_DIR_RESOURCE); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(PATH_FILE_RESOURCE); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(RESOURCES_PATH + PATH_DIR_RESOURCE); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(RESOURCES_PATH + PATH_FILE_RESOURCE); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(NON_EXISTENT_RESOURCE); - assertNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(INVALID_RESOURCE); - assertNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(null); - assertNull(theStream); + public void testGetResourceAsStream() throws IOException { + verifyStream(tmpDir.getAbsolutePath()); + verifyStream(tmpEmptyFile.getAbsolutePath()); + verifyStream(tmpUsedFile.getAbsolutePath()); + verifyStream(jarDirResource); + verifyStream(jarFileResource); + verifyStream(PATH_DIR_RESOURCE); + verifyStream(PATH_FILE_RESOURCE); + verifyStream(RESOURCES_PATH + PATH_DIR_RESOURCE); + verifyStream(RESOURCES_PATH + PATH_FILE_RESOURCE); + assertNull(ResourceUtils.getResourceAsStream(NON_EXISTENT_RESOURCE)); + assertNull(ResourceUtils.getResourceAsStream(INVALID_RESOURCE)); + assertNull(ResourceUtils.getResourceAsStream(null)); + verifyStream(""); + } - theStream = ResourceUtils.getResourceAsStream(""); - assertNotNull(theStream); + private void verifyStream(String path) throws IOException { + try (var theStream = ResourceUtils.getResourceAsStream(path)) { + assertNotNull(theStream); + } } /** @@ -234,10 +214,10 @@ public class ResourceUtilsTest { assertNotNull(theString); theString = ResourceUtils.getResourceAsString(tmpEmptyFile.getAbsolutePath()); - assertTrue(theString.equals("")); + assertEquals("", theString); theString = ResourceUtils.getResourceAsString(tmpUsedFile.getAbsolutePath()); - assertTrue(theString.equals("Bluebirds fly over the rainbow")); + assertEquals("Bluebirds fly over the rainbow", theString); theString = ResourceUtils.getResourceAsString(jarFileResource); assertNotNull(theString); @@ -265,7 +245,7 @@ public class ResourceUtilsTest { theString = ResourceUtils.getResourceAsString(""); - assertEquals("logback-test.xml\nMETA-INF\norg\ntestdir\n", theString); + assertEquals("cmdFiles\nlogback-test.xml\nMETA-INF\norg\ntestdir\nversion.txt\n", theString); } @@ -310,7 +290,7 @@ public class ResourceUtilsTest { assertNull(ResourceUtils.getFilePath4Resource(null)); assertEquals("/something/else", ResourceUtils.getFilePath4Resource("/something/else")); assertTrue(ResourceUtils.getFilePath4Resource("xml/example.xml").endsWith("xml/example.xml")); - assertTrue(ResourceUtils.getFilePath4Resource("com/google").endsWith("com/google")); + assertTrue(ResourceUtils.getFilePath4Resource("com/google").contains("com/google")); } @Test @@ -324,21 +304,21 @@ public class ResourceUtilsTest { assertEquals("testdir/testfile.xml", normalizePath(resultD0.iterator().next())); Set<String> resultD1 = ResourceUtils.getDirectoryContents("org/onap/policy/common"); - assertTrue(resultD1.size() > 0); + assertFalse(resultD1.isEmpty()); assertEquals("org/onap/policy/common/utils/", normalizePath(resultD1.iterator().next())); Set<String> resultD2 = ResourceUtils.getDirectoryContents("org/onap/policy/common/utils/coder"); assertTrue(resultD2.size() >= 15); assertEquals("org/onap/policy/common/utils/coder/CoderExceptionTest.class", - normalizePath(resultD2.iterator().next())); + normalizePath(resultD2.iterator().next())); Set<String> resultJ0 = ResourceUtils.getDirectoryContents("com"); - assertEquals(189, resultJ0.size()); + assertTrue(resultJ0.contains("com/google/gson/")); assertEquals("com/google/", normalizePath(resultJ0.iterator().next())); - Set<String> resultJ1 = ResourceUtils.getDirectoryContents("com/google/gson/util"); - assertEquals(1, resultJ1.size()); - assertEquals("com/google/gson/util/VersionUtils.class", normalizePath(resultJ1.iterator().next())); + Set<String> resultJ1 = ResourceUtils.getDirectoryContents("com/google/gson"); + assertTrue(resultJ1.size() > 1); + assertTrue(resultJ1.contains("com/google/gson/JsonElement.class")); URL dummyUrl = new URL("http://even/worse"); assertTrue(ResourceUtils.getDirectoryContentsJar(dummyUrl, "nonexistantdirectory").isEmpty()); @@ -347,6 +327,7 @@ public class ResourceUtilsTest { /** * Normalizes a path name, replacing OS-specific separators with "/". + * * @param pathName path name to be normalized * @return the normalized path name */ diff --git a/utils/src/test/java/org/onap/policy/common/utils/resources/TextFileUtilsTest.java b/utils/src/test/java/org/onap/policy/common/utils/resources/TextFileUtilsTest.java index 0952b168..91268979 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/resources/TextFileUtilsTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/resources/TextFileUtilsTest.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2019 Nordix Foundation. + * Modifications Copyright (C) 2020-2021 AT&T Intellectual Property. 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. @@ -20,12 +21,13 @@ package org.onap.policy.common.utils.resources; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import java.io.File; import java.io.FileInputStream; import java.io.IOException; - +import org.apache.commons.io.FileUtils; import org.junit.Test; /** @@ -39,35 +41,80 @@ public class TextFileUtilsTest { @Test public void testPutToFile() throws IOException { - final File tempTextFile = File.createTempFile("Test", "txt"); + final File tempTextFile = File.createTempFile("Test", ".txt"); + tempTextFile.deleteOnExit(); TextFileUtils.putStringAsTextFile(FILE_CONTENT, tempTextFile.getAbsolutePath()); final String textFileString0 = TextFileUtils.getTextFileAsString(tempTextFile.getAbsolutePath()); assertEquals(FILE_CONTENT, textFileString0); - final FileInputStream fis = new FileInputStream(tempTextFile); - final String textFileString1 = TextFileUtils.getStreamAsString(fis); - assertEquals(textFileString0, textFileString1); + try (final FileInputStream fis = new FileInputStream(tempTextFile)) { + final String textFileString1 = TextFileUtils.getStreamAsString(fis); + assertEquals(textFileString0, textFileString1); + } } @Test public void testPutToFileWithNewPath() throws IOException { String tempDirAndFileName = System.getProperty("java.io.tmpdir") + "/non/existant/path/Test.txt"; + FileUtils.forceDeleteOnExit(new File(tempDirAndFileName)); TextFileUtils.putStringAsTextFile(FILE_CONTENT, tempDirAndFileName); final String textFileString0 = TextFileUtils.getTextFileAsString(tempDirAndFileName); assertEquals(FILE_CONTENT, textFileString0); - final FileInputStream fis = new FileInputStream(tempDirAndFileName); - final String textFileString1 = TextFileUtils.getStreamAsString(fis); - assertEquals(textFileString0, textFileString1); + try (final FileInputStream fis = new FileInputStream(tempDirAndFileName)) { + final String textFileString1 = TextFileUtils.getStreamAsString(fis); + assertEquals(textFileString0, textFileString1); + } + } + + @Test + public void testCreateTempFile() throws IOException { + var file = TextFileUtils.createTempFile("textFileUtilsTest", ".txt"); + file.deleteOnExit(); + + verifyDefaultPermissions(file); + } + + @Test + public void testSetDefaultPermissions() throws IOException { + var file = new File("target/tempfile.txt"); + file.deleteOnExit(); + + // ensure it doesn't exist before we create it + file.delete(); + assertThat(file.createNewFile()).isTrue(); + + // check using whatever permissions it comes with + + TextFileUtils.setDefaultPermissions(file); + + verifyDefaultPermissions(file); + + // prevent read-write-execute by anyone + file.setReadable(false); + file.setWritable(false); + file.setExecutable(false); + + TextFileUtils.setDefaultPermissions(file); + + verifyDefaultPermissions(file); + + // make it read-write-execute by everyone + file.setReadable(true); + file.setWritable(true); + file.setExecutable(true); + + TextFileUtils.setDefaultPermissions(file); + + verifyDefaultPermissions(file); + } - File tempDirAndFile = new File(tempDirAndFileName); - tempDirAndFile.delete(); - tempDirAndFile.getParentFile().delete(); - tempDirAndFile.getParentFile().getParentFile().delete(); - tempDirAndFile.getParentFile().getParentFile().getParentFile().delete(); + private void verifyDefaultPermissions(File file) { + assertThat(file).canRead().canWrite(); + assertThat(file.canExecute()).isTrue(); } } diff --git a/utils/src/test/java/org/onap/policy/common/utils/security/CryptoUtilsTest.java b/utils/src/test/java/org/onap/policy/common/utils/security/CryptoUtilsTest.java index ce9435d8..625fd1f5 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/security/CryptoUtilsTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/security/CryptoUtilsTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 AT&T Intellectual Property. 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. @@ -37,7 +37,7 @@ public class CryptoUtilsTest { private static Logger logger = LoggerFactory.getLogger(CryptoUtilsTest.class); private static final String PASS = "HelloWorld"; private static final String SECRET_KEY = "MTIzNDU2Nzg5MDEyMzQ1Ng=="; - private static final String ENCRYPTED_PASS = "enc:hcI2XVX+cxPz/6rlbebkWpCFF6WPbBtT7iJRr2VHUkA="; + private static final String ENCRYPTED_PASS = "enc:Z6QzirpPyDpwmIcNbE3U2iq6g/ubJBEdzssoigxGGChlQtdWOLD8y00O"; private static final String DECRYPTED_MSG = "encrypted value: {} decrypted value : {}"; private static final String ENCRYPTED_MSG = "original value : {} encrypted value: {}"; @@ -120,4 +120,4 @@ public class CryptoUtilsTest { String decryptedAgain = CryptoUtils.decrypt(decryptedValue, SECRET_KEY); assertEquals(decryptedValue, decryptedAgain); } -}
\ No newline at end of file +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/services/FeatureApiUtilsTest.java b/utils/src/test/java/org/onap/policy/common/utils/services/FeatureApiUtilsTest.java index 232d3409..d111962e 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/services/FeatureApiUtilsTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/services/FeatureApiUtilsTest.java @@ -61,7 +61,7 @@ public class FeatureApiUtilsTest { public void testApplyFeatureFalse() { List<String> lst = Arrays.asList("falseF1", "exceptF2", "falseF3"); - assertFalse(FeatureApiUtils.apply(lst, pred, (str,ex) -> errors.add(str))); + assertFalse(FeatureApiUtils.apply(lst, pred, (str, ex) -> errors.add(str))); assertEquals(lst.toString(), tried.toString()); assertEquals("[exceptF2]", errors.toString()); } diff --git a/utils/src/test/java/org/onap/policy/common/utils/validation/VersionTest.java b/utils/src/test/java/org/onap/policy/common/utils/validation/VersionTest.java index 1a45f9e1..4673233e 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/validation/VersionTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/validation/VersionTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP PAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,7 +22,7 @@ package org.onap.policy.common.utils.validation; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -48,7 +48,7 @@ public class VersionTest { public void testHashCode() { int hash = vers.hashCode(); int hash2 = new Version(MAJOR, MINOR, PATCH + 1).hashCode(); - assertTrue(hash != hash2); + assertNotEquals(hash, hash2); } @Test @@ -72,16 +72,16 @@ public class VersionTest { @Test public void testEquals() { - assertFalse(vers.equals(null)); - assertFalse(vers.equals(new Object())); + assertNotEquals(vers, null); + assertNotEquals(vers, new Object()); - assertTrue(vers.equals(vers)); + assertEquals(vers, vers); - assertTrue(vers.equals(new Version(MAJOR, MINOR, PATCH))); + assertEquals(vers, new Version(MAJOR, MINOR, PATCH)); - assertFalse(vers.equals(new Version(MAJOR + 1, MINOR, PATCH))); - assertFalse(vers.equals(new Version(MAJOR, MINOR + 1, PATCH))); - assertFalse(vers.equals(new Version(MAJOR, MINOR, PATCH + 1))); + assertNotEquals(vers, new Version(MAJOR + 1, MINOR, PATCH)); + assertNotEquals(vers, new Version(MAJOR, MINOR + 1, PATCH)); + assertNotEquals(vers, new Version(MAJOR, MINOR, PATCH + 1)); } @Test @@ -89,7 +89,7 @@ public class VersionTest { vers = new Version(101, 201, 301); // equals case - assertTrue(new Version(101, 201, 301).compareTo(vers) == 0); + assertEquals(0, new Version(101, 201, 301).compareTo(vers)); // major takes precedence assertTrue(new Version(102, 200, 300).compareTo(vers) > 0); @@ -139,4 +139,4 @@ public class VersionTest { public void testVersion() { assertEquals("0.0.0", new Version().toString()); } -}
\ No newline at end of file +} diff --git a/utils/src/test/resources/cmdFiles/configuration.json b/utils/src/test/resources/cmdFiles/configuration.json new file mode 100644 index 00000000..64cd100c --- /dev/null +++ b/utils/src/test/resources/cmdFiles/configuration.json @@ -0,0 +1,4 @@ +{ + "propertyName" : "test", + "propertyType" : "string" +} diff --git a/utils/src/test/resources/cmdFiles/property.json b/utils/src/test/resources/cmdFiles/property.json new file mode 100644 index 00000000..be63ece4 --- /dev/null +++ b/utils/src/test/resources/cmdFiles/property.json @@ -0,0 +1,3 @@ +{ + "configName" : "test" +} diff --git a/utils/src/test/resources/version.txt b/utils/src/test/resources/version.txt new file mode 100644 index 00000000..9970c7b4 --- /dev/null +++ b/utils/src/test/resources/version.txt @@ -0,0 +1 @@ +ONAP Version test. |