/**
   * find DM or NAS from db using native id
   *
   * @param system
   * @param dbClient
   * @param nativeId
   * @return
   */
  private PhysicalNAS findPhysicalNasByNativeId(
      final StorageSystem system, DbClient dbClient, String nativeId) {
    URIQueryResultList results = new URIQueryResultList();
    PhysicalNAS physicalNas = null;

    // Set storage port details to vNas
    String nasNativeGuid =
        NativeGUIDGenerator.generateNativeGuid(system, nativeId, NativeGUIDGenerator.PHYSICAL_NAS);

    dbClient.queryByConstraint(
        AlternateIdConstraint.Factory.getPhysicalNasByNativeGuidConstraint(nasNativeGuid), results);

    Iterator<URI> iter = results.iterator();
    while (iter.hasNext()) {
      PhysicalNAS tmpNas = dbClient.queryObject(PhysicalNAS.class, iter.next());

      if (tmpNas != null && !tmpNas.getInactive()) {
        physicalNas = tmpNas;
        _logger.info(
            "found physical NAS {}", physicalNas.getNativeGuid() + ":" + physicalNas.getNasName());
        break;
      }
    }
    return physicalNas;
  }
  /**
   * get the DB metrics for each data mover or VDM
   *
   * @param storageSystem
   * @param dbClient
   * @param dmFsMountMap
   * @param dmCapacityMap
   * @param vdmFsMountMap
   * @param vdmCapacityMap
   */
  private void prepareDBMetrics(
      StorageSystem storageSystem,
      DbClient dbClient,
      final Map<String, List<String>> dmFsMountMap,
      final Map<String, Long> dmCapacityMap,
      final Map<String, List<String>> vdmFsMountMap,
      final Map<String, Long> vdmCapacityMap) {

    List<VirtualNAS> modifiedVNas = new ArrayList<VirtualNAS>();
    List<PhysicalNAS> modifiedPNas = new ArrayList<PhysicalNAS>();

    for (Entry<String, List<String>> eachNas : dmFsMountMap.entrySet()) {
      _logger.info(" Computing metrics for data mover {}  ", eachNas.getKey());
      // Get Physical NAS from db!!
      PhysicalNAS pNAS = findPhysicalNasByNativeId(storageSystem, dbClient, eachNas.getKey());

      List<VirtualNAS> vNasList = new ArrayList<VirtualNAS>();

      if (null != pNAS) {
        URIQueryResultList virtualNASUris = new URIQueryResultList();
        dbClient.queryByConstraint(
            ContainmentConstraint.Factory.getVirtualNASByParentConstraint(pNAS.getId()),
            virtualNASUris);

        Long totalDmObjects = 0L;
        Long totalDmCapacity = 0L;

        Iterator<URI> virtualNASIter = virtualNASUris.iterator();
        while (virtualNASIter.hasNext()) {
          // Get Each vNAS on Physical NAS
          VirtualNAS virtualNAS = dbClient.queryObject(VirtualNAS.class, virtualNASIter.next());
          if (virtualNAS != null && !virtualNAS.getInactive()) {

            vNasList.add(virtualNAS);
            int vNasObjects = 0;

            if (vdmFsMountMap.get(virtualNAS.getNativeId()) != null) {
              vNasObjects = vdmFsMountMap.get(virtualNAS.getNativeId()).size();
              totalDmObjects = totalDmObjects + vNasObjects;
            }

            Long vNasCapacity = 0L;
            if (vdmCapacityMap.get(virtualNAS.getNativeId()) != null) {
              vNasCapacity = vdmCapacityMap.get(virtualNAS.getNativeId());
              totalDmCapacity = totalDmCapacity + vNasCapacity;
            }

            // Update dbMetrics for vNAS!!
            StringMap vNasDbMetrics = virtualNAS.getMetrics();
            vNasDbMetrics.put(MetricsKeys.storageObjects.name(), String.valueOf(vNasObjects));
            vNasDbMetrics.put(MetricsKeys.usedStorageCapacity.name(), String.valueOf(vNasCapacity));

            modifiedVNas.add(virtualNAS);
          }
        }

        if (dmFsMountMap.get(pNAS.getNativeId()) != null) {

          totalDmObjects = totalDmObjects + dmFsMountMap.get(pNAS.getNativeId()).size();
        }

        if (dmCapacityMap.get(pNAS.getNativeId()) != null) {
          totalDmCapacity = totalDmCapacity + dmCapacityMap.get(pNAS.getNativeId());
        }

        for (VirtualNAS vNas : vNasList) {
          // Update dbMetrics for vNAS!!
          StringMap vNasDbMetrics = vNas.getMetrics();
          long StorageObj = MetricsKeys.getLong(MetricsKeys.storageObjects, vNas.getMetrics());
          double percentageLoad = ((double) StorageObj / totalDmObjects) * 100;
          vNasDbMetrics.put(MetricsKeys.percentLoad.name(), String.valueOf(percentageLoad));
        }

        StringMap pNasDbMetrics = pNAS.getMetrics();
        pNasDbMetrics.put(MetricsKeys.storageObjects.name(), String.valueOf(totalDmObjects));
        pNasDbMetrics.put(MetricsKeys.usedStorageCapacity.name(), String.valueOf(totalDmCapacity));

        long maxObjects = MetricsKeys.getLong(MetricsKeys.maxStorageObjects, pNasDbMetrics);
        long maxCapacity = MetricsKeys.getLong(MetricsKeys.maxStorageCapacity, pNasDbMetrics);
        double percentageLoad = ((double) totalDmObjects / maxObjects) * 100;
        pNasDbMetrics.put(MetricsKeys.percentLoad.name(), String.valueOf(percentageLoad));
        if (totalDmObjects >= maxObjects || totalDmCapacity >= maxCapacity) {
          pNasDbMetrics.put(MetricsKeys.overLoaded.name(), "true");
          // All vNas under should be updated!!!
          for (VirtualNAS vNas : vNasList) {
            // Update dbMetrics for vNAS!!
            StringMap vNasDbMetrics = vNas.getMetrics();
            vNasDbMetrics.put(MetricsKeys.overLoaded.name(), "true");
          }
        } else {
          pNasDbMetrics.put(MetricsKeys.overLoaded.name(), "false");
          // All vNas under should be updated!!!
          for (VirtualNAS vNas : vNasList) {
            // Update dbMetrics for vNAS!!
            StringMap vNasDbMetrics = vNas.getMetrics();
            vNasDbMetrics.put(MetricsKeys.overLoaded.name(), "false");
          }
        }
        modifiedPNas.add(pNAS);
      }

      // Update the db
      if (!modifiedVNas.isEmpty()) {
        dbClient.persistObject(modifiedVNas);
      }

      if (!modifiedPNas.isEmpty()) {
        dbClient.persistObject(modifiedPNas);
      }
    }
    return;
  }