Skip to content

Commit 47ee34d

Browse files
author
gdgate
authored
Merge pull request #1050 from gooddata/tz
Add workspace timezone setting Reviewed-by: Peter Plocháň https://github.com/peter-plochan
2 parents 45267f4 + d603ca5 commit 47ee34d

File tree

8 files changed

+303
-47
lines changed

8 files changed

+303
-47
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright (C) 2004-2021, GoodData(R) Corporation. All rights reserved.
3+
* This source code is licensed under the BSD-style license found in the
4+
* LICENSE.txt file in the root directory of this source tree.
5+
*/
6+
package com.gooddata.sdk.model.md;
7+
8+
import com.fasterxml.jackson.annotation.*;
9+
import com.gooddata.sdk.common.util.GoodDataToStringBuilder;
10+
11+
import java.io.Serializable;
12+
13+
/**
14+
* Represents project/workspace metadata configuration.
15+
*/
16+
@JsonTypeName("service")
17+
@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME)
18+
@JsonIgnoreProperties(ignoreUnknown = true)
19+
@JsonInclude(JsonInclude.Include.NON_NULL)
20+
public class Service implements Serializable {
21+
22+
public static final String TIMEZONE_URI = "/gdc/md/{projectId}/service/timezone";
23+
24+
private static final long serialVersionUID = -3382672258337809805L;
25+
26+
private final String timezone;
27+
28+
@JsonCreator
29+
public Service(@JsonProperty("timezone") String timezone) {
30+
this.timezone = timezone;
31+
}
32+
33+
/**
34+
* @return string identifier of the timezone (see IANA/Olson tz database for possible values)
35+
*/
36+
public String getTimezone() {
37+
return timezone;
38+
}
39+
40+
@Override
41+
public String toString() {
42+
return GoodDataToStringBuilder.defaultToString(this);
43+
}
44+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (C) 2004-2021, GoodData(R) Corporation. All rights reserved.
3+
* This source code is licensed under the BSD-style license found in the
4+
* LICENSE.txt file in the root directory of this source tree.
5+
*/
6+
package com.gooddata.sdk.model.md;
7+
8+
import org.testng.annotations.Test;
9+
10+
import static com.gooddata.sdk.common.util.ResourceUtils.readObjectFromResource;
11+
import static org.hamcrest.CoreMatchers.is;
12+
import static org.hamcrest.CoreMatchers.notNullValue;
13+
import static org.hamcrest.MatcherAssert.assertThat;
14+
15+
public class ServiceTest {
16+
17+
@Test
18+
public void shouldDeserialize() throws Exception {
19+
final Service service = readObjectFromResource("/md/service-timezone.json", Service.class);
20+
21+
assertThat(service, is(notNullValue()));
22+
assertThat(service.getTimezone(), is("UTC"));
23+
}
24+
25+
@Test
26+
public void testToStringFormat() throws Exception {
27+
final Service service = readObjectFromResource("/md/service-timezone.json", Service.class);
28+
29+
assertThat(service.toString(), is("Service[timezone=UTC]"));
30+
}
31+
32+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"service": {
3+
"timezone": "UTC"
4+
}
5+
}

gooddata-java/src/main/java/com/gooddata/sdk/service/md/MetadataService.java

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2004-2019, GoodData(R) Corporation. All rights reserved.
2+
* Copyright (C) 2004-2021, GoodData(R) Corporation. All rights reserved.
33
* This source code is licensed under the BSD-style license found in the
44
* LICENSE.txt file in the root directory of this source tree.
55
*/
@@ -21,9 +21,8 @@
2121
import java.util.*;
2222
import java.util.stream.Collectors;
2323

24-
import static com.gooddata.sdk.common.util.Validate.noNullElements;
25-
import static com.gooddata.sdk.common.util.Validate.notNull;
26-
import static com.gooddata.sdk.common.util.Validate.notNullState;
24+
import static com.gooddata.sdk.common.util.Validate.*;
25+
import static com.gooddata.sdk.model.md.Service.TIMEZONE_URI;
2726
import static java.util.Arrays.asList;
2827

2928
/**
@@ -440,6 +439,56 @@ public List<AttributeElement> getAttributeElements(DisplayForm displayForm) {
440439
}
441440
}
442441

442+
/**
443+
* Get project/workspace timezone.
444+
*
445+
* @param project project from what to return the timezone
446+
* @return string identifier of the timezone (see IANA/Olson tz database for possible values)
447+
* @throws com.gooddata.sdk.common.GoodDataRestException if GoodData REST API returns unexpected status code
448+
* @throws com.gooddata.sdk.common.GoodDataException if no response from API or client-side HTTP error
449+
*/
450+
public String getTimezone(final Project project) {
451+
notNull(project, "project");
452+
notNull(project.getId(), "project.id");
453+
454+
try {
455+
final Service result = restTemplate.getForObject(TIMEZONE_URI, Service.class, project.getId());
456+
457+
if (result != null) {
458+
return result.getTimezone();
459+
} else {
460+
throw new GoodDataException("Received empty response from API call.");
461+
}
462+
} catch (RestClientException e) {
463+
throw new GoodDataException("Unable to get timezone of project/workspace " + project.getId(), e);
464+
}
465+
}
466+
467+
/**
468+
* Set project/workspace timezone.
469+
*
470+
* @param project the project/workspace where to set the timezone
471+
* @param timezone the timezone to be set (see IANA/Olson tz database for possible values)
472+
*/
473+
public void setTimezone(final Project project, final String timezone) {
474+
notNull(project, "project");
475+
notNull(project.getId(), "project.id");
476+
notNull(timezone, "timezone");
477+
notEmpty(timezone, "timezone");
478+
479+
try {
480+
final Service result = restTemplate.postForObject(TIMEZONE_URI, new Service(timezone), Service.class,
481+
project.getId());
482+
483+
if (result == null) {
484+
throw new GoodDataException("Unexpected empty result from API call.");
485+
}
486+
} catch (RestClientException e) {
487+
throw new GoodDataException("Unable to set timezone of project/workspace " + project.getId(), e);
488+
}
489+
}
490+
491+
443492
private Collection<Entry> filterEntries(Collection<Entry> entries, Restriction... restrictions) {
444493
if (restrictions == null || restrictions.length == 0) {
445494
return entries;

gooddata-java/src/test/java/com/gooddata/sdk/service/md/MetadataServiceAT.java

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2004-2019, GoodData(R) Corporation. All rights reserved.
2+
* Copyright (C) 2004-2021, GoodData(R) Corporation. All rights reserved.
33
* This source code is licensed under the BSD-style license found in the
44
* LICENSE.txt file in the root directory of this source tree.
55
*/
@@ -38,6 +38,7 @@
3838
import static com.gooddata.sdk.model.md.Restriction.identifier;
3939
import static com.gooddata.sdk.model.md.report.MetricGroup.METRIC_GROUP;
4040
import static java.util.Arrays.asList;
41+
import static java.util.Collections.singletonList;
4142
import static org.hamcrest.MatcherAssert.assertThat;
4243
import static org.hamcrest.Matchers.empty;
4344
import static org.hamcrest.Matchers.hasItems;
@@ -52,15 +53,15 @@
5253
public class MetadataServiceAT extends AbstractGoodDataAT {
5354

5455
@Test(groups = "md", dependsOnGroups = "model")
55-
public void getObjs() throws Exception {
56+
public void getObjs() {
5657
final MetadataService md = gd.getMetadataService();
5758

5859
fact = md.getObjUri(project, Fact.class, identifier("fact.person.shoesize"));
5960
attr = md.getObj(project, Attribute.class, identifier("attr.person.department"));
6061
}
6162

6263
@Test(groups = "md", dependsOnMethods = "getObjs")
63-
public void updateObj() throws Exception {
64+
public void updateObj() {
6465
final MetadataService md = gd.getMetadataService();
6566

6667
attr.setSummary("Changed person department");
@@ -70,7 +71,7 @@ public void updateObj() throws Exception {
7071
}
7172

7273
@Test(groups = "md", dependsOnMethods = "getObjs")
73-
public void createMetric() throws Exception {
74+
public void createMetric() {
7475
final MetadataService md = gd.getMetadataService();
7576
final Metric create = new Metric("Avg shoe size", "SELECT AVG([" + fact + "])", "#,##0");
7677
create.setIdentifier("metric.avgshoesize");
@@ -79,12 +80,12 @@ public void createMetric() throws Exception {
7980
}
8081

8182
@Test(groups = "md", dependsOnMethods = "createMetric")
82-
public void createReport() throws Exception {
83+
public void createReport() {
8384
final MetadataService md = gd.getMetadataService();
8485

8586
reportDefinition = md.createObj(project, GridReportDefinitionContent.create(
8687
"Department avg shoe size",
87-
asList(METRIC_GROUP),
88+
singletonList(METRIC_GROUP),
8889
asList(new AttributeInGrid(attr.getDefaultDisplayForm())),
8990
asList(new MetricElement(metric, "Avg shoe size")),
9091
asList(new Filter("(SELECT [" + metric.getUri() + "]) >= 0"))
@@ -93,7 +94,7 @@ public void createReport() throws Exception {
9394
}
9495

9596
@Test(groups = "md", dependsOnGroups = "model")
96-
public void createDashboardEmpty() throws Exception {
97+
public void createDashboardEmpty() {
9798
dashboard = gd.getMetadataService().createObj(project, new ProjectDashboard("My Dashboard", new Tab("My Tab")));
9899

99100
assertThat(dashboard.getTitle(), is("My Dashboard"));
@@ -139,7 +140,7 @@ public void usedByBatch() {
139140
}
140141

141142
@Test(groups = "md", dependsOnGroups = "model")
142-
public void getObjsByUris() throws Exception {
143+
public void getObjsByUris() {
143144
final MetadataService md = gd.getMetadataService();
144145

145146
final Map<String, String> uris =
@@ -154,7 +155,7 @@ public void getObjsByUris() throws Exception {
154155
}
155156

156157
@Test(groups = "md", dependsOnMethods = "createReport")
157-
public void createScheduledMail() throws Exception {
158+
public void createScheduledMail() {
158159
final MetadataService md = gd.getMetadataService();
159160

160161
scheduledMail = md.createObj(project,
@@ -172,7 +173,7 @@ public void createScheduledMail() throws Exception {
172173
}
173174

174175
@Test(groups = "md", dependsOnMethods = "createScheduledMail")
175-
public void retrieveScheduledMail() throws Exception {
176+
public void retrieveScheduledMail() {
176177
final MetadataService md = gd.getMetadataService();
177178
Collection<Entry> result = md.find(project, ScheduledMail.class);
178179
assertThat(result, hasSize(1));
@@ -183,7 +184,7 @@ public void retrieveScheduledMail() throws Exception {
183184
}
184185

185186
@Test(groups = "md", dependsOnMethods = "retrieveScheduledMail")
186-
public void removeScheduledMail() throws Exception {
187+
public void removeScheduledMail() {
187188
final MetadataService metadataService = gd.getMetadataService();
188189
metadataService.removeObj(scheduledMail);
189190
}
@@ -192,30 +193,49 @@ public void removeScheduledMail() throws Exception {
192193
public void identifiersToUri() {
193194
final MetadataService metadataService = gd.getMetadataService();
194195
final Map<String, String> idsToUris =
195-
metadataService.identifiersToUris(project, asList("attr.person.department"));
196+
metadataService.identifiersToUris(project, singletonList("attr.person.department"));
196197
assertThat(idsToUris.entrySet(), hasSize(1));
197198
final Attribute attribute = metadataService.getObjByUri(idsToUris.get("attr.person.department"), Attribute.class);
198199
assertThat(attribute.getIdentifier(), is("attr.person.department"));
199200
}
200201

201202
@Test(dependsOnGroups = "export", dependsOnMethods = {"usedBy", "usedByBatch"})
202-
public void removeReport() throws Exception {
203+
public void removeReport() {
203204
final MetadataService metadataService = gd.getMetadataService();
204205
metadataService.removeObj(report);
205206
}
206207

207208
@Test(dependsOnMethods = {"removeReport", "removeScheduledMail"})
208-
public void removeDefinition() throws Exception {
209+
public void removeDefinition() {
209210
final MetadataService metadataService = gd.getMetadataService();
210211
metadataService.removeObj(reportDefinition);
211212
}
212213

213214
@Test(groups = "mdAfterLoad", dependsOnGroups = {"model", "dataset"}, dependsOnMethods = "getObjs")
214-
public void getAttributeElements() throws Exception {
215+
public void getAttributeElements() {
215216
final List<AttributeElement> elements = gd.getMetadataService().getAttributeElements(attr);
216217
assertThat("there should be 2 elements", elements, hasSize(2));
217218
final Set<String> titles = new HashSet<>(elements.size());
218219
titles.addAll(elements.stream().map(AttributeElement::getTitle).collect(Collectors.toList()));
219220
assertThat(titles, hasItems("DevOps", "HR"));
220221
}
222+
223+
@Test(groups = "md", dependsOnGroups = "project")
224+
public void getTimezone() {
225+
final MetadataService md = gd.getMetadataService();
226+
227+
final String tz = md.getTimezone(project);
228+
assertThat(tz, is("America/Los_Angeles"));
229+
}
230+
231+
@Test(groups = "md", dependsOnMethods = "getTimezone")
232+
public void setTimezone() {
233+
final MetadataService md = gd.getMetadataService();
234+
235+
md.setTimezone(project, "UTC");
236+
237+
final String tz = md.getTimezone(project);
238+
assertThat(tz, is("UTC"));
239+
}
240+
221241
}

0 commit comments

Comments
 (0)