package com.sequenceiq.cloudbreak.service.usages; import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; import java.util.Date; import java.util.List; import javax.inject.Inject; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.google.api.client.util.Lists; import com.sequenceiq.cloudbreak.api.model.UsageStatus; import com.sequenceiq.cloudbreak.domain.Blueprint; import com.sequenceiq.cloudbreak.domain.CloudbreakUsage; import com.sequenceiq.cloudbreak.domain.FlexSubscription; import com.sequenceiq.cloudbreak.domain.Stack; @Service public class UsageGeneratorService { private static final long HOURS_IN_DAY = 24L; @Inject private UsagePriceService usagePriceService; @Inject private UsageTimeService usageTimeService; @Value("${cb.instance.uuid:}") private String parentUuid; public CloudbreakUsage createFullClosed(CloudbreakUsage usage, Date day) { CloudbreakUsage newUsage = new CloudbreakUsage(); newUsage.setStackUuid(usage.getStackUuid()); newUsage.setParentUuid(parentUuid); newUsage.setOwner(usage.getOwner()); newUsage.setAccount(usage.getAccount()); newUsage.setProvider(usage.getProvider()); newUsage.setRegion(usage.getRegion()); newUsage.setAvailabilityZone(usage.getAvailabilityZone()); newUsage.setInstanceHours(HOURS_IN_DAY * usage.getInstanceNum()); newUsage.setDay(day); newUsage.setStackId(usage.getStackId()); newUsage.setStackName(usage.getStackName()); newUsage.setInstanceType(usage.getInstanceType()); newUsage.setInstanceNum(usage.getInstanceNum()); newUsage.setPeak(usage.getInstanceNum()); newUsage.setInstanceGroup(usage.getInstanceGroup()); newUsage.setBlueprintId(usage.getBlueprintId()); newUsage.setBlueprintName(usage.getBlueprintName()); newUsage.setPeriodStarted(day); newUsage.setDuration(Duration.of(HOURS_IN_DAY, ChronoUnit.HOURS).multipliedBy(usage.getInstanceNum()).toString()); newUsage.setStatus(UsageStatus.CLOSED); newUsage.setCosts(usagePriceService.calculateCostOfUsage(newUsage)); newUsage.setFlexId(usage.getFlexId()); newUsage.setSmartSenseId(usage.getSmartSenseId()); return newUsage; } public CloudbreakUsage createNewFromUsage(CloudbreakUsage usage) { CloudbreakUsage newUsage = new CloudbreakUsage(); newUsage.setStackUuid(usage.getStackUuid()); newUsage.setParentUuid(parentUuid); newUsage.setOwner(usage.getOwner()); newUsage.setAccount(usage.getAccount()); newUsage.setProvider(usage.getProvider()); newUsage.setRegion(usage.getRegion()); newUsage.setAvailabilityZone(usage.getAvailabilityZone()); newUsage.setInstanceHours(0L); newUsage.setCosts(0.0); Date day = Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant()); newUsage.setDay(day); newUsage.setStackId(usage.getStackId()); newUsage.setStackName(usage.getStackName()); newUsage.setInstanceType(usage.getInstanceType()); newUsage.setInstanceNum(usage.getInstanceNum()); newUsage.setPeak(usage.getInstanceNum()); newUsage.setInstanceGroup(usage.getInstanceGroup()); newUsage.setBlueprintId(usage.getBlueprintId()); newUsage.setBlueprintName(usage.getBlueprintName()); newUsage.setPeriodStarted(day); newUsage.setStatus(usage.getStatus()); newUsage.setFlexId(usage.getFlexId()); newUsage.setSmartSenseId(usage.getSmartSenseId()); return newUsage; } public CloudbreakUsage openNewUsage(Stack stack, String instanceType, Integer instanceNum, String groupName, Temporal started) { CloudbreakUsage usage = new CloudbreakUsage(); usage.setStackUuid(stack.getUuid()); usage.setParentUuid(parentUuid); usage.setOwner(stack.getOwner()); usage.setAccount(stack.getAccount()); usage.setProvider(stack.cloudPlatform()); usage.setRegion(stack.getRegion()); usage.setAvailabilityZone(stack.getAvailabilityZone()); usage.setInstanceHours(0L); usage.setCosts(0.0); Date day = Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant()); usage.setDay(day); usage.setStackId(stack.getId()); usage.setStackName(stack.getName()); usage.setInstanceType(instanceType); usage.setInstanceNum(instanceNum); usage.setPeak(instanceNum); usage.setInstanceGroup(groupName); if (stack.getCluster() != null && stack.getCluster().getBlueprint() != null) { Blueprint bp = stack.getCluster().getBlueprint(); usage.setBlueprintId(bp.getId()); usage.setBlueprintName(bp.getBlueprintName()); } usage.setPeriodStarted(Date.from(LocalDateTime.from(started).atZone(ZoneId.systemDefault()).toInstant())); usage.setStatus(UsageStatus.OPEN); FlexSubscription flexSubscription = stack.getFlexSubscription(); if (flexSubscription != null && flexSubscription.getSmartSenseSubscription() != null) { usage.setFlexId(flexSubscription.getSubscriptionId()); usage.setSmartSenseId(flexSubscription.getSmartSenseSubscription().getSubscriptionId()); } return usage; } public List<CloudbreakUsage> createClosedUsagesUntilNow(CloudbreakUsage usage) { List<CloudbreakUsage> result = Lists.newArrayList(); long days = usageTimeService.daysBetweenDateAndNow(usage.getDay()); ZonedDateTime zdt = usage.getDay().toInstant().atZone(ZoneId.systemDefault()); for (int i = 1; i < days; i++) { Date day = Date.from(zdt.plusDays(i).toInstant()); result.add(createFullClosed(usage, day)); } return result; } }