Merge "Query CmHandles using CPS path"
[cps.git] / cps-ncmp-service / src / main / java / org / onap / cps / ncmp / api / impl / NetworkCmProxyCmHandlerQueryServiceImpl.java
index 3deaa7d..d784bcd 100644 (file)
 
 package org.onap.cps.ncmp.api.impl;
 
-import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NCMP_DATASPACE_NAME;
-import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NCMP_DMI_REGISTRY_ANCHOR;
+import static org.onap.cps.ncmp.api.impl.utils.YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle;
 import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS;
+import static org.onap.cps.utils.CmHandleQueryRestParametersValidator.validateCpsPathConditionProperties;
 import static org.onap.cps.utils.CmHandleQueryRestParametersValidator.validateModuleNameConditionProperties;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.cpspath.parser.PathParsingException;
 import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService;
-import org.onap.cps.spi.CpsAdminPersistenceService;
-import org.onap.cps.spi.CpsDataPersistenceService;
+import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
+import org.onap.cps.ncmp.api.inventory.CmHandleQueries;
+import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
+import org.onap.cps.spi.exceptions.DataValidationException;
 import org.onap.cps.spi.model.Anchor;
 import org.onap.cps.spi.model.CmHandleQueryServiceParameters;
 import org.onap.cps.spi.model.ConditionProperties;
 import org.onap.cps.spi.model.DataNode;
-import org.onap.cps.spi.model.DataNodeIdentifier;
-import org.onap.cps.utils.JsonObjectMapper;
+import org.onap.cps.utils.ValidQueryProperties;
 import org.springframework.stereotype.Service;
 
 @Service
@@ -50,11 +56,9 @@ import org.springframework.stereotype.Service;
 @RequiredArgsConstructor
 public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCmHandlerQueryService {
 
-    private static final String PROPERTY_QUERY_NAME = "hasAllProperties";
-    private static final String MODULE_QUERY_NAME = "hasAllModules";
-    private final CpsDataPersistenceService cpsDataPersistenceService;
-    private final CpsAdminPersistenceService cpsAdminPersistenceService;
-    private final JsonObjectMapper jsonObjectMapper;
+    private static final Map<String, NcmpServiceCmHandle> NO_QUERY_TO_EXECUTE = null;
+    private final CmHandleQueries cmHandleQueries;
+    private final InventoryPersistence inventoryPersistence;
 
     /**
      * Query and return cm handles that match the given query parameters.
@@ -63,121 +67,161 @@ public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCm
      * @return collection of cm handles
      */
     @Override
-    public Collection<DataNode> queryCmHandles(final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
+    public Set<NcmpServiceCmHandle> queryCmHandles(
+        final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
 
         if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
             return getAllCmHandles();
         }
 
-        final Collection<DataNodeIdentifier> amalgamatedQueryResultIdentifiers = new ArrayList<>();
-        final Map<DataNodeIdentifier, DataNode> amalgamatedQueryResults = new HashMap<>();
+        final Map<String, NcmpServiceCmHandle> combinedQueryResult = executeInventoryQueries(
+            cmHandleQueryServiceParameters);
 
-        final boolean firstQuery = moduleNameQuery(cmHandleQueryServiceParameters,
-                amalgamatedQueryResultIdentifiers, amalgamatedQueryResults);
+        return new HashSet<>(combineWithModuleNameQuery(cmHandleQueryServiceParameters, combinedQueryResult).values());
+    }
 
-        publicPropertyQuery(cmHandleQueryServiceParameters, amalgamatedQueryResultIdentifiers,
-                amalgamatedQueryResults, firstQuery);
+    /**
+     * Query and return cm handles that match the given query parameters.
+     *
+     * @param cmHandleQueryServiceParameters the cm handle query parameters
+     * @return collection of cm handle ids
+     */
+    @Override
+    public Set<String> queryCmHandleIds(
+        final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
 
-        final Collection<DataNode> filteredDataNodes = new ArrayList<>();
-        amalgamatedQueryResultIdentifiers.forEach(amalgamatedQueryResultIdentifier ->
-            filteredDataNodes.add(amalgamatedQueryResults.get(amalgamatedQueryResultIdentifier))
-        );
+        if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
+            return getAllCmHandleIds();
+        }
 
-        return filteredDataNodes;
-    }
+        final Map<String, NcmpServiceCmHandle> combinedQueryResult = executeInventoryQueries(
+            cmHandleQueryServiceParameters);
 
-    private void publicPropertyQuery(final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
-                                     final Collection<DataNodeIdentifier> amalgamatedQueryResultIdentifiers,
-                                     final Map<DataNodeIdentifier, DataNode> amalgamatedQueryResults,
-                                     boolean firstQuery) {
-        for (final Map.Entry<String, String> entry :
-                getPublicPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters()).entrySet()) {
-            final String cmHandlePath = "//public-properties[@name='" + entry.getKey() + "' " + "and @value='"
-                    + entry.getValue() + "']" + "/ancestor::cm-handles";
-
-            final Collection<DataNode> dataNodes = getDataNodes(cmHandlePath);
-
-            if (firstQuery) {
-                firstQuery = false;
-                dataNodes.forEach(dataNode -> {
-                    final DataNodeIdentifier dataNodeIdentifier =
-                            jsonObjectMapper.convertToValueType(dataNode, DataNodeIdentifier.class);
-                    amalgamatedQueryResultIdentifiers.add(dataNodeIdentifier);
-                    amalgamatedQueryResults.put(dataNodeIdentifier, dataNode);
-                });
-            } else {
-                final Collection<DataNodeIdentifier> singleConditionQueryDataNodeIdentifiers = new ArrayList<>();
-                dataNodes.forEach(dataNode -> {
-                    final DataNodeIdentifier dataNodeIdentifier =
-                            jsonObjectMapper.convertToValueType(dataNode, DataNodeIdentifier.class);
-                    singleConditionQueryDataNodeIdentifiers.add(dataNodeIdentifier);
-                    amalgamatedQueryResults.put(dataNodeIdentifier, dataNode);
-                });
-                amalgamatedQueryResultIdentifiers.retainAll(singleConditionQueryDataNodeIdentifiers);
-            }
+        final Collection<String> moduleNamesForQuery =
+            getModuleNamesForQuery(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
+        if (moduleNamesForQuery.isEmpty()) {
+            return combinedQueryResult.keySet();
+        }
+        final Set<String> moduleNameQueryResult = getNamesOfAnchorsWithGivenModules(moduleNamesForQuery);
 
-            if (amalgamatedQueryResultIdentifiers.isEmpty()) {
-                break;
-            }
+        if (combinedQueryResult == NO_QUERY_TO_EXECUTE) {
+            return moduleNameQueryResult;
         }
-    }
 
-    private boolean moduleNameQuery(final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
-                                    final Collection<DataNodeIdentifier> amalgamatedQueryResultIdentifiers,
-                                    final Map<DataNodeIdentifier, DataNode> amalgamatedQueryResults) {
-        boolean firstQuery = true;
-        if (!getModuleNames(cmHandleQueryServiceParameters.getCmHandleQueryParameters()).isEmpty()) {
-            final Collection<String> anchorNames = cpsAdminPersistenceService.queryAnchors("NFP-Operational",
-                    getModuleNames(cmHandleQueryServiceParameters.getCmHandleQueryParameters()))
-                    .parallelStream().map(Anchor::getName).collect(Collectors.toList());
-
-            getAllCmHandles().forEach(dataNode -> {
-                if (anchorNames.contains(dataNode.getLeaves().get("id").toString())) {
-                    final DataNodeIdentifier dataNodeIdentifier =
-                            jsonObjectMapper.convertToValueType(dataNode, DataNodeIdentifier.class);
-                    amalgamatedQueryResultIdentifiers.add(dataNodeIdentifier);
-                    amalgamatedQueryResults.put(dataNodeIdentifier, dataNode);
-                }
-            });
+        moduleNameQueryResult.retainAll(combinedQueryResult.keySet());
+        return moduleNameQueryResult;
+    }
 
-            firstQuery = false;
+    private Map<String, NcmpServiceCmHandle> combineWithModuleNameQuery(
+        final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
+        final Map<String, NcmpServiceCmHandle> previousQueryResult) {
+        final Collection<String> moduleNamesForQuery =
+            getModuleNamesForQuery(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
+        if (moduleNamesForQuery.isEmpty()) {
+            return previousQueryResult;
+        }
+        final Collection<String> cmHandleIdsByModuleName = getNamesOfAnchorsWithGivenModules(moduleNamesForQuery);
+        if (cmHandleIdsByModuleName.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        final Map<String, NcmpServiceCmHandle> queryResult = new HashMap<>(cmHandleIdsByModuleName.size());
+        if (previousQueryResult == NO_QUERY_TO_EXECUTE) {
+            cmHandleIdsByModuleName.forEach(cmHandleId ->
+                    queryResult.put(cmHandleId, createNcmpServiceCmHandle(
+                            inventoryPersistence.getDataNode("/dmi-registry/cm-handles[@id='" + cmHandleId + "']")))
+            );
+            return queryResult;
         }
-        return firstQuery;
+        previousQueryResult.keySet().retainAll(cmHandleIdsByModuleName);
+        queryResult.putAll(previousQueryResult);
+        return queryResult;
     }
 
-    private List<Map<String, String>> getConditions(final List<ConditionProperties> conditionProperties,
-                                                    final String name) {
-        for (final ConditionProperties conditionProperty : conditionProperties) {
-            if (conditionProperty.getConditionName().equals(name)) {
-                return conditionProperty.getConditionParameters();
+    private Map<String, NcmpServiceCmHandle> executeInventoryQueries(
+        final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
+        final Map<String, String> cpsPath = getCpsPath(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
+        if (!validateCpsPathConditionProperties(cpsPath)) {
+            return Collections.emptyMap();
+        }
+        final Map<String, NcmpServiceCmHandle> cpsPathQueryResult;
+        if (cpsPath.isEmpty()) {
+            cpsPathQueryResult = NO_QUERY_TO_EXECUTE;
+        } else {
+            try {
+                cpsPathQueryResult = cmHandleQueries.getCmHandleDataNodesByCpsPath(
+                    cpsPath.get("cpsPath"), INCLUDE_ALL_DESCENDANTS)
+                    .stream().map(this::createNcmpServiceCmHandle)
+                    .collect(Collectors.toMap(NcmpServiceCmHandle::getCmHandleId,
+                        Function.identity()));
+            } catch (final PathParsingException pathParsingException) {
+                throw new DataValidationException(pathParsingException.getMessage(), pathParsingException.getDetails(),
+                    pathParsingException);
+            }
+            if (cpsPathQueryResult.isEmpty()) {
+                return Collections.emptyMap();
             }
         }
-        return Collections.emptyList();
+
+        final Map<String, String> publicPropertyQueryPairs =
+            getPublicPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
+        final Map<String, NcmpServiceCmHandle> propertiesQueryResult = publicPropertyQueryPairs.isEmpty()
+            ? NO_QUERY_TO_EXECUTE : cmHandleQueries.queryCmHandlePublicProperties(publicPropertyQueryPairs);
+
+        return cmHandleQueries.combineCmHandleQueries(cpsPathQueryResult, propertiesQueryResult);
+    }
+
+    private Set<String> getNamesOfAnchorsWithGivenModules(final Collection<String> moduleNamesForQuery) {
+        final Collection<Anchor> anchors = inventoryPersistence.queryAnchors(moduleNamesForQuery);
+        return anchors.parallelStream().map(Anchor::getName).collect(Collectors.toSet());
     }
 
-    private List<String> getModuleNames(final List<ConditionProperties> conditionProperties) {
+    private Collection<String> getModuleNamesForQuery(final List<ConditionProperties> conditionProperties) {
         final List<String> result = new ArrayList<>();
-        getConditions(conditionProperties, MODULE_QUERY_NAME).parallelStream().forEach(
+        getConditions(conditionProperties, ValidQueryProperties.HAS_ALL_MODULES.getQueryProperty())
+            .parallelStream().forEach(
                 conditionProperty -> {
                     validateModuleNameConditionProperties(conditionProperty);
                     result.add(conditionProperty.get("moduleName"));
                 }
-        );
+            );
+        return result;
+    }
+
+    private Map<String, String> getCpsPath(final List<ConditionProperties> conditionProperties) {
+        final Map<String, String> result = new HashMap<>();
+        getConditions(conditionProperties, ValidQueryProperties.WITH_CPS_PATH.getQueryProperty()).forEach(
+            result::putAll);
         return result;
     }
 
     private Map<String, String> getPublicPropertyPairs(final List<ConditionProperties> conditionProperties) {
         final Map<String, String> result = new HashMap<>();
-        getConditions(conditionProperties, PROPERTY_QUERY_NAME).forEach(result::putAll);
+        getConditions(conditionProperties,
+            ValidQueryProperties.HAS_ALL_PROPERTIES.getQueryProperty()).forEach(result::putAll);
         return result;
     }
 
-    private Collection<DataNode> getAllCmHandles() {
-        return getDataNodes("//public-properties/ancestor::cm-handles");
+    private List<Map<String, String>> getConditions(final List<ConditionProperties> conditionProperties,
+                                                    final String name) {
+        for (final ConditionProperties conditionProperty : conditionProperties) {
+            if (conditionProperty.getConditionName().equals(name)) {
+                return conditionProperty.getConditionParameters();
+            }
+        }
+        return Collections.emptyList();
+    }
+
+    private Set<NcmpServiceCmHandle> getAllCmHandles() {
+        return inventoryPersistence.getDataNode("/dmi-registry")
+            .getChildDataNodes().stream().map(this::createNcmpServiceCmHandle).collect(Collectors.toSet());
+    }
+
+    private Set<String> getAllCmHandleIds() {
+        return inventoryPersistence.getAnchors().parallelStream().map(Anchor::getName).collect(Collectors.toSet());
     }
 
-    private List<DataNode> getDataNodes(final String cmHandlePath) {
-        return cpsDataPersistenceService.queryDataNodes(
-                NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cmHandlePath, INCLUDE_ALL_DESCENDANTS);
+    private NcmpServiceCmHandle createNcmpServiceCmHandle(final DataNode dataNode) {
+        return convertYangModelCmHandleToNcmpServiceCmHandle(YangDataConverter
+            .convertCmHandleToYangModel(dataNode, dataNode.getLeaves().get("id").toString()));
     }
 }