From 9fc42d661ffb4e825421af797c6954ac0e01b435 Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Wed, 6 Sep 2017 18:47:21 +0200 Subject: [PATCH 001/598] prefer readFromResource() over getResourceAsStream() --- .../java/com/gooddata/dataset/DatasetServiceAT.java | 13 +++++++------ src/test/java/com/gooddata/dataset/MaqlDmlTest.java | 3 ++- .../java/com/gooddata/gdc/DatastoreServiceAT.java | 9 +++++---- .../java/com/gooddata/md/ExportImportServiceAT.java | 3 ++- .../java/com/gooddata/model/ModelServiceAT.java | 4 +++- .../project/ProjectValidationResultParamTest.java | 3 ++- .../com/gooddata/util/ResponseErrorHandlerTest.java | 3 ++- 7 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/test/java/com/gooddata/dataset/DatasetServiceAT.java b/src/test/java/com/gooddata/dataset/DatasetServiceAT.java index 406730143..f3620e65e 100644 --- a/src/test/java/com/gooddata/dataset/DatasetServiceAT.java +++ b/src/test/java/com/gooddata/dataset/DatasetServiceAT.java @@ -5,6 +5,7 @@ */ package com.gooddata.dataset; +import static com.gooddata.util.ResourceUtils.readFromResource; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; @@ -29,7 +30,7 @@ public void loadDataset() throws Exception { final DatasetService datasetService = gd.getDatasetService(); final DatasetManifest manifest = datasetService.getDatasetManifest(project, "dataset.person"); - datasetService.loadDataset(project, manifest, getClass().getResourceAsStream("/person.csv")).get(); + datasetService.loadDataset(project, manifest, readFromResource("/person.csv")).get(); } @Test(groups = "dataset", dependsOnMethods = {"loadDataset"}) @@ -37,9 +38,9 @@ public void loadDatasetBatch() throws Exception { final DatasetService datasetService = gd.getDatasetService(); final DatasetManifest personManifest = datasetService.getDatasetManifest(project, "dataset.person"); - personManifest.setSource(getClass().getResourceAsStream("/person.csv")); + personManifest.setSource(readFromResource("/person.csv")); final DatasetManifest cityManifest = datasetService.getDatasetManifest(project, "dataset.city"); - cityManifest.setSource(getClass().getResourceAsStream("/city.csv")); + cityManifest.setSource(readFromResource("/city.csv")); datasetService.loadDatasets(project, personManifest, cityManifest).get(); } @@ -55,7 +56,7 @@ public void loadDatasetFail(){ final DatasetService datasetService = gd.getDatasetService(); final DatasetManifest manifest = datasetService.getDatasetManifest(project, "dataset.person"); try { - datasetService.loadDataset(project, manifest, getClass().getResourceAsStream("/corruptedPerson.csv")).get(); + datasetService.loadDataset(project, manifest, readFromResource("/corruptedPerson.csv")).get(); fail(); } catch (DatasetException ex){ assertThat(ex.getMessage(),is(equalTo("Load datasets [dataset.person] failed: [Number of columns doesn't corespond on line 3 in dataset.person.csv]"))); @@ -67,9 +68,9 @@ public void loadDatasetBatchFail() throws Exception { final DatasetService datasetService = gd.getDatasetService(); final DatasetManifest personManifest = datasetService.getDatasetManifest(project, "dataset.person"); - personManifest.setSource(getClass().getResourceAsStream("/corruptedPerson.csv")); + personManifest.setSource(readFromResource("/corruptedPerson.csv")); final DatasetManifest cityManifest = datasetService.getDatasetManifest(project, "dataset.city"); - cityManifest.setSource(getClass().getResourceAsStream("/city.csv")); + cityManifest.setSource(readFromResource("/city.csv")); try { datasetService.loadDatasets(project, personManifest, cityManifest).get(); diff --git a/src/test/java/com/gooddata/dataset/MaqlDmlTest.java b/src/test/java/com/gooddata/dataset/MaqlDmlTest.java index 9ac62d8f6..414404f99 100644 --- a/src/test/java/com/gooddata/dataset/MaqlDmlTest.java +++ b/src/test/java/com/gooddata/dataset/MaqlDmlTest.java @@ -10,6 +10,7 @@ import org.testng.annotations.Test; import static com.gooddata.util.ResourceUtils.OBJECT_MAPPER; +import static com.gooddata.util.ResourceUtils.readFromResource; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; @@ -17,7 +18,7 @@ public class MaqlDmlTest { @Test public void testSerialization() throws Exception { - final String json = IOUtils.toString(getClass().getResourceAsStream("/dataset/maqlDml.json"), "UTF-8"); + final String json = IOUtils.toString(readFromResource("/dataset/maqlDml.json"), "UTF-8"); assertThat(OBJECT_MAPPER.writeValueAsString(new MaqlDml("maqlddl")), is(json)); } diff --git a/src/test/java/com/gooddata/gdc/DatastoreServiceAT.java b/src/test/java/com/gooddata/gdc/DatastoreServiceAT.java index 14d63e347..306584666 100644 --- a/src/test/java/com/gooddata/gdc/DatastoreServiceAT.java +++ b/src/test/java/com/gooddata/gdc/DatastoreServiceAT.java @@ -17,6 +17,7 @@ import java.io.InputStream; import java.util.UUID; +import static com.gooddata.util.ResourceUtils.readFromResource; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; @@ -42,7 +43,7 @@ public void datastoreUpload() throws Exception { DataStoreService dataStoreService = gd.getDataStoreService(); file = directory + "/file.csv"; - dataStoreService.upload(file, getClass().getResourceAsStream("/person.csv")); + dataStoreService.upload(file, readFromResource("/person.csv")); } @Test(groups = "datastore", dependsOnMethods = "datastoreUpload") @@ -77,7 +78,7 @@ public void datastoreConnectionsClosedAfterMultipleConnections() { DataStoreService dataStoreService = gd.getDataStoreService(); directory = "/" + UUID.randomUUID().toString(); for (int i = 0; i < ITER_MAX; i++) { - dataStoreService.upload(directory + "/file" + i + ".csv", getClass().getResourceAsStream("/person.csv")); + dataStoreService.upload(directory + "/file" + i + ".csv", readFromResource("/person.csv")); } assertThat(connManager.getTotalStats().getLeased(), is(equalTo(0))); } @@ -88,7 +89,7 @@ public void datastoreConnectionClosedAfterSingleConnection() throws Exception { directory = "/" + UUID.randomUUID().toString(); file = directory + "/file.csv"; - dataStoreService.upload(file, getClass().getResourceAsStream("/person.csv")); + dataStoreService.upload(file, readFromResource("/person.csv")); assertThat(connManager.getTotalStats().getLeased(), is(equalTo(0))); } @@ -100,7 +101,7 @@ public void shouldThrowExceptionWithMessageOnUnAuthRequest() throws Exception { try { final String fileWithAuth = directory + "/fileWithAuth.csv"; - dataStoreService.upload(fileWithAuth, getClass().getResourceAsStream("/person.csv")); + dataStoreService.upload(fileWithAuth, readFromResource("/person.csv")); } finally { datastoreGd.logout(); } diff --git a/src/test/java/com/gooddata/md/ExportImportServiceAT.java b/src/test/java/com/gooddata/md/ExportImportServiceAT.java index 85c072478..ae7edc26a 100644 --- a/src/test/java/com/gooddata/md/ExportImportServiceAT.java +++ b/src/test/java/com/gooddata/md/ExportImportServiceAT.java @@ -6,6 +6,7 @@ package com.gooddata.md; import static com.gooddata.md.Restriction.identifier; +import static com.gooddata.util.ResourceUtils.readFromResource; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; @@ -39,7 +40,7 @@ public void setUp() throws Exception { final ModelService modelService = gd.getModelService(); final ModelDiff projectModelDiff = modelService.getProjectModelDiff(importProject, - new InputStreamReader(getClass().getResourceAsStream("/person.json"))).get(); + new InputStreamReader(readFromResource("/person.json"))).get(); modelService.updateProjectModel(importProject, projectModelDiff).get(); } diff --git a/src/test/java/com/gooddata/model/ModelServiceAT.java b/src/test/java/com/gooddata/model/ModelServiceAT.java index 5e55ac3e7..9da499933 100644 --- a/src/test/java/com/gooddata/model/ModelServiceAT.java +++ b/src/test/java/com/gooddata/model/ModelServiceAT.java @@ -10,6 +10,8 @@ import java.io.InputStreamReader; +import static com.gooddata.util.ResourceUtils.readFromResource; + /** * Project model acceptance test */ @@ -20,7 +22,7 @@ public void createModel() throws Exception { final ModelService modelService = gd.getModelService(); final ModelDiff projectModelDiff = modelService.getProjectModelDiff(project, - new InputStreamReader(getClass().getResourceAsStream("/person.json"))).get(); + new InputStreamReader(readFromResource("/person.json"))).get(); modelService.updateProjectModel(project, projectModelDiff).get(); } diff --git a/src/test/java/com/gooddata/project/ProjectValidationResultParamTest.java b/src/test/java/com/gooddata/project/ProjectValidationResultParamTest.java index 92dcbea51..15087a400 100644 --- a/src/test/java/com/gooddata/project/ProjectValidationResultParamTest.java +++ b/src/test/java/com/gooddata/project/ProjectValidationResultParamTest.java @@ -12,6 +12,7 @@ import java.util.List; import static com.gooddata.util.ResourceUtils.OBJECT_MAPPER; +import static com.gooddata.util.ResourceUtils.readFromResource; import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; import static java.util.Arrays.asList; import static org.hamcrest.MatcherAssert.assertThat; @@ -22,7 +23,7 @@ public class ProjectValidationResultParamTest { @Test public void testDeser() throws Exception { final List result = OBJECT_MAPPER - .readValue(getClass().getResourceAsStream("/project/project-validationResultParam.json"), + .readValue(readFromResource("/project/project-validationResultParam.json"), new TypeReference>() { }); assertThat(result, hasItem(sameBeanAs(new ProjectValidationResultStringParam("report")))); diff --git a/src/test/java/com/gooddata/util/ResponseErrorHandlerTest.java b/src/test/java/com/gooddata/util/ResponseErrorHandlerTest.java index 5a5280968..d9c038988 100644 --- a/src/test/java/com/gooddata/util/ResponseErrorHandlerTest.java +++ b/src/test/java/com/gooddata/util/ResponseErrorHandlerTest.java @@ -18,6 +18,7 @@ import java.io.IOException; import static com.gooddata.util.ResourceUtils.OBJECT_MAPPER; +import static com.gooddata.util.ResourceUtils.readFromResource; import static java.util.Collections.singletonList; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; @@ -88,7 +89,7 @@ private ClientHttpResponse prepareResponse(String resourcePath) throws IOExcepti headers.set(GoodData.GDC_REQUEST_ID_HEADER, "requestId"); headers.setContentType(MediaType.APPLICATION_JSON); when(response.getHeaders()).thenReturn(headers); - when(response.getBody()).thenReturn(getClass().getResourceAsStream(resourcePath)); + when(response.getBody()).thenReturn(readFromResource(resourcePath)); return response; } From 23ef56458f455de106be5fbd4a97eded843dea89 Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Fri, 30 Jun 2017 17:21:32 +0200 Subject: [PATCH 002/598] extract gooddata-rest-common Close: #515 --- pom.xml | 5 + src/main/java/com/gooddata/GoodData.java | 2 +- .../java/com/gooddata/GoodDataException.java | 31 --- .../com/gooddata/GoodDataRestException.java | 146 ---------- src/main/java/com/gooddata/UriPrefixer.java | 94 ------- .../UriPrefixingClientHttpRequestFactory.java | 60 ----- .../java/com/gooddata/collections/Page.java | 49 ---- .../com/gooddata/collections/PageRequest.java | 135 ---------- .../gooddata/collections/PageableList.java | 255 ------------------ .../collections/PageableListDeserializer.java | 80 ------ .../collections/PageableListSerializer.java | 71 ----- .../java/com/gooddata/collections/Paging.java | 54 ---- .../com/gooddata/collections/UriPage.java | 86 ------ .../java/com/gooddata/gdc/ErrorStructure.java | 89 ------ .../gdc/ErrorStructureDeserializer.java | 68 ----- src/main/java/com/gooddata/gdc/GdcError.java | 36 --- .../gooddata/util/BooleanDeserializer.java | 38 --- .../util/BooleanIntegerSerializer.java | 23 -- .../util/BooleanStringSerializer.java | 23 -- .../com/gooddata/util/GDDateDeserializer.java | 38 --- .../com/gooddata/util/GDDateSerializer.java | 27 -- .../gooddata/util/GDDateTimeDeserializer.java | 31 --- .../gooddata/util/GDDateTimeSerializer.java | 35 --- .../util/ISODateTimeDeserializer.java | 32 --- .../gooddata/util/ISODateTimeSerializer.java | 29 -- src/main/java/com/gooddata/util/Validate.java | 119 -------- .../gooddata/GoodDataRestExceptionTest.java | 81 ------ .../java/com/gooddata/UriPrefixerTest.java | 72 ----- .../gooddata/collections/PageRequestTest.java | 110 -------- .../collections/PageableListTest.java | 63 ----- .../com/gooddata/collections/PagingTest.java | 55 ---- .../com/gooddata/collections/UriPageTest.java | 86 ------ .../com/gooddata/gdc/ErrorStructureTest.java | 38 --- .../java/com/gooddata/gdc/GdcErrorTest.java | 35 --- .../util/BooleanDeserializerTest.java | 62 ----- .../gooddata/util/BooleanIntegerClass.java | 25 -- .../util/BooleanIntegerSerializerTest.java | 32 --- .../com/gooddata/util/BooleanStringClass.java | 25 -- .../util/BooleanStringSerializerTest.java | 32 --- .../java/com/gooddata/util/GDDateClass.java | 27 -- .../gooddata/util/GDDateDeserializerTest.java | 31 --- .../gooddata/util/GDDateSerializerTest.java | 26 -- .../com/gooddata/util/GDDateTimeClass.java | 27 -- .../util/GDDateTimeDeserializerTest.java | 29 -- .../util/GDDateTimeSerializerTest.java | 27 -- .../java/com/gooddata/util/ISODateClass.java | 27 -- .../util/ISODateTimeDeserializerTest.java | 30 --- .../util/ISODateTimeSerializerTest.java | 27 -- .../java/com/gooddata/util/ResourceUtils.java | 59 ---- src/test/resources/collections/paging.json | 5 - .../resources/collections/paging_no_next.json | 4 - .../collections/paging_only_next.json | 3 - 52 files changed, 6 insertions(+), 2688 deletions(-) delete mode 100644 src/main/java/com/gooddata/GoodDataException.java delete mode 100644 src/main/java/com/gooddata/GoodDataRestException.java delete mode 100644 src/main/java/com/gooddata/UriPrefixer.java delete mode 100644 src/main/java/com/gooddata/UriPrefixingClientHttpRequestFactory.java delete mode 100644 src/main/java/com/gooddata/collections/Page.java delete mode 100644 src/main/java/com/gooddata/collections/PageRequest.java delete mode 100644 src/main/java/com/gooddata/collections/PageableList.java delete mode 100644 src/main/java/com/gooddata/collections/PageableListDeserializer.java delete mode 100644 src/main/java/com/gooddata/collections/PageableListSerializer.java delete mode 100644 src/main/java/com/gooddata/collections/Paging.java delete mode 100644 src/main/java/com/gooddata/collections/UriPage.java delete mode 100644 src/main/java/com/gooddata/gdc/ErrorStructure.java delete mode 100644 src/main/java/com/gooddata/gdc/ErrorStructureDeserializer.java delete mode 100644 src/main/java/com/gooddata/gdc/GdcError.java delete mode 100644 src/main/java/com/gooddata/util/BooleanDeserializer.java delete mode 100644 src/main/java/com/gooddata/util/BooleanIntegerSerializer.java delete mode 100644 src/main/java/com/gooddata/util/BooleanStringSerializer.java delete mode 100644 src/main/java/com/gooddata/util/GDDateDeserializer.java delete mode 100644 src/main/java/com/gooddata/util/GDDateSerializer.java delete mode 100644 src/main/java/com/gooddata/util/GDDateTimeDeserializer.java delete mode 100644 src/main/java/com/gooddata/util/GDDateTimeSerializer.java delete mode 100644 src/main/java/com/gooddata/util/ISODateTimeDeserializer.java delete mode 100644 src/main/java/com/gooddata/util/ISODateTimeSerializer.java delete mode 100644 src/main/java/com/gooddata/util/Validate.java delete mode 100644 src/test/java/com/gooddata/GoodDataRestExceptionTest.java delete mode 100644 src/test/java/com/gooddata/UriPrefixerTest.java delete mode 100644 src/test/java/com/gooddata/collections/PageRequestTest.java delete mode 100644 src/test/java/com/gooddata/collections/PageableListTest.java delete mode 100644 src/test/java/com/gooddata/collections/PagingTest.java delete mode 100644 src/test/java/com/gooddata/collections/UriPageTest.java delete mode 100644 src/test/java/com/gooddata/gdc/ErrorStructureTest.java delete mode 100644 src/test/java/com/gooddata/gdc/GdcErrorTest.java delete mode 100644 src/test/java/com/gooddata/util/BooleanDeserializerTest.java delete mode 100644 src/test/java/com/gooddata/util/BooleanIntegerClass.java delete mode 100644 src/test/java/com/gooddata/util/BooleanIntegerSerializerTest.java delete mode 100644 src/test/java/com/gooddata/util/BooleanStringClass.java delete mode 100644 src/test/java/com/gooddata/util/BooleanStringSerializerTest.java delete mode 100644 src/test/java/com/gooddata/util/GDDateClass.java delete mode 100644 src/test/java/com/gooddata/util/GDDateDeserializerTest.java delete mode 100644 src/test/java/com/gooddata/util/GDDateSerializerTest.java delete mode 100644 src/test/java/com/gooddata/util/GDDateTimeClass.java delete mode 100644 src/test/java/com/gooddata/util/GDDateTimeDeserializerTest.java delete mode 100644 src/test/java/com/gooddata/util/GDDateTimeSerializerTest.java delete mode 100644 src/test/java/com/gooddata/util/ISODateClass.java delete mode 100644 src/test/java/com/gooddata/util/ISODateTimeDeserializerTest.java delete mode 100644 src/test/java/com/gooddata/util/ISODateTimeSerializerTest.java delete mode 100644 src/test/java/com/gooddata/util/ResourceUtils.java delete mode 100644 src/test/resources/collections/paging.json delete mode 100644 src/test/resources/collections/paging_no_next.json delete mode 100644 src/test/resources/collections/paging_only_next.json diff --git a/pom.xml b/pom.xml index 20ac6fa91..300f90e43 100644 --- a/pom.xml +++ b/pom.xml @@ -178,6 +178,11 @@ + + com.gooddata + gooddata-rest-common + 1.0.0 + com.gooddata gooddata-http-client diff --git a/src/main/java/com/gooddata/GoodData.java b/src/main/java/com/gooddata/GoodData.java index 577472141..67e10860c 100644 --- a/src/main/java/com/gooddata/GoodData.java +++ b/src/main/java/com/gooddata/GoodData.java @@ -229,7 +229,7 @@ static RestTemplate createRestTemplate(GoodDataEndpoint endpoint, HttpClient htt final UriPrefixingClientHttpRequestFactory factory = new UriPrefixingClientHttpRequestFactory( new HttpComponentsClientHttpRequestFactory(httpClient), - endpoint + endpoint.toUri() ); final RestTemplate restTemplate = new RestTemplate(factory); restTemplate.setInterceptors(Arrays.asList( diff --git a/src/main/java/com/gooddata/GoodDataException.java b/src/main/java/com/gooddata/GoodDataException.java deleted file mode 100644 index c5600dccb..000000000 --- a/src/main/java/com/gooddata/GoodDataException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata; - -/** - * Signals that something unexpected happened in GoodData SDK. - */ -public class GoodDataException extends RuntimeException { - - /** - * Construct a GoodDataException with the specified detail message. - * - * @param message the detail message - */ - public GoodDataException(String message) { - super(message); - } - - /** - * Construct a GoodDataException with the specified detail message and cause. - * - * @param message the detail message - * @param cause the cause - */ - public GoodDataException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/src/main/java/com/gooddata/GoodDataRestException.java b/src/main/java/com/gooddata/GoodDataRestException.java deleted file mode 100644 index 782e4a4e4..000000000 --- a/src/main/java/com/gooddata/GoodDataRestException.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata; - -import com.gooddata.gdc.ErrorStructure; -import com.gooddata.gdc.GdcError; - -/** - * Signals client or server error during communication with GoodData REST API. - */ -public class GoodDataRestException extends GoodDataException { - - private final int statusCode; - - private final String requestId; - - private final String component; - - private final String errorClass; - - private final String text; - - private final String errorCode; - - /** - * Construct a GoodDataRestException with specified details. - * @param statusCode the HTTP status code of the response - * @param requestId the GoodData request ID (from header) - * @param message the detail message - * @param component the GoodData component where error occurred - * @param errorClass the class of the error - * @param errorCode the code of the error - */ - public GoodDataRestException(int statusCode, String requestId, String message, String component, - String errorClass, String errorCode) { - super(statusCode + - (requestId != null ? ": [requestId=" + requestId + "] " : ": ") + - (message != null ? message : "Unknown error")); - this.statusCode = statusCode; - this.requestId = requestId; - this.component = component; - this.errorClass = errorClass; - this.text = message; - this.errorCode = errorCode; - } - - /** - * Construct a GoodDataRestException with specified details. - * - * @param statusCode the HTTP status code of the response - * @param requestId the GoodData request ID (from header) - * @param message the detail message - * @param component the GoodData component where error occurred - * @param errorClass the class of the error - */ - public GoodDataRestException(int statusCode, String requestId, String message, String component, - String errorClass) { - this(statusCode, requestId, message, component, errorClass, null); - } - - /** - * Construct a GoodDataRestException with specified details. - * - * @param statusCode the HTTP status code of the response - * @param requestId the GoodData request ID (from header) - * @param statusText the HTTP status text of the response - * @param error the GoodData REST API error structure - */ - public GoodDataRestException(int statusCode, String requestId, String statusText, ErrorStructure error) { - this(statusCode, - error != null && error.getRequestId() != null ? error.getRequestId() : requestId, - error != null && error.getMessage() != null ? error.getFormattedMessage() : statusText, - error != null ? error.getComponent() : null, - error != null ? error.getErrorClass() : null, - error != null ? error.getErrorCode() : null); - } - - /** - * Construct a GoodDataRestException with specified details. - * Constructor is for binary compatibility with pre 2.4.1 version. - * - * @param statusCode the HTTP status code of the response - * @param requestId the GoodData request ID (from header) - * @param statusText the HTTP status text of the response - * @param error the GoodData REST API error structure - */ - public GoodDataRestException(int statusCode, String requestId, String statusText, GdcError error) { - this(statusCode, requestId, statusText, (ErrorStructure)error); - } - - /** - * Get the HTTP status code of the problematic REST API call response - * - * @return the HTTP status code of the response - */ - public int getStatusCode() { - return statusCode; - } - - /** - * Get the GoodData request ID (from header) of the problematic REST API call response - * - * @return the GoodData request ID (from header) - */ - public String getRequestId() { - return requestId; - } - - /** - * Get the GoodData component where error occurred - * - * @return the GoodData component where error occurred - */ - public String getComponent() { - return component; - } - - /** - * Get the class of the error - * - * @return the class of the error - */ - public String getErrorClass() { - return errorClass; - } - - /** - * Get the code of the error - * - * @return the code of the error - */ - public String getErrorCode() { - return errorCode; - } - - /** - * Text message describing the error - * @return text message - */ - public String getText() { - return text; - } -} diff --git a/src/main/java/com/gooddata/UriPrefixer.java b/src/main/java/com/gooddata/UriPrefixer.java deleted file mode 100644 index e64ab13b3..000000000 --- a/src/main/java/com/gooddata/UriPrefixer.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.web.util.UriComponentsBuilder; - -import java.net.URI; -import java.util.List; - -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.util.Validate.notNull; - -/** - * Used internally by GoodData SDK to hold and set URI prefix (hostname and port) of all requests. - */ -public class UriPrefixer { - - private final URI uriPrefix; - - /** - * Construct URI prefixer using given URI prefix (just hostname and port is used) - * - * @param uriPrefix the URI prefix - */ - public UriPrefixer(URI uriPrefix) { - this.uriPrefix = notNull(uriPrefix, "uriPrefix"); - } - - /** - * Construct URI prefixer using given URI prefix (just hostname and port is used) - * - * @param uriPrefix the URI prefix string - */ - public UriPrefixer(String uriPrefix) { - this(URI.create(uriPrefix)); - } - - /** - * Get the URI prefix - * - * @return the URI prefix - */ - public URI getUriPrefix() { - return uriPrefix; - } - - /** - * Return merged URI prefix (hostname and port) with the given URI (path, query, and fragment URI parts) - * - * @param uri the URI its parts (path, query, and fragment) will be merged with URI prefix - * @return the merged URI - */ - public URI mergeUris(URI uri) { - notNull(uri, "uri"); - - final String path = uri.getRawPath(); - final String[] pathSegments = getPathSegments(path); - - final UriComponentsBuilder builder = UriComponentsBuilder.fromUri(uriPrefix) - .pathSegment(pathSegments) - .query(uri.getRawQuery()) - .fragment(uri.getRawFragment()); - if (StringUtils.endsWith(path, "/")) { - builder.path("/"); - } - - return builder - .build(true) // we have an URI as the input, so it is already encoded - .toUri(); - } - - private static String[] getPathSegments(final String path) { - final List pathSegments = UriComponentsBuilder - .fromPath(path) - .build(true) - .getPathSegments(); - return pathSegments.toArray(new String[pathSegments.size()]); - } - - /** - * Return merged URI prefix (hostname and port) with the given URI string (path, query, and fragment URI parts) - * - * @param uri the URI string its parts (path, query, and fragment) will be merged with URI prefix - * @return the merged URI - */ - public URI mergeUris(String uri) { - notEmpty(uri, "uri"); - return mergeUris(URI.create(uri)); - } -} \ No newline at end of file diff --git a/src/main/java/com/gooddata/UriPrefixingClientHttpRequestFactory.java b/src/main/java/com/gooddata/UriPrefixingClientHttpRequestFactory.java deleted file mode 100644 index 7a8b868cf..000000000 --- a/src/main/java/com/gooddata/UriPrefixingClientHttpRequestFactory.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata; - -import org.springframework.http.HttpMethod; -import org.springframework.http.client.ClientHttpRequest; -import org.springframework.http.client.ClientHttpRequestFactory; - -import java.io.IOException; -import java.net.URI; - -import static com.gooddata.util.Validate.notNull; - -/** - * Factory for ClientHttpRequest objects. - * Sets default URI prefix for Spring REST client which by default requires absolute URI. - * UriPrefixingAsyncClientHttpRequestFactory allows you to specify default hostname and port. - */ -class UriPrefixingClientHttpRequestFactory implements ClientHttpRequestFactory { - - private final ClientHttpRequestFactory wrapped; - private final UriPrefixer prefixer; - - /** - * Create an instance that will wrap the given {@link org.springframework.http.client.ClientHttpRequestFactory} - * and use the given URI for setting hostname and port of all HTTP requests - * - * @param factory the factory to be wrapped - * @param uriPrefix the URI for setting hostname and port of all HTTP requests - */ - UriPrefixingClientHttpRequestFactory(ClientHttpRequestFactory factory, URI uriPrefix) { - this(factory, new UriPrefixer(uriPrefix)); - } - - /** - * Create an instance that will wrap the given {@link org.springframework.http.client.ClientHttpRequestFactory} - * and use the given hostname, port, and protocol for all HTTP requests - * - * @param factory the factory to be wrapped - * @param endpoint GoodData Platform's endpoint - */ - UriPrefixingClientHttpRequestFactory(ClientHttpRequestFactory factory, GoodDataEndpoint endpoint) { - this(factory, new UriPrefixer(notNull(endpoint, "prefixer").toUri())); - } - - private UriPrefixingClientHttpRequestFactory(final ClientHttpRequestFactory factory, final UriPrefixer prefixer) { - this.wrapped = notNull(factory, "factory"); - this.prefixer = notNull(prefixer, "prefixer"); - } - - @Override - public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException { - final URI merged = prefixer.mergeUris(uri); - return wrapped.createRequest(merged, httpMethod); - } - -} \ No newline at end of file diff --git a/src/main/java/com/gooddata/collections/Page.java b/src/main/java/com/gooddata/collections/Page.java deleted file mode 100644 index 42835b975..000000000 --- a/src/main/java/com/gooddata/collections/Page.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.collections; - -import org.springframework.web.client.RestOperations; -import org.springframework.web.util.UriComponentsBuilder; - -import java.net.URI; - -/** - * Defines logic for generating page URIs. - */ -public interface Page { - - /** - * Creates {@link URI} for this page request. - *

- * Use {@link #updateWithPageParams(UriComponentsBuilder)} if you have URI template and only want to update it with - * page query params. - * - * @param uriBuilder URI builder used for generating page URI - * @return compiled page URI - */ - URI getPageUri(final UriComponentsBuilder uriBuilder); - - /** - * Updates provided URI builder query params according to this page configuration. - *

- * As {@link #getPageUri(UriComponentsBuilder)} returns expanded page URI it is not very useful for cases that - * require use of URI template with URI variables. This method allows you to use URI templates and benefit - * from pagination support implemented in {@link Page} implementations. It is especially useful if you need to handle - * multiple requests of the same URI template in the same way - e.g. monitor request made by {@link RestOperations} - * methods. - *

- * Use this in the situation when you have URI template with placeholders and URI variables separately. - * This method is useful when you have URI template with placeholders and only want to add query parameters based - * on this page to it. - *

- * Use {@link #getPageUri(UriComponentsBuilder)} if you want to get concrete page URI and don't have URI template. - * - * @param uriBuilder URI builder used for constructing page URI - * @return provided and updated builder instance - * @see RestOperations - */ - UriComponentsBuilder updateWithPageParams(final UriComponentsBuilder uriBuilder); -} diff --git a/src/main/java/com/gooddata/collections/PageRequest.java b/src/main/java/com/gooddata/collections/PageRequest.java deleted file mode 100644 index 03bcb87e0..000000000 --- a/src/main/java/com/gooddata/collections/PageRequest.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.collections; - -import com.gooddata.util.GoodDataToStringBuilder; -import org.springframework.web.util.UriComponentsBuilder; - -import java.net.URI; - -import static com.gooddata.util.Validate.notNull; - -/** - * User defined page with desired offset and limit. - */ -public class PageRequest implements Page { - - public static final Integer DEFAULT_LIMIT = 100; - - private String offset; - private int limit; - - /** - * Creates new page definition with default values - */ - public PageRequest() { - this(null, DEFAULT_LIMIT); - } - - /** - * Creates new page definition with provided values. - * - * @param offset page offset (position in the collection) - * @param limit maximal number of returned elements (on a page) - */ - public PageRequest(final int offset, final int limit) { - this(String.valueOf(offset), limit); - } - - /** - * Creates new page definition with provided values. - * - * @param offset page offset (position in the collection) - * @param limit maximal number of returned elements (on a page) - */ - public PageRequest(final String offset, final int limit) { - this.offset = offset; - this.limit = limit; - } - - /** - * Creates new page definition with limit and no offset (usually for the first page) - * @param limit maximal number of returned elements (on a page) - */ - public PageRequest(final int limit) { - this(null, limit); - } - - - public String getOffset() { - return offset; - } - - public void setOffset(final String offset) { - this.offset = offset; - } - - public int getLimit() { - return limit; - } - - /** - * Return the limit value or the {@link #DEFAULT_LIMIT} if the limit is lower than or equal to zero - * @return sanitized limit - */ - public int getSanitizedLimit() { - return limit > 0 ? limit : DEFAULT_LIMIT; - } - - /** - * Return the {@link #getSanitizedLimit()} if lower than the given maximum or the maximum value - * @param max maximum value - * @return sanitized limit - */ - public int getSanitizedLimit(final int max) { - final int limit = getSanitizedLimit(); - return limit < max ? limit : max; - } - - public void setLimit(final int limit) { - this.limit = limit; - } - - @Override - public URI getPageUri(final UriComponentsBuilder uriBuilder) { - notNull(uriBuilder, "uriBuilder"); - final UriComponentsBuilder copy = UriComponentsBuilder.fromUriString(uriBuilder.build().toUriString()); - return updateWithPageParams(copy).build().toUri(); - } - - @Override - public UriComponentsBuilder updateWithPageParams(final UriComponentsBuilder uriBuilder) { - if (offset != null) { - uriBuilder.replaceQueryParam("offset", offset); - } - uriBuilder.replaceQueryParam("limit", limit); - return uriBuilder; - } - - @Override - public String toString() { - return GoodDataToStringBuilder.defaultToString(this); - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final PageRequest that = (PageRequest) o; - - if (limit != that.limit) return false; - return !(offset != null ? !offset.equals(that.offset) : that.offset != null); - - } - - @Override - public int hashCode() { - int result = offset != null ? offset.hashCode() : 0; - result = 31 * result + limit; - return result; - } -} diff --git a/src/main/java/com/gooddata/collections/PageableList.java b/src/main/java/com/gooddata/collections/PageableList.java deleted file mode 100644 index 072e6cd66..000000000 --- a/src/main/java/com/gooddata/collections/PageableList.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.collections; - -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import static com.gooddata.util.Validate.notNull; - -/** - * Wrapper over pageable GDC list. - * - * @param type of collection elements - */ -public class PageableList implements List { - - static final String ITEMS_NODE = "items"; - static final String LINKS_NODE = "links"; - static final String PAGING_NODE = "paging"; - - private final List items; - private final Paging paging; - private final Map links; - - /** - * Creates empty list with no next page. - */ - public PageableList() { - this(Collections.emptyList(), null); - } - - /** - * Creates list wrapping provided items and next page. - * - * @param items to be wrapped - * @param paging page description, might be null - */ - public PageableList(final List items, final Paging paging) { - this(items, paging, null); - } - - /** - * Creates list wrapping provided items, next page and links. - * - * @param items to be wrapped - * @param paging page description, might be null - * @param links links, might be null - */ - public PageableList(final List items, final Paging paging, final Map links) { - this.items = notNull(items, "items"); - this.paging = paging; - this.links = links; - } - - /** - * @return all items as list - */ - public List collectAll() { - return items; - } - - /** - * Returns description of the next page. - * - * @return next page, might be null - */ - public Page getNextPage() { - return paging == null ? null : paging.getNext(); - } - - /** - * Signals whether there are more subsequent pages or the last page has been reached - * @return true if there are more results to come - */ - public boolean hasNextPage() { - return getNextPage() != null; - } - - /** - * Returns map of links. - * - * @return map of links, might be null - */ - public Map getLinks() { - return links; - } - - /** - * Returns description of the current collection page. - * - * @return current collection page, might be null - */ - public Paging getPaging() { - return paging; - } - - /** - * Returns size of the items collection on a current page. - * - * @return size of the items collection on a current page - */ - @Override - public int size() { - return items.size(); - } - - @Override - public boolean isEmpty() { - return items.isEmpty(); - } - - /** - * Whether current page items contain the specified object. - */ - @Override - public boolean contains(final Object o) { - return items.contains(o); - } - - @Override - public Iterator iterator() { - return items.iterator(); - } - - /** - * @return the list of current page items only - */ - public List getCurrentPageItems() { return items; } - - @Override - public Object[] toArray() { - return items.toArray(); - } - - @Override - public T[] toArray(final T[] a) { - return items.toArray(a); - } - - @Override - public boolean add(final E e) { - return items.add(e); - } - - @Override - public boolean remove(final Object o) { - return items.remove(o); - } - - @Override - public boolean containsAll(final Collection c) { - return items.containsAll(c); - } - - @Override - public boolean addAll(final Collection c) { - return items.addAll(c); - } - - @Override - public boolean addAll(final int index, final Collection c) { - return items.addAll(index, c); - } - - @Override - public boolean removeAll(final Collection c) { - return items.removeAll(c); - } - - @Override - public boolean retainAll(final Collection c) { - return items.retainAll(c); - } - - @Override - public void clear() { - items.clear(); - } - - @Override - public E get(final int index) { - return items.get(index); - } - - @Override - public E set(final int index, final E element) { - return items.set(index, element); - } - - @Override - public void add(final int index, final E element) { - items.add(index, element); - } - - @Override - public E remove(final int index) { - return items.remove(index); - } - - @Override - public int indexOf(final Object o) { - return items.indexOf(o); - } - - @Override - public int lastIndexOf(final Object o) { - return items.lastIndexOf(o); - } - - @Override - public ListIterator listIterator() { - return items.listIterator(); - } - - @Override - public ListIterator listIterator(final int index) { - return items.listIterator(index); - } - - @Override - public List subList(final int fromIndex, final int toIndex) { - return items.subList(fromIndex, toIndex); - } - - Iterator getItemsIterator() { - return items.iterator(); - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final PageableList that = (PageableList) o; - - if (!items.equals(that.items)) return false; - if (getPaging() != null ? !getPaging().equals(that.getPaging()) : that.getPaging() != null) return false; - return getLinks() != null ? getLinks().equals(that.getLinks()) : that.getLinks() == null; - } - - @Override - public int hashCode() { - int result = items.hashCode(); - result = 31 * result + (getPaging() != null ? getPaging().hashCode() : 0); - result = 31 * result + (getLinks() != null ? getLinks().hashCode() : 0); - return result; - } -} diff --git a/src/main/java/com/gooddata/collections/PageableListDeserializer.java b/src/main/java/com/gooddata/collections/PageableListDeserializer.java deleted file mode 100644 index 2ec855b4f..000000000 --- a/src/main/java/com/gooddata/collections/PageableListDeserializer.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.collections; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.core.type.TypeReference; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static com.gooddata.collections.PageableList.ITEMS_NODE; -import static com.gooddata.collections.PageableList.LINKS_NODE; -import static com.gooddata.collections.PageableList.PAGING_NODE; -import static com.gooddata.util.Validate.notNull; - -public abstract class PageableListDeserializer extends JsonDeserializer { - - private static final TypeReference> LINKS_TYPE = new TypeReference>() {}; - - private final Class elementType; - private final String collectionName; - - protected PageableListDeserializer(final Class elementType) { - this(elementType, ITEMS_NODE); - } - - protected PageableListDeserializer(final Class elementType, final String collectionName) { - this.elementType = notNull(elementType, "elementType"); - this.collectionName = notNull(collectionName, "collectionName"); - } - - protected abstract T createList(final List items, final Paging paging, final Map links); - - @Override - public T deserialize(final JsonParser jp, final DeserializationContext context) throws IOException, JsonProcessingException { - final JsonNode root = jp.readValueAsTree(); - if (root == null || root.isNull()) { - return null; - } - - // codec should be always instance of ObjectMapper so this cast should be safe - // we do not want to create custom object mapper with different configuration than the global one has - final ObjectMapper objectMapper = (ObjectMapper) jp.getCodec(); - - final JsonNode pagingNode = root.get(PAGING_NODE); - final Paging paging = pagingNode == null ? null : objectMapper.convertValue(pagingNode, Paging.class); - - final JsonNode linksNode = root.get(LINKS_NODE); - final Map links; - if (linksNode != null) { - links = objectMapper.convertValue(linksNode, LINKS_TYPE); - } else { - links = null; - } - - final JsonNode itemsNode = root.get(collectionName); - final List items; - if (itemsNode == null) { - items = Collections.emptyList(); - } else { - items = new ArrayList<>(itemsNode.size()); - for (JsonNode item : itemsNode) { - items.add(objectMapper.convertValue(item, elementType)); - } - } - return createList(items, paging, links); - } - -} diff --git a/src/main/java/com/gooddata/collections/PageableListSerializer.java b/src/main/java/com/gooddata/collections/PageableListSerializer.java deleted file mode 100644 index 1b829cc87..000000000 --- a/src/main/java/com/gooddata/collections/PageableListSerializer.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.collections; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.ObjectCodec; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.jsontype.TypeSerializer; - -import java.io.IOException; - -import static com.gooddata.collections.PageableList.ITEMS_NODE; -import static com.gooddata.collections.PageableList.LINKS_NODE; -import static com.gooddata.collections.PageableList.PAGING_NODE; -import static com.gooddata.util.Validate.notEmpty; - -/** - * Serializer {@link PageableList} objects into JSON. - */ -public abstract class PageableListSerializer extends JsonSerializer> { - - private final String rootNode; - - public PageableListSerializer(String rootNode) { - this.rootNode = notEmpty(rootNode, "rootNode"); - } - - @Override - public void serialize(final PageableList value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException { - jgen.writeStartObject(); - jgen.writeFieldName(rootNode); - - jgen.writeStartObject(); - jgen.writeFieldName(ITEMS_NODE); - - jgen.writeStartArray(); - final ObjectCodec codec = jgen.getCodec(); - - for (final Object item: value.getCurrentPageItems()) { - codec.writeValue(jgen, item); - } - jgen.writeEndArray(); - - writeObjectOrEmpty(jgen, codec, PAGING_NODE, value.getPaging()); - - writeObjectOrEmpty(jgen, codec, LINKS_NODE, value.getLinks()); - - jgen.writeEndObject(); - jgen.writeEndObject(); - } - - @Override - public void serializeWithType(final PageableList value, final JsonGenerator gen, final SerializerProvider provider, - final TypeSerializer typeSer) throws IOException { - serialize(value, gen, provider); - } - - private void writeObjectOrEmpty(final JsonGenerator jgen, final ObjectCodec codec, final String name, final Object object) throws IOException { - jgen.writeFieldName(name); - if (object != null) { - codec.writeValue(jgen, object); - } else { - jgen.writeStartObject(); - jgen.writeEndObject(); - } - } -} diff --git a/src/main/java/com/gooddata/collections/Paging.java b/src/main/java/com/gooddata/collections/Paging.java deleted file mode 100644 index d59f6a4f7..000000000 --- a/src/main/java/com/gooddata/collections/Paging.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.collections; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.annotation.JsonTypeInfo.As; -import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; -import com.fasterxml.jackson.annotation.JsonTypeName; - -/** - * Description of the current collection page. - */ -@JsonTypeInfo(include = As.WRAPPER_OBJECT, use = Id.NONE) -@JsonTypeName("paging") -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class Paging { - - private final String offset; - private final UriPage next; - - @JsonCreator - public Paging(@JsonProperty("offset") final String offset, @JsonProperty("next") final String next) { - this.offset = offset; - this.next = next == null ? null : new UriPage(next); - } - - public Paging(final String next) { - this(null, next); - } - - @JsonIgnore - public String getOffset() { - return offset; - } - - @JsonIgnore - public UriPage getNext() { - return next; - } - - @JsonProperty("next") - public String getNextUri() { - return next == null ? null : next.getPageUri(null).toString(); - } -} diff --git a/src/main/java/com/gooddata/collections/UriPage.java b/src/main/java/com/gooddata/collections/UriPage.java deleted file mode 100644 index 05ca68427..000000000 --- a/src/main/java/com/gooddata/collections/UriPage.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.collections; - -import com.gooddata.util.GoodDataToStringBuilder; -import org.springframework.web.util.UriComponents; -import org.springframework.web.util.UriComponentsBuilder; -import org.springframework.web.util.UriUtils; - -import java.io.UnsupportedEncodingException; -import java.net.URI; -import java.util.List; -import java.util.Map.Entry; - -import static com.gooddata.util.Validate.notNull; - -/** - * {@link Page} implementation wrapping next page link from REST API. - */ -class UriPage implements Page { - - private final UriComponents pageUri; - - /** - * Creates new instance with defined page URI. - * - * @param pageUri page URI - */ - public UriPage(final String pageUri) { - try { - this.pageUri = UriComponentsBuilder.fromUriString(UriUtils.decode(notNull(pageUri, "pageUri"), "UTF-8")).build(); - } catch (final UnsupportedEncodingException e) { - throw new IllegalStateException(e); - } - } - - /** - * This is effectively no-op. Returns internal URI provided by REST API. - * - * @param uriBuilder not used internally, can be null - * @return next page URI provided by REST API - */ - @Override - public URI getPageUri(final UriComponentsBuilder uriBuilder) { - return pageUri.toUri(); - } - - /** - * {@inheritDoc} - *

- * Note that by using this method you might end up with URI that will be different from the one returned by - * {@link #getPageUri(UriComponentsBuilder)}. Method only copies query parameters and does not care about - * URI path. - */ - @Override - public UriComponentsBuilder updateWithPageParams(final UriComponentsBuilder uriBuilder) { - notNull(uriBuilder, "uriBuilder"); - for (Entry> entry : pageUri.getQueryParams().entrySet()) { - uriBuilder.replaceQueryParam(entry.getKey(), entry.getValue().toArray()); - } - return uriBuilder; - } - - @Override - public String toString() { - return GoodDataToStringBuilder.defaultToString(this); - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final UriPage uriPage = (UriPage) o; - - return pageUri != null ? pageUri.equals(uriPage.pageUri) : uriPage.pageUri == null; - } - - @Override - public int hashCode() { - return pageUri != null ? pageUri.hashCode() : 0; - } -} diff --git a/src/main/java/com/gooddata/gdc/ErrorStructure.java b/src/main/java/com/gooddata/gdc/ErrorStructure.java deleted file mode 100644 index 3872e6a92..000000000 --- a/src/main/java/com/gooddata/gdc/ErrorStructure.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.gdc; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -import static com.gooddata.util.Validate.notNull; -import static java.util.Arrays.copyOf; - -/** - * Error structure (for embedding). - * Deserialization only. - */ -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonDeserialize(using = ErrorStructureDeserializer.class) -public class ErrorStructure { - protected final String message; - protected final Object[] parameters; - protected final String component; - protected final String errorClass; - protected final String errorCode; - protected final String errorId; - protected final String trace; - protected final String requestId; - - @JsonCreator - protected ErrorStructure(@JsonProperty("errorClass") String errorClass, @JsonProperty("component") String component, - @JsonProperty("parameters") Object[] parameters, @JsonProperty("message") String message, - @JsonProperty("errorCode") String errorCode, @JsonProperty("errorId") String errorId, - @JsonProperty("trace") String trace, @JsonProperty("requestId") String requestId) { - this.errorClass = errorClass; - this.component = component; - this.parameters = parameters; - this.message = notNull(message, "message"); - this.errorCode = errorCode; - this.errorId = errorId; - this.trace = trace; - this.requestId = requestId; - } - - public String getMessage() { - return message; - } - - public Object[] getParameters() { - return parameters == null ? null : copyOf(parameters, parameters.length); - } - - public String getComponent() { - return component; - } - - public String getErrorClass() { - return errorClass; - } - - public String getErrorCode() { - return errorCode; - } - - public String getErrorId() { - return errorId; - } - - public String getTrace() { - return trace; - } - - public String getRequestId() { - return requestId; - } - - @JsonIgnore - public String getFormattedMessage() { - return message == null ? null : String.format(message, parameters); - } - - @Override - public String toString() { - return getFormattedMessage(); - } -} diff --git a/src/main/java/com/gooddata/gdc/ErrorStructureDeserializer.java b/src/main/java/com/gooddata/gdc/ErrorStructureDeserializer.java deleted file mode 100644 index 27598e0df..000000000 --- a/src/main/java/com/gooddata/gdc/ErrorStructureDeserializer.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.gdc; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.TreeNode; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.fasterxml.jackson.databind.util.TokenBuffer; - -import java.io.IOException; - -/** - * Common deserializer for {@link ErrorStructure} and {@link GdcError}. - */ -class ErrorStructureDeserializer extends JsonDeserializer { - - private static final String GDC_ERROR_TYPE_NAME = "error"; - - @Override - public ErrorStructure deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { - final TokenBuffer tokenBuffer = new TokenBuffer(jp); - tokenBuffer.copyCurrentStructure(jp); - - final TreeNode treeNode = tokenBuffer.asParser().readValueAsTree(); - - Class clazz; - if (treeNode.isObject()) { - if (((ObjectNode) treeNode).has(GDC_ERROR_TYPE_NAME)) { - clazz = GdcError.class; - } else { - clazz = DefaultDeserializerErrorStructure.class; - } - } else { - throw ctxt.mappingException("Unknown type of ErrorStructure"); - } - - final JsonParser nextParser = tokenBuffer.asParser(); - nextParser.nextToken(); // just created parser points before the first token - - return ctxt.readValue(nextParser, clazz); - } - - /** - * This class actually represents deserialized {@link ErrorStructure}. - * We need to override deserializer to break the cycle while deserialize. - */ - @JsonDeserialize(using = None.class) - private static class DefaultDeserializerErrorStructure extends ErrorStructure { - - protected DefaultDeserializerErrorStructure(@JsonProperty("errorClass") String errorClass, - @JsonProperty("component") String component, - @JsonProperty("parameters") Object[] parameters, - @JsonProperty("message") String message, - @JsonProperty("errorCode") String errorCode, - @JsonProperty("errorId") String errorId, - @JsonProperty("trace") String trace, - @JsonProperty("requestId") String requestId) { - super(errorClass, component, parameters, message, errorCode, errorId, trace, requestId); - } - } -} diff --git a/src/main/java/com/gooddata/gdc/GdcError.java b/src/main/java/com/gooddata/gdc/GdcError.java deleted file mode 100644 index 4e77d813b..000000000 --- a/src/main/java/com/gooddata/gdc/GdcError.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.gdc; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.annotation.JsonTypeName; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * GoodData REST API error structure. - * Deserialization only. - */ -@JsonTypeName("error") -@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonDeserialize(using = JsonDeserializer.None.class) -public class GdcError extends ErrorStructure { - - @JsonCreator - private GdcError(@JsonProperty("errorClass") String errorClass, @JsonProperty("component") String component, - @JsonProperty("parameters") String[] parameters, @JsonProperty("message") String message, - @JsonProperty("errorCode") String errorCode, @JsonProperty("errorId") String errorId, - @JsonProperty("trace") String trace, @JsonProperty("requestId") String requestId) { - super(errorClass, component, parameters, message, errorCode, errorId, trace, requestId); - } - -} diff --git a/src/main/java/com/gooddata/util/BooleanDeserializer.java b/src/main/java/com/gooddata/util/BooleanDeserializer.java deleted file mode 100644 index 804a7d466..000000000 --- a/src/main/java/com/gooddata/util/BooleanDeserializer.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import static com.fasterxml.jackson.databind.JsonMappingException.from; -import static com.gooddata.util.Validate.notNull; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; - -import java.io.IOException; - -/** - * Deserializes String or Integer 1 or 0 as boolean - */ -public class BooleanDeserializer extends JsonDeserializer { - - private static final Integer ONE = 1; - - @Override - public Boolean deserialize(JsonParser jp, DeserializationContext ctx) throws IOException { - final JsonNode root = jp.readValueAsTree(); - notNull(root, "jsonNode"); - if (root.isInt()) { - return ONE.equals(root.numberValue()); - } else if (root.isTextual()) { - return "1".equals(root.textValue()); - } else { - throw from(jp, "Unknown value of type: " + root.getNodeType()); - } - } - -} \ No newline at end of file diff --git a/src/main/java/com/gooddata/util/BooleanIntegerSerializer.java b/src/main/java/com/gooddata/util/BooleanIntegerSerializer.java deleted file mode 100644 index 777b7b393..000000000 --- a/src/main/java/com/gooddata/util/BooleanIntegerSerializer.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; - -/** - * Serializes boolean as Integer 1 or 0 - */ -public class BooleanIntegerSerializer extends JsonSerializer { - - @Override - public void serialize(Boolean value, JsonGenerator gen, SerializerProvider arg2) throws IOException { - gen.writeNumber(Boolean.TRUE.equals(value) ? 1 : 0); - } -} \ No newline at end of file diff --git a/src/main/java/com/gooddata/util/BooleanStringSerializer.java b/src/main/java/com/gooddata/util/BooleanStringSerializer.java deleted file mode 100644 index 9c3ff23c2..000000000 --- a/src/main/java/com/gooddata/util/BooleanStringSerializer.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; - -/** - * Serializes boolean as String "1" or "0" - */ -public class BooleanStringSerializer extends JsonSerializer { - - @Override - public void serialize(Boolean value, JsonGenerator gen, SerializerProvider arg2) throws IOException { - gen.writeString(Boolean.TRUE.equals(value) ? "1" : "0"); - } -} \ No newline at end of file diff --git a/src/main/java/com/gooddata/util/GDDateDeserializer.java b/src/main/java/com/gooddata/util/GDDateDeserializer.java deleted file mode 100644 index e7bf368eb..000000000 --- a/src/main/java/com/gooddata/util/GDDateDeserializer.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import org.joda.time.DateTimeZone; -import org.joda.time.LocalDate; -import org.joda.time.format.DateTimeFormatter; -import org.joda.time.format.DateTimeFormatterBuilder; -import org.joda.time.format.ISODateTimeFormat; - -import java.io.IOException; - -/** - * Deserializes to Joda's {@link LocalDate} fields from the GoodData date time format (yyyy-MM-dd). - */ -public class GDDateDeserializer extends JsonDeserializer { - - static final DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder() - .append(ISODateTimeFormat.date()) - .toFormatter().withZone(DateTimeZone.UTC); - - @Override - public LocalDate deserialize(JsonParser jp, DeserializationContext ctx) throws IOException { - final JsonNode root = jp.readValueAsTree(); - if (root == null || root.isNull()) { - return null; - } - return FORMATTER.parseLocalDate(root.textValue()); - } - -} diff --git a/src/main/java/com/gooddata/util/GDDateSerializer.java b/src/main/java/com/gooddata/util/GDDateSerializer.java deleted file mode 100644 index 1e0c906d5..000000000 --- a/src/main/java/com/gooddata/util/GDDateSerializer.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import org.joda.time.LocalDate; - -import java.io.IOException; - -import static com.gooddata.util.GDDateDeserializer.FORMATTER; - -/** - * Serializes from Joda's {@link LocalDate} fields to the GoodData date time format (yyyy-MM-dd). - */ -public class GDDateSerializer extends JsonSerializer { - - @Override - public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider arg2) throws IOException { - gen.writeString(FORMATTER.print(value)); - } - -} diff --git a/src/main/java/com/gooddata/util/GDDateTimeDeserializer.java b/src/main/java/com/gooddata/util/GDDateTimeDeserializer.java deleted file mode 100644 index 1ac4230e8..000000000 --- a/src/main/java/com/gooddata/util/GDDateTimeDeserializer.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import org.joda.time.DateTime; - -import java.io.IOException; - -import static com.gooddata.util.GDDateTimeSerializer.FORMATTER; - -/** - * Deserializes Joda's {@link DateTime} fields from the GoodData date time format in the UTC timezone (yyyy-MM-dd HH:mm:ss.SSSZ). - */ -public class GDDateTimeDeserializer extends JsonDeserializer { - - @Override - public DateTime deserialize(JsonParser jp, DeserializationContext ctx) throws IOException { - final JsonNode root = jp.readValueAsTree(); - if (root == null || root.isNull()) { - return null; - } - return FORMATTER.parseDateTime(root.textValue()); - } -} diff --git a/src/main/java/com/gooddata/util/GDDateTimeSerializer.java b/src/main/java/com/gooddata/util/GDDateTimeSerializer.java deleted file mode 100644 index 537070dbc..000000000 --- a/src/main/java/com/gooddata/util/GDDateTimeSerializer.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormatter; -import org.joda.time.format.DateTimeFormatterBuilder; -import org.joda.time.format.ISODateTimeFormat; - -import java.io.IOException; - -/** - * Serializes Joda's {@link DateTime} fields to the GoodDate date time format in the UTC timezone (yyyy-MM-dd HH:mm:ss.SSSZ). - */ -public class GDDateTimeSerializer extends JsonSerializer { - - static final DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder() - .append(ISODateTimeFormat.date()) - .appendLiteral(' ') - .append(ISODateTimeFormat.hourMinuteSecond()) - .toFormatter().withZone(DateTimeZone.UTC); - - @Override - public void serialize(DateTime value, JsonGenerator gen, SerializerProvider arg2) throws IOException { - gen.writeString(FORMATTER.print(value)); - } - -} diff --git a/src/main/java/com/gooddata/util/ISODateTimeDeserializer.java b/src/main/java/com/gooddata/util/ISODateTimeDeserializer.java deleted file mode 100644 index 2f0af106a..000000000 --- a/src/main/java/com/gooddata/util/ISODateTimeDeserializer.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import java.io.IOException; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import org.joda.time.DateTime; - -import static com.gooddata.util.ISODateTimeSerializer.FORMATTER; - -/** - * Deserializes Joda's {@link DateTime} fields from the ISO date time format in the UTC timezone (yyyy-MM-dd'T'HH:mm:ss.SSSZZ). - */ -public class ISODateTimeDeserializer extends JsonDeserializer { - - @Override - public DateTime deserialize(JsonParser jp, DeserializationContext ctx) throws IOException { - final JsonNode root = jp.readValueAsTree(); - if (root == null || root.isNull()) { - return null; - } - return FORMATTER.parseDateTime(root.textValue()); - } - -} \ No newline at end of file diff --git a/src/main/java/com/gooddata/util/ISODateTimeSerializer.java b/src/main/java/com/gooddata/util/ISODateTimeSerializer.java deleted file mode 100644 index e6ad92a7e..000000000 --- a/src/main/java/com/gooddata/util/ISODateTimeSerializer.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormatter; -import org.joda.time.format.ISODateTimeFormat; - -import java.io.IOException; - -/** - * Serializes Joda's {@link DateTime} fields to the ISO date time format in the UTC timezone (yyyy-MM-dd'T'HH:mm:ss.SSSZZ). - */ -public class ISODateTimeSerializer extends JsonSerializer { - - static final DateTimeFormatter FORMATTER = ISODateTimeFormat.dateTime().withZone(DateTimeZone.UTC); - - @Override - public void serialize(DateTime value, JsonGenerator gen, SerializerProvider arg2) throws IOException { - gen.writeString(FORMATTER.print(value)); - } -} \ No newline at end of file diff --git a/src/main/java/com/gooddata/util/Validate.java b/src/main/java/com/gooddata/util/Validate.java deleted file mode 100644 index d644ab7d7..000000000 --- a/src/main/java/com/gooddata/util/Validate.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import java.util.Collection; -import java.util.Iterator; - -/** - * Argument validation helper methods used internally by GoodData SDK. - */ -public abstract class Validate { - - /** - * Throws IllegalArgumentException if the value is null, otherwise returns the value. - * - * @param value input value - * @param argumentName the name of input argument - * @param the type of the argument - * @return the value - */ - public static T notNull(T value, String argumentName) { - if (value == null) { - throw new IllegalArgumentException(argumentName + " can't be null"); - } - return value; - } - - /** - * Throws IllegalArgumentException if the char sequence is empty, otherwise returns the char sequence. - * - * @param value input char sequence - * @param argumentName the name of input argument - * @param the type of char sequence - * @return the char sequence - */ - public static T notEmpty(T value, String argumentName) { - notNull(value, argumentName); - if (value.toString().trim().length() == 0) { - throw new IllegalArgumentException(argumentName + " can't be empty"); - } - return value; - } - - /** - * Throws IllegalArgumentException if the map is empty, otherwise returns the map. - * - * @param value input collection - * @param argumentName the name of the input argument - * @param the type of map - * @return map - */ - public static T notEmpty(T value, String argumentName) { - notNull(value, argumentName); - if (value.size() == 0) { - throw new IllegalArgumentException(argumentName + " can't be empty"); - } - return value; - } - - /** - * Throws IllegalArgumentException if the collection contains null elements (or is null), otherwise returns - * the collection. - * - * @param collection input collection - * @param argumentName the name of input argument - * @param the type of the collection - * @return the collection - */ - public static T noNullElements(T collection, String argumentName) { - notNull(collection, argumentName); - int i = 0; - for (Iterator it = collection.iterator(); it.hasNext(); i++) { - if (it.next() == null) { - throw new IllegalArgumentException(argumentName + " contains null element at index: " + i); - } - } - return collection; - } - - public static T[] noNullElements(T[] array, String argument) { - notNull(array, argument); - for (int i = 0; i < array.length; i++) { - if (array[i] == null) { - throw new IllegalArgumentException(argument + " contains null element at index: " + i); - } - } - return array; - } - - /** - * Throws IllegalStateException if the value is null, otherwise returns the value. - * - * @param value input value - * @param argumentName the name of input argument - * @param the type of the argument - * @return the value - */ - public static T notNullState(T value, String argumentName) { - if (value == null) { - throw new IllegalStateException(argumentName + " is null"); - } - return value; - } - - /** - * throws new {@link IllegalArgumentException} if expression is false - * - * @param expression boolean expression - * @param message of exception - */ - public static void isTrue(boolean expression, String message) { - if (!expression) { - throw new IllegalArgumentException(message); - } - } -} diff --git a/src/test/java/com/gooddata/GoodDataRestExceptionTest.java b/src/test/java/com/gooddata/GoodDataRestExceptionTest.java deleted file mode 100644 index 9268a55b4..000000000 --- a/src/test/java/com/gooddata/GoodDataRestExceptionTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata; - -import com.gooddata.gdc.GdcError; -import org.testng.annotations.Test; - -import static com.gooddata.util.ResourceUtils.readObjectFromResource; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.MatcherAssert.assertThat; - -public class GoodDataRestExceptionTest { - @Test - public void shouldCreateDefaultInstance() throws Exception { - final GoodDataRestException e = new GoodDataRestException(500, "a123", "message", "component", "gdc.error", "code"); - assertThat(e.getMessage(), is("500: [requestId=a123] message")); - assertThat(e.getStatusCode(), is(500)); - assertThat(e.getRequestId(), is("a123")); - assertThat(e.getText(), is("message")); - assertThat(e.getComponent(), is("component")); - assertThat(e.getErrorClass(), is("gdc.error")); - assertThat(e.getErrorCode(), is("code")); - } - - @Test - public void shouldCreateDefaultInstanceWithoutErrorCode() throws Exception { - final GoodDataRestException e = new GoodDataRestException(500, "a123", "message", "component", "gdc.error"); - assertThat(e.getMessage(), is("500: [requestId=a123] message")); - assertThat(e.getStatusCode(), is(500)); - assertThat(e.getRequestId(), is("a123")); - assertThat(e.getText(), is("message")); - assertThat(e.getComponent(), is("component")); - assertThat(e.getErrorClass(), is("gdc.error")); - } - - @Test - public void shouldCreateInstanceWithoutRequestId() throws Exception { - final GoodDataRestException e = new GoodDataRestException(500, null, "message", "component", "gdc.error"); - assertThat(e.getMessage(), is("500: message")); - assertThat(e.getStatusCode(), is(500)); - assertThat(e.getText(), is("message")); - assertThat(e.getComponent(), is("component")); - assertThat(e.getErrorClass(), is("gdc.error")); - } - - @Test - public void shouldCreateInstanceWithNullGdcError() throws Exception { - final GoodDataRestException e = new GoodDataRestException(500, "a123", "message", null); - assertThat(e.getMessage(), is("500: [requestId=a123] message")); - assertThat(e.getStatusCode(), is(500)); - assertThat(e.getRequestId(), is("a123")); - assertThat(e.getText(), is("message")); - } - - @Test - public void shouldCreateInstanceWithNullStatusAndGdcError() throws Exception { - final GoodDataRestException e = new GoodDataRestException(500, "a123", null, null); - assertThat(e.getMessage(), is("500: [requestId=a123] Unknown error")); - assertThat(e.getStatusCode(), is(500)); - assertThat(e.getRequestId(), is("a123")); - assertThat(e.getText(), is(nullValue())); - } - - @Test - public void shouldCreateInstanceWithGdcError() throws Exception { - final GdcError err = readObjectFromResource("/gdc/gdcError.json", GdcError.class); - - final GoodDataRestException e = new GoodDataRestException(500, "a123", "message", err); - assertThat(e.getMessage(), is("500: [requestId=REQ] MSG")); - assertThat(e.getStatusCode(), is(500)); - assertThat(e.getText(), is("MSG")); - assertThat(e.getErrorClass(), is("CLASS")); - assertThat(e.getComponent(), is("COMPONENT")); - assertThat(e.getRequestId(), is("REQ")); - assertThat(e.getErrorCode(), is("CODE")); - } -} diff --git a/src/test/java/com/gooddata/UriPrefixerTest.java b/src/test/java/com/gooddata/UriPrefixerTest.java deleted file mode 100644 index da4d5ae6b..000000000 --- a/src/test/java/com/gooddata/UriPrefixerTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata; - -import org.springframework.web.util.UriComponentsBuilder; -import org.testng.annotations.Test; - -import java.net.URI; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; - -public class UriPrefixerTest { - - @Test - public void testMergeUrisWithSlash() throws Exception { - final UriPrefixer prefixer = new UriPrefixer("http://localhost:1/uploads"); - final URI result = prefixer.mergeUris("/test"); - assertThat(result.toString(), is("http://localhost:1/uploads/test")); - } - - @Test - public void testMergeUrisWithSlashes() throws Exception { - final UriPrefixer prefixer = new UriPrefixer("http://localhost:1/uploads/"); - final URI result = prefixer.mergeUris("/test"); - assertThat(result.toString(), is("http://localhost:1/uploads/test")); - } - - @Test - public void testMergeUrisWithAllSlashes() throws Exception { - final UriPrefixer prefixer = new UriPrefixer("http://localhost:1/uploads/"); - final URI result = prefixer.mergeUris("/test/"); - assertThat(result.toString(), is("http://localhost:1/uploads/test/")); - } - - @Test - public void testMergeUrisWithoutSlash() throws Exception { - final UriPrefixer prefixer = new UriPrefixer("http://localhost:1/uploads/"); - final URI result = prefixer.mergeUris("test"); - assertThat(result.toString(), is("http://localhost:1/uploads/test")); - } - - @Test - public void testMergeUrisWithoutSlashes() throws Exception { - final UriPrefixer prefixer = new UriPrefixer("http://localhost:1/uploads"); - final URI result = prefixer.mergeUris("test"); - assertThat(result.toString(), is("http://localhost:1/uploads/test")); - } - - @Test - public void shouldNotDoubleEncodeQueryParam() throws Exception { - final UriPrefixer prefixer = new UriPrefixer("http://localhost:1/uploads"); - - final URI uri = UriComponentsBuilder.fromPath("/foo") - .queryParam("bar", "\n") // some crazy value which needs encoding - .build() - .toUri(); - - final URI result = prefixer.mergeUris(uri); - assertThat(result.toString(), is("http://localhost:1/uploads/foo?bar=%0A")); - } - - @Test - public void shouldName() throws Exception { - final UriPrefixer prefixer = new UriPrefixer("https://localhost:1"); - final URI result = prefixer.mergeUris("http://localhost:1/uploads/test/"); - assertThat(result.toString(), is("https://localhost:1/uploads/test/")); - } -} \ No newline at end of file diff --git a/src/test/java/com/gooddata/collections/PageRequestTest.java b/src/test/java/com/gooddata/collections/PageRequestTest.java deleted file mode 100644 index eab5c50ed..000000000 --- a/src/test/java/com/gooddata/collections/PageRequestTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.collections; - -import org.springframework.web.util.UriComponentsBuilder; -import org.testng.annotations.Test; - -import java.net.URI; - -import static com.gooddata.collections.PageRequest.DEFAULT_LIMIT; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.core.Is.is; - -public class PageRequestTest { - - @Test - public void testGetPageUri() throws Exception { - final PageRequest pageRequest = new PageRequest(12, 10); - final UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString("test_uri"); - final URI pageUri = pageRequest.getPageUri(uriBuilder); - assertThat(pageUri, notNullValue()); - assertThat(pageUri.toString(), is("test_uri?offset=12&limit=10")); - } - - @Test - public void testGetPageUriWithStringOffset() throws Exception { - final PageRequest pageRequest = new PageRequest("17", 10); - final UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString("test_uri"); - final URI pageUri = pageRequest.getPageUri(uriBuilder); - assertThat(pageUri, notNullValue()); - assertThat(pageUri.toString(), is("test_uri?offset=17&limit=10")); - } - - @Test - public void testUpdateWithPageParams() throws Exception { - final PageRequest pageRequest = new PageRequest(12, 10); - final UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString("test_uri/{test}"); - final String pageUri = pageRequest.updateWithPageParams(uriBuilder).build().toUriString(); - assertThat(pageUri, is("test_uri/{test}?offset=12&limit=10")); - } - - @Test - public void testUpdateWithPageParamsWithStringOffset() throws Exception { - final PageRequest pageRequest = new PageRequest("17", 10); - final UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString("test_uri/{test}"); - final String pageUri = pageRequest.updateWithPageParams(uriBuilder).build().toUriString(); - assertThat(pageUri, is("test_uri/{test}?offset=17&limit=10")); - } - - @Test - public void testUpdateWithPageParamsIdempotency() throws Exception { - final PageRequest pageRequest = new PageRequest(12, 10); - final UriComponentsBuilder uriBuilder1 = UriComponentsBuilder.fromUriString("test_uri/{test}"); - final UriComponentsBuilder uriBuilder2 = pageRequest.updateWithPageParams(uriBuilder1); - final UriComponentsBuilder uriBuilder3 = pageRequest.updateWithPageParams(uriBuilder2); - final String pageUri = uriBuilder3.build().toUriString(); - assertThat(pageUri, is("test_uri/{test}?offset=12&limit=10")); - } - - @Test - public void testGetPageUriDefaultValue() throws Exception { - final PageRequest pageRequest = new PageRequest(); - final UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString("test_uri"); - final URI pageUri = pageRequest.getPageUri(uriBuilder); - assertThat(pageUri, notNullValue()); - assertThat(pageUri.toString(), is("test_uri?limit=100")); - } - - @Test - public void testGetSanitizedLimit() throws Exception { - final PageRequest pageRequest = new PageRequest(); - pageRequest.setLimit(-2); - assertThat(pageRequest.getSanitizedLimit(), is(DEFAULT_LIMIT)); - } - - @Test - public void shouldReturnDefaultForZero() throws Exception { - final PageRequest pageRequest = new PageRequest(0); - assertThat(pageRequest.getSanitizedLimit(), is(DEFAULT_LIMIT)); - } - - @Test - public void shouldReturnMaxForSanitizedLimit() throws Exception { - final PageRequest pageRequest = new PageRequest(100); - assertThat(pageRequest.getSanitizedLimit(10), is(10)); - } - - @Test - public void equals() { - assertThat(new PageRequest(), is(not(new PageRequest(10)))); - - assertThat(new PageRequest(10), is(new PageRequest(10))); - assertThat(new PageRequest(10), is(not(new PageRequest(11)))); - - assertThat(new PageRequest(1, 2), is(new PageRequest(1, 2))); - assertThat(new PageRequest(1, 2), is(new PageRequest("1", 2))); - assertThat(new PageRequest(1, 2), is(not(new PageRequest("meh", 2)))); - assertThat(new PageRequest(1, 2), is(not(new PageRequest("1", 3)))); - } - - @Test - public void testToString() { - assertThat(new PageRequest(1, 2).toString(), is("PageRequest[offset=1,limit=2]")); - } -} diff --git a/src/test/java/com/gooddata/collections/PageableListTest.java b/src/test/java/com/gooddata/collections/PageableListTest.java deleted file mode 100644 index 4fc58e62f..000000000 --- a/src/test/java/com/gooddata/collections/PageableListTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.collections; - -import org.testng.annotations.Test; - -import java.util.Collections; - -import static java.util.Arrays.asList; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.empty; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.core.Is.is; -import static org.hamcrest.core.IsNot.not; - -public class PageableListTest { - - @Test - public void testCollectionEmpty() { - final PageableList collection = new PageableList<>(); - assertThat(collection, notNullValue()); - assertThat(collection, empty()); - assertThat(collection.getNextPage(), nullValue()); - } - - @Test - public void testCollection() { - final PageableList collection = new PageableList<>(asList(1, 2, 3), null); - assertThat(collection, notNullValue()); - assertThat(collection, hasSize(3)); - assertThat(collection.getNextPage(), nullValue()); - assertThat(collection.getCurrentPageItems(), is(asList(1, 2, 3))); - assertThat(collection.collectAll(), is(asList(1, 2, 3))); - } - - @Test - public void testCollectionWithPaging() { - final PageableList collection = new PageableList<>(asList(1, 2, 3), new Paging("1", "next")); - assertThat(collection, notNullValue()); - assertThat(collection, hasSize(3)); - assertThat(collection.getNextPage(), notNullValue()); - assertThat(collection.getNextPage().getPageUri(null).toString(), is("next")); - } - - @Test - public void testEquals() { - assertThat(new PageableList<>(), is(new PageableList<>())); - assertThat(new PageableList<>(Collections.singletonList(1), null), is(not(new PageableList<>()))); - } - - - @Test - public void testHashCode() { - assertThat(new PageableList<>().hashCode(), is(new PageableList<>().hashCode())); - assertThat(new PageableList<>(Collections.singletonList(1), null).hashCode(), is(not(new PageableList<>().hashCode()))); - } - -} diff --git a/src/test/java/com/gooddata/collections/PagingTest.java b/src/test/java/com/gooddata/collections/PagingTest.java deleted file mode 100644 index b14e5804d..000000000 --- a/src/test/java/com/gooddata/collections/PagingTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.collections; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.testng.annotations.Test; - -import java.io.InputStream; - -import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals; -import static net.javacrumbs.jsonunit.core.util.ResourceUtils.resource; -import static com.gooddata.util.ResourceUtils.readObjectFromResource; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.core.Is.is; - -public class PagingTest { - - @Test - public void testDeserialization() throws Exception { - final Paging paging = readObjectFromResource("/collections/paging.json", Paging.class); - - assertThat(paging.getOffset(), is("0")); - assertThat(paging.getNext(), notNullValue()); - assertThat(paging.getNext().getPageUri(null).toString(), is("next")); - } - - @Test - public void testDeserializationNullNext() throws Exception { - final Paging paging = readObjectFromResource("/collections/paging_no_next.json", Paging.class); - - assertThat(paging.getOffset(), is("0")); - assertThat(paging.getNext(), nullValue()); - } - - @Test - public void testDeserializationWithNextOnly() throws Exception { - final Paging paging = readObjectFromResource("/collections/paging_only_next.json", Paging.class); - - assertThat(paging.getOffset(), is(nullValue())); - assertThat(paging.getNext(), notNullValue()); - assertThat(paging.getNext().getPageUri(null).toString(), is("/nextUri?offset=17")); - } - - @Test - public void testSerialization() throws Exception { - final Paging paging = new Paging("/nextUri?offset=17"); - assertThat(paging, jsonEquals(resource("collections/paging_only_next.json"))); - } - -} \ No newline at end of file diff --git a/src/test/java/com/gooddata/collections/UriPageTest.java b/src/test/java/com/gooddata/collections/UriPageTest.java deleted file mode 100644 index eb7132c82..000000000 --- a/src/test/java/com/gooddata/collections/UriPageTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.collections; - -import org.hamcrest.core.Is; -import org.springframework.web.util.UriComponents; -import org.springframework.web.util.UriComponentsBuilder; -import org.testng.annotations.Test; - -import static java.util.Collections.singletonList; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasEntry; -import static org.hamcrest.Matchers.not; -import static org.springframework.web.util.UriComponentsBuilder.fromUriString; - -public class UriPageTest { - - @Test( - expectedExceptions = IllegalArgumentException.class, - expectedExceptionsMessageRegExp = ".*pageUri can't be null.*" - ) - public void testNullConstructorArgument() { - new UriPage(null); - } - - @Test - public void testGetPageUri() throws Exception { - final UriPage uri = new UriPage("uri"); - assertThat(uri.getPageUri(null).toString(), is("uri")); - } - - @Test - public void test() throws Exception { - final UriPage uri = new UriPage("uri?offset=god&limit=10"); - final UriComponentsBuilder builder = fromUriString("/this/is/{template}").query("other=false"); - - uri.updateWithPageParams(builder); - - final UriComponents components = builder.build(); - assertThat(components, is(notNullValue())); - assertThat(components.getPath(), is("/this/is/{template}")); - assertThat(components.getQueryParams(), hasEntry("other", singletonList("false"))); - assertThat(components.getQueryParams(), hasEntry("offset", singletonList("god"))); - assertThat(components.getQueryParams(), hasEntry("limit", singletonList("10"))); - } - - @Test - public void testIdempotency() throws Exception { - final UriPage uri = new UriPage("uri?offset=god&limit=10"); - final UriComponentsBuilder builder = fromUriString("/this/is/{template}").query("other=false"); - - uri.updateWithPageParams(builder); - uri.updateWithPageParams(builder); - uri.updateWithPageParams(builder); - - final UriComponents components = builder.build(); - assertThat(components, is(notNullValue())); - assertThat(components.getPath(), is("/this/is/{template}")); - assertThat(components.getQueryParams(), hasEntry("other", singletonList("false"))); - assertThat(components.getQueryParams(), hasEntry("offset", singletonList("god"))); - assertThat(components.getQueryParams(), hasEntry("limit", singletonList("10"))); - } - - @Test - public void testEncoding() throws Exception { - final UriPage uri = new UriPage("uri?test=foo%20bar"); - assertThat(uri.getPageUri(null).toString(), is("uri?test=foo%20bar")); - } - - @Test - public void equals() { - assertThat(new UriPage("meh"), is(new UriPage("meh"))); - assertThat(new UriPage("meh"), is(not(new UriPage("mah")))); - } - - - @Test - public void testToString() { - assertThat(new UriPage("abc").toString(), Is.is("UriPage[pageUri=abc]")); - } -} diff --git a/src/test/java/com/gooddata/gdc/ErrorStructureTest.java b/src/test/java/com/gooddata/gdc/ErrorStructureTest.java deleted file mode 100644 index 7162857a0..000000000 --- a/src/test/java/com/gooddata/gdc/ErrorStructureTest.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.gdc; - -import org.testng.annotations.Test; - -import static com.gooddata.util.ResourceUtils.readObjectFromResource; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.MatcherAssert.assertThat; - -public class ErrorStructureTest { - - @Test - public void testDeserialization() throws Exception { - final ErrorStructure errStructure = readObjectFromResource("/gdc/errorStructure.json", ErrorStructure.class); - - assertThat(errStructure, is(notNullValue())); - assertThat(errStructure.getErrorClass(), is("CLASS")); - assertThat(errStructure.getTrace(), is("TRACE")); - assertThat(errStructure.getMessage(), is("MSG %s %s %d")); - assertThat(errStructure.getComponent(), is("COMPONENT")); - assertThat(errStructure.getErrorId(), is("ID")); - assertThat(errStructure.getErrorCode(), is("CODE")); - assertThat(errStructure.getRequestId(), is("REQ")); - - assertThat(errStructure.getParameters(), is(notNullValue())); - assertThat(errStructure.getParameters().length, is(3)); - assertThat(errStructure.getParameters()[0].toString(), is("PARAM1")); - assertThat(errStructure.getParameters()[1].toString(), is("PARAM2")); - assertThat(errStructure.getParameters()[2].toString(), is("3")); - - assertThat(errStructure.getFormattedMessage(), is("MSG PARAM1 PARAM2 3")); - } -} \ No newline at end of file diff --git a/src/test/java/com/gooddata/gdc/GdcErrorTest.java b/src/test/java/com/gooddata/gdc/GdcErrorTest.java deleted file mode 100644 index 3f117dca0..000000000 --- a/src/test/java/com/gooddata/gdc/GdcErrorTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.gdc; - -import org.testng.annotations.Test; - -import static com.gooddata.util.ResourceUtils.readObjectFromResource; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.MatcherAssert.assertThat; - -public class GdcErrorTest { - - @Test - public void testDeserialization() throws Exception { - final GdcError err = readObjectFromResource("/gdc/gdcError.json", GdcError.class); - - assertThat(err, is(notNullValue())); - assertThat(err.getErrorClass(), is("CLASS")); - assertThat(err.getTrace(), is("TRACE")); - assertThat(err.getMessage(), is("MSG")); - assertThat(err.getComponent(), is("COMPONENT")); - assertThat(err.getErrorId(), is("ID")); - assertThat(err.getErrorCode(), is("CODE")); - assertThat(err.getRequestId(), is("REQ")); - - assertThat(err.getParameters(), is(notNullValue())); - assertThat(err.getParameters().length, is(2)); - assertThat(err.getParameters()[0].toString(), is("PARAM1")); - assertThat(err.getParameters()[1].toString(), is("PARAM2")); - } -} \ No newline at end of file diff --git a/src/test/java/com/gooddata/util/BooleanDeserializerTest.java b/src/test/java/com/gooddata/util/BooleanDeserializerTest.java deleted file mode 100644 index 5bad53053..000000000 --- a/src/test/java/com/gooddata/util/BooleanDeserializerTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.testng.annotations.Test; - -import static com.gooddata.util.ResourceUtils.OBJECT_MAPPER; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - -public class BooleanDeserializerTest { - - @Test - public void shouldDeserializeIntegerTrue() throws Exception { - final String json = OBJECT_MAPPER.writeValueAsString(new BooleanIntegerClass(true)); - - final JsonNode node = OBJECT_MAPPER.readTree(json); - assertThat(node.path("foo").numberValue().intValue(), is(1)); - - final BooleanIntegerClass moo = OBJECT_MAPPER.readValue(json, BooleanIntegerClass.class); - assertThat(moo.isFoo(), is(true)); - } - - @Test - public void shouldDeserializeIntegerFalse() throws Exception { - final String json = OBJECT_MAPPER.writeValueAsString(new BooleanIntegerClass(false)); - - final JsonNode node = OBJECT_MAPPER.readTree(json); - assertThat(node.path("foo").numberValue().intValue(), is(0)); - - final BooleanIntegerClass moo = OBJECT_MAPPER.readValue(json, BooleanIntegerClass.class); - assertThat(moo.isFoo(), is(false)); - } - - @Test - public void shouldDeserializeStringTrue() throws Exception { - final String json = OBJECT_MAPPER.writeValueAsString(new BooleanStringClass(true)); - - final JsonNode node = OBJECT_MAPPER.readTree(json); - assertThat(node.path("foo").textValue(), is("1")); - - final BooleanStringClass moo = OBJECT_MAPPER.readValue(json, BooleanStringClass.class); - assertThat(moo.isFoo(), is(true)); - } - - @Test - public void shouldDeserializeStringFalse() throws Exception { - final String json = OBJECT_MAPPER.writeValueAsString(new BooleanStringClass(false)); - - final JsonNode node = OBJECT_MAPPER.readTree(json); - assertThat(node.path("foo").textValue(), is("0")); - - final BooleanStringClass moo = OBJECT_MAPPER.readValue(json, BooleanStringClass.class); - assertThat(moo.isFoo(), is(false)); - } - -} \ No newline at end of file diff --git a/src/test/java/com/gooddata/util/BooleanIntegerClass.java b/src/test/java/com/gooddata/util/BooleanIntegerClass.java deleted file mode 100644 index b2d92b081..000000000 --- a/src/test/java/com/gooddata/util/BooleanIntegerClass.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - -public class BooleanIntegerClass { - private final boolean foo; - - @JsonCreator - public BooleanIntegerClass(@JsonProperty("foo") @JsonDeserialize(using = BooleanDeserializer.class) final boolean foo) { - this.foo = foo; - } - - @JsonSerialize(using = BooleanIntegerSerializer.class) - public boolean isFoo() { - return foo; - } -} diff --git a/src/test/java/com/gooddata/util/BooleanIntegerSerializerTest.java b/src/test/java/com/gooddata/util/BooleanIntegerSerializerTest.java deleted file mode 100644 index 79b3f1cfb..000000000 --- a/src/test/java/com/gooddata/util/BooleanIntegerSerializerTest.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.databind.JsonNode; -import org.testng.annotations.Test; - -import static com.gooddata.util.ResourceUtils.OBJECT_MAPPER; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - -public class BooleanIntegerSerializerTest { - - @Test - public void shouldSerializeTrue() throws Exception { - final String json = OBJECT_MAPPER.writeValueAsString(new BooleanIntegerClass(true)); - - final JsonNode node = OBJECT_MAPPER.readTree(json); - assertThat(node.path("foo").numberValue().intValue(), is(1)); - } - - @Test - public void shouldSerializeFalse() throws Exception { - final String json = OBJECT_MAPPER.writeValueAsString(new BooleanIntegerClass(false)); - - final JsonNode node = OBJECT_MAPPER.readTree(json); - assertThat(node.path("foo").numberValue().intValue(), is(0)); - } -} \ No newline at end of file diff --git a/src/test/java/com/gooddata/util/BooleanStringClass.java b/src/test/java/com/gooddata/util/BooleanStringClass.java deleted file mode 100644 index c1c192645..000000000 --- a/src/test/java/com/gooddata/util/BooleanStringClass.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - -public class BooleanStringClass { - private final boolean foo; - - @JsonCreator - public BooleanStringClass(@JsonProperty("foo") @JsonDeserialize(using = BooleanDeserializer.class) final boolean foo) { - this.foo = foo; - } - - @JsonSerialize(using = BooleanStringSerializer.class) - public boolean isFoo() { - return foo; - } -} diff --git a/src/test/java/com/gooddata/util/BooleanStringSerializerTest.java b/src/test/java/com/gooddata/util/BooleanStringSerializerTest.java deleted file mode 100644 index 7ec489f64..000000000 --- a/src/test/java/com/gooddata/util/BooleanStringSerializerTest.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.databind.JsonNode; -import org.testng.annotations.Test; - -import static com.gooddata.util.ResourceUtils.OBJECT_MAPPER; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - -public class BooleanStringSerializerTest { - - @Test - public void shouldSerializeTrue() throws Exception { - final String json = OBJECT_MAPPER.writeValueAsString(new BooleanStringClass(true)); - - final JsonNode node = OBJECT_MAPPER.readTree(json); - assertThat(node.path("foo").textValue(), is("1")); - } - - @Test - public void shouldSerializeFalse() throws Exception { - final String json = OBJECT_MAPPER.writeValueAsString(new BooleanStringClass(false)); - - final JsonNode node = OBJECT_MAPPER.readTree(json); - assertThat(node.path("foo").textValue(), is("0")); - } -} \ No newline at end of file diff --git a/src/test/java/com/gooddata/util/GDDateClass.java b/src/test/java/com/gooddata/util/GDDateClass.java deleted file mode 100644 index 4e687d86b..000000000 --- a/src/test/java/com/gooddata/util/GDDateClass.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import org.joda.time.LocalDate; - -public class GDDateClass { - private final LocalDate date; - - @JsonCreator - public GDDateClass(@JsonProperty("date") @JsonDeserialize(using = GDDateDeserializer.class) final LocalDate date) { - this.date = date; - } - - @JsonSerialize(using = GDDateSerializer.class) - public LocalDate getDate() { - return date; - } - -} diff --git a/src/test/java/com/gooddata/util/GDDateDeserializerTest.java b/src/test/java/com/gooddata/util/GDDateDeserializerTest.java deleted file mode 100644 index 5bc8d2fb9..000000000 --- a/src/test/java/com/gooddata/util/GDDateDeserializerTest.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.joda.time.LocalDate; -import org.testng.annotations.Test; - -import static com.gooddata.util.ResourceUtils.OBJECT_MAPPER; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - -public class GDDateDeserializerTest { - - @Test - public void testDeserialize() throws Exception { - final String json = OBJECT_MAPPER.writeValueAsString(new GDDateClass(new LocalDate(2012, 3, 20))); - - final JsonNode node = OBJECT_MAPPER.readTree(json); - assertThat(node.path("date").textValue(), is("2012-03-20")); - - final GDDateClass date = OBJECT_MAPPER.readValue(json, GDDateClass.class); - assertThat(date.getDate(), is(new LocalDate(2012, 3, 20))); - } - - -} diff --git a/src/test/java/com/gooddata/util/GDDateSerializerTest.java b/src/test/java/com/gooddata/util/GDDateSerializerTest.java deleted file mode 100644 index c1b312cc2..000000000 --- a/src/test/java/com/gooddata/util/GDDateSerializerTest.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.databind.JsonNode; -import org.joda.time.LocalDate; -import org.testng.annotations.Test; - -import static com.gooddata.util.ResourceUtils.OBJECT_MAPPER; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - -public class GDDateSerializerTest { - - @Test - public void testSerialize() throws Exception { - final GDDateClass foo = new GDDateClass(new LocalDate(2012, 3, 20)); - final String json = OBJECT_MAPPER.writeValueAsString(foo); - final JsonNode node = OBJECT_MAPPER.readTree(json); - - assertThat(node.path("date").textValue(), is("2012-03-20")); - } -} diff --git a/src/test/java/com/gooddata/util/GDDateTimeClass.java b/src/test/java/com/gooddata/util/GDDateTimeClass.java deleted file mode 100644 index 548f43333..000000000 --- a/src/test/java/com/gooddata/util/GDDateTimeClass.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import org.joda.time.DateTime; - -class GDDateTimeClass { - - private final DateTime date; - - @JsonCreator - public GDDateTimeClass(@JsonProperty("date") @JsonDeserialize(using = GDDateTimeDeserializer.class) final DateTime date) { - this.date = date; - } - - @JsonSerialize(using = GDDateTimeSerializer.class) - public DateTime getDate() { - return date; - } -} diff --git a/src/test/java/com/gooddata/util/GDDateTimeDeserializerTest.java b/src/test/java/com/gooddata/util/GDDateTimeDeserializerTest.java deleted file mode 100644 index 05660f096..000000000 --- a/src/test/java/com/gooddata/util/GDDateTimeDeserializerTest.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.databind.JsonNode; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.testng.annotations.Test; - -import static com.gooddata.util.ResourceUtils.OBJECT_MAPPER; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - -public class GDDateTimeDeserializerTest { - - @Test - public void testDeserialize() throws Exception { - final String json = OBJECT_MAPPER.writeValueAsString(new GDDateTimeClass(new DateTime(2012, 3, 20, 14, 31, 5, 3, DateTimeZone.UTC))); - - final JsonNode node = OBJECT_MAPPER.readTree(json); - assertThat(node.path("date").textValue(), is("2012-03-20 14:31:05")); - - final GDDateTimeClass date = OBJECT_MAPPER.readValue(json, GDDateTimeClass.class); - assertThat(date.getDate(), is(new DateTime(2012, 3, 20, 14, 31, 5, DateTimeZone.UTC))); - } -} diff --git a/src/test/java/com/gooddata/util/GDDateTimeSerializerTest.java b/src/test/java/com/gooddata/util/GDDateTimeSerializerTest.java deleted file mode 100644 index 213e5b0d4..000000000 --- a/src/test/java/com/gooddata/util/GDDateTimeSerializerTest.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.databind.JsonNode; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.testng.annotations.Test; - -import static com.gooddata.util.ResourceUtils.OBJECT_MAPPER; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - -public class GDDateTimeSerializerTest { - - @Test - public void testSerialize() throws Exception { - final GDDateTimeClass foo = new GDDateTimeClass(new DateTime(2012, 3, 20, 14, 31, 5, 3, DateTimeZone.UTC)); - final String json = OBJECT_MAPPER.writeValueAsString(foo); - final JsonNode node = OBJECT_MAPPER.readTree(json); - - assertThat(node.path("date").textValue(), is("2012-03-20 14:31:05")); - } -} \ No newline at end of file diff --git a/src/test/java/com/gooddata/util/ISODateClass.java b/src/test/java/com/gooddata/util/ISODateClass.java deleted file mode 100644 index ff65ea1e0..000000000 --- a/src/test/java/com/gooddata/util/ISODateClass.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import org.joda.time.DateTime; - -class ISODateClass { - - private final DateTime date; - - @JsonCreator - public ISODateClass(@JsonProperty("date") @JsonDeserialize(using = ISODateTimeDeserializer.class) final DateTime date) { - this.date = date; - } - - @JsonSerialize(using = ISODateTimeSerializer.class) - public DateTime getDate() { - return date; - } -} \ No newline at end of file diff --git a/src/test/java/com/gooddata/util/ISODateTimeDeserializerTest.java b/src/test/java/com/gooddata/util/ISODateTimeDeserializerTest.java deleted file mode 100644 index 3d120c349..000000000 --- a/src/test/java/com/gooddata/util/ISODateTimeDeserializerTest.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.databind.JsonNode; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.testng.annotations.Test; - -import static com.gooddata.util.ResourceUtils.OBJECT_MAPPER; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - -public class ISODateTimeDeserializerTest { - - @Test - public void testDeserialize() throws Exception { - final DateTime expected = new DateTime(2012, 3, 20, 14, 31, 5, 3, DateTimeZone.UTC); - final String json = OBJECT_MAPPER.writeValueAsString(new ISODateClass(expected)); - - final JsonNode node = OBJECT_MAPPER.readTree(json); - assertThat(node.path("date").textValue(), is("2012-03-20T14:31:05.003Z")); - - final ISODateClass moo = OBJECT_MAPPER.readValue(json, ISODateClass.class); - assertThat(moo.getDate(), is(expected)); - } -} \ No newline at end of file diff --git a/src/test/java/com/gooddata/util/ISODateTimeSerializerTest.java b/src/test/java/com/gooddata/util/ISODateTimeSerializerTest.java deleted file mode 100644 index e99fc9d78..000000000 --- a/src/test/java/com/gooddata/util/ISODateTimeSerializerTest.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import com.fasterxml.jackson.databind.JsonNode; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.testng.annotations.Test; - -import static com.gooddata.util.ResourceUtils.OBJECT_MAPPER; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - -public class ISODateTimeSerializerTest { - - @Test - public void testSerialize() throws Exception { - final ISODateClass foo = new ISODateClass(new DateTime(2012, 3, 20, 14, 31, 5, 3, DateTimeZone.UTC)); - final String json = OBJECT_MAPPER.writeValueAsString(foo); - final JsonNode node = OBJECT_MAPPER.readTree(json); - - assertThat(node.path("date").textValue(), is("2012-03-20T14:31:05.003Z")); - } -} \ No newline at end of file diff --git a/src/test/java/com/gooddata/util/ResourceUtils.java b/src/test/java/com/gooddata/util/ResourceUtils.java deleted file mode 100644 index 5ead9fb61..000000000 --- a/src/test/java/com/gooddata/util/ResourceUtils.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import static com.gooddata.util.Validate.notEmpty; -import static com.gooddata.util.Validate.notNull; -import static java.lang.String.format; - -import org.apache.commons.io.IOUtils; -import com.fasterxml.jackson.databind.ObjectMapper; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; - -public class ResourceUtils { - - public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - - public static T readObjectFromResource(String resourcePath, Class objectClass) { - return readObjectFromResource(ResourceUtils.class, resourcePath, objectClass); - } - - public static T readObjectFromResource(Class testClass, String resourcePath, Class objectClass) { - notNull(objectClass, "objectClass"); - - try { - return OBJECT_MAPPER.readValue(readFromResource(resourcePath, testClass), objectClass); - } catch (IOException e) { - throw new IllegalStateException(format("Cannot read class %s from resource %s", objectClass, resourcePath), e); - } - } - - public static String readStringFromResource(String resourcePath) { - try { - return IOUtils.toString(readFromResource(resourcePath), - StandardCharsets.UTF_8); - } catch (IOException e) { - throw new IllegalStateException(format("Cannot read from resource %s", resourcePath), e); - } - } - - public static InputStream readFromResource(String resourcePath) { - final Class clazz = ResourceUtils.class; - return readFromResource(resourcePath, clazz); - } - - - - private static InputStream readFromResource(String resourcePath, Class testClass) { - notEmpty(resourcePath, "resourcePath"); - notNull(testClass, "testClass"); - - return testClass.getResourceAsStream(resourcePath); - } -} diff --git a/src/test/resources/collections/paging.json b/src/test/resources/collections/paging.json deleted file mode 100644 index fd991fd0f..000000000 --- a/src/test/resources/collections/paging.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "offset": 0, - "count": 1, - "next": "next" -} \ No newline at end of file diff --git a/src/test/resources/collections/paging_no_next.json b/src/test/resources/collections/paging_no_next.json deleted file mode 100644 index ba8a78e29..000000000 --- a/src/test/resources/collections/paging_no_next.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "offset": 0, - "count": 1 -} \ No newline at end of file diff --git a/src/test/resources/collections/paging_only_next.json b/src/test/resources/collections/paging_only_next.json deleted file mode 100644 index c3827718a..000000000 --- a/src/test/resources/collections/paging_only_next.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "next": "/nextUri?offset=17" -} \ No newline at end of file From 7de9a4005672330ba876508a841c598453bcbce0 Mon Sep 17 00:00:00 2001 From: Stanislav Devyatovskiy Date: Mon, 11 Sep 2017 17:36:10 +0200 Subject: [PATCH 003/598] Reenable acceptance tests for S3 credentials Closes #517 --- .../com/gooddata/warehouse/WarehouseServiceAT.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/gooddata/warehouse/WarehouseServiceAT.java b/src/test/java/com/gooddata/warehouse/WarehouseServiceAT.java index 8c01a07ae..b436ba3f7 100644 --- a/src/test/java/com/gooddata/warehouse/WarehouseServiceAT.java +++ b/src/test/java/com/gooddata/warehouse/WarehouseServiceAT.java @@ -156,7 +156,7 @@ public void getDefaultWarehouseSchema() { assertThat(warehouseSchema, is(notNullValue())); } - @Test(groups = { "warehouse", "isolated_domain" }, dependsOnMethods = "createWarehouse") + @Test(groups = "warehouse", dependsOnMethods = "createWarehouse") public void addS3Credentials() { s3Credentials = service.addS3Credentials(warehouse, s3Credentials) .get(1, TimeUnit.MINUTES); @@ -164,7 +164,7 @@ public void addS3Credentials() { assertThat(s3Credentials, notNullValue()); } - @Test(groups = { "warehouse", "isolated_domain" }, dependsOnMethods = "addS3Credentials") + @Test(groups = "warehouse", dependsOnMethods = "addS3Credentials") public void updateS3Credentials() { final DateTime lastUpdated = s3Credentials.getUpdated(); s3Credentials.setSecretKey("newSecretKey"); @@ -175,7 +175,7 @@ public void updateS3Credentials() { assertThat(s3Credentials.getUpdated(), is(not(lastUpdated))); } - @Test(groups = { "warehouse", "isolated_domain" }, dependsOnMethods = "updateS3Credentials") + @Test(groups = "warehouse", dependsOnMethods = "updateS3Credentials") public void getS3SpecificCredentials() { final WarehouseS3Credentials result = service.getWarehouseS3Credentials(warehouse, S3_CREDENTIALS_REGION, S3_CREDENTIALS_ACCESS_KEY); @@ -184,7 +184,7 @@ public void getS3SpecificCredentials() { assertThat(result.getAccessKey(), is(S3_CREDENTIALS_ACCESS_KEY)); } - @Test(groups = { "warehouse", "isolated_domain" }, dependsOnMethods = "updateS3Credentials") + @Test(groups = "warehouse", dependsOnMethods = "updateS3Credentials") public void listS3Credentials() { final PageableList result = service.listWarehouseS3Credentials(warehouse); @@ -193,7 +193,7 @@ public void listS3Credentials() { assertThat(result.getNextPage(), nullValue()); } - @Test(groups = { "warehouse", "isolated_domain" }, dependsOnMethods = { "listS3Credentials", "getS3SpecificCredentials" }) + @Test(groups = "warehouse", dependsOnMethods = { "listS3Credentials", "getS3SpecificCredentials" }) public void removeS3Credentials() { service.removeS3Credentials(s3Credentials).get(1, TimeUnit.MINUTES); } From 87ccb7a5372f2d3a667ea98f56eb811187ccd96a Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Wed, 6 Sep 2017 18:00:59 +0200 Subject: [PATCH 004/598] add audit events Close: #513 --- pom.xml | 5 + src/main/java/com/gooddata/GoodData.java | 13 ++ .../com/gooddata/auditevent/AuditEvent.java | 133 ++++++++++++++++++ .../auditevent/AuditEventPageRequest.java | 113 +++++++++++++++ .../auditevent/AuditEventService.java | 133 ++++++++++++++++++ .../com/gooddata/auditevent/AuditEvents.java | 35 +++++ .../auditevent/AuditEventsDeserializer.java | 24 ++++ .../AuditEventsForbiddenException.java | 13 ++ .../auditevent/AuditEventsSerializer.java | 15 ++ .../gooddata/account/AccountServiceIT.java | 4 +- .../auditevent/AuditEventPageRequestTest.java | 100 +++++++++++++ .../auditevent/AuditEventServiceAT.java | 27 ++++ .../auditevent/AuditEventServiceIT.java | 109 ++++++++++++++ .../auditevent/AuditEventServiceTest.java | 61 ++++++++ .../gooddata/auditevent/AuditEventTest.java | 81 +++++++++++ .../gooddata/auditevent/AuditEventsTest.java | 108 ++++++++++++++ .../resources/auditevents/auditEvent.json | 11 ++ .../auditevents/auditEventWithParam.json | 14 ++ .../auditEventWithParamAndLink.json | 17 +++ .../resources/auditevents/auditEvents.json | 34 +++++ .../auditevents/auditEventsPage2.json | 20 +++ .../auditevents/emptyAuditEvents.json | 11 ++ .../auditevents/userAuditEvents.json | 23 +++ 23 files changed, 1102 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/gooddata/auditevent/AuditEvent.java create mode 100644 src/main/java/com/gooddata/auditevent/AuditEventPageRequest.java create mode 100644 src/main/java/com/gooddata/auditevent/AuditEventService.java create mode 100644 src/main/java/com/gooddata/auditevent/AuditEvents.java create mode 100644 src/main/java/com/gooddata/auditevent/AuditEventsDeserializer.java create mode 100644 src/main/java/com/gooddata/auditevent/AuditEventsForbiddenException.java create mode 100644 src/main/java/com/gooddata/auditevent/AuditEventsSerializer.java create mode 100644 src/test/java/com/gooddata/auditevent/AuditEventPageRequestTest.java create mode 100644 src/test/java/com/gooddata/auditevent/AuditEventServiceAT.java create mode 100644 src/test/java/com/gooddata/auditevent/AuditEventServiceIT.java create mode 100644 src/test/java/com/gooddata/auditevent/AuditEventServiceTest.java create mode 100644 src/test/java/com/gooddata/auditevent/AuditEventTest.java create mode 100644 src/test/java/com/gooddata/auditevent/AuditEventsTest.java create mode 100644 src/test/resources/auditevents/auditEvent.json create mode 100644 src/test/resources/auditevents/auditEventWithParam.json create mode 100644 src/test/resources/auditevents/auditEventWithParamAndLink.json create mode 100644 src/test/resources/auditevents/auditEvents.json create mode 100644 src/test/resources/auditevents/auditEventsPage2.json create mode 100644 src/test/resources/auditevents/emptyAuditEvents.json create mode 100644 src/test/resources/auditevents/userAuditEvents.json diff --git a/pom.xml b/pom.xml index 300f90e43..a26e518f4 100644 --- a/pom.xml +++ b/pom.xml @@ -208,6 +208,11 @@ spring-core ${spring.version} + + org.springframework + spring-beans + ${spring.version} + org.springframework spring-web diff --git a/src/main/java/com/gooddata/GoodData.java b/src/main/java/com/gooddata/GoodData.java index 67e10860c..68baee3ac 100644 --- a/src/main/java/com/gooddata/GoodData.java +++ b/src/main/java/com/gooddata/GoodData.java @@ -6,6 +6,7 @@ package com.gooddata; import com.gooddata.account.AccountService; +import com.gooddata.auditevent.AuditEventService; import com.gooddata.connector.ConnectorService; import com.gooddata.dataload.OutputStageService; import com.gooddata.dataload.processes.ProcessService; @@ -86,6 +87,7 @@ public class GoodData { private final OutputStageService outputStageService; private final ProjectTemplateService projectTemplateService; private final ExportService exportService; + private final AuditEventService auditEventService; /** * Create instance configured to communicate with GoodData Platform under user with given credentials. @@ -221,6 +223,7 @@ protected GoodData(GoodDataEndpoint endpoint, Authentication authentication, Goo featureFlagService = new FeatureFlagService(getRestTemplate()); outputStageService = new OutputStageService(getRestTemplate()); projectTemplateService = new ProjectTemplateService(getRestTemplate()); + auditEventService = new AuditEventService(getRestTemplate(), accountService); } static RestTemplate createRestTemplate(GoodDataEndpoint endpoint, HttpClient httpClient) { @@ -477,4 +480,14 @@ public OutputStageService getOutputStageService() { public ProjectTemplateService getProjectTemplateService() { return projectTemplateService; } + + /** + * Get initialized service for audit events + * @return initialized service for audit events + */ + @Bean + public AuditEventService getAuditEventService() { + return auditEventService; + } + } diff --git a/src/main/java/com/gooddata/auditevent/AuditEvent.java b/src/main/java/com/gooddata/auditevent/AuditEvent.java new file mode 100644 index 000000000..670183a9c --- /dev/null +++ b/src/main/java/com/gooddata/auditevent/AuditEvent.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.auditevent; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.gooddata.util.GoodDataToStringBuilder; +import com.gooddata.util.ISODateTimeDeserializer; +import com.gooddata.util.ISODateTimeSerializer; +import org.joda.time.DateTime; +import org.springframework.web.util.UriTemplate; + +import java.util.Map; + +/** + * Audit event + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName(AuditEvent.ROOT_NODE) +@JsonIgnoreProperties(ignoreUnknown = true) +public class AuditEvent { + + public static final String GDC_URI = "/gdc"; + public static final String USER_URI = GDC_URI + "/account/profile/{userId}/auditEvents"; + public static final String ADMIN_URI = GDC_URI + "/domains/{domainId}/auditEvents"; + + public static final UriTemplate ADMIN_URI_TEMPLATE = new UriTemplate(ADMIN_URI); + public static final UriTemplate USER_URI_TEMPLATE = new UriTemplate(USER_URI); + + static final String ROOT_NODE = "event"; + + private final String id; + + private final String userLogin; + + /** the time the event occurred */ + private final DateTime occurred; + + /** the time event was recorded by audit system */ + private final DateTime recorded; + + private final String userIp; + + private final boolean success; + + private final String type; + + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private final Map params; + + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private final Map links; + + @JsonCreator + public AuditEvent(@JsonProperty("id") String id, + @JsonProperty("userLogin") String userLogin, + @JsonProperty("occurred") @JsonDeserialize(using = ISODateTimeDeserializer.class) DateTime occurred, + @JsonProperty("recorded") @JsonDeserialize(using = ISODateTimeDeserializer.class) DateTime recorded, + @JsonProperty("userIp") String userIp, + @JsonProperty("success") boolean success, + @JsonProperty("type") String type, + @JsonProperty("params") Map params, + @JsonProperty("links") Map links) { + this.id = id; + this.userLogin = userLogin; + this.occurred = occurred; + this.recorded = recorded; + this.userIp = userIp; + this.success = success; + this.type = type; + this.params = params; + this.links = links; + } + + public String getId() { + return id; + } + + public String getUserLogin() { + return userLogin; + } + + /** + * the time the event occurred + */ + @JsonSerialize(using = ISODateTimeSerializer.class) + public DateTime getOccurred() { + return occurred; + } + + /** + * the time event was recorded by audit system + */ + @JsonSerialize(using = ISODateTimeSerializer.class) + public DateTime getRecorded() { + return recorded; + } + + public String getUserIp() { + return userIp; + } + + public boolean isSuccess() { + return success; + } + + public String getType() { + return type; + } + + public Map getParams() { + return params; + } + + public Map getLinks() { + return links; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + +} diff --git a/src/main/java/com/gooddata/auditevent/AuditEventPageRequest.java b/src/main/java/com/gooddata/auditevent/AuditEventPageRequest.java new file mode 100644 index 000000000..d548e5a15 --- /dev/null +++ b/src/main/java/com/gooddata/auditevent/AuditEventPageRequest.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.auditevent; + +import com.gooddata.collections.PageRequest; +import com.gooddata.util.GoodDataToStringBuilder; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.springframework.beans.BeanUtils; +import org.springframework.web.util.UriComponentsBuilder; + +import static org.apache.commons.lang3.Validate.notNull; + +/** + * Class to encapsulate time filtering and paging parameters + */ +public class AuditEventPageRequest extends PageRequest { + + private DateTime from; + + private DateTime to; + + private String type; + + public AuditEventPageRequest() { + } + + public DateTime getFrom() { + return from; + } + + /** + * Specify lower bound of interval + */ + public void setFrom(final DateTime from) { + this.from = from; + } + + public DateTime getTo() { + return to; + } + + /** + * Specify upper bound of interval + */ + public void setTo(final DateTime to) { + this.to = to; + } + + public String getType() { + return type; + } + + /** + * Specify event type for filtering purposes + * + * @param type event type + */ + public void setType(final String type) { + this.type = type; + } + + /** + * Copy constructor + * + * @param source source object (not null) to create copy of + * @return new instance, which fields has same value as fields of source + */ + public static AuditEventPageRequest copy(final AuditEventPageRequest source) { + notNull(source, "source cannot be null"); + + final AuditEventPageRequest copy = new AuditEventPageRequest(); + BeanUtils.copyProperties(source, copy); + + return copy; + } + + /** + * Copy this request parameters and increment request parameter limit. + * If Limit is negative, than sanitized limit is taken and incremented. + * + * @return new instance with incremented limit + */ + public AuditEventPageRequest withIncrementedLimit() { + final AuditEventPageRequest copy = AuditEventPageRequest.copy(this); + copy.setLimit(this.getSanitizedLimit() + 1); + return copy; + } + + @Override + public UriComponentsBuilder updateWithPageParams(final UriComponentsBuilder builder) { + UriComponentsBuilder builderWithPaging = super.updateWithPageParams(builder); + if (from != null) { + builderWithPaging.queryParam("from", from.toDateTime(DateTimeZone.UTC)); + } + if (to != null) { + builderWithPaging.queryParam("to", to.toDateTime(DateTimeZone.UTC)); + } + if (type != null) { + builderWithPaging.queryParam("type", type); + } + + return builderWithPaging; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/auditevent/AuditEventService.java b/src/main/java/com/gooddata/auditevent/AuditEventService.java new file mode 100644 index 000000000..198def60c --- /dev/null +++ b/src/main/java/com/gooddata/auditevent/AuditEventService.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + */ +package com.gooddata.auditevent; + +import com.gooddata.AbstractService; +import com.gooddata.GoodDataException; +import com.gooddata.GoodDataRestException; +import com.gooddata.account.Account; +import com.gooddata.account.AccountService; +import com.gooddata.collections.MultiPageList; +import com.gooddata.collections.Page; +import com.gooddata.collections.PageableList; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +import static com.gooddata.util.Validate.notEmpty; +import static com.gooddata.util.Validate.notNull; +import static org.springframework.http.HttpStatus.UNAUTHORIZED; + +/** + * List audit events. + */ +public class AuditEventService extends AbstractService { + + private final AccountService accountService; + + /** + * Service for audit events + * @param restTemplate rest template + * @param accountService account service + */ + public AuditEventService(final RestTemplate restTemplate, final AccountService accountService) { + super(restTemplate); + this.accountService = notNull(accountService, "account service"); + } + + /** + * Get list of audit events for the given domain id + * @param domainId domain id + * @return non-null paged list of events + * @throws AuditEventsForbiddenException if current user is not admin of the given domain + */ + public PageableList listAuditEvents(final String domainId) { + return listAuditEvents(domainId, new AuditEventPageRequest()); + } + + /** + * Get list of audit events for the given domain id + * @param domainId domain id + * @param page request parameters + * @return non-null paged list of events + * @throws AuditEventsForbiddenException if current user is not admin of the given domain + */ + public PageableList listAuditEvents(final String domainId, final Page page) { + notEmpty(domainId, "domainId"); + notNull(page, "page"); + + final String uri = AuditEvent.ADMIN_URI_TEMPLATE.expand(domainId).toString(); + return new MultiPageList<>(page, (p) -> doListAuditEvents(getAuditEventsUri(p, uri))); + } + + /** + * Get list of audit events for the given account + * @param account account with valid id + * @return non-null paged list of events + * @throws AuditEventsForbiddenException if audit events are not enabled for the given user or the current user is + * not domain admin + */ + public PageableList listAuditEvents(final Account account) { + return listAuditEvents(account, new AuditEventPageRequest()); + } + + /** + * Get list of audit events for the given account + * @param account account with valid id + * @param page request parameters + * @return non-null paged list of events + * @throws AuditEventsForbiddenException if audit events are not enabled for the given user or the current user is + * not domain admin + */ + public PageableList listAuditEvents(final Account account, final Page page) { + notNull(account, "account"); + notEmpty(account.getId(), "account.id"); + notNull(page, "page"); + + final String uri = AuditEvent.USER_URI_TEMPLATE.expand(account.getId()).toString(); + + return new MultiPageList<>(page, (p) -> doListAuditEvents(getAuditEventsUri(p, uri))); + } + + /** + * Get list of audit events for current account + * @return non-null paged list of events + * @throws AuditEventsForbiddenException if audit events are not enabled for current user + */ + public PageableList listAuditEvents() { + return listAuditEvents(new AuditEventPageRequest()); + } + + /** + * Get list of audit events for current account + * @param page request parameters + * @return non-null paged list of events + * @throws AuditEventsForbiddenException if audit events are not enabled for current user + */ + public PageableList listAuditEvents(final Page page) { + notNull(page, "page"); + final Account account = accountService.getCurrent(); + + return listAuditEvents(account, page); + } + + private AuditEvents doListAuditEvents(final String uri) { + try { + return restTemplate.getForObject(uri, AuditEvents.class); + } catch (GoodDataRestException e) { + if (UNAUTHORIZED.value() == e.getStatusCode()) { + throw new AuditEventsForbiddenException(e); + } else { + throw e; + } + } catch (RestClientException e) { + throw new GoodDataException("Unable to list audit events: " + uri); + } + } + + private String getAuditEventsUri(final Page page, final String uri) { + return page.updateWithPageParams(UriComponentsBuilder.fromUriString(uri)).build().toUriString(); + } +} + diff --git a/src/main/java/com/gooddata/auditevent/AuditEvents.java b/src/main/java/com/gooddata/auditevent/AuditEvents.java new file mode 100644 index 000000000..892adb7b7 --- /dev/null +++ b/src/main/java/com/gooddata/auditevent/AuditEvents.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.auditevent; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.gooddata.collections.PageableList; +import com.gooddata.collections.Paging; + +import java.util.List; +import java.util.Map; + +/** + * Pageable list DTO for Audit events + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName(AuditEvents.ROOT_NODE) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonSerialize(using = AuditEventsSerializer.class) +@JsonDeserialize(using = AuditEventsDeserializer.class) +public class AuditEvents extends PageableList { + + static final String ROOT_NODE = "events"; + + public AuditEvents(final List items, final Paging paging, final Map links) { + super(items, paging, links); + } + +} diff --git a/src/main/java/com/gooddata/auditevent/AuditEventsDeserializer.java b/src/main/java/com/gooddata/auditevent/AuditEventsDeserializer.java new file mode 100644 index 000000000..a3a94acf6 --- /dev/null +++ b/src/main/java/com/gooddata/auditevent/AuditEventsDeserializer.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.auditevent; + +import com.gooddata.collections.PageableListDeserializer; +import com.gooddata.collections.Paging; + +import java.util.List; +import java.util.Map; + +class AuditEventsDeserializer extends PageableListDeserializer{ + + protected AuditEventsDeserializer() { + super(AuditEvent.class); + } + + @Override + protected AuditEvents createList(final List items, final Paging paging, final Map links) { + return new AuditEvents(items, paging, links); + } +} diff --git a/src/main/java/com/gooddata/auditevent/AuditEventsForbiddenException.java b/src/main/java/com/gooddata/auditevent/AuditEventsForbiddenException.java new file mode 100644 index 000000000..b440c863e --- /dev/null +++ b/src/main/java/com/gooddata/auditevent/AuditEventsForbiddenException.java @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + */ +package com.gooddata.auditevent; + +import com.gooddata.GoodDataException; + +public class AuditEventsForbiddenException extends GoodDataException { + + public AuditEventsForbiddenException(final Throwable cause) { + super("Unable to list audit events", cause); + } +} diff --git a/src/main/java/com/gooddata/auditevent/AuditEventsSerializer.java b/src/main/java/com/gooddata/auditevent/AuditEventsSerializer.java new file mode 100644 index 000000000..d866220b5 --- /dev/null +++ b/src/main/java/com/gooddata/auditevent/AuditEventsSerializer.java @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.auditevent; + +import com.gooddata.collections.PageableListSerializer; + +class AuditEventsSerializer extends PageableListSerializer { + + public AuditEventsSerializer() { + super(AuditEvents.ROOT_NODE); + } +} diff --git a/src/test/java/com/gooddata/account/AccountServiceIT.java b/src/test/java/com/gooddata/account/AccountServiceIT.java index ef5f79a82..96da2a649 100644 --- a/src/test/java/com/gooddata/account/AccountServiceIT.java +++ b/src/test/java/com/gooddata/account/AccountServiceIT.java @@ -24,11 +24,11 @@ public class AccountServiceIT extends AbstractGoodDataIT { private static final String CREATE_ACCOUNT = "/account/create-account.json"; - private static final String ACCOUNT = "/account/account.json"; + public static final String ACCOUNT = "/account/account.json"; private static final String ACCOUNT_UPDATE = "/account/update-account.json"; private static final String ACCOUNT_ID = "ID"; private static final String ACCOUNT_URI = Account.TEMPLATE.expand(ACCOUNT_ID).toString(); - private static final String CURRENT_ACCOUNT_URI = Account.TEMPLATE.expand(Account.CURRENT_ID).toString(); + public static final String CURRENT_ACCOUNT_URI = Account.TEMPLATE.expand(Account.CURRENT_ID).toString(); private static final String LOGOUT_CURRENT = Account.LOGIN_TEMPLATE.expand(ACCOUNT_ID).toString(); private static final String DOMAIN = "default"; diff --git a/src/test/java/com/gooddata/auditevent/AuditEventPageRequestTest.java b/src/test/java/com/gooddata/auditevent/AuditEventPageRequestTest.java new file mode 100644 index 000000000..50abe1f8a --- /dev/null +++ b/src/test/java/com/gooddata/auditevent/AuditEventPageRequestTest.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.auditevent; + +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.springframework.web.util.UriComponentsBuilder; +import org.testng.annotations.Test; + +import static com.gooddata.collections.PageRequest.DEFAULT_LIMIT; +import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; + +public class AuditEventPageRequestTest { + + private static final DateTime FROM = new DateTime(); + private static final DateTime TO = new DateTime(); + private static final Integer LIMIT = 10; + private static final String OFFSET = "foo"; + public static final String EVENT_TYPE = "STANDARD_LOGIN"; + + @Test + public void testCopy() { + AuditEventPageRequest request = new AuditEventPageRequest(); + request.setFrom(FROM); + request.setTo(TO); + request.setLimit(LIMIT); + request.setOffset(OFFSET); + request.setType(EVENT_TYPE); + + AuditEventPageRequest copy = AuditEventPageRequest.copy(request); + + assertThat(request, is(sameBeanAs(copy))); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testCopyNull() { + AuditEventPageRequest.copy(null); + } + + @Test + public void testWithIncrementedLimit() { + AuditEventPageRequest request = new AuditEventPageRequest(); + request.setFrom(FROM); + request.setTo(TO); + request.setLimit(LIMIT); + request.setOffset(OFFSET); + request.setType(EVENT_TYPE); + + AuditEventPageRequest result = request.withIncrementedLimit(); + + assertThat(result.getFrom(), is(FROM)); + assertThat(result.getTo(), is(TO)); + assertThat(result.getSanitizedLimit(), is(LIMIT+1)); + assertThat(result.getOffset(), is(OFFSET)); + assertThat(result.getType(), is(EVENT_TYPE)); + } + + @Test + public void testUpdateWithAllFields() { + AuditEventPageRequest request = new AuditEventPageRequest(); + request.setFrom(FROM); + request.setTo(TO); + request.setLimit(LIMIT); + request.setOffset(OFFSET); + request.setType(EVENT_TYPE); + + UriComponentsBuilder result = request.updateWithPageParams(UriComponentsBuilder.newInstance()); + + assertThat(result.build().toUriString(), is(String.format("?offset=%s&limit=%d&from=%s&to=%s&type=%s", + OFFSET, LIMIT, FROM.toDateTime(DateTimeZone.UTC), TO.toDateTime(DateTimeZone.UTC), EVENT_TYPE))); + } + + @Test + public void testUpdateWithOnlyPagingFields() { + AuditEventPageRequest request = new AuditEventPageRequest(); + request.setLimit(LIMIT); + request.setOffset(OFFSET); + + UriComponentsBuilder result = request.updateWithPageParams(UriComponentsBuilder.newInstance()); + + assertThat(result.build().toUriString(), is("?offset=" + OFFSET + "&limit=" + LIMIT)); + } + + @Test + public void testUpdateWithOnlyTimeIntervalFields() { + AuditEventPageRequest request = new AuditEventPageRequest(); + request.setFrom(FROM); + request.setTo(TO); + + UriComponentsBuilder result = request.updateWithPageParams(UriComponentsBuilder.newInstance()); + + assertThat(result.build().toUriString(), is("?limit=" + DEFAULT_LIMIT + + "&from=" + FROM.toDateTime(DateTimeZone.UTC) + "&to=" + TO.toDateTime(DateTimeZone.UTC))); + } +} diff --git a/src/test/java/com/gooddata/auditevent/AuditEventServiceAT.java b/src/test/java/com/gooddata/auditevent/AuditEventServiceAT.java new file mode 100644 index 000000000..4c56d0bc7 --- /dev/null +++ b/src/test/java/com/gooddata/auditevent/AuditEventServiceAT.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + */ +package com.gooddata.auditevent; + +import com.gooddata.AbstractGoodDataAT; +import com.gooddata.collections.PageableList; +import org.testng.annotations.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; + +public class AuditEventServiceAT extends AbstractGoodDataAT { + + @Test + public void shouldListEventsForCurrentUser() throws Exception { + final PageableList events = gd.getAuditEventService().listAuditEvents(); + assertThat(events, is(notNullValue())); + } + + @Test(groups = "isolated_domain") + public void shouldListEventsForDomain() throws Exception { + final PageableList events = gd.getAuditEventService().listAuditEvents("default"); + assertThat(events, is(notNullValue())); + } +} \ No newline at end of file diff --git a/src/test/java/com/gooddata/auditevent/AuditEventServiceIT.java b/src/test/java/com/gooddata/auditevent/AuditEventServiceIT.java new file mode 100644 index 000000000..e617d31a7 --- /dev/null +++ b/src/test/java/com/gooddata/auditevent/AuditEventServiceIT.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + */ +package com.gooddata.auditevent; + +import com.gooddata.AbstractGoodDataIT; +import com.gooddata.GoodDataRestException; +import com.gooddata.account.Account; +import com.gooddata.collections.PageableList; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import static com.gooddata.account.AccountServiceIT.ACCOUNT; +import static com.gooddata.account.AccountServiceIT.CURRENT_ACCOUNT_URI; +import static com.gooddata.util.ResourceUtils.readFromResource; +import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; +import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED; +import static net.jadler.Jadler.onRequest; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasSize; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class AuditEventServiceIT extends AbstractGoodDataIT { + + private AuditEventService service; + + @BeforeMethod + public void setUp() throws Exception { + service = gd.getAuditEventService(); + } + + @Test(expectedExceptions = AuditEventsForbiddenException.class) + public void shouldThrowOnForbiddenDomain() { + onRequest() + .havingPathEqualTo("/gdc/domains/DOMAIN/auditEvents") + .respond() + .withStatus(SC_UNAUTHORIZED) + ; + + service.listAuditEvents("DOMAIN"); + } + + @Test(expectedExceptions = AuditEventsForbiddenException.class) + public void shouldThrowOnForbiddenAccount() { + onRequest() + .havingPathEqualTo("/gdc/account/profile/ID/auditEvents") + .respond() + .withStatus(SC_UNAUTHORIZED) + ; + final Account account = mock(Account.class); + when(account.getId()).thenReturn("ID"); + + service.listAuditEvents(account); + } + + @Test(expectedExceptions = GoodDataRestException.class) + public void shouldThrowOnUnknownError() { + onRequest() + .havingPathEqualTo("/gdc/account/profile/ID/auditEvents") + .respond() + .withStatus(SC_BAD_REQUEST) + ; + final Account account = mock(Account.class); + when(account.getId()).thenReturn("ID"); + + service.listAuditEvents(account); + } + + @Test + public void shouldReturnAuditEvents() throws Exception { + onRequest() + .havingPathEqualTo("/gdc/domains/DOMAIN/auditEvents") + .respond() + .withBody(readFromResource("/auditevents/auditEvents.json")) + ; + onRequest() + .havingPathEqualTo("/gdc/domains/DOMAIN/auditEvents") + .havingParameterEqualTo("offset", "456") + .respond() + .withBody(readFromResource("/auditevents/auditEventsPage2.json")) + ; + + final PageableList page1 = service.listAuditEvents("DOMAIN"); + assertThat(page1, hasSize(2)); + + final PageableList page2 = service.listAuditEvents("DOMAIN", page1.getNextPage()); + assertThat(page2, hasSize(1)); + } + + @Test + public void shouldReturnAuditEventsForUser() throws Exception { + onRequest() + .havingMethodEqualTo("GET") + .havingPathEqualTo(CURRENT_ACCOUNT_URI) + .respond() + .withBody(readFromResource(ACCOUNT)) + .withStatus(200); + + onRequest() + .havingPathEqualTo("/gdc/account/profile/ID/auditEvents") + .respond() + .withBody(readFromResource("/auditevents/auditEvents.json")) + ; + + final PageableList events = service.listAuditEvents(); + assertThat(events, hasSize(2)); + } +} \ No newline at end of file diff --git a/src/test/java/com/gooddata/auditevent/AuditEventServiceTest.java b/src/test/java/com/gooddata/auditevent/AuditEventServiceTest.java new file mode 100644 index 000000000..13fda9f44 --- /dev/null +++ b/src/test/java/com/gooddata/auditevent/AuditEventServiceTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved. + */ +package com.gooddata.auditevent; + +import com.gooddata.account.Account; +import com.gooddata.account.AccountService; +import com.gooddata.collections.PageRequest; +import org.springframework.web.client.RestTemplate; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class AuditEventServiceTest { + + private AuditEventService service; + + @BeforeMethod + public void setUp() throws Exception { + service = new AuditEventService(new RestTemplate(), mock(AccountService.class)); + } + + @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = ".*account.*") + public void shouldFailOnNullAccount() throws Exception { + service.listAuditEvents((Account) null); + } + + @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = ".*account.*") + public void shouldFailOnNullAccountButPage() throws Exception { + service.listAuditEvents((Account) null, new PageRequest()); + } + + @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = ".*account.id.*") + public void shouldFailOnNullAccountIdButPage() throws Exception { + service.listAuditEvents(mock(Account.class), new PageRequest()); + } + + @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = ".*page.*") + public void shouldFailOnNullPageButAccount() throws Exception { + final Account account = mock(Account.class); + when(account.getId()).thenReturn("123"); + service.listAuditEvents(account, null); + } + + @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = ".*domain.*") + public void shouldFailOnNullDomain() throws Exception { + service.listAuditEvents((String) null); + } + + @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = ".*domain.*") + public void shouldFailOnNullDomainButPage() throws Exception { + service.listAuditEvents((String) null, new PageRequest()); + } + + @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = ".*domain.*") + public void shouldFailOnNullPageButDomain() throws Exception { + service.listAuditEvents("", null); + } +} \ No newline at end of file diff --git a/src/test/java/com/gooddata/auditevent/AuditEventTest.java b/src/test/java/com/gooddata/auditevent/AuditEventTest.java new file mode 100644 index 000000000..658bd40e8 --- /dev/null +++ b/src/test/java/com/gooddata/auditevent/AuditEventTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.auditevent; + +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.joda.time.LocalDate; +import org.testng.annotations.Test; + +import static com.gooddata.util.ResourceUtils.readObjectFromResource; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals; +import static net.javacrumbs.jsonunit.core.util.ResourceUtils.resource; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasEntry; + +public class AuditEventTest { + + private static final String PARAM_KEY = "KEY"; + private static final String PARAM_VALUE = "VALUE"; + private static final String LINK_KEY = "LINK_KEY"; + private static final String LINK_VALUE = "LINK_VALUE"; + + private static final DateTime DATE = new LocalDate(1993, 3, 9).toDateTimeAtStartOfDay(DateTimeZone.UTC); + + private final AuditEvent event = new AuditEvent("123", "bear@gooddata.com", DATE, DATE, "127.0.0.1", true, "login", emptyMap(), null); + private final AuditEvent eventWithParams = new AuditEvent("123", "bear@gooddata.com", DATE, DATE, "127.0.0.1", true, "login", + singletonMap(PARAM_KEY, PARAM_VALUE), null); + + private final AuditEvent eventWithParamsAndLinks = new AuditEvent("123", "bear@gooddata.com", DATE, DATE, "127.0.0.1", true, "login", + singletonMap(PARAM_KEY, PARAM_VALUE), + singletonMap(LINK_KEY, LINK_VALUE)); + + @Test + public void testSerialize() throws Exception { + assertThat(event, jsonEquals(resource("auditevents/auditEvent.json"))); + } + + @Test + public void testDeserialize() throws Exception { + final AuditEvent deserializedObject = readObjectFromResource("/auditevents/auditEvent.json", AuditEvent.class); + assertThat(deserializedObject, notNullValue()); + assertThat(deserializedObject.getId(), is(event.getId())); + assertThat(deserializedObject.getOccurred(), is(event.getOccurred())); + assertThat(deserializedObject.getRecorded(), is(event.getRecorded())); + assertThat(deserializedObject.getUserLogin(), is(event.getUserLogin())); + assertThat(deserializedObject.getUserIp(), is(event.getUserIp())); + assertThat(deserializedObject.isSuccess(), is(event.isSuccess())); + assertThat(deserializedObject.getType(), is(event.getType())); + } + + @Test + public void testSerializeEventWithParams() throws Exception { + assertThat(eventWithParams, jsonEquals(resource("auditevents/auditEventWithParam.json"))); + } + + @Test + public void testDeserializeWithParams() throws Exception { + final AuditEvent deserializedObject = readObjectFromResource("/auditevents/auditEventWithParam.json", AuditEvent.class); + assertThat(deserializedObject.getParams(), hasEntry("KEY", "VALUE")); + } + + @Test + public void testSerializeEventWithParamsAndLinks() throws Exception { + assertThat(eventWithParamsAndLinks, jsonEquals(resource("auditevents/auditEventWithParamAndLink.json"))); + } + + @Test + public void testDeserializeWithParamsAndLinks() throws Exception { + final AuditEvent deserializedObject = readObjectFromResource("/auditevents/auditEventWithParamAndLink.json", AuditEvent.class); + assertThat(deserializedObject.getParams(), hasEntry("KEY", "VALUE")); + assertThat(deserializedObject.getLinks(), hasEntry("LINK_KEY", "LINK_VALUE")); + } + +} \ No newline at end of file diff --git a/src/test/java/com/gooddata/auditevent/AuditEventsTest.java b/src/test/java/com/gooddata/auditevent/AuditEventsTest.java new file mode 100644 index 000000000..f2c036bca --- /dev/null +++ b/src/test/java/com/gooddata/auditevent/AuditEventsTest.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.auditevent; + +import com.gooddata.collections.Paging; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.joda.time.LocalDate; +import org.testng.annotations.Test; + +import java.util.Collections; + +import static com.gooddata.auditevent.AuditEvent.ADMIN_URI_TEMPLATE; +import static com.gooddata.auditevent.AuditEvent.USER_URI_TEMPLATE; +import static com.gooddata.util.ResourceUtils.readObjectFromResource; +import static java.util.Arrays.asList; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonList; +import static java.util.Collections.singletonMap; +import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals; +import static net.javacrumbs.jsonunit.core.util.ResourceUtils.resource; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasSize; + +public class AuditEventsTest { + + private static final String USER1_ID = "user123"; + + private static final String USER1_LOGIN = "bear@gooddata.com"; + private static final String USER2_LOGIN = "jane@gooddata.com"; + + private static final String DOMAIN = "default"; + + private static final String IP = "127.0.0.1"; + private static final boolean SUCCESS = true; + private static final String TYPE = "login"; + + private static final DateTime DATE = new LocalDate(1993, 3, 9).toDateTimeAtStartOfDay(DateTimeZone.UTC); + private static final AuditEvent EVENT_1 = new AuditEvent("123", USER1_LOGIN, DATE, DATE, IP, SUCCESS, TYPE, emptyMap(), emptyMap()); + private static final AuditEvent EVENT_2 = new AuditEvent("456", USER2_LOGIN, DATE, DATE, IP, SUCCESS, TYPE, emptyMap(), emptyMap()); + + private static final String ADMIN_URI = ADMIN_URI_TEMPLATE.expand(DOMAIN).toString(); + private static final String USER_URI = USER_URI_TEMPLATE.expand(USER1_ID).toString(); + private static final String ADMIN_NEXT_URI = ADMIN_URI + "?offset=456"; + private static final String USER_NEXT_URI = USER_URI + "?offset=456&limit=1"; + + private static final AuditEvents EVENTS = new AuditEvents( + asList(EVENT_1, EVENT_2), + new Paging(ADMIN_NEXT_URI), + singletonMap("self", ADMIN_URI) + ); + + private static final AuditEvents EMPTY_EVENTS = new AuditEvents( + Collections.emptyList(), + new Paging(null), + singletonMap("self", ADMIN_URI) + ); + + private static final AuditEvents USER_EVENTS = new AuditEvents( + singletonList(EVENT_1), + new Paging(USER_NEXT_URI), + singletonMap("self", USER_URI) + ); + + @Test + public void testSerialize() throws Exception { + assertThat(EVENTS, jsonEquals(resource("auditevents/auditEvents.json"))); + } + + @Test + public void testDeserialize() throws Exception { + final AuditEvents deserialized = readObjectFromResource("/auditevents/auditEvents.json", AuditEvents.class); + assertThat(deserialized.getPaging().getNextUri(), is(ADMIN_NEXT_URI)); + assertThat(deserialized, hasSize(2)); + assertThat(deserialized.get(0).getId(), is(EVENT_1.getId())); + assertThat(deserialized.get(1).getId(), is(EVENT_2.getId())); + } + + @Test + public void testSerializeEmptyEvents() throws Exception { + assertThat(EMPTY_EVENTS, jsonEquals(resource("auditevents/emptyAuditEvents.json"))); + } + + @Test + public void testDeserializeEmptyEvents() throws Exception { + final AuditEvents deserialized = readObjectFromResource("/auditevents/emptyAuditEvents.json", AuditEvents.class); + assertThat(deserialized.getPaging().getNextUri(), nullValue()); + assertThat(deserialized, hasSize(0)); + } + + @Test + public void testSerializeUserEvents() throws Exception { + assertThat(USER_EVENTS, jsonEquals(resource("auditevents/userAuditEvents.json"))); + } + + @Test + public void testDeserializeUserEvents() throws Exception { + final AuditEvents deserialized = readObjectFromResource("/auditevents/userAuditEvents.json", AuditEvents.class); + assertThat(deserialized.getPaging().getNextUri(), is(USER_NEXT_URI)); + assertThat(deserialized, hasSize(1)); + assertThat(deserialized.get(0).getId(), is(EVENT_1.getId())); + } +} \ No newline at end of file diff --git a/src/test/resources/auditevents/auditEvent.json b/src/test/resources/auditevents/auditEvent.json new file mode 100644 index 000000000..a823a976a --- /dev/null +++ b/src/test/resources/auditevents/auditEvent.json @@ -0,0 +1,11 @@ +{ + "event": { + "id": "123", + "userLogin": "bear@gooddata.com", + "occurred": "1993-03-09T00:00:00.000Z", + "recorded": "1993-03-09T00:00:00.000Z", + "userIp": "127.0.0.1", + "success": true, + "type": "login" + } +} \ No newline at end of file diff --git a/src/test/resources/auditevents/auditEventWithParam.json b/src/test/resources/auditevents/auditEventWithParam.json new file mode 100644 index 000000000..342c277c2 --- /dev/null +++ b/src/test/resources/auditevents/auditEventWithParam.json @@ -0,0 +1,14 @@ +{ + "event": { + "id": "123", + "userLogin": "bear@gooddata.com", + "occurred": "1993-03-09T00:00:00.000Z", + "recorded": "1993-03-09T00:00:00.000Z", + "userIp": "127.0.0.1", + "success": true, + "type": "login", + "params" : { + "KEY" : "VALUE" + } + } +} diff --git a/src/test/resources/auditevents/auditEventWithParamAndLink.json b/src/test/resources/auditevents/auditEventWithParamAndLink.json new file mode 100644 index 000000000..1515d0867 --- /dev/null +++ b/src/test/resources/auditevents/auditEventWithParamAndLink.json @@ -0,0 +1,17 @@ +{ + "event": { + "id": "123", + "userLogin": "bear@gooddata.com", + "occurred": "1993-03-09T00:00:00.000Z", + "recorded": "1993-03-09T00:00:00.000Z", + "userIp": "127.0.0.1", + "success": true, + "type": "login", + "params" : { + "KEY" : "VALUE" + }, + "links" : { + "LINK_KEY" : "LINK_VALUE" + } + } +} diff --git a/src/test/resources/auditevents/auditEvents.json b/src/test/resources/auditevents/auditEvents.json new file mode 100644 index 000000000..c37542976 --- /dev/null +++ b/src/test/resources/auditevents/auditEvents.json @@ -0,0 +1,34 @@ +{ + "events": { + "items": [ + { + "event": { + "id": "123", + "userLogin": "bear@gooddata.com", + "occurred": "1993-03-09T00:00:00.000Z", + "recorded": "1993-03-09T00:00:00.000Z", + "userIp": "127.0.0.1", + "success": true, + "type": "login" + } + }, + { + "event": { + "id": "456", + "userLogin": "jane@gooddata.com", + "occurred": "1993-03-09T00:00:00.000Z", + "recorded": "1993-03-09T00:00:00.000Z", + "userIp": "127.0.0.1", + "success": true, + "type": "login" + } + } + ], + "paging": { + "next": "/gdc/domains/default/auditEvents?offset=456" + }, + "links": { + "self": "/gdc/domains/default/auditEvents" + } + } +} \ No newline at end of file diff --git a/src/test/resources/auditevents/auditEventsPage2.json b/src/test/resources/auditevents/auditEventsPage2.json new file mode 100644 index 000000000..8e29a19d9 --- /dev/null +++ b/src/test/resources/auditevents/auditEventsPage2.json @@ -0,0 +1,20 @@ +{ + "events": { + "items": [ + { + "event": { + "id": "456", + "userLogin": "jane@gooddata.com", + "occurred": "1993-03-09T00:00:00.000Z", + "recorded": "1993-03-09T00:00:00.000Z", + "userIp": "127.0.0.1", + "success": true, + "type": "login" + } + } + ], + "links": { + "self": "/gdc/domains/default/auditEvents" + } + } +} \ No newline at end of file diff --git a/src/test/resources/auditevents/emptyAuditEvents.json b/src/test/resources/auditevents/emptyAuditEvents.json new file mode 100644 index 000000000..5b3e8de73 --- /dev/null +++ b/src/test/resources/auditevents/emptyAuditEvents.json @@ -0,0 +1,11 @@ +{ + "events": { + "items": [ + ], + "paging": { + }, + "links": { + "self": "/gdc/domains/default/auditEvents" + } + } +} \ No newline at end of file diff --git a/src/test/resources/auditevents/userAuditEvents.json b/src/test/resources/auditevents/userAuditEvents.json new file mode 100644 index 000000000..8d2fdc6b4 --- /dev/null +++ b/src/test/resources/auditevents/userAuditEvents.json @@ -0,0 +1,23 @@ +{ + "events": { + "items": [ + { + "event": { + "id": "123", + "userLogin": "bear@gooddata.com", + "occurred": "1993-03-09T00:00:00.000Z", + "recorded": "1993-03-09T00:00:00.000Z", + "userIp": "127.0.0.1", + "success": true, + "type": "login" + } + } + ], + "paging": { + "next": "/gdc/account/profile/user123/auditEvents?offset=456&limit=1" + }, + "links": { + "self": "/gdc/account/profile/user123/auditEvents" + } + } +} \ No newline at end of file From 085633b235e502d1e0e27e2b68309f12bbf30b47 Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Wed, 13 Sep 2017 14:42:31 +0200 Subject: [PATCH 005/598] add equals and hashcode because parent class has them Without equals and hashcode overridden really unexpected things happen when comparing or mocking such classes --- pom.xml | 8 ++++- .../auditevent/AuditEventPageRequest.java | 30 ++++++++++++++++++- .../auditevent/AuditEventPageRequestTest.java | 10 +++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a26e518f4..5872c263b 100644 --- a/pom.xml +++ b/pom.xml @@ -181,7 +181,7 @@ com.gooddata gooddata-rest-common - 1.0.0 + 1.0.1 com.gooddata @@ -332,6 +332,12 @@ 0.11 test + + nl.jqno.equalsverifier + equalsverifier + 2.3.3 + test + diff --git a/src/main/java/com/gooddata/auditevent/AuditEventPageRequest.java b/src/main/java/com/gooddata/auditevent/AuditEventPageRequest.java index d548e5a15..43fe3d4a5 100644 --- a/src/main/java/com/gooddata/auditevent/AuditEventPageRequest.java +++ b/src/main/java/com/gooddata/auditevent/AuditEventPageRequest.java @@ -17,7 +17,7 @@ /** * Class to encapsulate time filtering and paging parameters */ -public class AuditEventPageRequest extends PageRequest { +public final class AuditEventPageRequest extends PageRequest { private DateTime from; @@ -106,6 +106,34 @@ public UriComponentsBuilder updateWithPageParams(final UriComponentsBuilder buil return builderWithPaging; } + @Override + protected boolean canEqual(final Object o) { + return o instanceof AuditEventPageRequest; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (!(o instanceof AuditEventPageRequest)) return false; + if (!super.equals(o)) return false; + + final AuditEventPageRequest that = (AuditEventPageRequest) o; + if (!that.canEqual(this)) return false; + + if (from != null ? !from.equals(that.from) : that.from != null) return false; + if (to != null ? !to.equals(that.to) : that.to != null) return false; + return type != null ? type.equals(that.type) : that.type == null; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (from != null ? from.hashCode() : 0); + result = 31 * result + (to != null ? to.hashCode() : 0); + result = 31 * result + (type != null ? type.hashCode() : 0); + return result; + } + @Override public String toString() { return GoodDataToStringBuilder.defaultToString(this); diff --git a/src/test/java/com/gooddata/auditevent/AuditEventPageRequestTest.java b/src/test/java/com/gooddata/auditevent/AuditEventPageRequestTest.java index 50abe1f8a..9f3fed0ba 100644 --- a/src/test/java/com/gooddata/auditevent/AuditEventPageRequestTest.java +++ b/src/test/java/com/gooddata/auditevent/AuditEventPageRequestTest.java @@ -5,6 +5,8 @@ */ package com.gooddata.auditevent; +import nl.jqno.equalsverifier.EqualsVerifier; +import nl.jqno.equalsverifier.Warning; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.springframework.web.util.UriComponentsBuilder; @@ -97,4 +99,12 @@ public void testUpdateWithOnlyTimeIntervalFields() { assertThat(result.build().toUriString(), is("?limit=" + DEFAULT_LIMIT + "&from=" + FROM.toDateTime(DateTimeZone.UTC) + "&to=" + TO.toDateTime(DateTimeZone.UTC))); } + + @Test + public void shouldVerifyEquals() throws Exception { + EqualsVerifier.forClass(AuditEventPageRequest.class) + .withRedefinedSuperclass() + .suppress(Warning.NONFINAL_FIELDS) + .verify(); + } } From 63836f89c3bc26cdcfd32a11a7faaf82c83defd8 Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Thu, 14 Sep 2017 11:39:01 +0200 Subject: [PATCH 006/598] [maven-release-plugin] prepare release gooddata-java-2.15.0 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 5872c263b..2893272be 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 gooddata-java - 2.14.1-SNAPSHOT + 2.15.0 ${project.artifactId} GoodData Java SDK https://github.com/gooddata/gooddata-java @@ -24,7 +24,7 @@ git@github.com:gooddata/gooddata-java.git scm:git:git@github.com:gooddata/gooddata-java.git scm:git:${basedir} - HEAD + gooddata-java-2.15.0 From ba856bfe89bda05e4a2524b94ff6d683a2d97b9a Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Thu, 14 Sep 2017 11:39:02 +0200 Subject: [PATCH 007/598] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2893272be..11ed74408 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 gooddata-java - 2.15.0 + 2.15.1-SNAPSHOT ${project.artifactId} GoodData Java SDK https://github.com/gooddata/gooddata-java @@ -24,7 +24,7 @@ git@github.com:gooddata/gooddata-java.git scm:git:git@github.com:gooddata/gooddata-java.git scm:git:${basedir} - gooddata-java-2.15.0 + HEAD From 0bae9e365df20523cabf8c3bcee95135e06c9c7c Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Thu, 14 Sep 2017 12:21:41 +0200 Subject: [PATCH 008/598] bump version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 035505644..c4aa1ebe2 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ The *GoodData Java SDK* is available in Maven Central Repository, to use it from com.gooddata gooddata-java - 2.14.0 + 2.15.0 ``` See [releases page](https://github.com/gooddata/gooddata-java/releases) for information about versions and notable changes, From b49fe03fe53aa768d2cba4aa932f0a2c782e6e91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Benkovsk=C3=BD?= Date: Thu, 14 Sep 2017 13:33:03 +0200 Subject: [PATCH 009/598] make classes for executing reports and report definitions public --- src/main/java/com/gooddata/export/ExecuteReport.java | 12 ++++++++++-- .../com/gooddata/export/ExecuteReportDefinition.java | 12 ++++++++++-- src/main/java/com/gooddata/export/ReportRequest.java | 2 +- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/gooddata/export/ExecuteReport.java b/src/main/java/com/gooddata/export/ExecuteReport.java index f1ebfe353..f756a2acc 100644 --- a/src/main/java/com/gooddata/export/ExecuteReport.java +++ b/src/main/java/com/gooddata/export/ExecuteReport.java @@ -12,7 +12,10 @@ import static com.gooddata.util.Validate.notNull; -class ExecuteReport extends ReportRequest { +/** + * Report execution request + */ +public class ExecuteReport extends ReportRequest { private final String reportUri; @@ -20,7 +23,12 @@ class ExecuteReport extends ReportRequest { this.reportUri = notNull(reportUri, "reportUri"); } - ExecuteReport(final Report report) { + /** + * Create ExecuteReport based on {@link Report} + * + * @param report to create report execution request for + */ + public ExecuteReport(final Report report) { this(notNull(report, "report").getUri()); } diff --git a/src/main/java/com/gooddata/export/ExecuteReportDefinition.java b/src/main/java/com/gooddata/export/ExecuteReportDefinition.java index cb0fded62..fe3ea0c8e 100644 --- a/src/main/java/com/gooddata/export/ExecuteReportDefinition.java +++ b/src/main/java/com/gooddata/export/ExecuteReportDefinition.java @@ -12,7 +12,10 @@ import static com.gooddata.util.Validate.notNull; -class ExecuteReportDefinition extends ReportRequest { +/** + * Report definition execution request + */ +public class ExecuteReportDefinition extends ReportRequest { private final String reportDefinitionUri; @@ -20,7 +23,12 @@ class ExecuteReportDefinition extends ReportRequest { this.reportDefinitionUri = notNull(reportDefinitionUri, "reportDefinitionUri"); } - ExecuteReportDefinition(final ReportDefinition reportDefinition) { + /** + * Create ExecuteReportDefinition based on {@link ReportDefinition} + * + * @param reportDefinition to create report definition execution request for + */ + public ExecuteReportDefinition(final ReportDefinition reportDefinition) { this(notNull(reportDefinition, "reportDefinition").getUri()); } diff --git a/src/main/java/com/gooddata/export/ReportRequest.java b/src/main/java/com/gooddata/export/ReportRequest.java index 5f52fec6b..290495c06 100644 --- a/src/main/java/com/gooddata/export/ReportRequest.java +++ b/src/main/java/com/gooddata/export/ReportRequest.java @@ -18,7 +18,7 @@ @JsonTypeName("report_req") @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) -abstract class ReportRequest { +public abstract class ReportRequest { public static final String URI = "/gdc/xtab2/executor3"; From 74e13f2a68f43580f90f3bae27034c779ab5181b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Benkovsk=C3=BD?= Date: Thu, 14 Sep 2017 14:03:01 +0200 Subject: [PATCH 010/598] adjust signature of executeReport and make it protected so export service can be extended and executeReport can be reused --- src/main/java/com/gooddata/export/ExportService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/gooddata/export/ExportService.java b/src/main/java/com/gooddata/export/ExportService.java index 548f1b2ac..9015e2471 100644 --- a/src/main/java/com/gooddata/export/ExportService.java +++ b/src/main/java/com/gooddata/export/ExportService.java @@ -98,7 +98,7 @@ public FutureResult export(final Report report, final ExportFormat format, private FutureResult exportReport(final ReportRequest request, final ExportFormat format, final OutputStream output) { notNull(output, "output"); notNull(format, "format"); - final JsonNode execResult = executeReport(request); + final JsonNode execResult = executeReport(ReportRequest.URI, request); final String uri = exportReport(execResult, format); return new PollResult<>(this, new SimplePollHandler(uri, Void.class) { @Override @@ -131,10 +131,10 @@ protected void onFinish() { }); } - private JsonNode executeReport(final ReportRequest request) { + protected JsonNode executeReport(final String executionUri, final ReportRequest request) { try { final ResponseEntity entity = restTemplate - .exchange(ReportRequest.URI, POST, new HttpEntity<>(request), String.class); + .exchange(executionUri, POST, new HttpEntity<>(request), String.class); return mapper.readTree(entity.getBody()); } catch (GoodDataException | RestClientException e) { throw new ExportException("Unable to execute report", e); From a8e8fb1f2f8d5ec16b5d43bb9f4d8dba0579bcc2 Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Fri, 15 Sep 2017 14:19:27 +0200 Subject: [PATCH 011/598] [maven-release-plugin] prepare release gooddata-java-2.15.1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 11ed74408..2a5460a22 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 gooddata-java - 2.15.1-SNAPSHOT + 2.15.1 ${project.artifactId} GoodData Java SDK https://github.com/gooddata/gooddata-java @@ -24,7 +24,7 @@ git@github.com:gooddata/gooddata-java.git scm:git:git@github.com:gooddata/gooddata-java.git scm:git:${basedir} - HEAD + gooddata-java-2.15.1 From d18672f01098dfbc9a03854a84dd1f9538032ec7 Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Fri, 15 Sep 2017 14:19:27 +0200 Subject: [PATCH 012/598] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2a5460a22..c606a168a 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 gooddata-java - 2.15.1 + 2.15.2-SNAPSHOT ${project.artifactId} GoodData Java SDK https://github.com/gooddata/gooddata-java @@ -24,7 +24,7 @@ git@github.com:gooddata/gooddata-java.git scm:git:git@github.com:gooddata/gooddata-java.git scm:git:${basedir} - gooddata-java-2.15.1 + HEAD From 922ed7404405ec2a97ffe7a8765bbc39e719d62a Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Fri, 15 Sep 2017 15:02:12 +0200 Subject: [PATCH 013/598] bump version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c4aa1ebe2..5c01da78f 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ The *GoodData Java SDK* is available in Maven Central Repository, to use it from com.gooddata gooddata-java - 2.15.0 + 2.15.1 ``` See [releases page](https://github.com/gooddata/gooddata-java/releases) for information about versions and notable changes, From 21d99c5351516ed6f5dc491ce41622e94b9cc893 Mon Sep 17 00:00:00 2001 From: Martin Matula Date: Mon, 18 Sep 2017 23:07:35 +0200 Subject: [PATCH 014/598] Add support for extracting object id for metadata objects. There are other methods in the SDK that work with object ID (e.g. MetadataService.getObjById()) and sometimes it may be useful to remember just an ID of object (rather than the whole URI) to be able to retrieve it later. However, there is no straightforward way to get ID of an object (it must be parsed from the URI). Adding method for obtaining object ID makes the SDK more complete and is consistent with other parts of the SDK (ProjectService). --- src/main/java/com/gooddata/md/AbstractObj.java | 13 +++++++++++++ src/main/java/com/gooddata/md/Entry.java | 13 +++++++++++++ src/main/java/com/gooddata/md/Meta.java | 14 ++++++++++++++ src/test/java/com/gooddata/md/AttributeTest.java | 1 + src/test/java/com/gooddata/md/EntryTest.java | 6 ++++-- src/test/java/com/gooddata/md/MetaTest.java | 4 +++- src/test/java/com/gooddata/md/ObjTest.java | 4 +++- 7 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/gooddata/md/AbstractObj.java b/src/main/java/com/gooddata/md/AbstractObj.java index fef8707b1..9779d7690 100644 --- a/src/main/java/com/gooddata/md/AbstractObj.java +++ b/src/main/java/com/gooddata/md/AbstractObj.java @@ -26,6 +26,15 @@ protected AbstractObj(@JsonProperty("meta") Meta meta) { this.meta = meta; } + /** + * Returns internally generated ID of the object (that's part of the object URI). + * @return internal ID of the object + */ + @JsonIgnore + public String getId() { + return Obj.OBJ_TEMPLATE.match(getUri()).get("objId"); + } + @JsonIgnore public String getAuthor() { return meta.getAuthor(); @@ -96,6 +105,10 @@ public void setDeprecated(Boolean deprecated) { meta.setDeprecated(deprecated); } + /** + * Returns user-specified identifier of the object. + * @return user-specified object identifier + */ @JsonIgnore public String getIdentifier() { return meta.getIdentifier(); diff --git a/src/main/java/com/gooddata/md/Entry.java b/src/main/java/com/gooddata/md/Entry.java index 90b2deef3..7a3c6bb51 100644 --- a/src/main/java/com/gooddata/md/Entry.java +++ b/src/main/java/com/gooddata/md/Entry.java @@ -72,6 +72,15 @@ public String getLink() { return getUri(); } + /** + * Returns internally generated ID of the object (that's part of the object URI). + * @return internal ID of the object + */ + @JsonIgnore + public String getId() { + return Obj.OBJ_TEMPLATE.match(getUri()).get("objId"); + } + @JsonIgnore public String getUri() { return uri; @@ -110,6 +119,10 @@ public Boolean getDeprecated() { return deprecated; } + /** + * Returns user-specified identifier of the object. + * @return user-specified object identifier + */ public String getIdentifier() { return identifier; } diff --git a/src/main/java/com/gooddata/md/Meta.java b/src/main/java/com/gooddata/md/Meta.java index 12b94d914..b38177b61 100644 --- a/src/main/java/com/gooddata/md/Meta.java +++ b/src/main/java/com/gooddata/md/Meta.java @@ -5,6 +5,7 @@ */ package com.gooddata.md; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.gooddata.util.*; import com.fasterxml.jackson.annotation.JsonCreator; @@ -98,6 +99,15 @@ public Meta(String title, String summary) { this.summary = summary; } + /** + * Returns internally generated ID of the object (that's part of the object URI). + * @return internal ID of the object + */ + @JsonIgnore + public String getId() { + return Obj.OBJ_TEMPLATE.match(getUri()).get("objId"); + } + public String getAuthor() { return author; } @@ -169,6 +179,10 @@ public void setDeprecated(Boolean deprecated) { this.deprecated = deprecated; } + /** + * Returns user-specified identifier of the object. + * @return user-specified object identifier + */ public String getIdentifier() { return identifier; } diff --git a/src/test/java/com/gooddata/md/AttributeTest.java b/src/test/java/com/gooddata/md/AttributeTest.java index 0f3eca1b6..8b90a4142 100644 --- a/src/test/java/com/gooddata/md/AttributeTest.java +++ b/src/test/java/com/gooddata/md/AttributeTest.java @@ -27,6 +27,7 @@ public class AttributeTest { public void shouldDeserialize() throws Exception { final Attribute attribute = readObjectFromResource("/md/attribute.json", Attribute.class); assertThat(attribute, is(notNullValue())); + assertThat(attribute.getId(), is("28")); final Collection displayForms = attribute.getDisplayForms(); assertThat(displayForms, is(notNullValue())); diff --git a/src/test/java/com/gooddata/md/EntryTest.java b/src/test/java/com/gooddata/md/EntryTest.java index 206e5e83d..dbe505e45 100644 --- a/src/test/java/com/gooddata/md/EntryTest.java +++ b/src/test/java/com/gooddata/md/EntryTest.java @@ -22,7 +22,8 @@ public class EntryTest { - public static final String URI = "/gdc/md/PROJECT_ID/obj/ENTRY_ID"; + public static final String OBJ_ID = "ENTRY_ID"; + public static final String URI = "/gdc/md/PROJECT_ID/obj/" + OBJ_ID; public static final String AUTHOR = "/gdc/account/profile/AUTHOR_USER_ID"; public static final String CONTRIBUTOR = "/gdc/account/profile/CONTRIBUTOR_USER_ID"; public static final DateTime CREATED = new DateTime(2014, 4, 11, 13, 45, 54, DateTimeZone.UTC); @@ -41,6 +42,7 @@ public class EntryTest { public void testDeserialize() throws Exception { final Entry entry = readObjectFromResource("/md/entry.json", Entry.class); assertThat(entry, is(notNullValue())); + assertThat(entry.getId(), is(OBJ_ID)); assertThat(entry.getLink(), is(URI)); assertThat(entry.getUri(), is(URI)); assertThat(entry.getTitle(), is(TITLE)); @@ -73,4 +75,4 @@ public void testToStringFormat() { assertThat(entry.toString(), matchesPattern(Entry.class.getSimpleName() + "\\[.*\\]")); } -} \ No newline at end of file +} diff --git a/src/test/java/com/gooddata/md/MetaTest.java b/src/test/java/com/gooddata/md/MetaTest.java index 74edff52b..2670e752f 100644 --- a/src/test/java/com/gooddata/md/MetaTest.java +++ b/src/test/java/com/gooddata/md/MetaTest.java @@ -31,7 +31,8 @@ public class MetaTest { public static final DateTime UPDATED = new DateTime(2014, 4, 11, 13, 45, 57, DateTimeZone.UTC); public static final String CATEGORY = "attributeDisplayForm"; public static final Set TAGS = new LinkedHashSet<>(asList("TAG1", "TAG2")); - public static final String URI = "/gdc/md/PROJECT_ID/obj/OBJ_ID"; + public static final String OBJ_ID = "OBJ_ID"; + public static final String URI = "/gdc/md/PROJECT_ID/obj/" + OBJ_ID; public static final boolean DEPRECATED = false; public static final String IDENTIFIER = "attr.person.id.name"; public static final boolean LOCKED = false; @@ -43,6 +44,7 @@ public class MetaTest { public void testDeserialization() throws Exception { final Meta meta = readObjectFromResource("/md/meta.json", Meta.class); assertThat(meta, is(notNullValue())); + assertThat(meta.getId(), is(OBJ_ID)); assertThat(meta.getAuthor(), is(AUTHOR)); assertThat(meta.getContributor(), is(CONTRIBUTOR)); assertThat(meta.getCreated(), is(CREATED)); diff --git a/src/test/java/com/gooddata/md/ObjTest.java b/src/test/java/com/gooddata/md/ObjTest.java index 38635aeb6..45b0cfe7d 100644 --- a/src/test/java/com/gooddata/md/ObjTest.java +++ b/src/test/java/com/gooddata/md/ObjTest.java @@ -31,7 +31,8 @@ public class ObjTest { public static final DateTime UPDATED = new DateTime(2014, 4, 11, 13, 45, 57, DateTimeZone.UTC); public static final String CATEGORY = "attributeDisplayForm"; public static final Set TAGS = new LinkedHashSet<>(asList("TAG1", "TAG2")); - public static final String URI = "/gdc/md/PROJECT_ID/obj/OBJ_ID"; + public static final String OBJ_ID = "OBJ_ID"; + public static final String URI = "/gdc/md/PROJECT_ID/obj/" + OBJ_ID; public static final boolean DEPRECATED = false; public static final String IDENTIFIER = "attr.person.id.name"; public static final boolean LOCKED = false; @@ -42,6 +43,7 @@ public void testDeserialization() throws Exception { final AbstractObj obj = readObjectFromResource("/md/objCommon.json", ConcreteObj.class); assertThat(obj, is(notNullValue())); + assertThat(obj.getId(), is(OBJ_ID)); assertThat(obj.getAuthor(), is(AUTHOR)); assertThat(obj.getContributor(), is(CONTRIBUTOR)); assertThat(obj.getCreated(), is(CREATED)); From b96eaa5188144a0c86f11e4639d3b93f39ec550e Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Tue, 19 Sep 2017 16:43:32 +0200 Subject: [PATCH 015/598] delete duplicated class in rest-common --- .../util/GoodDataToStringBuilder.java | 37 ----- .../util/GoodDataToStringBuilderTest.java | 149 ------------------ 2 files changed, 186 deletions(-) delete mode 100644 src/main/java/com/gooddata/util/GoodDataToStringBuilder.java delete mode 100644 src/test/java/com/gooddata/util/GoodDataToStringBuilderTest.java diff --git a/src/main/java/com/gooddata/util/GoodDataToStringBuilder.java b/src/main/java/com/gooddata/util/GoodDataToStringBuilder.java deleted file mode 100644 index cefc587c4..000000000 --- a/src/main/java/com/gooddata/util/GoodDataToStringBuilder.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.builder.RecursiveToStringStyle; -import org.apache.commons.lang3.builder.ReflectionToStringBuilder; - -/** - * GoodDataToStringBuilder enables to create string representation based on fields of an object and exclude specified fields. - * links field is excluded by default. - */ -public class GoodDataToStringBuilder extends ReflectionToStringBuilder { - - private static final String LINKS_FIELD_NAME = "links"; - - public GoodDataToStringBuilder(Object object) { - super(object, RecursiveToStringStyle.SHORT_PREFIX_STYLE); - setExcludeFieldNames(LINKS_FIELD_NAME); - } - - /** - * creates String representation of an object using reflection to get fields of an object. - * links field of an object is ignored by default, allows to specify more fields to be excluded - * - * @param object to create String representation for - * @param excludeFieldNames name of fields of an object to be excluded from String representation - * @return String representation, which excludes links field by default - */ - public static String defaultToString(Object object, String... excludeFieldNames) { - return new GoodDataToStringBuilder(object).setExcludeFieldNames(ArrayUtils.add(excludeFieldNames, LINKS_FIELD_NAME)) - .toString(); - } -} diff --git a/src/test/java/com/gooddata/util/GoodDataToStringBuilderTest.java b/src/test/java/com/gooddata/util/GoodDataToStringBuilderTest.java deleted file mode 100644 index 00d92fc3d..000000000 --- a/src/test/java/com/gooddata/util/GoodDataToStringBuilderTest.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.util; - -import static java.lang.String.format; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.core.Is.is; -import static org.hamcrest.MatcherAssert.assertThat; - -import org.testng.annotations.Test; - -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -/** - * two nested classes have toString() method implemented using {@link GoodDataToStringBuilder} and check if - * output of their toString() methods are as expected - */ -public class GoodDataToStringBuilderTest { - - //static nested classes are denoted with outer class, we need a name of outer class in this test - private static final String OUTER_CLASS_NAME = GoodDataToStringBuilderTest.class.getSimpleName(); - - private static final String TEST_CLASS_NAME = TestClass.class.getSimpleName(); - - private static final String ANOTHER_TEST_CLASS_NAME = AnotherTestClass.class.getSimpleName(); - - private static final String CLASS_WITH_ADDITIONAL_PARAM = ClassWithAdditionalParam.class.getSimpleName(); - - private static final String STRING_FIELD_VALUE = "STRING_FIELD"; - - private static final Long LONG_FIELD_VALUE = 10L; - - private static final List LIST_VALUE = Arrays.asList(1, 2, 3); - - private static final String ANOTHER_TEST_CLASS_STRING_EXPECTED = format("%s.%s[stringField=%s]", - OUTER_CLASS_NAME, ANOTHER_TEST_CLASS_NAME, STRING_FIELD_VALUE); - - @Test - public void testDefaultToStringNonRecursive() throws Exception { - final AnotherTestClass anotherTestClass = new AnotherTestClass(); - - final String toStringResult = anotherTestClass.toString(); - - assertThat(toStringResult, is(notNullValue())); - assertThat(toStringResult, is(ANOTHER_TEST_CLASS_STRING_EXPECTED)); - - } - - /** - * TestClass have field reference to {@link AnotherTestClass} - */ - @Test - public void testDefaultToStringRecursive() { - final TestClass testClass = new TestClass(); - - final String toStringResult = testClass.toString(); - - assertThat(toStringResult, is(notNullValue())); - assertThat(toStringResult, is(format("%s.%s[stringField=%s,longField=%d,list=%s,anotherTestClass=%s]", - OUTER_CLASS_NAME, TEST_CLASS_NAME, STRING_FIELD_VALUE, LONG_FIELD_VALUE, LIST_VALUE.toString(), - ANOTHER_TEST_CLASS_STRING_EXPECTED))); - } - - @Test - public void testToStringIncludeAdditionalParam() { - final ClassWithAdditionalParam classWithAdditionalParam = new ClassWithAdditionalParam(); - - final String toStringResult = classWithAdditionalParam.toString(); - - assertThat(toStringResult, is(notNullValue())); - assertThat(toStringResult, is(format("%s.%s[newField=%s]", - OUTER_CLASS_NAME, CLASS_WITH_ADDITIONAL_PARAM, STRING_FIELD_VALUE))); - } - - static class TestClass { - private Map links = new LinkedHashMap() {{ - put("self", "/gdc/link"); - }}; - private String stringField = STRING_FIELD_VALUE; - private Long longField = LONG_FIELD_VALUE; - private String toBeExcludedField = "SHOULD_NOT_BE_THERE"; - private String anotherToBeExcludedField = "ALSO_SHOULD_NOT_BE_THERE"; - private List list = LIST_VALUE; - private AnotherTestClass anotherTestClass = new AnotherTestClass(); - - public Map getLinks() { - return links; - } - - public String getStringField() { - return stringField; - } - - public Long getLongField() { - return longField; - } - - public String getToBeExcludedField() { - return toBeExcludedField; - } - - public String getAnotherToBeExcludedField() { - return anotherToBeExcludedField; - } - - public List getList() { - return list; - } - - public AnotherTestClass getTestClass2() { - return anotherTestClass; - } - - @Override - public String toString() { - return GoodDataToStringBuilder.defaultToString(this, "toBeExcludedField", "anotherToBeExcludedField"); - } - } - - static class AnotherTestClass { - private Map links = new LinkedHashMap() {{ - put("self", "/gdc/link2"); - }}; - - private String stringField = STRING_FIELD_VALUE; - - public String getStringField() { - return stringField; - } - - @Override - public String toString() { - return GoodDataToStringBuilder.defaultToString(this); - } - } - - static class ClassWithAdditionalParam { - @Override - public String toString() { - return new GoodDataToStringBuilder(this).append("newField", STRING_FIELD_VALUE).toString(); - } - } -} From 641e56fa2df10954c4786b6f1ac5587b475bd4ba Mon Sep 17 00:00:00 2001 From: Martin Matula Date: Sun, 24 Sep 2017 01:52:35 +0200 Subject: [PATCH 016/598] Add support for metadata bulk get Metadata API supports bulk retrieval of objects by their URIs. The SDK did not support this, so one had to retrieve objects one by one. Now, with the getObjsByUris() methods it is possible to retrieve multiple objects using a single request. Close #525 --- src/main/java/com/gooddata/md/BulkGet.java | 44 +++++++++ .../java/com/gooddata/md/BulkGetUris.java | 58 ++++++++++++ .../java/com/gooddata/md/MetadataService.java | 37 +++++++- src/main/java/com/gooddata/md/Obj.java | 21 +++++ .../com/gooddata/md/MetadataServiceAT.java | 37 ++++++-- .../com/gooddata/md/MetadataServiceIT.java | 48 ++++++++++ .../com/gooddata/md/MetadataServiceTest.java | 39 ++++++++ src/test/resources/md/bulk-get.json | 90 +++++++++++++++++++ 8 files changed, 361 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/gooddata/md/BulkGet.java create mode 100644 src/main/java/com/gooddata/md/BulkGetUris.java create mode 100644 src/test/resources/md/bulk-get.json diff --git a/src/main/java/com/gooddata/md/BulkGet.java b/src/main/java/com/gooddata/md/BulkGet.java new file mode 100644 index 000000000..9d0b4574c --- /dev/null +++ b/src/main/java/com/gooddata/md/BulkGet.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.md; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.util.GoodDataToStringBuilder; + +import java.util.Collection; + +/** + * Metadata bulk get result + */ +@JsonTypeName("objects") +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +class BulkGet { + + public static final String URI = "/gdc/md/{projectId}/objects/get"; + + private final Collection items; + + @JsonCreator + BulkGet(@JsonProperty("items") Collection items) { + this.items = items; + } + + public Collection getItems() { + return items; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } +} diff --git a/src/main/java/com/gooddata/md/BulkGetUris.java b/src/main/java/com/gooddata/md/BulkGetUris.java new file mode 100644 index 000000000..ccede5202 --- /dev/null +++ b/src/main/java/com/gooddata/md/BulkGetUris.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. + * This source code is licensed under the BSD-style license found in the + * LICENSE.txt file in the root directory of this source tree. + */ +package com.gooddata.md; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.gooddata.util.GoodDataToStringBuilder; + +import java.util.Collection; + +import static com.gooddata.util.Validate.notNull; + +/** + * Metadata bulk get request body representation. + * Serialization only. + */ +@JsonTypeName("get") +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +class BulkGetUris { + + private final Collection items; + + BulkGetUris(Collection items) { + notNull(items, "items"); + this.items = items; + } + + @JsonProperty("items") + public Collection getItems() { + return items; + } + + @Override + public String toString() { + return GoodDataToStringBuilder.defaultToString(this); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + BulkGetUris that = (BulkGetUris) o; + + if (!items.equals(that.items)) return false; + + return true; + } + + @Override + public int hashCode() { + return items.hashCode(); + } +} diff --git a/src/main/java/com/gooddata/md/MetadataService.java b/src/main/java/com/gooddata/md/MetadataService.java index 021cff3f1..419fdf317 100644 --- a/src/main/java/com/gooddata/md/MetadataService.java +++ b/src/main/java/com/gooddata/md/MetadataService.java @@ -15,7 +15,11 @@ import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import static com.gooddata.util.Validate.noNullElements; @@ -58,7 +62,7 @@ public T createObj(Project project, T obj) { } if (response == null) { - throw new ObjCreateException("empty response from API call", obj); + throw new ObjCreateException("Received empty response from API call.", obj); } return response; } @@ -83,7 +87,7 @@ public T getObjByUri(String uri, Class cls) { if (result != null) { return result; } else { - throw new GoodDataException("empty response from API call"); + throw new GoodDataException("Received empty response from API call."); } } catch (GoodDataRestException e) { if (HttpStatus.NOT_FOUND.value() == e.getStatusCode()) { @@ -96,6 +100,31 @@ public T getObjByUri(String uri, Class cls) { } } + /** + * Retrieves a collection of objects corresponding to the supplied collection of URIs. + * + * @param project project that contains the objects to be retrieved + * @param uris collection of URIs + * @return collection of metadata objects corresponding to the supplied URIs + */ + public Collection getObjsByUris(Project project, Collection uris) { + notNull(project, "project"); + notNull(project.getId(), "project.id"); + notNull(uris, "uris"); + + try { + final BulkGet result = restTemplate.postForObject(BulkGet.URI, new BulkGetUris(uris), BulkGet.class, project.getId()); + + if (result != null) { + return result.getItems(); + } else { + throw new GoodDataException("Received empty response from API call."); + } + } catch (RestClientException e) { + throw new GoodDataException("Unable to get objects. Some of the supplied URIs may be malformed.", e); + } + } + /** * Update given metadata object. * @@ -248,7 +277,7 @@ public Collection find(Project project, Class cl if (queryResult != null && queryResult.getEntries() != null) { return filterEntries(queryResult.getEntries(), restrictions); } else { - throw new GoodDataException("empty response from API call"); + throw new GoodDataException("Received empty response from API call."); } } catch (RestClientException e) { throw new GoodDataException("Unable to query metadata: " + type, e); diff --git a/src/main/java/com/gooddata/md/Obj.java b/src/main/java/com/gooddata/md/Obj.java index d57d5cba2..17b261452 100644 --- a/src/main/java/com/gooddata/md/Obj.java +++ b/src/main/java/com/gooddata/md/Obj.java @@ -5,11 +5,32 @@ */ package com.gooddata.md; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.gooddata.md.report.Report; +import com.gooddata.md.report.ReportDefinition; import org.springframework.web.util.UriTemplate; /** * First class metadata object - only dto objects, which have URI pointing to themselves should implement this. */ +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT) +@JsonSubTypes({ + @JsonSubTypes.Type(Attribute.class), + @JsonSubTypes.Type(AttributeDisplayForm.class), + @JsonSubTypes.Type(Column.class), + @JsonSubTypes.Type(DataLoadingColumn.class), + @JsonSubTypes.Type(Dataset.class), + @JsonSubTypes.Type(Dimension.class), + @JsonSubTypes.Type(Fact.class), + @JsonSubTypes.Type(Metric.class), + @JsonSubTypes.Type(ProjectDashboard.class), + @JsonSubTypes.Type(Report.class), + @JsonSubTypes.Type(ReportDefinition.class), + @JsonSubTypes.Type(ScheduledMail.class), + @JsonSubTypes.Type(Table.class), + @JsonSubTypes.Type(TableDataLoad.class), +}) public interface Obj { String URI = "/gdc/md/{projectId}/obj"; diff --git a/src/test/java/com/gooddata/md/MetadataServiceAT.java b/src/test/java/com/gooddata/md/MetadataServiceAT.java index c9528b04a..0311886be 100644 --- a/src/test/java/com/gooddata/md/MetadataServiceAT.java +++ b/src/test/java/com/gooddata/md/MetadataServiceAT.java @@ -5,15 +5,6 @@ */ package com.gooddata.md; -import static com.gooddata.export.ExportFormat.PDF; -import static com.gooddata.export.ExportFormat.XLS; -import static com.gooddata.md.Restriction.identifier; -import static com.gooddata.md.report.MetricGroup.METRIC_GROUP; -import static java.util.Arrays.asList; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; -import static org.testng.AssertJUnit.assertTrue; - import com.gooddata.AbstractGoodDataAT; import com.gooddata.md.ProjectDashboard.Tab; import com.gooddata.md.report.AttributeInGrid; @@ -33,6 +24,19 @@ import java.util.Set; import java.util.stream.Collectors; +import static com.gooddata.export.ExportFormat.PDF; +import static com.gooddata.export.ExportFormat.XLS; +import static com.gooddata.md.Restriction.identifier; +import static com.gooddata.md.report.MetricGroup.METRIC_GROUP; +import static java.util.Arrays.asList; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.hasItems; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.testng.AssertJUnit.assertTrue; + /** * Metadata acceptance tests. */ @@ -125,6 +129,21 @@ public void usedByBatch() { assertThat(usage2.getUsedBy(), hasSize(5)); } + @Test(groups = "md", dependsOnGroups = "model") + public void getObjsByUris() throws Exception { + final MetadataService md = gd.getMetadataService(); + + final Map uris = + md.identifiersToUris(project, asList( + "attr.person.department", + "attr.person.role", + "fact.person.shoesize" + )); + + final Collection objects = md.getObjsByUris(project, uris.values()); + assertThat(objects.stream().map(Obj::getUri).collect(Collectors.toSet()), is(new HashSet<>(uris.values()))); + } + @Test(groups = "md", dependsOnMethods = "createReport") public void createScheduledMail() throws Exception { final MetadataService md = gd.getMetadataService(); diff --git a/src/test/java/com/gooddata/md/MetadataServiceIT.java b/src/test/java/com/gooddata/md/MetadataServiceIT.java index 231a3a6c8..6aa1ec848 100644 --- a/src/test/java/com/gooddata/md/MetadataServiceIT.java +++ b/src/test/java/com/gooddata/md/MetadataServiceIT.java @@ -28,7 +28,9 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.hasSize; public class MetadataServiceIT extends AbstractGoodDataIT { @@ -38,9 +40,13 @@ public class MetadataServiceIT extends AbstractGoodDataIT { private static final String OBJ_URI = "/gdc/md/PROJECT_ID/obj"; private static final String OBJ_URI2 = "/gdc/md/PROJECT_ID/obj2"; private static final String SPECIFIC_OBJ_URI = "/gdc/md/PROJECT_ID/obj/ID"; + private static final String BULK_GET_URI = "/gdc/md/PROJECT_ID/objects/get"; private static final String ID = "ID"; private static final String TITLE = "TITLE"; private static final String TITLE2 = "TITLE2"; + private static final String METRIC_URL = "/gdc/md/PROJECT_ID/obj/METRIC_ID"; + private static final String FACT_URL = "/gdc/md/PROJECT_ID/obj/FACT_ID"; + private static final String DATASET_URL = "/gdc/md/PROJECT_ID/obj/DATASET_ID"; private Project project; private Metric metricInput; @@ -73,6 +79,48 @@ public void testUsedBy() throws Exception { assertThat(result.iterator().next().getTitle(), is(TITLE)); } + @Test + public void testGetObjsByUris() throws Exception { + onRequest() + .havingMethodEqualTo("POST") + .havingPathEqualTo(BULK_GET_URI) + .havingBody(allOf(containsString(DATASET_URL), containsString(FACT_URL), containsString(METRIC_URL))) + .respond() + .withStatus(200) + .withBody(readFromResource("/md/bulk-get.json")); + + final Collection result = gd.getMetadataService().getObjsByUris(project, Arrays.asList( + DATASET_URL, + FACT_URL, + METRIC_URL + )); + + Dataset dataset = null; + Fact fact = null; + Metric metric = null; + + for (Obj obj : result) { + if (obj instanceof Dataset) { + dataset = (Dataset) obj; + } else if (obj instanceof Fact) { + fact = (Fact) obj; + } else if (obj instanceof Metric) { + metric = (Metric) obj; + } + } + + assertThat(result, hasSize(3)); + assertThat(dataset, is(notNullValue())); + //noinspection ConstantConditions + assertThat(dataset.getTitle(), is("Date (Org minDate-first deal)")); + assertThat(fact, is(notNullValue())); + //noinspection ConstantConditions + assertThat(fact.getTitle(), is("Person Shoe Size")); + assertThat(metric, is(notNullValue())); + //noinspection ConstantConditions + assertThat(metric.getTitle(), is("Person Name")); + } + @Test public void testUsedByBatch() throws Exception { final List entryList = new ArrayList<>(); diff --git a/src/test/java/com/gooddata/md/MetadataServiceTest.java b/src/test/java/com/gooddata/md/MetadataServiceTest.java index 443e5d001..c3730b332 100644 --- a/src/test/java/com/gooddata/md/MetadataServiceTest.java +++ b/src/test/java/com/gooddata/md/MetadataServiceTest.java @@ -130,6 +130,45 @@ public void testUpdateObjRestException() throws Exception { service.updateObj(obj); } + @Test(expectedExceptions = IllegalArgumentException.class) + public void testGetObjsByUrisNullProject() throws Exception { + service.getObjsByUris(null, Collections.emptyList()); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testGetObjsByUrisNullUris() throws Exception { + service.getObjsByUris(project, null); + } + + @Test + public void testGetObjsByUris() throws Exception { + final BulkGetUris request = new BulkGetUris(Collections.singletonList(URI)); + final BulkGet response = new BulkGet(Collections.singletonList(mock(Obj.class))); + when(restTemplate.postForObject(BulkGet.URI, request, BulkGet.class, PROJECT_ID)).thenReturn(response); + + final Collection result = service.getObjsByUris(project, request.getItems()); + assertThat(result, is(response.getItems())); + } + + @Test(expectedExceptions = GoodDataException.class) + public void testGetObjsByUrisWithClientSideHTTPError() throws Exception { + final BulkGetUris request = new BulkGetUris(Collections.singletonList("")); + when(restTemplate.postForObject(BulkGet.URI, request, BulkGet.class, PROJECT_ID)).thenThrow(new RestClientException("")); + service.getObjsByUris(project, request.getItems()); + } + + @Test(expectedExceptions = GoodDataRestException.class) + public void testGetObjsByUrisWithServerSideHTTPError() throws Exception { + final BulkGetUris request = new BulkGetUris(Collections.singletonList("")); + when(restTemplate.postForObject(BulkGet.URI, request, BulkGet.class, PROJECT_ID)).thenThrow(new GoodDataRestException(500, "", "", "", "")); + service.getObjsByUris(project, request.getItems()); + } + + @Test(expectedExceptions = GoodDataException.class) + public void testGetObjsByUrisWithNoResponseFromAPI() throws Exception { + service.getObjsByUris(project, Collections.emptyList()); + } + @Test(expectedExceptions = IllegalArgumentException.class) public void testGetObjByUriNullUri() throws Exception { service.getObjByUri(null, Obj.class); diff --git a/src/test/resources/md/bulk-get.json b/src/test/resources/md/bulk-get.json new file mode 100644 index 000000000..d8936e8b7 --- /dev/null +++ b/src/test/resources/md/bulk-get.json @@ -0,0 +1,90 @@ +{ + "objects": { + "items": [ + { + "dataSet": { + "content": { + "ties": [ + "/gdc/md/PROJECT_ID/obj/688400" + ], + "mode": "", + "facts": [ + "/gdc/md/PROJECT_ID/obj/688401", + "/gdc/md/PROJECT_ID/obj/688402" + ], + "dataLoadingColumns": [], + "attributes": [ + "/gdc/md/PROJECT_ID/obj/688399", + "/gdc/md/PROJECT_ID/obj/688411", + "/gdc/md/PROJECT_ID/obj/688425" + ] + }, + "links": { + "dataUploads": "/gdc/md/PROJECT_ID/data/uploads/688536" + }, + "meta": { + "author": "/gdc/account/profile/PROFILE_ID", + "uri": "/gdc/md/PROJECT_ID/obj/DATASET_ID", + "tags": "", + "created": "2015-01-28 17:35:47", + "identifier": "DATASET_ID.dataset.dt", + "deprecated": "0", + "summary": "DataSet Date", + "title": "Date (Org minDate-first deal)", + "category": "dataSet", + "updated": "2015-01-28 17:35:47", + "contributor": "/gdc/account/profile/PROFILE_ID" + } + } + }, { + "fact" : { + "content" : { + "expr" : [ + { + "data" : "/gdc/md/PROJECT_ID/obj/COL_ID", + "type" : "col" + } + ], + "folders" : [ + "/gdc/md/PROJECT_ID/obj/FOLDER_ID", + "/gdc/md/PROJECT_ID/obj/FOLDER_ID2" + ] + }, + "meta" : { + "author" : "/gdc/account/profile/AUTHOR_ID", + "uri" : "/gdc/md/PROJECT_ID/obj/FACT_ID", + "tags" : "", + "created" : "2014-04-11 13:45:53", + "identifier" : "fact.person.shoesize", + "deprecated" : "0", + "summary" : "", + "title" : "Person Shoe Size", + "category" : "fact", + "updated" : "2014-04-11 13:46:52", + "contributor" : "/gdc/account/profile/CONTRIBUTOR_ID" + } + } + }, { + "metric" : { + "content" : { + "expression" : "[/gdc/md/PROJECT_ID/obj/EXPR_ID]", + "format" : "FORMAT" + }, + "meta" : { + "author" : "/gdc/account/profile/USER_ID", + "uri" : "/gdc/md/PROJECT_ID/obj/METRIC_ID", + "tags" : "", + "created" : "2014-04-11 13:45:56", + "identifier" : "attr.person.id.name", + "deprecated" : "0", + "summary" : "", + "title" : "Person Name", + "category" : "attributeDisplayForm", + "updated" : "2014-04-11 13:45:56", + "contributor" : "/gdc/account/profile/USER_ID" + } + } + } + ] + } +} From f53c32dc2bef579a4d7b9e9f819db7dd6dbe2d65 Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Wed, 27 Sep 2017 16:55:14 +0200 Subject: [PATCH 017/598] [maven-release-plugin] prepare release gooddata-java-2.16.0 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index c606a168a..8805300fb 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 gooddata-java - 2.15.2-SNAPSHOT + 2.16.0 ${project.artifactId} GoodData Java SDK https://github.com/gooddata/gooddata-java @@ -24,7 +24,7 @@ git@github.com:gooddata/gooddata-java.git scm:git:git@github.com:gooddata/gooddata-java.git scm:git:${basedir} - HEAD + gooddata-java-2.16.0 From a6830a3ae592c592d435b2c81c99cc2356d81448 Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Wed, 27 Sep 2017 16:55:14 +0200 Subject: [PATCH 018/598] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 8805300fb..43822207f 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 gooddata-java - 2.16.0 + 2.16.1-SNAPSHOT ${project.artifactId} GoodData Java SDK https://github.com/gooddata/gooddata-java @@ -24,7 +24,7 @@ git@github.com:gooddata/gooddata-java.git scm:git:git@github.com:gooddata/gooddata-java.git scm:git:${basedir} - gooddata-java-2.16.0 + HEAD From a0ddca28bbea22a201833aa1a046aed18db9c6cf Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Wed, 27 Sep 2017 17:05:32 +0200 Subject: [PATCH 019/598] bump version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c01da78f..5a821e6f9 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ The *GoodData Java SDK* is available in Maven Central Repository, to use it from com.gooddata gooddata-java - 2.15.1 + 2.16.0 ``` See [releases page](https://github.com/gooddata/gooddata-java/releases) for information about versions and notable changes, From 7a2dd5afe914fe31cbd5e47cc956f3a864375422 Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Thu, 28 Sep 2017 23:39:10 +0200 Subject: [PATCH 020/598] pronounce test starting Spring container as integration test --- ...aBeansAsServicesTest.java => GoodDataBeansAsServicesIT.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/test/java/com/gooddata/spring/{GoodDataBeansAsServicesTest.java => GoodDataBeansAsServicesIT.java} (97%) diff --git a/src/test/java/com/gooddata/spring/GoodDataBeansAsServicesTest.java b/src/test/java/com/gooddata/spring/GoodDataBeansAsServicesIT.java similarity index 97% rename from src/test/java/com/gooddata/spring/GoodDataBeansAsServicesTest.java rename to src/test/java/com/gooddata/spring/GoodDataBeansAsServicesIT.java index 9355f06fc..0e7e84808 100644 --- a/src/test/java/com/gooddata/spring/GoodDataBeansAsServicesTest.java +++ b/src/test/java/com/gooddata/spring/GoodDataBeansAsServicesIT.java @@ -25,7 +25,7 @@ import static org.testng.Assert.*; -public class GoodDataBeansAsServicesTest { +public class GoodDataBeansAsServicesIT { @Test public void servicesRegisteredFromXmlUsingAnnotationConfig() throws Exception { From 44f7a4e31d6db3a41c9b6fe9c5a7c1484a2be0a2 Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Thu, 28 Sep 2017 23:05:26 +0200 Subject: [PATCH 021/598] autoclose ZipInputStream --- src/main/java/com/gooddata/util/ZipHelper.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/gooddata/util/ZipHelper.java b/src/main/java/com/gooddata/util/ZipHelper.java index 7d8411024..e85e557c4 100644 --- a/src/main/java/com/gooddata/util/ZipHelper.java +++ b/src/main/java/com/gooddata/util/ZipHelper.java @@ -85,8 +85,9 @@ private static void zipFile(Path rootPath, File file, ZipOutputStream zos) throw } private static boolean isZipped(File file) { - try (final InputStream stream = Files.newInputStream(file.toPath())) { - return new ZipInputStream(stream).getNextEntry() != null; + try (final InputStream stream = Files.newInputStream(file.toPath()); + final ZipInputStream zipStream = new ZipInputStream(stream)) { + return zipStream.getNextEntry() != null; } catch (IOException e) { return false; } From af1346eb9572a55b20cb8cc6ef8ab6ece3159f79 Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Thu, 28 Sep 2017 23:21:26 +0200 Subject: [PATCH 022/598] remove wrongly implemented equals method without hashCode counterpart --- .../com/gooddata/warehouse/WarehouseS3Credentials.java | 10 ---------- .../gooddata/warehouse/WarehouseS3CredentialsTest.java | 5 ++++- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/gooddata/warehouse/WarehouseS3Credentials.java b/src/main/java/com/gooddata/warehouse/WarehouseS3Credentials.java index 872e9ca1f..bede8aa5e 100644 --- a/src/main/java/com/gooddata/warehouse/WarehouseS3Credentials.java +++ b/src/main/java/com/gooddata/warehouse/WarehouseS3Credentials.java @@ -177,16 +177,6 @@ public String getUpdatedBy() { return updatedBy; } - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (!(o instanceof Links)) return false; - - final Links links = (Links) o; - - return this.toString().equals(links.toString()); - } - @Override public String toString() { return GoodDataToStringBuilder.defaultToString(this); diff --git a/src/test/java/com/gooddata/warehouse/WarehouseS3CredentialsTest.java b/src/test/java/com/gooddata/warehouse/WarehouseS3CredentialsTest.java index 0741ff1b5..05326ef40 100644 --- a/src/test/java/com/gooddata/warehouse/WarehouseS3CredentialsTest.java +++ b/src/test/java/com/gooddata/warehouse/WarehouseS3CredentialsTest.java @@ -12,10 +12,12 @@ import org.testng.annotations.Test; import static com.gooddata.util.ResourceUtils.readObjectFromResource; +import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals; import static net.javacrumbs.jsonunit.core.util.ResourceUtils.resource; import static org.hamcrest.CoreMatchers.endsWith; import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; @@ -69,7 +71,8 @@ public void deserializeGet() { assertThat(credentials.getAccessKey(), is(ACCESS_KEY)); assertThat(credentials.getSecretKey(), is(nullValue())); assertThat(credentials.getUpdated().toString(), is(UPDATED_AT.toString())); - assertThat(credentials.getLinks(), is(LINKS)); + assertThat(credentials.getLinks(), is(sameBeanAs(LINKS))); + assertThat(credentials.getLinks().toString(), is(notNullValue())); } @Test From 3c0fa2a32df345d6573c755fbe526a2dbbb5ccf2 Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Thu, 28 Sep 2017 23:26:43 +0200 Subject: [PATCH 023/598] store/return deffensive copy --- src/main/java/com/gooddata/md/MaqlAst.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/gooddata/md/MaqlAst.java b/src/main/java/com/gooddata/md/MaqlAst.java index 20d458340..b5658a5f8 100644 --- a/src/main/java/com/gooddata/md/MaqlAst.java +++ b/src/main/java/com/gooddata/md/MaqlAst.java @@ -10,6 +10,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.gooddata.util.GoodDataToStringBuilder; +import java.util.Arrays; + /** * MAQL AST representation */ @@ -43,11 +45,11 @@ public MaqlAstPosition getPosition() { } public MaqlAst[] getContent() { - return content; + return content == null ? null : Arrays.copyOf(content, content.length); } public void setContent(final MaqlAst[] content) { - this.content = content; + this.content = content == null ? null : Arrays.copyOf(content, content.length); } public String getValue() { From 474fa76fff062a2fea35728bdb74b29ef937dacd Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Thu, 28 Sep 2017 23:31:49 +0200 Subject: [PATCH 024/598] delegate equals/hashCode methods to delegate list --- .../java/com/gooddata/collections/MultiPageList.java | 10 ++++++++++ .../gooddata/dataload/processes/ProcessService.java | 4 +++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/gooddata/collections/MultiPageList.java b/src/main/java/com/gooddata/collections/MultiPageList.java index ab609623e..a535c71b1 100644 --- a/src/main/java/com/gooddata/collections/MultiPageList.java +++ b/src/main/java/com/gooddata/collections/MultiPageList.java @@ -241,6 +241,16 @@ public List subList(final int fromIndex, final int toIndex) { return delegate.subList(fromIndex, toIndex); } + @Override + public boolean equals(final Object o) { + return delegate.equals(o); + } + + @Override + public int hashCode() { + return delegate.hashCode(); + } + private static final class PageIterator implements Iterator { private PageableList currentPage; diff --git a/src/main/java/com/gooddata/dataload/processes/ProcessService.java b/src/main/java/com/gooddata/dataload/processes/ProcessService.java index 522bee74d..ba7b33a56 100644 --- a/src/main/java/com/gooddata/dataload/processes/ProcessService.java +++ b/src/main/java/com/gooddata/dataload/processes/ProcessService.java @@ -670,6 +670,8 @@ private File createTempFile(String prefix, String suffix) { private void deleteTempFile(File file) { notNull(file, "file"); - file.delete(); + if (!file.delete()) { + // ignored + } } } From e9ee61dfc213c6708aa8a8241a226957ba41c264 Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Thu, 28 Sep 2017 23:35:41 +0200 Subject: [PATCH 025/598] run findbugs during test phase --- pom.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pom.xml b/pom.xml index 43822207f..a6ed3e538 100644 --- a/pom.xml +++ b/pom.xml @@ -92,6 +92,19 @@ + + org.codehaus.mojo + findbugs-maven-plugin + 3.0.5 + + + + check + + test + + + From a2def02868a07cde203998972ad7f4d93e063c1c Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Wed, 4 Oct 2017 17:14:55 +0200 Subject: [PATCH 026/598] add a test to keep the coverage --- .../collections/MultiPageListTest.java | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/gooddata/collections/MultiPageListTest.java b/src/test/java/com/gooddata/collections/MultiPageListTest.java index bc348b82b..3837d1527 100644 --- a/src/test/java/com/gooddata/collections/MultiPageListTest.java +++ b/src/test/java/com/gooddata/collections/MultiPageListTest.java @@ -20,6 +20,7 @@ import static org.hamcrest.core.Is.is; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import static org.testng.Assert.fail; public class MultiPageListTest { @@ -119,7 +120,8 @@ public void streamWithPageProvider() { assertThat(list.stream().max(Integer::compareTo).orElse(0), is(3)); } - @Test(expectedExceptions = IllegalStateException.class) + @Test(expectedExceptions = IllegalStateException.class, + expectedExceptionsMessageRegExp = ".*page provider does not iterate properly, returns the same page.*") public void infiniteLoopShouldBePrevented() { final PageableList pageableList = new PageableList<>(asList(1, 2), new Paging("next")); final PageableList list = new MultiPageList<>( @@ -127,7 +129,22 @@ public void infiniteLoopShouldBePrevented() { page -> pageableList ); - list.stream().anyMatch(it -> it == 5); + list.forEach((i) -> {}); + } + + @Test(expectedExceptions = IllegalStateException.class, + expectedExceptionsMessageRegExp = ".*page has no results, yet claims there is next page.*") + public void shouldFailOnMisbehavingNextPage() throws Exception { + final PageableList pageableList = new PageableList<>(asList(1, 2), new Paging("next")); + final PageableList misbehaving = mock(PageableList.class); + when(misbehaving.isEmpty()).thenReturn(true); + when(misbehaving.getNextPage()).thenReturn(new PageRequest()); + + final PageableList list = new MultiPageList<>( + pageableList, + page -> misbehaving + ); + list.forEach((i) -> {}); } @Test From 1122bf626202f4d7d6de8b1c5ae81ba55cd5520e Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Wed, 4 Oct 2017 16:10:32 +0200 Subject: [PATCH 027/598] make poll sleep interval configurable Set poll sleep interval to 0 in tests which makes tests invoked by mvn verify 4 times faster! --- .../java/com/gooddata/AbstractService.java | 22 +++++++-- src/main/java/com/gooddata/GoodData.java | 34 +++++++------- .../java/com/gooddata/GoodDataSettings.java | 47 +++++++++++++++---- .../com/gooddata/account/AccountService.java | 6 ++- .../auditevent/AuditEventService.java | 6 ++- .../gooddata/connector/ConnectorService.java | 5 +- .../gooddata/dataload/OutputStageService.java | 6 ++- .../dataload/processes/ProcessService.java | 7 ++- .../com/gooddata/dataset/DatasetService.java | 6 ++- .../com/gooddata/export/ExportService.java | 6 ++- .../featureflag/FeatureFlagService.java | 6 ++- .../java/com/gooddata/gdc/GdcService.java | 5 +- .../java/com/gooddata/md/MetadataService.java | 5 +- .../md/maintenance/ExportImportService.java | 5 +- .../java/com/gooddata/model/ModelService.java | 5 +- .../notification/NotificationService.java | 5 +- .../com/gooddata/project/ProjectService.java | 8 ++-- .../ProjectTemplateService.java | 6 ++- .../com/gooddata/report/ReportService.java | 5 +- .../gooddata/warehouse/WarehouseService.java | 6 ++- .../java/com/gooddata/AbstractGoodDataIT.java | 4 +- .../com/gooddata/AbstractServiceTest.java | 2 +- .../com/gooddata/GoodDataSettingsTest.java | 18 +++++++ .../auditevent/AuditEventServiceTest.java | 3 +- .../dataload/OutputStageServiceTest.java | 3 +- .../processes/ProcessServiceTest.java | 3 +- .../gooddata/dataset/DatasetServiceTest.java | 3 +- .../gooddata/export/ExportServiceTest.java | 7 +-- .../featureflag/FeatureFlagServiceTest.java | 3 +- .../com/gooddata/md/MetadataServiceTest.java | 3 +- .../maintenance/ExportImportServiceTest.java | 3 +- .../notification/NotificationServiceTest.java | 3 +- .../gooddata/project/ProjectServiceTest.java | 3 +- .../ProjectTemplateServiceTest.java | 3 +- .../gooddata/report/ReportServiceTest.java | 5 +- .../warehouse/WarehouseServiceTest.java | 3 +- 36 files changed, 186 insertions(+), 84 deletions(-) diff --git a/src/main/java/com/gooddata/AbstractService.java b/src/main/java/com/gooddata/AbstractService.java index 07f24fb14..76d31bb80 100644 --- a/src/main/java/com/gooddata/AbstractService.java +++ b/src/main/java/com/gooddata/AbstractService.java @@ -22,7 +22,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.URI; import java.util.concurrent.TimeUnit; /** @@ -30,23 +29,36 @@ */ public abstract class AbstractService { - public static final Integer WAIT_BEFORE_RETRY_IN_MILLIS = 5 * 1000; - protected final RestTemplate restTemplate; + private final GoodDataSettings settings; + protected final ObjectMapper mapper = new ObjectMapper(); private final ResponseExtractor reusableResponseExtractor = ReusableClientHttpResponse::new; + /** + * Sets RESTful HTTP Spring template. Should be called from constructor of concrete service extending + * this abstract one. + * + * @param restTemplate RESTful HTTP Spring template + * @param settings settings + */ + public AbstractService(final RestTemplate restTemplate, final GoodDataSettings settings) { + this.restTemplate = notNull(restTemplate, "restTemplate"); + this.settings = notNull(settings, "settings"); + } /** * Sets RESTful HTTP Spring template. Should be called from constructor of concrete service extending * this abstract one. * * @param restTemplate RESTful HTTP Spring template + * @deprecated use {@link #AbstractService(RestTemplate, GoodDataSettings)} */ + @Deprecated public AbstractService(RestTemplate restTemplate) { - this.restTemplate = notNull(restTemplate, "restTemplate"); + this(restTemplate, new GoodDataSettings()); } final R poll(final PollHandler handler, long timeout, final TimeUnit unit) { @@ -61,7 +73,7 @@ final R poll(final PollHandler handler, long timeout, final TimeUnit un } try { - Thread.sleep(WAIT_BEFORE_RETRY_IN_MILLIS); + Thread.sleep(settings.getPollSleep()); } catch (InterruptedException e) { throw new GoodDataException("interrupted"); } diff --git a/src/main/java/com/gooddata/GoodData.java b/src/main/java/com/gooddata/GoodData.java index 68baee3ac..3e5d28dc8 100644 --- a/src/main/java/com/gooddata/GoodData.java +++ b/src/main/java/com/gooddata/GoodData.java @@ -206,24 +206,24 @@ protected GoodData(GoodDataEndpoint endpoint, Authentication authentication, Goo restTemplate = createRestTemplate(endpoint, httpClient); - accountService = new AccountService(getRestTemplate()); - projectService = new ProjectService(getRestTemplate(), accountService); - metadataService = new MetadataService(getRestTemplate()); - modelService = new ModelService(getRestTemplate()); - gdcService = new GdcService(getRestTemplate()); + accountService = new AccountService(getRestTemplate(), settings); + projectService = new ProjectService(getRestTemplate(), accountService, settings); + metadataService = new MetadataService(getRestTemplate(), settings); + modelService = new ModelService(getRestTemplate(), settings); + gdcService = new GdcService(getRestTemplate(), settings); dataStoreService = new DataStoreService(getHttpClient(), getRestTemplate(), gdcService, endpoint.toUri()); - datasetService = new DatasetService(getRestTemplate(), dataStoreService); - exportService = new ExportService(getRestTemplate(), endpoint); - reportService = new ReportService(exportService, getRestTemplate()); - processService = new ProcessService(getRestTemplate(), accountService, dataStoreService); - warehouseService = new WarehouseService(getRestTemplate()); - connectorService = new ConnectorService(getRestTemplate(), projectService); - notificationService = new NotificationService(getRestTemplate()); - exportImportService = new ExportImportService(getRestTemplate()); - featureFlagService = new FeatureFlagService(getRestTemplate()); - outputStageService = new OutputStageService(getRestTemplate()); - projectTemplateService = new ProjectTemplateService(getRestTemplate()); - auditEventService = new AuditEventService(getRestTemplate(), accountService); + datasetService = new DatasetService(getRestTemplate(), dataStoreService, settings); + exportService = new ExportService(getRestTemplate(), endpoint, settings); + reportService = new ReportService(exportService, getRestTemplate(), settings); + processService = new ProcessService(getRestTemplate(), accountService, dataStoreService, settings); + warehouseService = new WarehouseService(getRestTemplate(), settings); + connectorService = new ConnectorService(getRestTemplate(), projectService, settings); + notificationService = new NotificationService(getRestTemplate(), settings); + exportImportService = new ExportImportService(getRestTemplate(), settings); + featureFlagService = new FeatureFlagService(getRestTemplate(), settings); + outputStageService = new OutputStageService(getRestTemplate(), settings); + projectTemplateService = new ProjectTemplateService(getRestTemplate(), settings); + auditEventService = new AuditEventService(getRestTemplate(), accountService, settings); } static RestTemplate createRestTemplate(GoodDataEndpoint endpoint, HttpClient httpClient) { diff --git a/src/main/java/com/gooddata/GoodDataSettings.java b/src/main/java/com/gooddata/GoodDataSettings.java index 44deaeea4..579fce6a0 100644 --- a/src/main/java/com/gooddata/GoodDataSettings.java +++ b/src/main/java/com/gooddata/GoodDataSettings.java @@ -5,7 +5,7 @@ */ package com.gooddata; -import org.apache.commons.lang.StringUtils; +import com.gooddata.util.GoodDataToStringBuilder; import java.util.concurrent.TimeUnit; @@ -24,6 +24,7 @@ public class GoodDataSettings { private int connectionTimeout = secondsToMillis(10); private int connectionRequestTimeout = secondsToMillis(10); private int socketTimeout = secondsToMillis(60); + private int pollSleep = secondsToMillis(5); private String userAgent; @@ -158,6 +159,36 @@ public int getSocketTimeout() { return socketTimeout; } + /** + * Get sleep time in milliseconds between poll retries + * + * @see AbstractService#poll(PollHandler, long, TimeUnit) + */ + public int getPollSleep() { + return pollSleep; + } + + /** + * Set sleep time between poll retries + * + * @param pollSleep sleep milliseconds + * @see AbstractService#poll(PollHandler, long, TimeUnit) + */ + public void setPollSleep(final int pollSleep) { + isTrue(pollSleep >= 0, "pollSleep must be not negative"); + this.pollSleep = pollSleep; + } + + /** + * Set sleep time between poll retries + * + * @param pollSleep sleep seconds + * @see AbstractService#poll(PollHandler, long, TimeUnit) + */ + public void setPollSleepSeconds(final int pollSleep) { + setPollSleep(secondsToMillis(pollSleep)); + } + /** * User agent * @return user agent string @@ -184,8 +215,9 @@ public boolean equals(final Object o) { if (maxConnections != that.maxConnections) return false; if (connectionTimeout != that.connectionTimeout) return false; if (connectionRequestTimeout != that.connectionRequestTimeout) return false; - return socketTimeout == that.socketTimeout; - + if (socketTimeout != that.socketTimeout) return false; + if (pollSleep != that.pollSleep) return false; + return userAgent != null ? userAgent.equals(that.userAgent) : that.userAgent == null; } @Override @@ -194,17 +226,14 @@ public int hashCode() { result = 31 * result + connectionTimeout; result = 31 * result + connectionRequestTimeout; result = 31 * result + socketTimeout; + result = 31 * result + pollSleep; + result = 31 * result + (userAgent != null ? userAgent.hashCode() : 0); return result; } @Override public String toString() { - return "GoodDataSettings{" + - "connectionRequestTimeout=" + connectionRequestTimeout + - ", maxConnections=" + maxConnections + - ", connectionTimeout=" + connectionTimeout + - ", socketTimeout=" + socketTimeout + - '}'; + return GoodDataToStringBuilder.defaultToString(this); } private static int secondsToMillis(int seconds) { diff --git a/src/main/java/com/gooddata/account/AccountService.java b/src/main/java/com/gooddata/account/AccountService.java index d25771082..0131b77fa 100644 --- a/src/main/java/com/gooddata/account/AccountService.java +++ b/src/main/java/com/gooddata/account/AccountService.java @@ -8,6 +8,7 @@ import com.gooddata.AbstractService; import com.gooddata.GoodDataException; import com.gooddata.GoodDataRestException; +import com.gooddata.GoodDataSettings; import com.gooddata.gdc.UriResponse; import org.springframework.http.HttpStatus; import org.springframework.http.converter.json.MappingJacksonValue; @@ -26,9 +27,10 @@ public class AccountService extends AbstractService { * Constructs service for GoodData account management. * * @param restTemplate RESTful HTTP Spring template + * @param settings settings */ - public AccountService(RestTemplate restTemplate) { - super(restTemplate); + public AccountService(final RestTemplate restTemplate, final GoodDataSettings settings) { + super(restTemplate, settings); } /** diff --git a/src/main/java/com/gooddata/auditevent/AuditEventService.java b/src/main/java/com/gooddata/auditevent/AuditEventService.java index 198def60c..d72a14e6b 100644 --- a/src/main/java/com/gooddata/auditevent/AuditEventService.java +++ b/src/main/java/com/gooddata/auditevent/AuditEventService.java @@ -6,6 +6,7 @@ import com.gooddata.AbstractService; import com.gooddata.GoodDataException; import com.gooddata.GoodDataRestException; +import com.gooddata.GoodDataSettings; import com.gooddata.account.Account; import com.gooddata.account.AccountService; import com.gooddata.collections.MultiPageList; @@ -30,9 +31,10 @@ public class AuditEventService extends AbstractService { * Service for audit events * @param restTemplate rest template * @param accountService account service + * @param settings settings */ - public AuditEventService(final RestTemplate restTemplate, final AccountService accountService) { - super(restTemplate); + public AuditEventService(final RestTemplate restTemplate, final AccountService accountService, final GoodDataSettings settings) { + super(restTemplate, settings); this.accountService = notNull(accountService, "account service"); } diff --git a/src/main/java/com/gooddata/connector/ConnectorService.java b/src/main/java/com/gooddata/connector/ConnectorService.java index 6e0160105..ea71a801e 100644 --- a/src/main/java/com/gooddata/connector/ConnectorService.java +++ b/src/main/java/com/gooddata/connector/ConnectorService.java @@ -7,6 +7,7 @@ import com.gooddata.AbstractService; import com.gooddata.FutureResult; +import com.gooddata.GoodDataSettings; import com.gooddata.PollResult; import com.gooddata.GoodDataException; import com.gooddata.GoodDataRestException; @@ -35,8 +36,8 @@ public class ConnectorService extends AbstractService { private final ProjectService projectService; - public ConnectorService(final RestTemplate restTemplate, final ProjectService projectService) { - super(restTemplate); + public ConnectorService(final RestTemplate restTemplate, final ProjectService projectService, final GoodDataSettings settings) { + super(restTemplate, settings); this.projectService = notNull(projectService, "projectService"); } diff --git a/src/main/java/com/gooddata/dataload/OutputStageService.java b/src/main/java/com/gooddata/dataload/OutputStageService.java index d990ddd73..98b934274 100644 --- a/src/main/java/com/gooddata/dataload/OutputStageService.java +++ b/src/main/java/com/gooddata/dataload/OutputStageService.java @@ -12,6 +12,7 @@ import com.gooddata.AbstractService; import com.gooddata.GoodDataException; import com.gooddata.GoodDataRestException; +import com.gooddata.GoodDataSettings; import com.gooddata.project.Project; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; @@ -28,9 +29,10 @@ public class OutputStageService extends AbstractService { * Sets RESTful HTTP Spring template. Should be called from constructor of concrete service extending * this abstract one. * @param restTemplate RESTful HTTP Spring template + * @param settings settings */ - public OutputStageService(final RestTemplate restTemplate) { - super(restTemplate); + public OutputStageService(final RestTemplate restTemplate, final GoodDataSettings settings) { + super(restTemplate, settings); } /** diff --git a/src/main/java/com/gooddata/dataload/processes/ProcessService.java b/src/main/java/com/gooddata/dataload/processes/ProcessService.java index 522bee74d..d29c946a2 100644 --- a/src/main/java/com/gooddata/dataload/processes/ProcessService.java +++ b/src/main/java/com/gooddata/dataload/processes/ProcessService.java @@ -8,6 +8,7 @@ import com.gooddata.AbstractPollHandler; import com.gooddata.AbstractService; import com.gooddata.FutureResult; +import com.gooddata.GoodDataSettings; import com.gooddata.PollResult; import com.gooddata.GoodDataException; import com.gooddata.GoodDataRestException; @@ -64,9 +65,11 @@ public class ProcessService extends AbstractService { * @param restTemplate RESTful HTTP Spring template * @param accountService service to access accounts * @param dataStoreService service for upload process data + * @param settings settings */ - public ProcessService(RestTemplate restTemplate, AccountService accountService, DataStoreService dataStoreService) { - super(restTemplate); + public ProcessService(final RestTemplate restTemplate, final AccountService accountService, + final DataStoreService dataStoreService, final GoodDataSettings settings) { + super(restTemplate, settings); this.dataStoreService = dataStoreService; this.accountService = notNull(accountService, "accountService"); } diff --git a/src/main/java/com/gooddata/dataset/DatasetService.java b/src/main/java/com/gooddata/dataset/DatasetService.java index b5596b641..bea214130 100644 --- a/src/main/java/com/gooddata/dataset/DatasetService.java +++ b/src/main/java/com/gooddata/dataset/DatasetService.java @@ -10,6 +10,7 @@ import com.gooddata.FutureResult; import com.gooddata.GoodDataException; import com.gooddata.GoodDataRestException; +import com.gooddata.GoodDataSettings; import com.gooddata.PollResult; import com.gooddata.gdc.AboutLinks.Link; import com.gooddata.gdc.DataStoreException; @@ -50,8 +51,9 @@ public class DatasetService extends AbstractService { private final DataStoreService dataStoreService; - public DatasetService(RestTemplate restTemplate, DataStoreService dataStoreService) { - super(restTemplate); + public DatasetService(final RestTemplate restTemplate, final DataStoreService dataStoreService, + final GoodDataSettings settings) { + super(restTemplate, settings); this.dataStoreService = notNull(dataStoreService, "dataStoreService"); } diff --git a/src/main/java/com/gooddata/export/ExportService.java b/src/main/java/com/gooddata/export/ExportService.java index 9015e2471..590277feb 100644 --- a/src/main/java/com/gooddata/export/ExportService.java +++ b/src/main/java/com/gooddata/export/ExportService.java @@ -12,6 +12,7 @@ import com.gooddata.GoodDataEndpoint; import com.gooddata.GoodDataException; import com.gooddata.GoodDataRestException; +import com.gooddata.GoodDataSettings; import com.gooddata.PollResult; import com.gooddata.SimplePollHandler; import com.gooddata.gdc.AsyncTask; @@ -55,9 +56,10 @@ public class ExportService extends AbstractService { * Service for data export * @param restTemplate REST template * @param endpoint GoodData Endpoint + * @param settings settings */ - public ExportService(final RestTemplate restTemplate, final GoodDataEndpoint endpoint) { - super(restTemplate); + public ExportService(final RestTemplate restTemplate, final GoodDataEndpoint endpoint, final GoodDataSettings settings) { + super(restTemplate, settings); this.endpoint = notNull(endpoint, "endpoint"); } diff --git a/src/main/java/com/gooddata/featureflag/FeatureFlagService.java b/src/main/java/com/gooddata/featureflag/FeatureFlagService.java index 93ab3a91c..77a888d07 100644 --- a/src/main/java/com/gooddata/featureflag/FeatureFlagService.java +++ b/src/main/java/com/gooddata/featureflag/FeatureFlagService.java @@ -7,6 +7,7 @@ import com.gooddata.AbstractService; import com.gooddata.GoodDataException; +import com.gooddata.GoodDataSettings; import com.gooddata.project.Project; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; @@ -29,9 +30,10 @@ public class FeatureFlagService extends AbstractService { * Constructs service for GoodData feature flags management. * * @param restTemplate RESTful HTTP Spring template + * @param settings settings */ - public FeatureFlagService(final RestTemplate restTemplate) { - super(restTemplate); + public FeatureFlagService(final RestTemplate restTemplate, final GoodDataSettings settings) { + super(restTemplate, settings); } /** diff --git a/src/main/java/com/gooddata/gdc/GdcService.java b/src/main/java/com/gooddata/gdc/GdcService.java index cbda1b06c..4f60348cf 100644 --- a/src/main/java/com/gooddata/gdc/GdcService.java +++ b/src/main/java/com/gooddata/gdc/GdcService.java @@ -7,6 +7,7 @@ import com.gooddata.AbstractService; import com.gooddata.GoodDataException; +import com.gooddata.GoodDataSettings; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; @@ -15,8 +16,8 @@ */ public class GdcService extends AbstractService { - public GdcService(RestTemplate restTemplate) { - super(restTemplate); + public GdcService(final RestTemplate restTemplate, final GoodDataSettings settings) { + super(restTemplate, settings); } /** diff --git a/src/main/java/com/gooddata/md/MetadataService.java b/src/main/java/com/gooddata/md/MetadataService.java index 419fdf317..f428bdf5c 100644 --- a/src/main/java/com/gooddata/md/MetadataService.java +++ b/src/main/java/com/gooddata/md/MetadataService.java @@ -8,6 +8,7 @@ import com.gooddata.AbstractService; import com.gooddata.GoodDataException; import com.gooddata.GoodDataRestException; +import com.gooddata.GoodDataSettings; import com.gooddata.md.report.ReportDefinition; import com.gooddata.project.Project; import org.springframework.http.HttpStatus; @@ -31,8 +32,8 @@ */ public class MetadataService extends AbstractService { - public MetadataService(RestTemplate restTemplate) { - super(restTemplate); + public MetadataService(final RestTemplate restTemplate, final GoodDataSettings settings) { + super(restTemplate, settings); } /** diff --git a/src/main/java/com/gooddata/md/maintenance/ExportImportService.java b/src/main/java/com/gooddata/md/maintenance/ExportImportService.java index 0bae95849..25feee03a 100644 --- a/src/main/java/com/gooddata/md/maintenance/ExportImportService.java +++ b/src/main/java/com/gooddata/md/maintenance/ExportImportService.java @@ -11,6 +11,7 @@ import com.gooddata.AbstractService; import com.gooddata.FutureResult; import com.gooddata.GoodDataRestException; +import com.gooddata.GoodDataSettings; import com.gooddata.PollResult; import com.gooddata.gdc.TaskStatus; import com.gooddata.gdc.UriResponse; @@ -23,8 +24,8 @@ */ public class ExportImportService extends AbstractService { - public ExportImportService(RestTemplate restTemplate) { - super(restTemplate); + public ExportImportService(final RestTemplate restTemplate, final GoodDataSettings settings) { + super(restTemplate, settings); } diff --git a/src/main/java/com/gooddata/model/ModelService.java b/src/main/java/com/gooddata/model/ModelService.java index 66df630d3..0ef236c30 100644 --- a/src/main/java/com/gooddata/model/ModelService.java +++ b/src/main/java/com/gooddata/model/ModelService.java @@ -7,6 +7,7 @@ import com.gooddata.AbstractService; import com.gooddata.FutureResult; +import com.gooddata.GoodDataSettings; import com.gooddata.PollResult; import com.gooddata.GoodDataRestException; import com.gooddata.AbstractPollHandlerBase; @@ -34,8 +35,8 @@ */ public class ModelService extends AbstractService { - public ModelService(RestTemplate restTemplate) { - super(restTemplate); + public ModelService(final RestTemplate restTemplate, final GoodDataSettings settings) { + super(restTemplate, settings); } private FutureResult getProjectModelDiff(Project project, DiffRequest diffRequest) { diff --git a/src/main/java/com/gooddata/notification/NotificationService.java b/src/main/java/com/gooddata/notification/NotificationService.java index c4c6fe861..7cb8df269 100644 --- a/src/main/java/com/gooddata/notification/NotificationService.java +++ b/src/main/java/com/gooddata/notification/NotificationService.java @@ -10,6 +10,7 @@ import com.gooddata.AbstractService; import com.gooddata.GoodDataException; import com.gooddata.GoodDataRestException; +import com.gooddata.GoodDataSettings; import com.gooddata.project.Project; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; @@ -19,8 +20,8 @@ */ public class NotificationService extends AbstractService { - public NotificationService(final RestTemplate restTemplate) { - super(restTemplate); + public NotificationService(final RestTemplate restTemplate, final GoodDataSettings settings) { + super(restTemplate, settings); } /** diff --git a/src/main/java/com/gooddata/project/ProjectService.java b/src/main/java/com/gooddata/project/ProjectService.java index 62bec58e2..9a7458ba5 100644 --- a/src/main/java/com/gooddata/project/ProjectService.java +++ b/src/main/java/com/gooddata/project/ProjectService.java @@ -10,6 +10,7 @@ import com.gooddata.FutureResult; import com.gooddata.GoodDataException; import com.gooddata.GoodDataRestException; +import com.gooddata.GoodDataSettings; import com.gooddata.PollResult; import com.gooddata.SimplePollHandler; import com.gooddata.account.Account; @@ -55,12 +56,13 @@ public class ProjectService extends AbstractService { /** * Constructs service for GoodData project management (list projects, create a project, ...). - * * @param restTemplate RESTful HTTP Spring template * @param accountService GoodData account service + * @param settings settings */ - public ProjectService(RestTemplate restTemplate, AccountService accountService) { - super(restTemplate); + public ProjectService(final RestTemplate restTemplate, final AccountService accountService, + final GoodDataSettings settings) { + super(restTemplate, settings); this.accountService = notNull(accountService, "accountService"); } diff --git a/src/main/java/com/gooddata/projecttemplate/ProjectTemplateService.java b/src/main/java/com/gooddata/projecttemplate/ProjectTemplateService.java index 8def79977..ee7d36cf0 100644 --- a/src/main/java/com/gooddata/projecttemplate/ProjectTemplateService.java +++ b/src/main/java/com/gooddata/projecttemplate/ProjectTemplateService.java @@ -8,6 +8,7 @@ import com.gooddata.AbstractService; import com.gooddata.GoodDataException; import com.gooddata.GoodDataRestException; +import com.gooddata.GoodDataSettings; import com.gooddata.dataset.DatasetManifest; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; @@ -28,9 +29,10 @@ public class ProjectTemplateService extends AbstractService { * this abstract one. * * @param restTemplate RESTful HTTP Spring template + * @param settings settings */ - public ProjectTemplateService(RestTemplate restTemplate) { - super(restTemplate); + public ProjectTemplateService(final RestTemplate restTemplate, final GoodDataSettings settings) { + super(restTemplate, settings); } /** diff --git a/src/main/java/com/gooddata/report/ReportService.java b/src/main/java/com/gooddata/report/ReportService.java index efbae1b65..67ecbf2c6 100644 --- a/src/main/java/com/gooddata/report/ReportService.java +++ b/src/main/java/com/gooddata/report/ReportService.java @@ -7,6 +7,7 @@ import com.gooddata.AbstractService; import com.gooddata.FutureResult; +import com.gooddata.GoodDataSettings; import com.gooddata.export.ExportService; import com.gooddata.md.report.Report; import com.gooddata.md.report.ReportDefinition; @@ -32,8 +33,8 @@ public class ReportService extends AbstractService { private final ExportService service; - public ReportService(final ExportService service, final RestTemplate restTemplate) { - super(restTemplate); + public ReportService(final ExportService service, final RestTemplate restTemplate, final GoodDataSettings settings) { + super(restTemplate, settings); this.service = notNull(service, "service"); } diff --git a/src/main/java/com/gooddata/warehouse/WarehouseService.java b/src/main/java/com/gooddata/warehouse/WarehouseService.java index 9d89c5506..09a8089be 100644 --- a/src/main/java/com/gooddata/warehouse/WarehouseService.java +++ b/src/main/java/com/gooddata/warehouse/WarehouseService.java @@ -10,6 +10,7 @@ import com.gooddata.FutureResult; import com.gooddata.GoodDataException; import com.gooddata.GoodDataRestException; +import com.gooddata.GoodDataSettings; import com.gooddata.PollResult; import com.gooddata.collections.MultiPageList; import com.gooddata.collections.Page; @@ -45,9 +46,10 @@ public class WarehouseService extends AbstractService { * this abstract one. * * @param restTemplate RESTful HTTP Spring template + * @param settings settings */ - public WarehouseService(RestTemplate restTemplate) { - super(restTemplate); + public WarehouseService(final RestTemplate restTemplate, final GoodDataSettings settings) { + super(restTemplate, settings); } /** diff --git a/src/test/java/com/gooddata/AbstractGoodDataIT.java b/src/test/java/com/gooddata/AbstractGoodDataIT.java index f5c4b9e95..e408a3ef1 100644 --- a/src/test/java/com/gooddata/AbstractGoodDataIT.java +++ b/src/test/java/com/gooddata/AbstractGoodDataIT.java @@ -28,7 +28,9 @@ public void commonSetUp() { } protected GoodDataSettings createGoodDataSettings() { - return new GoodDataSettings(); + final GoodDataSettings settings = new GoodDataSettings(); + settings.setPollSleep(0); + return settings; } @AfterMethod diff --git a/src/test/java/com/gooddata/AbstractServiceTest.java b/src/test/java/com/gooddata/AbstractServiceTest.java index e389c0a62..23c8c10b2 100644 --- a/src/test/java/com/gooddata/AbstractServiceTest.java +++ b/src/test/java/com/gooddata/AbstractServiceTest.java @@ -33,7 +33,7 @@ public class AbstractServiceTest { @BeforeMethod public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - service = new AbstractService(restTemplate) {}; + service = new AbstractService(restTemplate, new GoodDataSettings()) {}; final ClientHttpResponse response = mock(ClientHttpResponse.class); when(response.getStatusCode()).thenReturn(HttpStatus.OK); when(restTemplate.execute(any(), any(HttpMethod.class), any(RequestCallback.class), any(ResponseExtractor.class))) diff --git a/src/test/java/com/gooddata/GoodDataSettingsTest.java b/src/test/java/com/gooddata/GoodDataSettingsTest.java index 651232816..d83e45011 100644 --- a/src/test/java/com/gooddata/GoodDataSettingsTest.java +++ b/src/test/java/com/gooddata/GoodDataSettingsTest.java @@ -5,6 +5,8 @@ */ package com.gooddata; +import nl.jqno.equalsverifier.EqualsVerifier; +import nl.jqno.equalsverifier.Warning; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -29,6 +31,7 @@ public void testHasDefaults() throws Exception { assertTrue(settings.getConnectionTimeout() >= 0); assertTrue(settings.getConnectionRequestTimeout() >= 0); assertTrue(settings.getSocketTimeout() >= 0); + assertTrue(settings.getPollSleep() >= 0); assertThat(settings.getUserAgent(), is(nullValue())); } @@ -37,10 +40,12 @@ public void testSetSeconds() throws Exception { settings.setConnectionTimeoutSeconds(53); settings.setConnectionRequestTimeoutSeconds(69); settings.setSocketTimeoutSeconds(71); + settings.setPollSleepSeconds(81); assertEquals(53000, settings.getConnectionTimeout()); assertEquals(69000, settings.getConnectionRequestTimeout()); assertEquals(71000, settings.getSocketTimeout()); + assertEquals(81000, settings.getPollSleep()); } @Test(expectedExceptions = IllegalArgumentException.class) @@ -58,6 +63,11 @@ public void setNegativeSocketTimeoutFails() throws Exception { settings.setSocketTimeout(-5); } + @Test(expectedExceptions = IllegalArgumentException.class) + public void setNegativePollSleepFails() throws Exception { + settings.setPollSleep(-5); + } + @Test(expectedExceptions = IllegalArgumentException.class) public void setZeroMaxConnectionsFails() throws Exception { settings.setMaxConnections(0); @@ -69,4 +79,12 @@ public void customUserAgentShouldBePrefixOfDefault() { goodDataSettings.setUserAgent("customAgent/X.Y"); assertThat(goodDataSettings.getUserAgent(), is("customAgent/X.Y")); } + + @Test + public void shouldVerifyEquals() throws Exception { + EqualsVerifier.forClass(GoodDataSettings.class) + .usingGetClass() + .suppress(Warning.NONFINAL_FIELDS) + .verify(); + } } \ No newline at end of file diff --git a/src/test/java/com/gooddata/auditevent/AuditEventServiceTest.java b/src/test/java/com/gooddata/auditevent/AuditEventServiceTest.java index 13fda9f44..984e9033a 100644 --- a/src/test/java/com/gooddata/auditevent/AuditEventServiceTest.java +++ b/src/test/java/com/gooddata/auditevent/AuditEventServiceTest.java @@ -3,6 +3,7 @@ */ package com.gooddata.auditevent; +import com.gooddata.GoodDataSettings; import com.gooddata.account.Account; import com.gooddata.account.AccountService; import com.gooddata.collections.PageRequest; @@ -19,7 +20,7 @@ public class AuditEventServiceTest { @BeforeMethod public void setUp() throws Exception { - service = new AuditEventService(new RestTemplate(), mock(AccountService.class)); + service = new AuditEventService(new RestTemplate(), mock(AccountService.class), new GoodDataSettings()); } @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = ".*account.*") diff --git a/src/test/java/com/gooddata/dataload/OutputStageServiceTest.java b/src/test/java/com/gooddata/dataload/OutputStageServiceTest.java index d7d03579f..89817e925 100644 --- a/src/test/java/com/gooddata/dataload/OutputStageServiceTest.java +++ b/src/test/java/com/gooddata/dataload/OutputStageServiceTest.java @@ -5,6 +5,7 @@ */ package com.gooddata.dataload; +import com.gooddata.GoodDataSettings; import com.gooddata.project.Project; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -41,7 +42,7 @@ public class OutputStageServiceTest { @BeforeMethod public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - outputStageService = new OutputStageService(restTemplate); + outputStageService = new OutputStageService(restTemplate, new GoodDataSettings()); outputStage = readObjectFromResource(OUTPUT_STAGE, OutputStage.class); } diff --git a/src/test/java/com/gooddata/dataload/processes/ProcessServiceTest.java b/src/test/java/com/gooddata/dataload/processes/ProcessServiceTest.java index 4a492d5a2..d4b5019a3 100644 --- a/src/test/java/com/gooddata/dataload/processes/ProcessServiceTest.java +++ b/src/test/java/com/gooddata/dataload/processes/ProcessServiceTest.java @@ -8,6 +8,7 @@ import com.gooddata.FutureResult; import com.gooddata.GoodDataException; import com.gooddata.GoodDataRestException; +import com.gooddata.GoodDataSettings; import com.gooddata.account.Account; import com.gooddata.account.AccountService; import com.gooddata.gdc.DataStoreService; @@ -80,7 +81,7 @@ public class ProcessServiceTest { @BeforeMethod public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - processService = new ProcessService(restTemplate, accountService, dataStoreService); + processService = new ProcessService(restTemplate, accountService, dataStoreService, new GoodDataSettings()); when(process.getId()).thenReturn(PROCESS_ID); when(process.getUri()).thenReturn(DataloadProcess.TEMPLATE.expand(PROJECT_ID, PROCESS_ID).toString()); when(project.getId()).thenReturn(PROJECT_ID); diff --git a/src/test/java/com/gooddata/dataset/DatasetServiceTest.java b/src/test/java/com/gooddata/dataset/DatasetServiceTest.java index 4437fe453..cd2025878 100644 --- a/src/test/java/com/gooddata/dataset/DatasetServiceTest.java +++ b/src/test/java/com/gooddata/dataset/DatasetServiceTest.java @@ -7,6 +7,7 @@ import com.gooddata.GoodDataException; import com.gooddata.GoodDataRestException; +import com.gooddata.GoodDataSettings; import com.gooddata.gdc.AboutLinks.Link; import com.gooddata.gdc.DataStoreException; import com.gooddata.gdc.DataStoreService; @@ -59,7 +60,7 @@ public class DatasetServiceTest { @BeforeMethod public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - service = new DatasetService(restTemplate, dataStoreService); + service = new DatasetService(restTemplate, dataStoreService, new GoodDataSettings()); when(project.getId()).thenReturn(PROJECT_ID); } diff --git a/src/test/java/com/gooddata/export/ExportServiceTest.java b/src/test/java/com/gooddata/export/ExportServiceTest.java index f627df7a2..5ca58d3ce 100644 --- a/src/test/java/com/gooddata/export/ExportServiceTest.java +++ b/src/test/java/com/gooddata/export/ExportServiceTest.java @@ -6,6 +6,7 @@ package com.gooddata.export; import com.gooddata.GoodDataEndpoint; +import com.gooddata.GoodDataSettings; import com.gooddata.md.ProjectDashboard; import com.gooddata.md.ProjectDashboard.Tab; import com.gooddata.md.report.Report; @@ -25,7 +26,7 @@ public class ExportServiceTest { - private final ExportService service = new ExportService(new RestTemplate(), new GoodDataEndpoint()); + private final ExportService service = new ExportService(new RestTemplate(), new GoodDataEndpoint(), new GoodDataSettings()); private ProjectDashboard dashboard; private Tab tab; private Report report; @@ -39,12 +40,12 @@ public void setUp() throws Exception { @Test(expectedExceptions = IllegalArgumentException.class) public void shouldFailOnNullArgument() throws Exception { - new ExportService(null, new GoodDataEndpoint()); + new ExportService(null, new GoodDataEndpoint(), new GoodDataSettings()); } @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = ".*endpoint.*") public void shouldFailOnNullEndpoint() throws Exception { - new ExportService(new RestTemplate(), null); + new ExportService(new RestTemplate(), null, new GoodDataSettings()); } @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = ".*dashboard.*") diff --git a/src/test/java/com/gooddata/featureflag/FeatureFlagServiceTest.java b/src/test/java/com/gooddata/featureflag/FeatureFlagServiceTest.java index 75352fdfc..3f9ffb71a 100644 --- a/src/test/java/com/gooddata/featureflag/FeatureFlagServiceTest.java +++ b/src/test/java/com/gooddata/featureflag/FeatureFlagServiceTest.java @@ -6,6 +6,7 @@ package com.gooddata.featureflag; import com.gooddata.GoodDataException; +import com.gooddata.GoodDataSettings; import com.gooddata.project.Project; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -48,7 +49,7 @@ public class FeatureFlagServiceTest { @BeforeMethod public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - service = new FeatureFlagService(restTemplate); + service = new FeatureFlagService(restTemplate, new GoodDataSettings()); when(project.getId()).thenReturn(PROJECT_ID); } diff --git a/src/test/java/com/gooddata/md/MetadataServiceTest.java b/src/test/java/com/gooddata/md/MetadataServiceTest.java index c3730b332..3cc9678a6 100644 --- a/src/test/java/com/gooddata/md/MetadataServiceTest.java +++ b/src/test/java/com/gooddata/md/MetadataServiceTest.java @@ -7,6 +7,7 @@ import com.gooddata.GoodDataException; import com.gooddata.GoodDataRestException; +import com.gooddata.GoodDataSettings; import com.gooddata.gdc.UriResponse; import com.gooddata.md.report.ReportDefinition; import com.gooddata.project.Project; @@ -53,7 +54,7 @@ public class MetadataServiceTest { @BeforeMethod public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - service = new MetadataService(restTemplate); + service = new MetadataService(restTemplate, new GoodDataSettings()); when(project.getId()).thenReturn(PROJECT_ID); } diff --git a/src/test/java/com/gooddata/md/maintenance/ExportImportServiceTest.java b/src/test/java/com/gooddata/md/maintenance/ExportImportServiceTest.java index c7ab39bc1..933d17c7a 100644 --- a/src/test/java/com/gooddata/md/maintenance/ExportImportServiceTest.java +++ b/src/test/java/com/gooddata/md/maintenance/ExportImportServiceTest.java @@ -10,6 +10,7 @@ import static org.mockito.Mockito.when; import com.gooddata.GoodDataRestException; +import com.gooddata.GoodDataSettings; import com.gooddata.gdc.UriResponse; import com.gooddata.project.Project; import org.mockito.Mock; @@ -32,7 +33,7 @@ public class ExportImportServiceTest { @BeforeMethod public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - service = new ExportImportService(restTemplate); + service = new ExportImportService(restTemplate, new GoodDataSettings()); when(project.getId()).thenReturn(PROJECT_ID); } diff --git a/src/test/java/com/gooddata/notification/NotificationServiceTest.java b/src/test/java/com/gooddata/notification/NotificationServiceTest.java index 81855ef32..241589246 100644 --- a/src/test/java/com/gooddata/notification/NotificationServiceTest.java +++ b/src/test/java/com/gooddata/notification/NotificationServiceTest.java @@ -8,6 +8,7 @@ import static java.util.Collections.singletonMap; import static org.mockito.Mockito.*; +import com.gooddata.GoodDataSettings; import com.gooddata.project.Project; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -30,7 +31,7 @@ public class NotificationServiceTest { @BeforeMethod public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - notificationService = new NotificationService(restTemplate); + notificationService = new NotificationService(restTemplate, new GoodDataSettings()); when(project.getId()).thenReturn(PROJECT_ID); } diff --git a/src/test/java/com/gooddata/project/ProjectServiceTest.java b/src/test/java/com/gooddata/project/ProjectServiceTest.java index 09862f89f..9ae66503f 100644 --- a/src/test/java/com/gooddata/project/ProjectServiceTest.java +++ b/src/test/java/com/gooddata/project/ProjectServiceTest.java @@ -7,6 +7,7 @@ import com.gooddata.GoodDataException; import com.gooddata.GoodDataRestException; +import com.gooddata.GoodDataSettings; import com.gooddata.account.Account; import com.gooddata.account.AccountService; import org.mockito.Mock; @@ -46,7 +47,7 @@ public class ProjectServiceTest { @BeforeMethod public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - service = new ProjectService(restTemplate, accountService); + service = new ProjectService(restTemplate, accountService, new GoodDataSettings()); when(accountService.getCurrent()).thenReturn(account); when(account.getId()).thenReturn(ACCOUNT_ID); when(project.getId()).thenReturn(ID); diff --git a/src/test/java/com/gooddata/projecttemplate/ProjectTemplateServiceTest.java b/src/test/java/com/gooddata/projecttemplate/ProjectTemplateServiceTest.java index 184dfe55d..6a59c693d 100644 --- a/src/test/java/com/gooddata/projecttemplate/ProjectTemplateServiceTest.java +++ b/src/test/java/com/gooddata/projecttemplate/ProjectTemplateServiceTest.java @@ -5,6 +5,7 @@ */ package com.gooddata.projecttemplate; +import com.gooddata.GoodDataSettings; import com.gooddata.dataset.DatasetManifest; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -38,7 +39,7 @@ public class ProjectTemplateServiceTest { @BeforeMethod public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - service = new ProjectTemplateService(restTemplate); + service = new ProjectTemplateService(restTemplate, new GoodDataSettings()); when(templates.getTemplates()).thenReturn(singletonList(template)); } diff --git a/src/test/java/com/gooddata/report/ReportServiceTest.java b/src/test/java/com/gooddata/report/ReportServiceTest.java index 7cda22e56..5cd7754e2 100644 --- a/src/test/java/com/gooddata/report/ReportServiceTest.java +++ b/src/test/java/com/gooddata/report/ReportServiceTest.java @@ -5,6 +5,7 @@ */ package com.gooddata.report; +import com.gooddata.GoodDataSettings; import com.gooddata.export.ExportFormat; import com.gooddata.export.ExportService; import com.gooddata.md.report.Report; @@ -27,12 +28,12 @@ public class ReportServiceTest { @BeforeMethod public void setUp() throws Exception { exportService = mock(ExportService.class); - reportService = new ReportService(exportService, mock(RestTemplate.class)); + reportService = new ReportService(exportService, mock(RestTemplate.class), new GoodDataSettings()); } @Test(expectedExceptions = IllegalArgumentException.class) public void shouldFailOnNullArgument() throws Exception { - new ReportService(null, mock(RestTemplate.class)); + new ReportService(null, mock(RestTemplate.class), new GoodDataSettings()); } @Test diff --git a/src/test/java/com/gooddata/warehouse/WarehouseServiceTest.java b/src/test/java/com/gooddata/warehouse/WarehouseServiceTest.java index 4fe84aca1..cccb7a78c 100644 --- a/src/test/java/com/gooddata/warehouse/WarehouseServiceTest.java +++ b/src/test/java/com/gooddata/warehouse/WarehouseServiceTest.java @@ -5,6 +5,7 @@ */ package com.gooddata.warehouse; +import com.gooddata.GoodDataSettings; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.http.HttpEntity; @@ -33,7 +34,7 @@ public class WarehouseServiceTest { @BeforeMethod public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - service = new WarehouseService(restTemplate); + service = new WarehouseService(restTemplate, new GoodDataSettings()); when(warehouse.getId()).thenReturn("instanceId"); final WarehouseTask warehouseTask = mock(WarehouseTask.class); From 426ae12f04f56a710e4cdb32967aca080d2a7870 Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Thu, 5 Oct 2017 22:09:52 +0200 Subject: [PATCH 028/598] enhance tests for error handler --- .../util/ResponseErrorHandlerTest.java | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/test/java/com/gooddata/util/ResponseErrorHandlerTest.java b/src/test/java/com/gooddata/util/ResponseErrorHandlerTest.java index d9c038988..8903e1636 100644 --- a/src/test/java/com/gooddata/util/ResponseErrorHandlerTest.java +++ b/src/test/java/com/gooddata/util/ResponseErrorHandlerTest.java @@ -42,7 +42,7 @@ public void testHandleGdcError() throws Exception { final GoodDataRestException exc = assertException(response); - assertThat("GoodDataRestException should have been thrown!", exc, is(notNullValue())); + assertThat(exc.getMessage(), is("500: [requestId=REQ] MSG")); assertThat(exc.getStatusCode(), is(500)); assertThat(exc.getRequestId(), is("REQ")); assertThat(exc.getComponent(), is("COMPONENT")); @@ -57,7 +57,7 @@ public void testHandleErrorStructure() throws Exception { final GoodDataRestException exc = assertException(response); - assertThat("GoodDataRestException should have been thrown!", exc, is(notNullValue())); + assertThat(exc.getMessage(), is("500: [requestId=REQ] MSG PARAM1 PARAM2 3")); assertThat(exc.getStatusCode(), is(500)); assertThat(exc.getRequestId(), is("REQ")); assertThat(exc.getComponent(), is("COMPONENT")); @@ -72,7 +72,7 @@ public void testHandleInvalidError() throws Exception { final GoodDataRestException exc = assertException(response); - assertThat("GoodDataRestException should have been thrown!", exc, is(notNullValue())); + assertThat(exc.getMessage(), is("500: [requestId=requestId] Unknown error")); assertThat(exc.getStatusCode(), is(500)); assertThat(exc.getRequestId(), is("requestId")); assertThat(exc.getComponent(), is(nullValue())); @@ -81,16 +81,39 @@ public void testHandleInvalidError() throws Exception { assertThat(exc.getText(), is(nullValue())); } + @Test + public void shouldName() throws Exception { + final ClientHttpResponse response = prepareResponse(); + final HttpHeaders headers = new HttpHeaders(); + when(response.getHeaders()).thenReturn(headers); + when(response.getStatusText()).thenThrow(IOException.class); + when(response.getRawStatusCode()).thenThrow(IOException.class); + + final GoodDataRestException exc = assertException(response); + + assertThat(exc.getMessage(), is("0: Unknown error")); + assertThat(exc.getStatusCode(), is(0)); + assertThat(exc.getRequestId(), is(nullValue())); + assertThat(exc.getComponent(), is(nullValue())); + assertThat(exc.getErrorClass(), is(nullValue())); + assertThat(exc.getErrorCode(), is(nullValue())); + assertThat(exc.getText(), is(nullValue())); + } + private ClientHttpResponse prepareResponse(String resourcePath) throws IOException { - final ClientHttpResponse response = mock(ClientHttpResponse.class); - when(response.getStatusCode()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR); - when(response.getRawStatusCode()).thenReturn(500); + final ClientHttpResponse response = prepareResponse(); final HttpHeaders headers = new HttpHeaders(); + when(response.getHeaders()).thenReturn(headers); headers.set(GoodData.GDC_REQUEST_ID_HEADER, "requestId"); headers.setContentType(MediaType.APPLICATION_JSON); - when(response.getHeaders()).thenReturn(headers); when(response.getBody()).thenReturn(readFromResource(resourcePath)); + return response; + } + private ClientHttpResponse prepareResponse() throws IOException { + final ClientHttpResponse response = mock(ClientHttpResponse.class); + when(response.getStatusCode()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR); + when(response.getRawStatusCode()).thenReturn(500); return response; } From c4e7e69aa11fdbd847f57be5176cfe0d1e02140d Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Wed, 4 Oct 2017 21:27:05 +0200 Subject: [PATCH 029/598] remove tests using mocked rest template --- CONTRIBUTING.md | 2 +- .../gooddata/notification/ProjectEvent.java | 16 ++-- .../dataload/OutputStageServiceTest.java | 60 +-------------- .../processes/ProcessServiceTest.java | 6 +- .../gooddata/dataset/DatasetServiceTest.java | 20 ----- .../featureflag/FeatureFlagServiceTest.java | 65 ---------------- .../featureflag/ProjectFeatureFlagTest.java | 11 +++ .../notification/NotificationServiceTest.java | 18 +---- .../notification/ProjectEventTest.java | 9 +++ .../ProjectTemplateServiceTest.java | 75 ------------------- .../gooddata/report/ReportServiceTest.java | 2 +- .../warehouse/WarehouseServiceTest.java | 13 ---- 12 files changed, 35 insertions(+), 262 deletions(-) delete mode 100644 src/test/java/com/gooddata/projecttemplate/ProjectTemplateServiceTest.java diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c61a4f09f..3c2fc1028 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,7 +65,7 @@ is specific enough. ## Best practices * **Test class naming**: - * `*Test` unit tests + * `*Test` unit tests, but avoid service tests using mocked `RestTemplate` - use integration test * `*IT` integration tests (see [`AbstractGoodDataIT`](src/test/java/com/gooddata/AbstractGoodDataIT.java)) * `*AT` acceptance tests * Everything public should be **documented** using _javadoc_. diff --git a/src/main/java/com/gooddata/notification/ProjectEvent.java b/src/main/java/com/gooddata/notification/ProjectEvent.java index 126a62bcf..cc2173a3e 100644 --- a/src/main/java/com/gooddata/notification/ProjectEvent.java +++ b/src/main/java/com/gooddata/notification/ProjectEvent.java @@ -66,18 +66,14 @@ public Map getParameters() { } @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (!(o instanceof ProjectEvent)) - return false; + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; - ProjectEvent that = (ProjectEvent) o; - - if (type != null ? !type.equals(that.type) : that.type != null) - return false; - return !(parameters != null ? !parameters.equals(that.parameters) : that.parameters != null); + final ProjectEvent that = (ProjectEvent) o; + if (type != null ? !type.equals(that.type) : that.type != null) return false; + return parameters != null ? parameters.equals(that.parameters) : that.parameters == null; } @Override diff --git a/src/test/java/com/gooddata/dataload/OutputStageServiceTest.java b/src/test/java/com/gooddata/dataload/OutputStageServiceTest.java index 89817e925..ee4fdea27 100644 --- a/src/test/java/com/gooddata/dataload/OutputStageServiceTest.java +++ b/src/test/java/com/gooddata/dataload/OutputStageServiceTest.java @@ -6,44 +6,17 @@ package com.gooddata.dataload; import com.gooddata.GoodDataSettings; -import com.gooddata.project.Project; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.springframework.http.HttpMethod; -import org.springframework.http.RequestEntity; -import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import static com.gooddata.util.ResourceUtils.readObjectFromResource; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.core.Is.is; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - public class OutputStageServiceTest { - private static final String OUTPUT_STAGE = "/dataload/outputStage.json"; - - @Mock - private RestTemplate restTemplate; - private OutputStageService outputStageService; - private OutputStage outputStage; - @BeforeMethod public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - outputStageService = new OutputStageService(restTemplate, new GoodDataSettings()); - outputStage = readObjectFromResource(OUTPUT_STAGE, OutputStage.class); + outputStageService = new OutputStageService(new RestTemplate(), new GoodDataSettings()); } @Test(expectedExceptions = IllegalArgumentException.class) @@ -51,44 +24,13 @@ public void testGetOutputStageByNullUri() throws Exception { outputStageService.getOutputStageByUri(null); } - @Test - public void testGetOutputStageByUri() throws Exception { - when(restTemplate.getForObject(outputStage.getUri(), OutputStage.class)).thenReturn(outputStage); - - OutputStage outputStageByUri = outputStageService.getOutputStageByUri(outputStage.getUri()); - - assertThat(outputStageByUri, is(equalTo(outputStage))); - } - @Test(expectedExceptions = IllegalArgumentException.class) public void testGetOutputStageByNullProject() throws Exception { outputStageService.getOutputStage(null); } - @Test - public void testGetOutputStage() throws Exception { - Project project = mock(Project.class); - when(project.getId()).thenReturn("projectId"); - when(restTemplate.getForObject(outputStage.getUri(), OutputStage.class)).thenReturn(outputStage); - - OutputStage outputStageByProject = outputStageService.getOutputStage(project); - - assertThat(outputStageByProject, is(equalTo(outputStage))); - } - @Test(expectedExceptions = IllegalArgumentException.class) public void testUpdateOutputStageNullOutputStage() throws Exception { outputStageService.updateOutputStage(null); } - - @Test - public void testUpdateOutputStage() throws Exception { - ResponseEntity responseEntity = mock(ResponseEntity.class); - when(restTemplate.exchange(eq(outputStage.getUri()), eq(HttpMethod.PUT), any(RequestEntity.class), eq(OutputStage.class))).thenReturn(responseEntity); - doReturn(outputStage).when(responseEntity).getBody(); - - outputStageService.updateOutputStage(outputStage); - - verify(restTemplate, times(1)).exchange(eq(outputStage.getUri()), eq(HttpMethod.PUT), any(RequestEntity.class), eq(OutputStage.class)); - } } \ No newline at end of file diff --git a/src/test/java/com/gooddata/dataload/processes/ProcessServiceTest.java b/src/test/java/com/gooddata/dataload/processes/ProcessServiceTest.java index d4b5019a3..7842f9659 100644 --- a/src/test/java/com/gooddata/dataload/processes/ProcessServiceTest.java +++ b/src/test/java/com/gooddata/dataload/processes/ProcessServiceTest.java @@ -90,7 +90,7 @@ public void setUp() throws Exception { } @Test - public void testCreateProcess() throws Exception { + public void shouldDeploySmallProcessUsingAPI() throws Exception { final DataloadProcess process = new DataloadProcess("test", ProcessType.GRAPH); @@ -109,7 +109,7 @@ public void testCreateProcess() throws Exception { } @Test - public void testCreateProcessLargerThan1MB() throws Exception { + public void shouldDeployLargeProcessUsingWebDAV() throws Exception { final DataloadProcess process = new DataloadProcess("test", ProcessType.GRAPH); @@ -122,8 +122,6 @@ public void testCreateProcessLargerThan1MB() throws Exception { verify(dataStoreService).upload(anyString(), notNull(InputStream.class)); } - - private static File createProcessOfSize(int size) throws Exception { final Random r = new Random(); final File file = File.createTempFile("process", ".txt"); diff --git a/src/test/java/com/gooddata/dataset/DatasetServiceTest.java b/src/test/java/com/gooddata/dataset/DatasetServiceTest.java index cd2025878..502b6cf49 100644 --- a/src/test/java/com/gooddata/dataset/DatasetServiceTest.java +++ b/src/test/java/com/gooddata/dataset/DatasetServiceTest.java @@ -79,15 +79,6 @@ public void testGetDatasetManifestWithEmptyId() throws Exception { service.getDatasetManifest(project, ""); } - @Test - public void testGetDatasetManifest() throws Exception { - when(restTemplate.getForObject(DatasetManifest.URI, DatasetManifest.class, PROJECT_ID, DATASET_ID)) - .thenReturn(manifest); - final DatasetManifest result = service.getDatasetManifest(project, DATASET_ID); - - assertThat(result, is(manifest)); - } - @Test(expectedExceptions = DatasetNotFoundException.class) public void testGetDatasetManifestWhenNotFound() throws Exception { when(restTemplate.getForObject(DatasetManifest.URI, DatasetManifest.class, PROJECT_ID, DATASET_ID)) @@ -207,17 +198,6 @@ public void testListDatasetLinksWithRestClientError() throws Exception { service.listDatasetLinks(project); } - @Test - public void testListDatasetLinksWithEmptyResponse() throws Exception { - final DatasetLinks datasets = mock(DatasetLinks.class); - when(restTemplate.getForObject(DatasetLinks.URI, DatasetLinks.class, PROJECT_ID)).thenReturn(datasets); - when(datasets.getLinks()).thenReturn(singletonList(datasetLink)); - - final Collection result = service.listDatasetLinks(project); - assertThat(result, hasSize(1)); - assertThat(result, contains(datasetLink)); - } - @Test(expectedExceptions = GoodDataException.class) public void testGetDataSetInfoRestClientError() throws Exception { when(restTemplate.getForObject(UploadsInfo.URI, UploadsInfo.class, PROJECT_ID)) diff --git a/src/test/java/com/gooddata/featureflag/FeatureFlagServiceTest.java b/src/test/java/com/gooddata/featureflag/FeatureFlagServiceTest.java index 3f9ffb71a..9ffcbfaa7 100644 --- a/src/test/java/com/gooddata/featureflag/FeatureFlagServiceTest.java +++ b/src/test/java/com/gooddata/featureflag/FeatureFlagServiceTest.java @@ -71,17 +71,6 @@ public void whenClientErrorResponseThenGetFeatureFlagsShouldThrow() throws Excep service.listFeatureFlags(project); } - @Test - public void testGetFeatureFlags() throws Exception { - final FeatureFlag flag1 = new FeatureFlag(FLAG_NAME, true); - when(restTemplate.getForObject(new URI(FEATURE_FLAGS_URI), FeatureFlags.class)).thenReturn(featureFlags); - when(featureFlags.iterator()).thenReturn(singleton(flag1).iterator()); - - final FeatureFlags flags = service.listFeatureFlags(project); - - assertThat(flags, contains(flag1)); - } - @Test(expectedExceptions = IllegalArgumentException.class) public void whenNullArgThenGetProjectFeatureFlagsShouldThrow() throws Exception { service.listProjectFeatureFlags(null); @@ -100,18 +89,6 @@ public void whenClientErrorResponseThenGetProjectFeatureFlagsShouldThrow() throw service.listProjectFeatureFlags(project); } - @Test - public void testGetProjectFeatureFlags() throws Exception { - final ProjectFeatureFlag flag1 = new ProjectFeatureFlag(FLAG_NAME, true); - when(restTemplate.getForObject(new URI(PROJECT_FEATURE_FLAGS_URI), ProjectFeatureFlags.class)) - .thenReturn(projectFeatureFlags); - when(projectFeatureFlags.iterator()).thenReturn(singleton(flag1).iterator()); - - final ProjectFeatureFlags flags = service.listProjectFeatureFlags(project); - - assertThat(flags, contains(flag1)); - } - @Test(expectedExceptions = IllegalArgumentException.class) public void whenNullKeyThenCreateProjectFeatureFlagShouldThrow() throws Exception { service.createProjectFeatureFlag(project, null); @@ -135,18 +112,6 @@ public void whenClientErrorResponseThenCreateProjectFeatureFlagShouldThrow() thr service.createProjectFeatureFlag(project, projectFeatureFlag); } - @Test - public void testCreateProjectFeatureFlag() throws Exception { - final ProjectFeatureFlag flag = new ProjectFeatureFlag(FLAG_NAME, true); - when(restTemplate.postForLocation(PROJECT_FEATURE_FLAGS_URI, flag)) - .thenReturn(new URI(PROJECT_FEATURE_FLAG_URI)); - when(restTemplate.getForObject(PROJECT_FEATURE_FLAG_URI, ProjectFeatureFlag.class)).thenReturn(flag); - - final ProjectFeatureFlag result = service.createProjectFeatureFlag(project, flag); - - assertThat(result, is(flag)); - } - @Test(expectedExceptions = IllegalArgumentException.class) public void whenNullKeyThenGetProjectFeatureFlagShouldThrow() throws Exception { service.getProjectFeatureFlag(project, null); @@ -170,16 +135,6 @@ public void whenClientErrorResponseThenGetProjectFeatureFlagShouldThrow() throws service.getProjectFeatureFlag(project, FLAG_NAME); } - @Test - public void testGetProjectFeatureFlag() throws Exception { - final ProjectFeatureFlag flag = new ProjectFeatureFlag(FLAG_NAME, true); - when(restTemplate.getForObject(PROJECT_FEATURE_FLAG_URI, ProjectFeatureFlag.class)).thenReturn(flag); - - final ProjectFeatureFlag result = service.getProjectFeatureFlag(project, FLAG_NAME); - - assertThat(result, is(flag)); - } - @Test(expectedExceptions = IllegalArgumentException.class) public void whenNullFlagThenUpdateProjectFeatureFlagShouldThrow() throws Exception { service.updateProjectFeatureFlag(null); @@ -200,19 +155,6 @@ public void whenClientErrorResponseThenUpdateProjectFeatureFlagShouldThrow() thr service.updateProjectFeatureFlag(projectFeatureFlag); } - @Test - public void testUpdateProjectFeatureFlag() throws Exception { - final ProjectFeatureFlag newFlag = new ProjectFeatureFlag(FLAG_NAME, true); - when(projectFeatureFlag.getUri()).thenReturn(PROJECT_FEATURE_FLAG_URI); - when(restTemplate.getForObject(PROJECT_FEATURE_FLAG_URI, ProjectFeatureFlag.class)) - .thenReturn(newFlag); - - final ProjectFeatureFlag result = service.updateProjectFeatureFlag(projectFeatureFlag); - - verify(restTemplate).put(PROJECT_FEATURE_FLAG_URI, projectFeatureFlag); - assertThat(result, is(newFlag)); - } - @Test(expectedExceptions = IllegalArgumentException.class) public void whenNullFlagThenDeleteProjectFeatureFlagShouldThrow() throws Exception { service.deleteProjectFeatureFlag(null); @@ -225,11 +167,4 @@ public void whenClientErrorResponseThenDeleteProjectFeatureFlagShouldThrow() thr service.deleteProjectFeatureFlag(projectFeatureFlag); } - @Test - public void testDeleteProjectFeatureFlag() throws Exception { - when(projectFeatureFlag.getUri()).thenReturn(PROJECT_FEATURE_FLAG_URI); - service.deleteProjectFeatureFlag(projectFeatureFlag); - verify(restTemplate).delete(PROJECT_FEATURE_FLAG_URI); - } - } \ No newline at end of file diff --git a/src/test/java/com/gooddata/featureflag/ProjectFeatureFlagTest.java b/src/test/java/com/gooddata/featureflag/ProjectFeatureFlagTest.java index 6f1165d5b..a0b7c1aea 100644 --- a/src/test/java/com/gooddata/featureflag/ProjectFeatureFlagTest.java +++ b/src/test/java/com/gooddata/featureflag/ProjectFeatureFlagTest.java @@ -5,6 +5,8 @@ */ package com.gooddata.featureflag; +import nl.jqno.equalsverifier.EqualsVerifier; +import nl.jqno.equalsverifier.Warning; import org.testng.annotations.Test; import static org.hamcrest.CoreMatchers.is; @@ -41,4 +43,13 @@ public void testToStringFormat() { assertThat(flag.toString(), matchesPattern(ProjectFeatureFlag.class.getSimpleName() + "\\[.*\\]")); } + + @Test + public void shouldVerifyEquals() throws Exception { + EqualsVerifier.forClass(ProjectFeatureFlag.class) + .usingGetClass() + .suppress(Warning.NONFINAL_FIELDS) + .withIgnoredFields("links") + .verify(); + } } \ No newline at end of file diff --git a/src/test/java/com/gooddata/notification/NotificationServiceTest.java b/src/test/java/com/gooddata/notification/NotificationServiceTest.java index 241589246..fc232cc1c 100644 --- a/src/test/java/com/gooddata/notification/NotificationServiceTest.java +++ b/src/test/java/com/gooddata/notification/NotificationServiceTest.java @@ -5,9 +5,6 @@ */ package com.gooddata.notification; -import static java.util.Collections.singletonMap; -import static org.mockito.Mockito.*; - import com.gooddata.GoodDataSettings; import com.gooddata.project.Project; import org.mockito.Mock; @@ -16,6 +13,9 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + public class NotificationServiceTest { private static final String PROJECT_ID = "TEST_PROJ_ID"; @@ -23,25 +23,15 @@ public class NotificationServiceTest { @Mock private Project project; - @Mock - private RestTemplate restTemplate; - private NotificationService notificationService; @BeforeMethod public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - notificationService = new NotificationService(restTemplate, new GoodDataSettings()); + notificationService = new NotificationService(new RestTemplate(), new GoodDataSettings()); when(project.getId()).thenReturn(PROJECT_ID); } - @Test - public void testTriggerEvent() throws Exception { - final ProjectEvent projectEvent = new ProjectEvent("type", singletonMap("key", "value")); - notificationService.triggerEvent(project, projectEvent); - verify(restTemplate).postForEntity(eq(ProjectEvent.URI), eq(projectEvent), eq(Void.class), eq(PROJECT_ID)); - } - @Test(expectedExceptions = IllegalArgumentException.class) public void testTriggerNullEvent() throws Exception { notificationService.triggerEvent(project, null); diff --git a/src/test/java/com/gooddata/notification/ProjectEventTest.java b/src/test/java/com/gooddata/notification/ProjectEventTest.java index aec1f24a7..089c8643d 100644 --- a/src/test/java/com/gooddata/notification/ProjectEventTest.java +++ b/src/test/java/com/gooddata/notification/ProjectEventTest.java @@ -10,6 +10,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.text.MatchesPattern.matchesPattern; +import nl.jqno.equalsverifier.EqualsVerifier; import org.testng.annotations.Test; public class ProjectEventTest { @@ -27,4 +28,12 @@ public void testToStringFormat() { assertThat(projectEvent.toString(), matchesPattern(ProjectEvent.class.getSimpleName() + "\\[.*\\]")); } + + @Test + public void shouldVerifyEquals() throws Exception { + EqualsVerifier.forClass(ProjectEvent.class) + .usingGetClass() + .verify(); + } + } \ No newline at end of file diff --git a/src/test/java/com/gooddata/projecttemplate/ProjectTemplateServiceTest.java b/src/test/java/com/gooddata/projecttemplate/ProjectTemplateServiceTest.java deleted file mode 100644 index 6a59c693d..000000000 --- a/src/test/java/com/gooddata/projecttemplate/ProjectTemplateServiceTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2004-2017, GoodData(R) Corporation. All rights reserved. - * This source code is licensed under the BSD-style license found in the - * LICENSE.txt file in the root directory of this source tree. - */ -package com.gooddata.projecttemplate; - -import com.gooddata.GoodDataSettings; -import com.gooddata.dataset.DatasetManifest; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.springframework.web.client.RestTemplate; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import java.util.Collection; - -import static java.util.Collections.singletonList; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; -import static org.mockito.Mockito.when; - -public class ProjectTemplateServiceTest { - - private static final String TEMPLATE_URI = "/projectTemplates/ZendeskAnalytics/20"; - - @Mock - private RestTemplate restTemplate; - @Mock - private Template template; - @Mock - private Templates templates; - @Mock - private DatasetManifest manifest; - - private ProjectTemplateService service; - - @BeforeMethod - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - service = new ProjectTemplateService(restTemplate, new GoodDataSettings()); - when(templates.getTemplates()).thenReturn(singletonList(template)); - } - - @Test - public void testGetTemplate() throws Exception { - when(restTemplate.getForObject(TEMPLATE_URI, Template.class)) - .thenReturn(template); - final Template template = service.getTemplateByUri(TEMPLATE_URI); - assertThat(template, is(template)); - } - - @Test - public void testGetTemplates() throws Exception { - when(restTemplate.getForObject("/projectTemplates", Templates.class)) - .thenReturn(templates); - - final Collection