aboutsummaryrefslogtreecommitdiffstats
path: root/utils/src
diff options
context:
space:
mode:
Diffstat (limited to 'utils/src')
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/cmd/CommandLineArgumentsHandler.java273
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/cmd/CommandLineException.java57
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/coder/Coder.java46
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/coder/PropertyCoder.java20
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoder.java135
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoderInstantAsMillis.java61
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoderObject.java98
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/coder/StandardValCoder.java119
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/coder/StandardYamlCoder.java15
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/coder/YamlJsonTranslator.java58
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/jpa/EntityMgrCloser.java35
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/jpa/EntityMgrFactoryCloser.java35
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/jpa/EntityTransCloser.java37
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/logging/LoggerMarkerFilter.java98
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/logging/LoggerUtils.java105
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/network/NetworkUtil.java64
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/properties/BeanConfigurator.java8
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/properties/PropertyObjectUtils.java242
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/properties/SpecProperties.java15
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyException.java43
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/resources/DirectoryUtils.java63
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/resources/MessageConstants.java43
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/resources/PrometheusUtils.java107
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/resources/ResourceUtils.java105
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/resources/TextFileUtils.java68
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/security/CryptoUtils.java49
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/services/FeatureApiUtils.java13
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/services/OrderedServiceImpl.java19
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/services/Registry.java12
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/services/ServiceManager.java43
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/time/CurrentTime.java22
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/validation/Assertions.java11
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/validation/ParameterValidationUtils.java10
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/validation/Version.java14
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/cmd/TestCommandLineArguments.java181
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/coder/CoderTest.java129
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/coder/PropertyCoderTest.java25
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderInstantAsMillisTest.java160
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderObjectTest.java47
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderTest.java85
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/coder/StandardValCoderTest.java165
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/coder/StandardYamlCoderTest.java30
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/jpa/EntityMgrCloserTest.java6
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/jpa/EntityMgrFactoryCloserTest.java6
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/jpa/EntityTransCloserTest.java10
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/logging/LoggerUtilsTest.java53
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/network/NetworkUtilTest.java19
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/properties/BeanConfiguratorTest.java81
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/properties/PropertyObjectUtilsTest.java212
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyAccessExceptionTest.java28
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyAnnotationExceptionTest.java20
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyExceptionTest.java20
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyInvalidExceptionTest.java20
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyMissingExceptionTest.java14
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/properties/exception/SupportBasicPropertyExceptionTester.java34
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/resources/DirectoryUtilsTest.java42
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java109
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/resources/TextFileUtilsTest.java73
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/security/CryptoUtilsTest.java6
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/services/FeatureApiUtilsTest.java2
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/validation/VersionTest.java24
-rw-r--r--utils/src/test/resources/cmdFiles/configuration.json4
-rw-r--r--utils/src/test/resources/cmdFiles/property.json3
-rw-r--r--utils/src/test/resources/org/onap/policy/common/utils/coder/bad-regex.json9
-rw-r--r--utils/src/test/resources/org/onap/policy/common/utils/coder/missing-required.json5
-rw-r--r--utils/src/test/resources/org/onap/policy/common/utils/coder/test.schema.json71
-rw-r--r--utils/src/test/resources/org/onap/policy/common/utils/coder/valid.json9
-rw-r--r--utils/src/test/resources/version.txt1
68 files changed, 3180 insertions, 666 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 bb51f2b9..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
@@ -1,8 +1,8 @@
/*
* ============LICENSE_START=======================================================
- * ONAP PAP
+ * 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.
@@ -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
@@ -41,6 +72,17 @@ public interface Coder {
String encode(Object object) throws CoderException;
/**
+ * 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
+ * @return a json string representing the object
+ * @throws CoderException if an error occurs
+ */
+ String encode(Object object, boolean pretty) throws CoderException;
+
+ /**
* Encodes an object into json, writing to the given target.
*
* @param target target to which to write the encoded json
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 e84a92f2..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
@@ -1,8 +1,8 @@
/*
* ============LICENSE_START=======================================================
- * ONAP PAP
+ * 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.
@@ -38,35 +38,101 @@ import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
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 = GsonMessageBodyHandler.configBuilder(
- new GsonBuilder().registerTypeAdapter(StandardCoderObject.class, new StandardTypeAdapter()))
- .create();
+ private static final Gson GSON_STD;
+
+ /**
+ * Gson object used to encode messages in "pretty" format.
+ */
+ private static final Gson GSON_STD_PRETTY;
+
+ static {
+ GsonBuilder builder = GsonMessageBodyHandler.configBuilder(
+ new GsonBuilder().registerTypeAdapter(StandardCoderObject.class, new StandardTypeAdapter()));
+
+ 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
public String encode(Object object) throws CoderException {
+ return encode(object, false);
+ }
+
+ @Override
+ public String encode(Object object, boolean pretty) throws CoderException {
try {
- return toJson(object);
+ if (pretty) {
+ return toPrettyJson(object);
+
+ } else {
+ return toJson(object);
+ }
} catch (RuntimeException e) {
throw new CoderException(e);
@@ -78,7 +144,7 @@ public class StandardCoder implements Coder {
try {
toJson(target, object);
- } catch (RuntimeException | IOException e) {
+ } catch (RuntimeException e) {
throw new CoderException(e);
}
}
@@ -86,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
@@ -99,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
@@ -141,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) {
@@ -149,10 +215,20 @@ public class StandardCoder implements Coder {
}
}
+ /**
+ * Encodes the object as "pretty" json.
+ *
+ * @param object object to be encoded
+ * @return the encoded object
+ */
+ protected String toPrettyJson(Object 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);
@@ -162,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);
@@ -220,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);
}
/**
@@ -230,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);
}
/**
@@ -238,10 +314,9 @@ public class StandardCoder implements Coder {
*
* @param target target to which to write the encoded json
* @param object object to be encoded
- * @throws IOException if an I/O error occurs
*/
- protected void toJson(Writer target, Object object) throws IOException {
- GSON.toJson(object, object.getClass(), target);
+ protected void toJson(Writer target, Object object) {
+ gson.toJson(object, object.getClass(), target);
}
/**
@@ -252,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));
}
/**
@@ -263,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));
}
/**
@@ -274,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));
}
/**
@@ -286,8 +361,8 @@ public class StandardCoder implements Coder {
* @param value value to be converted
* @return the converted value
*/
- private <T> T convertFromDouble(Class<T> clazz, T value) {
- if (clazz != Object.class) {
+ protected <T> T convertFromDouble(Class<T> clazz, T value) {
+ if (clazz != Object.class && !Map.class.isAssignableFrom(clazz) && !List.class.isAssignableFrom(clazz)) {
return value;
}
@@ -297,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 60c5f4ef..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 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,18 +21,29 @@
package org.onap.policy.common.utils.coder;
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.
*/
-public class StandardCoderObject {
+@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.
@@ -42,52 +53,75 @@ public class StandardCoderObject {
}
/**
- * 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
+ * @param fields field hierarchy. These may be strings, identifying fields within the
+ * object, or Integers, identifying an index within an array
* @return the field value or {@code null} if the field does not exist or is not a
* primitive
*/
- public String getString(String... fields) {
-
- /*
- * This could be relatively easily modified to allow Integer arguments, as well,
- * which would be used to specify indices within an array.
- */
+ public String getString(Object... fields) {
JsonElement jel = data;
- for (String field : fields) {
+ for (Object field : fields) {
if (jel == null) {
return null;
}
- if (jel.isJsonObject()) {
- jel = jel.getAsJsonObject().get(field);
+ if (field instanceof String) {
+ jel = getFieldFromObject(jel, field.toString());
+
+ } else if (field instanceof Integer) {
+ jel = getItemFromArray(jel, (int) field);
} else {
- return null;
+ throw new IllegalArgumentException("subscript is not a string or integer: " + field);
}
}
return (jel != null && jel.isJsonPrimitive() ? jel.getAsString() : null);
}
+
+ /**
+ * Gets an item from an object.
+ *
+ * @param element object from which to extract the item
+ * @param field name of the field from which to extract the item
+ * @return the item, or {@code null} if the element is not an object or if the field
+ * does not exist
+ */
+ protected JsonElement getFieldFromObject(JsonElement element, String field) {
+ if (!element.isJsonObject()) {
+ return null;
+ }
+
+ return element.getAsJsonObject().get(field);
+ }
+
+ /**
+ * Gets an item from an array.
+ *
+ * @param element array from which to extract the item
+ * @param index index of the item to extract
+ * @return the item, or {@code null} if the element is not an array or if the index is
+ * out of bounds
+ */
+ protected JsonElement getItemFromArray(JsonElement element, int index) {
+ if (index < 0) {
+ throw new IllegalArgumentException("subscript is invalid: " + index);
+ }
+
+ if (!element.isJsonArray()) {
+ return null;
+ }
+
+ var array = element.getAsJsonArray();
+
+ if (index >= array.size()) {
+ return null;
+ }
+
+ return array.get(index);
+ }
}
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
new file mode 100644
index 00000000..4deeba14
--- /dev/null
+++ b/utils/src/main/java/org/onap/policy/common/utils/coder/StandardValCoder.java
@@ -0,0 +1,119 @@
+/*--
+ * ============LICENSE_START=======================================================
+ * 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.
+ * 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.coder;
+
+import com.worldturner.medeia.api.JsonSchemaVersion;
+import com.worldturner.medeia.api.SchemaSource;
+import com.worldturner.medeia.api.StringSchemaSource;
+import com.worldturner.medeia.api.ValidationFailedException;
+import com.worldturner.medeia.api.gson.MedeiaGsonApi;
+import com.worldturner.medeia.schema.validation.SchemaValidator;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import lombok.NonNull;
+import lombok.ToString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Extension to the StandardCoder to support streaming validation against a Draft-07 Json schema specification.
+ */
+
+@ToString
+public class StandardValCoder extends StandardCoder {
+
+ // The medeia-validator library integrates better than
+ // other libraries considered with GSON, and therefore
+ // the StandardCoder.
+
+ private static final Logger logger = LoggerFactory.getLogger(StandardValCoder.class);
+
+ private final MedeiaGsonApi validatorApi = new MedeiaGsonApi();
+ private final SchemaValidator validator;
+
+ /**
+ * StandardCoder with validation.
+ */
+ public StandardValCoder(@NonNull String jsonSchema, @NonNull String 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.
+ */
+ gson.toJson(object, object.getClass(), validatorApi.createJsonWriter(validator, new StringWriter()));
+
+ return super.toPrettyJson(object);
+ }
+
+ @Override
+ protected String toJson(@NonNull Object object) {
+ var output = new StringWriter();
+ toJson(output, object);
+ return output.toString();
+ }
+
+ @Override
+ protected void toJson(@NonNull Writer target, @NonNull Object object) {
+ gson.toJson(object, object.getClass(), validatorApi.createJsonWriter(validator, target));
+ }
+
+ @Override
+ protected <T> T fromJson(@NonNull Reader source, @NonNull Class<T> clazz) {
+ return convertFromDouble(clazz, gson.fromJson(validatorApi.createJsonReader(validator, source), clazz));
+ }
+
+ @Override
+ protected <T> T fromJson(String json, Class<T> clazz) {
+ var reader = new StringReader(json);
+ return convertFromDouble(clazz, gson.fromJson(validatorApi.createJsonReader(validator, reader), clazz));
+ }
+
+ /**
+ * Is the json conformant?.
+ */
+ public boolean isConformant(@NonNull String json) {
+ try {
+ conformance(json);
+ } catch (CoderException e) {
+ logger.info("JSON is not conformant to schema", e);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Check a json string for conformance against its schema definition.
+ */
+ public void conformance(@NonNull String json) throws CoderException {
+ try {
+ validatorApi.parseAll(validatorApi.createJsonReader(validator, new StringReader(json)));
+ } catch (ValidationFailedException e) {
+ throw new CoderException(e);
+ }
+ }
+}
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 36f15b96..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
@@ -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.
@@ -34,7 +34,18 @@ 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
+ protected String toPrettyJson(Object object) {
+ // YAML is already "pretty"
+ return toJson(object);
}
@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/StandardCoderObjectTest.java b/utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderObjectTest.java
index 44086f30..1748aed3 100644
--- a/utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderObjectTest.java
+++ b/utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderObjectTest.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.
@@ -20,6 +20,7 @@
package org.onap.policy.common.utils.coder;
+import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -34,10 +35,11 @@ public class StandardCoderObjectTest {
private static final String PROP1 = "abc";
private static final String PROP2 = "ghi";
+ private static final Integer PROP2_INDEX = 1;
private static final String PROP2b = "jkl";
private static final String VAL1 = "def";
private static final String VAL2 = "mno";
- private static final String JSON = "{'abc':'def','ghi':{'jkl':'mno'}}".replace('\'', '"');
+ private static final String JSON = "{'abc':'def','ghi':[{},{'jkl':'mno'}]}".replace('\'', '"');
private StandardCoderObject sco;
@@ -68,7 +70,7 @@ public class StandardCoderObjectTest {
assertEquals(VAL1, sco.getString(PROP1));
// multiple fields
- assertEquals(VAL2, sco.getString(PROP2, PROP2b));
+ assertEquals(VAL2, sco.getString(PROP2, PROP2_INDEX, PROP2b));
// not found
assertNull(sco.getString("xyz"));
@@ -85,5 +87,44 @@ public class StandardCoderObjectTest {
// not a JSON object
assertNull(sco.getString(PROP1, PROP2));
+
+ // invalid subscript
+ assertThatIllegalArgumentException().isThrownBy(() -> sco.getString(10.0));
+ }
+
+ @Test
+ public void testGetFieldFromObject() {
+ // not an object
+ assertNull(sco.getFieldFromObject(fromJson("[]"), PROP1));
+
+ // field doesn't exist
+ assertNull(sco.getFieldFromObject(fromJson("{}"), "non-existent"));
+
+ // field exists
+ assertEquals(4, sco.getFieldFromObject(fromJson("{\"world\":4}"), "world").getAsInt());
+ }
+
+ @Test
+ public void testGetItemFromArray() {
+ // not an array
+ assertNull(sco.getItemFromArray(fromJson("{}"), 0));
+
+ // negative index
+ assertThatIllegalArgumentException().isThrownBy(() -> sco.getItemFromArray(fromJson("[]"), -1));
+
+ // index out of bounds
+ assertNull(sco.getItemFromArray(fromJson("[5]"), 1));
+ assertNull(sco.getItemFromArray(fromJson("[5]"), 2));
+
+ // index exists
+ assertEquals(6, sco.getItemFromArray(fromJson("[5,6,7]"), 1).getAsInt());
+
+ // edge case: first and last item
+ assertEquals(50, sco.getItemFromArray(fromJson("[50,60,70]"), 0).getAsInt());
+ assertEquals(700, sco.getItemFromArray(fromJson("[500,600,700]"), 2).getAsInt());
+ }
+
+ private JsonElement fromJson(String json) {
+ return gson.fromJson(json, JsonElement.class);
}
}
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 2a70f85a..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 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;
@@ -45,8 +48,11 @@ import java.nio.file.Files;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
+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;
@@ -64,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));
@@ -75,6 +110,32 @@ public class StandardCoderTest {
}
@Test
+ public void testEncodeObjectBoolean() throws Exception {
+ final List<Integer> arr = Arrays.asList(1100, 1110);
+
+ /*
+ * As plain json.
+ */
+ assertEquals("[1100,1110]", coder.encode(arr, false));
+
+ // test exception case
+ coder = spy(new StandardCoder());
+ when(coder.toJson(arr)).thenThrow(jpe);
+ assertThatThrownBy(() -> coder.encode(arr, false)).isInstanceOf(CoderException.class).hasCause(jpe);
+
+
+ /*
+ * As pretty json.
+ */
+ assertEquals("[\n 1100,\n 1110\n]", coder.encode(arr, true));
+
+ // test exception case
+ coder = spy(new StandardCoder());
+ when(coder.toPrettyJson(arr)).thenThrow(jpe);
+ assertThatThrownBy(() -> coder.encode(arr, true)).isInstanceOf(CoderException.class).hasCause(jpe);
+ }
+
+ @Test
public void testEncodeWriterObject() throws Exception {
List<Integer> arr = Arrays.asList(1200, 1210);
StringWriter wtr = new StringWriter();
@@ -260,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
@@ -281,16 +344,24 @@ public class StandardCoderTest {
assertEquals(-10, map.props.get("negInt"));
assertEquals(100000000000L, map.props.get("posLong"));
assertEquals(12.5, map.props.get("doubleVal"));
+
+ // test when decoding into a map
+ @SuppressWarnings("unchecked")
+ Map<String, Object> map2 = coder.decode("{'intValue':10, 'dblVal':20.1}", TreeMap.class);
+ assertEquals("{dblVal=20.1, intValue=10}", map2.toString());
+ }
+
+ @Test
+ public void testListDouble() throws Exception {
+ @SuppressWarnings("unchecked")
+ List<Object> list = coder.decode("[10, 20.1, 30]", LinkedList.class);
+ assertEquals("[10, 20.1, 30]", list.toString());
}
+ @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/StandardValCoderTest.java b/utils/src/test/java/org/onap/policy/common/utils/coder/StandardValCoderTest.java
new file mode 100644
index 00000000..2fcdb0dd
--- /dev/null
+++ b/utils/src/test/java/org/onap/policy/common/utils/coder/StandardValCoderTest.java
@@ -0,0 +1,165 @@
+/*
+ * ============LICENSE_START=======================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+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.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.worldturner.medeia.api.ValidationFailedException;
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.junit.Before;
+import org.junit.Test;
+
+public class StandardValCoderTest {
+ private String jsonSchema;
+ private String validJson;
+ private String missingReqJson;
+ private String badRegexJson;
+
+ @Data
+ @NoArgsConstructor
+ public static class ValOuter {
+ @Data
+ @NoArgsConstructor
+ public static class ValInner {
+ public String subItemString;
+ public Integer subItemInteger;
+ }
+
+ public String aaString;
+ public int anInteger;
+ public boolean aaBoolean;
+ public List<ValInner> aaCollection;
+ }
+
+ @Before
+ public void testSetUp() throws Exception {
+ jsonSchema = getJson("src/test/resources/org/onap/policy/common/utils/coder/test.schema.json");
+ validJson = getJson("src/test/resources/org/onap/policy/common/utils/coder/valid.json");
+ missingReqJson = getJson("src/test/resources/org/onap/policy/common/utils/coder/missing-required.json");
+ badRegexJson = getJson("src/test/resources/org/onap/policy/common/utils/coder/bad-regex.json");
+ }
+
+ @Test
+ public void testDecode() throws CoderException {
+ StandardValCoder valCoder = new StandardValCoder(jsonSchema, "test-schema");
+
+ ValOuter valOuter = valCoder.decode(validJson, ValOuter.class);
+ assertValidJson(valOuter);
+
+ StringReader reader = new StringReader(validJson);
+ valOuter = valCoder.decode(reader, ValOuter.class);
+ assertValidJson(valOuter);
+
+ try {
+ valCoder.decode(missingReqJson, ValOuter.class);
+ fail("missing required field should have been flagged by the schema validation");
+ } catch (CoderException e) {
+ assertEquals("required", ((ValidationFailedException) e.getCause()).getFailures().get(0).getRule());
+ assertEquals("aaCollection",
+ ((ValidationFailedException) e.getCause()).getFailures().get(0).getProperty());
+ assertEquals("Required property aaCollection is missing from object",
+ ((ValidationFailedException) e.getCause()).getFailures().get(0).getMessage());
+ }
+
+ try {
+ valCoder.decode(badRegexJson, ValOuter.class);
+ fail("bad regex should have been flagged by the schema validation");
+ } catch (CoderException e) {
+ assertEquals("properties", ((ValidationFailedException) e.getCause()).getFailures().get(0).getRule());
+ assertEquals("aaString",
+ ((ValidationFailedException) e.getCause()).getFailures().get(0).getProperty());
+ assertEquals("Property validation failed",
+ ((ValidationFailedException) e.getCause()).getFailures().get(0).getMessage());
+ assertEquals("pattern",
+ ((ValidationFailedException) e.getCause()).getFailures()
+ .get(0).getDetails().iterator().next().getRule());
+ assertEquals("Pattern ^([a-z]*)$ is not contained in text",
+ ((ValidationFailedException) e.getCause()).getFailures()
+ .get(0).getDetails().iterator().next().getMessage());
+ }
+ }
+
+ @Test
+ public void testEncode() throws CoderException {
+ StandardValCoder valCoder = new StandardValCoder(jsonSchema, "test-schema");
+ ValOuter valOuter = valCoder.decode(validJson, ValOuter.class);
+
+ String valOuterJson = valCoder.encode(valOuter);
+ assertEquals(valOuter, valCoder.decode(valOuterJson, ValOuter.class));
+ assertValidJson(valOuter);
+
+ StringWriter writer = new StringWriter();
+ valCoder.encode(writer, valOuter);
+ assertEquals(valOuterJson, writer.toString());
+
+ // test exception case with an empty object
+ assertThatThrownBy(() -> valCoder.encode(new ValOuter())).isInstanceOf(CoderException.class);
+ }
+
+ @Test
+ public void testPretty() throws CoderException {
+ StandardValCoder valCoder = new StandardValCoder(jsonSchema, "test-schema");
+ ValOuter valOuter = valCoder.decode(validJson, ValOuter.class);
+
+ String valOuterJson = valCoder.encode(valOuter);
+ assertEquals(valOuterJson, valCoder.encode(valOuter, false));
+ String prettyValOuterJson = valCoder.encode(valOuter, true);
+ assertNotEquals(valOuterJson, prettyValOuterJson);
+
+ assertEquals(valOuter, valCoder.decode(prettyValOuterJson, ValOuter.class));
+
+ // test exception cases with an empty object
+ assertThatThrownBy(() -> valCoder.encode(new ValOuter(), false)).isInstanceOf(CoderException.class);
+ assertThatThrownBy(() -> valCoder.encode(new ValOuter(), true)).isInstanceOf(CoderException.class);
+ }
+
+ @Test
+ public void testConformance() {
+ StandardValCoder valCoder = new StandardValCoder(jsonSchema, "test-schema");
+ assertTrue(valCoder.isConformant(validJson));
+ assertFalse(valCoder.isConformant(missingReqJson));
+ assertFalse(valCoder.isConformant(badRegexJson));
+ }
+
+ private void assertValidJson(ValOuter valOuter) {
+ assertEquals("abcd", valOuter.getAaString());
+ assertEquals(90, valOuter.getAnInteger());
+ assertTrue(valOuter.isAaBoolean());
+ assertEquals("defg", valOuter.getAaCollection().get(0).getSubItemString());
+ assertEquals(Integer.valueOf(1200), valOuter.getAaCollection().get(0).getSubItemInteger());
+ }
+
+ private String getJson(String filePath) throws IOException {
+ return new String(Files.readAllBytes(Paths.get(filePath)));
+ }
+} \ No newline at end of file
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 e38c5c9c..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
@@ -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.
@@ -20,8 +20,11 @@
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.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
import java.io.File;
import java.io.StringWriter;
@@ -45,6 +48,25 @@ public class StandardYamlCoderTest {
}
@Test
+ public void testToPrettyJson() throws CoderException {
+ String expected = coder.encode(cont);
+ assertEquals(expected, coder.encode(cont, false));
+
+ String yaml = coder.encode(cont, true);
+ assertEquals(expected, yaml);
+
+ Container cont2 = coder.decode(yaml, Container.class);
+ assertEquals(cont, cont2);
+
+ // test exception cases
+ IllegalArgumentException expex = new IllegalArgumentException("expected exception");
+ coder = spy(new StandardYamlCoder());
+ when(coder.toJson(cont)).thenThrow(expex);
+ assertThatThrownBy(() -> coder.encode(cont, false)).isInstanceOf(CoderException.class).hasCause(expex);
+ assertThatThrownBy(() -> coder.encode(cont, true)).isInstanceOf(CoderException.class).hasCause(expex);
+ }
+
+ @Test
public void testToJsonObject() throws CoderException {
String yaml = coder.encode(cont);
@@ -75,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 2991009f..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 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
@@ -321,26 +301,37 @@ public class ResourceUtilsTest {
Set<String> resultD0 = ResourceUtils.getDirectoryContents("testdir");
assertEquals(1, resultD0.size());
- assertEquals("testdir/testfile.xml", resultD0.iterator().next());
+ assertEquals("testdir/testfile.xml", normalizePath(resultD0.iterator().next()));
Set<String> resultD1 = ResourceUtils.getDirectoryContents("org/onap/policy/common");
- assertTrue(resultD1.size() > 0);
- assertEquals("org/onap/policy/common/utils/", resultD1.iterator().next());
+ 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", resultD2.iterator().next());
+ assertEquals("org/onap/policy/common/utils/coder/CoderExceptionTest.class",
+ normalizePath(resultD2.iterator().next()));
Set<String> resultJ0 = ResourceUtils.getDirectoryContents("com");
- assertEquals(189, resultJ0.size());
- assertEquals("com/google/", resultJ0.iterator().next());
+ 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", 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());
}
+
+ /**
+ * Normalizes a path name, replacing OS-specific separators with "/".
+ *
+ * @param pathName path name to be normalized
+ * @return the normalized path name
+ */
+ private String normalizePath(String pathName) {
+ return pathName.replace(File.separator, "/");
+ }
}
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/org/onap/policy/common/utils/coder/bad-regex.json b/utils/src/test/resources/org/onap/policy/common/utils/coder/bad-regex.json
new file mode 100644
index 00000000..049de2cf
--- /dev/null
+++ b/utils/src/test/resources/org/onap/policy/common/utils/coder/bad-regex.json
@@ -0,0 +1,9 @@
+{
+ "aaString": "abc123",
+ "anInteger": 90,
+ "aaBoolean": true,
+ "aaCollection": [ {
+ "subItemString": "defg",
+ "subItemInteger": 1200
+ }]
+} \ No newline at end of file
diff --git a/utils/src/test/resources/org/onap/policy/common/utils/coder/missing-required.json b/utils/src/test/resources/org/onap/policy/common/utils/coder/missing-required.json
new file mode 100644
index 00000000..e19db9db
--- /dev/null
+++ b/utils/src/test/resources/org/onap/policy/common/utils/coder/missing-required.json
@@ -0,0 +1,5 @@
+{
+ "aaString": "abcd",
+ "anInteger": 90,
+ "aaBoolean": true
+} \ No newline at end of file
diff --git a/utils/src/test/resources/org/onap/policy/common/utils/coder/test.schema.json b/utils/src/test/resources/org/onap/policy/common/utils/coder/test.schema.json
new file mode 100644
index 00000000..e79475eb
--- /dev/null
+++ b/utils/src/test/resources/org/onap/policy/common/utils/coder/test.schema.json
@@ -0,0 +1,71 @@
+{
+ "definitions": {},
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "http://onap.org/policy/common/coders/root.json",
+ "type": "object",
+ "title": "Test Schema",
+ "required": [
+ "aaString",
+ "anInteger",
+ "aaBoolean",
+ "aaCollection"
+ ],
+ "properties": {
+ "aaString": {
+ "$id": "#/properties/aaString",
+ "type": "string",
+ "title": "an alphabetical string",
+ "default": "",
+ "examples": [
+ "abcdef"
+ ],
+ "pattern": "^([a-z]*)$"
+ },
+ "anInteger": {
+ "$id": "#/properties/anInteger",
+ "type": "integer",
+ "title": "a bounded integer",
+ "default": 5,
+ "examples": [
+ 98
+ ],
+ "minimum": 10,
+ "maximum": 100
+ },
+ "aaBoolean": {
+ "$id": "#/properties/aaBoolean",
+ "type": "boolean",
+ "title": "a boolean",
+ "default": false,
+ "examples": [
+ true
+ ]
+ },
+ "aaCollection": {
+ "$id": "#/properties/aaCollection",
+ "type": "array",
+ "title": "a collection",
+ "items": {
+ "$id": "#/properties/aaCollection/items",
+ "type": "object",
+ "title": "the collection items",
+ "required": [
+ "subItemString"
+ ],
+ "properties": {
+ "subItemString": {
+ "$id": "#/properties/aaCollection/items/properties/subItemString",
+ "type": "string",
+ "title": "the subitem string",
+ "default": "blah",
+ "pattern": "^(.*)$"
+ },
+ "subItemInteger": {
+ "$id": "#/properties/aaCollection/items/properties/subItemInteger",
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/utils/src/test/resources/org/onap/policy/common/utils/coder/valid.json b/utils/src/test/resources/org/onap/policy/common/utils/coder/valid.json
new file mode 100644
index 00000000..c1738176
--- /dev/null
+++ b/utils/src/test/resources/org/onap/policy/common/utils/coder/valid.json
@@ -0,0 +1,9 @@
+{
+ "aaString": "abcd",
+ "anInteger": 90,
+ "aaBoolean": true,
+ "aaCollection": [ {
+ "subItemString": "defg",
+ "subItemInteger": 1200
+ }]
+} \ No newline at end of file
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.