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
The following commit(s) were added to refs/heads/DLAB-1571 by this push: new d97da87 Code refactoring d97da87 is described below commit d97da87b85dc5530ba67e7ebd5571951e5d3ba88 Author: Oleh Fuks <olegfuk...@gmail.com> AuthorDate: Fri Mar 6 14:55:36 2020 +0200 Code refactoring --- .../gcp/conf/BillingApplicationConfiguration.java | 4 +- .../billing/gcp/dao/impl/BigQueryBillingDAO.java | 12 +- .../epam/dlab/billing/gcp/documents/Project.java | 41 ----- .../dlab/billing/gcp/documents/UserInstance.java | 55 ------ .../epam/dlab/billing/gcp/model/BillingData.java | 59 ------ .../billing/gcp/repository/BillingRepository.java | 1 - .../billing/gcp/repository/ProjectRepository.java | 26 --- .../gcp/repository/UserInstanceRepository.java | 30 ---- .../billing/gcp/scheduler/BillingScheduler.java | 2 +- .../dlab/billing/gcp/service/BillingService.java | 3 - .../billing/gcp/service/BillingServiceImpl.java | 197 --------------------- .../gcp/service/impl/BillingServiceImpl.java | 64 +++++++ .../epam/dlab/billing/gcp/util/BillingUtils.java | 96 ---------- .../gcp/service/BillingServiceImplTest.java | 48 ++--- 14 files changed, 82 insertions(+), 556 deletions(-) diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/conf/BillingApplicationConfiguration.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/conf/BillingApplicationConfiguration.java index 5cb1ec5..79c1d9e 100644 --- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/conf/BillingApplicationConfiguration.java +++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/conf/BillingApplicationConfiguration.java @@ -27,10 +27,8 @@ import org.springframework.context.annotation.Configuration; @Configuration public class BillingApplicationConfiguration { - -// @Bean + @Bean public BigQuery bigQueryService() { return BigQueryOptions.getDefaultInstance().getService(); } - } 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 1df1ab2..cfb99de 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 @@ -58,11 +58,13 @@ import static org.springframework.data.mongodb.core.aggregation.Aggregation.newA @Slf4j public class BigQueryBillingDAO implements BillingDAO { private static final String DATE_FORMAT = "yyyy-MM-dd"; - private static final String SBN_PARAM = "sbn"; private static final String DATASET_PARAM = "dataset"; + private final BillingHistoryRepository billingHistoryRepo; private final MongoTemplate mongoTemplate; + private final BigQuery service; + private final String dataset; private final String sbn; private static final String GET_BILLING_DATA_QUERY = "SELECT b.sku.description usageType," + @@ -73,17 +75,15 @@ public class BigQueryBillingDAO implements BillingDAO { "CROSS JOIN UNNEST(b.labels) as label\n" + "where label.key = 'name' and cost != 0 and label.value like @sbn\n" + "group by usageType, usage_date_from, usage_date_to, product, value, currency"; - private BigQuery service = null; - private final String dataset; @Autowired public BigQueryBillingDAO(DlabConfiguration conf, BillingHistoryRepository billingHistoryRepo, - MongoTemplate mongoTemplate) { + BigQuery service, MongoTemplate mongoTemplate) { dataset = conf.getBigQueryDataset(); - sbn = conf.getSbn(); -// this.service = null; + this.service = service; this.billingHistoryRepo = billingHistoryRepo; this.mongoTemplate = mongoTemplate; + sbn = conf.getSbn(); } @Override diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/documents/Project.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/documents/Project.java deleted file mode 100644 index 0b40235..0000000 --- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/documents/Project.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.billing.gcp.documents; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Data; -import org.springframework.data.mongodb.core.mapping.Document; - -import java.util.List; - -@Document(collection = "Projects") -@Data -public class Project { - - @JsonProperty("name") - private String name; - private List<Endpoint> endpoints; - - - @Data - public class Endpoint { - private final String name; - } -} diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/documents/UserInstance.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/documents/UserInstance.java deleted file mode 100644 index b5a61ba..0000000 --- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/documents/UserInstance.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.billing.gcp.documents; - -import com.epam.dlab.billing.gcp.model.BillingData; -import lombok.Data; -import org.springframework.data.annotation.Id; -import org.springframework.data.mongodb.core.mapping.Document; -import org.springframework.data.mongodb.core.mapping.Field; - -import java.util.List; - -@Document(collection = "userInstances") -@Data -public class UserInstance { - - @Id - private String id; - @Field("user") - private String user; - @Field("exploratory_name") - private String exploratoryName; - @Field("exploratory_id") - private String exploratoryId; - private String project; - private List<BillingData> billing; - private String cost; - @Field("computational_resources") - private List<ComputationalResource> computationalResources; - - @Data - public class ComputationalResource { - @Field("computational_name") - private String computationalName; - @Field("computational_id") - private String computationalId; - } -} diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/model/BillingData.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/model/BillingData.java deleted file mode 100644 index 773d381..0000000 --- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/model/BillingData.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.billing.gcp.model; - -import com.epam.dlab.dto.billing.BillingResourceType; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Builder; -import lombok.Data; -import org.springframework.data.annotation.Id; -import org.springframework.data.mongodb.core.mapping.Field; - -import java.time.LocalDate; - -@Data -@Builder -//@Document(collection = "billing") -@JsonIgnoreProperties(ignoreUnknown = true) -public class BillingData { - @Id - private String id; - private String user; - @Field("resource_name") - private String resourceName; - @Field("from") - private LocalDate usageDateFrom; - @Field("to") - private LocalDate usageDateTo; - @Field("usage_date") - private String usageDate; - private String product; - private String usageType; - private Double cost; - @Field("currency_code") - private String currency; - private String project; - private String exploratoryName; - private String computationalName; - @Field("dlab_id") - private String dlabId; - @Field("dlab_resource_type") - private BillingResourceType resourceType; -} diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/BillingRepository.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/BillingRepository.java index 77c362a..2d4c5c1 100644 --- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/BillingRepository.java +++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/BillingRepository.java @@ -19,7 +19,6 @@ package com.epam.dlab.billing.gcp.repository; -import com.epam.dlab.billing.gcp.model.BillingData; import com.epam.dlab.billing.gcp.model.GcpBillingData; import org.springframework.data.mongodb.repository.MongoRepository; diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/ProjectRepository.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/ProjectRepository.java deleted file mode 100644 index 955c6a2..0000000 --- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/ProjectRepository.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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.billing.gcp.repository; - -import com.epam.dlab.billing.gcp.documents.Project; -import org.springframework.data.mongodb.repository.MongoRepository; - -public interface ProjectRepository extends MongoRepository<Project, String> { -} diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/UserInstanceRepository.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/UserInstanceRepository.java deleted file mode 100644 index a95d033..0000000 --- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/UserInstanceRepository.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.billing.gcp.repository; - -import com.epam.dlab.billing.gcp.documents.UserInstance; -import org.springframework.data.mongodb.repository.MongoRepository; - -import java.util.Optional; - -public interface UserInstanceRepository extends MongoRepository<UserInstance, String> { - - Optional<UserInstance> findByUserAndExploratoryName(String user, String exploratoryName); -} diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/scheduler/BillingScheduler.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/scheduler/BillingScheduler.java index ceaf8ce..9724d43 100644 --- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/scheduler/BillingScheduler.java +++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/scheduler/BillingScheduler.java @@ -37,6 +37,6 @@ public class BillingScheduler { @Scheduled(cron = "${dlab.cron}") public void getBillingReport() { -// billingService.updateBillingData(); + billingService.updateBillingData(); } } diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/BillingService.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/BillingService.java index dd69f7a..bb56d6c 100644 --- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/BillingService.java +++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/BillingService.java @@ -20,8 +20,5 @@ package com.epam.dlab.billing.gcp.service; public interface BillingService { - void updateBillingData(); - - void updateBillingData2(); } diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/BillingServiceImpl.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/BillingServiceImpl.java deleted file mode 100644 index 3ec4eac..0000000 --- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/BillingServiceImpl.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * 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.billing.gcp.service; - -import com.epam.dlab.billing.gcp.dao.BillingDAO; -import com.epam.dlab.billing.gcp.documents.Project; -import com.epam.dlab.billing.gcp.documents.UserInstance; -import com.epam.dlab.billing.gcp.model.BillingData; -import com.epam.dlab.billing.gcp.model.GcpBillingData; -import com.epam.dlab.billing.gcp.repository.BillingRepository; -import com.epam.dlab.billing.gcp.repository.ProjectRepository; -import com.epam.dlab.billing.gcp.repository.UserInstanceRepository; -import com.epam.dlab.billing.gcp.util.BillingUtils; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.mongodb.core.query.Update; -import org.springframework.stereotype.Service; - -import java.math.BigDecimal; -import java.time.format.DateTimeFormatter; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collector; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static com.epam.dlab.billing.gcp.util.BillingUtils.edgeBillingDataStream; -import static org.springframework.data.mongodb.core.query.Criteria.where; - -@Service -@Slf4j -public class BillingServiceImpl implements BillingService { - - private static final String DATE_FORMAT = "yyyy-MM-dd"; - private static final String USAGE_DATE_FORMAT = "yyyy-MM"; - private final BillingDAO billingDAO; - private final ProjectRepository projectRepository; - private final UserInstanceRepository userInstanceRepository; - private final BillingRepository billingRepository; - private final MongoTemplate mongoTemplate; - @Value("${dlab.sbn}") - private String sbn; - - @Autowired - public BillingServiceImpl(BillingDAO billingDAO, ProjectRepository projectRepository, - UserInstanceRepository userInstanceRepository, BillingRepository billingRepository, - MongoTemplate mongoTemplate) { - this.billingDAO = billingDAO; - this.projectRepository = projectRepository; - this.userInstanceRepository = userInstanceRepository; - this.billingRepository = billingRepository; - this.mongoTemplate = mongoTemplate; - } - - @Override - public void updateBillingData() { - try { - - final Stream<BillingData> ssnBillingDataStream = BillingUtils.ssnBillingDataStream(sbn); - final Stream<BillingData> billableUserInstances = userInstanceRepository.findAll() - .stream() - .filter(userInstance -> userInstance.getExploratoryId() != null) - .flatMap(BillingUtils::exploratoryBillingDataStream); - - final Stream<BillingData> billableEdges = projectRepository.findAll() - .stream() - .collect(Collectors.toMap(Project::getName, Project::getEndpoints)) - .entrySet() - .stream() - .flatMap(e -> projectEdges(e.getKey(), e.getValue())); - - - final Map<String, BillingData> billableResources = Stream.of(billableUserInstances, billableEdges, - ssnBillingDataStream) - .flatMap(s -> s) - .filter(bd -> bd.getDlabId() != null) - .collect(Collectors.toMap(BillingData::getDlabId, b -> b)); - log.info("Billable resources are: {}", billableResources); -// final Map<String, List<BillingData>> billingDataMap = billingDAO.getBillingData() -// .stream() -// .map(bd -> toBillingData(bd, getOrDefault(billableResources, bd.getTag()))) -// .collect(Collectors.groupingBy(bd -> bd.getUsageDate().substring(0, -// USAGE_DATE_FORMAT.length()))); - -// billingDataMap.forEach((usageDate, billingDataList) -> { -// log.info("Updating billing information for month {}", usageDate); -// billingRepository.deleteByUsageDateRegex("^" + usageDate); -// billingRepository.insert(billingDataList); -// updateExploratoryCost(billingDataList); -// }); - - log.info("Finished updating billing data"); - - - } catch (Exception e) { - log.error("Can not update billing due to: {}", e.getMessage(), e); - } - } - - @Override - public void updateBillingData2() { - try { - Map<String, List<GcpBillingData>> collect = billingDAO.getBillingData() - .stream() - .collect(Collectors.groupingBy(bd -> bd.getUsageDate().substring(0, USAGE_DATE_FORMAT.length()))); - - collect.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); - } - } - - private Stream<BillingData> projectEdges(String projectName, List<Project.Endpoint> endpoints) { - return endpoints - .stream() - .flatMap(endpoint -> edgeBillingDataStream(projectName, sbn, endpoint.getName())); - } - - private BillingData getOrDefault(Map<String, BillingData> billableResources, String tag) { - return billableResources.getOrDefault(tag, BillingData.builder().dlabId(tag).build()); - } - - private void updateExploratoryCost(List<BillingData> billingDataList) { - billingDataList.stream() - .filter(this::userAndExploratoryNamePresent) - .collect(groupByUserNameExploratoryNameCollector()) - .forEach(this::updateUserExploratoryBillingData); - } - - private void updateUserExploratoryBillingData(String user, - Map<String, List<BillingData>> billableExploratoriesMap) { - billableExploratoriesMap.forEach((exploratoryName, billingInfoList) -> - updateExploratoryBillingData(user, exploratoryName, billingInfoList) - ); - } - - private Collector<BillingData, ?, Map<String, Map<String, List<BillingData>>>> groupByUserNameExploratoryNameCollector() { - return Collectors.groupingBy(BillingData::getUser, Collectors.groupingBy(BillingData::getExploratoryName)); - } - - private boolean userAndExploratoryNamePresent(BillingData bd) { - return Objects.nonNull(bd.getUser()) && Objects.nonNull(bd.getExploratoryName()); - } - - private void updateExploratoryBillingData(String user, String exploratoryName, List<BillingData> billingInfoList) { - userInstanceRepository.findByUserAndExploratoryName(user, exploratoryName).ifPresent(userInstance -> - mongoTemplate.updateFirst(Query.query(where("user").is(user).and("exploratory_name").is(exploratoryName)), - Update.update("cost", getTotalCost(billingInfoList) + "$").set("billing", billingInfoList), - UserInstance.class)); - } - - private double getTotalCost(List<BillingData> billingInfoList) { - return new BigDecimal(billingInfoList.stream().mapToDouble(BillingData::getCost).sum()) - .setScale(2, BigDecimal.ROUND_HALF_UP) - .doubleValue(); - - } - - private BillingData toBillingData(GcpBillingData bd) { - - return BillingData.builder() - .cost(bd.getCost().setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()) - .currency(bd.getCurrency()) - .product(bd.getProduct()) - .usageDateTo(bd.getUsageDateTo()) - .usageDateFrom(bd.getUsageDateFrom()) - .usageDate(bd.getUsageDateFrom().format((DateTimeFormatter.ofPattern(DATE_FORMAT)))) - .usageType(bd.getUsageType()) - .dlabId(bd.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 new file mode 100644 index 0000000..c37436b --- /dev/null +++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/impl/BillingServiceImpl.java @@ -0,0 +1,64 @@ +/* + * 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.billing.gcp.service.impl; + +import com.epam.dlab.billing.gcp.dao.BillingDAO; +import com.epam.dlab.billing.gcp.model.GcpBillingData; +import com.epam.dlab.billing.gcp.repository.BillingRepository; +import com.epam.dlab.billing.gcp.service.BillingService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +@Slf4j +public class BillingServiceImpl implements BillingService { + private static final String USAGE_DATE_FORMAT = "yyyy-MM"; + + private final BillingDAO billingDAO; + private final BillingRepository billingRepository; + + @Autowired + public BillingServiceImpl(BillingDAO billingDAO, BillingRepository billingRepository) { + this.billingDAO = billingDAO; + this.billingRepository = billingRepository; + } + + @Override + public void updateBillingData() { + try { + Map<String, List<GcpBillingData>> billingData = 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); + } + } +} diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/util/BillingUtils.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/util/BillingUtils.java deleted file mode 100644 index 6a6341e..0000000 --- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/util/BillingUtils.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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.billing.gcp.util; - -import com.epam.dlab.billing.gcp.documents.UserInstance; -import com.epam.dlab.billing.gcp.model.BillingData; -import com.epam.dlab.dto.billing.BillingResourceType; - -import java.util.stream.Stream; - -public class BillingUtils { - - private static final String EDGE_FORMAT = "%s-%s-%s-edge"; - private static final String EDGE_VOLUME_FORMAT = "%s-%s-%s-edge-volume-primary"; - private static final String EDGE_BUCKET_FORMAT = "%s-%s-bucket"; - private static final String VOLUME_PRIMARY_FORMAT = "%s-volume-primary"; - private static final String VOLUME_SECONDARY_FORMAT = "%s-volume-secondary"; - private static final String VOLUME_PRIMARY = "Volume primary"; - private static final String VOLUME_SECONDARY = "Volume secondary"; - private static final String SHARED_RESOURCE = "Shared resource"; - - public static Stream<BillingData> edgeBillingDataStream(String project, String sbn, String endpoint) { - 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( - BillingData.builder().resourceName("EDGE node").user(SHARED_RESOURCE).project(project).dlabId(userEdgeId).resourceType(BillingResourceType.EDGE).build(), - BillingData.builder().resourceName("EDGE volume").user(SHARED_RESOURCE).project(project).dlabId(edgeVolumeId).resourceType(BillingResourceType.VOLUME).build(), - BillingData.builder().resourceName("EDGE bucket").user(SHARED_RESOURCE).project(project).dlabId(edgeBucketId).resourceType(BillingResourceType.EDGE_BUCKET).build() - ); - } - - public static Stream<BillingData> ssnBillingDataStream(String sbn) { - final String ssnId = sbn + "-ssn"; - final String bucketName = sbn.replaceAll("_", "-"); - return Stream.of( - BillingData.builder().user(SHARED_RESOURCE).resourceName("SSN").dlabId(ssnId).resourceType(BillingResourceType.SSN).build(), - BillingData.builder().user(SHARED_RESOURCE).resourceName("SSN Volume").dlabId(String.format(VOLUME_PRIMARY_FORMAT, ssnId)).resourceType(BillingResourceType.VOLUME).build(), - BillingData.builder().user(SHARED_RESOURCE).resourceName("SSN bucket").dlabId(bucketName + "-ssn" + - "-bucket").resourceType(BillingResourceType.SSN_BUCKET).build(), - BillingData.builder().user(SHARED_RESOURCE).resourceName("Collaboration bucket").dlabId(bucketName + - "-shared-bucket").resourceType(BillingResourceType.SHARED_BUCKET).build() - ); - } - - public static Stream<BillingData> exploratoryBillingDataStream(UserInstance userInstance) { - final Stream<BillingData> computationalStream = userInstance.getComputationalResources() - .stream() - .filter(cr -> cr.getComputationalId() != null) - .flatMap(cr -> Stream.of(computationalBillableResource(userInstance, cr), - withExploratoryName(userInstance).resourceName(cr.getComputationalName() + ":" + VOLUME_PRIMARY).dlabId(String.format(VOLUME_PRIMARY_FORMAT, cr.getComputationalId())) - .resourceType(BillingResourceType.VOLUME).computationalName(cr.getComputationalName()).build())); - 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<BillingData> exploratoryStream = Stream.of( - withExploratoryName(userInstance).resourceName(userInstance.getExploratoryName()).dlabId(exploratoryId).resourceType(BillingResourceType.EXPLORATORY).build(), - withExploratoryName(userInstance).resourceName(VOLUME_PRIMARY).dlabId(primaryVolumeId).resourceType(BillingResourceType.VOLUME).build(), - withExploratoryName(userInstance).resourceName(VOLUME_SECONDARY).dlabId(secondaryVolumeId).resourceType(BillingResourceType.VOLUME).build()); - return Stream.concat(computationalStream, exploratoryStream); - } - - private static BillingData computationalBillableResource(UserInstance userInstance, - UserInstance.ComputationalResource cr) { - return withExploratoryName(userInstance) - .dlabId(cr.getComputationalId()) - .resourceName(cr.getComputationalName()) - .resourceType(BillingResourceType.COMPUTATIONAL) - .computationalName(cr.getComputationalName()) - .project(userInstance.getProject()) - .build(); - } - - private static BillingData.BillingDataBuilder withExploratoryName(UserInstance userInstance) { - return BillingData.builder().user(userInstance.getUser()).exploratoryName(userInstance.getExploratoryName()) - .project(userInstance.getProject()); - } - -} diff --git a/services/billing-gcp/src/test/java/com/epam/dlab/billing/gcp/service/BillingServiceImplTest.java b/services/billing-gcp/src/test/java/com/epam/dlab/billing/gcp/service/BillingServiceImplTest.java index e002419..7a51f62 100644 --- a/services/billing-gcp/src/test/java/com/epam/dlab/billing/gcp/service/BillingServiceImplTest.java +++ b/services/billing-gcp/src/test/java/com/epam/dlab/billing/gcp/service/BillingServiceImplTest.java @@ -1,27 +1,25 @@ package com.epam.dlab.billing.gcp.service; import com.epam.dlab.billing.gcp.dao.BillingDAO; -import com.epam.dlab.billing.gcp.documents.UserInstance; import com.epam.dlab.billing.gcp.model.GcpBillingData; import com.epam.dlab.billing.gcp.repository.BillingRepository; -import com.epam.dlab.billing.gcp.repository.ProjectRepository; -import com.epam.dlab.billing.gcp.repository.UserInstanceRepository; -import org.junit.Before; +import com.epam.dlab.billing.gcp.service.impl.BillingServiceImpl; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.test.util.ReflectionTestUtils; import java.math.BigDecimal; import java.time.LocalDate; -import java.util.Arrays; import java.util.Collections; import java.util.List; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.anyCollection; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) @@ -29,52 +27,26 @@ public class BillingServiceImplTest { @Mock private BillingDAO billingDAO; @Mock - private ProjectRepository projectRepository; - @Mock - private UserInstanceRepository userInstanceRepository; - @Mock private BillingRepository billingRepository; - @Mock - private MongoTemplate mongoTemplate; @InjectMocks private BillingServiceImpl billingService; - @Before - public void setUp() { - ReflectionTestUtils.setField(billingService, "sbn", "CONF_SERVICE_BASE_NAME"); - } - @Test public void updateBillingData() throws InterruptedException { - when(userInstanceRepository.findAll()).thenReturn(getUserInstances()); when(billingDAO.getBillingData()).thenReturn(getBillingData()); billingService.updateBillingData(); - verify(userInstanceRepository).findAll(); - verify(userInstanceRepository, times(1)).findAll(); verify(billingDAO).getBillingData(); - verify(billingDAO, times(1)).getBillingData(); - verify(projectRepository, times(1)).findAll(); - verify(billingRepository, times(1)).deleteByUsageDateRegex(anyString()); - verify(billingRepository, times(1)).insert(anyCollection()); - - verifyNoMoreInteractions(billingDAO, userInstanceRepository, projectRepository); - } - - private List<UserInstance> getUserInstances() { - UserInstance userInstance1 = new UserInstance(); - userInstance1.setComputationalResources(Collections.emptyList()); - - UserInstance userInstance2 = new UserInstance(); - userInstance2.setComputationalResources(Collections.emptyList()); - userInstance2.setExploratoryId("exploratoryIId"); + verify(billingRepository).deleteByUsageDateRegex(anyString()); + verify(billingRepository).insert(anyCollection()); - return Arrays.asList(userInstance1, userInstance1, userInstance2); + verifyNoMoreInteractions(billingDAO); } private List<GcpBillingData> getBillingData() { return Collections.singletonList(GcpBillingData.builder() + .usageDate(LocalDate.MIN.toString()) .usageDateFrom(LocalDate.MIN) .usageDateTo(LocalDate.MAX) .product("product") --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@dlab.apache.org For additional commands, e-mail: commits-h...@dlab.apache.org