use of com.vmware.photon.controller.model.adapters.aws.dto.AwsAccountDetailDto in project photon-model by vmware.
the class AWSCostStatsService method insertEC2ServiceDetail.
private void insertEC2ServiceDetail(AwsAccountDetailDto awsAccountDetailDto) {
AwsServiceDetailDto vm = awsAccountDetailDto.serviceDetailsMap.get(AwsServices.EC2_Instance_Usage.getName());
AwsServiceDetailDto ebs = awsAccountDetailDto.serviceDetailsMap.get(AwsServices.EC2_EBS.getName());
AwsServiceDetailDto others = awsAccountDetailDto.serviceDetailsMap.get(AwsServices.EC2_Others.getName());
AwsServiceDetailDto ec2ServiceDetail = new AwsServiceDetailDto();
ec2ServiceDetail.id = AwsServices.EC2.getName();
ec2ServiceDetail.type = AwsServices.getTypeByName(AwsServices.EC2.getName()).toString();
ec2ServiceDetail.directCosts = Stream.of(vm, ebs, others).filter(Objects::nonNull).map(dto -> dto.directCosts.entrySet()).flatMap(Set::stream).collect(Collectors.toMap(Entry::getKey, Entry::getValue, Double::sum));
ec2ServiceDetail.otherCosts = Stream.of(vm, ebs, others).filter(Objects::nonNull).map(dto -> dto.otherCosts.entrySet()).flatMap(Set::stream).collect(Collectors.toMap(Entry::getKey, Entry::getValue, Double::sum));
ec2ServiceDetail.remainingCosts = Stream.of(vm, ebs, others).filter(Objects::nonNull).map(dto -> dto.remainingCosts.entrySet()).flatMap(Set::stream).collect(Collectors.toMap(Entry::getKey, Entry::getValue, Double::sum));
ec2ServiceDetail.reservedRecurringCosts = Stream.of(vm, ebs, others).filter(Objects::nonNull).map(dto -> dto.reservedRecurringCosts.entrySet()).flatMap(Set::stream).collect(Collectors.toMap(Entry::getKey, Entry::getValue, Double::sum));
awsAccountDetailDto.serviceDetailsMap.put(AwsServices.EC2.getName(), ec2ServiceDetail);
}
use of com.vmware.photon.controller.model.adapters.aws.dto.AwsAccountDetailDto in project photon-model by vmware.
the class AWSCostStatsService method createServiceStatsForAccount.
protected void createServiceStatsForAccount(AWSCostStatsCreationContext statsData, LocalDate billMonth, AwsAccountDetailDto awsAccountDetailDto) {
Consumer<ComputeState> serviceStatsProcessor = (accountComputeState) -> {
ComputeStats awsServiceStats = new ComputeStats();
awsServiceStats.statValues = new ConcurrentHashMap<>();
awsServiceStats.computeLink = accountComputeState.documentSelfLink;
awsServiceStats.addCustomProperty(PhotonModelConstants.DOES_CONTAIN_SERVICE_STATS, Boolean.TRUE.toString());
for (AwsServiceDetailDto serviceDetailDto : awsAccountDetailDto.serviceDetailsMap.values()) {
Map<String, List<ServiceStat>> statsForAwsService = createStatsForAwsService(serviceDetailDto);
awsServiceStats.statValues.putAll(statsForAwsService);
}
if (!awsServiceStats.statValues.isEmpty()) {
statsData.statsResponse.statsList.add(awsServiceStats);
}
};
insertEC2ServiceDetail(awsAccountDetailDto);
processAccountStats(statsData, billMonth, awsAccountDetailDto, serviceStatsProcessor);
}
use of com.vmware.photon.controller.model.adapters.aws.dto.AwsAccountDetailDto in project photon-model by vmware.
the class AWSCostStatsService method createAccountStats.
protected void createAccountStats(AWSCostStatsCreationContext statsData, LocalDate billMonth, AwsAccountDetailDto awsAccountDetailDto) {
Consumer<ComputeState> accountStatsProcessor = (accountComputeState) -> {
ComputeStats accountStats = new ComputeStats();
accountStats.statValues = new ConcurrentHashMap<>();
accountStats.computeLink = accountComputeState.documentSelfLink;
if (isBillUpdated(statsData, awsAccountDetailDto)) {
logWithContext(statsData, Level.INFO, () -> String.format("Persisting cost of Account: %s (%s) for month: %s", awsAccountDetailDto.id, accountComputeState.documentSelfLink, billMonth));
ServiceStat costStat = createStat(AWSStatsNormalizer.getNormalizedUnitValue(DIMENSION_CURRENCY_VALUE), AWSStatsNormalizer.getNormalizedStatKeyValue(AWSConstants.COST), awsAccountDetailDto.billProcessedTimeMillis, awsAccountDetailDto.cost);
accountStats.statValues.put(costStat.name, Collections.singletonList(costStat));
ServiceStat otherCostsStat = createStat(AWSStatsNormalizer.getNormalizedUnitValue(DIMENSION_CURRENCY_VALUE), AWSConstants.OTHER_CHARGES, awsAccountDetailDto.billProcessedTimeMillis, awsAccountDetailDto.otherCharges);
accountStats.statValues.put(otherCostsStat.name, Collections.singletonList(otherCostsStat));
ServiceStat oneTimeChargesStat = createStat(AWSStatsNormalizer.getNormalizedUnitValue(DIMENSION_CURRENCY_VALUE), PhotonModelConstants.ACCOUNT_ONE_TIME_CHARGES, awsAccountDetailDto.billProcessedTimeMillis, awsAccountDetailDto.accountOneTimeCharges);
accountStats.statValues.put(oneTimeChargesStat.name, Collections.singletonList(oneTimeChargesStat));
}
if (!accountStats.statValues.isEmpty()) {
statsData.statsResponse.statsList.add(accountStats);
}
};
processAccountStats(statsData, billMonth, awsAccountDetailDto, accountStatsProcessor);
ResourceMetrics prevMarkerMetrics = statsData.accountsMarkersMap.get(awsAccountDetailDto.id);
if (prevMarkerMetrics != null) {
prevMarkerMetrics.entries.putAll(transformMapDataTypes(awsAccountDetailDto.lineCountPerInterval));
}
}
use of com.vmware.photon.controller.model.adapters.aws.dto.AwsAccountDetailDto in project photon-model by vmware.
the class AWSCsvBillParser method parseDetailedCsvBill.
private void parseDetailedCsvBill(InputStream inputStream, Collection<String> ignorableInvoiceCharge, Set<String> configuredAccounts, BiConsumer<Map<String, AwsAccountDetailDto>, String> hourlyStatsConsumer, Consumer<Map<String, AwsAccountDetailDto>> monthlyStatsConsumer) throws IOException {
final CsvPreference STANDARD_SKIP_COMMENTS = new CsvPreference.Builder(CsvPreference.STANDARD_PREFERENCE).skipComments(new CommentStartsWith(AWS_SKIP_COMMENTS)).build();
try (InputStreamReader reader = new InputStreamReader(inputStream, "UTF-8");
ICsvMapReader mapReader = new CsvMapReader(reader, STANDARD_SKIP_COMMENTS)) {
final String[] header = mapReader.getHeader(true);
List<CellProcessor> processorList = new ArrayList<>();
final CellProcessor[] basicProcessors = getDetailedProcessors(header);
processorList.addAll(Arrays.asList(basicProcessors));
List<String> tagHeaders = new ArrayList<>();
// Add new cell-processors for each extra tag column
int numberOfTags = header.length - basicProcessors.length;
if (numberOfTags > 0) {
for (int i = 0; i < numberOfTags; i++) {
processorList.add(new Optional());
tagHeaders.add(header[basicProcessors.length + i]);
}
}
CellProcessor[] cellProcessorArray = new CellProcessor[processorList.size()];
Map<String, AwsAccountDetailDto> monthlyBill = new HashMap<>();
cellProcessorArray = processorList.toArray(cellProcessorArray);
Map<String, Object> rowMap;
Long prevRowTime = null;
Long prevRowEndTime;
String interval = null;
while ((rowMap = mapReader.read(header, cellProcessorArray)) != null) {
LocalDateTime currRowLocalDateTime = (LocalDateTime) rowMap.get(DetailedCsvHeaders.USAGE_START_DATE);
Long curRowTime = getMillisForHour(currRowLocalDateTime);
if (prevRowTime != null && curRowTime != null && !prevRowTime.equals(curRowTime) && !StringUtils.contains(interval, "-")) {
// This indicates that we have processed all rows belonging to a corresponding hour in the
// current month bill. Consume the batch
hourlyStatsConsumer.accept(monthlyBill, interval);
}
try {
readRow(rowMap, monthlyBill, tagHeaders, ignorableInvoiceCharge, configuredAccounts);
} catch (Exception e) {
this.logger.warning(String.format("Got error while parsing a row in aws bill of %s", getStringFieldValue(rowMap, DetailedCsvHeaders.PAYER_ACCOUNT_ID) + e));
}
if (curRowTime != null) {
prevRowTime = curRowTime;
prevRowEndTime = getMillisForHour((LocalDateTime) rowMap.get(DetailedCsvHeaders.USAGE_END_DATE));
interval = createInterval(prevRowTime, prevRowEndTime);
}
}
// Consume the final batch of parsed rows
hourlyStatsConsumer.accept(monthlyBill, interval);
monthlyStatsConsumer.accept(monthlyBill);
}
}
use of com.vmware.photon.controller.model.adapters.aws.dto.AwsAccountDetailDto in project photon-model by vmware.
the class AWSCsvBillParser method readSummaryRow.
private void readSummaryRow(Map<String, Object> rowMap, String linkedAccountId, String productName, Map<String, AwsAccountDetailDto> accountDetails, Collection<String> ignorableInvoiceCharge) {
AwsAccountDetailDto awsAccountDetail;
if (linkedAccountId == null || linkedAccountId.length() == 0) {
// The AccountId is not obtained from LinkedAccountId in case of
// non-consolidated bills and has to be fetched from PayerAccountId
// column from the bill file
awsAccountDetail = createOrGetAccountDetailObject(accountDetails, getStringFieldValue(rowMap, DetailedCsvHeaders.PAYER_ACCOUNT_ID));
} else {
awsAccountDetail = createOrGetAccountDetailObject(accountDetails, linkedAccountId);
}
String lineInvoiceId = getStringFieldValue(rowMap, DetailedCsvHeaders.INVOICE_ID);
Double resourceCost = getResourceCost(rowMap);
if (matchFieldValue(rowMap, DetailedCsvHeaders.RECORD_TYPE, DetailedCsvHeaders.LINE_ITEM)) {
LocalDateTime usageStartTimeFromCsv = (LocalDateTime) rowMap.get(DetailedCsvHeaders.USAGE_START_DATE);
Long millisForBillHour = getMillisForHour(usageStartTimeFromCsv);
AwsServiceDetailDto serviceDetail = createOrGetServiceDetailObject(awsAccountDetail, productName, null);
if (serviceDetail != null && millisForBillHour != null) {
if (matchFieldValue(rowMap, DetailedCsvHeaders.OPERATION, RUN_INSTANCES)) {
serviceDetail.addToReservedRecurringCosts(millisForBillHour, resourceCost);
return;
}
serviceDetail.addToRemainingCosts(millisForBillHour, resourceCost);
if (StringUtils.isNotEmpty(lineInvoiceId) && StringUtils.isNotEmpty(this.billInvoiceId) && !StringUtils.equals(lineInvoiceId, this.billInvoiceId)) {
// service subscriptions/renewals
awsAccountDetail.accountOneTimeCharges += resourceCost;
ignorableInvoiceCharge.add(lineInvoiceId);
}
return;
}
awsAccountDetail.otherCharges += resourceCost;
} else if (matchFieldValue(rowMap, DetailedCsvHeaders.RECORD_TYPE, ACCOUNT_TOTAL)) {
// If the RecordType is AccountTotal, this is the account monthly cost for consolidated bills
awsAccountDetail.cost = resourceCost;
} else if (matchFieldValue(rowMap, DetailedCsvHeaders.RECORD_TYPE, INVOICE_TOTAL)) {
// ie, for primary accounts with no linked accounts
if (!ignorableInvoiceCharge.contains(lineInvoiceId)) {
awsAccountDetail.cost = resourceCost;
}
}
}
Aggregations