Normalize dates in Usage and Quota APIs (#8243)

* Normalize dates in Usage and Quota APIs

* Apply Daan's sugestions

Co-authored-by: dahn <daan.hoogland@gmail.com>

* Restore removed sinces

* Add missing space

* Change param descriptions for quotaBalance and quotaStatement

* Apply Daniel's suggestions

Co-authored-by: Daniel Augusto Veronezi Salvador <38945620+GutoVeronezi@users.noreply.github.com>

---------

Co-authored-by: dahn <daan.hoogland@gmail.com>
Co-authored-by: Daniel Augusto Veronezi Salvador <38945620+GutoVeronezi@users.noreply.github.com>
This commit is contained in:
Fabricio Duarte 2024-05-27 12:06:52 -03:00 committed by GitHub
parent acce88ff39
commit 371ce12abe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 79 additions and 187 deletions

View File

@ -1142,6 +1142,14 @@ public class ApiConstants {
} }
} }
public static final String PARAMETER_DESCRIPTION_START_DATE_POSSIBLE_FORMATS = "The recommended format is \"yyyy-MM-dd'T'HH:mm:ssZ\" (e.g.: \"2023-01-01T12:00:00+0100\"); " +
"however, the following formats are also accepted: \"yyyy-MM-dd HH:mm:ss\" (e.g.: \"2023-01-01 12:00:00\") and \"yyyy-MM-dd\" (e.g.: \"2023-01-01\" - if the time is not " +
"added, it will be interpreted as \"00:00:00\"). If the recommended format is not used, the date will be considered in the server timezone.";
public static final String PARAMETER_DESCRIPTION_END_DATE_POSSIBLE_FORMATS = "The recommended format is \"yyyy-MM-dd'T'HH:mm:ssZ\" (e.g.: \"2023-01-01T12:00:00+0100\"); " +
"however, the following formats are also accepted: \"yyyy-MM-dd HH:mm:ss\" (e.g.: \"2023-01-01 12:00:00\") and \"yyyy-MM-dd\" (e.g.: \"2023-01-01\" - if the time is not " +
"added, it will be interpreted as \"23:59:59\"). If the recommended format is not used, the date will be considered in the server timezone.";
public enum BootType { public enum BootType {
UEFI, BIOS; UEFI, BIOS;

View File

@ -53,16 +53,12 @@ public class ListUsageRecordsCmd extends BaseListCmd {
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "List usage records for the specified domain.") @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "List usage records for the specified domain.")
private Long domainId; private Long domainId;
@Parameter(name = ApiConstants.END_DATE, @Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, required = true, description = "End date range for usage record query. " +
type = CommandType.DATE, ApiConstants.PARAMETER_DESCRIPTION_END_DATE_POSSIBLE_FORMATS)
required = true,
description = "End date range for usage record query (use format \"yyyy-MM-dd\" or the new format \"yyyy-MM-dd HH:mm:ss\", e.g. startDate=2015-01-01 or startdate=2015-01-01 10:30:00).")
private Date endDate; private Date endDate;
@Parameter(name = ApiConstants.START_DATE, @Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, required = true, description = "Start date range for usage record query. " +
type = CommandType.DATE, ApiConstants.PARAMETER_DESCRIPTION_START_DATE_POSSIBLE_FORMATS)
required = true,
description = "Start date range for usage record query (use format \"yyyy-MM-dd\" or the new format \"yyyy-MM-dd HH:mm:ss\", e.g. startDate=2015-01-01 or startdate=2015-01-01 11:00:00).")
private Date startDate; private Date startDate;
@Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "List usage records for the specified account") @Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "List usage records for the specified account")
@ -137,11 +133,11 @@ public class ListUsageRecordsCmd extends BaseListCmd {
} }
public void setEndDate(Date endDate) { public void setEndDate(Date endDate) {
this.endDate = endDate == null ? null : new Date(endDate.getTime()); this.endDate = endDate;
} }
public void setStartDate(Date startDate) { public void setStartDate(Date startDate) {
this.startDate = startDate == null ? null : new Date(startDate.getTime()); this.startDate = startDate;
} }
public void setAccountId(Long accountId) { public void setAccountId(Long accountId) {
@ -167,8 +163,8 @@ public class ListUsageRecordsCmd extends BaseListCmd {
@Override @Override
public void execute() { public void execute() {
Pair<List<? extends Usage>, Integer> usageRecords = _usageService.getUsageRecords(this); Pair<List<? extends Usage>, Integer> usageRecords = _usageService.getUsageRecords(this);
ListResponse<UsageRecordResponse> response = new ListResponse<UsageRecordResponse>(); ListResponse<UsageRecordResponse> response = new ListResponse<>();
List<UsageRecordResponse> usageResponses = new ArrayList<UsageRecordResponse>(); List<UsageRecordResponse> usageResponses = new ArrayList<>();
Map<String, Set<ResourceTagResponse>> resourceTagResponseMap = null; Map<String, Set<ResourceTagResponse>> resourceTagResponseMap = null;
if (usageRecords != null) { if (usageRecords != null) {
//read the resource tags details for all the resources in usage data and store in Map //read the resource tags details for all the resources in usage data and store in Map

View File

@ -16,6 +16,7 @@
// under the License. // under the License.
package org.apache.cloudstack.api.response; package org.apache.cloudstack.api.response;
import java.util.Date;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Set; import java.util.Set;
@ -133,11 +134,11 @@ public class UsageRecordResponse extends BaseResponseWithTagInformation implemen
@SerializedName(ApiConstants.START_DATE) @SerializedName(ApiConstants.START_DATE)
@Param(description = "start date of the usage record") @Param(description = "start date of the usage record")
private String startDate; private Date startDate;
@SerializedName(ApiConstants.END_DATE) @SerializedName(ApiConstants.END_DATE)
@Param(description = "end date of the usage record") @Param(description = "end date of the usage record")
private String endDate; private Date endDate;
@SerializedName("issourcenat") @SerializedName("issourcenat")
@Param(description = "True if the IPAddress is source NAT") @Param(description = "True if the IPAddress is source NAT")
@ -160,7 +161,7 @@ public class UsageRecordResponse extends BaseResponseWithTagInformation implemen
private String vpcId; private String vpcId;
public UsageRecordResponse() { public UsageRecordResponse() {
tags = new LinkedHashSet<ResourceTagResponse>(); tags = new LinkedHashSet<>();
} }
public void setTags(Set<ResourceTagResponse> tags) { public void setTags(Set<ResourceTagResponse> tags) {
@ -245,11 +246,11 @@ public class UsageRecordResponse extends BaseResponseWithTagInformation implemen
this.size = size; this.size = size;
} }
public void setStartDate(String startDate) { public void setStartDate(Date startDate) {
this.startDate = startDate; this.startDate = startDate;
} }
public void setEndDate(String endDate) { public void setEndDate(Date endDate) {
this.endDate = endDate; this.endDate = endDate;
} }

View File

@ -43,10 +43,12 @@ public class QuotaBalanceCmd extends BaseCmd {
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = true, entityType = DomainResponse.class, description = "If domain Id is given and the caller is domain admin then the statement is generated for domain.") @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = true, entityType = DomainResponse.class, description = "If domain Id is given and the caller is domain admin then the statement is generated for domain.")
private Long domainId; private Long domainId;
@Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, description = "End date range for quota query. Use yyyy-MM-dd as the date format, e.g. startDate=2009-06-03.") @Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, description = "End of the period of the Quota balance." +
ApiConstants.PARAMETER_DESCRIPTION_END_DATE_POSSIBLE_FORMATS)
private Date endDate; private Date endDate;
@Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, description = "Start date range quota query. Use yyyy-MM-dd as the date format, e.g. startDate=2009-06-01.") @Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, description = "Start of the period of the Quota balance. " +
ApiConstants.PARAMETER_DESCRIPTION_START_DATE_POSSIBLE_FORMATS)
private Date startDate; private Date startDate;
@Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "List usage records for the specified account") @Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "List usage records for the specified account")

View File

@ -45,10 +45,12 @@ public class QuotaStatementCmd extends BaseCmd {
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = true, entityType = DomainResponse.class, description = "Optional, If domain Id is given and the caller is domain admin then the statement is generated for domain.") @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = true, entityType = DomainResponse.class, description = "Optional, If domain Id is given and the caller is domain admin then the statement is generated for domain.")
private Long domainId; private Long domainId;
@Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, required = true, description = "End date range for quota query. Use yyyy-MM-dd as the date format, e.g. startDate=2009-06-03.") @Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, required = true, description = "End of the period of the Quota statement. " +
ApiConstants.PARAMETER_DESCRIPTION_END_DATE_POSSIBLE_FORMATS)
private Date endDate; private Date endDate;
@Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, required = true, description = "Start date range quota query. Use yyyy-MM-dd as the date format, e.g. startDate=2009-06-01.") @Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, required = true, description = "Start of the period of the Quota statement. " +
ApiConstants.PARAMETER_DESCRIPTION_START_DATE_POSSIBLE_FORMATS)
private Date startDate; private Date startDate;
@Parameter(name = ApiConstants.TYPE, type = CommandType.INTEGER, description = "List quota usage records for the specified usage type") @Parameter(name = ApiConstants.TYPE, type = CommandType.INTEGER, description = "List quota usage records for the specified usage type")

View File

@ -60,12 +60,12 @@ public class QuotaTariffCreateCmd extends BaseCmd {
"value will be applied.", length = 65535) "value will be applied.", length = 65535)
private String activationRule; private String activationRule;
@Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, description = "The effective start date on/after which the quota tariff is effective. Use yyyy-MM-dd as" @Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, description = "The effective start date on/after which the quota tariff is effective. Inform null to " +
+ " the date format, e.g. startDate=2009-06-03. Inform null to use the current date.") "use the current date. " + ApiConstants.PARAMETER_DESCRIPTION_START_DATE_POSSIBLE_FORMATS)
private Date startDate; private Date startDate;
@Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, description = "The end date of the quota tariff. Use yyyy-MM-dd as the date format, e.g." @Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, description = "The end date of the quota tariff. If not informed, the tariff will be valid indefinitely. " +
+ " endDate=2009-06-03.") ApiConstants.PARAMETER_DESCRIPTION_END_DATE_POSSIBLE_FORMATS)
private Date endDate; private Date endDate;
@Override @Override

View File

@ -44,18 +44,18 @@ public class QuotaTariffListCmd extends BaseListCmd {
@Parameter(name = ApiConstants.USAGE_TYPE, type = CommandType.INTEGER, description = "Usage type of the resource") @Parameter(name = ApiConstants.USAGE_TYPE, type = CommandType.INTEGER, description = "Usage type of the resource")
private Integer usageType; private Integer usageType;
@Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, description = "The start date of the quota tariff. Use yyyy-MM-dd as the date format, " @Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, description = "The start date of the quota tariff. " +
+ "e.g. startDate=2009-06-03.") ApiConstants.PARAMETER_DESCRIPTION_START_DATE_POSSIBLE_FORMATS)
private Date effectiveDate; private Date effectiveDate;
@Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, description = "The end date of the quota tariff. Use yyyy-MM-dd as the date format, e.g. " @Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, description = "The end date of the quota tariff. " +
+ "endDate=2021-11-03.", since = "4.18.0.0") ApiConstants.PARAMETER_DESCRIPTION_END_DATE_POSSIBLE_FORMATS, since = "4.18.0.0")
private Date endDate; private Date endDate;
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "The name of the quota tariff.", since = "4.18.0.0") @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "The name of the quota tariff.", since = "4.18.0.0")
private String name; private String name;
@Parameter(name = ApiConstants.LIST_ALL, type = CommandType.BOOLEAN, description = "False will list only not removed quota tariffs. If set to True, we will " @Parameter(name = ApiConstants.LIST_ALL, type = CommandType.BOOLEAN, description = "False will list only not removed quota tariffs. If set to true, we will "
+ "list all, including the removed ones. The default is false.", since = "4.18.0.0") + "list all, including the removed ones. The default is false.", since = "4.18.0.0")
private boolean listAll = false; private boolean listAll = false;

View File

@ -52,8 +52,8 @@ public class QuotaTariffUpdateCmd extends BaseCmd {
"Use yyyy-MM-dd as the date format, e.g. startDate=2009-06-03.") "Use yyyy-MM-dd as the date format, e.g. startDate=2009-06-03.")
private Date startDate; private Date startDate;
@Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, description = "The end date of the quota tariff. Use yyyy-MM-dd as the date format, e.g." @Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, description = "The end date of the quota tariff. " +
+ " endDate=2009-06-03.", since = "4.18.0.0") ApiConstants.PARAMETER_DESCRIPTION_END_DATE_POSSIBLE_FORMATS, since = "4.18.0.0")
private Date endDate; private Date endDate;
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "Quota tariff's name", length = 65535, since = "4.18.0.0") @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "Quota tariff's name", length = 65535, since = "4.18.0.0")

View File

@ -134,7 +134,7 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
response.setName(tariff.getName()); response.setName(tariff.getName());
response.setEndDate(tariff.getEndDate()); response.setEndDate(tariff.getEndDate());
response.setDescription(tariff.getDescription()); response.setDescription(tariff.getDescription());
response.setUuid(tariff.getUuid()); response.setId(tariff.getUuid());
response.setRemoved(tariff.getRemoved()); response.setRemoved(tariff.getRemoved());
return response; return response;
} }
@ -376,8 +376,8 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
@Override @Override
public Pair<List<QuotaTariffVO>, Integer> listQuotaTariffPlans(final QuotaTariffListCmd cmd) { public Pair<List<QuotaTariffVO>, Integer> listQuotaTariffPlans(final QuotaTariffListCmd cmd) {
Date startDate = _quotaService.computeAdjustedTime(cmd.getEffectiveDate()); Date startDate = cmd.getEffectiveDate();
Date endDate = _quotaService.computeAdjustedTime(cmd.getEndDate()); Date endDate = cmd.getEndDate();
Integer usageType = cmd.getUsageType(); Integer usageType = cmd.getUsageType();
String name = cmd.getName(); String name = cmd.getName();
boolean listAll = cmd.isListAll(); boolean listAll = cmd.isListAll();
@ -395,10 +395,10 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
public QuotaTariffVO updateQuotaTariffPlan(QuotaTariffUpdateCmd cmd) { public QuotaTariffVO updateQuotaTariffPlan(QuotaTariffUpdateCmd cmd) {
String name = cmd.getName(); String name = cmd.getName();
Double value = cmd.getValue(); Double value = cmd.getValue();
Date endDate = _quotaService.computeAdjustedTime(cmd.getEndDate()); Date endDate = cmd.getEndDate();
String description = cmd.getDescription(); String description = cmd.getDescription();
String activationRule = cmd.getActivationRule(); String activationRule = cmd.getActivationRule();
Date now = _quotaService.computeAdjustedTime(new Date()); Date now = new Date();
warnQuotaTariffUpdateDeprecatedFields(cmd); warnQuotaTariffUpdateDeprecatedFields(cmd);
@ -488,7 +488,7 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
endDate, startDate)); endDate, startDate));
} }
Date now = _quotaService.computeAdjustedTime(new Date()); Date now = new Date();
if (endDate.compareTo(now) < 0) { if (endDate.compareTo(now) < 0) {
throw new InvalidParameterValueException(String.format("The quota tariff's end date [%s] cannot be less than now [%s].", throw new InvalidParameterValueException(String.format("The quota tariff's end date [%s] cannot be less than now [%s].",
endDate, now)); endDate, now));
@ -499,7 +499,7 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
@Override @Override
public QuotaCreditsResponse addQuotaCredits(Long accountId, Long domainId, Double amount, Long updatedBy, Boolean enforce) { public QuotaCreditsResponse addQuotaCredits(Long accountId, Long domainId, Double amount, Long updatedBy, Boolean enforce) {
Date despositedOn = _quotaService.computeAdjustedTime(new Date()); Date despositedOn = new Date();
QuotaBalanceVO qb = _quotaBalanceDao.findLaterBalanceEntry(accountId, domainId, despositedOn); QuotaBalanceVO qb = _quotaBalanceDao.findLaterBalanceEntry(accountId, domainId, despositedOn);
if (qb != null) { if (qb != null) {
@ -643,8 +643,8 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
int usageType = cmd.getUsageType(); int usageType = cmd.getUsageType();
Date startDate = cmd.getStartDate(); Date startDate = cmd.getStartDate();
Date now = new Date(); Date now = new Date();
startDate = _quotaService.computeAdjustedTime(startDate == null ? now : startDate); startDate = startDate == null ? now : startDate;
Date endDate = _quotaService.computeAdjustedTime(cmd.getEndDate()); Date endDate = cmd.getEndDate();
Double value = cmd.getValue(); Double value = cmd.getValue();
String description = cmd.getDescription(); String description = cmd.getDescription();
String activationRule = cmd.getActivationRule(); String activationRule = cmd.getActivationRule();
@ -675,10 +675,8 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Quota tariff with the provided UUID does not exist."); throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Quota tariff with the provided UUID does not exist.");
} }
quotaTariff.setRemoved(_quotaService.computeAdjustedTime(new Date())); quotaTariff.setRemoved(new Date());
CallContext.current().setEventResourceId(quotaTariff.getId()); CallContext.current().setEventResourceId(quotaTariff.getId());
return _quotaTariffDao.updateQuotaTariff(quotaTariff); return _quotaTariffDao.updateQuotaTariff(quotaTariff);
} }

View File

@ -19,6 +19,7 @@ package org.apache.cloudstack.api.response;
import com.cloud.serializer.Param; import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse; import org.apache.cloudstack.api.BaseResponse;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -74,9 +75,9 @@ public class QuotaTariffResponse extends BaseResponse {
@Param(description = "description") @Param(description = "description")
private String description; private String description;
@SerializedName("uuid") @SerializedName(ApiConstants.ID)
@Param(description = "uuid") @Param(description = "the ID of the tariff")
private String uuid; private String id;
@SerializedName("removed") @SerializedName("removed")
@Param(description = "when the quota tariff was removed") @Param(description = "when the quota tariff was removed")
@ -87,15 +88,6 @@ public class QuotaTariffResponse extends BaseResponse {
this.setObjectName("quotatariff"); this.setObjectName("quotatariff");
} }
public QuotaTariffResponse(final int usageType) {
super();
this.usageType = usageType;
}
public String getUsageName() {
return usageName;
}
public void setUsageName(String usageName) { public void setUsageName(String usageName) {
this.usageName = usageName; this.usageName = usageName;
} }
@ -108,18 +100,10 @@ public class QuotaTariffResponse extends BaseResponse {
this.usageType = usageType; this.usageType = usageType;
} }
public String getUsageUnit() {
return usageUnit;
}
public void setUsageUnit(String usageUnit) { public void setUsageUnit(String usageUnit) {
this.usageUnit = usageUnit; this.usageUnit = usageUnit;
} }
public String getUsageDiscriminator() {
return usageDiscriminator;
}
public void setUsageDiscriminator(String usageDiscriminator) { public void setUsageDiscriminator(String usageDiscriminator) {
this.usageDiscriminator = usageDiscriminator; this.usageDiscriminator = usageDiscriminator;
} }
@ -132,26 +116,14 @@ public class QuotaTariffResponse extends BaseResponse {
this.tariffValue = tariffValue; this.tariffValue = tariffValue;
} }
public String getUsageTypeDescription() {
return usageTypeDescription;
}
public void setUsageTypeDescription(String usageTypeDescription) { public void setUsageTypeDescription(String usageTypeDescription) {
this.usageTypeDescription = usageTypeDescription; this.usageTypeDescription = usageTypeDescription;
} }
public Date getEffectiveOn() {
return effectiveOn;
}
public void setEffectiveOn(Date effectiveOn) { public void setEffectiveOn(Date effectiveOn) {
this.effectiveOn = effectiveOn; this.effectiveOn = effectiveOn;
} }
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) { public void setCurrency(String currency) {
this.currency = currency; this.currency = currency;
} }
@ -188,16 +160,12 @@ public class QuotaTariffResponse extends BaseResponse {
this.description = description; this.description = description;
} }
public String getUuid() { public String getId() {
return uuid; return id;
} }
public void setUuid(String uuid) { public void setId(String id) {
this.uuid = uuid; this.id = id;
}
public Date getRemoved() {
return removed;
} }
public void setRemoved(Date removed) { public void setRemoved(Date removed) {

View File

@ -32,8 +32,6 @@ public interface QuotaService extends PluggableService {
List<QuotaBalanceVO> findQuotaBalanceVO(Long accountId, String accountName, Long domainId, Date startDate, Date endDate); List<QuotaBalanceVO> findQuotaBalanceVO(Long accountId, String accountName, Long domainId, Date startDate, Date endDate);
Date computeAdjustedTime(Date date);
void setLockAccount(Long accountId, Boolean state); void setLockAccount(Long accountId, Boolean state);
void setMinBalance(Long accountId, Double balance); void setMinBalance(Long accountId, Double balance);

View File

@ -18,7 +18,6 @@ package org.apache.cloudstack.quota;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -165,36 +164,32 @@ public class QuotaServiceImpl extends ManagerBase implements QuotaService, Confi
if (endDate == null) { if (endDate == null) {
// adjust start date to end of day as there is no end date // adjust start date to end of day as there is no end date
Date adjustedStartDate = computeAdjustedTime(_respBldr.startOfNextDay(startDate)); startDate = _respBldr.startOfNextDay(startDate);
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("getQuotaBalance1: Getting quota balance records for account: " + accountId + ", domainId: " + domainId + ", on or before " + adjustedStartDate); logger.debug("getQuotaBalance1: Getting quota balance records for account: " + accountId + ", domainId: " + domainId + ", on or before " + startDate);
} }
List<QuotaBalanceVO> qbrecords = _quotaBalanceDao.lastQuotaBalanceVO(accountId, domainId, adjustedStartDate); List<QuotaBalanceVO> qbrecords = _quotaBalanceDao.lastQuotaBalanceVO(accountId, domainId, startDate);
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Found records size=" + qbrecords.size()); logger.debug("Found records size=" + qbrecords.size());
} }
if (qbrecords.isEmpty()) { if (qbrecords.isEmpty()) {
logger.info("Incorrect Date there are no quota records before this date " + adjustedStartDate); logger.info("Incorrect Date there are no quota records before this date " + startDate);
return qbrecords; return qbrecords;
} else { } else {
return qbrecords; return qbrecords;
} }
} else { } else {
Date adjustedStartDate = computeAdjustedTime(startDate); if (startDate.before(endDate)) {
if (endDate.after(_respBldr.startOfNextDay())) {
throw new InvalidParameterValueException("Incorrect Date Range. End date:" + endDate + " should not be in future. ");
} else if (startDate.before(endDate)) {
Date adjustedEndDate = computeAdjustedTime(endDate);
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("getQuotaBalance2: Getting quota balance records for account: " + accountId + ", domainId: " + domainId + ", between " + adjustedStartDate logger.debug("getQuotaBalance2: Getting quota balance records for account: " + accountId + ", domainId: " + domainId + ", between " + startDate
+ " and " + adjustedEndDate); + " and " + endDate);
} }
List<QuotaBalanceVO> qbrecords = _quotaBalanceDao.findQuotaBalance(accountId, domainId, adjustedStartDate, adjustedEndDate); List<QuotaBalanceVO> qbrecords = _quotaBalanceDao.findQuotaBalance(accountId, domainId, startDate, endDate);
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("getQuotaBalance3: Found records size=" + qbrecords.size()); logger.debug("getQuotaBalance3: Found records size=" + qbrecords.size());
} }
if (qbrecords.isEmpty()) { if (qbrecords.isEmpty()) {
logger.info("There are no quota records between these dates start date " + adjustedStartDate + " and end date:" + endDate); logger.info("There are no quota records between these dates start date " + startDate + " and end date:" + endDate);
return qbrecords; return qbrecords;
} else { } else {
return qbrecords; return qbrecords;
@ -230,44 +225,11 @@ public class QuotaServiceImpl extends ManagerBase implements QuotaService, Confi
if (startDate.after(endDate)) { if (startDate.after(endDate)) {
throw new InvalidParameterValueException("Incorrect Date Range. Start date: " + startDate + " is after end date:" + endDate); throw new InvalidParameterValueException("Incorrect Date Range. Start date: " + startDate + " is after end date:" + endDate);
} }
if (endDate.after(_respBldr.startOfNextDay())) {
throw new InvalidParameterValueException("Incorrect Date Range. End date:" + endDate + " should not be in future. ");
}
Date adjustedEndDate = computeAdjustedTime(endDate);
Date adjustedStartDate = computeAdjustedTime(startDate);
if (logger.isDebugEnabled()) {
logger.debug("Getting quota records for account: " + accountId + ", domainId: " + domainId + ", between " + adjustedStartDate + " and " + adjustedEndDate);
}
return _quotaUsageDao.findQuotaUsage(accountId, domainId, usageType, adjustedStartDate, adjustedEndDate);
}
@Override logger.debug("Getting quota records of type [{}] for account [{}] in domain [{}], between [{}] and [{}].",
public Date computeAdjustedTime(final Date date) { usageType, accountId, domainId, startDate, endDate);
if (date == null) {
return null;
}
Calendar cal = Calendar.getInstance(); return _quotaUsageDao.findQuotaUsage(accountId, domainId, usageType, startDate, endDate);
cal.setTime(date);
TimeZone localTZ = cal.getTimeZone();
int timezoneOffset = cal.get(Calendar.ZONE_OFFSET);
if (localTZ.inDaylightTime(date)) {
timezoneOffset += (60 * 60 * 1000);
}
cal.add(Calendar.MILLISECOND, timezoneOffset);
Date newTime = cal.getTime();
Calendar calTS = Calendar.getInstance(_usageTimezone);
calTS.setTime(newTime);
timezoneOffset = calTS.get(Calendar.ZONE_OFFSET);
if (_usageTimezone.inDaylightTime(date)) {
timezoneOffset += (60 * 60 * 1000);
}
calTS.add(Calendar.MILLISECOND, -1 * timezoneOffset);
return calTS.getTime();
} }
@Override @Override

View File

@ -177,7 +177,6 @@ public class QuotaResponseBuilderImplTest extends TestCase {
Mockito.when(quotaCreditsDaoMock.saveCredits(Mockito.any(QuotaCreditsVO.class))).thenReturn(credit); Mockito.when(quotaCreditsDaoMock.saveCredits(Mockito.any(QuotaCreditsVO.class))).thenReturn(credit);
Mockito.when(quotaBalanceDaoMock.lastQuotaBalance(Mockito.anyLong(), Mockito.anyLong(), Mockito.any(Date.class))).thenReturn(new BigDecimal(111)); Mockito.when(quotaBalanceDaoMock.lastQuotaBalance(Mockito.anyLong(), Mockito.anyLong(), Mockito.any(Date.class))).thenReturn(new BigDecimal(111));
Mockito.when(quotaServiceMock.computeAdjustedTime(Mockito.any(Date.class))).thenReturn(new Date());
AccountVO account = new AccountVO(); AccountVO account = new AccountVO();
account.setState(Account.State.LOCKED); account.setState(Account.State.LOCKED);
@ -245,7 +244,6 @@ public class QuotaResponseBuilderImplTest extends TestCase {
entry.setCreditBalance(new BigDecimal(100)); entry.setCreditBalance(new BigDecimal(100));
quotaBalance.add(entry); quotaBalance.add(entry);
quotaBalance.add(entry); quotaBalance.add(entry);
Mockito.lenient().when(quotaServiceMock.computeAdjustedTime(Mockito.any(Date.class))).thenReturn(new Date());
QuotaBalanceResponse resp = quotaResponseBuilderSpy.createQuotaLastBalanceResponse(quotaBalance, null); QuotaBalanceResponse resp = quotaResponseBuilderSpy.createQuotaLastBalanceResponse(quotaBalance, null);
assertTrue(resp.getStartQuota().compareTo(new BigDecimal(200)) == 0); assertTrue(resp.getStartQuota().compareTo(new BigDecimal(200)) == 0);
} }
@ -326,16 +324,14 @@ public class QuotaResponseBuilderImplTest extends TestCase {
Date startDate = DateUtils.addDays(date, -100); Date startDate = DateUtils.addDays(date, -100);
Date endDate = DateUtils.addDays(new Date(), -1); Date endDate = DateUtils.addDays(new Date(), -1);
Mockito.doReturn(date).when(quotaServiceMock).computeAdjustedTime(Mockito.any(Date.class));
quotaResponseBuilderSpy.validateEndDateOnCreatingNewQuotaTariff(quotaTariffVoMock, startDate, endDate); quotaResponseBuilderSpy.validateEndDateOnCreatingNewQuotaTariff(quotaTariffVoMock, startDate, endDate);
} }
@Test @Test
public void validateEndDateOnCreatingNewQuotaTariffTestSetValidEndDate() { public void validateEndDateOnCreatingNewQuotaTariffTestSetValidEndDate() {
Date startDate = DateUtils.addDays(date, -100); Date startDate = DateUtils.addDays(date, -100);
Date endDate = date; Date endDate = DateUtils.addMilliseconds(new Date(), 1);
Mockito.doReturn(DateUtils.addDays(date, -10)).when(quotaServiceMock).computeAdjustedTime(Mockito.any(Date.class));
quotaResponseBuilderSpy.validateEndDateOnCreatingNewQuotaTariff(quotaTariffVoMock, startDate, endDate); quotaResponseBuilderSpy.validateEndDateOnCreatingNewQuotaTariff(quotaTariffVoMock, startDate, endDate);
Mockito.verify(quotaTariffVoMock).setEndDate(Mockito.any(Date.class)); Mockito.verify(quotaTariffVoMock).setEndDate(Mockito.any(Date.class));
} }
@ -387,7 +383,6 @@ public class QuotaResponseBuilderImplTest extends TestCase {
public void deleteQuotaTariffTestUpdateRemoved() { public void deleteQuotaTariffTestUpdateRemoved() {
Mockito.doReturn(quotaTariffVoMock).when(quotaTariffDaoMock).findByUuid(Mockito.anyString()); Mockito.doReturn(quotaTariffVoMock).when(quotaTariffDaoMock).findByUuid(Mockito.anyString());
Mockito.doReturn(true).when(quotaTariffDaoMock).updateQuotaTariff(Mockito.any(QuotaTariffVO.class)); Mockito.doReturn(true).when(quotaTariffDaoMock).updateQuotaTariff(Mockito.any(QuotaTariffVO.class));
Mockito.doReturn(new Date()).when(quotaServiceMock).computeAdjustedTime(Mockito.any(Date.class));
Assert.assertTrue(quotaResponseBuilderSpy.deleteQuotaTariff("")); Assert.assertTrue(quotaResponseBuilderSpy.deleteQuotaTariff(""));

View File

@ -30,7 +30,6 @@ import org.apache.cloudstack.quota.dao.QuotaUsageDao;
import org.apache.cloudstack.quota.vo.QuotaAccountVO; import org.apache.cloudstack.quota.vo.QuotaAccountVO;
import org.apache.cloudstack.quota.vo.QuotaBalanceVO; import org.apache.cloudstack.quota.vo.QuotaBalanceVO;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -102,13 +101,6 @@ public class QuotaServiceImplTest extends TestCase {
quotaService.configure("randomName", null); quotaService.configure("randomName", null);
} }
@Test
public void testComputeAdjustedTime() {
DateTime now = new DateTime(DateTimeZone.UTC);
DateTime result = new DateTime(quotaService.computeAdjustedTime(now.toDate()));
// FIXME: fix this test
}
@Test @Test
public void testFindQuotaBalanceVO() { public void testFindQuotaBalanceVO() {
final long accountId = 2L; final long accountId = 2L;
@ -123,7 +115,6 @@ public class QuotaServiceImplTest extends TestCase {
qb.setAccountId(accountId); qb.setAccountId(accountId);
records.add(qb); records.add(qb);
Mockito.when(respBldr.startOfNextDay()).thenReturn(endDate);
Mockito.when(respBldr.startOfNextDay(Mockito.any(Date.class))).thenReturn(startDate); Mockito.when(respBldr.startOfNextDay(Mockito.any(Date.class))).thenReturn(startDate);
Mockito.when(quotaBalanceDao.findQuotaBalance(Mockito.eq(accountId), Mockito.eq(domainId), Mockito.any(Date.class), Mockito.any(Date.class))).thenReturn(records); Mockito.when(quotaBalanceDao.findQuotaBalance(Mockito.eq(accountId), Mockito.eq(domainId), Mockito.any(Date.class), Mockito.any(Date.class))).thenReturn(records);
Mockito.when(quotaBalanceDao.lastQuotaBalanceVO(Mockito.eq(accountId), Mockito.eq(domainId), Mockito.any(Date.class))).thenReturn(records); Mockito.when(quotaBalanceDao.lastQuotaBalanceVO(Mockito.eq(accountId), Mockito.eq(domainId), Mockito.any(Date.class))).thenReturn(records);
@ -142,7 +133,6 @@ public class QuotaServiceImplTest extends TestCase {
final Date startDate = new DateTime().minusDays(2).toDate(); final Date startDate = new DateTime().minusDays(2).toDate();
final Date endDate = new Date(); final Date endDate = new Date();
Mockito.when(respBldr.startOfNextDay()).thenReturn(endDate);
quotaService.getQuotaUsage(accountId, accountName, domainId, QuotaTypes.IP_ADDRESS, startDate, endDate); quotaService.getQuotaUsage(accountId, accountName, domainId, QuotaTypes.IP_ADDRESS, startDate, endDate);
Mockito.verify(quotaUsageDao, Mockito.times(1)).findQuotaUsage(Mockito.eq(accountId), Mockito.eq(domainId), Mockito.eq(QuotaTypes.IP_ADDRESS), Mockito.any(Date.class), Mockito.any(Date.class)); Mockito.verify(quotaUsageDao, Mockito.times(1)).findQuotaUsage(Mockito.eq(accountId), Mockito.eq(domainId), Mockito.eq(QuotaTypes.IP_ADDRESS), Mockito.any(Date.class), Mockito.any(Date.class));
} }

View File

@ -4374,10 +4374,10 @@ public class ApiResponseHelper implements ResponseGenerator {
} }
if (usageRecord.getStartDate() != null) { if (usageRecord.getStartDate() != null) {
usageRecResponse.setStartDate(getDateStringInternal(usageRecord.getStartDate())); usageRecResponse.setStartDate(usageRecord.getStartDate());
} }
if (usageRecord.getEndDate() != null) { if (usageRecord.getEndDate() != null) {
usageRecResponse.setEndDate(getDateStringInternal(usageRecord.getEndDate())); usageRecResponse.setEndDate(usageRecord.getEndDate());
} }
return usageRecResponse; return usageRecResponse;

View File

@ -206,14 +206,10 @@ public class UsageServiceImpl extends ManagerBase implements UsageService, Manag
if (startDate.after(endDate)) { if (startDate.after(endDate)) {
throw new InvalidParameterValueException("Incorrect Date Range. Start date: " + startDate + " is after end date:" + endDate); throw new InvalidParameterValueException("Incorrect Date Range. Start date: " + startDate + " is after end date:" + endDate);
} }
TimeZone usageTZ = getUsageTimezone();
Date adjustedStartDate = computeAdjustedTime(startDate, usageTZ);
Date adjustedEndDate = computeAdjustedTime(endDate, usageTZ);
logger.debug("Getting usage records for account ID [{}], domain ID [{}] between [{}] and [{}] using page size [{}] and start index [{}].", logger.debug("Getting usage records for account ID [{}], domain ID [{}] between [{}] and [{}] using page size [{}] and start index [{}].",
accountId, domainId, DateUtil.displayDateInTimezone(_usageTimezone, adjustedStartDate), accountId, domainId, DateUtil.displayDateInTimezone(_usageTimezone, startDate), DateUtil.displayDateInTimezone(_usageTimezone, endDate),
DateUtil.displayDateInTimezone(_usageTimezone, adjustedEndDate), cmd.getPageSizeVal(), cmd.getPageSizeVal(), cmd.getStartIndex());
cmd.getStartIndex());
Filter usageFilter = new Filter(UsageVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); Filter usageFilter = new Filter(UsageVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
@ -338,9 +334,9 @@ public class UsageServiceImpl extends ManagerBase implements UsageService, Manag
// Filter out hidden usages // Filter out hidden usages
sc.addAnd("isHidden", SearchCriteria.Op.EQ, false); sc.addAnd("isHidden", SearchCriteria.Op.EQ, false);
if ((adjustedStartDate != null) && (adjustedEndDate != null) && adjustedStartDate.before(adjustedEndDate)) { if ((startDate != null) && (endDate != null) && startDate.before(endDate)) {
sc.addAnd("startDate", SearchCriteria.Op.BETWEEN, adjustedStartDate, adjustedEndDate); sc.addAnd("startDate", SearchCriteria.Op.BETWEEN, startDate, endDate);
sc.addAnd("endDate", SearchCriteria.Op.BETWEEN, adjustedStartDate, adjustedEndDate); sc.addAnd("endDate", SearchCriteria.Op.BETWEEN, startDate, endDate);
} else { } else {
return new Pair<List<? extends Usage>, Integer>(new ArrayList<Usage>(), new Integer(0)); // return an empty list if we fail to validate the dates return new Pair<List<? extends Usage>, Integer>(new ArrayList<Usage>(), new Integer(0)); // return an empty list if we fail to validate the dates
} }
@ -490,30 +486,6 @@ public class UsageServiceImpl extends ManagerBase implements UsageService, Manag
return true; return true;
} }
private Date computeAdjustedTime(Date initialDate, TimeZone targetTZ) {
Calendar cal = Calendar.getInstance();
cal.setTime(initialDate);
TimeZone localTZ = cal.getTimeZone();
int timezoneOffset = cal.get(Calendar.ZONE_OFFSET);
if (localTZ.inDaylightTime(initialDate)) {
timezoneOffset += (60 * 60 * 1000);
}
cal.add(Calendar.MILLISECOND, timezoneOffset);
Date newTime = cal.getTime();
Calendar calTS = Calendar.getInstance(targetTZ);
calTS.setTime(newTime);
timezoneOffset = calTS.get(Calendar.ZONE_OFFSET);
if (targetTZ.inDaylightTime(initialDate)) {
timezoneOffset += (60 * 60 * 1000);
}
calTS.add(Calendar.MILLISECOND, -1 * timezoneOffset);
return calTS.getTime();
}
@Override @Override
public List<UsageTypeResponse> listUsageTypes() { public List<UsageTypeResponse> listUsageTypes() {
return UsageTypes.listUsageTypes(); return UsageTypes.listUsageTypes();