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/03/03 11:39:21 UTC

[incubator-dlab] 06/08: Added metadata to billing report

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 66cb8787d98a98f360906925851fc2be37e9f0ed
Author: Oleh Fuks <ol...@gmail.com>
AuthorDate: Mon Mar 2 19:05:58 2020 +0200

    Added metadata to billing report
---
 .../{BillingReportDTO.java => BillingReport.java}  | 22 +++-----
 ...llingReportDTO.java => BillingReportLines.java} |  2 +-
 .../dlab/backendapi/service/BillingServiceNew.java |  6 ++-
 .../service/impl/BillingServiceImplNew.java        | 60 ++++++++++++++--------
 .../epam/dlab/backendapi/util/BillingUtils.java    | 34 ++++++------
 5 files changed, 69 insertions(+), 55 deletions(-)

diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BillingReportDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BillingReport.java
similarity index 69%
copy from services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BillingReportDTO.java
copy to services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BillingReport.java
index 8816f33..3d603dd 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BillingReportDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BillingReport.java
@@ -19,32 +19,24 @@
 
 package com.epam.dlab.backendapi.domain;
 
-import com.epam.dlab.dto.UserInstanceStatus;
-import com.epam.dlab.dto.billing.BillingResourceType;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import lombok.Builder;
 import lombok.Data;
 
 import java.time.LocalDate;
+import java.util.List;
 
 @Data
 @Builder
-public class BillingReportDTO {
-    private String dlabId;
-    @JsonProperty("resource_name")
-    private String resourceName;
-    private String project;
-    private String user;
+public class BillingReport {
+    private String sbn;
+    @JsonProperty("report_lines")
+    private List<BillingReportLines> reportLines;
     @JsonProperty("from")
     private LocalDate usageDateFrom;
     @JsonProperty("to")
     private LocalDate usageDateTo;
-    private String product;
-    private String usageType;
-    private Double cost;
+    @JsonProperty("total_cost")
+    private double totalCost;
     private String currency;
-    @JsonProperty("resource_type")
-    private BillingResourceType resourceType;
-    private UserInstanceStatus status;
-    private String shape;
 }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BillingReportDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BillingReportLines.java
similarity index 97%
rename from services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BillingReportDTO.java
rename to services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BillingReportLines.java
index 8816f33..256e1cc 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BillingReportDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BillingReportLines.java
@@ -29,7 +29,7 @@ import java.time.LocalDate;
 
 @Data
 @Builder
-public class BillingReportDTO {
+public class BillingReportLines {
     private String dlabId;
     @JsonProperty("resource_name")
     private String resourceName;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/BillingServiceNew.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/BillingServiceNew.java
index b486a23..f569c78 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/BillingServiceNew.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/BillingServiceNew.java
@@ -20,12 +20,14 @@
 package com.epam.dlab.backendapi.service;
 
 import com.epam.dlab.auth.UserInfo;
-import com.epam.dlab.backendapi.domain.BillingReportDTO;
+import com.epam.dlab.backendapi.domain.BillingReport;
+import com.epam.dlab.backendapi.domain.BillingReportLines;
 import com.epam.dlab.backendapi.resources.dto.BillingFilter;
 
 import java.util.List;
 
 public interface BillingServiceNew {
+    BillingReport getBillingReport(UserInfo userInfo, BillingFilter filter);
 
-    List<BillingReportDTO> getBillingReport(UserInfo userInfo, BillingFilter filter);
+    List<BillingReportLines> getBillingReportLines(UserInfo userInfo, BillingFilter filter);
 }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImplNew.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImplNew.java
index 2b44f44..2753270 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImplNew.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImplNew.java
@@ -21,7 +21,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.domain.BillingReportDTO;
+import com.epam.dlab.backendapi.domain.BillingReport;
+import com.epam.dlab.backendapi.domain.BillingReportLines;
 import com.epam.dlab.backendapi.domain.EndpointDTO;
 import com.epam.dlab.backendapi.domain.ProjectDTO;
 import com.epam.dlab.backendapi.domain.ProjectEndpointDTO;
@@ -46,9 +47,11 @@ import java.net.URISyntaxException;
 import java.time.LocalDate;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
@@ -78,26 +81,43 @@ public class BillingServiceImplNew implements BillingServiceNew {
     }
 
     @Override
-    public List<BillingReportDTO> getBillingReport(UserInfo userInfo, BillingFilter filter) {
+    public BillingReport getBillingReport(UserInfo user, BillingFilter filter) {
+        List<BillingReportLines> billingReportLines = getBillingReportLines(user, filter);
+        Optional<LocalDate> min = billingReportLines.stream().min(Comparator.comparing(BillingReportLines::getUsageDateFrom)).map(BillingReportLines::getUsageDateFrom);
+        Optional<LocalDate> max = billingReportLines.stream().max(Comparator.comparing(BillingReportLines::getUsageDateTo)).map(BillingReportLines::getUsageDateTo);
+        double sum = billingReportLines.stream().mapToDouble(BillingReportLines::getCost).sum();
+        Optional<String> currency = billingReportLines.stream().findAny().map(BillingReportLines::getCurrency);
+        return BillingReport.builder()
+                .sbn(configuration.getServiceBaseName())
+                .reportLines(billingReportLines)
+                .usageDateFrom(min.orElse(null))
+                .usageDateTo(max.orElse(null))
+                .totalCost(sum)
+                .currency(currency.orElse(null))
+                .build();
+    }
+
+    @Override
+    public List<BillingReportLines> getBillingReportLines(UserInfo user, BillingFilter filter) {
         final String serviceBaseName = configuration.getServiceBaseName();
-        final Stream<BillingReportDTO> ssnBillingDataStream = BillingUtils.ssnBillingDataStream(serviceBaseName);
-        final Stream<BillingReportDTO> billableUserInstances = exploratoryService.findAll()
+        final Stream<BillingReportLines> ssnBillingDataStream = BillingUtils.ssnBillingDataStream(serviceBaseName);
+        final Stream<BillingReportLines> billableUserInstances = exploratoryService.findAll()
                 .stream()
                 .filter(userInstance -> Objects.nonNull(userInstance.getExploratoryId()))
                 .flatMap(BillingUtils::exploratoryBillingDataStream);
-        final Stream<BillingReportDTO> billableEdges = projectService.getProjects()
+        final Stream<BillingReportLines> billableEdges = projectService.getProjects()
                 .stream()
                 .collect(Collectors.toMap(ProjectDTO::getName, ProjectDTO::getEndpoints))
                 .entrySet()
                 .stream()
                 .flatMap(e -> projectEdges(serviceBaseName, e.getKey(), e.getValue()));
 
-        final Map<String, BillingReportDTO> billableResources = Stream.of(billableUserInstances, billableEdges, ssnBillingDataStream)
+        final Map<String, BillingReportLines> billableResources = Stream.of(billableUserInstances, billableEdges, ssnBillingDataStream)
                 .flatMap(s -> s)
-                .collect(Collectors.toMap(BillingReportDTO::getDlabId, b -> b));
+                .collect(Collectors.toMap(BillingReportLines::getDlabId, b -> b));
         log.debug("Billable resources are: {}", billableResources);
 
-        List<BillingReportDTO> billingReport = getRemoteBillingData(userInfo)
+        List<BillingReportLines> billingReport = getRemoteBillingData(user)
                 .stream()
                 .filter(getBillingDataFilter(filter))
                 .map(bd -> toBillingData(bd, getOrDefault(billableResources, bd.getTag())))
@@ -108,15 +128,15 @@ public class BillingServiceImplNew implements BillingServiceNew {
         return billingReport;
     }
 
-    private Stream<BillingReportDTO> projectEdges(String serviceBaseName, String projectName, List<ProjectEndpointDTO> endpoints) {
+    private Stream<BillingReportLines> projectEdges(String serviceBaseName, String projectName, List<ProjectEndpointDTO> endpoints) {
         return endpoints
                 .stream()
                 .flatMap(endpoint -> BillingUtils.edgeBillingDataStream(projectName, serviceBaseName, endpoint.getName(),
                         endpoint.getStatus().toString()));
     }
 
-    private BillingReportDTO getOrDefault(Map<String, BillingReportDTO> billableResources, String tag) {
-        return billableResources.getOrDefault(tag, BillingReportDTO.builder().dlabId(tag).build());
+    private BillingReportLines getOrDefault(Map<String, BillingReportLines> billableResources, String tag) {
+        return billableResources.getOrDefault(tag, BillingReportLines.builder().dlabId(tag).build());
     }
 
     private List<BillingData> getRemoteBillingData(UserInfo userInfo) {
@@ -172,7 +192,7 @@ public class BillingServiceImplNew implements BillingServiceNew {
         });
     }
 
-    private Predicate<BillingReportDTO> getBillingReportFilter(BillingFilter filter) {
+    private Predicate<BillingReportLines> getBillingReportFilter(BillingFilter filter) {
         return br -> (filter.getUsers().isEmpty() || filter.getUsers().contains(br.getUser())) &&
                 (filter.getProjects().isEmpty() || filter.getProjects().contains(br.getProject())) &&
                 (filter.getResourceTypes().isEmpty() || filter.getResourceTypes().contains(br.getResourceType().name())) &&
@@ -187,21 +207,21 @@ public class BillingServiceImplNew implements BillingServiceNew {
                 (filter.getProducts().isEmpty() || filter.getProducts().contains(br.getProduct()));
     }
 
-    private BillingReportDTO toBillingData(BillingData billingData, BillingReportDTO billingReportDTO) {
-        return BillingReportDTO.builder()
+    private BillingReportLines toBillingData(BillingData billingData, BillingReportLines billingReportLines) {
+        return BillingReportLines.builder()
                 .cost(billingData.getCost())
                 .currency(billingData.getCurrency())
                 .product(billingData.getProduct())
-                .project(billingReportDTO.getProject())
+                .project(billingReportLines.getProject())
                 .usageDateTo(billingData.getUsageDateTo())
                 .usageDateFrom(billingData.getUsageDateFrom())
                 .usageType(billingData.getUsageType())
-                .user(billingReportDTO.getUser())
+                .user(billingReportLines.getUser())
                 .dlabId(billingData.getTag())
-                .resourceType(billingReportDTO.getResourceType())
-                .resourceName(billingReportDTO.getResourceName())
-                .status(billingReportDTO.getStatus())
-                .shape(billingReportDTO.getShape())
+                .resourceType(billingReportLines.getResourceType())
+                .resourceName(billingReportLines.getResourceName())
+                .status(billingReportLines.getStatus())
+                .shape(billingReportLines.getShape())
                 .build();
     }
 }
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 02d4682..27320f8 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
@@ -19,7 +19,7 @@
 
 package com.epam.dlab.backendapi.util;
 
-import com.epam.dlab.backendapi.domain.BillingReportDTO;
+import com.epam.dlab.backendapi.domain.BillingReportLines;
 import com.epam.dlab.dto.UserInstanceDTO;
 import com.epam.dlab.dto.UserInstanceStatus;
 import com.epam.dlab.dto.base.DataEngineType;
@@ -42,31 +42,31 @@ public class BillingUtils {
     private static final String DATAENGINE_NAME_FORMAT = "%d x %s";
     private static final String DATAENGINE_SERVICE_NAME_FORMAT = "Master: %s%sSlave:  %d x %s";
 
-    public static Stream<BillingReportDTO> edgeBillingDataStream(String project, String sbn, String endpoint, String status) {
+    public static Stream<BillingReportLines> edgeBillingDataStream(String project, String sbn, String endpoint, String status) {
         final String userEdgeId = String.format(EDGE_FORMAT, sbn, project.toLowerCase(), endpoint);
         final String edgeVolumeId = String.format(EDGE_VOLUME_FORMAT, sbn, project.toLowerCase(), endpoint);
         final String edgeBucketId = String.format(EDGE_BUCKET_FORMAT, sbn, project.toLowerCase());
         return Stream.of(
-                BillingReportDTO.builder().resourceName("EDGE node").user(SHARED_RESOURCE).project(project).dlabId(userEdgeId).resourceType(BillingResourceType.EDGE)
+                BillingReportLines.builder().resourceName("EDGE node").user(SHARED_RESOURCE).project(project).dlabId(userEdgeId).resourceType(BillingResourceType.EDGE)
                         .status(UserInstanceStatus.of(status)).build(),
-                BillingReportDTO.builder().resourceName("EDGE volume").user(SHARED_RESOURCE).project(project).dlabId(edgeVolumeId).resourceType(BillingResourceType.VOLUME).build(),
-                BillingReportDTO.builder().resourceName("EDGE bucket").user(SHARED_RESOURCE).project(project).dlabId(edgeBucketId).resourceType(BillingResourceType.EDGE_BUCKET).build()
+                BillingReportLines.builder().resourceName("EDGE volume").user(SHARED_RESOURCE).project(project).dlabId(edgeVolumeId).resourceType(BillingResourceType.VOLUME).build(),
+                BillingReportLines.builder().resourceName("EDGE bucket").user(SHARED_RESOURCE).project(project).dlabId(edgeBucketId).resourceType(BillingResourceType.EDGE_BUCKET).build()
         );
     }
 
-    public static Stream<BillingReportDTO> ssnBillingDataStream(String sbn) {
+    public static Stream<BillingReportLines> ssnBillingDataStream(String sbn) {
         final String ssnId = sbn + "-ssn";
         final String bucketName = sbn.replaceAll("_", "-");
         return Stream.of(
-                BillingReportDTO.builder().user(SHARED_RESOURCE).resourceName("SSN").dlabId(ssnId).resourceType(BillingResourceType.SSN).build(),
-                BillingReportDTO.builder().user(SHARED_RESOURCE).resourceName("SSN Volume").dlabId(String.format(VOLUME_PRIMARY_FORMAT, ssnId)).resourceType(BillingResourceType.VOLUME).build(),
-                BillingReportDTO.builder().user(SHARED_RESOURCE).resourceName("SSN bucket").dlabId(bucketName + "-ssn" + "-bucket").resourceType(BillingResourceType.SSN_BUCKET).build(),
-                BillingReportDTO.builder().user(SHARED_RESOURCE).resourceName("Collaboration bucket").dlabId(bucketName + "-shared-bucket").resourceType(BillingResourceType.SHARED_BUCKET).build()
+                BillingReportLines.builder().user(SHARED_RESOURCE).resourceName("SSN").dlabId(ssnId).resourceType(BillingResourceType.SSN).build(),
+                BillingReportLines.builder().user(SHARED_RESOURCE).resourceName("SSN Volume").dlabId(String.format(VOLUME_PRIMARY_FORMAT, ssnId)).resourceType(BillingResourceType.VOLUME).build(),
+                BillingReportLines.builder().user(SHARED_RESOURCE).resourceName("SSN bucket").dlabId(bucketName + "-ssn" + "-bucket").resourceType(BillingResourceType.SSN_BUCKET).build(),
+                BillingReportLines.builder().user(SHARED_RESOURCE).resourceName("Collaboration bucket").dlabId(bucketName + "-shared-bucket").resourceType(BillingResourceType.SHARED_BUCKET).build()
         );
     }
 
-    public static Stream<BillingReportDTO> exploratoryBillingDataStream(UserInstanceDTO userInstance) {
-        final Stream<BillingReportDTO> computationalStream = userInstance.getResources()
+    public static Stream<BillingReportLines> exploratoryBillingDataStream(UserInstanceDTO userInstance) {
+        final Stream<BillingReportLines> computationalStream = userInstance.getResources()
                 .stream()
                 .filter(cr -> cr.getComputationalId() != null)
                 .flatMap(cr -> Stream.of(computationalBillableResource(userInstance, cr),
@@ -75,7 +75,7 @@ public class BillingUtils {
         final String exploratoryId = userInstance.getExploratoryId();
         final String primaryVolumeId = String.format(VOLUME_PRIMARY_FORMAT, exploratoryId);
         final String secondaryVolumeId = String.format(VOLUME_SECONDARY_FORMAT, exploratoryId);
-        final Stream<BillingReportDTO> exploratoryStream = Stream.of(
+        final Stream<BillingReportLines> exploratoryStream = Stream.of(
                 withExploratoryName(userInstance).resourceName(userInstance.getExploratoryName()).dlabId(exploratoryId).resourceType(BillingResourceType.EXPLORATORY)
                         .status(UserInstanceStatus.of(userInstance.getStatus())).shape(userInstance.getShape()).build(),
                 withExploratoryName(userInstance).resourceName(VOLUME_PRIMARY).dlabId(primaryVolumeId).resourceType(BillingResourceType.VOLUME).build(),
@@ -83,8 +83,8 @@ public class BillingUtils {
         return Stream.concat(computationalStream, exploratoryStream);
     }
 
-    private static BillingReportDTO computationalBillableResource(UserInstanceDTO userInstance,
-                                                                  UserComputationalResource cr) {
+    private static BillingReportLines computationalBillableResource(UserInstanceDTO userInstance,
+                                                                    UserComputationalResource cr) {
         return withExploratoryName(userInstance)
                 .dlabId(cr.getComputationalId())
                 .resourceName(cr.getComputationalName())
@@ -95,8 +95,8 @@ public class BillingUtils {
                 .build();
     }
 
-    private static BillingReportDTO.BillingReportDTOBuilder withExploratoryName(UserInstanceDTO userInstance) {
-        return BillingReportDTO.builder().user(userInstance.getUser()).project(userInstance.getProject());
+    private static BillingReportLines.BillingReportLinesBuilder withExploratoryName(UserInstanceDTO userInstance) {
+        return BillingReportLines.builder().user(userInstance.getUser()).project(userInstance.getProject());
     }
 
     private static String getComputationalShape(UserComputationalResource resource) {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@dlab.apache.org
For additional commands, e-mail: commits-help@dlab.apache.org