@Override public Map<String, UsageNetworkVO> getRecentNetworkStats() { Transaction txn = Transaction.open(Transaction.USAGE_DB); String sql = SELECT_LATEST_STATS; PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(sql); ResultSet rs = pstmt.executeQuery(); Map<String, UsageNetworkVO> returnMap = new HashMap<String, UsageNetworkVO>(); while (rs.next()) { long accountId = rs.getLong(1); long zoneId = rs.getLong(2); Long hostId = rs.getLong(3); String hostType = rs.getString(4); Long networkId = rs.getLong(5); long bytesSent = rs.getLong(6); long bytesReceived = rs.getLong(7); long aggBytesReceived = rs.getLong(8); long aggBytesSent = rs.getLong(9); long eventTimeMillis = rs.getLong(10); if (hostId != 0) { returnMap.put( zoneId + "-" + accountId + "-Host-" + hostId, new UsageNetworkVO( accountId, zoneId, hostId, hostType, networkId, bytesSent, bytesReceived, aggBytesReceived, aggBytesSent, eventTimeMillis)); } else { returnMap.put( zoneId + "-" + accountId, new UsageNetworkVO( accountId, zoneId, hostId, hostType, networkId, bytesSent, bytesReceived, aggBytesReceived, aggBytesSent, eventTimeMillis)); } } return returnMap; } catch (Exception ex) { s_logger.error("error getting recent usage network stats", ex); } finally { txn.close(); } return null; }
@Override public void run() { try { Transaction txn = Transaction.open("SG Work"); try { work(); } finally { txn.close("SG Work"); } } catch (Throwable th) { try { s_logger.error("Problem with SG work", th); } catch (Throwable th2) { } } }
/** * This request registers the user Cloud.com account holder to the S3 service. The Cloud.com * account holder saves his API access and secret keys with the S3 service so that each rest call * he makes can be verified was originated from him. The given API access and secret key are saved * into the "usercredentials" database table. * * <p>This is an unauthenticated REST call. The only required parameters are 'accesskey' and * 'secretkey'. * * <p>To verify that the given keys represent an existing account they are used to execute the * Cloud.com's listAccounts API function. If the keys do not represent a valid account the * listAccounts function will fail. * * <p>A user can call this REST function any number of times, on each call the Cloud.com secret * key is simply over writes any previously stored value. * * <p>As with all REST calls HTTPS should be used to ensure their security. */ @DB private void setUserKeys(HttpServletRequest request, HttpServletResponse response) { String[] accessKey = null; String[] secretKey = null; try { // -> both these parameters are required accessKey = request.getParameterValues("accesskey"); if (null == accessKey || 0 == accessKey.length) { response.sendError(530, "Missing accesskey parameter"); return; } secretKey = request.getParameterValues("secretkey"); if (null == secretKey || 0 == secretKey.length) { response.sendError(530, "Missing secretkey parameter"); return; } } catch (Exception e) { logger.error("SetUserKeys exception " + e.getMessage(), e); response.setStatus(500); endResponse(response, "SetUserKeys exception " + e.getMessage()); return; } try { // -> use the keys to see if the account actually exists // ServiceProvider.getInstance().getEC2Engine().validateAccount( accessKey[0], secretKey[0] ); // UserCredentialsDaoImpl credentialDao = new UserCredentialsDao(); Transaction txn = Transaction.open(Transaction.AWSAPI_DB); txn.start(); UserCredentialsVO user = new UserCredentialsVO(accessKey[0], secretKey[0]); user = ucDao.persist(user); txn.commit(); txn.close(); // credentialDao.setUserKeys( accessKey[0], secretKey[0] ); } catch (Exception e) { logger.error("SetUserKeys " + e.getMessage(), e); response.setStatus(401); endResponse(response, e.toString()); return; } response.setStatus(200); endResponse(response, "User keys set successfully"); }
@Override public CloudStackServiceOfferingVO getSvcOfferingById(String id) { SearchBuilder<CloudStackServiceOfferingVO> searchByID = createSearchBuilder(); searchByID.and("uuid", searchByID.entity().getUuid(), SearchCriteria.Op.EQ); searchByID.done(); Transaction txn = Transaction.open(Transaction.CLOUD_DB); try { txn.start(); SearchCriteria<CloudStackServiceOfferingVO> sc = searchByID.create(); sc.setParameters("uuid", id); return findOneBy(sc); } finally { txn.commit(); txn.close(); } }
@Override public void run() { try { Transaction txn = Transaction.open("SG Cleanup"); try { cleanupFinishedWork(); cleanupUnfinishedWork(); // processScheduledWork(); } finally { txn.close("SG Cleanup"); } } catch (Throwable th) { try { s_logger.error("Problem with SG Cleanup", th); } catch (Throwable th2) { } } }
@Override public void deleteRecordsForAccount(Long accountId) { String sql = ((accountId == null) ? DELETE_ALL : DELETE_ALL_BY_ACCOUNTID); Transaction txn = Transaction.open(Transaction.USAGE_DB); PreparedStatement pstmt = null; try { txn.start(); pstmt = txn.prepareAutoCloseStatement(sql); if (accountId != null) { pstmt.setLong(1, accountId.longValue()); } pstmt.executeUpdate(); txn.commit(); } catch (Exception ex) { txn.rollback(); s_logger.error("error retrieving usage vm instances for account id: " + accountId); } finally { txn.close(); } }
public void update(UsageVPNUserVO usage) { Transaction txn = Transaction.open(Transaction.USAGE_DB); PreparedStatement pstmt = null; try { txn.start(); if (usage.getDeleted() != null) { pstmt = txn.prepareAutoCloseStatement(UPDATE_DELETED); pstmt.setString( 1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted())); pstmt.setLong(2, usage.getAccountId()); pstmt.setLong(3, usage.getUserId()); } pstmt.executeUpdate(); txn.commit(); } catch (Exception e) { txn.rollback(); s_logger.warn("Error updating UsageVPNUserVO", e); } finally { txn.close(); } }
@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); } }
/** * POST requests do not get authenticated on entry. The associated access key and signature * headers are embedded in the message not encoded as HTTP headers. */ private void processRequest( HttpServletRequest request, HttpServletResponse response, String method) { Transaction txn = Transaction.open("cloudbridge", Transaction.AWSAPI_DB, true); try { logRequest(request); // Our extensions to the S3 REST API for simple management actions // are conveyed with Request parameter "Action". // The present extensions are either to set up the user credentials // (see the cloud-bridge-register script for more detail) or // to report our version of this capability. // -> unauthenticated calls, should still be done over HTTPS String cloudAction = request.getParameter("Action"); if (!isS3APIEnabled) { throw new RuntimeException("Amazon S3 API is disabled."); } if (null != cloudAction) { if (cloudAction.equalsIgnoreCase("SetUserKeys")) { setUserKeys(request, response); return; } if (cloudAction.equalsIgnoreCase("SetCertificate")) // At present a noop return; if (cloudAction.equalsIgnoreCase("CloudS3Version")) { cloudS3Version(request, response); return; } } txn.start(); // -> authenticated calls if (!((method.equalsIgnoreCase("POST") && !(request.getQueryString().equalsIgnoreCase("delete"))))) { S3AuthParams params = extractRequestHeaders(request); authenticateRequest(request, params); } ServletAction action = routeRequest(request); if (action != null) { action.execute(request, response); } else { response.setStatus(404); endResponse(response, "File not found"); } txn.close(); } catch (InvalidBucketName e) { logger.error("Unexpected exception " + e.getMessage(), e); response.setStatus(400); endResponse(response, "Invalid Bucket Name - " + e.toString()); } catch (PermissionDeniedException e) { logger.error("Unexpected exception " + e.getMessage(), e); response.setStatus(403); endResponse(response, "Access denied - " + e.toString()); } catch (Throwable e) { logger.error("Unexpected exception " + e.getMessage(), e); response.setStatus(404); endResponse(response, "Bad request"); } finally { try { response.flushBuffer(); } catch (IOException e) { logger.error("Unexpected exception " + e.getMessage(), e); } } }
@Override public List<UsageVPNUserVO> getUsageRecords( Long accountId, Long domainId, Date startDate, Date endDate, boolean limit, int page) { List<UsageVPNUserVO> usageRecords = new ArrayList<UsageVPNUserVO>(); Long param1 = null; String sql = null; if (accountId != null) { sql = GET_USAGE_RECORDS_BY_ACCOUNT; param1 = accountId; } else if (domainId != null) { sql = GET_USAGE_RECORDS_BY_DOMAIN; param1 = domainId; } else { sql = GET_ALL_USAGE_RECORDS; } if (limit) { int startIndex = 0; if (page > 0) { startIndex = 500 * (page - 1); } sql += " LIMIT " + startIndex + ",500"; } Transaction txn = Transaction.open(Transaction.USAGE_DB); PreparedStatement pstmt = null; try { int i = 1; pstmt = txn.prepareAutoCloseStatement(sql); if (param1 != null) { pstmt.setLong(i++, param1); } pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate)); pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate)); pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate)); pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate)); pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate)); pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate)); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { // zoneId, account_id, domain_id, user_id, user_name, created, deleted Long zoneId = Long.valueOf(rs.getLong(1)); Long acctId = Long.valueOf(rs.getLong(2)); Long dId = Long.valueOf(rs.getLong(3)); long userId = Long.valueOf(rs.getLong(4)); String userName = rs.getString(5); Date createdDate = null; Date deletedDate = null; String createdTS = rs.getString(6); String deletedTS = rs.getString(7); if (createdTS != null) { createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS); } if (deletedTS != null) { deletedDate = DateUtil.parseDateString(s_gmtTimeZone, deletedTS); } usageRecords.add( new UsageVPNUserVO(zoneId, acctId, dId, userId, userName, createdDate, deletedDate)); } } catch (Exception e) { txn.rollback(); s_logger.warn("Error getting usage records", e); } finally { txn.close(); } return usageRecords; }
public boolean verifyRequest(Map<String, Object[]> requestParameters, Long userId) throws ServerApiException { try { String apiKey = null; String secretKey = null; String signature = null; String unsignedRequest = null; String[] command = (String[]) requestParameters.get("command"); if (command == null) { s_logger.info("missing command, ignoring request..."); return false; } String commandName = command[0]; // if userId not null, that mean that user is logged in if (userId != null) { User user = ApiDBUtils.findUserById(userId); try { checkCommandAvailable(user, commandName); } catch (PermissionDeniedException ex) { s_logger.debug( "The given command:" + commandName + " does not exist or it is not available for user with id:" + userId); throw new ServerApiException( ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "The given command does not exist or it is not available for user"); } return true; } else { // check against every available command to see if the command exists or not if (!_apiNameCmdClassMap.containsKey(commandName) && !commandName.equals("login") && !commandName.equals("logout")) { s_logger.debug( "The given command:" + commandName + " does not exist or it is not available for user with id:" + userId); throw new ServerApiException( ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "The given command does not exist or it is not available for user"); } } // - build a request string with sorted params, make sure it's all lowercase // - sign the request, verify the signature is the same List<String> parameterNames = new ArrayList<String>(); for (Object paramNameObj : requestParameters.keySet()) { parameterNames.add((String) paramNameObj); // put the name in a list that we'll sort later } Collections.sort(parameterNames); String signatureVersion = null; String expires = null; for (String paramName : parameterNames) { // parameters come as name/value pairs in the form String/String[] String paramValue = ((String[]) requestParameters.get(paramName))[0]; if ("signature".equalsIgnoreCase(paramName)) { signature = paramValue; } else { if ("apikey".equalsIgnoreCase(paramName)) { apiKey = paramValue; } else if ("signatureversion".equalsIgnoreCase(paramName)) { signatureVersion = paramValue; } else if ("expires".equalsIgnoreCase(paramName)) { expires = paramValue; } if (unsignedRequest == null) { unsignedRequest = paramName + "=" + URLEncoder.encode(paramValue, "UTF-8").replaceAll("\\+", "%20"); } else { unsignedRequest = unsignedRequest + "&" + paramName + "=" + URLEncoder.encode(paramValue, "UTF-8").replaceAll("\\+", "%20"); } } } // if api/secret key are passed to the parameters if ((signature == null) || (apiKey == null)) { s_logger.debug( "Expired session, missing signature, or missing apiKey -- ignoring request. Signature: " + signature + ", apiKey: " + apiKey); return false; // no signature, bad request } Date expiresTS = null; // FIXME: Hard coded signature, why not have an enum if ("3".equals(signatureVersion)) { // New signature authentication. Check for expire parameter and its validity if (expires == null) { s_logger.debug( "Missing Expires parameter -- ignoring request. Signature: " + signature + ", apiKey: " + apiKey); return false; } synchronized (_dateFormat) { try { expiresTS = _dateFormat.parse(expires); } catch (ParseException pe) { s_logger.debug("Incorrect date format for Expires parameter", pe); return false; } } Date now = new Date(System.currentTimeMillis()); if (expiresTS.before(now)) { s_logger.debug( "Request expired -- ignoring ...sig: " + signature + ", apiKey: " + apiKey); return false; } } Transaction txn = Transaction.open(Transaction.CLOUD_DB); txn.close(); User user = null; // verify there is a user with this api key Pair<User, Account> userAcctPair = _accountMgr.findUserByApiKey(apiKey); if (userAcctPair == null) { s_logger.debug( "apiKey does not map to a valid user -- ignoring request, apiKey: " + apiKey); return false; } user = userAcctPair.first(); Account account = userAcctPair.second(); if (user.getState() != Account.State.enabled || !account.getState().equals(Account.State.enabled)) { s_logger.info( "disabled or locked user accessing the api, userid = " + user.getId() + "; name = " + user.getUsername() + "; state: " + user.getState() + "; accountState: " + account.getState()); return false; } UserContext.updateContext(user.getId(), account, null); try { checkCommandAvailable(user, commandName); } catch (PermissionDeniedException ex) { s_logger.debug( "The given command:" + commandName + " does not exist or it is not available for user"); throw new ServerApiException( ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "The given command:" + commandName + " does not exist or it is not available for user with id:" + userId); } // verify secret key exists secretKey = user.getSecretKey(); if (secretKey == null) { s_logger.info( "User does not have a secret key associated with the account -- ignoring request, username: "******"HmacSHA1"); SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1"); mac.init(keySpec); mac.update(unsignedRequest.getBytes()); byte[] encryptedBytes = mac.doFinal(); String computedSignature = Base64.encodeBase64String(encryptedBytes); boolean equalSig = signature.equals(computedSignature); if (!equalSig) { s_logger.info( "User signature: " + signature + " is not equaled to computed signature: " + computedSignature); } return equalSig; } catch (ServerApiException ex) { throw ex; } catch (Exception ex) { s_logger.error("unable to verify request signature"); } return false; }
private boolean collectDirectNetworkUsage(HostVO host) { s_logger.debug("Direct Network Usage stats collector is running..."); long zoneId = host.getDataCenterId(); DetailVO lastCollectDetail = _detailsDao.findDetail(host.getId(), "last_collection"); if (lastCollectDetail == null) { s_logger.warn( "Last collection time not available. Skipping direct usage collection for Traffic Monitor: " + host.getId()); return false; } Date lastCollection = new Date(new Long(lastCollectDetail.getValue())); // Get list of IPs currently allocated List<IPAddressVO> allocatedIps = listAllocatedDirectIps(zoneId); Calendar rightNow = Calendar.getInstance(); // Allow 2 hours for traffic sentinel to populate historical traffic // This coule be made configurable rightNow.add(Calendar.HOUR_OF_DAY, -2); Date now = rightNow.getTime(); if (lastCollection.after(now)) { s_logger.debug( "Current time is less than 2 hours after last collection time : " + lastCollection.toString() + ". Skipping direct network usage collection"); return false; } // Get IP Assign/Release events from lastCollection time till now List<UsageEventVO> IpEvents = _eventDao.listDirectIpEvents(lastCollection, now, zoneId); Map<String, Date> ipAssigment = new HashMap<String, Date>(); List<UsageIPAddressVO> IpPartialUsage = new ArrayList< UsageIPAddressVO>(); // Ips which were allocated only for the part of collection // duration List<UsageIPAddressVO> fullDurationIpUsage = new ArrayList< UsageIPAddressVO>(); // Ips which were allocated only for the entire collection // duration // Use UsageEvents to track the IP assignment // Add them to IpUsage list with account_id , ip_address, alloc_date, release_date for (UsageEventVO IpEvent : IpEvents) { String address = IpEvent.getResourceName(); if (EventTypes.EVENT_NET_IP_ASSIGN.equals(IpEvent.getType())) { ipAssigment.put(address, IpEvent.getCreateDate()); } else if (EventTypes.EVENT_NET_IP_RELEASE.equals(IpEvent.getType())) { if (ipAssigment.containsKey(address)) { Date assigned = ipAssigment.get(address); ipAssigment.remove(address); IpPartialUsage.add( new UsageIPAddressVO( IpEvent.getAccountId(), address, assigned, IpEvent.getCreateDate())); } else { // Ip was assigned prior to lastCollection Date IpPartialUsage.add( new UsageIPAddressVO( IpEvent.getAccountId(), address, lastCollection, IpEvent.getCreateDate())); } } } List<String> IpList = new ArrayList<String>(); for (IPAddressVO ip : allocatedIps) { if (ip.getAllocatedToAccountId() == AccountVO.ACCOUNT_ID_SYSTEM) { // Ignore usage for system account continue; } String address = (ip.getAddress()).toString(); if (ipAssigment.containsKey(address)) { // Ip was assigned during the current period but not release till Date now IpPartialUsage.add( new UsageIPAddressVO( ip.getAllocatedToAccountId(), address, ipAssigment.get(address), now)); } else { // Ip was not assigned or released during current period. Consider entire duration for // usage calculation (lastCollection to now) fullDurationIpUsage.add( new UsageIPAddressVO(ip.getAllocatedToAccountId(), address, lastCollection, now)); // Store just the Ips to send the list as part of DirectNetworkUsageCommand IpList.add(address); } } List<UserStatisticsVO> collectedStats = new ArrayList<UserStatisticsVO>(); // Get usage for Ips which were assigned for the entire duration if (fullDurationIpUsage.size() > 0) { DirectNetworkUsageCommand cmd = new DirectNetworkUsageCommand(IpList, lastCollection, now, _TSinclZones, _TSexclZones); DirectNetworkUsageAnswer answer = (DirectNetworkUsageAnswer) _agentMgr.easySend(host.getId(), cmd); if (answer == null || !answer.getResult()) { String details = (answer != null) ? answer.getDetails() : "details unavailable"; String msg = "Unable to get network usage stats from " + host.getId() + " due to: " + details + "."; s_logger.error(msg); return false; } else { for (UsageIPAddressVO usageIp : fullDurationIpUsage) { String publicIp = usageIp.getAddress(); long[] bytesSentRcvd = answer.get(publicIp); Long bytesSent = bytesSentRcvd[0]; Long bytesRcvd = bytesSentRcvd[1]; if (bytesSent == null || bytesRcvd == null) { s_logger.debug("Incorrect bytes for IP: " + publicIp); continue; } if (bytesSent == 0L && bytesRcvd == 0L) { s_logger.trace("Ignore zero bytes for IP: " + publicIp); continue; } UserStatisticsVO stats = new UserStatisticsVO(usageIp.getAccountId(), zoneId, null, null, null, null); stats.setCurrentBytesSent(bytesSent); stats.setCurrentBytesReceived(bytesRcvd); collectedStats.add(stats); } } } // Get usage for Ips which were assigned for part of the duration period for (UsageIPAddressVO usageIp : IpPartialUsage) { IpList = new ArrayList<String>(); IpList.add(usageIp.getAddress()); DirectNetworkUsageCommand cmd = new DirectNetworkUsageCommand( IpList, usageIp.getAssigned(), usageIp.getReleased(), _TSinclZones, _TSexclZones); DirectNetworkUsageAnswer answer = (DirectNetworkUsageAnswer) _agentMgr.easySend(host.getId(), cmd); if (answer == null || !answer.getResult()) { String details = (answer != null) ? answer.getDetails() : "details unavailable"; String msg = "Unable to get network usage stats from " + host.getId() + " due to: " + details + "."; s_logger.error(msg); return false; } else { String publicIp = usageIp.getAddress(); long[] bytesSentRcvd = answer.get(publicIp); Long bytesSent = bytesSentRcvd[0]; Long bytesRcvd = bytesSentRcvd[1]; if (bytesSent == null || bytesRcvd == null) { s_logger.debug("Incorrect bytes for IP: " + publicIp); continue; } if (bytesSent == 0L && bytesRcvd == 0L) { s_logger.trace("Ignore zero bytes for IP: " + publicIp); continue; } UserStatisticsVO stats = new UserStatisticsVO(usageIp.getAccountId(), zoneId, null, null, null, null); stats.setCurrentBytesSent(bytesSent); stats.setCurrentBytesReceived(bytesRcvd); collectedStats.add(stats); } } if (collectedStats.size() == 0) { s_logger.debug("No new direct network stats. No need to persist"); return false; } // Persist all the stats and last_collection time in a single transaction Transaction txn = Transaction.open(Transaction.CLOUD_DB); try { txn.start(); for (UserStatisticsVO stat : collectedStats) { UserStatisticsVO stats = _statsDao.lock( stat.getAccountId(), stat.getDataCenterId(), 0L, null, host.getId(), "DirectNetwork"); if (stats == null) { stats = new UserStatisticsVO( stat.getAccountId(), zoneId, null, host.getId(), "DirectNetwork", 0L); stats.setCurrentBytesSent(stat.getCurrentBytesSent()); stats.setCurrentBytesReceived(stat.getCurrentBytesReceived()); _statsDao.persist(stats); } else { stats.setCurrentBytesSent(stats.getCurrentBytesSent() + stat.getCurrentBytesSent()); stats.setCurrentBytesReceived( stats.getCurrentBytesReceived() + stat.getCurrentBytesReceived()); _statsDao.update(stats.getId(), stats); } } lastCollectDetail.setValue("" + now.getTime()); _detailsDao.update(lastCollectDetail.getId(), lastCollectDetail); txn.commit(); } finally { txn.close(); } return true; }