diff --git a/src/main/java/com/gooddata/warehouse/WarehouseService.java b/src/main/java/com/gooddata/warehouse/WarehouseService.java index 71d58b8d4..9254eea74 100644 --- a/src/main/java/com/gooddata/warehouse/WarehouseService.java +++ b/src/main/java/com/gooddata/warehouse/WarehouseService.java @@ -176,6 +176,18 @@ private PageableList listWarehouses(final URI uri) { } } + public PageableList listWarehouseUsers(final Warehouse warehouse, final Page page) { + notNull(warehouse, "warehouse"); + notNull(warehouse.getId(), "warehouse.id"); + notNull(page, "page"); + try { + final WarehouseUsers result = restTemplate.getForObject(WarehouseUsers.URI, WarehouseUsers.class, warehouse.getId()); + return result != null ? result : new PageableList(); + } catch (GoodDataException | RestClientException e) { + throw new GoodDataException("Unable to list users of warehouse " + warehouse.getId(), e); + } + } + /** * Updates given Warehouse. * diff --git a/src/main/java/com/gooddata/warehouse/WarehouseUser.java b/src/main/java/com/gooddata/warehouse/WarehouseUser.java new file mode 100644 index 000000000..086df1f09 --- /dev/null +++ b/src/main/java/com/gooddata/warehouse/WarehouseUser.java @@ -0,0 +1,76 @@ +package com.gooddata.warehouse; + +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonIgnore; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.annotate.JsonTypeInfo; +import org.codehaus.jackson.annotate.JsonTypeName; +import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.springframework.web.util.UriTemplate; + +import java.util.Map; + +import static com.gooddata.util.Validate.notNull; +import static org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_NULL; + +/** + * Warehouse user + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName("user") +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonSerialize(include = NON_NULL) +public class WarehouseUser { + + public static final String URI = WarehouseUsers.URI + "/{userId}"; + public static final UriTemplate TEMPLATE = new UriTemplate(URI); + + private static final String SELF_LINK = "self"; + + private String role; + private String profile; + private String login; + private Map links; + + public WarehouseUser(final String role, final String profile, final String login) { + this.role = notNull(role, "role"); + if (profile == null) { + notNull(login, "login"); + } + if (login == null) { + notNull(profile, "profile"); + } + this.profile = profile; + this.login = login; + } + + @JsonCreator + public WarehouseUser(@JsonProperty("role") String role, @JsonProperty("profile") String profile, + @JsonProperty("login") String login, @JsonProperty("links") Map links) { + this(role, profile, login); + this.links = links; + } + + public String getRole() { + return role; + } + + public String getProfile() { + return profile; + } + + public String getLogin() { + return login; + } + + public Map getLinks() { + return links; + } + + @JsonIgnore + public String getUri() { + return links != null ? links.get(SELF_LINK): null; + } + +} diff --git a/src/main/java/com/gooddata/warehouse/WarehouseUsers.java b/src/main/java/com/gooddata/warehouse/WarehouseUsers.java new file mode 100644 index 000000000..419b881da --- /dev/null +++ b/src/main/java/com/gooddata/warehouse/WarehouseUsers.java @@ -0,0 +1,38 @@ +package com.gooddata.warehouse; + +import com.gooddata.collections.PageableList; +import com.gooddata.collections.Paging; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonTypeInfo; +import org.codehaus.jackson.annotate.JsonTypeName; +import org.codehaus.jackson.map.annotate.JsonDeserialize; +import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.springframework.web.util.UriTemplate; + +import java.util.List; +import java.util.Map; + +/** + * List of warehouse users. + */ +@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) +@JsonTypeName(WarehouseUsers.ROOT_NODE) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonDeserialize(using = WarehouseUsersDeserializer.class) +@JsonSerialize(using = WarehouseUsersSerializer.class) +public class WarehouseUsers extends PageableList { + + public static final String URI = Warehouse.URI + "/users"; + public static final UriTemplate TEMPLATE = new UriTemplate(URI); + + static final String ROOT_NODE = "users"; + + public WarehouseUsers(final List items, final Paging paging) { + super(items, paging); + } + + public WarehouseUsers(final List items, final Paging paging, final Map links) { + super(items, paging, links); + } + +} diff --git a/src/main/java/com/gooddata/warehouse/WarehouseUsersDeserializer.java b/src/main/java/com/gooddata/warehouse/WarehouseUsersDeserializer.java new file mode 100644 index 000000000..54526e9f9 --- /dev/null +++ b/src/main/java/com/gooddata/warehouse/WarehouseUsersDeserializer.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2007-2015, GoodData(R) Corporation. All rights reserved. + */ +package com.gooddata.warehouse; + +import com.gooddata.collections.PageableListDeserializer; +import com.gooddata.collections.Paging; + +import java.util.List; +import java.util.Map; + +/** + * Deserializer of JSON into warehouse users object. + */ +class WarehouseUsersDeserializer extends PageableListDeserializer { + + protected WarehouseUsersDeserializer() { + super(WarehouseUser.class); + } + + @Override + protected WarehouseUsers createList(final List items, final Paging paging, final Map links) { + return new WarehouseUsers(items, paging, links); + } +} diff --git a/src/main/java/com/gooddata/warehouse/WarehouseUsersSerializer.java b/src/main/java/com/gooddata/warehouse/WarehouseUsersSerializer.java new file mode 100644 index 000000000..93968d55a --- /dev/null +++ b/src/main/java/com/gooddata/warehouse/WarehouseUsersSerializer.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2007-2015, GoodData(R) Corporation. All rights reserved. + */ +package com.gooddata.warehouse; + +import com.gooddata.collections.PageableListSerializer; + +import static com.gooddata.warehouse.WarehouseUsers.ROOT_NODE; + +/** + * Serializer of warehouse users object into JSON. + */ +class WarehouseUsersSerializer extends PageableListSerializer { + + public WarehouseUsersSerializer() { + super(ROOT_NODE); + } + +} diff --git a/src/test/java/com/gooddata/warehouse/WarehouseServiceAT.java b/src/test/java/com/gooddata/warehouse/WarehouseServiceAT.java index f9bd67167..fac69398b 100644 --- a/src/test/java/com/gooddata/warehouse/WarehouseServiceAT.java +++ b/src/test/java/com/gooddata/warehouse/WarehouseServiceAT.java @@ -14,6 +14,8 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.core.IsCollectionContaining.hasItem; /** @@ -75,6 +77,14 @@ public void shouldReturnNullOnEndOfPaging() throws Exception { } } + @Test(groups = "warehouse", dependsOnMethods = "createWarehouse") + public void shouldListUsers() throws Exception { + final PageableList users = service.listWarehouseUsers(warehouse, new PageRequest(1)); + assertThat(users, hasSize(1)); + assertThat(users.get(0), is(notNullValue())); + assertThat(users.getNextPage(), is(nullValue())); + } + @Test(dependsOnGroups = "warehouse") public void removeWarehouse() throws Exception { service.removeWarehouse(warehouse); diff --git a/src/test/java/com/gooddata/warehouse/WarehouseUserTest.java b/src/test/java/com/gooddata/warehouse/WarehouseUserTest.java new file mode 100644 index 000000000..8002d77bc --- /dev/null +++ b/src/test/java/com/gooddata/warehouse/WarehouseUserTest.java @@ -0,0 +1,53 @@ +package com.gooddata.warehouse; + +import org.codehaus.jackson.map.ObjectMapper; +import org.testng.annotations.Test; + +import java.util.LinkedHashMap; +import java.util.Map; + +import static com.gooddata.JsonMatchers.serializesToJson; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; + +public class WarehouseUserTest { + + public static final String ROLE = "admin"; + public static final String PROFILE = "/gdc/account/profile/{profile-id}"; + public static final String LOGIN = "foo@bar.com"; + public static final String SELF_LINK = "/gdc/datawarehouse/instances/{instance-id}/users/{profile-id}"; + public static final Map LINKS = new LinkedHashMap() {{ + put("self", SELF_LINK); + put("parent", "/gdc/datawarehouse/instances/{instance-id}/users"); + }}; + + @Test + public void testSerializationWithProfile() throws Exception { + final WarehouseUser user = new WarehouseUser(ROLE, PROFILE, null); + assertThat(user, serializesToJson("/warehouse/user-createWithProfile.json")); + } + + @Test + public void testSerializationWithLogin() throws Exception { + final WarehouseUser user = new WarehouseUser(ROLE, null, LOGIN); + assertThat(user, serializesToJson("/warehouse/user-createWithLogin.json")); + } + + @Test + public void testCompleteSerialization() throws Exception { + final WarehouseUser user = new WarehouseUser(ROLE, PROFILE, LOGIN, LINKS); + assertThat(user, serializesToJson("/warehouse/user.json")); + } + + @Test + public void testDeserialization() throws Exception { + final WarehouseUser user = new ObjectMapper() + .readValue(getClass().getResourceAsStream("/warehouse/user.json"), WarehouseUser.class); + + assertThat(user.getRole(), is(ROLE)); + assertThat(user.getProfile(), is(PROFILE)); + assertThat(user.getLogin(), is(LOGIN)); + assertThat(user.getUri(), is(SELF_LINK)); + assertThat(user.getLinks(), is(LINKS)); + } +} \ No newline at end of file diff --git a/src/test/java/com/gooddata/warehouse/WarehouseUsersTest.java b/src/test/java/com/gooddata/warehouse/WarehouseUsersTest.java new file mode 100644 index 000000000..52f3f9f6b --- /dev/null +++ b/src/test/java/com/gooddata/warehouse/WarehouseUsersTest.java @@ -0,0 +1,45 @@ +package com.gooddata.warehouse; + +import org.testng.annotations.Test; + +import java.util.Collections; + +import static com.gooddata.JsonMatchers.serializesToJson; +import static com.gooddata.util.ResourceUtils.readObjectFromResource; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; +import static org.hamcrest.core.Is.is; + +public class WarehouseUsersTest { + + private final WarehouseUsers users = readObjectFromResource("/warehouse/users.json", WarehouseUsers.class); + + private final WarehouseUsers empty = new WarehouseUsers(Collections.emptyList(), null); + + @Test + public void testDeserialization() throws Exception { + assertThat(users, notNullValue()); + assertThat(users, hasSize(2)); + assertThat(users.get(0).getProfile(), startsWith("/gdc/account/profile/{profile-id")); + } + + @Test + public void shouldDeserializeEmpty() throws Exception { + final WarehouseUsers result = readObjectFromResource("/warehouse/users-empty.json", WarehouseUsers.class); + assertThat(result, hasSize(0)); + assertThat(result.getPaging(), is(notNullValue())); + } + + @Test + public void testSerialization() throws Exception { + assertThat(users, serializesToJson("/warehouse/users.json")); + } + + @Test + public void shouldSerializeEmpty() throws Exception { + assertThat(empty, serializesToJson("/warehouse/users-empty.json")); + } +} \ No newline at end of file diff --git a/src/test/resources/warehouse/user-createWithLogin.json b/src/test/resources/warehouse/user-createWithLogin.json new file mode 100644 index 000000000..57f1b96c0 --- /dev/null +++ b/src/test/resources/warehouse/user-createWithLogin.json @@ -0,0 +1,6 @@ +{ + "user" : { + "role" : "admin", + "login" : "foo@bar.com" + } +} diff --git a/src/test/resources/warehouse/user-createWithProfile.json b/src/test/resources/warehouse/user-createWithProfile.json new file mode 100644 index 000000000..666f8cdfc --- /dev/null +++ b/src/test/resources/warehouse/user-createWithProfile.json @@ -0,0 +1,6 @@ +{ + "user" : { + "role" : "admin", + "profile" : "/gdc/account/profile/{profile-id}" + } +} diff --git a/src/test/resources/warehouse/user-withoutLogin.json b/src/test/resources/warehouse/user-withoutLogin.json new file mode 100644 index 000000000..2ef6cba04 --- /dev/null +++ b/src/test/resources/warehouse/user-withoutLogin.json @@ -0,0 +1,10 @@ +{ + "user" : { + "role" : "admin", + "profile" : "/gdc/account/profile/{profile-id}", + "links" : { + "self" : "/gdc/datawarehouse/instances/{instance-id}/users/{profile-id}", + "parent" : "/gdc/datawarehouse/instances/{instance-id}/users" + } + } +} diff --git a/src/test/resources/warehouse/user.json b/src/test/resources/warehouse/user.json new file mode 100644 index 000000000..4d2320c7b --- /dev/null +++ b/src/test/resources/warehouse/user.json @@ -0,0 +1,11 @@ +{ + "user" : { + "role" : "admin", + "profile" : "/gdc/account/profile/{profile-id}", + "login" : "foo@bar.com", + "links" : { + "self" : "/gdc/datawarehouse/instances/{instance-id}/users/{profile-id}", + "parent" : "/gdc/datawarehouse/instances/{instance-id}/users" + } + } +} \ No newline at end of file diff --git a/src/test/resources/warehouse/users-empty.json b/src/test/resources/warehouse/users-empty.json new file mode 100644 index 000000000..5974e5512 --- /dev/null +++ b/src/test/resources/warehouse/users-empty.json @@ -0,0 +1,7 @@ +{ + "users": { + "items": [], + "paging": {}, + "links": {} + } +} \ No newline at end of file diff --git a/src/test/resources/warehouse/users.json b/src/test/resources/warehouse/users.json new file mode 100644 index 000000000..57c48a2f9 --- /dev/null +++ b/src/test/resources/warehouse/users.json @@ -0,0 +1,31 @@ +{ + "users": { + "items": [ + { + "user": { + "role": "admin", + "profile": "/gdc/account/profile/{profile-id}", + "links": { + "self": "/gdc/datawarehouse/instances/{instance-id}/users/{profile-id}", + "parent": "/gdc/datawarehouse/instances/{instance-id}/users" + } + } + }, + { + "user": { + "role": "dataAdmin", + "profile": "/gdc/account/profile/{profile-id-2}", + "links": { + "self": "/gdc/datawarehouse/instances/{instance-id}/users/{profile-id-2}", + "parent": "/gdc/datawarehouse/instances/{instance-id}/users" + } + } + } + ], + "paging": {}, + "links": { + "parent": "/gdc/datawarehouse/{instance-id}", + "self": "/gdc/datawarehouse/instances/{instance-id}/users" + } + } +} \ No newline at end of file