diff --git a/node_modules/.pnpm-workspace-state.json b/node_modules/.pnpm-workspace-state.json new file mode 100644 index 0000000..f416e62 --- /dev/null +++ b/node_modules/.pnpm-workspace-state.json @@ -0,0 +1,25 @@ +{ + "lastValidatedTimestamp": 1750960559706, + "projects": {}, + "pnpmfileExists": false, + "settings": { + "autoInstallPeers": true, + "dedupeDirectDeps": false, + "dedupeInjectedDeps": true, + "dedupePeerDependents": true, + "dev": true, + "excludeLinksFromLockfile": false, + "hoistPattern": [ + "*" + ], + "hoistWorkspacePackages": true, + "injectWorkspacePackages": false, + "linkWorkspacePackages": false, + "nodeLinker": "isolated", + "optional": true, + "preferWorkspacePackages": false, + "production": true, + "publicHoistPattern": [] + }, + "filteredInstall": false +} diff --git a/node_modules/.pnpm/lock.yaml b/node_modules/.pnpm/lock.yaml new file mode 100644 index 0000000..c65e7f9 --- /dev/null +++ b/node_modules/.pnpm/lock.yaml @@ -0,0 +1,16 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + pricing4ts: link:../../../../../Library/pnpm/global/5/node_modules/pricing4ts + +importers: + + .: + dependencies: + pricing4ts: + specifier: link:../../../../../Library/pnpm/global/5/node_modules/pricing4ts + version: link:../../../../../Library/pnpm/global/5/node_modules/pricing4ts diff --git a/node_modules/pricing4ts b/node_modules/pricing4ts new file mode 120000 index 0000000..c9df06c --- /dev/null +++ b/node_modules/pricing4ts @@ -0,0 +1 @@ +../../../../../../Library/pnpm/global/5/node_modules/pricing4ts \ No newline at end of file diff --git a/pom.xml b/pom.xml index 36326ac..74138a7 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ io.github.isa-group Pricing4Java - 5.5.1 + 5.5.2 ${project.groupId}:${project.artifactId} A pricing driven feature toggling library for java diff --git a/src/main/java/io/github/isagroup/services/parsing/AddOnParser.java b/src/main/java/io/github/isagroup/services/parsing/AddOnParser.java index e914312..b299e1c 100644 --- a/src/main/java/io/github/isagroup/services/parsing/AddOnParser.java +++ b/src/main/java/io/github/isagroup/services/parsing/AddOnParser.java @@ -179,7 +179,13 @@ private static void setAddOnFeatures(String addOnName, Map addOn for (String addOnFeatureName : addOnFeaturesMap.keySet()) { - Map addOnFeatureMap = (Map) addOnFeaturesMap.get(addOnFeatureName); + Object featureObj = addOnFeaturesMap.get(addOnFeatureName); + if (!(featureObj instanceof Map)) { + throw new PricingParsingException("The feature " + addOnFeatureName + + " of the add-on " + addOnName + " is not a valid map. Maybe 'value' attribute is missing to set the value of the feature"); + } + @SuppressWarnings("unchecked") + Map addOnFeatureMap = (Map) featureObj; if (!globalFeaturesMap.containsKey(addOnFeatureName)) { throw new FeatureNotFoundException( @@ -233,9 +239,23 @@ private static void setAddOnUsageLimits(String addOnName, Map ad Map addOnUsageLimitsMap = null; if (areExtensions) { - addOnUsageLimitsMap = (Map) addOnMap.get("usageLimitsExtensions"); + Object usageLimitsExtensionsObj = addOnMap.get("usageLimitsExtensions"); + if (usageLimitsExtensionsObj instanceof Map) { + addOnUsageLimitsMap = (Map) usageLimitsExtensionsObj; + } else if (usageLimitsExtensionsObj != null) { + throw new PricingParsingException("The field \"usageLimitsExtensions\" should be a map. It is currently: " + + usageLimitsExtensionsObj.getClass().getSimpleName() + ". " + + "Maybe you forgot to add the 'value' attribute to the usage limit in the add-on definition."); + } } else { - addOnUsageLimitsMap = (Map) addOnMap.get("usageLimits"); + Object usageLimitsObj = addOnMap.get("usageLimits"); + if (usageLimitsObj instanceof Map) { + addOnUsageLimitsMap = (Map) usageLimitsObj; + } else if (usageLimitsObj != null) { + throw new PricingParsingException("The field \"usageLimits\" should be a map. It is currently: " + + usageLimitsObj.getClass().getSimpleName() + ". " + + "Maybe you forgot to add the 'value' attribute to the usage limit in the add-on definition."); + } } Map globalUsageLimitsMap = pricingManager.getUsageLimits(); Map addOnUsageLimits = new LinkedHashMap<>(); diff --git a/src/main/java/io/github/isagroup/services/parsing/FeatureParser.java b/src/main/java/io/github/isagroup/services/parsing/FeatureParser.java index a6b8b4d..c58ad80 100644 --- a/src/main/java/io/github/isagroup/services/parsing/FeatureParser.java +++ b/src/main/java/io/github/isagroup/services/parsing/FeatureParser.java @@ -105,7 +105,17 @@ private static Integration parseMapToIntegration(String featureName, Map) map.get("pricingUrls")); + if (map.get("pricingUrls") != null) { + if (!(map.get("pricingUrls") instanceof List) || ((List) map.get("pricingUrls")).isEmpty() + || ((List) map.get("pricingUrls")).stream().anyMatch(url -> !url.matches("^(http|https)://.*"))) { + throw new PricingParsingException("The feature " + featureName + + " is from type INTEGRATION with integrationType WEB_SAAS but does not have a valid pricingUrls list (each item must be a valid URL with the http or https protocol). Current value: " + map.get("pricingUrls") + + ". To specify a list you must use dash (-) before each item. Remember, it is an optional field so you can remove it from the input."); + } + integration.setPricingUrls((List) map.get("pricingUrls")); + } else { + integration.setPricingUrls(List.of()); + } } return integration; @@ -134,7 +144,7 @@ private static Automation parseMapToAutomation(String featureName, Map map, for (String planFeatureName : planFeaturesMap.keySet()) { - Map planFeatureMap = (Map) planFeaturesMap.get(planFeatureName); + Object planFeatureObj = planFeaturesMap.get(planFeatureName); + if (!(planFeatureObj instanceof Map)) { + throw new PricingParsingException("The feature " + planFeatureName + + " of the plan " + planName + " is not a valid map. Maybe 'value' attribute is missing to set the value of the feature"); + } + @SuppressWarnings("unchecked") + Map planFeatureMap = (Map) planFeatureObj; if (!plan.getFeatures().containsKey(planFeatureName)) { throw new FeatureNotFoundException( @@ -188,7 +194,13 @@ private static void setUsageLimitsToPlan(String planName, Map ma for (String planUsageLimitName : planUsageLimitsMap.keySet()) { - Map planUsageLimitMap = (Map) planUsageLimitsMap.get(planUsageLimitName); + Object planUsageLimitObj = planUsageLimitsMap.get(planUsageLimitName); + if (!(planUsageLimitObj instanceof Map)) { + throw new PricingParsingException("The usageLimit " + planUsageLimitName + + " of the plan " + planName + " is not a valid map. Maybe 'value' attribute is missing to set the value of the usageLimit"); + } + @SuppressWarnings("unchecked") + Map planUsageLimitMap = (Map) planUsageLimitObj; if (!plan.getUsageLimits().containsKey(planUsageLimitName)) { throw new FeatureNotFoundException( @@ -196,7 +208,16 @@ private static void setUsageLimitsToPlan(String planName, Map ma } else { UsageLimit usageLimit = plan.getUsageLimits().get(planUsageLimitName); - Object value = planUsageLimitMap.get("value"); + Object value = null; + try{ + value = planUsageLimitMap.get("value"); + } + catch (NullPointerException e){ + throw new InvalidDefaultValueException("The usageLimit " + planUsageLimitName + + " does not have a valid value. Current valueType: " + + usageLimit.getValueType().toString() + "; Current value in plan " + plan.getName() + " is null"); + } + boolean isValueNull = (value == null); if (isValueNull){ @@ -251,7 +272,7 @@ public static void parsePaymentValue(Feature feature, String featureName, Map map, PricingManager pricingMana } private static void setAddOns(Map map, PricingManager pricingManager) { - Map addOnsMap = (Map) map.get("addOns"); + Map addOnsMap = null; + if (map.get("addOns") instanceof Map) { + addOnsMap = (Map) map.get("addOns"); + } if (addOnsMap == null) { return; @@ -356,7 +359,7 @@ private static void setAddOns(Map map, PricingManager pricingMan AddOn addOn = AddOnParser.parseMapToAddOn(addOnName, addOnMap, pricingManager); pricingManager.getAddOns().put(addOnName, addOn); - } catch (ClassCastException e) { + } catch (ClassCastException | NullPointerException | IllegalArgumentException e) { throw new PricingParsingException( "An error has occurred while parsing the add-on " + addOnName + ". Error: " + e.getMessage()); } diff --git a/src/main/java/io/github/isagroup/services/parsing/UsageLimitParser.java b/src/main/java/io/github/isagroup/services/parsing/UsageLimitParser.java index a4c73eb..a116f33 100644 --- a/src/main/java/io/github/isagroup/services/parsing/UsageLimitParser.java +++ b/src/main/java/io/github/isagroup/services/parsing/UsageLimitParser.java @@ -47,7 +47,7 @@ public static UsageLimit parseMapToUsageLimit(String limitName, Map