From 3eaf15998a14bd0cf6df9757e98a08d932c5583d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Jandre?= Date: Tue, 27 Dec 2022 11:27:52 -0300 Subject: [PATCH 1/4] Allow users to inform timezones on APIs that have the date parameter --- .../org/apache/cloudstack/api/BaseCmd.java | 2 +- .../command/user/job/ListAsyncJobsCmd.java | 2 +- .../api/dispatch/ParamProcessWorker.java | 20 ++++++++++++------- ui/src/components/view/StatsTab.vue | 11 ++-------- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java index c2ff5a844f12..ba4e89e438c4 100644 --- a/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java @@ -103,7 +103,7 @@ public static enum HTTPMethod { GET, POST, PUT, DELETE } public static enum CommandType { - BOOLEAN, DATE, FLOAT, DOUBLE, INTEGER, SHORT, LIST, LONG, OBJECT, MAP, STRING, TZDATE, UUID + BOOLEAN, DATE, FLOAT, DOUBLE, INTEGER, SHORT, LIST, LONG, OBJECT, MAP, STRING, UUID } private Object _responseObject; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/job/ListAsyncJobsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/job/ListAsyncJobsCmd.java index d2ffcf3cd9f5..4f8f3b46ce64 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/job/ListAsyncJobsCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/job/ListAsyncJobsCmd.java @@ -34,7 +34,7 @@ public class ListAsyncJobsCmd extends BaseListAccountResourcesCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @Parameter(name = ApiConstants.START_DATE, type = CommandType.TZDATE, description = "The start date of the async job (use format \"yyyy-MM-dd'T'HH:mm:ss'+'SSSS\")") + @Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, description = "The start date of the async job (use format \"yyyy-MM-dd'T'HH:mm:ss'+'SSSS\")") private Date startDate; ///////////////////////////////////////////////////// diff --git a/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java b/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java index c23933438b4a..7a9c808b1ec9 100644 --- a/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java +++ b/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java @@ -63,8 +63,10 @@ public class ParamProcessWorker implements DispatchWorker { private static final Logger s_logger = Logger.getLogger(ParamProcessWorker.class.getName()); - public final DateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd"); - public final DateFormat newInputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + private final String inputFormatString = "yyyy-MM-dd"; + private final String newInputFormatString = "yyyy-MM-dd HH:mm:ss"; + public final DateFormat inputFormat = new SimpleDateFormat(inputFormatString); + public final DateFormat newInputFormat = new SimpleDateFormat(newInputFormatString); @Inject protected AccountManager _accountMgr; @@ -335,13 +337,20 @@ private void setFieldValue(final Field field, final BaseCmd cmdObj, final Object case DATE: // This piece of code is for maintaining backward compatibility // and support both the date formats(Bug 9724) - final boolean isObjInNewDateFormat = isObjInNewDateFormat(paramObj.toString()); - if (isObjInNewDateFormat) { + try { + field.set(cmdObj, DateUtil.parseTZDateString(paramObj.toString())); + break; + } catch (ParseException parseException) { + s_logger.debug(String.format("Could not parse date [%s] with timezone parser, trying to parse without timezone.", paramObj)); + } + if (isObjInNewDateFormat(paramObj.toString())) { + s_logger.debug(String.format("Parsing date [%s] using the [%s] format.", paramObj, newInputFormatString)); final DateFormat newFormat = newInputFormat; synchronized (newFormat) { field.set(cmdObj, newFormat.parse(paramObj.toString())); } } else { + s_logger.debug(String.format("Parsing date [%s] using the [%s] format.", paramObj, inputFormatString)); final DateFormat format = inputFormat; synchronized (format) { Date date = format.parse(paramObj.toString()); @@ -428,9 +437,6 @@ private void setFieldValue(final Field field, final BaseCmd cmdObj, final Object } } break; - case TZDATE: - field.set(cmdObj, DateUtil.parseTZDateString(paramObj.toString())); - break; case MAP: default: field.set(cmdObj, paramObj); diff --git a/ui/src/components/view/StatsTab.vue b/ui/src/components/view/StatsTab.vue index 613868c8bed8..cacedcc7d6b5 100644 --- a/ui/src/components/view/StatsTab.vue +++ b/ui/src/components/view/StatsTab.vue @@ -375,23 +375,16 @@ export default { } return new Date(date.getTime() + date.getTimezoneOffset() * 60000) }, - convertAndFormatDateAppropriately (date) { - if (this.$store.getters.usebrowsertimezone) { - var dateInUTC = new Date(date).toISOString().split('T') - return dateInUTC[0] + ' ' + dateInUTC[1].split('-')[0].split('.')[0] - } - return moment(date).format('YYYY-MM-DD HH:mm:ss') - }, fetchData () { this.loaded = false this.showResourceInfoModal = false this.formatPeriod() var params = { id: this.resource.id } if (this.startDate) { - params.startDate = this.convertAndFormatDateAppropriately(this.startDate) + params.startDate = moment(this.startDate).format() } if (this.endDate) { - params.endDate = this.convertAndFormatDateAppropriately(this.endDate) + params.endDate = moment(this.endDate).format() } api('listVirtualMachinesUsageHistory', params).then(response => { this.handleStatsResponse(response) From 84bff2b539e7e486f15eb0edc0df767319d18193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Jandre?= <48719461+JoaoJandre@users.noreply.github.com> Date: Fri, 30 Dec 2022 09:47:17 -0300 Subject: [PATCH 2/4] Address review --- .../api/dispatch/ParamProcessWorker.java | 64 ++++++++++--------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java b/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java index 7a9c808b1ec9..d920b983be6b 100644 --- a/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java +++ b/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java @@ -63,10 +63,10 @@ public class ParamProcessWorker implements DispatchWorker { private static final Logger s_logger = Logger.getLogger(ParamProcessWorker.class.getName()); - private final String inputFormatString = "yyyy-MM-dd"; - private final String newInputFormatString = "yyyy-MM-dd HH:mm:ss"; - public final DateFormat inputFormat = new SimpleDateFormat(inputFormatString); - public final DateFormat newInputFormat = new SimpleDateFormat(newInputFormatString); + private static final String inputFormatString = "yyyy-MM-dd"; + private static final String newInputFormatString = "yyyy-MM-dd HH:mm:ss"; + public static final DateFormat inputFormat = new SimpleDateFormat(inputFormatString); + public static final DateFormat newInputFormat = new SimpleDateFormat(newInputFormatString); @Inject protected AccountManager _accountMgr; @@ -335,33 +335,7 @@ private void setFieldValue(final Field field, final BaseCmd cmdObj, final Object field.set(cmdObj, Boolean.valueOf(paramObj.toString())); break; case DATE: - // This piece of code is for maintaining backward compatibility - // and support both the date formats(Bug 9724) - try { - field.set(cmdObj, DateUtil.parseTZDateString(paramObj.toString())); - break; - } catch (ParseException parseException) { - s_logger.debug(String.format("Could not parse date [%s] with timezone parser, trying to parse without timezone.", paramObj)); - } - if (isObjInNewDateFormat(paramObj.toString())) { - s_logger.debug(String.format("Parsing date [%s] using the [%s] format.", paramObj, newInputFormatString)); - final DateFormat newFormat = newInputFormat; - synchronized (newFormat) { - field.set(cmdObj, newFormat.parse(paramObj.toString())); - } - } else { - s_logger.debug(String.format("Parsing date [%s] using the [%s] format.", paramObj, inputFormatString)); - final DateFormat format = inputFormat; - synchronized (format) { - Date date = format.parse(paramObj.toString()); - if (field.getName().equals("startDate")) { - date = messageDate(date, 0, 0, 0); - } else if (field.getName().equals("endDate")) { - date = messageDate(date, 23, 59, 59); - } - field.set(cmdObj, date); - } - } + parseAndSetDate(field, cmdObj, paramObj); break; case FLOAT: // Assuming that the parameters have been checked for required before now, @@ -448,6 +422,34 @@ private void setFieldValue(final Field field, final BaseCmd cmdObj, final Object " is not accessible]"); } } + + private void parseAndSetDate(Field field, BaseCmd cmdObj, Object paramObj) throws IllegalAccessException, ParseException { + try { + field.set(cmdObj, DateUtil.parseTZDateString(paramObj.toString())); + return; + } catch (ParseException parseException) { + s_logger.debug(String.format("Could not parse date [%s] with timezone parser, trying to parse without timezone.", paramObj)); + } + if (isObjInNewDateFormat(paramObj.toString())) { + s_logger.debug(String.format("Parsing date [%s] using the [%s] format.", paramObj, newInputFormatString)); + final DateFormat newFormat = newInputFormat; + synchronized (newFormat) { + field.set(cmdObj, newFormat.parse(paramObj.toString())); + } + } else { + s_logger.debug(String.format("Parsing date [%s] using the [%s] format.", paramObj, inputFormatString)); + final DateFormat format = inputFormat; + synchronized (format) { + Date date = format.parse(paramObj.toString()); + if (field.getName().equals("startDate")) { + date = messageDate(date, 0, 0, 0); + } else if (field.getName().equals("endDate")) { + date = messageDate(date, 23, 59, 59); + } + field.set(cmdObj, date); + } + } + } private boolean isObjInNewDateFormat(final String string) { final Matcher matcher = BaseCmd.newInputDateFormat.matcher(string); From 69bc3af13b6cc37616e9ef9e40bb5689fd1bff96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Jandre?= <48719461+JoaoJandre@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:40:13 -0300 Subject: [PATCH 3/4] Update server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java Co-authored-by: dahn --- .../src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java b/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java index d920b983be6b..9f07db4b033b 100644 --- a/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java +++ b/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java @@ -422,7 +422,6 @@ private void setFieldValue(final Field field, final BaseCmd cmdObj, final Object " is not accessible]"); } } - private void parseAndSetDate(Field field, BaseCmd cmdObj, Object paramObj) throws IllegalAccessException, ParseException { try { field.set(cmdObj, DateUtil.parseTZDateString(paramObj.toString())); From baea191e3646741a43180179182a06190ee4a4a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Jandre?= <48719461+JoaoJandre@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:41:38 -0300 Subject: [PATCH 4/4] Always consider the users timezone when opening the page --- ui/src/components/view/StatsTab.vue | 30 +---------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/ui/src/components/view/StatsTab.vue b/ui/src/components/view/StatsTab.vue index cacedcc7d6b5..45026c0ff169 100644 --- a/ui/src/components/view/StatsTab.vue +++ b/ui/src/components/view/StatsTab.vue @@ -289,26 +289,12 @@ export default { mounted () { this.fetchData() }, - computed: { - usebrowsertimezone: function () { - return this.$store.getters.usebrowsertimezone - } - }, watch: { resource: function (newItem) { if (!newItem || !newItem.id) { return } this.fetchData() - }, - usebrowsertimezone: function () { - if (this.startDate) { - this.startDate = this.onToggleUseBrowserTimezone(new Date(this.startDate)) - } - if (this.endDate) { - this.endDate = this.onToggleUseBrowserTimezone(new Date(this.endDate)) - } - this.fetchData() } }, methods: { @@ -355,25 +341,11 @@ export default { }, getStartDate () { var now = new Date() - if (!this.$store.getters.usebrowsertimezone) { - var dateInUTC = new Date(now.getTime() + now.getTimezoneOffset() * 60000) - return dateInUTC.setHours(dateInUTC.getHours() - 1) - } now.setHours(now.getHours() - 1) return now }, getEndDate () { - var now = new Date() - if (this.$store.getters.usebrowsertimezone) { - return now - } - return new Date(now.getTime() + now.getTimezoneOffset() * 60000) - }, - onToggleUseBrowserTimezone (date) { - if (this.$store.getters.usebrowsertimezone) { - return this.$toLocalDate(date) - } - return new Date(date.getTime() + date.getTimezoneOffset() * 60000) + return new Date() }, fetchData () { this.loaded = false