+\r
+ /**\r
+ * Collects all deployed versions of specified policy in all pdp groups.\r
+ *\r
+ * @param policyId the ID of policy\r
+ * @param policyType the concept key of policy type\r
+ * @param getter the custom generic getter Bifunction\r
+ * @param consumer the BiConsumer\r
+ * @param data the data structure storing retrieved deployed policies\r
+ *\r
+ * @return a map between pdp group and deployed versions of specified policy in that group\r
+ *\r
+ * @throws PfModelException the PfModel parsing exception\r
+ */\r
+ protected <T, R> Map<Pair<String, String>, T> collectDeployedPolicies(String policyId, PfConceptKey policyType,\r
+ BiFunctionWithEx<String, String, R> getter, BiConsumer<T, R> consumer, T data) throws PfModelException {\r
+\r
+ List<PdpGroup> pdpGroups = getPolicyTypeFilteredPdpGroups(policyType);\r
+ hasActivePdpGroup(pdpGroups, policyType, policyId);\r
+ return constructDeployedPolicyMap(pdpGroups, policyId, policyType, getter, consumer, data);\r
+ }\r
+\r
+ @FunctionalInterface\r
+ protected interface BiFunctionWithEx<T,U,R> {\r
+ public R apply(T value1, U value2) throws PfModelException;\r
+ }\r
+\r
+ /**\r
+ * Checks if the list of pdp groups is empty.\r
+ * If so, throws exception saying specified policy deployment is not found in all existing pdp groups.\r
+ *\r
+ * @param pdpGroups the list of pdp groups to check against\r
+ * @param policyType the concept key of policy type\r
+ * @param policyId the ID of policy\r
+ *\r
+ * @throws PfModelException the PfModel parsing exception\r
+ */\r
+ private void hasActivePdpGroup(List<PdpGroup> pdpGroups, PfConceptKey policyType, String policyId)\r
+ throws PfModelException {\r
+\r
+ if (pdpGroups.isEmpty()) {\r
+ throw new PfModelException(Response.Status.NOT_FOUND,\r
+ constructDeploymentNotFoundMessage(policyType, policyId));\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Retrieves all pdp groups supporting specified policy type.\r
+ *\r
+ * @param policyTypeId the ID of policy type\r
+ * @param policyTypeVersion the version of policy type\r
+ *\r
+ * @return a list of pdp groups supporting specified policy type\r
+ *\r
+ * @throws PfModelException the PfModel parsing exception\r
+ */\r
+ private List<PdpGroup> getPolicyTypeFilteredPdpGroups(PfConceptKey policyType)\r
+ throws PfModelException {\r
+\r
+ List<ToscaPolicyTypeIdentifier> policyTypes = new ArrayList<>();\r
+ policyTypes.add(new ToscaPolicyTypeIdentifier(policyType.getName(), policyType.getVersion()));\r
+ PdpGroupFilter pdpGroupFilter = PdpGroupFilter.builder().policyTypeList(policyTypes)\r
+ .groupState(PdpState.ACTIVE).pdpState(PdpState.ACTIVE).build();\r
+ return modelsProvider.getFilteredPdpGroups(pdpGroupFilter);\r
+ }\r
+\r
+ /**\r
+ * Constructs the map of deployed pdp groups and deployed policies.\r
+ *\r
+ * @param pdpGroups the list of pdp groups that contain the specified policy\r
+ * @param policyId the ID of policy\r
+ * @param policyType the concept key of policy type\r
+ * @param getter the custom generic getter BiFunction\r
+ * @param consumer the BiConsumer\r
+ * @param data the data structure storing retrieved deployed policies\r
+ *\r
+ * @return the constructed map of pdp groups and deployed policies\r
+ *\r
+ * @throws PfModelException the PfModel parsing exception\r
+ */\r
+ private <T, R> Map<Pair<String, String>, T> constructDeployedPolicyMap(List<PdpGroup> pdpGroups, String policyId,\r
+ PfConceptKey policyType, BiFunctionWithEx<String, String, R> getter, BiConsumer<T, R> consumer, T data)\r
+ throws PfModelException {\r
+\r
+ Map<Pair<String, String>, T> deployedPolicyMap = new HashMap<>();\r
+ for (PdpGroup pdpGroup : pdpGroups) {\r
+ List<ToscaPolicyIdentifier> policyIdentifiers = extractPolicyIdentifiers(policyId, pdpGroup, policyType);\r
+ T deployedPolicies = getDeployedPolicies(policyIdentifiers, policyType, getter, consumer, data);\r
+ deployedPolicyMap.put(Pair.of(pdpGroup.getName(), pdpGroup.getVersion()), deployedPolicies);\r
+ }\r
+ return deployedPolicyMap;\r
+ }\r
+\r
+ /**\r
+ * Extracts policy identifiers matching specified policy ID from specified pdp group.\r
+ *\r
+ * @param policyId the ID of policy to match\r
+ * @param pdpGroup the target pdp group to search\r
+ * @param policyType the concept key of policy type\r
+ *\r
+ * @return the list of policy identifiers\r
+ *\r
+ * @throws PfModelException the PfModel parsing exception\r
+ */\r
+ private List<ToscaPolicyIdentifier> extractPolicyIdentifiers(String policyId, PdpGroup pdpGroup,\r
+ PfConceptKey policyType) throws PfModelException {\r
+\r
+ List<ToscaPolicyIdentifier> policyIdentifiers = new ArrayList<>();\r
+ for (PdpSubGroup pdpSubGroup : pdpGroup.getPdpSubgroups()) {\r
+ for (ToscaPolicyIdentifier policyIdentifier : pdpSubGroup.getPolicies()) {\r
+ if (policyId.equalsIgnoreCase(policyIdentifier.getName())) {\r
+ policyIdentifiers.add(policyIdentifier);\r
+ }\r
+ }\r
+ }\r
+ if (policyIdentifiers.isEmpty()) {\r
+ throw new PfModelException(Response.Status.NOT_FOUND,\r
+ constructDeploymentNotFoundMessage(policyType, policyId));\r
+ }\r
+ return policyIdentifiers;\r
+ }\r
+\r
+ /**\r
+ * Retrieves deployed policies in a generic way.\r
+ *\r
+ * @param policyIdentifiers the identifiers of the policies to return\r
+ * @param policyType the concept key of current policy type\r
+ * @param getter the method reference of getting deployed policies\r
+ * @param consumer the method reference of consuming the returned policies\r
+ * @param data the data structure of deployed policies to return\r
+ *\r
+ * @return the generic type of policy data structure to return\r
+ *\r
+ * @throws PfModelException the PfModel parsing exception\r
+ */\r
+ private <T, R> T getDeployedPolicies(List<ToscaPolicyIdentifier> policyIdentifiers, PfConceptKey policyType,\r
+ BiFunctionWithEx<String, String, R> getter, BiConsumer<T, R> consumer, T data) throws PfModelException {\r
+\r
+ for (ToscaPolicyIdentifier policyIdentifier : policyIdentifiers) {\r
+ R result = getter.apply(policyIdentifier.getName(),\r
+ getTrimedVersionForLegacyType(policyIdentifier.getVersion(), policyType));\r
+ consumer.accept(data, result);\r
+ }\r
+ return data;\r
+ }\r
+\r
+ /**\r
+ * Trims the version for legacy policies.\r
+ *\r
+ * @param fullVersion the full version format with major, minor, patch\r
+ * @param policyType the concept key of policy type\r
+ *\r
+ * @return the trimmed version\r
+ */\r
+ private String getTrimedVersionForLegacyType(String fullVersion, PfConceptKey policyType) {\r
+ return (policyType.getName().contains("guard")\r
+ || policyType.getName().contains("Operational")) ? fullVersion.split("\\.")[0] : fullVersion;\r
+ }\r
+\r
+ /**\r
+ * Constructs returned message for not found policy deployment.\r
+ *\r
+ * @param policyType the concept key of policy type\r
+ * @param policyId the ID of policy\r
+ *\r
+ * @return constructed message\r
+ */\r
+ private String constructDeploymentNotFoundMessage(PfConceptKey policyType, String policyId) {\r
+\r
+ return "could not find policy with ID " + policyId + " and type "\r
+ + policyType.getName() + ":" + policyType.getVersion() + " deployed in any pdp group";\r
+ }\r
+}
\ No newline at end of file