Issue 830: add resolveEntity

This commit is contained in:
Adrian Cole 2012-08-18 22:15:51 -07:00
parent 05e495fe08
commit 7fe724db43
21 changed files with 134 additions and 99 deletions

View File

@ -19,6 +19,8 @@
package org.jclouds.vcloud.director.v1_5.admin;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SkipEncoding;
import org.jclouds.vcloud.director.v1_5.features.admin.AdminCatalogAsyncApi;
import org.jclouds.vcloud.director.v1_5.features.admin.AdminNetworkAsyncApi;
import org.jclouds.vcloud.director.v1_5.features.admin.AdminOrgAsyncApi;
@ -26,6 +28,7 @@ import org.jclouds.vcloud.director.v1_5.features.admin.AdminQueryAsyncApi;
import org.jclouds.vcloud.director.v1_5.features.admin.AdminVdcAsyncApi;
import org.jclouds.vcloud.director.v1_5.features.admin.GroupAsyncApi;
import org.jclouds.vcloud.director.v1_5.features.admin.UserAsyncApi;
import org.jclouds.vcloud.director.v1_5.filters.AddVCloudAuthorizationAndCookieToRequest;
import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorAsyncApi;
/**
@ -34,6 +37,8 @@ import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorAsyncApi;
* @see VCloudDirectorAdminApi
* @author danikov
*/
@RequestFilters(AddVCloudAuthorizationAndCookieToRequest.class)
@SkipEncoding({ '-', ':' })
public interface VCloudDirectorAdminAsyncApi extends VCloudDirectorAsyncApi {
/**
* @return asynchronous access to admin query features

View File

@ -18,7 +18,6 @@
*/
package org.jclouds.vcloud.director.v1_5.domain.org;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Collections;
@ -30,7 +29,7 @@ import javax.xml.bind.annotation.XmlRootElement;
import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
import org.jclouds.vcloud.director.v1_5.domain.Reference;
import com.google.common.base.Objects;
import com.google.common.collect.ForwardingSet;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
@ -40,7 +39,7 @@ import com.google.common.collect.Sets;
* @author Adrian Cole
*/
@XmlRootElement(name = "OrgList")
public class OrgList {
public class OrgList extends ForwardingSet<Reference> {
public static final String MEDIA_TYPE = VCloudDirectorMediaType.ORG_LIST;
@ -77,7 +76,7 @@ public class OrgList {
}
public Builder fromOrgList(OrgList in) {
return orgs(in.getOrgs());
return orgs(in.delegate());
}
}
@ -92,27 +91,9 @@ public class OrgList {
@XmlElement(name = "Org")
private Set<Reference> orgs = Sets.newLinkedHashSet();
public Set<Reference> getOrgs() {
@Override
protected Set<Reference> delegate() {
return Collections.unmodifiableSet(orgs);
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
OrgList that = OrgList.class.cast(o);
return equal(orgs, that.orgs);
}
@Override
public int hashCode() {
return Objects.hashCode(orgs);
}
@Override
public String toString() {
return Objects.toStringHelper("").add("orgs", orgs).toString();
}
}

View File

@ -21,9 +21,10 @@ package org.jclouds.vcloud.director.v1_5.features;
import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.vcloud.director.v1_5.domain.Catalog;
import org.jclouds.vcloud.director.v1_5.domain.CatalogReference;
import org.jclouds.vcloud.director.v1_5.domain.Entity;
import org.jclouds.vcloud.director.v1_5.domain.Link;
import org.jclouds.vcloud.director.v1_5.domain.Media;
import org.jclouds.vcloud.director.v1_5.domain.VApp;
import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate;
import org.jclouds.vcloud.director.v1_5.domain.Vm;
@ -41,15 +42,6 @@ import org.jclouds.vcloud.director.v1_5.domain.query.VAppReferences;
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
public interface QueryApi {
/**
* Redirects to the URL of an entity with the given VCD ID.
*
* <pre>
* GET /entity/{id}
* </pre>
*/
Entity entity(String id);
// TODO Add a typed object for filter syntax, or at least a fluent builder
/**

View File

@ -21,16 +21,13 @@ package org.jclouds.vcloud.director.v1_5.features;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.JAXBResponseParser;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SkipEncoding;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.vcloud.director.v1_5.domain.Entity;
import org.jclouds.vcloud.director.v1_5.domain.Catalog;
import org.jclouds.vcloud.director.v1_5.domain.VApp;
import org.jclouds.vcloud.director.v1_5.domain.query.CatalogReferences;
import org.jclouds.vcloud.director.v1_5.domain.query.QueryList;
@ -48,16 +45,6 @@ import com.google.common.util.concurrent.ListenableFuture;
@SkipEncoding({ '=' })
public interface QueryAsyncApi {
/**
* @see QueryApi#entity(String)
*/
@GET
@Path("/entity/{id}")
@Consumes
@JAXBResponseParser
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Entity> entity(@PathParam("id") String id);
/**
* REST API General queries handler.
*/

View File

@ -62,7 +62,7 @@ public class OrgsForNames implements Function<Iterable<String>, Iterable<? exten
@Override
public Iterable<? extends Org> apply(Iterable<String> from) {
final Set<Reference> orgs = sapi.getOrgApi().getOrgList().getOrgs();
final Set<Reference> orgs = sapi.getOrgApi().getOrgList();
return transformParallel(from, new Function<String, Future<? extends Org>>() {

View File

@ -22,6 +22,7 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.vcloud.director.v1_5.domain.Entity;
import org.jclouds.vcloud.director.v1_5.domain.Session;
import org.jclouds.vcloud.director.v1_5.features.CatalogApi;
import org.jclouds.vcloud.director.v1_5.features.MediaApi;
@ -40,11 +41,21 @@ import com.google.inject.Provides;
/**
* Provides synchronous access to VCloudDirector.
*
* @see VCloudDirectorAdminAsyncApi
* @see VCloudDirectorAsyncApi
* @author danikov
*/
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface VCloudDirectorApi {
/**
* Redirects to the URL of an entity with the given VCD ID.
*
* <pre>
* GET /entity/{id}
* </pre>
*/
Entity resolveEntity(String id);
/**
* @return the current login session
*/

View File

@ -18,8 +18,28 @@
*/
package org.jclouds.vcloud.director.v1_5.user;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.JAXBResponseParser;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SkipEncoding;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.vcloud.director.v1_5.domain.Catalog;
import org.jclouds.vcloud.director.v1_5.domain.Entity;
import org.jclouds.vcloud.director.v1_5.domain.Media;
import org.jclouds.vcloud.director.v1_5.domain.Session;
import org.jclouds.vcloud.director.v1_5.domain.Task;
import org.jclouds.vcloud.director.v1_5.domain.VApp;
import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate;
import org.jclouds.vcloud.director.v1_5.domain.Vdc;
import org.jclouds.vcloud.director.v1_5.domain.Vm;
import org.jclouds.vcloud.director.v1_5.domain.network.Network;
import org.jclouds.vcloud.director.v1_5.domain.org.Org;
import org.jclouds.vcloud.director.v1_5.features.CatalogAsyncApi;
import org.jclouds.vcloud.director.v1_5.features.NetworkAsyncApi;
import org.jclouds.vcloud.director.v1_5.features.OrgAsyncApi;
@ -30,7 +50,9 @@ import org.jclouds.vcloud.director.v1_5.features.VAppAsyncApi;
import org.jclouds.vcloud.director.v1_5.features.VAppTemplateAsyncApi;
import org.jclouds.vcloud.director.v1_5.features.VdcAsyncApi;
import org.jclouds.vcloud.director.v1_5.features.VmAsyncApi;
import org.jclouds.vcloud.director.v1_5.filters.AddVCloudAuthorizationAndCookieToRequest;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.Provides;
/**
@ -39,7 +61,20 @@ import com.google.inject.Provides;
* @see VCloudDirectorApi
* @author Adrian Cole
*/
@RequestFilters(AddVCloudAuthorizationAndCookieToRequest.class)
@SkipEncoding({ '-', ':' })
public interface VCloudDirectorAsyncApi {
/**
* @see VCloudDirectorApi#resolveEntity(String)
*/
@GET
@Path("/entity/{id}")
@Consumes
@JAXBResponseParser
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Entity> resolveEntity(@PathParam("id") String id);
/**
*
* @return the current login session
@ -58,31 +93,31 @@ public interface VCloudDirectorAsyncApi {
*/
@Delegate
OrgAsyncApi getOrgApi();
/**
* @return asynchronous access to {@link Task} features
*/
@Delegate
TaskAsyncApi getTaskApi();
/**
* @return asynchronous access to {@link Network} features
*/
@Delegate
NetworkAsyncApi getNetworkApi();
/**
* @return asynchronous access to {@link Catalog} features
*/
@Delegate
CatalogAsyncApi getCatalogApi();
/**
* @return asynchronous access to {@link Media} features
*/
@Delegate
CatalogAsyncApi getMediaApi();
/**
* @return asynchronous access to {@link Vdc} features
*/
@ -94,7 +129,7 @@ public interface VCloudDirectorAsyncApi {
*/
@Delegate
UploadAsyncApi getUploadApi();
/**
* @return asynchronous access to {@link VApp} features
*/

View File

@ -85,9 +85,9 @@ public class HttpClientLiveTest extends BaseVCloudDirectorApiLiveTest {
OrgList orgList = parser.fromXML(Strings2.toString(response.getPayload()), OrgList.class);
assertTrue(orgList.getOrgs().size() > 0, "must have orgs");
assertTrue(orgList.size() > 0, "must have orgs");
context.getApi().getOrgApi().getOrg(Iterables.getLast(orgList.getOrgs()).getHref());
context.getApi().getOrgApi().getOrg(Iterables.getLast(orgList).getHref());
}
@Test(description = "GET /schema/{schemaFileName}", dependsOnMethods = { "testPostLogin", "testGetLogin" })

View File

@ -0,0 +1,52 @@
/*
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.vcloud.director.v1_5;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkEntityType;
import org.jclouds.vcloud.director.v1_5.domain.Entity;
import org.jclouds.vcloud.director.v1_5.domain.Reference;
import org.jclouds.vcloud.director.v1_5.domain.org.Org;
import org.jclouds.vcloud.director.v1_5.internal.BaseVCloudDirectorApiLiveTest;
import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorApi;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Tests live behavior of {@link VCloudDirectorApi}.
*
* @author Adrian Cole
*/
@Test(groups = { "live", "user" }, singleThreaded = true, testName = "VCloudDirectorApiLiveTest")
public class VCloudDirectorApiLiveTest extends BaseVCloudDirectorApiLiveTest {
@Test(description = "GET /entity/{id}")
public void testResolveEntity() {
for (Reference orgRef : context.getApi().getOrgApi().getOrgList()) {
Org org = context.getApi().getOrgApi().getOrg(orgRef.getHref());
Entity entity = context.getApi().resolveEntity(org.getId());
checkEntityType(entity);
}
}
@Override
@BeforeClass(alwaysRun = true)
public void setupRequiredApis() {
}
}

View File

@ -83,7 +83,7 @@ public class CatalogApiLiveTest extends BaseVCloudDirectorApiLiveTest {
// TODO why do I need a guard clause here?
if (adminCatalog != null) return;
catalogApi = context.getApi().getCatalogApi();
Reference orgRef = Iterables.getFirst(context.getApi().getOrgApi().getOrgList().getOrgs(), null).toAdminReference(endpoint);
Reference orgRef = Iterables.getFirst(context.getApi().getOrgApi().getOrgList(), null).toAdminReference(endpoint);
if (adminContext != null) {
AdminCatalog newCatalog = AdminCatalog.builder()

View File

@ -72,7 +72,7 @@ public class OrgApiExpectTest extends VCloudDirectorAdminApiExpectTest {
getStandardRequest("GET", "/org/"),
getStandardPayloadResponse("/org/orglist.xml", VCloudDirectorMediaType.ORG_LIST));
Reference org = Iterables.getOnlyElement(api.getOrgApi().getOrgList().getOrgs());
Reference org = Iterables.getOnlyElement(api.getOrgApi().getOrgList());
api = requestsSendResponses(loginRequest, sessionResponse,
getStandardRequest("GET", org.getHref()),

View File

@ -105,9 +105,9 @@ public class OrgApiLiveTest extends BaseVCloudDirectorApiLiveTest {
// NOTE The environment MUST have at least one organisation configured
// Check test requirements
assertFalse(Iterables.isEmpty(orgList.getOrgs()), String.format(NOT_EMPTY_OBJECT_FMT, "Org", "OrgList"));
assertFalse(Iterables.isEmpty(orgList), String.format(NOT_EMPTY_OBJECT_FMT, "Org", "OrgList"));
for (Reference orgRef : orgList.getOrgs()) {
for (Reference orgRef : orgList) {
assertEquals(orgRef.getType(), VCloudDirectorMediaType.ORG, String.format(CONDITION_FMT, "Reference.Type", VCloudDirectorMediaType.ORG, orgRef.getType()));
checkReferenceType(orgRef);
}
@ -115,7 +115,7 @@ public class OrgApiLiveTest extends BaseVCloudDirectorApiLiveTest {
@Test(description = "GET /org/{id}", dependsOnMethods = { "testGetOrgList" })
public void testGetOrg() {
Reference orgRef = Iterables.getFirst(orgList.getOrgs(), null);
Reference orgRef = Iterables.getFirst(orgList, null);
assertNotNull(orgRef);
orgURI = orgRef.getHref();

View File

@ -18,9 +18,7 @@
*/
package org.jclouds.vcloud.director.v1_5.features;
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.ENTITY_EQUAL;
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.NOT_EMPTY_OBJECT_FMT;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkEntityType;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
@ -34,8 +32,6 @@ import java.util.List;
import java.util.Set;
import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
import org.jclouds.vcloud.director.v1_5.domain.Entity;
import org.jclouds.vcloud.director.v1_5.domain.Link;
import org.jclouds.vcloud.director.v1_5.domain.Resource;
import org.jclouds.vcloud.director.v1_5.domain.Task;
import org.jclouds.vcloud.director.v1_5.domain.VApp;
@ -49,7 +45,6 @@ import org.jclouds.vcloud.director.v1_5.domain.query.QueryResultVAppRecord;
import org.jclouds.vcloud.director.v1_5.domain.query.QueryResultVAppTemplateRecord;
import org.jclouds.vcloud.director.v1_5.domain.query.QueryResultVMRecord;
import org.jclouds.vcloud.director.v1_5.internal.BaseVCloudDirectorApiLiveTest;
import org.jclouds.vcloud.director.v1_5.predicates.ReferencePredicates;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@ -87,24 +82,6 @@ public class QueryApiLiveTest extends BaseVCloudDirectorApiLiveTest {
vAppApi = context.getApi().getVAppApi();
}
@Test(description = "GET /entity/{id}")
public void testEntity() {
// Get a VAppTemplate to look up as an entity
VAppTemplate vAppTemplate = vAppTemplateApi.getVAppTemplate(vAppTemplateURI);
// Method under test
Entity entity = queryApi.entity(vAppTemplate.getId());
// Check returned entity
checkEntityType(entity);
// Retrieve and check template using entity link
Link link = Iterables.find(entity.getLinks(), ReferencePredicates.<Link>typeEquals(VCloudDirectorMediaType.VAPP_TEMPLATE));
VAppTemplate retrieved = vAppTemplateApi.getVAppTemplate(link.getHref());
assertEquals(retrieved, vAppTemplate, String.format(ENTITY_EQUAL, "VAppTemplate"));
}
@Test(description = "GET /query")
public void testQuery() {
VAppTemplate vAppTemplate = vAppTemplateApi.getVAppTemplate(vAppTemplateURI);

View File

@ -80,7 +80,7 @@ public class TaskApiLiveTest extends BaseVCloudDirectorApiLiveTest {
@Test(description = "GET /tasksList/{id}")
public void testGetTaskList() {
orgList = orgApi.getOrgList();
Reference orgRef = Iterables.getFirst(orgList.getOrgs(), null);
Reference orgRef = Iterables.getFirst(orgList, null);
assertNotNull(orgRef);
orgURI = orgRef.getHref();

View File

@ -101,7 +101,6 @@ import org.testng.annotations.Test;
import com.google.common.base.CharMatcher;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;

View File

@ -24,8 +24,6 @@ import static org.testng.Assert.fail;
import java.net.URI;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import org.jclouds.vcloud.director.v1_5.VCloudDirectorException;
import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
@ -35,17 +33,15 @@ import org.jclouds.vcloud.director.v1_5.domain.ComputeCapacity;
import org.jclouds.vcloud.director.v1_5.domain.Error;
import org.jclouds.vcloud.director.v1_5.domain.Link;
import org.jclouds.vcloud.director.v1_5.domain.Media;
import org.jclouds.vcloud.director.v1_5.domain.Owner;
import org.jclouds.vcloud.director.v1_5.domain.Task;
import org.jclouds.vcloud.director.v1_5.domain.User;
import org.jclouds.vcloud.director.v1_5.domain.Media.ImageType;
import org.jclouds.vcloud.director.v1_5.domain.Metadata;
import org.jclouds.vcloud.director.v1_5.domain.MetadataValue;
import org.jclouds.vcloud.director.v1_5.domain.Owner;
import org.jclouds.vcloud.director.v1_5.domain.Reference;
import org.jclouds.vcloud.director.v1_5.domain.User;
import org.jclouds.vcloud.director.v1_5.domain.VApp;
import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate;
import org.jclouds.vcloud.director.v1_5.domain.Vdc;
import org.jclouds.vcloud.director.v1_5.domain.org.Org;
import org.jclouds.vcloud.director.v1_5.domain.params.CaptureVAppParams;
import org.jclouds.vcloud.director.v1_5.domain.params.CloneMediaParams;
import org.jclouds.vcloud.director.v1_5.domain.params.CloneVAppParams;

View File

@ -71,7 +71,7 @@ public class AdminCatalogApiLiveTest extends BaseVCloudDirectorApiLiveTest {
@BeforeClass(alwaysRun = true)
protected void setupRequiredApis() {
catalogApi = adminContext.getApi().getCatalogApi();
orgRef = Iterables.getFirst(context.getApi().getOrgApi().getOrgList().getOrgs(), null).toAdminReference(endpoint);
orgRef = Iterables.getFirst(context.getApi().getOrgApi().getOrgList(), null).toAdminReference(endpoint);
}
@AfterClass(alwaysRun = true)

View File

@ -73,7 +73,7 @@ public class AdminOrgApiLiveTest extends BaseVCloudDirectorApiLiveTest {
@BeforeClass(alwaysRun = true)
public void setupRequiredApis() {
orgApi = adminContext.getApi().getOrgApi();
orgRef = Iterables.getFirst(orgApi.getOrgList().getOrgs(), null).toAdminReference(endpoint);
orgRef = Iterables.getFirst(orgApi.getOrgList(), null).toAdminReference(endpoint);
assertNotNull(orgRef, String.format(REF_REQ_LIVE, "admin org"));
}

View File

@ -68,7 +68,7 @@ public class UserApiLiveTest extends BaseVCloudDirectorApiLiveTest {
@BeforeClass(alwaysRun = true)
public void setupRequiredApis() {
userApi = adminContext.getApi().getUserApi();
orgRef = Iterables.getFirst(context.getApi().getOrgApi().getOrgList().getOrgs(), null).toAdminReference(endpoint);
orgRef = Iterables.getFirst(context.getApi().getOrgApi().getOrgList(), null).toAdminReference(endpoint);
}
@AfterClass(alwaysRun = true)

View File

@ -262,7 +262,7 @@ public abstract class BaseVCloudDirectorApiLiveTest extends BaseContextLiveTest<
if (Iterables.any(Lists.newArrayList(vAppTemplateURI, networkURI, vdcURI), Predicates.isNull())) {
Org thisOrg = context.getApi().getOrgApi().getOrg(
Iterables.find(context.getApi().getOrgApi().getOrgList().getOrgs(),
Iterables.find(context.getApi().getOrgApi().getOrgList(),
ReferencePredicates.<Reference> nameEquals(session.getOrg())).getHref());
if (vdcURI == null)

View File

@ -92,7 +92,7 @@ public class VCloudDirectorTestSession implements Closeable {
adminContext = userContext.getAdminContext();
// Lookup the user details
Reference orgRef = Iterables.getFirst(userContext.getApi().getOrgApi().getOrgList().getOrgs(), null)
Reference orgRef = Iterables.getFirst(userContext.getApi().getOrgApi().getOrgList(), null)
.toAdminReference(endpoint);
Reference userRef = Iterables.find(
adminContext.getApi().getOrgApi().getOrg(orgRef.getHref()).getUsers(),