aboutsummaryrefslogtreecommitdiffstats
AgeCommit message (Collapse)AuthorFilesLines
2023-04-13Merge "Remove "isTagged" mapping method"Priyank Maheshwari1-6/+1
2023-04-12Migrate query tests to integration-test module #5danielhanrahan6-25/+56
- Migrate query tests for composite keys to integration-test - Add addresses with composite key to bookstore model Issue-ID: CPS-1597 Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech> Change-Id: I6f8dfc2c44ae6ba3bac1cce804841671ef5a009d
2023-04-12Remove "isTagged" mapping methodlukegleeson1-6/+1
Remove redundant mapping method causing sonarqube violation Issue-ID: CPS-1394 Signed-off-by: lukegleeson <luke.gleeson@est.tech> Change-Id: Ie3ed1411c05fcc3671e547b80b41826dcd6e1fab
2023-04-12Merge "Expose endpoint to accept bulk request"Sourabh Sourabh8-2/+55
2023-04-12Migrate query tests to integration-test module #3danielhanrahan4-24/+35
Issue-ID: CPS-1597 Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech> Change-Id: I1d92355f272271424a7014057d251cf88eac0203
2023-04-12Merge "Migrate query tests to integration-test module #2"Sourabh Sourabh7-110/+143
2023-04-11Performance tests for getDataNodes and queryDataNodesdanielhanrahan6-10135/+568
- Generate openroadm data from a single innerNode.json template - Double the number of openroadm device nodes (25 -> 50) in tests - Add new performance tests for getDataNodes and queryDataNodes to integration-test module, using openroadm and bookstore data - Remove old performance tests from cps-ri Issue-ID: CPS-1524 Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech> Change-Id: Id9ec2a86d984d6c50c9ae6093e7a62729cb851da
2023-04-11Migrate query tests to integration-test module #2danielhanrahan7-110/+143
- Migrate some query tests to integration-test - Edit bookstore model to add integer leaf-list 'editions' - Lower cps-ri code coverage Issue-ID: CPS-1597 Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech> Change-Id: If50bf15ad7d7f147448f6b60d464efc1cdc91005
2023-04-11Merge "Migrate query tests to integration-test module #1"Toine Siebelink2-56/+43
2023-04-11Merge "Populate Dataspace field of DataNode"Toine Siebelink3-2/+27
2023-04-11Migrate query tests to integration-test module #1danielhanrahan2-56/+43
Issue-ID: CPS-1597 Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech> Change-Id: I0403641e2e5293571c61a58aa2b67b144cf68ac4
2023-04-11Merge "[CPS] Fix SonarQube Violations / Improve Coverage - Recurring task"Toine Siebelink2-21/+29
2023-04-11[CPS] Fix SonarQube Violations / Improve Coverage - Recurring taskraviteja.karumuri2-21/+29
Issue-ID: CPS-475 Signed-off-by: raviteja.karumuri <raviteja.karumuri@est.tech> Change-Id: I7429e1563608159b5592a2dc52ab5383f11a8ab3
2023-04-11Populate Dataspace field of DataNodedanielhanrahan3-2/+27
Issue-ID: CPS-1603 Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech> Change-Id: I85aca8bccc28d36aa4cefa0a32cb9bdf2156618a
2023-04-11Merge "Migrate query tests to integration-test module #4"Sourabh Sourabh2-35/+50
2023-04-07[CPS] Bump minor version - Step12mpriyank19-20/+20
- bump minor cps version from 3.2.7-SNAPSHOT to 3.3.0-SNAPSHOT which is step11 of the release process Issue-ID: CPS-1610 Change-Id: I74f20a7a7fa1edad417c40a09a60fecc0a96ccb7 Signed-off-by: mpriyank <priyank.maheshwari@est.tech>
2023-04-06Toggle subscription persistence for model loaderlukegleeson2-6/+15
Current implementation will attempt to persist the subscription model for subscription create events even when the model loader is disabled which causes a persistence error. Subscription Model will now be persisted based on whether the model loader is enabled Issue-ID: CPS-1394 Signed-off-by: lukegleeson <luke.gleeson@est.tech> Change-Id: I8f8cfc47996eed6b95fd3958996f16c8395dc341
2023-04-05Migrate query tests to integration-test module #4danielhanrahan2-35/+50
Issue-ID: CPS-1597 Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech> Change-Id: Id3b4a3829b6f9aec1a649ed0001d7c11db91ccfe
2023-04-05Expose endpoint to accept bulk requestleventecsanyi8-2/+55
- added wiremock mapping for testing/demo Issue-ID: CPS-1555 Change-Id: I82af6c43e80a346efcd84aae8945572aa37a6875 Signed-off-by: leventecsanyi <levente.csanyi@est.tech>
2023-04-04Merge "Add Query Spec to integration-test package"Priyank Maheshwari1-0/+48
2023-04-04Merge "500 Error Response on NCMP ID-Searches Testing"Luke Gleeson1-1/+43
2023-04-04Add Query Spec to integration-test packagelukegleeson1-0/+48
Issue-ID: CPS-1598 Signed-off-by: lukegleeson <luke.gleeson@est.tech> Change-Id: Ifab8863eae4a3ee07ba3d6096e73f9f98077584d
2023-04-03Merge "Persist SubscriptionEvent"Priyank Maheshwari12-20/+430
2023-04-03500 Error Response on NCMP ID-Searches Testingseanbeirne1-1/+43
Issue-ID: CPS-1563 Signed-off-by: seanbeirne <sean.beirne@est.tech> Change-Id: Idc393e90d31b369095bc2b122537e17a4464a364
2023-03-31Remove docs/conf.yamldanielhanrahan1-25/+0
Change to ONAP pipeline is causing docs-rules job to fail if docs/conf.yaml file exists. So we remove it. Issue-ID: CPS-1596 Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech> Change-Id: I4aa576c698162b2a99ca1459d9d192b88c3ac9b6
2023-03-30Merge "Update performance test timings"Toine Siebelink2-28/+28
2023-03-30Merge "[CPS] Improve code coverage for Class 'SubscriptionModelLoader'"Toine Siebelink2-57/+68
2023-03-30Persist SubscriptionEventlukegleeson12-20/+430
- Updated subscription.yang to subscription name instead of client name - Implemented Mapper for SubscriptionEvent to yang model version - Implemented Subscription Persistence for storing subscriptions - Minor changes to existing variable names Issue-ID: CPS-1394 Signed-off-by: lukegleeson <luke.gleeson@est.tech> Change-Id: Ibe066006a913cb7f6e52b6fa8a851e976a338ac3
2023-03-30Fix assertion in integration-test performance testsdanielhanrahan1-1/+1
Issue-ID: CPS-1587 Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech> Change-Id: I044e4c81ce9972bb7979b494496d74beb733c5ed
2023-03-30Update performance test timingsdanielhanrahan2-28/+28
Issue-ID: CPS-1524 Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech> Change-Id: Iaa8e9a0ca3170a2b487df312834245d609fdfe13
2023-03-30[CPS] Improve code coverage for Class 'SubscriptionModelLoader'raviteja.karumuri2-57/+68
Issue-ID: CPS-1584 Signed-off-by: raviteja.karumuri <raviteja.karumuri@est.tech> Change-Id: Ief2b14cc90c24db50a95f1c62661b1918413408e
2023-03-28[CPS] Fix SonarQube Violations / Improve Coverage - Recurring taskraviteja.karumuri1-7/+21
Issue-ID: CPS-475 Signed-off-by: raviteja.karumuri <raviteja.karumuri@est.tech> Change-Id: Id3507fb24c4c6eb002a9ae6fed553daa2fca7895
2023-03-27Enhanced logging for bugmpriyank1-3/+4
- Added minor logging and temporarily converted some debug logs to info level Issue-ID: CPS-1566 Change-Id: I2c706ecd601b06f2a92388b318a44640c682bdd1 Signed-off-by: mpriyank <priyank.maheshwari@est.tech>
2023-03-27Merge "Fixes for CM-handle de-registration test script"Toine Siebelink3-14/+7
2023-03-23Prepare the next drop by bumping patch versionhalil.cakal20-19/+48
- Bumping modules up to 3.2.7-SNAPSHOT - Update version.properties and release notes Issue-ID: CPS-1577 Change-Id: Ib223c8bea164c42caceaba31a13f43c77d55c48c Signed-off-by: halil.cakal <halil.cakal@est.tech>
2023-03-23Merge "Add 3.2.6-container.yaml file to releases folder"Priyank Maheshwari1-0/+8
2023-03-23Add 3.2.6-container.yaml file to releases folderhalil.cakal1-0/+8
- Add container yaml for cps maven docker stage master Issue-ID: CPS-1576 Change-Id: Iee530e0cd679f98013475b1d706d8d217dd074fa Signed-off-by: halil.cakal <halil.cakal@est.tech>
2023-03-23Add 3.2.6.yaml file to releases folderhalil.cakal1-0/+4
- Add yaml file for cps maven stage master Issue-ID: CPS-1575 Change-Id: I04b2285b4011c72dd8b15008d271bdaf5852271c Signed-off-by: halil.cakal <halil.cakal@est.tech>
2023-03-22NCMP Inventory documentation updateseanbeirne5-11/+189
- Updated release notes Issue-ID: CPS-1494 Signed-off-by: seanbeirne <sean.beirne@est.tech> Change-Id: I43fc285da9d6699326d5e0a933fdb3c5c7abcb12
2023-03-22Fixes for CM-handle de-registration test scriptdanielhanrahan3-14/+7
- Fixed dmi-plugin-stub port - Removed unneeded test cases - Added pushd/popd so script can be run from any directory - Added metrics-reports to .gitignore Issue-ID: CPS-1552 Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech> Change-Id: I0ff3549449687a919faf1c2f3172fbea6178a658
2023-03-22Merge "500 Error Reponse on NCMP inventory cmhandle search"Luke Gleeson1-1/+4
2023-03-22500 Error Reponse on NCMP inventory cmhandle searchseanbeirne1-1/+4
Issue-ID: CPS-1563 Signed-off-by: seanbeirne <sean.beirne@est.tech> Change-Id: I5579e8e852c20ce61a6684140198e989f7876d79
2023-03-22Update documnetationmpriyank2-760/+783
- update release notes and sync the openapi specs as per the latest changes Issue-ID: CPS-1572 Change-Id: I1dedad736664e3bdd164ba371270c1cf4586515d Signed-off-by: mpriyank <priyank.maheshwari@est.tech>
2023-03-22Merge "Subscription model with status and predicates"Priyank Maheshwari1-4/+19
2023-03-22Merge "Add event to mapper as well"Luke Gleeson5-4/+13
2023-03-22Merge "Query data nodes across all anchors under one dataspace"Priyank Maheshwari22-11/+448
2023-03-21Subscription model with status and predicatesemaclee1-4/+19
Issue-ID: CPS-1497 Signed-off-by: emaclee <lee.anjella.macabuhay@est.tech> Change-Id: I4a81389797620eac9b67f31ddcbb4d5168d742ce
2023-03-21Add event to mapper as wellmpriyank5-4/+13
- Explicitly add event to the mapper - Also parameterized the cm-events topic to be overridden later Issue-ID: CPS-1554 Change-Id: Ia6e75117dbb4214648d40318989c4c5fe6fd69f1 Signed-off-by: mpriyank <priyank.maheshwari@est.tech>
2023-03-21Query data nodes across all anchors under one dataspacerajesh.kumar22-11/+448
Issue-ID: CPS-1396 Change-ID: I73f97f986a817d423f93a8d922dcd9647b1412ab Signed-off-by: rajesh.kumar <rk00747546@techmahindra.com>
2023-03-20Script to fully automate CM-handle de-registrationsourabh_sourabh1-0/+162
Issue-ID: CPS-1552 Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech> Change-Id: Ie1ea0cf410f78f1a8675c30d2e278a407afc0d0a Signed-off-by: sourabh_sourabh <sourabh.sourabh@est.tech>
java.util.Optional; import java.util.Queue; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedTransferQueue; import java.util.concurrent.TransferQueue; import java.util.function.Predicate; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import static java.util.Optional.ofNullable; import static org.onap.config.api.Hint.EXTERNAL_LOOKUP; import static org.onap.config.api.Hint.LATEST_LOOKUP; import static org.onap.config.api.Hint.NODE_SPECIFIC; public class ConfigurationUtils { private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationUtils.class); private static final String CONFIGURATION_TYPE_NOT_SUPPORTED = "Configuration type not supported:"; private static final Map<Class<?>, Class<?>> ARRAY_CLASS_MAP; private static final String CONFIG_REGEX_TPL_OPT_1 = "CONFIG(-\\w*){0,1}(-(%s|%s|%s)){0,1}\\.(%s|%s|%s|%s)$"; private static final String CONFIG_REGEX_TPL_OPT_2 = "CONFIG(.)*\\.(%s|%s|%s|%s)$"; static { Map<Class<?>, Class<?>> arrayTypes = new HashMap<>(); arrayTypes.put(Byte.class, Byte[].class); arrayTypes.put(Short.class, Short[].class); arrayTypes.put(Integer.class, Integer[].class); arrayTypes.put(Long.class, Long[].class); arrayTypes.put(Float.class, Float[].class); arrayTypes.put(Double.class, Double[].class); arrayTypes.put(Boolean.class, Boolean[].class); arrayTypes.put(Character.class, Character[].class); arrayTypes.put(String.class, String[].class); ARRAY_CLASS_MAP = Collections.unmodifiableMap(arrayTypes); } private ConfigurationUtils() { // prevent instantiation } public static Collection<File> getAllFiles(File file, boolean recursive, boolean onlyDirectory) { ArrayList<File> collection = new ArrayList<>(); Path rootPath = file.toPath(); try { Files.walkFileTree(rootPath, new SimpleFileVisitor<Path>() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { super.preVisitDirectory(dir,attrs); if (rootPath.equals(dir)) { return FileVisitResult.CONTINUE; } collection.add(dir.toFile()); return recursive? FileVisitResult.CONTINUE : FileVisitResult.SKIP_SUBTREE; } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { super.visitFile(file, attrs); if (!onlyDirectory) { collection.add(file.toFile()); } return FileVisitResult.CONTINUE; } }); } catch (IOException e) { LOGGER.error("Failed to walk through directories starting from: {}.", file.toString(), e); } return collection; } public static String getCommaSeparatedList(String[] list) { return (list == null) || (list.length == 0) ? "" : getCommaSeparatedList(Arrays.asList(list)); } public static String getCommaSeparatedList(List<?> list) { if ((list == null) || list.isEmpty()) { return ""; } return list.stream().filter(o -> o != null && !o.toString().trim().isEmpty()) .map(o -> o.toString().trim()).collect(Collectors.joining(",")); } public static boolean isConfig(URL url) { return isConfig(url.getFile()); } public static boolean isConfig(String file) { file = file.toUpperCase().substring(file.lastIndexOf('!') + 1); file = file.substring(file.lastIndexOf('/') + 1); return file.matches( String.format( CONFIG_REGEX_TPL_OPT_1, ConfigurationMode.OVERRIDE, ConfigurationMode.MERGE, ConfigurationMode.UNION, ConfigurationType.PROPERTIES.name(), ConfigurationType.XML.name(), ConfigurationType.JSON.name(), ConfigurationType.YAML.name() ) ) || file.matches( String.format( CONFIG_REGEX_TPL_OPT_2, ConfigurationType.PROPERTIES.name(), ConfigurationType.XML.name(), ConfigurationType.JSON.name(), ConfigurationType.YAML.name() ) ); } public static boolean isConfig(File file) { return file != null && file.exists() && isConfig(file.getName()); } private static Optional<String> readNamespace(Configuration config) { return ofNullable(config).flatMap(configuration -> ofNullable(configuration.getString(Constants.NAMESPACE_KEY))) .map(String::toUpperCase); } private static Optional<String> readMergeStrategy(Configuration config) { return ofNullable(config).flatMap(configuration -> ofNullable(configuration.getString(Constants.MODE_KEY))) .map(String::toUpperCase); } public static ConfigurationMode getMergeStrategy(File file) { Optional<ConfigurationMode> configurationMode = getConfiguration(file).flatMap(ConfigurationUtils::readMergeStrategy) .flatMap(ConfigurationUtils::convertConfigurationMode); return configurationMode.orElseGet(() -> getMergeStrategy(file.getName().toUpperCase())); } public static ConfigurationMode getMergeStrategy(URL url) { Optional<ConfigurationMode> configurationMode = getConfiguration(url).flatMap(ConfigurationUtils::readMergeStrategy) .flatMap(ConfigurationUtils::convertConfigurationMode); return configurationMode.orElseGet(() -> getMergeStrategy(url.getFile().toUpperCase())); } public static ConfigurationMode getMergeStrategy(String file) { file = file.toUpperCase().substring(file.lastIndexOf('!') + 1); file = file.substring(file.lastIndexOf('/') + 1); Pattern pattern = Pattern.compile( String.format( CONFIG_REGEX_TPL_OPT_1, ConfigurationMode.OVERRIDE, ConfigurationMode.MERGE, ConfigurationMode.UNION, ConfigurationType.PROPERTIES.name(), ConfigurationType.XML.name(), ConfigurationType.JSON.name(), ConfigurationType.YAML.name() ) ); Matcher matcher = pattern.matcher(file); boolean b1 = matcher.matches(); if (b1) { for (int i = 1; i <= matcher.groupCount(); i++) { String modeName = matcher.group(i); if (modeName != null) { modeName = modeName.substring(1); } try { return Enum.valueOf(ConfigurationMode.class, modeName); } catch (Exception exception) { LOGGER.debug("Configuration mode for merge strategy '{}' not found", modeName, exception); } } } return null; } public static Optional<FileBasedConfiguration> getConfiguration(URL url) { try { ConfigurationType configType = ConfigurationUtils.getConfigType(url); switch (configType) { case PROPERTIES: return Optional.of(new Configurations().fileBased(PropertiesConfiguration.class, url)); case XML: return Optional.of(new Configurations().fileBased(XMLConfiguration.class, url)); case JSON: return Optional.of(new Configurations().fileBased(JsonConfiguration.class, url)); case YAML: return Optional.of(new Configurations().fileBased(YamlConfiguration.class, url)); default: throw new ConfigurationException(CONFIGURATION_TYPE_NOT_SUPPORTED + configType); } } catch (ConfigurationException exception) { LOGGER.error("Error reading configuration at {}.", url.toString(), exception); } return Optional.empty(); } public static Optional<FileBasedConfiguration> getConfiguration(File file) { try { return getConfiguration(file.getAbsoluteFile().toURI().toURL()); } catch (MalformedURLException e) { throw new IllegalStateException("Malformed URL: " + file.getAbsolutePath()); } } public static ConfigurationType getConfigType(File file) { Objects.requireNonNull(file, "File cannot be null"); return Enum.valueOf(ConfigurationType.class, file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf('.') + 1).toUpperCase()); } public static ConfigurationType getConfigType(URL url) { Objects.requireNonNull(url, "URL cannot be null"); return Enum.valueOf(ConfigurationType.class, url.getFile().substring(url.getFile().lastIndexOf('.') + 1).toUpperCase()); } private static Optional<ConfigurationMode> convertConfigurationMode(String configMode) { ConfigurationMode configurationMode = null; try { configurationMode = ConfigurationMode.valueOf(configMode); } catch (Exception exception) { LOGGER.error("Could not find convert {} into configuration mode.", configMode, exception); } return Optional.ofNullable(configurationMode); } public static Class<?> getCollectionGenericType(Field field) { Type type = field.getGenericType(); if (type instanceof ParameterizedType) { ParameterizedType paramType = (ParameterizedType) type; Type[] arr = paramType.getActualTypeArguments(); if (arr.length > 0) { Class<?> clazz = (Class<?>) arr[0]; if (isWrapperClass(clazz)) { return clazz; } else { throw new IllegalArgumentException("Collection of type " + clazz.getName() + " not supported."); } } } return String[].class; } public static boolean isWrapperClass(Class<?> clazz) { Predicate<Class<?>> predicateWrapper = type -> type == String.class || type == Boolean.class || type == Character.class || Number.class.isAssignableFrom(type); return isA(predicateWrapper, clazz); } public static boolean isAPrimitive(Class<?> clazz) { return isA(Class::isPrimitive, clazz); } /** * Check if clazz implementing Map iface */ public static boolean isAMap(Class<?> clazz) { Predicate<Class<?>> predicateMap = Map.class::isAssignableFrom; return isA(predicateMap, clazz); } /** * Check if clazz implementing Collection iface */ public static boolean isACollection(Class<?> clazz) { Predicate<Class<?>> predicateCollection = Collection.class::isAssignableFrom; return isA(predicateCollection, clazz); } /** * Check if clazz is a primitive or primitive wrapper */ public static boolean isAPrimitiveOrWrapper(Class<?> clazz) { Predicate<Class<?>> predicatePrimitive = Class::isPrimitive; Predicate<Class<?>> predicateWrapper = ConfigurationUtils::isWrapperClass; return isA(predicatePrimitive.or(predicateWrapper), clazz); } /** * Check if clazz is array of primitives or array of primitives wrappers */ public static boolean isAPrimitivesOrWrappersArray(Class<?> clazz) { Predicate<Class<?>> predicatePrimitivesOrWrappersArray = type -> ConfigurationUtils.isAWrappersArray(type) || ConfigurationUtils.isAPrimitivesArray(type); return isA(predicatePrimitivesOrWrappersArray, clazz); } /** * Check is clazz is array of primitives */ public static boolean isAPrimitivesArray(Class<?> clazz) { Predicate<Class<?>> predicateArray = Class::isArray; Predicate<Class<?>> predicateComponentPrimitive = type -> type.getComponentType().isPrimitive(); return isA(predicateArray.and(predicateComponentPrimitive), clazz); } /** * Check is clazz is array of primitives wrappers */ public static boolean isAWrappersArray(Class<?> clazz) { Predicate<Class<?>> predicateArray = Class::isArray; Predicate<Class<?>> predicateComponentWrapper = type -> isWrapperClass(type.getComponentType()); return isA(predicateArray.and(predicateComponentWrapper), clazz); } private static boolean isA(Predicate<Class<?>> predicate, Class<?> clazz) { return predicate.test(clazz); } public static Class<?> getArrayClass(Class<?> clazz) { return ARRAY_CLASS_MAP.getOrDefault(clazz, null); } public static List<URL> getAllClassPathResources() { try (ScanResult scanResult = new ClassGraph().scan()) { return scanResult.getAllResources().getURLs(); } } public static BasicConfigurationBuilder<FileBasedConfiguration> getConfigurationBuilder(File file) { FileBasedConfigurationBuilder<FileBasedConfiguration> builder; ConfigurationType configType = ConfigurationUtils.getConfigType(file); builder = getFileBasedConfigurationBuilder(configType); builder.configure(new Parameters().fileBased().setFile(file) .setListDelimiterHandler(new DefaultListDelimiterHandler(','))); return builder; } public static BasicConfigurationBuilder<FileBasedConfiguration> getConfigurationBuilder(URL url) { ConfigurationType configType = ConfigurationUtils.getConfigType(url); ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> builder = getFileBasedConfigurationBuilder(configType); builder.configure( new Parameters().fileBased().setURL(url).setListDelimiterHandler(new DefaultListDelimiterHandler(','))); return builder; } private static ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> getFileBasedConfigurationBuilder( ConfigurationType configType) { ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> builder; switch (configType) { case PROPERTIES: builder = new ReloadingFileBasedConfigurationBuilder<>(PropertiesConfiguration.class); break; case XML: builder = new ReloadingFileBasedConfigurationBuilder<>(XMLConfiguration.class); break; case JSON: builder = new ReloadingFileBasedConfigurationBuilder<>(JsonConfiguration.class); break; case YAML: builder = new ReloadingFileBasedConfigurationBuilder<>(YamlConfiguration.class); break; default: throw new IllegalArgumentException(CONFIGURATION_TYPE_NOT_SUPPORTED + configType); } return builder; } public static <T> T read(Configuration config, Class<T> clazz, String keyPrefix) throws Exception { Config confAnnotation = clazz.getAnnotation(Config.class); if (confAnnotation != null) { keyPrefix += (confAnnotation.key() + "."); } T objToReturn = clazz.newInstance(); for (Field field : clazz.getDeclaredFields()) { Config fieldAnnotation = field.getAnnotation(Config.class); if (fieldAnnotation != null) { field.setAccessible(true); field.set(objToReturn, config.getProperty(keyPrefix + fieldAnnotation.key())); } else if (field.getType().getAnnotation(Config.class) != null) { field.set(objToReturn, read(config, field.getType(), keyPrefix)); } } return objToReturn; } public static Object getPrimitiveArray(Collection<?> collection, Class<?> clazz) { switch (clazz.getName()) { case "int": return getIntsPrimitiveArray(collection); case "byte": return getBytesPrimitiveArray(collection); case "short": return getShortsPrimitiveArray(collection); case "long": return getLongsPrimitiveArray(collection); case "float": return getFloatsPrimitiveArray(collection); case "double": return getDoublesPrimitiveArray(collection); case "boolean": return getBooleansPrimitiveArray(collection); case "char": return getCharsPrimitiveArray(collection); default: return null; } } public static Object getWrappersArray(Collection<?> collection, Class<?> clazz) { Object array = null; if (isWrapperClass(clazz)){ int collectionSize = collection.size(); array = Array.newInstance(clazz, collection.size()); Object[] objArray = collection.toArray(); System.arraycopy(objArray, 0, array, 0, collectionSize); } return array; } public static String getCollectionString(String input) { Pattern pattern = Pattern.compile("^\\[(.*)\\]$"); Matcher matcher = pattern.matcher(input); if (matcher.matches()) { input = matcher.group(1); } return input; } public static String processVariablesIfPresent(String tenant, String namespace, String data) { Pattern pattern = Pattern.compile("^.*\\$\\{(.*)\\}.*"); Matcher matcher = pattern.matcher(data); if (matcher.matches()) { final int substringStartIndex = 4; String key = matcher.group(1); String value; if (key.toUpperCase().startsWith("ENV:")) { value = System.getenv(key.substring(substringStartIndex)); } else if (key.toUpperCase().startsWith("SYS:")) { value = System.getProperty(key.substring(substringStartIndex)); } else { value = ConfigurationUtils.getCollectionString( ConfigurationManager.lookup().getAsStringValues(tenant, namespace, key).toString()); } return processVariablesIfPresent(tenant, namespace, data.replaceAll("\\$\\{" + key + "}", value == null ? "" : value.replace("\\", "\\\\"))); } else { return data; } } public static String getFileContents(String path) { try { if (path != null) { return IOUtils.toString(new URL(path), Charset.defaultCharset()); } } catch (Exception exception) { LOGGER.error("Error while getting '{}' content", path, exception); } return null; } public static String getFileContents(Path path) { try { if (path != null) { return new String(Files.readAllBytes(path)); } } catch (Exception exception) { LOGGER.error("Error while getting '{}' content", path.toString(), exception); } return null; } public static Object getDefaultFor(Class<?> clazz) { if (byte.class == clazz) { return new Byte("0"); } else if (short.class == clazz) { return new Short("0"); } else if (int.class == clazz) { return new Integer("0"); } else if (float.class == clazz) { return new Float("0"); } else if (long.class == clazz) { return new Long("0"); } else if (double.class == clazz) { return new Double("0"); } else if (boolean.class == clazz) { return Boolean.FALSE; } return (char) 0; } public static Collection getCompatibleCollectionForAbstractDef(Class<?> clazz) { if (TransferQueue.class.isAssignableFrom(clazz)) { return getConcreteCollection(TransferQueue.class); } if (BlockingQueue.class.isAssignableFrom(clazz)) { return getConcreteCollection(BlockingQueue.class); } if (Deque.class.isAssignableFrom(clazz)) { return getConcreteCollection(Deque.class); } if (Queue.class.isAssignableFrom(clazz)) { return getConcreteCollection(Queue.class); } if (SortedSet.class.isAssignableFrom(clazz)) { return getConcreteCollection(SortedSet.class); } if (Set.class.isAssignableFrom(clazz)) { return getConcreteCollection(Set.class); } if (List.class.isAssignableFrom(clazz)) { return getConcreteCollection(List.class); } throw new IllegalArgumentException("Only corresponding array classes and any are allowed as argument." + "assignable from TransferQueue, BlockingQueue, Deque, Queue, SortedSet, Set, List class"); } public static Collection getConcreteCollection(Class<?> clazz) { switch (clazz.getName()) { case "java.util.Collection": case "java.util.List": return new ArrayList<>(); case "java.util.Set": return new HashSet<>(); case "java.util.SortedSet": return new TreeSet<>(); case "java.util.Queue": return new ConcurrentLinkedQueue<>(); case "java.util.Deque": return new ArrayDeque<>(); case "java.util.concurrent.TransferQueue": return new LinkedTransferQueue<>(); case "java.util.concurrent.BlockingQueue": return new LinkedBlockingQueue<>(); default: throw new IllegalArgumentException("Only corresponding array classes and any are allowed as argument." + "assignable from TransferQueue, BlockingQueue, Deque, Queue, SortedSet, Set, List class"); } } public static String getConfigurationRepositoryKey(File file) { return getConfigurationRepositoryKey( ConfigurationUtils.getNamespace(file).split(Constants.TENANT_NAMESPACE_SEPARATOR)); } public static String getConfigurationRepositoryKey(URL url) { return getConfigurationRepositoryKey( ConfigurationUtils.getNamespace(url).split(Constants.TENANT_NAMESPACE_SEPARATOR)); } public static String getConfigurationRepositoryKey(String[] array) { Deque<String> stack = new ArrayDeque<>(); stack.push(Constants.DEFAULT_TENANT); for (String element : array) { stack.push(element); } String toReturn = stack.pop(); return stack.pop() + Constants.KEY_ELEMENTS_DELIMITER + toReturn; } public static String getNamespace(File file) { Optional<String> namespace = getConfiguration(file).flatMap(ConfigurationUtils::readNamespace).map(String::toUpperCase); return namespace.orElseGet(() -> getNamespace(file.getName().toUpperCase())); } public static String getNamespace(String file) { file = file.toUpperCase().substring(file.lastIndexOf('!') + 1); file = file.substring(file.lastIndexOf('/') + 1); Pattern pattern = Pattern.compile( String.format( CONFIG_REGEX_TPL_OPT_1, ConfigurationMode.OVERRIDE, ConfigurationMode.MERGE, ConfigurationMode.UNION, ConfigurationType.PROPERTIES.name(), ConfigurationType.XML.name(), ConfigurationType.JSON.name(), ConfigurationType.YAML.name() ) ); Matcher matcher = pattern.matcher(file); boolean b1 = matcher.matches(); if (b1) { if (matcher.group(1) != null) { String moduleName = matcher.group(1).substring(1); return moduleName.equalsIgnoreCase(ConfigurationMode.OVERRIDE.name()) || moduleName.equalsIgnoreCase( ConfigurationMode.UNION.name()) || moduleName.equalsIgnoreCase(ConfigurationMode.MERGE.name()) ? Constants.DEFAULT_NAMESPACE : moduleName; } else { return Constants.DEFAULT_NAMESPACE; } } else if (isConfig(file)) { return Constants.DEFAULT_NAMESPACE; } return null; } public static String getNamespace(URL url) { Optional<String> namespace = getConfiguration(url).flatMap(ConfigurationUtils::readNamespace).map(String::toUpperCase); return namespace.orElseGet(() -> getNamespace(url.getFile().toUpperCase())); } public static Object getProperty(Configuration config, String key, int processingHints) { if (!isDirectLookup(processingHints) && isNodeSpecific(processingHints) && (config instanceof CompositeConfiguration)) { CompositeConfiguration conf = (CompositeConfiguration) config; for (int i = 0; i < conf.getNumberOfConfigurations(); i++) { Object obj = conf.getConfiguration(i).getProperty(key); if (obj != null) { return obj; } } } return config.getProperty(key); } public static boolean isCollection(String input) { Pattern pattern = Pattern.compile("^\\[(.*)\\]$"); Matcher matcher = pattern.matcher(input); return matcher.matches(); } public static boolean isDirectLookup(int hints) { return (hints & LATEST_LOOKUP.value()) == LATEST_LOOKUP.value(); } public static boolean isNodeSpecific(int hints) { return (hints & NODE_SPECIFIC.value()) == NODE_SPECIFIC.value(); } public static boolean isExternalLookup(int hints) { return (hints & EXTERNAL_LOOKUP.value()) == EXTERNAL_LOOKUP.value(); } public static boolean isZeroLengthArray(Class<?> clazz, Object obj) { if (isAPrimitivesArray(clazz)) { if (clazz.getComponentType() == int.class) { return ((int[]) obj).length == 0; } else if (clazz.getComponentType() == byte.class) { return ((byte[]) obj).length == 0; } else if (clazz.getComponentType() == short.class) { return ((short[]) obj).length == 0; } else if (clazz.getComponentType() == float.class) { return ((float[]) obj).length == 0; } else if (clazz.getComponentType() == boolean.class) { return ((boolean[]) obj).length == 0; } else if (clazz.getComponentType() == double.class) { return ((double[]) obj).length == 0; } else if (clazz.getComponentType() == long.class) { return ((long[]) obj).length == 0; } else { return ((Object[]) obj).length == 0; } } return false; } public static boolean isBlank(String value) { return value == null || value.trim().isEmpty(); } // private methods section starts here private static int[] getIntsPrimitiveArray(Collection<?> collection) { int collectionSize = collection.size(); int[] array = new int[collectionSize]; Object[] objArray = collection.toArray(); for (int i = 0; i < collectionSize; i++) { array[i] = (int) objArray[i]; } return array; } private static byte[] getBytesPrimitiveArray(Collection<?> collection) { int collectionSize = collection.size(); byte[] array = new byte[collectionSize]; Object[] objArray = collection.toArray(); for (int i = 0; i < collectionSize; i++) { array[i] = (byte) objArray[i]; } return array; } private static short[] getShortsPrimitiveArray(Collection<?> collection) { int collectionSize = collection.size(); short[] array = new short[collectionSize]; Object[] objArray = collection.toArray(); for (int i = 0; i < collectionSize; i++) { array[i] = (short) objArray[i]; } return array; } private static long[] getLongsPrimitiveArray(Collection<?> collection) { int collectionSize = collection.size(); long[] array = new long[collectionSize]; Object[] objArray = collection.toArray(); for (int i = 0; i < collectionSize; i++) { array[i] = (long) objArray[i]; } return array; } private static float[] getFloatsPrimitiveArray(Collection<?> collection) { int collectionSize = collection.size(); float[] array = new float[collectionSize]; Object[] objArray = collection.toArray(); for (int i = 0; i < collectionSize; i++) { array[i] = (float) objArray[i]; } return array; } private static double[] getDoublesPrimitiveArray(Collection<?> collection) { int collectionSize = collection.size(); double[] array = new double[collectionSize]; Object[] objArray = collection.toArray(); for (int i = 0; i < collectionSize; i++) { array[i] = (double) objArray[i]; } return array; } private static boolean[] getBooleansPrimitiveArray(Collection<?> collection) { int collectionSize = collection.size(); boolean[] array = new boolean[collectionSize]; Object[] objArray = collection.toArray(); for (int i = 0; i < collectionSize; i++) { array[i] = (boolean) objArray[i]; } return array; } private static char[] getCharsPrimitiveArray(Collection<?> collection) { int collectionSize = collection.size(); char[] array = new char[collectionSize]; Object[] objArray = collection.toArray(); for (int i = 0; i < collectionSize; i++) { array[i] = (char) objArray[i]; } return array; } }