Search in sources :

Example 1 with EaDetailedBillElement

use of com.vmware.photon.controller.model.adapters.azure.model.cost.EaDetailedBillElement in project photon-model by vmware.

the class AzureCostHelper method sanitizeDetailedBillElement.

/**
 * Get a bill line item and check if any of the required / mandatory fields are not present
 * or are in a form that cannot be processed further (like cost being a non-parse-able double)
 * and if they are, set them to an acceptable value.
 * This method also processes fields in the elements, which after processing, would make
 * processing those fields faster or easier. For ex. convert date in the element to epoch time
 * @param billRow bill line item (may be a JSON object's Java representation)
 * @param currency currency of costs in the bill.
 * @return the sanitized bill item.
 */
static EaDetailedBillElement sanitizeDetailedBillElement(String[] billRow, String currency) {
    EaDetailedBillElement detailedBillElement = constructDetailedBillElementObject(billRow);
    // set meter category to unknown in case meter category is absent.
    detailedBillElement.meterCategory = StringUtils.isBlank(detailedBillElement.meterCategory) ? AzureCostConstants.UNKNOWN_SERVICE_NAME : detailedBillElement.meterCategory;
    // set subscription name to unknown in case subscription name is absent.
    detailedBillElement.subscriptionName = StringUtils.isBlank(detailedBillElement.subscriptionName) ? AzureCostConstants.UNKNOWN_SUBSCRIPTION : detailedBillElement.subscriptionName;
    // set epochDate to epoch format of date.
    detailedBillElement.epochDate = getMillisForDateString(detailedBillElement.date);
    convertToUsd(detailedBillElement, currency);
    return detailedBillElement;
}
Also used : EaDetailedBillElement(com.vmware.photon.controller.model.adapters.azure.model.cost.EaDetailedBillElement)

Example 2 with EaDetailedBillElement

use of com.vmware.photon.controller.model.adapters.azure.model.cost.EaDetailedBillElement in project photon-model by vmware.

the class AzureCostHelper method constructDetailedBillElementObject.

static EaDetailedBillElement constructDetailedBillElementObject(String[] billRow) {
    EaDetailedBillElement billElement = new EaDetailedBillElement();
    billElement.accountOwnerId = billRow[ACCOUNT_OWNER_ID.position];
    billElement.accountName = billRow[ACCOUNT_NAME.position];
    billElement.serviceAdministratorId = billRow[SERVICE_ADMINISTRATOR_ID.position];
    billElement.subscriptionId = billRow[SUBSCRIPTION_ID.position];
    billElement.subscriptionGuid = billRow[SUBSCRIPTION_GUID.position];
    billElement.subscriptionName = billRow[SUBSCRIPTION_NAME.position];
    billElement.date = billRow[DATE.position];
    billElement.month = getIntNoException(billRow, billRow[MONTH.position]);
    billElement.day = getIntNoException(billRow, billRow[DAY.position]);
    billElement.year = getIntNoException(billRow, billRow[YEAR.position]);
    billElement.product = billRow[PRODUCT.position];
    billElement.meterId = billRow[METER_ID.position];
    billElement.meterCategory = billRow[METER_CATEGORY.position];
    billElement.meterSubCategory = billRow[METER_SUB_CATEGORY.position];
    billElement.meterRegion = billRow[METER_REGION.position];
    billElement.meterName = billRow[METER_NAME.position];
    billElement.consumedQuantity = getDoubleOrNull(billRow, billRow[CONSUMED_QUANTITY.position]);
    billElement.resourceRate = getDoubleOrNull(billRow, billRow[RESOURCE_RATE.position]);
    billElement.extendedCost = getDoubleOrNull(billRow, billRow[EXTENDED_COST.position]);
    billElement.resourceLocation = billRow[RESOURCE_LOCATION.position];
    billElement.consumedService = billRow[CONSUMED_SERVICE.position];
    billElement.instanceId = billRow[INSTANCE_ID.position];
    billElement.serviceInfo1 = billRow[SERVICE_INFO_1.position];
    billElement.serviceInfo2 = billRow[SERVICE_INFO_2.position];
    billElement.additionalInfo = billRow[ADDITIONAL_INFO.position];
    billElement.tags = billRow[TAGS.position];
    billElement.storeServiceIdentifier = billRow[STORE_SERVICE_IDENTIFIER.position];
    billElement.departmentName = billRow[DEPARTMENT_NAME.position];
    billElement.costCenter = billRow[COST_CENTER.position];
    billElement.unitOfMeasure = billRow[UNIT_OF_MEASURE.position];
    billElement.resourceGroup = billRow[RESOURCE_GROUP.position];
    return billElement;
}
Also used : EaDetailedBillElement(com.vmware.photon.controller.model.adapters.azure.model.cost.EaDetailedBillElement)

Example 3 with EaDetailedBillElement

use of com.vmware.photon.controller.model.adapters.azure.model.cost.EaDetailedBillElement in project photon-model by vmware.

the class AzureDetailedBillHandler method parseDetailedCsv.

public BillParsingStatus parseDetailedCsv(File billFile, Set<String> newSubscriptions, BillParsingStatus status, long billProcessedTimeMillis, String currency, BiConsumer<Map<String, AzureSubscription>, Long> dailyStatsConsumer) throws IOException {
    logger.fine(() -> "Beginning to parse CSV file.");
    try (CSVReader csvReader = new CSVReader(new FileReader(billFile), AzureCostConstants.DEFAULT_COLUMN_SEPARATOR, AzureCostConstants.DEFAULT_QUOTE_CHARACTER, AzureCostConstants.DEFAULT_ESCAPE_CHARACTER, (int) status.getNoLinesRead())) {
        HeaderColumnNameMappingStrategy<EaDetailedBillElement> strategy = new HeaderColumnNameMappingStrategy<>();
        strategy.setType(EaDetailedBillElement.class);
        long timeToStartBillProcessing = getTimeToStartBillProcessing(billProcessedTimeMillis);
        // This map will contain daily subscription, service & resource cost. The subscription
        // GUID is the key and the subscription details is the value. This map is maintained
        // since daily-level stats are needed for services and resources.
        Map<String, AzureSubscription> monthlyBill = new HashMap<>();
        String[] nextRow;
        Long prevRowEpoch = null;
        while ((nextRow = csvReader.readNext()) != null) {
            final String[] finalNextRow = nextRow;
            if (nextRow.length != BillHeaders.values().length) {
                // Skip any blank or malformed rows
                logger.warning(() -> String.format("Skipping malformed row: %s", Arrays.toString(finalNextRow)));
                continue;
            }
            logger.fine(() -> String.format("Beginning to process row: %s", Arrays.toString(finalNextRow)));
            EaDetailedBillElement detailedBillElement = AzureCostHelper.sanitizeDetailedBillElement(nextRow, currency);
            AzureSubscription subscription = populateSubscriptionCost(monthlyBill, detailedBillElement);
            long curRowEpoch = detailedBillElement.epochDate;
            if (shouldCreateServiceAndResourceCost(detailedBillElement, newSubscriptions, timeToStartBillProcessing)) {
                AzureService service = populateServiceCost(subscription, detailedBillElement);
                populateResourceCost(service, detailedBillElement);
            }
            billProcessedTimeMillis = billProcessedTimeMillis < curRowEpoch ? curRowEpoch : billProcessedTimeMillis;
            monthlyBill.put(detailedBillElement.subscriptionGuid, subscription);
            if (prevRowEpoch != null && !prevRowEpoch.equals(curRowEpoch)) {
                // This indicates that we have processed all rows belonging to a
                // corresponding day in the current month's bill.
                // Consume the batch
                // Subtract 1, to account for detecting date change line.
                status.setNoLinesRead(csvReader.getLinesRead() - 1);
                dailyStatsConsumer.accept(monthlyBill, null);
                break;
            }
            prevRowEpoch = curRowEpoch;
        }
        if ((nextRow == null && monthlyBill.size() > 0) || (nextRow == null && csvReader.getLinesRead() == AzureCostConstants.DEFAULT_LINES_TO_SKIP)) {
            status.setParsingComplete(true);
            dailyStatsConsumer.accept(monthlyBill, billProcessedTimeMillis);
            logger.fine(() -> "Finished parsing CSV bill.");
        }
        return status;
    }
}
Also used : CSVReader(com.opencsv.CSVReader) HashMap(java.util.HashMap) EaDetailedBillElement(com.vmware.photon.controller.model.adapters.azure.model.cost.EaDetailedBillElement) AzureSubscription(com.vmware.photon.controller.model.adapters.azure.model.cost.AzureSubscription) HeaderColumnNameMappingStrategy(com.opencsv.bean.HeaderColumnNameMappingStrategy) AzureService(com.vmware.photon.controller.model.adapters.azure.model.cost.AzureService) FileReader(java.io.FileReader)

Aggregations

EaDetailedBillElement (com.vmware.photon.controller.model.adapters.azure.model.cost.EaDetailedBillElement)3 CSVReader (com.opencsv.CSVReader)1 HeaderColumnNameMappingStrategy (com.opencsv.bean.HeaderColumnNameMappingStrategy)1 AzureService (com.vmware.photon.controller.model.adapters.azure.model.cost.AzureService)1 AzureSubscription (com.vmware.photon.controller.model.adapters.azure.model.cost.AzureSubscription)1 FileReader (java.io.FileReader)1 HashMap (java.util.HashMap)1