From 9e1bf621be4cb21146a124b6908625cbb6933ccb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Javier=20Cavero=20L=C3=B3pez?= Date: Tue, 8 Apr 2025 20:48:07 +0200 Subject: [PATCH 1/4] fix: parsing unhandled exceptions --- .../isagroup/services/parsing/FeatureParser.java | 4 ++-- .../isagroup/services/parsing/PlanParser.java | 13 +++++++++++-- .../services/parsing/PricingManagerParser.java | 7 +++++-- .../isagroup/services/parsing/UsageLimitParser.java | 4 ++-- 4 files changed, 20 insertions(+), 8 deletions(-) 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..28f416e 100644 --- a/src/main/java/io/github/isagroup/services/parsing/FeatureParser.java +++ b/src/main/java/io/github/isagroup/services/parsing/FeatureParser.java @@ -134,7 +134,7 @@ private static Automation parseMapToAutomation(String featureName, 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 +260,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 Date: Thu, 5 Jun 2025 17:52:18 +0200 Subject: [PATCH 2/4] fix: error for parsing feature/usageLimit without value key --- .../services/parsing/AddOnParser.java | 26 ++++++++++++++++--- .../isagroup/services/parsing/PlanParser.java | 16 ++++++++++-- 2 files changed, 37 insertions(+), 5 deletions(-) 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 4a70afe..26f6058 100644 --- a/src/main/java/io/github/isagroup/services/parsing/AddOnParser.java +++ b/src/main/java/io/github/isagroup/services/parsing/AddOnParser.java @@ -178,7 +178,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( @@ -232,9 +238,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/PlanParser.java b/src/main/java/io/github/isagroup/services/parsing/PlanParser.java index d65d402..3b8f485 100644 --- a/src/main/java/io/github/isagroup/services/parsing/PlanParser.java +++ b/src/main/java/io/github/isagroup/services/parsing/PlanParser.java @@ -103,7 +103,13 @@ private static void setFeaturesToPlan(String planName, 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( From de687916d02a2ea3ff691432969c784783a14f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Javier=20Cavero=20L=C3=B3pez?= Date: Wed, 2 Jul 2025 19:20:47 +0200 Subject: [PATCH 3/4] fix: parsing urls check --- .../services/parsing/FeatureParser.java | 18 ++++++++++++++++-- src/test/resources/negative-parsing-tests.csv | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) 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 28f416e..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; @@ -160,7 +170,11 @@ private static Guarantee parseMapToGuarantee(String featureName, Map Date: Thu, 3 Jul 2025 11:48:02 +0200 Subject: [PATCH 4/4] feat: increment patch version --- node_modules/.pnpm-workspace-state.json | 25 +++++++++++++++++++++++++ node_modules/.pnpm/lock.yaml | 16 ++++++++++++++++ node_modules/pricing4ts | 1 + pom.xml | 2 +- 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 node_modules/.pnpm-workspace-state.json create mode 100644 node_modules/.pnpm/lock.yaml create mode 120000 node_modules/pricing4ts 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