public void createOrUpdateIpCapacity(Long dcId, Long podId, short capacityType) {
    SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();

    List<CapacityVO> capacities = _capacityDao.search(capacitySC, null);
    capacitySC = _capacityDao.createSearchCriteria();
    capacitySC.addAnd("podId", SearchCriteria.Op.EQ, podId);
    capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, dcId);
    capacitySC.addAnd("capacityType", SearchCriteria.Op.EQ, capacityType);

    int totalIPs;
    int allocatedIPs;
    capacities = _capacityDao.search(capacitySC, null);
    if (capacityType == CapacityVO.CAPACITY_TYPE_PRIVATE_IP) {
      totalIPs = _privateIPAddressDao.countIPs(podId, dcId, false);
      allocatedIPs = _privateIPAddressDao.countIPs(podId, dcId, true);
    } else if (capacityType == CapacityVO.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP) {
      totalIPs = _publicIPAddressDao.countIPsForNetwork(dcId, false, VlanType.VirtualNetwork);
      allocatedIPs = _publicIPAddressDao.countIPsForNetwork(dcId, true, VlanType.VirtualNetwork);
    } else {
      totalIPs = _publicIPAddressDao.countIPsForNetwork(dcId, false, VlanType.DirectAttached);
      allocatedIPs = _publicIPAddressDao.countIPsForNetwork(dcId, true, VlanType.DirectAttached);
    }

    if (capacities.size() == 0) {
      CapacityVO newPublicIPCapacity =
          new CapacityVO(null, dcId, podId, null, allocatedIPs, totalIPs, capacityType);
      _capacityDao.persist(newPublicIPCapacity);
    } else if (!(capacities.get(0).getUsedCapacity() == allocatedIPs
        && capacities.get(0).getTotalCapacity() == totalIPs)) {
      CapacityVO capacity = capacities.get(0);
      capacity.setUsedCapacity(allocatedIPs);
      capacity.setTotalCapacity(totalIPs);
      _capacityDao.update(capacity.getId(), capacity);
    }
  }
  private void createOrUpdateVlanCapacity(long dcId) {

    SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();

    List<CapacityVO> capacities = _capacityDao.search(capacitySC, null);
    capacitySC = _capacityDao.createSearchCriteria();
    capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, dcId);
    capacitySC.addAnd("capacityType", SearchCriteria.Op.EQ, Capacity.CAPACITY_TYPE_VLAN);
    capacities = _capacityDao.search(capacitySC, null);

    int totalVlans = _dcDao.countZoneVlans(dcId, false);
    int allocatedVlans = _dcDao.countZoneVlans(dcId, true);

    if (capacities.size() == 0) {
      CapacityVO newPublicIPCapacity =
          new CapacityVO(
              null, dcId, null, null, allocatedVlans, totalVlans, Capacity.CAPACITY_TYPE_VLAN);
      _capacityDao.persist(newPublicIPCapacity);
    } else if (!(capacities.get(0).getUsedCapacity() == allocatedVlans
        && capacities.get(0).getTotalCapacity() == totalVlans)) {
      CapacityVO capacity = capacities.get(0);
      capacity.setUsedCapacity(allocatedVlans);
      capacity.setTotalCapacity(totalVlans);
      _capacityDao.update(capacity.getId(), capacity);
    }
  }
    @Override
    public void run() {
      try {
        SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
        sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString());
        sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.Storage.toString());

        ConcurrentHashMap<Long, StorageStats> storageStats =
            new ConcurrentHashMap<Long, StorageStats>();
        List<HostVO> hosts = _hostDao.search(sc, null);
        for (HostVO host : hosts) {
          GetStorageStatsCommand command = new GetStorageStatsCommand(host.getGuid());
          Answer answer = _agentMgr.easySend(host.getId(), command);
          if (answer != null && answer.getResult()) {
            storageStats.put(host.getId(), (StorageStats) answer);
          }
        }

        sc = _hostDao.createSearchCriteria();
        sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString());
        sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.SecondaryStorage.toString());

        hosts = _hostDao.search(sc, null);
        for (HostVO host : hosts) {
          GetStorageStatsCommand command = new GetStorageStatsCommand(host.getGuid());
          Answer answer = _agentMgr.easySend(host.getId(), command);
          if (answer != null && answer.getResult()) {
            storageStats.put(host.getId(), (StorageStats) answer);
          }
        }
        _storageStats = storageStats;

        ConcurrentHashMap<Long, StorageStats> storagePoolStats =
            new ConcurrentHashMap<Long, StorageStats>();

        List<StoragePoolVO> storagePools = _storagePoolDao.listAll();
        for (StoragePoolVO pool : storagePools) {
          GetStorageStatsCommand command =
              new GetStorageStatsCommand(pool.getUuid(), pool.getPoolType(), pool.getPath());
          Answer answer = _storageManager.sendToPool(pool, command);
          if (answer != null && answer.getResult()) {
            storagePoolStats.put(pool.getId(), (StorageStats) answer);
          }
        }
        _storagePoolStats = storagePoolStats;

        // a list to store the new capacity entries that will be committed once everything is
        // calculated
        List<CapacityVO> newCapacities = new ArrayList<CapacityVO>();

        // Updating the storage entries and creating new ones if they dont exist.
        Transaction txn = Transaction.open(Transaction.CLOUD_DB);
        try {
          if (s_logger.isTraceEnabled()) {
            s_logger.trace("recalculating system storage capacity");
          }
          txn.start();
          for (Long hostId : storageStats.keySet()) {
            StorageStats stats = storageStats.get(hostId);
            short capacityType = -1;
            HostVO host = _hostDao.findById(hostId);
            host.setTotalSize(stats.getCapacityBytes());
            _hostDao.update(host.getId(), host);

            SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();
            capacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId);
            capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, host.getDataCenterId());

            if (Host.Type.SecondaryStorage.equals(host.getType())) {
              capacityType = CapacityVO.CAPACITY_TYPE_SECONDARY_STORAGE;
            } else if (Host.Type.Storage.equals(host.getType())) {
              capacityType = CapacityVO.CAPACITY_TYPE_STORAGE;
            }
            if (-1 != capacityType) {
              capacitySC.addAnd("capacityType", SearchCriteria.Op.EQ, capacityType);
              List<CapacityVO> capacities = _capacityDao.search(capacitySC, null);
              if (capacities.size() == 0) { // Create a new one
                CapacityVO capacity =
                    new CapacityVO(
                        host.getId(),
                        host.getDataCenterId(),
                        host.getPodId(),
                        stats.getByteUsed(),
                        stats.getCapacityBytes(),
                        capacityType);
                _capacityDao.persist(capacity);
              } else { // Update if it already exists.
                CapacityVO capacity = capacities.get(0);
                capacity.setUsedCapacity(stats.getByteUsed());
                capacity.setTotalCapacity(stats.getCapacityBytes());
                _capacityDao.update(capacity.getId(), capacity);
              }
            }
          } // End of for
          txn.commit();
        } catch (Exception ex) {
          txn.rollback();
          s_logger.error("Unable to start transaction for storage capacity update");
        } finally {
          txn.close();
        }

        for (Long poolId : storagePoolStats.keySet()) {
          StorageStats stats = storagePoolStats.get(poolId);
          StoragePoolVO pool = _storagePoolDao.findById(poolId);

          if (pool == null) {
            continue;
          }

          pool.setCapacityBytes(stats.getCapacityBytes());
          long available = stats.getCapacityBytes() - stats.getByteUsed();
          if (available < 0) {
            available = 0;
          }
          pool.setAvailableBytes(available);
          _storagePoolDao.update(pool.getId(), pool);

          _storageManager.createCapacityEntry(pool, 0L);
        }
      } catch (Throwable t) {
        s_logger.error("Error trying to retrieve storage stats", t);
      }
    }