Repository: incubator-griffin Updated Branches: refs/heads/master d99155749 -> 05680f01a
[GRIFFIN-206] fix job timezone when creating from UI Demonstration of the problem: ``` > new Date() Wed Oct 10 2018 11:30:48 GMT-0700 (Pacific Daylight Time) > new Date().getTimezoneOffset()/60 7 ``` Author: Nikolay Sokolov <chemika...@gmail.com> Closes #435 from chemikadze/GRIFFIN-206. Project: http://git-wip-us.apache.org/repos/asf/incubator-griffin/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-griffin/commit/05680f01 Tree: http://git-wip-us.apache.org/repos/asf/incubator-griffin/tree/05680f01 Diff: http://git-wip-us.apache.org/repos/asf/incubator-griffin/diff/05680f01 Branch: refs/heads/master Commit: 05680f01a9e16d2db5fbe541757dc8ca19353fce Parents: d991557 Author: Nikolay Sokolov <chemika...@gmail.com> Authored: Mon Oct 15 11:13:38 2018 +0800 Committer: William Guo <gu...@apache.org> Committed: Mon Oct 15 11:13:38 2018 +0800 ---------------------------------------------------------------------- .../apache/griffin/core/job/JobInstance.java | 9 +-- .../org/apache/griffin/core/util/TimeUtil.java | 8 ++ .../apache/griffin/core/util/TimeUtilTest.java | 36 +++++++++ .../job/create-job/batch/batch.component.html | 9 ++- .../app/job/create-job/batch/batch.component.ts | 9 ++- .../create-job/streaming/streaming.component.ts | 5 +- .../configuration/configuration.component.html | 2 +- .../configuration/configuration.component.ts | 82 ++++++++++---------- ui/angular/src/app/shared/shared.module.ts | 30 +++++++ ui/angular/src/app/shared/time-utils.ts | 26 +++++++ ui/angular/src/styles.css | 14 ++++ 11 files changed, 171 insertions(+), 59 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/05680f01/service/src/main/java/org/apache/griffin/core/job/JobInstance.java ---------------------------------------------------------------------- diff --git a/service/src/main/java/org/apache/griffin/core/job/JobInstance.java b/service/src/main/java/org/apache/griffin/core/job/JobInstance.java index afb25d8..47b42f3 100644 --- a/service/src/main/java/org/apache/griffin/core/job/JobInstance.java +++ b/service/src/main/java/org/apache/griffin/core/job/JobInstance.java @@ -257,7 +257,7 @@ public class JobInstance implements Job { } for (Long timestamp : sampleTs) { set.add(TimeUtil.format(value, timestamp, - getTimeZone(timezone))); + TimeUtil.getTimeZone(timezone))); } conf.put(entry.getKey(), StringUtils.join(set, PATH_CONNECTOR_CHARACTER)); @@ -265,13 +265,6 @@ public class JobInstance implements Job { } } - private TimeZone getTimeZone(String timezone) { - if (StringUtils.isEmpty(timezone)) { - return TimeZone.getDefault(); - } - return TimeZone.getTimeZone(timezone); - } - @SuppressWarnings("unchecked") private void createJobInstance(Map<String, Object> confMap) throws Exception { http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/05680f01/service/src/main/java/org/apache/griffin/core/util/TimeUtil.java ---------------------------------------------------------------------- diff --git a/service/src/main/java/org/apache/griffin/core/util/TimeUtil.java b/service/src/main/java/org/apache/griffin/core/util/TimeUtil.java index b233c54..17e08d6 100644 --- a/service/src/main/java/org/apache/griffin/core/util/TimeUtil.java +++ b/service/src/main/java/org/apache/griffin/core/util/TimeUtil.java @@ -28,6 +28,7 @@ import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -148,4 +149,11 @@ public class TimeUtil { return str.replaceAll(escapeHashTagPattern, hashTag); } + public static TimeZone getTimeZone(String timezone) { + if (StringUtils.isEmpty(timezone)) { + return TimeZone.getDefault(); + } + return TimeZone.getTimeZone(timezone); + } + } http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/05680f01/service/src/test/java/org/apache/griffin/core/util/TimeUtilTest.java ---------------------------------------------------------------------- diff --git a/service/src/test/java/org/apache/griffin/core/util/TimeUtilTest.java b/service/src/test/java/org/apache/griffin/core/util/TimeUtilTest.java index aefe76d..f2e89ae 100644 --- a/service/src/test/java/org/apache/griffin/core/util/TimeUtilTest.java +++ b/service/src/test/java/org/apache/griffin/core/util/TimeUtilTest.java @@ -21,6 +21,8 @@ package org.apache.griffin.core.util; import static org.junit.Assert.assertEquals; +import java.util.HashMap; +import java.util.Map; import java.util.TimeZone; import org.junit.Test; @@ -110,4 +112,38 @@ public class TimeUtilTest { TimeUtil.format(format, time, TimeZone.getTimeZone(timeZone)); } + @Test + public void testGetTimeZone() { + Map<String, String> tests = new HashMap<>(); + tests.put("", TimeZone.getDefault().getID()); + // standard cases + tests.put("GMT", "GMT"); + tests.put("GMT+1", "GMT+01:00"); + tests.put("GMT+1:00", "GMT+01:00"); + tests.put("GMT+01:00", "GMT+01:00"); + tests.put("GMT-1", "GMT-01:00"); + tests.put("GMT-1:00", "GMT-01:00"); + tests.put("GMT-01:00", "GMT-01:00"); + // values pushed by UI for jobs + tests.put("GMT1", "GMT"); + tests.put("GMT1:00", "GMT"); + tests.put("GMT01:00", "GMT"); + // values generated by UI for datasets in a past + tests.put("UTC1", "GMT"); + tests.put("UTC1:00", "GMT"); + tests.put("UTC01:00", "GMT"); + tests.put("UTC-1", "GMT"); + tests.put("UTC-1:00", "GMT"); + tests.put("UTC-01:00", "GMT"); + // "named" time zones support + tests.put("CST", "CST"); // supported + tests.put("CDT", "GMT"); // not supported + tests.put("America/Los_Angeles", "America/Los_Angeles"); // supported + tests.forEach((input, expected) -> { + String actual = TimeUtil.getTimeZone(input).getID(); + assertEquals(String.format("For input: %s", input), expected, actual); + }); + } + + } http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/05680f01/ui/angular/src/app/job/create-job/batch/batch.component.html ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/job/create-job/batch/batch.component.html b/ui/angular/src/app/job/create-job/batch/batch.component.html index 0922eff..91026f4 100644 --- a/ui/angular/src/app/job/create-job/batch/batch.component.html +++ b/ui/angular/src/app/job/create-job/batch/batch.component.html @@ -97,10 +97,13 @@ under the License. (keydown)="blinkKeydownLabel()" style="margin-bottom: 5rem"></nouislider> </div> </div> - <div class="setcolor"> + <div class="setcolor bottom-info"> <p> - <i class="fa fa-info-circle"></i> After submitted, please go to " - <a class="bark-link" href="/jobs">Jobs</a>" to check the job status + <i class="fa fa-info-circle"></i>After submitted, please go to + "<a class="bark-link" href="/jobs">Jobs</a>" to check the job status + </p> + <p> + <i class="fa fa-info-circle"></i>Cron expression is using browser's time zone: {{timezone}} </p> </div> </fieldset> http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/05680f01/ui/angular/src/app/job/create-job/batch/batch.component.ts ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/job/create-job/batch/batch.component.ts b/ui/angular/src/app/job/create-job/batch/batch.component.ts index b8f0100..150f307 100644 --- a/ui/angular/src/app/job/create-job/batch/batch.component.ts +++ b/ui/angular/src/app/job/create-job/batch/batch.component.ts @@ -33,6 +33,8 @@ import {Router} from "@angular/router"; import {NouisliderModule} from "ng2-nouislider"; import {HttpClient} from "@angular/common/http"; +import {TimeUtils} from "../../../shared/time-utils"; + @Component({ selector: "app-batch", templateUrl: "./batch.component.html", @@ -66,6 +68,7 @@ export class BatchComponent implements OnInit, AfterViewChecked { Measures = []; measure: string; measureid: any; + timezone = TimeUtils.getBrowserTimeZone(); newJob = { "cron.expression": "", @@ -134,14 +137,12 @@ export class BatchComponent implements OnInit, AfterViewChecked { return false; } this.measureid = this.getMeasureId(); - let time = new Date().getTimezoneOffset() / 60; - let timezone = "GMT" + time + ":00"; this.newJob = { "job.name": this.jobname, "job.type": "batch", "measure.id": this.measureid, "cron.expression": this.cronExp, - "cron.time.zone": timezone, + "cron.time.zone": this.timezone, // "cron.time.zone": "GMT+8:00", // "predicate.config": { // "interval": "1m", @@ -228,7 +229,7 @@ export class BatchComponent implements OnInit, AfterViewChecked { 200 ); $(".y-scrollable").css({ - height: $("fieldset").height() + height: $("fieldset").height() - 20 }); $("#data-asset-pie").css({ height: $("#data-asset-pie") http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/05680f01/ui/angular/src/app/job/create-job/streaming/streaming.component.ts ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/job/create-job/streaming/streaming.component.ts b/ui/angular/src/app/job/create-job/streaming/streaming.component.ts index 94a400e..200d788 100644 --- a/ui/angular/src/app/job/create-job/streaming/streaming.component.ts +++ b/ui/angular/src/app/job/create-job/streaming/streaming.component.ts @@ -31,6 +31,8 @@ import {HttpParams} from "@angular/common/http"; import {Router} from "@angular/router"; import {HttpClient} from "@angular/common/http"; +import {TimeUtils} from '../../../shared/time-utils'; + @Component({ selector: 'app-streaming', templateUrl: './streaming.component.html', @@ -132,8 +134,7 @@ export class StreamingComponent implements OnInit { return false; } this.measureid = this.getMeasureId(); - let time = new Date().getTimezoneOffset() / 60; - let timezone = "GMT" + time + ":00"; + let timezone = TimeUtils.getBrowserTimeZone(); this.newJob = { "job.type": "streaming", "job.name": this.jobname, http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/05680f01/ui/angular/src/app/measure/create-measure/configuration/configuration.component.html ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/measure/create-measure/configuration/configuration.component.html b/ui/angular/src/app/measure/create-measure/configuration/configuration.component.html index 713017b..c030b5f 100644 --- a/ui/angular/src/app/measure/create-measure/configuration/configuration.component.html +++ b/ui/angular/src/app/measure/create-measure/configuration/configuration.component.html @@ -49,7 +49,7 @@ under the License. </label> <div class="col-md-10 col-lg-10 col-sm-10 scrollable"> <select id="timezone" class="form-control" name="zone" [(ngModel)]="timezone" required (change)="upward()"> - <option *ngFor="let item of timezones;let i = index" [value]="item">{{item}}</option> + <option *ngFor="let item of timezones.keys(); let i = index" [value]="timezones.get(item)">{{item}}</option> </select> </div> </div> http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/05680f01/ui/angular/src/app/measure/create-measure/configuration/configuration.component.ts ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/measure/create-measure/configuration/configuration.component.ts b/ui/angular/src/app/measure/create-measure/configuration/configuration.component.ts index ff86f99..e874dc1 100644 --- a/ui/angular/src/app/measure/create-measure/configuration/configuration.component.ts +++ b/ui/angular/src/app/measure/create-measure/configuration/configuration.component.ts @@ -56,47 +56,47 @@ export class ConfigurationComponent implements OnInit { }; timetypes = ["day", "hour", "minute"]; timetype: string; - timezones = [ - "UTC-12(IDL)", - "UTC-11(MIT)", - "UTC-10(HST)", - "UTC-9:30(MSIT)", - "UTC-9(AKST)", - "UTC-8(PST)", - "UTC-7(MST)", - "UTC-6(CST)", - "UTC-5(EST)", - "UTC-4(AST)", - "UTC-3:30(NST)", - "UTC-3(SAT)", - "UTC-2(BRT)", - "UTC-1(CVT)", - "UTC(WET,GMT)", - "UTC+1(CET)", - "UTC+2(EET)", - "UTC+3(MSK)", - "UTC+3:30(IRT)", - "UTC+4(META)", - "UTC+4:30(AFT)", - "UTC+5(METB)", - "UTC+5:30(IDT)", - "UTC+5:45(NPT)", - "UTC+6(BHT)", - "UTC+6:30(MRT)", - "UTC+7(IST)", - "UTC+8(EAT)", - "UTC+8:30(KRT)", - "UTC+9(FET)", - "UTC+9:30(ACST)", - "UTC+10(AEST)", - "UTC+10:30(FAST)", - "UTC+11(VTT)", - "UTC+11:30(NFT)", - "UTC+12(PSTB)", - "UTC+12:45(CIT)", - "UTC+13(PSTC)", - "UTC+14(PSTD)" - ]; + timezones: Map<string, string> = new Map<string, string>([ + ["UTC-12(IDL)", "GMT-12"], + ["UTC-11(MIT)", "GMT-11"], + ["UTC-10(HST)", "GMT-10"], + ["UTC-9:30(MSIT)", "GMT-9:30"], + ["UTC-9(AKST)", "GMT-9"], + ["UTC-8(PST)", "GMT-8"], + ["UTC-7(MST)", "GMT-7"], + ["UTC-6(CST)", "GMT-6"], + ["UTC-5(EST)", "GMT-5"], + ["UTC-4(AST)", "GMT-4"], + ["UTC-3:30(NST)", "GMT-3:30"], + ["UTC-3(SAT)", "GMT-3"], + ["UTC-2(BRT)", "GMT-2"], + ["UTC-1(CVT)", "GMT-1"], + ["UTC(WET,GMT)", "GMT"], + ["UTC+1(CET)", "GMT+1"], + ["UTC+2(EET)", "GMT+2"], + ["UTC+3(MSK)", "GMT+3"], + ["UTC+3:30(IRT)", "GMT+3:30"], + ["UTC+4(META)", "GMT+4"], + ["UTC+4:30(AFT)", "GMT+4:30"], + ["UTC+5(METB)", "GMT+5"], + ["UTC+5:30(IDT)", "GMT+5:30"], + ["UTC+5:45(NPT)", "GMT+5:45"], + ["UTC+6(BHT)", "GMT+6"], + ["UTC+6:30(MRT)", "GMT+6:30"], + ["UTC+7(IST)", "GMT+7"], + ["UTC+8(EAT)", "GMT+8"], + ["UTC+8:30(KRT)", "GMT+8:30"], + ["UTC+9(FET)", "GMT+9"], + ["UTC+9:30(ACST)", "GMT+9:30"], + ["UTC+10(AEST)", "GMT+10"], + ["UTC+10:30(FAST)", "GMT+10:30"], + ["UTC+11(VTT)", "GMT+11"], + ["UTC+11:30(NFT)", "GMT+11:30"], + ["UTC+12(PSTB)", "GMT+12"], + ["UTC+12:45(CIT)", "GMT+12:45"], + ["UTC+13(PSTC)", "GMT+13"], + ["UTC+14(PSTD)", "GMT+14"], + ]); timezone: string; upward() { http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/05680f01/ui/angular/src/app/shared/shared.module.ts ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/shared/shared.module.ts b/ui/angular/src/app/shared/shared.module.ts new file mode 100644 index 0000000..9ad6ec3 --- /dev/null +++ b/ui/angular/src/app/shared/shared.module.ts @@ -0,0 +1,30 @@ +/* +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. +*/ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +@NgModule({ + imports: [ + CommonModule + ], + declarations: [], + exports: [ + ] +}) +export class SharedModule { } http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/05680f01/ui/angular/src/app/shared/time-utils.ts ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/shared/time-utils.ts b/ui/angular/src/app/shared/time-utils.ts new file mode 100644 index 0000000..4aa2906 --- /dev/null +++ b/ui/angular/src/app/shared/time-utils.ts @@ -0,0 +1,26 @@ +/* +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. +*/ +export class TimeUtils { + + static getBrowserTimeZone() { + let time = -(new Date().getTimezoneOffset() / 60); + return "GMT" + (time >= 0 ? "+"+time : time) + ":00"; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/05680f01/ui/angular/src/styles.css ---------------------------------------------------------------------- diff --git a/ui/angular/src/styles.css b/ui/angular/src/styles.css index 3bbaf1b..42ba238 100644 --- a/ui/angular/src/styles.css +++ b/ui/angular/src/styles.css @@ -1239,3 +1239,17 @@ input { overflow-x: hidden; height: 100%; } + +.bottom-info { + position: absolute; + bottom: 0; + margin-bottom: 5px; +} + +.bottom-info p { + margin-bottom: 0; +} + +.bottom-info .fa { + margin-right: 3px; +}