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 4b7abeb Refactoring local billing 4b7abeb is described below commit 4b7abeb99b1afbc6bf84eadc5ba89863c918c5c6 Author: Oleh Fuks <olegfuk...@gmail.com> AuthorDate: Thu Mar 26 18:40:35 2020 +0200 Refactoring local billing --- .../com/epam/dlab/billing/DlabResourceType.java | 86 ----- .../epam/dlab/backendapi/dao/BaseBillingDAO.java | 358 --------------------- .../com/epam/dlab/backendapi/dao/BillingDAO.java | 6 - .../dlab/backendapi/dao/aws/AwsBillingDAO.java | 74 ----- .../dlab/backendapi/dao/azure/AzureBillingDAO.java | 121 ------- .../dlab/backendapi/dao/gcp/GcpBillingDao.java | 65 ---- .../com/epam/dlab/backendapi/domain/BaseShape.java | 23 -- .../backendapi/domain/DataEngineServiceShape.java | 37 --- .../dlab/backendapi/domain/DataEngineShape.java | 34 -- .../epam/dlab/backendapi/domain/EndpointShape.java | 14 - .../dlab/backendapi/domain/ExploratoryShape.java | 14 - .../com/epam/dlab/backendapi/domain/SsnShape.java | 14 - .../backendapi/modules/AwsSelfServiceModule.java | 83 ----- .../backendapi/modules/AzureSelfServiceModule.java | 81 ----- .../backendapi/modules/CloudProviderModule.java | 32 +- .../backendapi/modules/GcpSelfServiceModule.java | 84 ----- .../dlab/backendapi/modules/ModuleFactory.java | 13 - .../dlab/backendapi/resources/BillingResource.java | 26 +- .../dlab/backendapi/service/BillingService.java | 80 +---- .../dlab/backendapi/service/BillingServiceNew.java | 39 --- .../epam/dlab/backendapi/service/ShapeFormat.java | 5 - .../backendapi/service/aws/AwsBillingService.java | 110 ------- .../service/azure/AzureBillingService.java | 116 ------- .../backendapi/service/gcp/GcpBillingService.java | 104 ------ ...ServiceImplNew.java => BillingServiceImpl.java} | 10 +- .../impl/InfrastructureInfoServiceImpl.java | 10 +- .../service/aws/AwsBillingServiceTest.java | 224 ------------- .../service/azure/AzureBillingServiceTest.java | 208 ------------ 28 files changed, 24 insertions(+), 2047 deletions(-) diff --git a/services/common/src/main/java/com/epam/dlab/billing/DlabResourceType.java b/services/common/src/main/java/com/epam/dlab/billing/DlabResourceType.java index 54a590e..dfec0dc 100644 --- a/services/common/src/main/java/com/epam/dlab/billing/DlabResourceType.java +++ b/services/common/src/main/java/com/epam/dlab/billing/DlabResourceType.java @@ -19,10 +19,6 @@ package com.epam.dlab.billing; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - public enum DlabResourceType { SSN, SSN_BUCKET, @@ -51,88 +47,6 @@ public enum DlabResourceType { return null; } - public static String getResourceTypeName(String id) { - DlabResourceType resourceTypeId = DlabResourceType.of(id); - if (resourceTypeId != null) { - switch (resourceTypeId) { - case COMPUTATIONAL: - return "Cluster"; - case EXPLORATORY: - return "Notebook"; - case EDGE: - return "Edge Node"; - case VOLUME: - return "Volume"; - case EDGE_BUCKET: - case SSN_BUCKET: - case COLLABORATION_BUCKET: - return "Bucket"; - case EDGE_CONTAINER: - case SSN_CONTAINER: - case COLLABORATION_CONTAINER: - return "Container"; - case SSN_STORAGE_ACCOUNT: - case EDGE_STORAGE_ACCOUNT: - case COLLABORATION_STORAGE_ACCOUNT: - return "Storage Account"; - case SSN: - return "SSN"; - case DATA_LAKE_STORE: - return "Data Lake Store Account"; - } - } - return id; - } - - public static List<String> getResourceTypeIds(List<String> names) { - if (names == null || names.isEmpty()) { - return Collections.emptyList(); - } - - List<String> list = new ArrayList<>(); - names.forEach(e -> { - switch (e) { - case "Cluster": - list.add(DlabResourceType.COMPUTATIONAL.toString()); - break; - case "Notebook": - list.add(DlabResourceType.EXPLORATORY.toString()); - break; - case "Edge Node": - list.add(DlabResourceType.EDGE.toString()); - break; - case "Bucket": - list.add(DlabResourceType.EDGE_BUCKET.toString()); - list.add(DlabResourceType.SSN_BUCKET.toString()); - list.add(DlabResourceType.COLLABORATION_BUCKET.toString()); - break; - case "Container": - list.add(DlabResourceType.EDGE_CONTAINER.toString()); - list.add(DlabResourceType.SSN_CONTAINER.toString()); - list.add(DlabResourceType.COLLABORATION_CONTAINER.toString()); - break; - case "SSN": - list.add(DlabResourceType.SSN.toString()); - break; - case "Storage Account": - list.add(DlabResourceType.SSN_STORAGE_ACCOUNT.toString()); - list.add(DlabResourceType.EDGE_STORAGE_ACCOUNT.toString()); - list.add(DlabResourceType.COLLABORATION_STORAGE_ACCOUNT.toString()); - break; - case "Data Lake Store Account": - list.add(DlabResourceType.DATA_LAKE_STORE.toString()); - break; - case "Volume": - list.add(DlabResourceType.VOLUME.toString()); - break; - default: - list.add(e); - } - }); - - return list; - } - @Override public String toString() { return super.toString().toUpperCase(); 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 71223db..31f9b4d 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,89 +19,33 @@ package com.epam.dlab.backendapi.dao; -import com.epam.dlab.MongoKeyWords; -import com.epam.dlab.auth.UserInfo; -import com.epam.dlab.backendapi.domain.BaseShape; -import com.epam.dlab.backendapi.domain.DataEngineServiceShape; -import com.epam.dlab.backendapi.domain.DataEngineShape; -import com.epam.dlab.backendapi.domain.EndpointShape; -import com.epam.dlab.backendapi.domain.ExploratoryShape; -import com.epam.dlab.backendapi.domain.SsnShape; -import com.epam.dlab.backendapi.resources.dto.BillingFilter; -import com.epam.dlab.backendapi.roles.RoleType; -import com.epam.dlab.backendapi.roles.UserRoles; -import com.epam.dlab.billing.BillingCalculationUtils; -import com.epam.dlab.billing.DlabResourceType; -import com.epam.dlab.dto.UserInstanceStatus; -import com.epam.dlab.dto.base.DataEngineType; -import com.epam.dlab.model.aws.ReportLine; -import com.google.common.collect.Lists; import com.google.inject.Inject; -import com.mongodb.client.AggregateIterable; -import com.mongodb.client.FindIterable; -import com.mongodb.client.model.Aggregates; -import com.mongodb.client.model.Filters; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.bson.Document; import org.bson.conversions.Bson; import java.math.BigDecimal; -import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.function.Supplier; -import java.util.stream.StreamSupport; -import static com.epam.dlab.backendapi.dao.ComputationalDAO.COMPUTATIONAL_ID; -import static com.epam.dlab.backendapi.dao.ExploratoryDAO.COMPUTATIONAL_RESOURCES; -import static com.epam.dlab.backendapi.dao.ExploratoryDAO.EXPLORATORY_ID; import static com.epam.dlab.backendapi.dao.MongoCollections.BILLING; -import static com.epam.dlab.backendapi.dao.MongoCollections.USER_INSTANCES; -import static com.epam.dlab.model.aws.ReportLine.FIELD_RESOURCE_TYPE; -import static com.epam.dlab.model.aws.ReportLine.FIELD_USAGE_DATE; 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.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 com.mongodb.client.model.Projections.excludeId; -import static com.mongodb.client.model.Projections.fields; -import static com.mongodb.client.model.Projections.include; import static java.util.Collections.singletonList; @Slf4j public abstract class BaseBillingDAO extends BaseDAO implements BillingDAO { - public static final String SHAPE = "shape"; - public static final String SERVICE_BASE_NAME = "service_base_name"; public static final String ITEMS = "lines"; - public static final String COST_TOTAL = "cost_total"; public static final String FULL_REPORT = "full_report"; - private static final String PROJECT = "project"; - private static final String MASTER_NODE_SHAPE = "master_node_shape"; - private static final String SLAVE_NODE_SHAPE = "slave_node_shape"; - private static final String TOTAL_INSTANCE_NUMBER = "total_instance_number"; - - private static final String DATAENGINE_SHAPE = "dataengine_instance_shape"; - private static final String DATAENGINE_INSTANCE_COUNT = "dataengine_instance_count"; - - private static final String DATAENGINE_DOCKER_IMAGE = "image"; private static final int ONE_HUNDRED = 100; private static final String TOTAL_FIELD_NAME = "total"; private static final String COST_FIELD = "$cost"; public static final String SHARED_RESOURCE_NAME = "Shared resource"; - protected static final String FIELD_PROJECT = "project"; - private static final String EDGE_FORMAT = "%s-%s-%s-edge"; - private static final String PROJECT_COLLECTION = "Projects"; - private static final String TAGS = "tags"; @Inject protected SettingsDAO settings; @@ -111,160 +55,6 @@ public abstract class BaseBillingDAO extends BaseDAO implements BillingDAO { private ProjectDAO projectDAO; @Override - public Document getReport(UserInfo userInfo, BillingFilter filter) { - boolean isFullReport = UserRoles.checkAccess(userInfo, RoleType.PAGE, "/api/infrastructure_provision/billing", - userInfo.getRoles()); - setUserFilter(userInfo, filter, isFullReport); - List<Bson> matchCriteria = matchCriteria(filter); - List<Bson> pipeline = new ArrayList<>(); - if (!matchCriteria.isEmpty()) { - pipeline.add(Aggregates.match(Filters.and(matchCriteria))); - } - pipeline.add(groupCriteria()); - pipeline.add(sortCriteria()); - final Map<String, BaseShape> shapes = getShapes(filter.getShapes()); - return prepareReport(filter.getStatuses(), !filter.getShapes().isEmpty(), - getCollection(BILLING).aggregate(pipeline), shapes, isFullReport); - } - - private Document prepareReport(List<UserInstanceStatus> statuses, boolean filterByShape, - AggregateIterable<Document> agg, - Map<String, BaseShape> shapes, boolean fullReport) { - - List<Document> reportItems = new ArrayList<>(); - - String usageDateStart = null; - String usageDateEnd = null; - double costTotal = 0D; - - for (Document d : agg) { - Document id = (Document) d.get(MongoKeyWords.MONGO_ID); - String resourceId = id.getString(dlabIdFieldName()); - BaseShape shape = shapes.get(resourceId); - final UserInstanceStatus status = Optional.ofNullable(shape).map(BaseShape::getStatus).orElse(null); - if ((filterByShape && shape == null) || - (!statuses.isEmpty() && statuses.stream().noneMatch(s -> s.equals(status)))) { - continue; - } - - - String dateStart = d.getString(MongoKeyWords.USAGE_FROM); - if (StringUtils.compare(usageDateStart, dateStart, false) > 0) { - usageDateStart = dateStart; - } - String dateEnd = d.getString(MongoKeyWords.USAGE_TO); - if (StringUtils.compare(usageDateEnd, dateEnd) < 0) { - usageDateEnd = dateEnd; - } - - - costTotal += d.getDouble(MongoKeyWords.COST); - - final String dlabResourceType = id.getString("dlab_resource_type"); - final String statusString = Optional - .ofNullable(status) - .map(UserInstanceStatus::toString) - .orElse(StringUtils.EMPTY); - - Document item = new Document() - .append(MongoKeyWords.DLAB_USER, getOrDefault(id.getString(USER))) - .append(dlabIdFieldName(), resourceId) - .append(shapeFieldName(), Optional.ofNullable(shape).map(BaseShape::format) - .orElse(StringUtils.EMPTY)) - .append("dlab_resource_type", DlabResourceType - .getResourceTypeName(dlabResourceType)) //todo check on azure!!! - .append(STATUS, statusString) - .append(FIELD_RESOURCE_TYPE, resourceType(id)) - .append(productFieldName(), id.getString(productFieldName())) - .append(PROJECT, getOrDefault(id.getString(PROJECT))) - .append(MongoKeyWords.COST, d.getDouble(MongoKeyWords.COST)) - .append(costFieldName(), BillingCalculationUtils.formatDouble(d.getDouble(MongoKeyWords - .COST))) - .append(currencyCodeFieldName(), id.getString(currencyCodeFieldName())) - .append(usageDateFromFieldName(), dateStart) - .append(usageDateToFieldName(), dateEnd); - - reportItems.add(item); - } - - return new Document() - .append(SERVICE_BASE_NAME, settings.getServiceBaseName()) - .append(usageDateFromFieldName(), usageDateStart) - .append(usageDateToFieldName(), usageDateEnd) - .append(ITEMS, reportItems) - .append(COST_TOTAL, BillingCalculationUtils.formatDouble(BillingCalculationUtils.round - (costTotal, 2))) - .append(currencyCodeFieldName(), (reportItems.isEmpty() ? null : - reportItems.get(0).getString(currencyCodeFieldName()))) - .append(FULL_REPORT, fullReport); - - } - - protected String resourceType(Document id) { - return id.getString(FIELD_RESOURCE_TYPE); - } - - protected String currencyCodeFieldName() { - return "currency_code"; - } - - protected String usageDateToFieldName() { - return MongoKeyWords.USAGE_TO; - } - - protected String costFieldName() { - return MongoKeyWords.COST; - } - - protected String productFieldName() { - return ReportLine.FIELD_PRODUCT; - } - - protected String usageDateFromFieldName() { - return MongoKeyWords.USAGE_FROM; - } - - protected String dlabIdFieldName() { - return ReportLine.FIELD_DLAB_ID; - } - - protected String shapeFieldName() { - return SHAPE; - } - - protected abstract Bson sortCriteria(); - - protected abstract Bson groupCriteria(); - - private Map<String, BaseShape> getShapes(List<String> shapeNames) { - FindIterable<Document> userInstances = getUserInstances(); - final Map<String, BaseShape> shapes = new HashMap<>(); - - for (Document d : userInstances) { - getExploratoryShape(shapeNames, d) - .ifPresent(shape -> shapes.put(d.getString(EXPLORATORY_ID), shape)); - @SuppressWarnings("unchecked") - List<Document> comp = (List<Document>) d.get(COMPUTATIONAL_RESOURCES); - comp.forEach(c -> (isDataEngine(c.getString(DATAENGINE_DOCKER_IMAGE)) ? getDataEngineShape(shapeNames, c) : - getDataEngineServiceShape(shapeNames, c)) - .ifPresent(shape -> shapes.put(c.getString(COMPUTATIONAL_ID), shape))); - } - - StreamSupport.stream(getCollection(PROJECT_COLLECTION).find().spliterator(), false) - .forEach(d -> ((List<Document>) d.get("endpoints")) - .forEach(endpoint -> getEndpointShape(shapeNames, endpoint) - .ifPresent(shape -> shapes.put(String.format(EDGE_FORMAT, getServiceBaseName(), - d.getString("name").toLowerCase(), - endpoint.getString("name")), shape)))); - - getSsnShape(shapeNames) - .ifPresent(shape -> shapes.put(getServiceBaseName() + "-ssn", shape)); - - log.trace("Loaded shapes is {}", shapes); - return shapes; - } - - @Override public Double getTotalCost() { return aggregateBillingData(singletonList(group(null, sum(TOTAL_FIELD_NAME, COST_FIELD)))); } @@ -306,7 +96,6 @@ public abstract class BaseBillingDAO extends BaseDAO implements BillingDAO { .isPresent(); } - @Override public boolean isProjectQuoteReached(String project) { final Double projectCost = getProjectCost(project); @@ -320,10 +109,6 @@ public abstract class BaseBillingDAO extends BaseDAO implements BillingDAO { return toPercentage(() -> projectDAO.getAllowedBudget(project), getProjectCost(project)); } - private String getOrDefault(String value) { - return StringUtils.isNotBlank(value) ? value : SHARED_RESOURCE_NAME; - } - private Integer toPercentage(Supplier<Optional<Integer>> allowedBudget, Double totalCost) { return allowedBudget.get() .map(userBudget -> (totalCost * ONE_HUNDRED) / userBudget) @@ -331,152 +116,9 @@ public abstract class BaseBillingDAO extends BaseDAO implements BillingDAO { .orElse(BigDecimal.ZERO.intValue()); } - private List<Bson> matchCriteria(BillingFilter filter) { - - List<Bson> searchCriteria = new ArrayList<>(); - - if (filter.getUsers() != null && !filter.getUsers().isEmpty()) { - searchCriteria.add(Filters.in(MongoKeyWords.DLAB_USER, filter.getUsers())); - } - - if (filter.getResourceTypes() != null && !filter.getResourceTypes().isEmpty()) { - searchCriteria.add(Filters.in("dlab_resource_type", - DlabResourceType.getResourceTypeIds(filter.getResourceTypes()))); - } - - if (filter.getDlabId() != null && !filter.getDlabId().isEmpty()) { - searchCriteria.add(regex(dlabIdFieldName(), filter.getDlabId(), "i")); - } - - if (filter.getDateStart() != null && !filter.getDateStart().isEmpty()) { - searchCriteria.add(gte(FIELD_USAGE_DATE, filter.getDateStart())); - } - if (filter.getDateEnd() != null && !filter.getDateEnd().isEmpty()) { - searchCriteria.add(lte(FIELD_USAGE_DATE, filter.getDateEnd())); - } - if (filter.getProjects() != null && !filter.getProjects().isEmpty()) { - searchCriteria.add(in(PROJECT, filter.getProjects())); - } - - searchCriteria.addAll(cloudMatchCriteria(filter)); - return searchCriteria; - } - - protected abstract List<Bson> cloudMatchCriteria(BillingFilter filter); - private Double aggregateBillingData(List<Bson> pipeline) { return Optional.ofNullable(aggregate(BILLING, pipeline).first()) .map(d -> d.getDouble(TOTAL_FIELD_NAME)) .orElse(BigDecimal.ZERO.doubleValue()); } - - private FindIterable<Document> getUserInstances() { - return getCollection(USER_INSTANCES) - .find() - .projection( - fields(excludeId(), - include(SHAPE, EXPLORATORY_ID, STATUS, TAGS, - COMPUTATIONAL_RESOURCES + "." + COMPUTATIONAL_ID, - COMPUTATIONAL_RESOURCES + "." + MASTER_NODE_SHAPE, - COMPUTATIONAL_RESOURCES + "." + SLAVE_NODE_SHAPE, - COMPUTATIONAL_RESOURCES + "." + TOTAL_INSTANCE_NUMBER, - COMPUTATIONAL_RESOURCES + "." + DATAENGINE_SHAPE, - COMPUTATIONAL_RESOURCES + "." + DATAENGINE_INSTANCE_COUNT, - COMPUTATIONAL_RESOURCES + "." + DATAENGINE_DOCKER_IMAGE, - COMPUTATIONAL_RESOURCES + "." + STATUS, - COMPUTATIONAL_RESOURCES + "." + TAGS - ))); - } - - private Optional<ExploratoryShape> getExploratoryShape(List<String> shapeNames, Document d) { - final String shape = d.getString(SHAPE); - if (isShapeAcceptable(shapeNames, shape)) { - return Optional.of(ExploratoryShape.builder() - .shape(shape) - .status(UserInstanceStatus.of(d.getString(STATUS))) - .tags((Map<String, String>) d.get(TAGS)) - .build()); - } - return Optional.empty(); - } - - private Optional<DataEngineServiceShape> getDataEngineServiceShape(List<String> shapeNames, Document c) { - final String desMasterShape = c.getString(MASTER_NODE_SHAPE); - final String desSlaveShape = c.getString(SLAVE_NODE_SHAPE); - if (isShapeAcceptable(shapeNames, desMasterShape, desSlaveShape)) { - return Optional.of(DataEngineServiceShape.builder() - .shape(desMasterShape) - .status(UserInstanceStatus.of(c.getString(STATUS))) - .slaveCount(c.getString(TOTAL_INSTANCE_NUMBER)) - .slaveShape(desSlaveShape) - .tags((Map<String, String>) c.get(TAGS)) - .build()); - } - return Optional.empty(); - } - - private Optional<DataEngineShape> getDataEngineShape(List<String> shapeNames, Document c) { - final String shape = c.getString(DATAENGINE_SHAPE); - if ((isShapeAcceptable(shapeNames, shape)) && StringUtils.isNotEmpty(c.getString(COMPUTATIONAL_ID))) { - - return Optional.of(DataEngineShape.builder() - .shape(shape) - .status(UserInstanceStatus.of(c.getString(STATUS))) - .slaveCount(c.getString(DATAENGINE_INSTANCE_COUNT)) - .tags((Map<String, String>) c.get(TAGS)) - .build()); - } - return Optional.empty(); - } - - private Optional<SsnShape> getSsnShape(List<String> shapeNames) { - final String shape = getSsnShape(); - if (isShapeAcceptable(shapeNames, shape)) { - return Optional.of(SsnShape.builder() - .shape(shape) - .status(UserInstanceStatus.RUNNING) - .build()); - } - return Optional.empty(); - } - - private Optional<EndpointShape> getEndpointShape(List<String> shapeNames, Document endpoint) { - if (isShapeAcceptable(shapeNames, getSsnShape())) { - return Optional.of(EndpointShape.builder() - .shape(StringUtils.EMPTY) - .status(UserInstanceStatus.of(endpoint.getString("status"))) - .build()); - } - return Optional.empty(); - } - - private boolean isDataEngine(String dockerImage) { - return DataEngineType.fromDockerImageName(dockerImage) == DataEngineType.SPARK_STANDALONE; - } - - private boolean isShapeAcceptable(List<String> shapeNames, String... shapes) { - return shapeNames == null || shapeNames.isEmpty() || Arrays.stream(shapes).anyMatch(shapeNames::contains); - } - - protected String getServiceBaseName() { - return settings.getServiceBaseName(); - } - - protected String getSsnShape() { - return settings.getSsnInstanceSize(); - } - - protected void usersToLowerCase(List<String> users) { - if (users != null) { - users.replaceAll(u -> u != null ? u.toLowerCase() : null); - } - } - - protected void setUserFilter(UserInfo userInfo, BillingFilter filter, boolean isFullReport) { - if (isFullReport) { - usersToLowerCase(filter.getUsers()); - } else { - filter.setUsers(Lists.newArrayList(userInfo.getName().toLowerCase())); - } - } } 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 1ea06b8..d50c62f 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,10 +18,6 @@ */ package com.epam.dlab.backendapi.dao; -import com.epam.dlab.auth.UserInfo; -import com.epam.dlab.backendapi.resources.dto.BillingFilter; -import org.bson.Document; - public interface BillingDAO { Double getTotalCost(); @@ -40,6 +36,4 @@ public interface BillingDAO { boolean isUserQuoteReached(String user); boolean isProjectQuoteReached(String project); - - Document getReport(UserInfo userInfo, BillingFilter filter); } diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/aws/AwsBillingDAO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/aws/AwsBillingDAO.java deleted file mode 100644 index fde1d8f..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/aws/AwsBillingDAO.java +++ /dev/null @@ -1,74 +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.backendapi.dao.aws; - -import com.epam.dlab.MongoKeyWords; -import com.epam.dlab.backendapi.dao.BaseBillingDAO; -import com.epam.dlab.backendapi.resources.dto.BillingFilter; -import org.bson.Document; -import org.bson.conversions.Bson; - -import java.util.Collections; -import java.util.List; - -import static com.epam.dlab.model.aws.ReportLine.FIELD_COST; -import static com.epam.dlab.model.aws.ReportLine.FIELD_CURRENCY_CODE; -import static com.epam.dlab.model.aws.ReportLine.FIELD_DLAB_ID; -import static com.epam.dlab.model.aws.ReportLine.FIELD_PRODUCT; -import static com.epam.dlab.model.aws.ReportLine.FIELD_RESOURCE_TYPE; -import static com.epam.dlab.model.aws.ReportLine.FIELD_USAGE_DATE; -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.sort; - -/** - * DAO for user billing. - */ -public class AwsBillingDAO extends BaseBillingDAO { - - public static final String DLAB_RESOURCE_TYPE = "dlab_resource_type"; - public static final String USAGE_DATE_START = "from"; - public static final String USAGE_DATE_END = "to"; - public static final String TAG_RESOURCE_ID = "tag_resource_id"; - - @Override - protected Bson sortCriteria() { - return sort(new Document(ID + "." + USER, 1) - .append(ID + "." + FIELD_DLAB_ID, 1) - .append(ID + "." + DLAB_RESOURCE_TYPE, 1) - .append(ID + "." + FIELD_PRODUCT, 1)); - } - - @Override - protected Bson groupCriteria() { - return group(getGroupingFields(USER, FIELD_DLAB_ID, DLAB_RESOURCE_TYPE, FIELD_PRODUCT, FIELD_RESOURCE_TYPE, - FIELD_CURRENCY_CODE, FIELD_PROJECT), - sum(FIELD_COST, "$" + FIELD_COST), - min(MongoKeyWords.USAGE_FROM, "$" + FIELD_USAGE_DATE), - max(MongoKeyWords.USAGE_TO, "$" + FIELD_USAGE_DATE)); - } - - @Override - protected List<Bson> cloudMatchCriteria(BillingFilter filter) { - return Collections.emptyList(); - } -} \ No newline at end of file diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/azure/AzureBillingDAO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/azure/AzureBillingDAO.java deleted file mode 100644 index 8eeb52c..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/azure/AzureBillingDAO.java +++ /dev/null @@ -1,121 +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.backendapi.dao.azure; - -import com.epam.dlab.MongoKeyWords; -import com.epam.dlab.backendapi.dao.BaseBillingDAO; -import com.epam.dlab.backendapi.resources.dto.BillingFilter; -import com.epam.dlab.billing.DlabResourceType; -import com.google.inject.Singleton; -import com.mongodb.client.model.Accumulators; -import com.mongodb.client.model.Aggregates; -import com.mongodb.client.model.Filters; -import com.mongodb.client.model.Sorts; -import lombok.extern.slf4j.Slf4j; -import org.bson.Document; -import org.bson.conversions.Bson; - -import java.util.Collections; -import java.util.List; - -@Singleton -@Slf4j -public class AzureBillingDAO extends BaseBillingDAO { - public static final String SIZE = "size"; - - @Override - protected List<Bson> cloudMatchCriteria(BillingFilter filter) { - if (!filter.getProducts().isEmpty()) { - return Collections.singletonList(Filters.in(MongoKeyWords.METER_CATEGORY, filter.getProducts())); - } else { - return Collections.emptyList(); - } - } - - @Override - protected Bson groupCriteria() { - return Aggregates.group(getGroupingFields( - MongoKeyWords.DLAB_USER, - MongoKeyWords.DLAB_ID, - MongoKeyWords.RESOURCE_TYPE, - MongoKeyWords.METER_CATEGORY, - MongoKeyWords.CURRENCY_CODE, - FIELD_PROJECT), - Accumulators.sum(MongoKeyWords.COST, MongoKeyWords.prepend$(MongoKeyWords.COST)), - Accumulators.min(MongoKeyWords.USAGE_FROM, MongoKeyWords.prepend$(MongoKeyWords.USAGE_DAY)), - Accumulators.max(MongoKeyWords.USAGE_TO, MongoKeyWords.prepend$(MongoKeyWords.USAGE_DAY)) - ); - } - - @Override - protected Bson sortCriteria() { - return Aggregates.sort(Sorts.ascending( - MongoKeyWords.prependId(MongoKeyWords.DLAB_USER), - MongoKeyWords.prependId(MongoKeyWords.DLAB_ID), - MongoKeyWords.prependId(MongoKeyWords.RESOURCE_TYPE), - MongoKeyWords.prependId(MongoKeyWords.METER_CATEGORY))); - } - - @Override - protected String getServiceBaseName() { - return settings.getServiceBaseName().replace("_", "-").toLowerCase(); - } - - @Override - protected String shapeFieldName() { - return SIZE; - } - - @Override - protected String dlabIdFieldName() { - return MongoKeyWords.DLAB_ID; - } - - @Override - protected String productFieldName() { - return MongoKeyWords.METER_CATEGORY; - } - - @Override - protected String costFieldName() { - return MongoKeyWords.COST_STRING; - } - - @Override - protected String usageDateFromFieldName() { - return MongoKeyWords.USAGE_FROM; - } - - @Override - protected String usageDateToFieldName() { - return MongoKeyWords.USAGE_TO; - } - - @Override - protected String currencyCodeFieldName() { - return MongoKeyWords.CURRENCY_CODE; - } - - @Override - protected String resourceType(Document id) { - return DlabResourceType.getResourceTypeName(id.getString(MongoKeyWords.RESOURCE_TYPE)); - } - -} diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/gcp/GcpBillingDao.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/gcp/GcpBillingDao.java deleted file mode 100644 index 1105066..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/gcp/GcpBillingDao.java +++ /dev/null @@ -1,65 +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.backendapi.dao.gcp; - -import com.epam.dlab.backendapi.dao.BaseBillingDAO; -import com.epam.dlab.backendapi.resources.dto.BillingFilter; -import org.bson.Document; -import org.bson.conversions.Bson; - -import java.util.Collections; -import java.util.List; - -import static com.epam.dlab.MongoKeyWords.USAGE_FROM; -import static com.epam.dlab.MongoKeyWords.USAGE_TO; -import static com.epam.dlab.backendapi.dao.aws.AwsBillingDAO.DLAB_RESOURCE_TYPE; -import static com.epam.dlab.model.aws.ReportLine.FIELD_COST; -import static com.epam.dlab.model.aws.ReportLine.FIELD_DLAB_ID; -import static com.epam.dlab.model.aws.ReportLine.FIELD_PRODUCT; -import static com.epam.dlab.model.aws.ReportLine.FIELD_USAGE_DATE; -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.sort; - -public class GcpBillingDao extends BaseBillingDAO { - @Override - protected Bson sortCriteria() { - return sort(new Document(ID + "." + USER, 1) - .append(ID + "." + FIELD_DLAB_ID, 1) - .append(ID + "." + FIELD_PRODUCT, 1)); - } - - @Override - protected Bson groupCriteria() { - return group(getGroupingFields(USER, FIELD_DLAB_ID, DLAB_RESOURCE_TYPE, FIELD_PRODUCT, - currencyCodeFieldName(), FIELD_PROJECT), - sum(FIELD_COST, "$" + FIELD_COST), - min(USAGE_FROM, "$" + FIELD_USAGE_DATE), - max(USAGE_TO, "$" + FIELD_USAGE_DATE) - ); - } - - @Override - protected List<Bson> cloudMatchCriteria(BillingFilter filter) { - return Collections.emptyList(); - } -} diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BaseShape.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BaseShape.java deleted file mode 100644 index 4a56034..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/BaseShape.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.epam.dlab.backendapi.domain; - -import com.epam.dlab.backendapi.service.ShapeFormat; -import com.epam.dlab.dto.UserInstanceStatus; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.Map; - -@Data -@AllArgsConstructor -@NoArgsConstructor -public class BaseShape implements ShapeFormat { - protected String shape; - protected UserInstanceStatus status; - protected Map<String, String> tags; - - @Override - public String format() { - return shape; - } -} diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/DataEngineServiceShape.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/DataEngineServiceShape.java deleted file mode 100644 index 73c0193..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/DataEngineServiceShape.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.epam.dlab.backendapi.domain; - -import com.epam.dlab.backendapi.service.ShapeFormat; -import com.epam.dlab.dto.UserInstanceStatus; -import lombok.Builder; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.Map; - - -@Slf4j -public class DataEngineServiceShape extends BaseShape implements ShapeFormat { - private static final String DES_NAME_FORMAT = "Master: %s%sSlave: %d x %s"; - private String slaveCount; - private String slaveShape; - - @Builder - public DataEngineServiceShape(String shape, UserInstanceStatus status, String slaveCount, String slaveShape, - Map<String, String> tags) { - super(shape, status, tags); - this.slaveCount = slaveCount; - this.slaveShape = slaveShape; - } - - @Override - public String format() { - Integer count; - try { - count = Integer.valueOf(slaveCount); - } catch (NumberFormatException e) { - log.error("Cannot parse string {} to integer", slaveCount); - return StringUtils.EMPTY; - } - return String.format(DES_NAME_FORMAT, shape, System.lineSeparator(), count - 1, slaveShape); - } -} diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/DataEngineShape.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/DataEngineShape.java deleted file mode 100644 index 8d4c003..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/DataEngineShape.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.epam.dlab.backendapi.domain; - -import com.epam.dlab.backendapi.service.ShapeFormat; -import com.epam.dlab.dto.UserInstanceStatus; -import lombok.Builder; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.Map; - -@Slf4j -public class DataEngineShape extends BaseShape implements ShapeFormat { - private static final String DE_NAME_FORMAT = "%d x %s"; - private String slaveCount; - - - @Builder - public DataEngineShape(String shape, UserInstanceStatus status, String slaveCount, Map<String, String> tags) { - super(shape, status, tags); - this.slaveCount = slaveCount; - } - - @Override - public String format() { - Integer count; - try { - count = Integer.valueOf(slaveCount); - } catch (NumberFormatException e) { - log.error("Cannot parse string {} to integer", slaveCount); - return StringUtils.EMPTY; - } - return String.format(DE_NAME_FORMAT, count, shape); - } -} diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/EndpointShape.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/EndpointShape.java deleted file mode 100644 index 5f41cad..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/EndpointShape.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.epam.dlab.backendapi.domain; - -import com.epam.dlab.dto.UserInstanceStatus; -import lombok.Builder; - -import java.util.Collections; - -public class EndpointShape extends BaseShape { - - @Builder - public EndpointShape(String shape, UserInstanceStatus status) { - super(shape, status, Collections.emptyMap()); - } -} diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ExploratoryShape.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ExploratoryShape.java deleted file mode 100644 index 74ceab0..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ExploratoryShape.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.epam.dlab.backendapi.domain; - -import com.epam.dlab.dto.UserInstanceStatus; -import lombok.Builder; - -import java.util.Map; - -public class ExploratoryShape extends BaseShape { - - @Builder - public ExploratoryShape(String shape, UserInstanceStatus status, Map<String, String> tags) { - super(shape, status, tags); - } -} diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/SsnShape.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/SsnShape.java deleted file mode 100644 index a38a99e..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/SsnShape.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.epam.dlab.backendapi.domain; - -import com.epam.dlab.dto.UserInstanceStatus; -import lombok.Builder; - -import java.util.Collections; - -public class SsnShape extends BaseShape { - - @Builder - public SsnShape(String shape, UserInstanceStatus status) { - super(shape, status, Collections.emptyMap()); - } -} diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/AwsSelfServiceModule.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/AwsSelfServiceModule.java deleted file mode 100644 index 0fd45de..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/AwsSelfServiceModule.java +++ /dev/null @@ -1,83 +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.backendapi.modules; - -import com.epam.dlab.backendapi.SelfServiceApplication; -import com.epam.dlab.backendapi.annotation.BudgetLimited; -import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration; -import com.epam.dlab.backendapi.dao.BillingDAO; -import com.epam.dlab.backendapi.dao.aws.AwsBillingDAO; -import com.epam.dlab.backendapi.interceptor.BudgetLimitInterceptor; -import com.epam.dlab.backendapi.resources.aws.ComputationalResourceAws; -import com.epam.dlab.backendapi.service.BillingService; -import com.epam.dlab.backendapi.service.aws.AwsBillingService; -import com.epam.dlab.cloud.CloudModule; -import com.epam.dlab.mongo.MongoServiceFactory; -import com.fiestacabin.dropwizard.quartz.SchedulerConfiguration; -import com.google.inject.Injector; -import com.google.inject.Provides; -import com.google.inject.Singleton; -import io.dropwizard.setup.Environment; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.impl.StdSchedulerFactory; - -import static com.google.inject.matcher.Matchers.annotatedWith; -import static com.google.inject.matcher.Matchers.any; - -public class AwsSelfServiceModule extends CloudModule { - - private static final String MONGO_URI_FORMAT = "mongodb://%s:%s@%s:%d/%s"; - private static final String QUARTZ_MONGO_URI_PROPERTY = "org.quartz.jobStore.mongoUri"; - private static final String QUARTZ_DB_NAME = "org.quartz.jobStore.dbName"; - - @Override - protected void configure() { - bind(BillingService.class).to(AwsBillingService.class); - bind(SchedulerConfiguration.class).toInstance( - new SchedulerConfiguration(SelfServiceApplication.class.getPackage().getName())); - bind(BillingDAO.class).to(AwsBillingDAO.class); - final BudgetLimitInterceptor budgetLimitInterceptor = new BudgetLimitInterceptor(); - requestInjection(budgetLimitInterceptor); - bindInterceptor(any(), annotatedWith(BudgetLimited.class), budgetLimitInterceptor); - } - - @Override - public void init(Environment environment, Injector injector) { - environment.jersey().register(injector.getInstance(ComputationalResourceAws.class)); -// - - /*injector.getInstance(SecurityFactory.class).configure(injector, environment, - SelfServiceSecurityAuthenticator.class, injector.getInstance(Authorizer.class));*/ - } - - - @Provides - @Singleton - Scheduler provideScheduler(SelfServiceApplicationConfiguration configuration) throws SchedulerException { - final MongoServiceFactory mongoFactory = configuration.getMongoFactory(); - final String database = mongoFactory.getDatabase(); - final String mongoUri = String.format(MONGO_URI_FORMAT, mongoFactory.getUsername(), mongoFactory.getPassword(), - mongoFactory.getHost(), mongoFactory.getPort(), database); - System.setProperty(QUARTZ_MONGO_URI_PROPERTY, mongoUri); - System.setProperty(QUARTZ_DB_NAME, database); - return StdSchedulerFactory.getDefaultScheduler(); - } -} diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/AzureSelfServiceModule.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/AzureSelfServiceModule.java deleted file mode 100644 index ee04041..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/AzureSelfServiceModule.java +++ /dev/null @@ -1,81 +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.backendapi.modules; - -import com.epam.dlab.backendapi.SelfServiceApplication; -import com.epam.dlab.backendapi.annotation.BudgetLimited; -import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration; -import com.epam.dlab.backendapi.dao.BillingDAO; -import com.epam.dlab.backendapi.dao.azure.AzureBillingDAO; -import com.epam.dlab.backendapi.interceptor.BudgetLimitInterceptor; -import com.epam.dlab.backendapi.resources.azure.ComputationalResourceAzure; -import com.epam.dlab.backendapi.service.BillingService; -import com.epam.dlab.backendapi.service.azure.AzureBillingService; -import com.epam.dlab.cloud.CloudModule; -import com.epam.dlab.mongo.MongoServiceFactory; -import com.fiestacabin.dropwizard.quartz.SchedulerConfiguration; -import com.google.inject.Injector; -import com.google.inject.Provides; -import com.google.inject.Singleton; -import io.dropwizard.setup.Environment; -import lombok.extern.slf4j.Slf4j; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.impl.StdSchedulerFactory; - -import static com.google.inject.matcher.Matchers.annotatedWith; -import static com.google.inject.matcher.Matchers.any; - -@Slf4j -public class AzureSelfServiceModule extends CloudModule { - - private static final String MONGO_URI_FORMAT = "mongodb://%s:%s@%s:%d/%s"; - private static final String QUARTZ_MONGO_URI_PROPERTY = "org.quartz.jobStore.mongoUri"; - private static final String QUARTZ_DB_NAME = "org.quartz.jobStore.dbName"; - - @Override - protected void configure() { - bind(BillingService.class).to(AzureBillingService.class); - bind(SchedulerConfiguration.class).toInstance( - new SchedulerConfiguration(SelfServiceApplication.class.getPackage().getName())); - bind(BillingDAO.class).to(AzureBillingDAO.class); - final BudgetLimitInterceptor budgetLimitInterceptor = new BudgetLimitInterceptor(); - requestInjection(budgetLimitInterceptor); - bindInterceptor(any(), annotatedWith(BudgetLimited.class), budgetLimitInterceptor); - } - - @Override - public void init(Environment environment, Injector injector) { - environment.jersey().register(injector.getInstance(ComputationalResourceAzure.class)); - - } - - @Provides - @Singleton - Scheduler provideScheduler(SelfServiceApplicationConfiguration configuration) throws SchedulerException { - final MongoServiceFactory mongoFactory = configuration.getMongoFactory(); - final String database = mongoFactory.getDatabase(); - final String mongoUri = String.format(MONGO_URI_FORMAT, mongoFactory.getUsername(), mongoFactory.getPassword(), - mongoFactory.getHost(), mongoFactory.getPort(), database); - System.setProperty(QUARTZ_MONGO_URI_PROPERTY, mongoUri); - System.setProperty(QUARTZ_DB_NAME, database); - return StdSchedulerFactory.getDefaultScheduler(); - } -} diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/CloudProviderModule.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/CloudProviderModule.java index 0ee0d10..f251b01 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/CloudProviderModule.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/CloudProviderModule.java @@ -22,10 +22,6 @@ package com.epam.dlab.backendapi.modules; import com.epam.dlab.backendapi.SelfServiceApplication; import com.epam.dlab.backendapi.annotation.BudgetLimited; import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration; -import com.epam.dlab.backendapi.dao.BillingDAO; -import com.epam.dlab.backendapi.dao.aws.AwsBillingDAO; -import com.epam.dlab.backendapi.dao.azure.AzureBillingDAO; -import com.epam.dlab.backendapi.dao.gcp.GcpBillingDao; import com.epam.dlab.backendapi.interceptor.BudgetLimitInterceptor; import com.epam.dlab.backendapi.resources.BillingResource; import com.epam.dlab.backendapi.resources.aws.ComputationalResourceAws; @@ -33,13 +29,9 @@ import com.epam.dlab.backendapi.resources.azure.ComputationalResourceAzure; import com.epam.dlab.backendapi.resources.gcp.ComputationalResourceGcp; import com.epam.dlab.backendapi.resources.gcp.GcpOauthResource; import com.epam.dlab.backendapi.service.BillingService; -import com.epam.dlab.backendapi.service.BillingServiceNew; import com.epam.dlab.backendapi.service.InfrastructureInfoService; import com.epam.dlab.backendapi.service.InfrastructureTemplateService; -import com.epam.dlab.backendapi.service.aws.AwsBillingService; -import com.epam.dlab.backendapi.service.azure.AzureBillingService; -import com.epam.dlab.backendapi.service.gcp.GcpBillingService; -import com.epam.dlab.backendapi.service.impl.BillingServiceImplNew; +import com.epam.dlab.backendapi.service.impl.BillingServiceImpl; import com.epam.dlab.backendapi.service.impl.InfrastructureInfoServiceImpl; import com.epam.dlab.backendapi.service.impl.InfrastructureTemplateServiceImpl; import com.epam.dlab.cloud.CloudModule; @@ -70,8 +62,7 @@ public class CloudProviderModule extends CloudModule { @Override protected void configure() { - bindBilling(); - bind(BillingServiceNew.class).to(BillingServiceImplNew.class); + bind(BillingService.class).to(BillingServiceImpl.class); bind(InfrastructureInfoService.class).to(InfrastructureInfoServiceImpl.class); bind(InfrastructureTemplateService.class).to(InfrastructureTemplateServiceImpl.class); bind(SchedulerConfiguration.class).toInstance( @@ -104,23 +95,4 @@ public class CloudProviderModule extends CloudModule { System.setProperty(QUARTZ_DB_NAME, database); return StdSchedulerFactory.getDefaultScheduler(); } - - private void bindBilling() { - switch (configuration.getCloudProvider()) { - case AWS: - bind(BillingService.class).to(AwsBillingService.class); - bind(BillingDAO.class).to(AwsBillingDAO.class); - break; - case AZURE: - bind(BillingService.class).to(AzureBillingService.class); - bind(BillingDAO.class).to(AzureBillingDAO.class); - break; - case GCP: - bind(BillingService.class).to(GcpBillingService.class); - bind(BillingDAO.class).to(GcpBillingDao.class); - break; - default: - throw new UnsupportedOperationException("Unsupported cloud provider " + configuration.getCloudProvider()); - } - } } diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/GcpSelfServiceModule.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/GcpSelfServiceModule.java deleted file mode 100644 index 276238e..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/GcpSelfServiceModule.java +++ /dev/null @@ -1,84 +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.backendapi.modules; - -import com.epam.dlab.backendapi.SelfServiceApplication; -import com.epam.dlab.backendapi.annotation.BudgetLimited; -import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration; -import com.epam.dlab.backendapi.dao.BillingDAO; -import com.epam.dlab.backendapi.dao.gcp.GcpBillingDao; -import com.epam.dlab.backendapi.interceptor.BudgetLimitInterceptor; -import com.epam.dlab.backendapi.resources.gcp.ComputationalResourceGcp; -import com.epam.dlab.backendapi.resources.gcp.GcpOauthResource; -import com.epam.dlab.backendapi.service.BillingService; -import com.epam.dlab.backendapi.service.gcp.GcpBillingService; -import com.epam.dlab.cloud.CloudModule; -import com.epam.dlab.mongo.MongoServiceFactory; -import com.fiestacabin.dropwizard.quartz.SchedulerConfiguration; -import com.google.inject.Injector; -import com.google.inject.Provides; -import com.google.inject.Singleton; -import io.dropwizard.setup.Environment; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.impl.StdSchedulerFactory; - -import static com.google.inject.matcher.Matchers.annotatedWith; -import static com.google.inject.matcher.Matchers.any; - -public class GcpSelfServiceModule extends CloudModule { - - private static final String MONGO_URI_FORMAT = "mongodb://%s:%s@%s:%d/%s"; - private static final String QUARTZ_MONGO_URI_PROPERTY = "org.quartz.jobStore.mongoUri"; - private static final String QUARTZ_DB_NAME = "org.quartz.jobStore.dbName"; - - @Override - @SuppressWarnings("unchecked") - public void init(Environment environment, Injector injector) { - environment.jersey().register(injector.getInstance(ComputationalResourceGcp.class)); - if (injector.getInstance(SelfServiceApplicationConfiguration.class).isGcpOuauth2AuthenticationEnabled()) { - environment.jersey().register(injector.getInstance(GcpOauthResource.class)); - } - - } - - @Override - protected void configure() { - bind(BillingService.class).to(GcpBillingService.class); - bind(BillingDAO.class).to(GcpBillingDao.class); - bind(SchedulerConfiguration.class).toInstance( - new SchedulerConfiguration(SelfServiceApplication.class.getPackage().getName())); - final BudgetLimitInterceptor budgetLimitInterceptor = new BudgetLimitInterceptor(); - requestInjection(budgetLimitInterceptor); - bindInterceptor(any(), annotatedWith(BudgetLimited.class), budgetLimitInterceptor); - } - - @Provides - @Singleton - Scheduler provideScheduler(SelfServiceApplicationConfiguration configuration) throws SchedulerException { - final MongoServiceFactory mongoFactory = configuration.getMongoFactory(); - final String database = mongoFactory.getDatabase(); - final String mongoUri = String.format(MONGO_URI_FORMAT, mongoFactory.getUsername(), mongoFactory.getPassword(), - mongoFactory.getHost(), mongoFactory.getPort(), database); - System.setProperty(QUARTZ_MONGO_URI_PROPERTY, mongoUri); - System.setProperty(QUARTZ_DB_NAME, database); - return StdSchedulerFactory.getDefaultScheduler(); - } -} diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/ModuleFactory.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/ModuleFactory.java index 1480fe7..eb8d3bc 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/ModuleFactory.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/ModuleFactory.java @@ -48,17 +48,4 @@ public class ModuleFactory { public static CloudModule getCloudProviderModule(SelfServiceApplicationConfiguration configuration) { return new CloudProviderModule(configuration); } - - private static CloudModule getCloudModule(SelfServiceApplicationConfiguration configuration) { - switch (configuration.getCloudProvider()) { - case AWS: - return new AwsSelfServiceModule(); - case AZURE: - return new AzureSelfServiceModule(); - case GCP: - return new GcpSelfServiceModule(); - default: - throw new UnsupportedOperationException("Unsupported cloud provider " + configuration.getCloudProvider()); - } - } } diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/BillingResource.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/BillingResource.java index 54e3695..1916a38 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/BillingResource.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/BillingResource.java @@ -22,7 +22,6 @@ package com.epam.dlab.backendapi.resources; import com.epam.dlab.auth.UserInfo; import com.epam.dlab.backendapi.resources.dto.BillingFilter; import com.epam.dlab.backendapi.service.BillingService; -import com.epam.dlab.backendapi.service.BillingServiceNew; import com.google.inject.Inject; import io.dropwizard.auth.Auth; @@ -41,43 +40,24 @@ import javax.ws.rs.core.Response; public class BillingResource { private final BillingService billingService; - private final BillingServiceNew billingServiceNew; @Inject - public BillingResource(BillingService billingService, BillingServiceNew billingServiceNew) { + public BillingResource(BillingService billingService) { this.billingService = billingService; - this.billingServiceNew = billingServiceNew; } -// @POST -// @Path("/report") -// @Produces(MediaType.APPLICATION_JSON) -// public Document getBillingReport(@Auth UserInfo userInfo, @Valid @NotNull BillingFilter formDTO) { -// return billingService.getBillingReport(userInfo, formDTO); -// } -// -// @POST -// @Path("/report/download") -// @Produces(MediaType.APPLICATION_OCTET_STREAM) -// public Response downloadBillingReport(@Auth UserInfo userInfo, @Valid @NotNull BillingFilter formDTO) { -// return Response.ok(billingService.downloadReport(userInfo, formDTO)) -// .header(HttpHeaders.CONTENT_DISPOSITION, -// "attachment; filename=\"" + billingService.getReportFileName(userInfo, formDTO) + "\"") -// .build(); -// } - @POST @Path("/report") @Produces(MediaType.APPLICATION_JSON) public Response getBillingReport(@Auth UserInfo userInfo, @Valid @NotNull BillingFilter filter) { - return Response.ok(billingServiceNew.getBillingReport(userInfo, filter)).build(); + return Response.ok(billingService.getBillingReport(userInfo, filter)).build(); } @POST @Path("/report/download") @Produces(MediaType.APPLICATION_OCTET_STREAM) public Response downloadBillingReport(@Auth UserInfo userInfo, @Valid @NotNull BillingFilter filter) { - return Response.ok(billingServiceNew.downloadReport(userInfo, filter)) + return Response.ok(billingService.downloadReport(userInfo, filter)) .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"billing-report.csv\"") .build(); } 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 c16bd10..40a5c14 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 @@ -20,82 +20,20 @@ package com.epam.dlab.backendapi.service; import com.epam.dlab.auth.UserInfo; -import com.epam.dlab.backendapi.dao.BaseBillingDAO; -import com.epam.dlab.backendapi.dao.BillingDAO; +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.backendapi.util.CSVFormatter; -import com.epam.dlab.exceptions.DlabException; -import com.google.inject.Inject; -import jersey.repackaged.com.google.common.collect.Lists; -import lombok.extern.slf4j.Slf4j; -import org.bson.Document; +import com.epam.dlab.dto.UserInstanceDTO; +import com.epam.dlab.dto.billing.BillingData; -import java.text.ParseException; import java.util.List; -@Slf4j -public abstract class BillingService { +public interface BillingService { + BillingReport getBillingReport(UserInfo userInfo, BillingFilter filter); - @Inject - private BillingDAO billingDAO; + String downloadReport(UserInfo userInfo, BillingFilter filter); - public Document getReport(UserInfo userInfo, BillingFilter filter) { - log.trace("Get billing report for user {} with filter {}", userInfo.getName(), filter); - try { - return billingDAO.getReport(userInfo, filter); - } catch (RuntimeException t) { - log.error("Cannot load billing report for user {} with filter {}", userInfo.getName(), filter, t); - throw new DlabException("Cannot load billing report: " + t.getLocalizedMessage(), t); - } - } + List<BillingReportLine> getBillingReportLines(UserInfo userInfo, BillingFilter filter); - protected String getValueOrEmpty(Document document, String key) { - String value = document.getString(key); - return value == null ? "" : value; - } - - String getHeaders(boolean full) { - return CSVFormatter.formatLine(getHeadersList(full), CSVFormatter.SEPARATOR); - } - - public Document getBillingReport(UserInfo userInfo, BillingFilter filter) { - filter.getUsers().replaceAll(s -> s.equalsIgnoreCase(BaseBillingDAO.SHARED_RESOURCE_NAME) ? null : s); - return getReport(userInfo, filter); - } - - public byte[] downloadReport(UserInfo userInfo, BillingFilter filter) { - return prepareReport(getReport(userInfo, filter)).getBytes(); - } - - String prepareReport(Document document) { - try { - StringBuilder builder = - new StringBuilder(CSVFormatter.formatLine(Lists.newArrayList(getFirstLine(document)), - CSVFormatter.SEPARATOR, '\"')); - - Boolean full = (Boolean) document.get(BaseBillingDAO.FULL_REPORT); - builder.append(getHeaders(full)); - - @SuppressWarnings("unchecked") - List<Document> items = (List<Document>) document.get(BaseBillingDAO.ITEMS); - - items.forEach(d -> builder.append(getLine(full, d))); - - builder.append(getTotal(full, document)); - - return builder.toString(); - } catch (ParseException e) { - throw new DlabException("Cannot prepare CSV file", e); - } - } - - public abstract String getFirstLine(Document document) throws ParseException; - - public abstract List<String> getHeadersList(boolean full); - - public abstract String getLine(boolean full, Document document); - - public abstract String getTotal(boolean full, Document document); - - public abstract String getReportFileName(UserInfo userInfo, BillingFilter filter); + List<BillingData> getExploratoryRemoteBillingData(UserInfo user, String endpoint, List<UserInstanceDTO> userInstanceDTOS); } 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 deleted file mode 100644 index 0ec17a9..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/BillingServiceNew.java +++ /dev/null @@ -1,39 +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.backendapi.service; - -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; - -public interface BillingServiceNew { - BillingReport getBillingReport(UserInfo userInfo, BillingFilter filter); - - String downloadReport(UserInfo userInfo, BillingFilter filter); - - List<BillingReportLine> getBillingReportLines(UserInfo userInfo, BillingFilter filter); - - List<BillingData> getExploratoryRemoteBillingData(UserInfo user, String endpoint, List<UserInstanceDTO> userInstanceDTOS); -} diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ShapeFormat.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ShapeFormat.java deleted file mode 100644 index da224ab..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ShapeFormat.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.epam.dlab.backendapi.service; - -public interface ShapeFormat { - String format(); -} diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/aws/AwsBillingService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/aws/AwsBillingService.java deleted file mode 100644 index eb94ea5..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/aws/AwsBillingService.java +++ /dev/null @@ -1,110 +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.backendapi.service.aws; - -import com.epam.dlab.auth.UserInfo; -import com.epam.dlab.backendapi.dao.aws.AwsBillingDAO; -import com.epam.dlab.backendapi.resources.dto.BillingFilter; -import com.epam.dlab.backendapi.service.BillingService; -import com.epam.dlab.backendapi.util.CSVFormatter; -import com.epam.dlab.model.aws.ReportLine; -import com.google.inject.Singleton; -import lombok.extern.slf4j.Slf4j; -import org.bson.Document; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.List; - -@Slf4j -@Singleton -public class AwsBillingService extends BillingService { - - @Override - public String getReportFileName(UserInfo userInfo, BillingFilter filter) { - return "aws-billing-report.csv"; - } - - public String getFirstLine(Document document) throws ParseException { - - SimpleDateFormat from = new SimpleDateFormat("yyyy-MM-dd"); - SimpleDateFormat to = new SimpleDateFormat("MMM dd, yyyy"); - - return String.format("Service base name: %s " + - "Resource tag ID: %s " + - "Available reporting period from: %s to: %s", - document.get(AwsBillingDAO.SERVICE_BASE_NAME), document.get(AwsBillingDAO.TAG_RESOURCE_ID), - to.format(from.parse((String) document.get(AwsBillingDAO.USAGE_DATE_START))), - to.format(from.parse((String) document.get(AwsBillingDAO.USAGE_DATE_END)))); - - } - - public List<String> getHeadersList(boolean full) { - List<String> headers = new ArrayList<>(); - - if (full) { - headers.add("USER"); - } - - headers.add("PROJECT"); - headers.add("ENVIRONMENT NAME"); - headers.add("RESOURCE TYPE"); - headers.add("SHAPE"); - headers.add("SERVICE"); - headers.add("SERVICE CHARGES"); - - return headers; - } - - public String getLine(boolean full, Document document) { - List<String> items = new ArrayList<>(); - - if (full) { - items.add(getValueOrEmpty(document, ReportLine.FIELD_USER_ID)); - } - - items.add(getValueOrEmpty(document, ReportLine.FIELD_PROJECT)); - items.add(getValueOrEmpty(document, ReportLine.FIELD_DLAB_ID)); - items.add(getValueOrEmpty(document, AwsBillingDAO.DLAB_RESOURCE_TYPE)); - items.add(getValueOrEmpty(document, AwsBillingDAO.SHAPE).replace(System.lineSeparator(), " ")); - items.add(getValueOrEmpty(document, ReportLine.FIELD_PRODUCT)); - - items.add(getValueOrEmpty(document, ReportLine.FIELD_COST) - + " " + getValueOrEmpty(document, ReportLine.FIELD_CURRENCY_CODE)); - - return CSVFormatter.formatLine(items, CSVFormatter.SEPARATOR); - } - - public String getTotal(boolean full, Document document) { - int padding = getHeadersList(full).size() - 1; - - List<String> items = new ArrayList<>(); - while (padding-- > 0) { - items.add(""); - } - - items.add(String.format("Total: %s %s", getValueOrEmpty(document, AwsBillingDAO.COST_TOTAL), - getValueOrEmpty(document, ReportLine.FIELD_CURRENCY_CODE))); - - return CSVFormatter.formatLine(items, CSVFormatter.SEPARATOR); - - } -} diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/azure/AzureBillingService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/azure/AzureBillingService.java deleted file mode 100644 index 9ff33a8..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/azure/AzureBillingService.java +++ /dev/null @@ -1,116 +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.backendapi.service.azure; - -import com.epam.dlab.MongoKeyWords; -import com.epam.dlab.auth.UserInfo; -import com.epam.dlab.backendapi.dao.BaseBillingDAO; -import com.epam.dlab.backendapi.dao.BillingDAO; -import com.epam.dlab.backendapi.dao.azure.AzureBillingDAO; -import com.epam.dlab.backendapi.resources.dto.BillingFilter; -import com.epam.dlab.backendapi.service.BillingService; -import com.epam.dlab.backendapi.util.CSVFormatter; -import com.epam.dlab.model.aws.ReportLine; -import com.google.inject.Inject; -import com.google.inject.Singleton; -import lombok.extern.slf4j.Slf4j; -import org.bson.Document; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.List; - -@Slf4j -@Singleton -public class AzureBillingService extends BillingService { - - @Inject - private BillingDAO billingDAO; - - @Override - public String getReportFileName(UserInfo userInfo, BillingFilter filter) { - return "azure-billing-report.csv"; - } - - @Override - public String getFirstLine(Document document) throws ParseException { - SimpleDateFormat from = new SimpleDateFormat("yyyy-MM-dd"); - SimpleDateFormat to = new SimpleDateFormat("MMM dd, yyyy"); - - return String.format("Service base name: %s " + - "Available reporting period from: %s to: %s", - document.get(BaseBillingDAO.SERVICE_BASE_NAME), - to.format(from.parse((String) document.get(MongoKeyWords.USAGE_FROM))), - to.format(from.parse((String) document.get(MongoKeyWords.USAGE_TO)))); - } - - public List<String> getHeadersList(boolean full) { - List<String> headers = new ArrayList<>(); - - if (full) { - headers.add("USER"); - } - - headers.add("PROJECT"); - headers.add("ENVIRONMENT NAME"); - headers.add("RESOURCE TYPE"); - headers.add("INSTANCE SIZE"); - headers.add("CATEGORY"); - headers.add("SERVICE CHARGES"); - - return headers; - } - - @Override - public String getLine(boolean full, Document document) { - List<String> items = new ArrayList<>(); - - if (full) { - items.add(getValueOrEmpty(document, MongoKeyWords.DLAB_USER)); - } - - items.add(getValueOrEmpty(document, ReportLine.FIELD_PROJECT)); - items.add(getValueOrEmpty(document, MongoKeyWords.DLAB_ID)); - items.add(getValueOrEmpty(document, MongoKeyWords.RESOURCE_TYPE)); - items.add(getValueOrEmpty(document, AzureBillingDAO.SIZE).replace(System.lineSeparator(), " ")); - items.add(getValueOrEmpty(document, MongoKeyWords.METER_CATEGORY)); - - items.add(getValueOrEmpty(document, MongoKeyWords.COST_STRING) - + " " + getValueOrEmpty(document, MongoKeyWords.CURRENCY_CODE)); - - return CSVFormatter.formatLine(items, CSVFormatter.SEPARATOR); - } - - @Override - public String getTotal(boolean full, Document document) { - int padding = getHeadersList(full).size() - 1; - - List<String> items = new ArrayList<>(); - while (padding-- > 0) { - items.add(""); - } - - items.add(String.format("Total: %s %s", getValueOrEmpty(document, MongoKeyWords.COST_STRING), - getValueOrEmpty(document, MongoKeyWords.CURRENCY_CODE))); - - return CSVFormatter.formatLine(items, CSVFormatter.SEPARATOR); - } -} diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/gcp/GcpBillingService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/gcp/GcpBillingService.java deleted file mode 100644 index a7599f7..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/gcp/GcpBillingService.java +++ /dev/null @@ -1,104 +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.backendapi.service.gcp; - -import com.epam.dlab.auth.UserInfo; -import com.epam.dlab.backendapi.dao.aws.AwsBillingDAO; -import com.epam.dlab.backendapi.resources.dto.BillingFilter; -import com.epam.dlab.backendapi.service.BillingService; -import com.epam.dlab.backendapi.util.CSVFormatter; -import com.epam.dlab.model.aws.ReportLine; -import org.bson.Document; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.List; - -public class GcpBillingService extends BillingService { - @Override - public String getFirstLine(Document document) throws ParseException { - SimpleDateFormat from = new SimpleDateFormat("yyyy-MM-dd"); - SimpleDateFormat to = new SimpleDateFormat("MMM dd, yyyy"); - - return String.format("Service base name: %s Available reporting period from: %s to: %s", - document.get(AwsBillingDAO.SERVICE_BASE_NAME), - to.format(from.parse((String) document.get("from"))), - to.format(from.parse((String) document.get("to")))); - } - - @Override - public List<String> getHeadersList(boolean full) { - List<String> headers = new ArrayList<>(); - - if (full) { - headers.add("USER"); - } - - headers.add("PROJECT"); - headers.add("ENVIRONMENT NAME"); - headers.add("RESOURCE TYPE"); - headers.add("SHAPE"); - headers.add("SERVICE"); - headers.add("SERVICE CHARGES"); - - return headers; - } - - @Override - public String getLine(boolean full, Document document) { - List<String> items = new ArrayList<>(); - - if (full) { - items.add(getValueOrEmpty(document, ReportLine.FIELD_USER_ID)); - } - - items.add(getValueOrEmpty(document, ReportLine.FIELD_PROJECT)); - items.add(getValueOrEmpty(document, ReportLine.FIELD_DLAB_ID)); - items.add(getValueOrEmpty(document, AwsBillingDAO.DLAB_RESOURCE_TYPE)); - items.add(getValueOrEmpty(document, AwsBillingDAO.SHAPE).replace(System.lineSeparator(), " ")); - items.add(getValueOrEmpty(document, ReportLine.FIELD_PRODUCT)); - - items.add(getValueOrEmpty(document, ReportLine.FIELD_COST) - + " " + getValueOrEmpty(document, ReportLine.FIELD_CURRENCY_CODE)); - - return CSVFormatter.formatLine(items, CSVFormatter.SEPARATOR); - } - - @Override - public String getTotal(boolean full, Document document) { - int padding = getHeadersList(full).size() - 1; - - List<String> items = new ArrayList<>(); - while (padding-- > 0) { - items.add(""); - } - - items.add(String.format("Total: %s %s", getValueOrEmpty(document, AwsBillingDAO.COST_TOTAL), - getValueOrEmpty(document, ReportLine.FIELD_CURRENCY_CODE))); - - return CSVFormatter.formatLine(items, CSVFormatter.SEPARATOR); - } - - @Override - public String getReportFileName(UserInfo userInfo, BillingFilter filter) { - return "gcp-billing-report.csv"; - } -} 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/BillingServiceImpl.java similarity index 96% rename from services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImplNew.java rename to services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImpl.java index d922461..100dd00 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/BillingServiceImpl.java @@ -29,7 +29,7 @@ import com.epam.dlab.backendapi.domain.ProjectEndpointDTO; import com.epam.dlab.backendapi.resources.dto.BillingFilter; import com.epam.dlab.backendapi.roles.RoleType; import com.epam.dlab.backendapi.roles.UserRoles; -import com.epam.dlab.backendapi.service.BillingServiceNew; +import com.epam.dlab.backendapi.service.BillingService; import com.epam.dlab.backendapi.service.EndpointService; import com.epam.dlab.backendapi.service.ExploratoryService; import com.epam.dlab.backendapi.service.ProjectService; @@ -69,7 +69,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; @Slf4j -public class BillingServiceImplNew implements BillingServiceNew { +public class BillingServiceImpl implements BillingService { private static final String BILLING_PATH = "/api/billing"; private static final String BILLING_REPORT_PATH = "/api/billing/report"; @@ -80,9 +80,9 @@ public class BillingServiceImplNew implements BillingServiceNew { private final RESTService provisioningService; @Inject - public BillingServiceImplNew(ProjectService projectService, EndpointService endpointService, - ExploratoryService exploratoryService, SelfServiceApplicationConfiguration configuration, - @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService) { + public BillingServiceImpl(ProjectService projectService, EndpointService endpointService, + ExploratoryService exploratoryService, SelfServiceApplicationConfiguration configuration, + @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService) { this.projectService = projectService; this.endpointService = endpointService; this.exploratoryService = exploratoryService; 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 deb0019..3f86c29 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 @@ -28,7 +28,7 @@ import com.epam.dlab.backendapi.domain.EndpointDTO; import com.epam.dlab.backendapi.domain.ProjectEndpointDTO; import com.epam.dlab.backendapi.resources.dto.HealthStatusPageDTO; import com.epam.dlab.backendapi.resources.dto.ProjectInfrastructureInfo; -import com.epam.dlab.backendapi.service.BillingServiceNew; +import com.epam.dlab.backendapi.service.BillingService; import com.epam.dlab.backendapi.service.EndpointService; import com.epam.dlab.backendapi.service.InfrastructureInfoService; import com.epam.dlab.backendapi.service.ProjectService; @@ -64,19 +64,19 @@ public class InfrastructureInfoServiceImpl implements InfrastructureInfoService private final BillingDAO billingDAO; private final ProjectService projectService; private final EndpointService endpointService; - private final BillingServiceNew billingServiceNew; + private final BillingService billingService; @Inject public InfrastructureInfoServiceImpl(ExploratoryDAO expDAO, EnvDAO envDAO, SelfServiceApplicationConfiguration configuration, BillingDAO billingDAO, ProjectService projectService, EndpointService endpointService, - BillingServiceNew billingServiceNew) { + BillingService billingService) { this.expDAO = expDAO; this.envDAO = envDAO; this.configuration = configuration; this.billingDAO = billingDAO; this.projectService = projectService; this.endpointService = endpointService; - this.billingServiceNew = billingServiceNew; + this.billingService = billingService; } @Override @@ -102,7 +102,7 @@ public class InfrastructureInfoServiceImpl implements InfrastructureInfoService .map(exp -> { List<BillingData> exploratoryRemoteBillingData = new ArrayList<>(); try { - exploratoryRemoteBillingData = billingServiceNew.getExploratoryRemoteBillingData(user, (String) exp.get("endpoint"), + 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); diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/aws/AwsBillingServiceTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/aws/AwsBillingServiceTest.java deleted file mode 100644 index 0c9cf26..0000000 --- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/aws/AwsBillingServiceTest.java +++ /dev/null @@ -1,224 +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.backendapi.service.aws; - -import com.epam.dlab.auth.UserInfo; -import com.epam.dlab.backendapi.dao.aws.AwsBillingDAO; -import com.epam.dlab.backendapi.resources.dto.BillingFilter; -import com.epam.dlab.exceptions.DlabException; -import org.bson.Document; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import java.text.ParseException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class AwsBillingServiceTest { - - private UserInfo userInfo; - private BillingFilter billingFilter; - private Document basicDocument; - - @Mock - private AwsBillingDAO billingDAO; - - @InjectMocks - private AwsBillingService awsBillingService; - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Before - public void setUp() { - userInfo = getUserInfo(); - billingFilter = new BillingFilter(); - basicDocument = getBasicDocument(); - } - - @Test - public void getReportWithTheSameInstanceOfDocument() { - Document expectedDocument = new Document(); - when(billingDAO.getReport(any(UserInfo.class), any(BillingFilter.class))).thenReturn(expectedDocument); - - Document actualDocument = awsBillingService.getReport(userInfo, billingFilter); - assertEquals(expectedDocument, actualDocument); - - verify(billingDAO).getReport(userInfo, billingFilter); - verifyNoMoreInteractions(billingDAO); - } - - @Test - public void getReportWithAnotherInstanceOfDocument() { - Document expectedDocument = new Document().append("someField", "someValue"); - Document anotherDocument = new Document().append("someField", "anotherValue"); - when(billingDAO.getReport(any(UserInfo.class), any(BillingFilter.class))).thenReturn(anotherDocument); - - Document actualDocument = awsBillingService.getReport(userInfo, billingFilter); - assertNotEquals(expectedDocument, actualDocument); - - verify(billingDAO).getReport(userInfo, billingFilter); - verifyNoMoreInteractions(billingDAO); - } - - @Test - public void getReportWithException() { - doThrow(new RuntimeException()).when(billingDAO).getReport(any(UserInfo.class), any(BillingFilter.class)); - - try { - awsBillingService.getReport(userInfo, billingFilter); - } catch (DlabException e) { - assertEquals("Cannot load billing report: null", e.getMessage()); - } - - verify(billingDAO).getReport(userInfo, billingFilter); - verifyNoMoreInteractions(billingDAO); - } - - @Test - public void downloadReport() { - when(billingDAO.getReport(any(UserInfo.class), any(BillingFilter.class))).thenReturn(basicDocument); - - byte[] result = awsBillingService.downloadReport(userInfo, billingFilter); - assertNotNull(result); - assertTrue(result.length > 0); - - verify(billingDAO).getReport(userInfo, billingFilter); - verifyNoMoreInteractions(billingDAO); - } - - @Test - public void downloadReportWithInapproprietaryDateFormatInDocument() { - basicDocument.put("from", "someDateStart"); - when(billingDAO.getReport(any(UserInfo.class), any(BillingFilter.class))).thenReturn(basicDocument); - - try { - awsBillingService.downloadReport(userInfo, billingFilter); - } catch (DlabException e) { - assertEquals("Cannot prepare CSV file", e.getMessage()); - } - - verify(billingDAO).getReport(userInfo, billingFilter); - verifyNoMoreInteractions(billingDAO); - } - - @Test - public void downloadReportWhenDocumentHasNotAllRequiredFields() { - basicDocument.remove("lines"); - when(billingDAO.getReport(any(UserInfo.class), any(BillingFilter.class))).thenReturn(basicDocument); - - expectedException.expect(NullPointerException.class); - - awsBillingService.downloadReport(userInfo, billingFilter); - } - - @Test - public void getReportFileName() { - String result = awsBillingService.getReportFileName(userInfo, billingFilter); - assertEquals("aws-billing-report.csv", result); - } - - @Test - public void getFirstLine() throws ParseException { - String result = awsBillingService.getFirstLine(basicDocument); - assertEquals("Service base name: someSBN Resource tag ID: someTagResourceId Available reporting " + - "period from: Mar 21, 2018 to: Mar 22, 2018", result); - } - - @Test - public void getFirstLineWithException() throws ParseException { - basicDocument.put("from", "someStartDate"); - - expectedException.expect(ParseException.class); - expectedException.expectMessage("Unparseable date: \"someStartDate\""); - - awsBillingService.getFirstLine(basicDocument); - - } - - @Test - public void getHeadersList() { - List<String> expectedResult1 = - Arrays.asList("USER", "PROJECT", "ENVIRONMENT NAME", "RESOURCE TYPE", "SHAPE", "SERVICE", "SERVICE CHARGES"); - List<String> expectedResult2 = expectedResult1.subList(1, expectedResult1.size()); - - List<String> actualResult1 = awsBillingService.getHeadersList(true); - assertEquals(expectedResult1, actualResult1); - - List<String> actualResult2 = awsBillingService.getHeadersList(false); - assertEquals(expectedResult2, actualResult2); - } - - @Test - public void getLine() { - String expectedResult1 = "someUser,someProject,someId,someResType,someShape,someProduct,someCost someCode\n"; - String actualResult1 = awsBillingService.getLine(true, basicDocument); - assertEquals(expectedResult1, actualResult1); - - basicDocument.remove("user"); - String expectedResult2 = "someProject,someId,someResType,someShape,someProduct,someCost someCode\n"; - String actualResult2 = awsBillingService.getLine(false, basicDocument); - assertEquals(expectedResult2, actualResult2); - } - - @Test - public void getTotal() { - String expectedResult1 = ",,,,,,Total: someCostTotal someCode\n"; - String actualResult1 = awsBillingService.getTotal(true, basicDocument); - assertEquals(expectedResult1, actualResult1); - - String expectedResult2 = ",,,,,Total: someCostTotal someCode\n"; - String actualResult2 = awsBillingService.getTotal(false, basicDocument); - assertEquals(expectedResult2, actualResult2); - } - - private UserInfo getUserInfo() { - return new UserInfo("user", "token"); - } - - private Document getBasicDocument() { - return new Document().append("service_base_name", "someSBN").append("user", "someUser") - .append("project", "someProject").append("dlab_id", "someId") - .append("dlab_resource_type", "someResType").append("tag_resource_id", "someTagResourceId") - .append("from", "2018-03-21").append("to", "2018-03-22").append("full_report", false) - .append("shape", "someShape").append("product", "someProduct").append("cost", "someCost") - .append("cost_total", "someCostTotal").append("currency_code", "someCode") - .append("lines", Collections.singletonList(new Document())); - } - -} diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/azure/AzureBillingServiceTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/azure/AzureBillingServiceTest.java deleted file mode 100644 index ebd4b83..0000000 --- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/azure/AzureBillingServiceTest.java +++ /dev/null @@ -1,208 +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.backendapi.service.azure; - -import com.epam.dlab.auth.UserInfo; -import com.epam.dlab.backendapi.dao.BillingDAO; -import com.epam.dlab.backendapi.resources.dto.BillingFilter; -import com.epam.dlab.exceptions.DlabException; -import org.bson.Document; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import java.text.ParseException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class AzureBillingServiceTest { - - private UserInfo userInfo; - private BillingFilter billingFilter; - private Document basicDocument; - - @Mock - private BillingDAO billingDAO; - - @InjectMocks - private AzureBillingService azureBillingService; - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Before - public void setUp() { - userInfo = getUserInfo(); - billingFilter = new BillingFilter(); - basicDocument = getBasicDocument(); - } - - @Test - public void getReportWithTheSameInstanceOfDocument() { - when(billingDAO.getReport(any(UserInfo.class), any(BillingFilter.class))).thenReturn(new Document()); - - Document actualDocument = azureBillingService.getReport(userInfo, billingFilter); - assertEquals(new Document(), actualDocument); - - verify(billingDAO).getReport(userInfo, billingFilter); - verifyNoMoreInteractions(billingDAO); - } - - @Test - public void getReportWithException() { - doThrow(new RuntimeException()).when(billingDAO).getReport(any(UserInfo.class), any(BillingFilter.class)); - - try { - azureBillingService.getReport(userInfo, billingFilter); - } catch (DlabException e) { - assertEquals("Cannot load billing report: null", e.getMessage()); - } - - verify(billingDAO).getReport(userInfo, billingFilter); - verifyNoMoreInteractions(billingDAO); - } - - @Test - public void downloadReport() { - when(billingDAO.getReport(any(UserInfo.class), any(BillingFilter.class))).thenReturn(basicDocument); - - byte[] result = azureBillingService.downloadReport(userInfo, billingFilter); - assertNotNull(result); - assertTrue(result.length > 0); - - verify(billingDAO).getReport(userInfo, billingFilter); - verifyNoMoreInteractions(billingDAO); - } - - @Test - public void downloadReportWithInapproprietaryDateFormatInDocument() { - basicDocument.put("from", "someDateStart"); - when(billingDAO.getReport(any(UserInfo.class), any(BillingFilter.class))).thenReturn(basicDocument); - - try { - azureBillingService.downloadReport(userInfo, billingFilter); - } catch (DlabException e) { - assertEquals("Cannot prepare CSV file", e.getMessage()); - } - - verify(billingDAO).getReport(userInfo, billingFilter); - verifyNoMoreInteractions(billingDAO); - } - - @Test - public void downloadReportWhenDocumentHasNotAllRequiredFields() { - basicDocument.remove("lines"); - when(billingDAO.getReport(any(UserInfo.class), any(BillingFilter.class))).thenReturn(basicDocument); - - expectedException.expect(NullPointerException.class); - - azureBillingService.downloadReport(userInfo, billingFilter); - } - - @Test - public void getReportFileName() { - String result = azureBillingService.getReportFileName(userInfo, billingFilter); - assertEquals("azure-billing-report.csv", result); - } - - @Test - public void getFirstLine() throws ParseException { - String result = azureBillingService.getFirstLine(basicDocument); - assertEquals("Service base name: someSBN Available reporting period from: Mar 21, 2018 " + - "to: Mar 22, 2018", result); - } - - @Test - public void getFirstLineWithException() throws ParseException { - basicDocument.put("from", "someStartDate"); - - expectedException.expect(ParseException.class); - - expectedException.expectMessage("Unparseable date: \"someStartDate\""); - azureBillingService.getFirstLine(basicDocument); - } - - @Test - public void getHeadersList() { - List<String> expectedResult1 = - Arrays.asList("USER", "PROJECT" ,"ENVIRONMENT NAME", "RESOURCE TYPE", "INSTANCE SIZE", "CATEGORY", "SERVICE " + - "CHARGES"); - List<String> expectedResult2 = expectedResult1.subList(1, expectedResult1.size()); - - List<String> actualResult1 = azureBillingService.getHeadersList(true); - assertEquals(expectedResult1, actualResult1); - - List<String> actualResult2 = azureBillingService.getHeadersList(false); - assertEquals(expectedResult2, actualResult2); - } - - @Test - public void getLine() { - String expectedResult1 = "someUser,someProject,someId,someResType,someSize,someMeterCategory,someCost someCode\n"; - String actualResult1 = azureBillingService.getLine(true, basicDocument); - assertEquals(expectedResult1, actualResult1); - - basicDocument.remove("user"); - String expectedResult2 = "someProject,someId,someResType,someSize,someMeterCategory,someCost someCode\n"; - String actualResult2 = azureBillingService.getLine(false, basicDocument); - assertEquals(expectedResult2, actualResult2); - } - - @Test - public void getTotal() { - String expectedResult1 = ",,,,,,Total: someCost someCode\n"; - String actualResult1 = azureBillingService.getTotal(true, basicDocument); - assertEquals(expectedResult1, actualResult1); - - String expectedResult2 = ",,,,,Total: someCost someCode\n"; - String actualResult2 = azureBillingService.getTotal(false, basicDocument); - assertEquals(expectedResult2, actualResult2); - } - - private UserInfo getUserInfo() { - return new UserInfo("user", "token"); - } - - private Document getBasicDocument() { - return new Document().append("service_base_name", "someSBN").append("user", "someUser") - .append("project", "someProject").append("dlabId", "someId").append("resourceType", "someResType") - .append("from", "2018-03-21").append("size", "someSize").append("to", "2018-03-22") - .append("full_report", false).append("meterCategory", "someMeterCategory") - .append("costString", "someCost").append("currencyCode", "someCode") - .append("lines", Collections.singletonList(new Document())); - } - -} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@dlab.apache.org For additional commands, e-mail: commits-h...@dlab.apache.org