You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dlab.apache.org by of...@apache.org on 2020/04/08 11:44:03 UTC
[incubator-dlab] 02/02: billing
This is an automated email from the ASF dual-hosted git repository.
ofuks pushed a commit to branch DLAB-1571
in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git
commit 754252d33ae4e33a95323ad8f892ee19ad89d891
Author: Oleh Fuks <ol...@gmail.com>
AuthorDate: Wed Apr 8 14:43:28 2020 +0300
billing
---
.../billing/gcp/controller/BillingController.java | 8 -
.../com/epam/dlab/billing/gcp/dao/BillingDAO.java | 5 -
.../billing/gcp/dao/impl/BigQueryBillingDAO.java | 82 ----------
.../gcp/service/impl/BillingServiceImpl.java | 9 --
.../com/epam/dlab/dto/billing/BillingData.java | 1 +
services/self-service/self-service.yml | 3 +
.../epam/dlab/backendapi/dao/BaseBillingDAO.java | 109 ++++++++++++-
.../java/com/epam/dlab/backendapi/dao/BaseDAO.java | 64 +++++++-
.../com/epam/dlab/backendapi/dao/BillingDAO.java | 13 ++
.../dlab/backendapi/domain/BillingReportLine.java | 4 +
.../resources/dto/ProjectInfrastructureInfo.java | 4 +-
.../schedulers/billing/BillingScheduler.java | 52 ++++++
.../dlab/backendapi/service/BillingService.java | 6 +-
.../service/impl/BillingServiceImpl.java | 177 +++++++++------------
.../impl/InfrastructureInfoServiceImpl.java | 32 ++--
.../epam/dlab/backendapi/util/BillingUtils.java | 8 +-
16 files changed, 333 insertions(+), 244 deletions(-)
diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/controller/BillingController.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/controller/BillingController.java
index c1b178a..ea45d89 100644
--- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/controller/BillingController.java
+++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/controller/BillingController.java
@@ -41,12 +41,4 @@ public class BillingController {
public ResponseEntity<List<BillingData>> getBilling() {
return new ResponseEntity<>(billingService.getBillingData(), HttpStatus.OK);
}
-
-// @GetMapping("/report")
-// public ResponseEntity<List<BillingData>> getBilling(@RequestParam("date-start") String dateStart,
-// @RequestParam("date-end") String dateEnd,
-// @RequestParam("dlab-id") String dlabId,
-// @RequestParam("product") List<String> products) {
-// return new ResponseEntity<>(billingDAO.getBillingReport(dateStart, dateEnd, dlabId, products), HttpStatus.OK);
-// }
}
diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/BillingDAO.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/BillingDAO.java
index 0a04502..7c791df 100644
--- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/BillingDAO.java
+++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/BillingDAO.java
@@ -24,10 +24,5 @@ import com.epam.dlab.dto.billing.BillingData;
import java.util.List;
public interface BillingDAO {
-
List<BillingData> getBillingData() throws InterruptedException;
-
- List<BillingData> getBillingReport(String dateStart, String dateEnd, String dlabId, List<String> products);
-
- List<BillingData> getBillingReport(List<String> dlabIds);
}
diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/impl/BigQueryBillingDAO.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/impl/BigQueryBillingDAO.java
index ef28679..6949d95 100644
--- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/impl/BigQueryBillingDAO.java
+++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/impl/BigQueryBillingDAO.java
@@ -22,10 +22,8 @@ package com.epam.dlab.billing.gcp.dao.impl;
import com.epam.dlab.billing.gcp.conf.DlabConfiguration;
import com.epam.dlab.billing.gcp.dao.BillingDAO;
import com.epam.dlab.billing.gcp.model.BillingHistory;
-import com.epam.dlab.billing.gcp.model.GcpBillingData;
import com.epam.dlab.billing.gcp.repository.BillingHistoryRepository;
import com.epam.dlab.dto.billing.BillingData;
-import com.epam.dlab.exceptions.DlabException;
import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.FieldValueList;
import com.google.cloud.bigquery.QueryJobConfiguration;
@@ -33,32 +31,20 @@ import com.google.cloud.bigquery.QueryParameterValue;
import com.google.cloud.bigquery.Table;
import com.google.cloud.bigquery.TableInfo;
import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
-import org.springframework.data.mongodb.core.aggregation.Aggregation;
-import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
-import org.springframework.data.mongodb.core.aggregation.GroupOperation;
-import org.springframework.data.mongodb.core.aggregation.MatchOperation;
-import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Component;
-import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
-import static org.springframework.data.mongodb.core.aggregation.Aggregation.group;
-import static org.springframework.data.mongodb.core.aggregation.Aggregation.newAggregation;
-
@Component
@Slf4j
public class BigQueryBillingDAO implements BillingDAO {
@@ -107,62 +93,6 @@ public class BigQueryBillingDAO implements BillingDAO {
.collect(Collectors.toList());
}
- @Override
- public List<BillingData> getBillingReport(String dateStart, String dateEnd, String dlabId, List<String> products) {
- try {
- List<AggregationOperation> aggregationOperations = new ArrayList<>();
- aggregationOperations.add(Aggregation.match(Criteria.where("dlabId").regex(dlabId, "i")));
- if (!products.isEmpty()) {
- aggregationOperations.add(Aggregation.match(Criteria.where("product").in(products)));
- }
- getMatchCriteria(dateStart, Criteria.where("usage_date").gte(dateStart))
- .ifPresent(aggregationOperations::add);
- getMatchCriteria(dateEnd, Criteria.where("usage_date").lte(dateEnd))
- .ifPresent(aggregationOperations::add);
- aggregationOperations.add(getGroupOperation());
-
- Aggregation aggregation = newAggregation(aggregationOperations);
-
- return mongoTemplate.aggregate(aggregation, "billing", GcpBillingData.class).getMappedResults()
- .stream()
- .map(this::toBillingData)
- .collect(Collectors.toList());
- } catch (Exception e) {
- log.error("Cannot retrieve billing information ", e);
- throw new DlabException("Cannot retrieve billing information", e);
- }
- }
-
- @Override
- public List<BillingData> getBillingReport(List<String> dlabIds) {
- try {
- GroupOperation groupOperation = getGroupOperation();
- MatchOperation matchOperation = Aggregation.match(Criteria.where("dlabId").in(dlabIds));
- Aggregation aggregation = newAggregation(matchOperation, groupOperation);
-
- return mongoTemplate.aggregate(aggregation, "billing", GcpBillingData.class).getMappedResults()
- .stream()
- .map(this::toBillingData)
- .collect(Collectors.toList());
- } catch (Exception e) {
- log.error("Cannot retrieve billing information ", e);
- throw new DlabException("Cannot retrieve billing information", e);
- }
- }
-
- private GroupOperation getGroupOperation() {
- return group("product", "currency", "dlabId")
- .min("from").as("from")
- .max("to").as("to")
- .sum("cost").as("cost");
- }
-
- private Optional<MatchOperation> getMatchCriteria(String dateStart, Criteria criteria) {
- return Optional.ofNullable(dateStart)
- .filter(StringUtils::isNotEmpty)
- .map(date -> Aggregation.match(criteria));
- }
-
private Stream<? extends BillingData> bigQueryResultSetStream(Table table) {
try {
final String tableName = table.getTableId().getTable();
@@ -199,16 +129,4 @@ public class BigQueryBillingDAO implements BillingDAO {
return LocalDate.from(Instant.ofEpochMilli(fieldValues.get(timestampFieldName).getTimestampValue() / 1000)
.atZone(ZoneId.systemDefault()));
}
-
- private BillingData toBillingData(GcpBillingData billingData) {
- return BillingData.builder()
- .usageDateFrom(billingData.getUsageDateFrom())
- .usageDateTo(billingData.getUsageDateTo())
- .product(billingData.getProduct())
- .usageType(billingData.getUsageType())
- .cost(BigDecimal.valueOf(billingData.getCost()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue())
- .currency(billingData.getCurrency())
- .tag(billingData.getTag())
- .build();
- }
}
diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/impl/BillingServiceImpl.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/impl/BillingServiceImpl.java
index 12e526b..5661dfb 100644
--- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/impl/BillingServiceImpl.java
+++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/impl/BillingServiceImpl.java
@@ -32,7 +32,6 @@ import java.util.List;
@Service
@Slf4j
public class BillingServiceImpl implements BillingService {
- private static final String USAGE_DATE_FORMAT = "yyyy-MM";
private final BillingDAO billingDAO;
@@ -45,14 +44,6 @@ public class BillingServiceImpl implements BillingService {
public List<BillingData> getBillingData() {
try {
return billingDAO.getBillingData();
-// .stream()
-// .collect(Collectors.groupingBy(bd -> bd.getUsageDate().substring(0, USAGE_DATE_FORMAT.length())));
-
-// billingData.forEach((usageDate, billingDataList) -> {
-// log.info("Updating billing information for month {}", usageDate);
-// billingRepository.deleteByUsageDateRegex("^" + usageDate);
-// billingRepository.insert(billingDataList);
-// });
} catch (Exception e) {
log.error("Can not update billing due to: {}", e.getMessage(), e);
return Collections.emptyList();
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/billing/BillingData.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/billing/BillingData.java
index 8409fc0..c95a02e 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/billing/BillingData.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/billing/BillingData.java
@@ -31,6 +31,7 @@ import java.time.LocalDate;
@JsonIgnoreProperties(ignoreUnknown = true)
public class BillingData {
private final String tag;
+ private String application;
@JsonProperty("from")
private LocalDate usageDateFrom;
@JsonProperty("to")
diff --git a/services/self-service/self-service.yml b/services/self-service/self-service.yml
index 53bd131..4e71316 100644
--- a/services/self-service/self-service.yml
+++ b/services/self-service/self-service.yml
@@ -150,6 +150,9 @@ schedulers:
checkEndpointStatusScheduler:
enabled: true
cron: "0 */15 * ? * *"
+ billingScheduler:
+ enabled: true
+ cron: "*/50 * * ? * * *"
guacamole:
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BaseBillingDAO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BaseBillingDAO.java
index d22e400..0612a1a 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BaseBillingDAO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BaseBillingDAO.java
@@ -19,30 +19,56 @@
package com.epam.dlab.backendapi.dao;
+import com.epam.dlab.backendapi.domain.BillingReportLine;
+import com.epam.dlab.backendapi.resources.dto.BillingFilter;
+import com.epam.dlab.dto.billing.BillingResourceType;
import com.google.inject.Inject;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.bson.Document;
import org.bson.conversions.Bson;
import java.math.BigDecimal;
+import java.time.ZoneId;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
import static com.epam.dlab.backendapi.dao.MongoCollections.BILLING;
+import static com.mongodb.client.model.Accumulators.max;
+import static com.mongodb.client.model.Accumulators.min;
import static com.mongodb.client.model.Accumulators.sum;
import static com.mongodb.client.model.Aggregates.group;
import static com.mongodb.client.model.Aggregates.match;
+import static com.mongodb.client.model.Filters.and;
import static com.mongodb.client.model.Filters.eq;
+import static com.mongodb.client.model.Filters.gte;
+import static com.mongodb.client.model.Filters.in;
+import static com.mongodb.client.model.Filters.lte;
+import static com.mongodb.client.model.Filters.regex;
import static java.util.Collections.singletonList;
@Slf4j
public class BaseBillingDAO extends BaseDAO implements BillingDAO {
-
- private static final String PROJECT = "project";
private static final int ONE_HUNDRED = 100;
- private static final String TOTAL_FIELD_NAME = "total";
private static final String COST_FIELD = "$cost";
+ private static final String TOTAL_FIELD_NAME = "total";
+ private static final String PROJECT = "project";
+ private static final String APPLICATION = "application";
+ private static final String USAGE_DATE = "usageDate";
+ private static final String USER = "user";
+ private static final String RESOURCE_TYPE = "resource_type";
+ private static final String DLAB_ID = "dlabId";
+ private static final String FROM = "from";
+ private static final String TO = "to";
+ private static final String PRODUCT = "product";
+ private static final String CURRENCY = "currency";
+ private static final String COST = "cost";
@Inject
protected SettingsDAO settings;
@@ -102,10 +128,37 @@ public class BaseBillingDAO extends BaseDAO implements BillingDAO {
}
@Override
+ public List<BillingReportLine> findBillingData(List<String> dlabIds) {
+ return find(BILLING, in(DLAB_ID, dlabIds), BillingReportLine.class);
+ }
+
+ @Override
public int getBillingProjectQuoteUsed(String project) {
return toPercentage(() -> projectDAO.getAllowedBudget(project), getProjectCost(project));
}
+ public List<BillingReportLine> aggregateBillingData(BillingFilter filter) {
+ List<Bson> pipeline = new ArrayList<>();
+ List<Bson> matchCriteria = matchCriteria(filter);
+ if (!matchCriteria.isEmpty()) {
+ pipeline.addAll(matchCriteria);
+ }
+ pipeline.add(groupCriteria());
+ return StreamSupport.stream(getCollection(BILLING).aggregate(pipeline).spliterator(), false)
+ .map(this::toBillingReport)
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public void deleteByUsageDate(String application, String usageDate) {
+ deleteMany(BILLING, and(eq(APPLICATION, application), regex(USAGE_DATE, "^" + usageDate)));
+ }
+
+ @Override
+ public void save(List<BillingReportLine> billingData) {
+ insertMany(BILLING, new ArrayList<>(billingData));
+ }
+
private Integer toPercentage(Supplier<Optional<Integer>> allowedBudget, Double totalCost) {
return allowedBudget.get()
.map(userBudget -> (totalCost * ONE_HUNDRED) / userBudget)
@@ -118,4 +171,54 @@ public class BaseBillingDAO extends BaseDAO implements BillingDAO {
.map(d -> d.getDouble(TOTAL_FIELD_NAME))
.orElse(BigDecimal.ZERO.doubleValue());
}
+
+ private Bson groupCriteria() {
+ return group(getGroupingFields(USER, DLAB_ID, RESOURCE_TYPE, PROJECT, PRODUCT, CURRENCY),
+ sum(COST, "$" + COST),
+ min(FROM, "$" + FROM),
+ max(TO, "$" + TO));
+ }
+
+ private List<Bson> matchCriteria(BillingFilter filter) {
+ List<Bson> searchCriteria = new ArrayList<>();
+
+ if (CollectionUtils.isNotEmpty(filter.getUsers())) {
+ searchCriteria.add(in(USER, filter.getUsers()));
+ }
+ if (CollectionUtils.isNotEmpty(filter.getResourceTypes())) {
+ searchCriteria.add(in(RESOURCE_TYPE, filter.getResourceTypes()));
+ }
+ if (StringUtils.isNotEmpty(filter.getDlabId())) {
+ searchCriteria.add(regex(DLAB_ID, filter.getDlabId(), "i"));
+ }
+ if (StringUtils.isNotEmpty(filter.getDateStart())) {
+ searchCriteria.add(gte(FROM, filter.getDateStart()));
+ }
+ if (StringUtils.isNotEmpty(filter.getDateEnd())) {
+ searchCriteria.add(lte(TO, filter.getDateEnd()));
+ }
+ if (CollectionUtils.isNotEmpty(filter.getProjects())) {
+ searchCriteria.add(in(PROJECT, filter.getProjects()));
+ }
+ if (CollectionUtils.isNotEmpty(filter.getProducts())) {
+ searchCriteria.add(in(PRODUCT, filter.getProducts()));
+ }
+
+ return searchCriteria;
+ }
+
+ private BillingReportLine toBillingReport(Document d) {
+ Document id = (Document) d.get("_id");
+ return BillingReportLine.builder()
+ .dlabId(id.getString(DLAB_ID))
+ .project(id.getString(PROJECT))
+ .user(id.getString(USER))
+ .product(id.getString(PRODUCT))
+ .resourceType(BillingResourceType.valueOf(id.getString(RESOURCE_TYPE)))
+ .usageDateFrom(d.getDate(FROM).toInstant().atZone(ZoneId.systemDefault()).toLocalDate())
+ .usageDateTo(d.getDate(TO).toInstant().atZone(ZoneId.systemDefault()).toLocalDate())
+ .cost(d.getDouble(COST))
+ .currency(id.getString(CURRENCY))
+ .build();
+ }
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BaseDAO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BaseDAO.java
index 034011a..c2ff69b 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BaseDAO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BaseDAO.java
@@ -31,7 +31,11 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.inject.Inject;
import com.mongodb.BasicDBObject;
import com.mongodb.MongoException;
-import com.mongodb.client.*;
+import com.mongodb.client.AggregateIterable;
+import com.mongodb.client.FindIterable;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoCursor;
+import com.mongodb.client.MongoIterable;
import com.mongodb.client.model.UpdateOptions;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
@@ -41,13 +45,21 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
-import static com.mongodb.client.model.Filters.*;
+import static com.mongodb.client.model.Filters.and;
+import static com.mongodb.client.model.Filters.exists;
+import static com.mongodb.client.model.Filters.ne;
/**
* Implements the base API for Mongo database.
@@ -158,6 +170,29 @@ public class BaseDAO {
}
/**
+ * Serializes objects and inserts into the collection.
+ *
+ * @param collection collection name.
+ * @param object for inserting to collection.
+ */
+ protected void insertMany(String collection, List<Object> object) {
+ try {
+ mongoService.getCollection(collection)
+ .insertMany(convertToBson(object)
+ .stream()
+ .peek(o -> {
+ o.append(ID, generateUUID());
+ o.append(TIMESTAMP, new Date());
+ })
+ .collect(Collectors.toList())
+ );
+ } catch (MongoException e) {
+ LOGGER.warn("Insert to Mongo DB fails: {}", e.getLocalizedMessage(), e);
+ throw new DlabException("Insert to Mongo DB fails: " + e.getLocalizedMessage(), e);
+ }
+ }
+
+ /**
* Updates single document in the collection by condition.
*
* @param collection collection name.
@@ -230,6 +265,22 @@ public class BaseDAO {
}
/**
+ * Removes many documents in the collection by condition.
+ *
+ * @param collection collection name.
+ * @param condition condition for search documents in collection.
+ */
+ protected DeleteResult deleteMany(String collection, Bson condition) {
+ try {
+ return mongoService.getCollection(collection)
+ .deleteMany(condition);
+ } catch (MongoException e) {
+ LOGGER.warn("Removing document from Mongo DB fails: {}", e.getLocalizedMessage(), e);
+ throw new DlabException("Removing document from Mongo DB fails: " + e.getLocalizedMessage(), e);
+ }
+ }
+
+ /**
* Finds and returns all documents from the collection.
*
* @param collection collection name.
@@ -362,6 +413,13 @@ public class BaseDAO {
}
}
+ List<Document> convertToBson(List<Object> objects) {
+ return objects
+ .stream()
+ .map(this::convertToBson)
+ .collect(Collectors.toList());
+ }
+
/**
* Finds and returns one object as given class from the collection by condition.
*
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BillingDAO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BillingDAO.java
index d50c62f..3a00d5b 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BillingDAO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BillingDAO.java
@@ -18,6 +18,11 @@
*/
package com.epam.dlab.backendapi.dao;
+import com.epam.dlab.backendapi.domain.BillingReportLine;
+import com.epam.dlab.backendapi.resources.dto.BillingFilter;
+
+import java.util.List;
+
public interface BillingDAO {
Double getTotalCost();
@@ -36,4 +41,12 @@ public interface BillingDAO {
boolean isUserQuoteReached(String user);
boolean isProjectQuoteReached(String project);
+
+ List<BillingReportLine> findBillingData(List<String> dlabIds);
+
+ List<BillingReportLine> aggregateBillingData(BillingFilter filter);
+
+ void deleteByUsageDate(String application, String usageDate);
+
+ void save(List<BillingReportLine> billingData);
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BillingReportLine.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BillingReportLine.java
index ed97a44..123a5c3 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BillingReportLine.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BillingReportLine.java
@@ -21,6 +21,7 @@ package com.epam.dlab.backendapi.domain;
import com.epam.dlab.dto.UserInstanceStatus;
import com.epam.dlab.dto.billing.BillingResourceType;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Data;
@@ -29,8 +30,10 @@ import java.time.LocalDate;
@Data
@Builder
+@JsonIgnoreProperties(ignoreUnknown = true)
public class BillingReportLine {
private String dlabId;
+ private String application;
@JsonProperty("resource_name")
private String resourceName;
private String project;
@@ -39,6 +42,7 @@ public class BillingReportLine {
private LocalDate usageDateFrom;
@JsonProperty("to")
private LocalDate usageDateTo;
+ private String usageDate;
private String product;
private String usageType;
private Double cost;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/ProjectInfrastructureInfo.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/ProjectInfrastructureInfo.java
index e1f09e9..d215ac2 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/ProjectInfrastructureInfo.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/ProjectInfrastructureInfo.java
@@ -19,8 +19,8 @@
package com.epam.dlab.backendapi.resources.dto;
+import com.epam.dlab.backendapi.domain.BillingReportLine;
import com.epam.dlab.backendapi.domain.EndpointDTO;
-import com.epam.dlab.dto.billing.BillingData;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.ToString;
@@ -41,7 +41,7 @@ public class ProjectInfrastructureInfo {
@JsonProperty
private Iterable<Document> exploratory;
@JsonProperty
- private List<BillingData> exploratoryBilling;
+ private List<BillingReportLine> exploratoryBilling;
@JsonProperty
private List<EndpointDTO> endpoints;
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/billing/BillingScheduler.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/billing/BillingScheduler.java
new file mode 100644
index 0000000..45563a2
--- /dev/null
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/billing/BillingScheduler.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.epam.dlab.backendapi.schedulers.billing;
+
+import com.epam.dlab.backendapi.schedulers.internal.Scheduled;
+import com.epam.dlab.backendapi.service.BillingService;
+import com.epam.dlab.backendapi.service.SecurityService;
+import com.google.inject.Inject;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+
+@Scheduled("billingScheduler")
+@Slf4j
+public class BillingScheduler implements Job {
+
+ private final BillingService billingService;
+ private final SecurityService securityService;
+
+ @Inject
+ public BillingScheduler(BillingService billingService, SecurityService securityService) {
+ this.billingService = billingService;
+ this.securityService = securityService;
+ }
+
+ @Override
+ public void execute(JobExecutionContext jobExecutionContext) {
+ log.info("Trying to update billing");
+ try {
+ billingService.updateRemoteBillingData(securityService.getServiceAccountInfo("admin"));
+ } catch (Exception e) {
+ log.error("Something went wrong {}", e.getMessage());
+ }
+ }
+}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/BillingService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/BillingService.java
index 40a5c14..7d30f74 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/BillingService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/BillingService.java
@@ -23,8 +23,6 @@ import com.epam.dlab.auth.UserInfo;
import com.epam.dlab.backendapi.domain.BillingReport;
import com.epam.dlab.backendapi.domain.BillingReportLine;
import com.epam.dlab.backendapi.resources.dto.BillingFilter;
-import com.epam.dlab.dto.UserInstanceDTO;
-import com.epam.dlab.dto.billing.BillingData;
import java.util.List;
@@ -33,7 +31,7 @@ public interface BillingService {
String downloadReport(UserInfo userInfo, BillingFilter filter);
- List<BillingReportLine> getBillingReportLines(UserInfo userInfo, BillingFilter filter);
+ List<BillingReportLine> getExploratoryBillingData(String exploratoryId, List<String> resources);
- List<BillingData> getExploratoryRemoteBillingData(UserInfo user, String endpoint, List<UserInstanceDTO> userInstanceDTOS);
+ void updateRemoteBillingData(UserInfo userInfo);
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImpl.java
index 7d6ab11..fdbb789 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImpl.java
@@ -21,6 +21,7 @@ package com.epam.dlab.backendapi.service.impl;
import com.epam.dlab.auth.UserInfo;
import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
+import com.epam.dlab.backendapi.dao.BillingDAO;
import com.epam.dlab.backendapi.dao.ImageExploratoryDao;
import com.epam.dlab.backendapi.domain.BillingReport;
import com.epam.dlab.backendapi.domain.BillingReportLine;
@@ -35,8 +36,8 @@ import com.epam.dlab.backendapi.service.EndpointService;
import com.epam.dlab.backendapi.service.ExploratoryService;
import com.epam.dlab.backendapi.service.ProjectService;
import com.epam.dlab.backendapi.util.BillingUtils;
+import com.epam.dlab.cloud.CloudProvider;
import com.epam.dlab.constants.ServiceConsts;
-import com.epam.dlab.dto.UserInstanceDTO;
import com.epam.dlab.dto.billing.BillingData;
import com.epam.dlab.exceptions.DlabException;
import com.epam.dlab.rest.client.RESTService;
@@ -52,7 +53,6 @@ import java.math.BigDecimal;
import java.net.URI;
import java.net.URISyntaxException;
import java.time.LocalDate;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -61,19 +61,12 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-
@Slf4j
public class BillingServiceImpl implements BillingService {
private static final String BILLING_PATH = "/api/billing";
- private static final String BILLING_REPORT_PATH = "/api/billing/report";
+ private static final String USAGE_DATE_FORMAT = "yyyy-MM";
private final ProjectService projectService;
private final EndpointService endpointService;
@@ -81,24 +74,28 @@ public class BillingServiceImpl implements BillingService {
private final SelfServiceApplicationConfiguration configuration;
private final RESTService provisioningService;
private final ImageExploratoryDao imageExploratoryDao;
+ private final BillingDAO billingDAO;
private final String sbn;
@Inject
public BillingServiceImpl(ProjectService projectService, EndpointService endpointService,
ExploratoryService exploratoryService, SelfServiceApplicationConfiguration configuration,
- @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService, ImageExploratoryDao imageExploratoryDao) {
+ @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService, ImageExploratoryDao imageExploratoryDao,
+ BillingDAO billingDAO) {
this.projectService = projectService;
this.endpointService = endpointService;
this.exploratoryService = exploratoryService;
this.configuration = configuration;
this.provisioningService = provisioningService;
this.imageExploratoryDao = imageExploratoryDao;
+ this.billingDAO = billingDAO;
sbn = configuration.getServiceBaseName();
}
@Override
public BillingReport getBillingReport(UserInfo user, BillingFilter filter) {
- List<BillingReportLine> billingReportLines = getBillingReportLines(user, filter);
+ setUserFilter(user, filter);
+ List<BillingReportLine> billingReportLines = billingDAO.aggregateBillingData(filter);
LocalDate min = billingReportLines.stream().min(Comparator.comparing(BillingReportLine::getUsageDateFrom)).map(BillingReportLine::getUsageDateFrom).orElse(null);
LocalDate max = billingReportLines.stream().max(Comparator.comparing(BillingReportLine::getUsageDateTo)).map(BillingReportLine::getUsageDateTo).orElse(null);
double sum = billingReportLines.stream().mapToDouble(BillingReportLine::getCost).sum();
@@ -129,31 +126,57 @@ public class BillingServiceImpl implements BillingService {
}
}
- @Override
- public List<BillingReportLine> getBillingReportLines(UserInfo user, BillingFilter filter) {
- setUserFilter(user, filter);
- Set<ProjectDTO> projects;
- if (isFullReport(user)) {
- projects = new HashSet<>(projectService.getProjects());
- } else {
- projects = new HashSet<>(projectService.getProjects(user));
- projects.addAll(projectService.getUserProjects(user, false));
+ public List<BillingReportLine> getExploratoryBillingData(String exploratoryId, List<String> resources) {
+ List<String> dlabIds = null;
+ try {
+ dlabIds = Stream.concat(
+ BillingUtils.getExploratoryIds(exploratoryId).stream(),
+ resources
+ .stream()
+ .map(BillingUtils::getComputationalIds)
+ .flatMap(Collection::stream)
+ )
+ .collect(Collectors.toList());
+
+ return billingDAO.findBillingData(dlabIds);
+ } catch (Exception e) {
+ log.error("Cannot retrieve billing information for {} {}", dlabIds, e.getMessage());
+ return Collections.emptyList();
}
+ }
- final Map<String, BillingReportLine> billableResources = getBillableResources(projects);
+ public void updateRemoteBillingData(UserInfo userInfo) {
+ try {
+ List<EndpointDTO> endpoints = endpointService.getEndpoints();
+ if (CollectionUtils.isEmpty(endpoints)) {
+ log.error("Cannot update billing info. There are no endpoints");
+ throw new DlabException("Cannot update billing info. There are no endpoints");
+ }
- List<BillingReportLine> billingReport = getRemoteBillingData(user, filter)
- .stream()
- .filter(bd -> billableResources.containsKey(bd.getTag()))
- .map(bd -> toBillingData(bd, billableResources.get(bd.getTag())))
- .filter(getBillingReportFilter(filter))
- .collect(Collectors.toList());
- log.debug("Billing report: {}", billingReport);
+ Map<EndpointDTO, List<BillingData>> billingDataMap = endpoints
+ .stream()
+ .collect(Collectors.toMap(e -> e, e -> provisioningService.get(getBillingUrl(e.getUrl(), BILLING_PATH), userInfo.getAccessToken(),
+ new GenericType<List<BillingData>>() {
+ })));
- return billingReport;
+ billingDataMap.forEach((endpointDTO, billingData) -> {
+ log.info("Updating billing information for endpoint {}", endpointDTO.getName());
+ updateBillingData(userInfo, endpointDTO, billingData);
+ });
+ } catch (DlabException e) {
+ log.error("Cannot retrieve billing information for {}", e.getMessage());
+ }
}
- private Map<String, BillingReportLine> getBillableResources(Set<ProjectDTO> projects) {
+ private Map<String, BillingReportLine> getBillableResources(UserInfo userInfo) {
+ Set<ProjectDTO> projects;
+ if (isFullReport(userInfo)) {
+ projects = new HashSet<>(projectService.getProjects());
+ } else {
+ projects = new HashSet<>(projectService.getProjects(userInfo));
+ projects.addAll(projectService.getUserProjects(userInfo, false));
+ }
+
final Stream<BillingReportLine> ssnBillingDataStream = BillingUtils.ssnBillingDataStream(sbn);
final Stream<BillingReportLine> billableEdges = projects
.stream()
@@ -189,59 +212,27 @@ public class BillingServiceImpl implements BillingService {
endpoint.getStatus().toString()));
}
- public List<BillingData> getExploratoryRemoteBillingData(UserInfo user, String endpoint, List<UserInstanceDTO> userInstanceDTOS) {
- List<String> dlabIds = null;
- try {
- dlabIds = userInstanceDTOS
- .stream()
- .map(instance -> Stream.concat(BillingUtils.getExploratoryIds(instance.getExploratoryId()).stream(), instance.getResources()
- .stream()
- .map(cr -> BillingUtils.getComputationalIds(cr.getComputationalId()))
- .flatMap(Collection::stream)
- ))
- .flatMap(a -> a)
- .collect(Collectors.toList());
-
- EndpointDTO endpointDTO = endpointService.get(endpoint);
- return provisioningService.get(getBillingUrl(endpointDTO.getUrl(), BILLING_PATH), user.getAccessToken(),
- new GenericType<List<BillingData>>() {
- }, Collections.singletonMap("dlabIds", String.join(",", dlabIds)));
- } catch (Exception e) {
- log.error("Cannot retrieve billing information for {} {}", dlabIds, e.getMessage());
- return Collections.emptyList();
- }
- }
-
- private List<BillingData> getRemoteBillingData(UserInfo userInfo, BillingFilter filter) {
- List<EndpointDTO> endpoints = endpointService.getEndpoints();
- ExecutorService executor = Executors.newFixedThreadPool(endpoints.size());
- List<Callable<List<BillingData>>> callableTasks = new ArrayList<>();
- endpoints.forEach(e -> callableTasks.add(getTask(userInfo, getBillingUrl(e.getUrl(), BILLING_REPORT_PATH), filter)));
+ private void updateBillingData(UserInfo userInfo, EndpointDTO endpointDTO, List<BillingData> billingData) {
+ final String endpointName = endpointDTO.getName();
+ final Map<String, BillingReportLine> billableResources = getBillableResources(userInfo);
- List<BillingData> billingData;
- try {
- log.debug("Trying to retrieve billing info for {}", endpoints);
- billingData = executor.invokeAll(callableTasks)
+ if (endpointDTO.getCloudProvider() == CloudProvider.GCP) {
+ final Map<String, List<BillingReportLine>> gcpBillingData = billingData
.stream()
- .map(this::getBillingReportDTOS)
- .flatMap(Collection::stream)
- .collect(Collectors.toList());
- } catch (Exception e) {
- executor.shutdown();
- log.error("Cannot retrieve billing information {}", e.getMessage(), e);
- throw new DlabException("Cannot retrieve billing information", e);
+ .filter(bd -> billableResources.containsKey(bd.getTag()))
+ .peek(bd -> bd.setApplication(endpointName))
+ .map(bd -> toBillingData(bd, billableResources.get(bd.getTag())))
+ .collect(Collectors.groupingBy(bd -> bd.getUsageDate().substring(0, USAGE_DATE_FORMAT.length())));
+
+ updateGcpBillingData(endpointName, gcpBillingData);
}
- executor.shutdown();
- return billingData;
}
- private List<BillingData> getBillingReportDTOS(Future<List<BillingData>> s) {
- try {
- return s.get();
- } catch (InterruptedException | ExecutionException e) {
- log.error("Cannot retrieve billing information {}", e.getMessage());
- return Collections.emptyList();
- }
+ private void updateGcpBillingData(String endpointName, Map<String, List<BillingReportLine>> billingData) {
+ billingData.forEach((usageDate, billingReportLines) -> {
+ billingDAO.deleteByUsageDate(endpointName, usageDate);
+ billingDAO.save(billingReportLines);
+ });
}
private String getBillingUrl(String endpointUrl, String path) {
@@ -260,27 +251,6 @@ public class BillingServiceImpl implements BillingService {
.toString();
}
- private Callable<List<BillingData>> getTask(UserInfo userInfo, String url, BillingFilter filter) {
- return () -> provisioningService.get(url, userInfo.getAccessToken(),
- new GenericType<List<BillingData>>() {
- },
- Stream.of(new String[][]{
- {"date-start", filter.getDateStart()},
- {"date-end", filter.getDateEnd()},
- {"dlab-id", filter.getDlabId()},
- {"product", String.join(",", filter.getProducts())}
- }).collect(Collectors.toMap(data -> data[0], data -> data[1])));
- }
-
- private Predicate<BillingReportLine> getBillingReportFilter(BillingFilter filter) {
- return br ->
- (CollectionUtils.isEmpty(filter.getUsers()) || filter.getUsers().contains(br.getUser())) &&
- (CollectionUtils.isEmpty(filter.getProjects()) || filter.getProjects().contains(br.getProject())) &&
- (CollectionUtils.isEmpty(filter.getResourceTypes()) || filter.getResourceTypes().contains(String.valueOf(br.getResourceType()))) &&
- (CollectionUtils.isEmpty(filter.getStatuses()) || filter.getStatuses().contains(br.getStatus())) &&
- (CollectionUtils.isEmpty(filter.getShapes()) || filter.getShapes().contains(br.getShape()));
- }
-
private boolean isFullReport(UserInfo userInfo) {
return UserRoles.checkAccess(userInfo, RoleType.PAGE, "/api/infrastructure_provision/billing",
userInfo.getRoles());
@@ -294,18 +264,19 @@ public class BillingServiceImpl implements BillingService {
private BillingReportLine toBillingData(BillingData billingData, BillingReportLine billingReportLine) {
return BillingReportLine.builder()
- .cost(billingData.getCost())
+ .application(billingData.getApplication())
+ .cost(BigDecimal.valueOf(billingData.getCost()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue())
.currency(billingData.getCurrency())
.product(billingData.getProduct())
.project(billingReportLine.getProject())
- .usageDateTo(billingData.getUsageDateTo())
.usageDateFrom(billingData.getUsageDateFrom())
+ .usageDateTo(billingData.getUsageDateTo())
+ .usageDate(billingData.getUsageDate())
.usageType(billingData.getUsageType())
.user(billingReportLine.getUser())
.dlabId(billingData.getTag())
.resourceType(billingReportLine.getResourceType())
.resourceName(billingReportLine.getResourceName())
- .status(billingReportLine.getStatus())
.shape(billingReportLine.getShape())
.build();
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/InfrastructureInfoServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/InfrastructureInfoServiceImpl.java
index 28b94e9..88f4b9a 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/InfrastructureInfoServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/InfrastructureInfoServiceImpl.java
@@ -22,8 +22,8 @@ package com.epam.dlab.backendapi.service.impl;
import com.epam.dlab.auth.UserInfo;
import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
import com.epam.dlab.backendapi.dao.BillingDAO;
-import com.epam.dlab.backendapi.dao.EnvDAO;
import com.epam.dlab.backendapi.dao.ExploratoryDAO;
+import com.epam.dlab.backendapi.domain.BillingReportLine;
import com.epam.dlab.backendapi.domain.EndpointDTO;
import com.epam.dlab.backendapi.domain.ProjectEndpointDTO;
import com.epam.dlab.backendapi.resources.dto.HealthStatusEnum;
@@ -38,7 +38,6 @@ import com.epam.dlab.dto.InfrastructureMetaInfoDTO;
import com.epam.dlab.dto.aws.edge.EdgeInfoAws;
import com.epam.dlab.dto.azure.edge.EdgeInfoAzure;
import com.epam.dlab.dto.base.edge.EdgeInfo;
-import com.epam.dlab.dto.billing.BillingData;
import com.epam.dlab.dto.gcp.edge.EdgeInfoGcp;
import com.epam.dlab.exceptions.DlabException;
import com.google.inject.Inject;
@@ -46,7 +45,6 @@ import com.jcabi.manifests.Manifests;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -62,7 +60,6 @@ public class InfrastructureInfoServiceImpl implements InfrastructureInfoService
private static final String RELEASE_NOTES_FORMAT = "https://github.com/apache/incubator-dlab/blob/%s" +
"/RELEASE_NOTES.md";
private final ExploratoryDAO expDAO;
- private final EnvDAO envDAO;
private final SelfServiceApplicationConfiguration configuration;
private final BillingDAO billingDAO;
private final ProjectService projectService;
@@ -70,11 +67,10 @@ public class InfrastructureInfoServiceImpl implements InfrastructureInfoService
private final BillingService billingService;
@Inject
- public InfrastructureInfoServiceImpl(ExploratoryDAO expDAO, EnvDAO envDAO, SelfServiceApplicationConfiguration configuration,
+ public InfrastructureInfoServiceImpl(ExploratoryDAO expDAO, SelfServiceApplicationConfiguration configuration,
BillingDAO billingDAO, ProjectService projectService, EndpointService endpointService,
BillingService billingService) {
this.expDAO = expDAO;
- this.envDAO = envDAO;
this.configuration = configuration;
this.billingDAO = billingDAO;
this.projectService = projectService;
@@ -88,8 +84,7 @@ public class InfrastructureInfoServiceImpl implements InfrastructureInfoService
try {
Iterable<Document> documents = expDAO.findExploratory(user.getName());
List<EndpointDTO> allEndpoints = endpointService.getEndpoints();
- return StreamSupport.stream(documents.spliterator(),
- false)
+ return StreamSupport.stream(documents.spliterator(), false)
.collect(Collectors.groupingBy(d -> d.getString("project")))
.entrySet()
.stream()
@@ -100,18 +95,15 @@ public class InfrastructureInfoServiceImpl implements InfrastructureInfoService
.anyMatch(endpoint1 -> endpoint1.getName().equals(endpoint.getName())))
.collect(Collectors.toList());
- List<BillingData> collect = e.getValue()
+ List<BillingReportLine> billingData = e.getValue()
.stream()
- .map(exp -> {
- List<BillingData> exploratoryRemoteBillingData = new ArrayList<>();
- try {
- exploratoryRemoteBillingData = billingService.getExploratoryRemoteBillingData(user, (String) exp.get("endpoint"),
- expDAO.findExploratories(e.getKey(), (String) exp.get("endpoint"), user.getName()));
- } catch (Exception ex) {
- log.error("Cannot retrieve billing information", ex);
- }
- return exploratoryRemoteBillingData;
- })
+ .map(exp ->
+ billingService.getExploratoryBillingData(exp.getString("exploratory_id"),
+ Optional.ofNullable(exp.get("computational_resources")).map(cr -> (List<Document>) cr).get()
+ .stream()
+ .map(cr -> cr.getString("computational_id"))
+ .collect(Collectors.toList()))
+ )
.flatMap(Collection::stream)
.collect(Collectors.toList());
@@ -120,7 +112,7 @@ public class InfrastructureInfoServiceImpl implements InfrastructureInfoService
.stream()
.collect(Collectors.toMap(ProjectEndpointDTO::getName, this::getSharedInfo));
return new ProjectInfrastructureInfo(e.getKey(),
- billingDAO.getBillingProjectQuoteUsed(e.getKey()), projectEdges, e.getValue(), collect, endpointResult);
+ billingDAO.getBillingProjectQuoteUsed(e.getKey()), projectEdges, e.getValue(), billingData, endpointResult);
})
.collect(Collectors.toList());
} catch (Exception e) {
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/util/BillingUtils.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/util/BillingUtils.java
index c8454b2..16b828c 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/util/BillingUtils.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/util/BillingUtils.java
@@ -22,7 +22,6 @@ package com.epam.dlab.backendapi.util;
import com.epam.dlab.backendapi.domain.BillingReportLine;
import com.epam.dlab.backendapi.resources.dto.ImageInfoRecord;
import com.epam.dlab.dto.UserInstanceDTO;
-import com.epam.dlab.dto.UserInstanceStatus;
import com.epam.dlab.dto.base.DataEngineType;
import com.epam.dlab.dto.computational.UserComputationalResource;
import jersey.repackaged.com.google.common.collect.Lists;
@@ -78,7 +77,7 @@ public class BillingUtils {
final String endpointBucketId = String.format(PROJECT_ENDPOINT_BUCKET_FORMAT, sbn, project.toLowerCase(), endpoint);
return Stream.concat(Stream.of(
- BillingReportLine.builder().resourceName("EDGE node").user(SHARED_RESOURCE).project(project).dlabId(userEdgeId).resourceType(EDGE).status(UserInstanceStatus.of(status)).build(),
+ BillingReportLine.builder().resourceName("EDGE node").user(SHARED_RESOURCE).project(project).dlabId(userEdgeId).resourceType(EDGE).build(),
BillingReportLine.builder().resourceName("EDGE volume").user(SHARED_RESOURCE).project(project).dlabId(edgeVolumeId).resourceType(VOLUME).build(),
BillingReportLine.builder().resourceName("Project endpoint shared bucket").user(SHARED_RESOURCE).project(project).dlabId(endpointBucketId).resourceType(BUCKET).build()
),
@@ -108,8 +107,7 @@ public class BillingUtils {
.stream()
.filter(cr -> cr.getComputationalId() != null)
.flatMap(cr -> Stream.concat(Stream.of(
- withUserProject(userInstance).dlabId(cr.getComputationalId()).resourceName(cr.getComputationalName()).resourceType(COMPUTATIONAL)
- .status(UserInstanceStatus.of(cr.getStatus())).shape(getComputationalShape(cr)).build(),
+ withUserProject(userInstance).dlabId(cr.getComputationalId()).resourceName(cr.getComputationalName()).resourceType(COMPUTATIONAL).shape(getComputationalShape(cr)).build(),
withUserProject(userInstance).resourceName(cr.getComputationalName() + ":" + VOLUME_PRIMARY).dlabId(String.format(VOLUME_PRIMARY_COMPUTATIONAL_FORMAT, cr.getComputationalId(), "m"))
.resourceType(VOLUME).build(),
withUserProject(userInstance).resourceName(cr.getComputationalName() + ":" + VOLUME_SECONDARY).dlabId(String.format(VOLUME_SECONDARY_COMPUTATIONAL_FORMAT, cr.getComputationalId(), "m"))
@@ -121,7 +119,7 @@ public class BillingUtils {
final String primaryVolumeId = String.format(VOLUME_PRIMARY_FORMAT, exploratoryId);
final String secondaryVolumeId = String.format(VOLUME_SECONDARY_FORMAT, exploratoryId);
final Stream<BillingReportLine> exploratoryStream = Stream.of(
- withUserProject(userInstance).resourceName(userInstance.getExploratoryName()).dlabId(exploratoryId).resourceType(EXPLORATORY).status(UserInstanceStatus.of(userInstance.getStatus())).shape(userInstance.getShape()).build(),
+ withUserProject(userInstance).resourceName(userInstance.getExploratoryName()).dlabId(exploratoryId).resourceType(EXPLORATORY).shape(userInstance.getShape()).build(),
withUserProject(userInstance).resourceName(VOLUME_PRIMARY).dlabId(primaryVolumeId).resourceType(VOLUME).build(),
withUserProject(userInstance).resourceName(VOLUME_SECONDARY).dlabId(secondaryVolumeId).resourceType(VOLUME).build());
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@dlab.apache.org
For additional commands, e-mail: commits-help@dlab.apache.org