Updated Branches: refs/heads/master 981db3465 -> 8b94ee589
JCLOUDS-218. List templates in all known projects for CloudStack. Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/8b94ee58 Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/8b94ee58 Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/8b94ee58 Branch: refs/heads/master Commit: 8b94ee589bb9a5a6df3823569a55775f66cef502 Parents: 981db34 Author: Andrew Bayer <[email protected]> Authored: Mon Nov 25 16:43:46 2013 -0800 Committer: Andrew Bayer <[email protected]> Committed: Tue Nov 26 10:00:09 2013 -0800 ---------------------------------------------------------------------- .../org/jclouds/cloudstack/CloudStackApi.java | 7 + .../CloudStackComputeServiceContextModule.java | 11 + .../CloudStackComputeServiceAdapter.java | 25 +- .../org/jclouds/cloudstack/domain/Project.java | 243 +++++++++++++++++++ .../jclouds/cloudstack/features/ProjectApi.java | 77 ++++++ .../cloudstack/options/ListProjectsOptions.java | 171 +++++++++++++ .../suppliers/ProjectsForCurrentUser.java | 64 +++++ ...oudStackComputeServiceAdapterExpectTest.java | 149 ++++++------ .../features/ProjectApiExpectTest.java | 79 ++++++ .../cloudstack/features/ProjectApiLiveTest.java | 48 ++++ .../cloudstack/features/ProjectApiTest.java | 98 ++++++++ ...oudStackComputeServiceContextExpectTest.java | 17 +- .../test/resources/listprojectsresponse.json | 1 + 13 files changed, 911 insertions(+), 79 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds/blob/8b94ee58/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackApi.java ---------------------------------------------------------------------- diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackApi.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackApi.java index 9959421..b9a2ca8 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackApi.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackApi.java @@ -32,6 +32,7 @@ import org.jclouds.cloudstack.features.LoadBalancerApi; import org.jclouds.cloudstack.features.NATApi; import org.jclouds.cloudstack.features.NetworkApi; import org.jclouds.cloudstack.features.OfferingApi; +import org.jclouds.cloudstack.features.ProjectApi; import org.jclouds.cloudstack.features.SSHKeyPairApi; import org.jclouds.cloudstack.features.SecurityGroupApi; import org.jclouds.cloudstack.features.SessionApi; @@ -189,4 +190,10 @@ public interface CloudStackApi extends Closeable { */ @Delegate SessionApi getSessionApi(); + + /** + * Provides synchronous access to Projects + */ + @Delegate + ProjectApi getProjectApi(); } http://git-wip-us.apache.org/repos/asf/jclouds/blob/8b94ee58/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java ---------------------------------------------------------------------- diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java index 9ed08de..b06b396 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java @@ -53,6 +53,7 @@ import org.jclouds.cloudstack.domain.IngressRule; import org.jclouds.cloudstack.domain.Network; import org.jclouds.cloudstack.domain.NetworkType; import org.jclouds.cloudstack.domain.OSType; +import org.jclouds.cloudstack.domain.Project; import org.jclouds.cloudstack.domain.SecurityGroup; import org.jclouds.cloudstack.domain.ServiceOffering; import org.jclouds.cloudstack.domain.SshKeyPair; @@ -71,6 +72,7 @@ import org.jclouds.cloudstack.functions.ZoneIdToZone; import org.jclouds.cloudstack.predicates.JobComplete; import org.jclouds.cloudstack.suppliers.GetCurrentUser; import org.jclouds.cloudstack.suppliers.NetworksForCurrentUser; +import org.jclouds.cloudstack.suppliers.ProjectsForCurrentUser; import org.jclouds.cloudstack.suppliers.ZoneIdToZoneSupplier; import org.jclouds.collect.Memoized; import org.jclouds.compute.ComputeServiceAdapter; @@ -223,6 +225,15 @@ public class CloudStackComputeServiceContextModule extends @Provides @Singleton @Memoized + public Supplier<Map<String, Project>> listProjects(AtomicReference<AuthorizationException> authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, + final ProjectsForCurrentUser projectsForCurrentUser) { + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, projectsForCurrentUser, + seconds, TimeUnit.SECONDS); + } + + @Provides + @Singleton + @Memoized public Supplier<User> getCurrentUser(AtomicReference<AuthorizationException> authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, final GetCurrentUser getCurrentUser) { return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, getCurrentUser, http://git-wip-us.apache.org/repos/asf/jclouds/blob/8b94ee58/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java ---------------------------------------------------------------------- diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java index a04b9fe..6961ab7 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java @@ -19,9 +19,11 @@ package org.jclouds.cloudstack.compute.strategy; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; +import static com.google.common.collect.Iterables.concat; import static com.google.common.collect.Iterables.contains; import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.get; +import static com.google.common.collect.Iterables.transform; import static org.jclouds.cloudstack.options.DeployVirtualMachineOptions.Builder.displayName; import static org.jclouds.cloudstack.options.ListTemplatesOptions.Builder.id; import static org.jclouds.cloudstack.predicates.TemplatePredicates.isReady; @@ -31,7 +33,6 @@ import static org.jclouds.ssh.SshKeys.fingerprintPrivateKey; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.ExecutionException; import javax.annotation.Resource; import javax.inject.Inject; @@ -46,6 +47,7 @@ import org.jclouds.cloudstack.domain.FirewallRule; import org.jclouds.cloudstack.domain.IPForwardingRule; import org.jclouds.cloudstack.domain.Network; import org.jclouds.cloudstack.domain.NetworkType; +import org.jclouds.cloudstack.domain.Project; import org.jclouds.cloudstack.domain.PublicIPAddress; import org.jclouds.cloudstack.domain.SecurityGroup; import org.jclouds.cloudstack.domain.ServiceOffering; @@ -55,12 +57,14 @@ import org.jclouds.cloudstack.domain.VirtualMachine; import org.jclouds.cloudstack.domain.Zone; import org.jclouds.cloudstack.domain.ZoneAndName; import org.jclouds.cloudstack.domain.ZoneSecurityGroupNamePortsCidrs; +import org.jclouds.cloudstack.features.TemplateApi; import org.jclouds.cloudstack.functions.CreateFirewallRulesForIP; import org.jclouds.cloudstack.functions.CreatePortForwardingRulesForIP; import org.jclouds.cloudstack.functions.StaticNATVirtualMachineInNetwork; import org.jclouds.cloudstack.functions.StaticNATVirtualMachineInNetwork.Factory; import org.jclouds.cloudstack.options.DeployVirtualMachineOptions; import org.jclouds.cloudstack.options.ListFirewallRulesOptions; +import org.jclouds.cloudstack.options.ListTemplatesOptions; import org.jclouds.cloudstack.strategy.BlockUntilJobCompletesAndReturnResult; import org.jclouds.collect.Memoized; import org.jclouds.compute.ComputeServiceAdapter; @@ -70,14 +74,13 @@ import org.jclouds.domain.Credentials; import org.jclouds.domain.LoginCredentials; import org.jclouds.logging.Logger; +import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Supplier; -import com.google.common.base.Throwables; import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.common.collect.Sets; import com.google.common.collect.ImmutableSet.Builder; +import com.google.common.collect.Sets; import com.google.common.primitives.Ints; /** @@ -95,6 +98,7 @@ public class CloudStackComputeServiceAdapter implements private final CloudStackApi client; private final Predicate<String> jobComplete; private final Supplier<Map<String, Network>> networkSupplier; + private final Supplier<Map<String, Project>> projectSupplier; private final BlockUntilJobCompletesAndReturnResult blockUntilJobCompletesAndReturnResult; private final Factory staticNATVMInNetwork; private final CreatePortForwardingRulesForIP setupPortForwardingRulesForIP; @@ -110,6 +114,7 @@ public class CloudStackComputeServiceAdapter implements @Inject public CloudStackComputeServiceAdapter(CloudStackApi client, Predicate<String> jobComplete, @Memoized Supplier<Map<String, Network>> networkSupplier, + @Memoized Supplier<Map<String, Project>> projectSupplier, BlockUntilJobCompletesAndReturnResult blockUntilJobCompletesAndReturnResult, StaticNATVirtualMachineInNetwork.Factory staticNATVMInNetwork, CreatePortForwardingRulesForIP setupPortForwardingRulesForIP, @@ -124,6 +129,7 @@ public class CloudStackComputeServiceAdapter implements this.client = checkNotNull(client, "client"); this.jobComplete = checkNotNull(jobComplete, "jobComplete"); this.networkSupplier = checkNotNull(networkSupplier, "networkSupplier"); + this.projectSupplier = checkNotNull(projectSupplier, "projectSupplier"); this.blockUntilJobCompletesAndReturnResult = checkNotNull(blockUntilJobCompletesAndReturnResult, "blockUntilJobCompletesAndReturnResult"); this.staticNATVMInNetwork = checkNotNull(staticNATVMInNetwork, "staticNATVMInNetwork"); @@ -270,9 +276,14 @@ public class CloudStackComputeServiceAdapter implements @Override public Iterable<Template> listImages() { - // TODO: we may need to filter these further - // we may also want to see if we can work with ssh keys - return filter(client.getTemplateApi().listTemplates(), isReady()); + TemplateApi templateApi = client.getTemplateApi(); + ImmutableSet.Builder<Template> templates = ImmutableSet.builder(); + templates.addAll(templateApi.listTemplates()); + for (String project : projectSupplier.get().keySet()) { + templates.addAll(templateApi.listTemplates(ListTemplatesOptions.Builder.projectId(project))); + } + + return filter(templates.build(), isReady()); } @Override http://git-wip-us.apache.org/repos/asf/jclouds/blob/8b94ee58/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/Project.java ---------------------------------------------------------------------- diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/Project.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/Project.java new file mode 100644 index 0000000..a58a6f0 --- /dev/null +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/Project.java @@ -0,0 +1,243 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.cloudstack.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.beans.ConstructorProperties; + +import org.jclouds.javax.annotation.Nullable; + +import com.google.common.base.CaseFormat; +import com.google.common.base.Objects; +import com.google.common.base.Objects.ToStringHelper; + +/** + * Representation of the API project response + * + * @author Andrew Bayer + */ +public class Project implements Comparable<Project> { + + public static enum State { + ACTIVE, DISABLED, SUSPENDED, UNRECOGNIZED; + + @Override + public String toString() { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name()); + } + + public static State fromValue(String state) { + try { + return valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(state, "state"))); + } catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } + + } + + public static Builder<?> builder() { + return new ConcreteBuilder(); + } + + public Builder<?> toBuilder() { + return new ConcreteBuilder().fromDomain(this); + } + + public abstract static class Builder<T extends Builder<T>> { + protected abstract T self(); + + protected String id; + protected String account; + protected String displayText; + protected String domain; + protected String domainId; + protected String name; + protected State state; + + /** + * @see org.jclouds.cloudstack.domain.Project#getId() + */ + public T id(String id) { + this.id = id; + return self(); + } + + /** + * @see org.jclouds.cloudstack.domain.Project#getName() + */ + public T name(String name) { + this.name = name; + return self(); + } + + /** + * @see org.jclouds.cloudstack.domain.Project#getDomainId() + */ + public T domainId(String domainId) { + this.domainId = domainId; + return self(); + } + + /** + * @see org.jclouds.cloudstack.domain.Project#getDomain() + */ + public T domain(String domain) { + this.domain = domain; + return self(); + } + + /** + * @see org.jclouds.cloudstack.domain.Project#getAccount() + */ + public T account(String account) { + this.account = account; + return self(); + } + + /** + * @see org.jclouds.cloudstack.domain.Project#getDisplayText() + */ + public T displayText(String displayText) { + this.displayText = displayText; + return self(); + } + + /** + * @see org.jclouds.cloudstack.domain.Project#getState() + */ + public T state(State state) { + this.state = state; + return self(); + } + + + public Project build() { + return new Project(id, account, displayText, domain, domainId, name, state); + } + + public T fromDomain(Project in) { + return this + .id(in.getId()) + .account(in.getAccount()) + .displayText(in.getDisplayText()) + .domain(in.getDomain()) + .domainId(in.getDomainId()) + .name(in.getName()) + .state(in.getState()); + } + } + + private static class ConcreteBuilder extends Builder<ConcreteBuilder> { + @Override + protected ConcreteBuilder self() { + return this; + } + } + + private final String id; + private final String account; + private final String displayText; + private final String domain; + private final String domainId; + private final String name; + private final State state; + + @ConstructorProperties({ + "id", "account", "displaytext", "domain", "domainid", "name", "state" + }) + protected Project(String id, String account, String displayText, String domain, String domainId, + String name, State state) { + this.id = checkNotNull(id, "id"); + this.account = account; + this.displayText = displayText; + this.domain = domain; + this.domainId = domainId; + this.name = name; + this.state = checkNotNull(state, "state"); + } + + public String getId() { + return this.id; + } + + @Nullable + public String getAccount() { + return this.account; + } + + @Nullable + public String getDisplayText() { + return this.displayText; + } + + @Nullable + public String getDomain() { + return this.domain; + } + + @Nullable + public String getDomainId() { + return this.domainId; + } + + @Nullable + public String getName() { + return this.name; + } + + public State getState() { + return this.state; + } + + @Override + public int hashCode() { + return Objects.hashCode(id, account, displayText, domain, domainId, name, state); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + Project that = Project.class.cast(obj); + return Objects.equal(this.id, that.id) + && Objects.equal(this.account, that.account) + && Objects.equal(this.displayText, that.displayText) + && Objects.equal(this.domain, that.domain) + && Objects.equal(this.domainId, that.domainId) + && Objects.equal(this.name, that.name) + && Objects.equal(this.state, that.state); + } + + protected ToStringHelper string() { + return Objects.toStringHelper(this).omitNullValues() + .add("id", id).add("account", account).add("displayText", displayText) + .add("domain", domain).add("domainId", domainId).add("name", name).add("state", state); + } + + @Override + public String toString() { + return string().toString(); + } + + @Override + public int compareTo(Project other) { + return id.compareTo(other.getId()); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/8b94ee58/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/ProjectApi.java ---------------------------------------------------------------------- diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/ProjectApi.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/ProjectApi.java new file mode 100644 index 0000000..dbe7fa9 --- /dev/null +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/ProjectApi.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.cloudstack.features; + +import java.util.Set; + +import javax.inject.Named; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404; +import org.jclouds.Fallbacks.NullOnNotFoundOr404; +import org.jclouds.cloudstack.domain.Project; +import org.jclouds.cloudstack.filters.AuthenticationFilter; +import org.jclouds.cloudstack.options.ListProjectsOptions; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.OnlyElement; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.SelectJson; + +/** + * Provides synchronous access to CloudStack project features. + * + * @author Andrew Bayer + * @see <a + * href="http://download.cloud.com/releases/3.0.6/api_3.0.6/TOC_Root_Admin.html" + * /> + */ +@RequestFilters(AuthenticationFilter.class) +@QueryParams(keys = "response", values = "json") +public interface ProjectApi { + /** + * Lists the projects this account has access to. + * + * @param options if present, how to constrain the list + */ + @Named("listProjects") + @GET + @QueryParams(keys = { "command", "listAll" }, values = { "listProjects", "true" }) + @SelectJson("project") + @Consumes(MediaType.APPLICATION_JSON) + @Fallback(EmptySetOnNotFoundOr404.class) + Set<Project> listProjects(ListProjectsOptions... options); + + /** + * gets a specific Project by id + * + * @param id + * Project to get + * @return Project or null if not found */ + @Named("listProjects") + @GET + @QueryParams(keys = { "command", "listAll" }, values = { "listProjects", "true" }) + @SelectJson("project") + @OnlyElement + @Consumes(MediaType.APPLICATION_JSON) + @Fallback(NullOnNotFoundOr404.class) + Project getProject(@QueryParam("id") String id); + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/8b94ee58/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListProjectsOptions.java ---------------------------------------------------------------------- diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListProjectsOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListProjectsOptions.java new file mode 100644 index 0000000..db67ed5 --- /dev/null +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListProjectsOptions.java @@ -0,0 +1,171 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.cloudstack.options; + +import com.google.common.collect.ImmutableSet; + +/** + * Options used to control what account information is returned + * + * @see <a + * href="http://download.cloud.com/releases/3.0.6/api_3.0.6/root_admin/listProjects.html" + * /> + * @author Andrew Bayer + */ +public class ListProjectsOptions extends AccountInDomainOptions { + + public static final ListProjectsOptions NONE = new ListProjectsOptions(); + + /** + * @param id + * list projects by project ID + */ + public ListProjectsOptions id(String id) { + this.queryParameters.replaceValues("id", ImmutableSet.of(id)); + return this; + } + + /** + * @param name + * list project by project name + */ + public ListProjectsOptions name(String name) { + this.queryParameters.replaceValues("name", ImmutableSet.of(name)); + return this; + } + + /** + * @param state + * list projects by state. Valid states are enabled, disabled, and + * locked. + */ + public ListProjectsOptions state(String state) { + this.queryParameters.replaceValues("state", ImmutableSet.of(state)); + return this; + } + + /** + * @param displayText + * list projects by displayText. + */ + public ListProjectsOptions displayText(String displayText) { + this.queryParameters.replaceValues("displaytext", ImmutableSet.of(displayText)); + return this; + } + + /** + * @param keyword + * list projects by keyword. + */ + public ListProjectsOptions keyword(String keyword) { + this.queryParameters.replaceValues("keyword", ImmutableSet.of(keyword)); + return this; + } + + /** + * @param recursive + * defaults to false, but if true, lists all projects from the + * parent specified by the domain id till leaves. + */ + public ListProjectsOptions recursive(boolean recursive) { + this.queryParameters.replaceValues("isrecursive", ImmutableSet.of(recursive + "")); + return this; + } + + public static class Builder { + + /** + * @see org.jclouds.cloudstack.options.ListProjectsOptions#accountInDomain(String, String) + */ + public static ListProjectsOptions accountInDomain(String project, String domain) { + ListProjectsOptions options = new ListProjectsOptions(); + return options.accountInDomain(project, domain); + } + + /** + * @see org.jclouds.cloudstack.options.ListProjectsOptions#domainId + */ + public static ListProjectsOptions domainId(String domainId) { + ListProjectsOptions options = new ListProjectsOptions(); + return options.domainId(domainId); + } + + /** + * @see org.jclouds.cloudstack.options.ListProjectsOptions#id + */ + public static ListProjectsOptions id(String id) { + ListProjectsOptions options = new ListProjectsOptions(); + return options.id(id); + } + + /** + * @see org.jclouds.cloudstack.options.ListProjectsOptions#name + */ + public static ListProjectsOptions name(String name) { + ListProjectsOptions options = new ListProjectsOptions(); + return options.name(name); + } + + /** + * @see org.jclouds.cloudstack.options.ListProjectsOptions#state + */ + public static ListProjectsOptions state(String state) { + ListProjectsOptions options = new ListProjectsOptions(); + return options.state(state); + } + + /** + * @see org.jclouds.cloudstack.options.ListProjectsOptions#displayText(String) + */ + public static ListProjectsOptions displayText(String displayText) { + ListProjectsOptions options = new ListProjectsOptions(); + return options.displayText(displayText); + } + + /** + * @see org.jclouds.cloudstack.options.ListProjectsOptions#keyword(String) + */ + public static ListProjectsOptions keyword(String keyword) { + ListProjectsOptions options = new ListProjectsOptions(); + return options.keyword(keyword); + } + + /** + * @see org.jclouds.cloudstack.options.ListProjectsOptions#recursive + */ + public static ListProjectsOptions recursive(boolean recursive) { + ListProjectsOptions options = new ListProjectsOptions(); + return options.recursive(recursive); + } + } + + /** + * {@inheritDoc} + */ + @Override + public ListProjectsOptions accountInDomain(String account, String domain) { + return ListProjectsOptions.class.cast(super.accountInDomain(account, domain)); + } + + /** + * {@inheritDoc} + */ + @Override + public ListProjectsOptions domainId(String domainId) { + return ListProjectsOptions.class.cast(super.domainId(domainId)); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/8b94ee58/apis/cloudstack/src/main/java/org/jclouds/cloudstack/suppliers/ProjectsForCurrentUser.java ---------------------------------------------------------------------- diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/suppliers/ProjectsForCurrentUser.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/suppliers/ProjectsForCurrentUser.java new file mode 100644 index 0000000..9422276 --- /dev/null +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/suppliers/ProjectsForCurrentUser.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.cloudstack.suppliers; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.cloudstack.options.ListProjectsOptions.Builder.accountInDomain; + +import java.util.Map; + +import javax.inject.Inject; + +import org.jclouds.cloudstack.CloudStackApi; +import org.jclouds.cloudstack.domain.Project; +import org.jclouds.cloudstack.domain.User; +import org.jclouds.cloudstack.features.ProjectApi; +import org.jclouds.collect.Memoized; + +import com.google.common.base.Function; +import com.google.common.base.Supplier; +import com.google.common.collect.Maps; + +/** + * + * @author Andrew Bayer + */ +public class ProjectsForCurrentUser implements Supplier<Map<String, Project>> { + private final CloudStackApi api; + private final Supplier<User> currentUserSupplier; + + @Inject + public ProjectsForCurrentUser(CloudStackApi api, @Memoized Supplier<User> currentUserSupplier) { + this.api = checkNotNull(api, "api"); + this.currentUserSupplier = checkNotNull(currentUserSupplier, "currentUserSupplier"); + } + + @Override + public Map<String, Project> get() { + User currentUser = currentUserSupplier.get(); + ProjectApi projectApi = api.getProjectApi(); + return Maps.uniqueIndex( + projectApi.listProjects(accountInDomain(currentUser.getAccount(), currentUser.getDomainId())), + new Function<Project, String>() { + + @Override + public String apply(Project arg0) { + return arg0.getId(); + } + }); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/8b94ee58/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackComputeServiceAdapterExpectTest.java ---------------------------------------------------------------------- diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackComputeServiceAdapterExpectTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackComputeServiceAdapterExpectTest.java index be888cc..112c7bd 100644 --- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackComputeServiceAdapterExpectTest.java +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackComputeServiceAdapterExpectTest.java @@ -110,17 +110,18 @@ public class CloudStackComputeServiceAdapterExpectTest extends BaseCloudStackCom .build(); Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder() - .put(listTemplates, listTemplatesResponse) - .put(listOsTypes, listOsTypesResponse) - .put(listOsCategories, listOsCategoriesResponse) - .put(listZones, listZonesResponse) - .put(listServiceOfferings, listServiceOfferingsResponse) - .put(listAccounts, listAccountsResponse) - .put(listNetworks, listNetworksResponse) - .put(getZone, getZoneResponse) - .put(deployVM, deployVMResponse) - .put(queryAsyncJobResult, queryAsyncJobResultResponse) - .build(); + .put(listProjects, listProjectsResponse) + .put(listTemplates, listTemplatesResponse) + .put(listOsTypes, listOsTypesResponse) + .put(listOsCategories, listOsCategoriesResponse) + .put(listZones, listZonesResponse) + .put(listServiceOfferings, listServiceOfferingsResponse) + .put(listAccounts, listAccountsResponse) + .put(listNetworks, listNetworksResponse) + .put(getZone, getZoneResponse) + .put(deployVM, deployVMResponse) + .put(queryAsyncJobResult, queryAsyncJobResultResponse) + .build(); Injector forNode = requestsSendResponses(requestResponseMap); @@ -154,17 +155,18 @@ public class CloudStackComputeServiceAdapterExpectTest extends BaseCloudStackCom .build(); Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder() - .put(listTemplates, listTemplatesResponse) - .put(listOsTypes, listOsTypesResponse) - .put(listOsCategories, listOsCategoriesResponse) - .put(listZones, listZonesResponse) - .put(listServiceOfferings, listServiceOfferingsResponse) - .put(listAccounts, listAccountsResponse) - .put(listNetworks, listNetworksResponse) - .put(getZone, getZoneResponse) - .put(deployVM, deployVMResponse) - .put(queryAsyncJobResult, queryAsyncJobResultResponse) - .build(); + .put(listProjects, listProjectsResponse) + .put(listTemplates, listTemplatesResponse) + .put(listOsTypes, listOsTypesResponse) + .put(listOsCategories, listOsCategoriesResponse) + .put(listZones, listZonesResponse) + .put(listServiceOfferings, listServiceOfferingsResponse) + .put(listAccounts, listAccountsResponse) + .put(listNetworks, listNetworksResponse) + .put(getZone, getZoneResponse) + .put(deployVM, deployVMResponse) + .put(queryAsyncJobResult, queryAsyncJobResultResponse) + .build(); Injector forKeyPair = requestsSendResponses(requestResponseMap); @@ -201,18 +203,19 @@ public class CloudStackComputeServiceAdapterExpectTest extends BaseCloudStackCom .build(); Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder() - .put(listTemplates, listTemplatesResponse) - .put(listOsTypes, listOsTypesResponse) - .put(listOsCategories, listOsCategoriesResponse) - .put(listZones, listZonesResponse) - .put(listServiceOfferings, listServiceOfferingsResponse) - .put(listAccounts, listAccountsResponse) - .put(listNetworks, listNetworksResponse) - .put(getZone, getZoneResponse) - .put(deployVM, deployVMResponse) - .put(createSSHKeyPair, createSSHKeyPairResponse) - .put(queryAsyncJobResult, queryAsyncJobResultResponse) - .build(); + .put(listProjects, listProjectsResponse) + .put(listTemplates, listTemplatesResponse) + .put(listOsTypes, listOsTypesResponse) + .put(listOsCategories, listOsCategoriesResponse) + .put(listZones, listZonesResponse) + .put(listServiceOfferings, listServiceOfferingsResponse) + .put(listAccounts, listAccountsResponse) + .put(listNetworks, listNetworksResponse) + .put(getZone, getZoneResponse) + .put(deployVM, deployVMResponse) + .put(createSSHKeyPair, createSSHKeyPairResponse) + .put(queryAsyncJobResult, queryAsyncJobResultResponse) + .build(); Injector forKeyPair = requestsSendResponses(requestResponseMap); @@ -247,17 +250,18 @@ public class CloudStackComputeServiceAdapterExpectTest extends BaseCloudStackCom .build(); Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder() - .put(listTemplates, listTemplatesResponse) - .put(listOsTypes, listOsTypesResponse) - .put(listOsCategories, listOsCategoriesResponse) - .put(listZones, listZonesResponse) - .put(listServiceOfferings, listServiceOfferingsResponse) - .put(listAccounts, listAccountsResponse) - .put(listNetworks, listNetworksWithSecurityGroupsResponse) - .put(getZoneWithSecurityGroups, getZoneWithSecurityGroupsResponse) - .put(deployVM, deployVMResponse) - .put(queryAsyncJobResult, queryAsyncJobResultResponse) - .build(); + .put(listProjects, listProjectsResponse) + .put(listTemplates, listTemplatesResponse) + .put(listOsTypes, listOsTypesResponse) + .put(listOsCategories, listOsCategoriesResponse) + .put(listZones, listZonesResponse) + .put(listServiceOfferings, listServiceOfferingsResponse) + .put(listAccounts, listAccountsResponse) + .put(listNetworks, listNetworksWithSecurityGroupsResponse) + .put(getZoneWithSecurityGroups, getZoneWithSecurityGroupsResponse) + .put(deployVM, deployVMResponse) + .put(queryAsyncJobResult, queryAsyncJobResultResponse) + .build(); Injector forKeyPair = requestsSendResponses(requestResponseMap); @@ -299,6 +303,7 @@ public class CloudStackComputeServiceAdapterExpectTest extends BaseCloudStackCom .build(); Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder() + .put(listProjects, listProjectsResponse) .put(listTemplates, listTemplatesResponse) .put(listOsTypes, listOsTypesResponse) .put(listOsCategories, listOsCategoriesResponse) @@ -353,21 +358,22 @@ public class CloudStackComputeServiceAdapterExpectTest extends BaseCloudStackCom .build(); Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder() - .put(listTemplates, listTemplatesResponse) - .put(listOsTypes, listOsTypesResponse) - .put(listOsCategories, listOsCategoriesResponse) - .put(listZones, listZonesResponse) - .put(listServiceOfferings, listServiceOfferingsResponse) - .put(listAccounts, listAccountsResponse) - .put(listNetworks, listNetworksWithSecurityGroupsResponse) - .put(getZoneWithSecurityGroups, getZoneWithSecurityGroupsResponse) - .put(deployVM, deployVMResponse) - .put(queryAsyncJobResult, queryAsyncJobResultSecurityGroupResponse) - .put(queryAsyncJobResultAuthorizeIngress, queryAsyncJobResultAuthorizeIngressResponse) - .put(getSecurityGroup, getSecurityGroupResponse) - .put(createSecurityGroup, createSecurityGroupResponse) - .put(authorizeIngress, authorizeIngressResponse) - .build(); + .put(listProjects, listProjectsResponse) + .put(listTemplates, listTemplatesResponse) + .put(listOsTypes, listOsTypesResponse) + .put(listOsCategories, listOsCategoriesResponse) + .put(listZones, listZonesResponse) + .put(listServiceOfferings, listServiceOfferingsResponse) + .put(listAccounts, listAccountsResponse) + .put(listNetworks, listNetworksWithSecurityGroupsResponse) + .put(getZoneWithSecurityGroups, getZoneWithSecurityGroupsResponse) + .put(deployVM, deployVMResponse) + .put(queryAsyncJobResult, queryAsyncJobResultSecurityGroupResponse) + .put(queryAsyncJobResultAuthorizeIngress, queryAsyncJobResultAuthorizeIngressResponse) + .put(getSecurityGroup, getSecurityGroupResponse) + .put(createSecurityGroup, createSecurityGroupResponse) + .put(authorizeIngress, authorizeIngressResponse) + .build(); Injector forKeyPair = requestsSendResponses(requestResponseMap); @@ -411,17 +417,18 @@ public class CloudStackComputeServiceAdapterExpectTest extends BaseCloudStackCom .build(); Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder() - .put(listTemplates, listTemplatesResponse) - .put(listOsTypes, listOsTypesResponse) - .put(listOsCategories, listOsCategoriesResponse) - .put(listZones, listZonesResponse) - .put(listServiceOfferings, listServiceOfferingsResponse) - .put(listAccounts, listAccountsResponse) - .put(listNetworks, listNetworksResponse) - .put(getZone, getZoneResponse) - .put(deployVM, deployVMResponse) - .put(queryAsyncJobResult, queryAsyncJobResultResponse) - .build(); + .put(listProjects, listProjectsResponse) + .put(listTemplates, listTemplatesResponse) + .put(listOsTypes, listOsTypesResponse) + .put(listOsCategories, listOsCategoriesResponse) + .put(listZones, listZonesResponse) + .put(listServiceOfferings, listServiceOfferingsResponse) + .put(listAccounts, listAccountsResponse) + .put(listNetworks, listNetworksResponse) + .put(getZone, getZoneResponse) + .put(deployVM, deployVMResponse) + .put(queryAsyncJobResult, queryAsyncJobResultResponse) + .build(); Injector forKeyPair = requestsSendResponses(requestResponseMap); http://git-wip-us.apache.org/repos/asf/jclouds/blob/8b94ee58/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/ProjectApiExpectTest.java ---------------------------------------------------------------------- diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/ProjectApiExpectTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/ProjectApiExpectTest.java new file mode 100644 index 0000000..86ad263 --- /dev/null +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/ProjectApiExpectTest.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.cloudstack.features; + +import static org.testng.Assert.assertEquals; + +import java.util.Set; + +import org.jclouds.cloudstack.CloudStackContext; +import org.jclouds.cloudstack.domain.Project; +import org.jclouds.cloudstack.internal.BaseCloudStackExpectTest; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * Test the CloudStack ProjectApi + * + * @author Andrew Bayer + */ +@Test(groups = "unit", testName = "ProjectApiExpectTest") +public class ProjectApiExpectTest extends BaseCloudStackExpectTest<ProjectApi> { + + + public void testListProjectsWhenResponseIs2xx() { + + ProjectApi client = requestSendsResponse( + HttpRequest.builder() + .method("GET") + .endpoint("http://localhost:8080/client/api?response=json&command=listProjects&listAll=true&apiKey=identity&signature=vtCqaYXfXttr6mD18Es0e22QBIQ%3D") + .addHeader("Accept", "application/json") + .build(), + HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResource("/listprojectsresponse.json")) + .build()); + + Set<Project> projects = ImmutableSet.of( + Project.builder() + .id("489da162-0b77-489d-b044-ce39aa018b1f") + .account("thyde") + .displayText("") + .domain("ROOT") + .domainId("41a4917b-7952-499d-ba7f-4c57464d3dc8") + .name("NN-HA-T1") + .state(Project.State.ACTIVE).build(), + Project.builder() + .id("1c11f22c-15ac-4fa7-b833-4d748df317b7") + .account("prasadm") + .displayText("Hive") + .domain("ROOT") + .domainId("41a4917b-7952-499d-ba7f-4c57464d3dc8") + .name("hive") + .state(Project.State.ACTIVE).build()); + + assertEquals(client.listProjects(), projects); + } + + @Override + protected ProjectApi clientFrom(CloudStackContext context) { + return context.getApi().getProjectApi(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/8b94ee58/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/ProjectApiLiveTest.java ---------------------------------------------------------------------- diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/ProjectApiLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/ProjectApiLiveTest.java new file mode 100644 index 0000000..55b9280 --- /dev/null +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/ProjectApiLiveTest.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.cloudstack.features; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +import org.jclouds.cloudstack.domain.Project; +import org.jclouds.cloudstack.internal.BaseCloudStackApiLiveTest; +import org.testng.annotations.Test; + +/** + * Tests behavior of {@code ProjectApi} + * + * @author Andrew Bayer + */ +@Test(groups = "live", singleThreaded = true, testName = "ProjectApiLiveTest") +public class ProjectApiLiveTest extends BaseCloudStackApiLiveTest { + + @Test + public void testListAccounts() throws Exception { + for (Project project : client.getProjectApi().listProjects()) + checkProject(project); + } + + protected void checkProject(Project project) { + assertNotNull(project.getId()); + assertEquals(project.toString(), client.getProjectApi().getProject(project.getId()).toString()); + assertTrue(project.getState() != null); + assertTrue(project.getState() != Project.State.UNRECOGNIZED); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/8b94ee58/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/ProjectApiTest.java ---------------------------------------------------------------------- diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/ProjectApiTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/ProjectApiTest.java new file mode 100644 index 0000000..e77e844 --- /dev/null +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/ProjectApiTest.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.cloudstack.features; +import static org.jclouds.reflect.Reflection2.method; + +import java.io.IOException; + +import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404; +import org.jclouds.Fallbacks.NullOnNotFoundOr404; +import org.jclouds.cloudstack.internal.BaseCloudStackApiTest; +import org.jclouds.cloudstack.options.ListProjectsOptions; +import org.jclouds.functions.IdentityFunction; +import org.jclouds.http.functions.ParseFirstJsonValueNamed; +import org.jclouds.rest.internal.GeneratedHttpRequest; +import org.testng.annotations.Test; + +import com.google.common.base.Functions; +import com.google.common.collect.ImmutableList; +import com.google.common.reflect.Invokable; + +/** + * Tests behavior of {@code ProjectApi} + * + * @author Andrew Bayer + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during +// surefire +@Test(groups = "unit", testName = "ProjectApiTest") +public class ProjectApiTest extends BaseCloudStackApiTest<ProjectApi> { + + public void testListProjects() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(ProjectApi.class, "listProjects", ListProjectsOptions[].class); + GeneratedHttpRequest httpRequest = processor.createRequest(method, ImmutableList.of()); + + assertRequestLineEquals(httpRequest, + "GET http://localhost:8080/client/api?response=json&command=listProjects&listAll=true HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, ParseFirstJsonValueNamed.class); + assertSaxResponseParserClassEquals(method, null); + assertFallbackClassEquals(method, EmptySetOnNotFoundOr404.class); + + checkFilters(httpRequest); + + } + + public void testListProjectsOptions() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(ProjectApi.class, "listProjects", ListProjectsOptions[].class); + GeneratedHttpRequest httpRequest = processor.createRequest(method, ImmutableList.<Object> of( + ListProjectsOptions.Builder.accountInDomain("jclouds", "123"))); + + assertRequestLineEquals(httpRequest, + "GET http://localhost:8080/client/api?response=json&command=listProjects&listAll=true&account=jclouds&domainid=123 HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, ParseFirstJsonValueNamed.class); + assertSaxResponseParserClassEquals(method, null); + assertFallbackClassEquals(method, EmptySetOnNotFoundOr404.class); + + checkFilters(httpRequest); + + } + + public void testGetAccount() throws SecurityException, NoSuchMethodException, IOException { + Invokable<?, ?> method = method(ProjectApi.class, "getProject", String.class); + GeneratedHttpRequest httpRequest = processor.createRequest(method, ImmutableList.<Object> of("3")); + + assertRequestLineEquals(httpRequest, + "GET http://localhost:8080/client/api?response=json&command=listProjects&listAll=true&id=3 HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, + Functions.compose(IdentityFunction.INSTANCE, IdentityFunction.INSTANCE).getClass()); + assertSaxResponseParserClassEquals(method, null); + assertFallbackClassEquals(method, NullOnNotFoundOr404.class); + + checkFilters(httpRequest); + + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/8b94ee58/apis/cloudstack/src/test/java/org/jclouds/cloudstack/internal/BaseCloudStackComputeServiceContextExpectTest.java ---------------------------------------------------------------------- diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/internal/BaseCloudStackComputeServiceContextExpectTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/internal/BaseCloudStackComputeServiceContextExpectTest.java index 8b8d01d..411651e 100644 --- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/internal/BaseCloudStackComputeServiceContextExpectTest.java +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/internal/BaseCloudStackComputeServiceContextExpectTest.java @@ -47,7 +47,22 @@ public abstract class BaseCloudStackComputeServiceContextExpectTest<T> extends B protected final HttpResponse listTemplatesResponse = HttpResponse.builder().statusCode(200) .payload(payloadFromResource("/listtemplatesresponse.json")) .build(); - + + protected final HttpRequest listProjects = HttpRequest.builder().method("GET") + .endpoint("http://localhost:8080/client/api") + .addQueryParam("response", "json") + .addQueryParam("command", "listProjects") + .addQueryParam("listAll", "true") + .addQueryParam("account", "jclouds") + .addQueryParam("domainid", "457") + .addQueryParam("apiKey", "APIKEY") + .addQueryParam("signature", "yAx1XbtjeEhdBQCNP0OLyWWAFCw%3D") + .addHeader("Accept", "application/json") + .build(); + + protected final HttpResponse listProjectsResponse = HttpResponse.builder().statusCode(200) + .build(); + protected final HttpRequest listOsTypes = HttpRequest.builder().method("GET") .endpoint("http://localhost:8080/client/api") .addQueryParam("response", "json") http://git-wip-us.apache.org/repos/asf/jclouds/blob/8b94ee58/apis/cloudstack/src/test/resources/listprojectsresponse.json ---------------------------------------------------------------------- diff --git a/apis/cloudstack/src/test/resources/listprojectsresponse.json b/apis/cloudstack/src/test/resources/listprojectsresponse.json new file mode 100644 index 0000000..33273ef --- /dev/null +++ b/apis/cloudstack/src/test/resources/listprojectsresponse.json @@ -0,0 +1 @@ +{ "listprojectsresponse" : { "count":2 ,"project" : [ {"id":"489da162-0b77-489d-b044-ce39aa018b1f","name":"NN-HA-T1","displaytext":"","domainid":"41a4917b-7952-499d-ba7f-4c57464d3dc8","domain":"ROOT","account":"thyde","state":"Active"}, {"id":"1c11f22c-15ac-4fa7-b833-4d748df317b7","name":"hive","displaytext":"Hive","domainid":"41a4917b-7952-499d-ba7f-4c57464d3dc8","domain":"ROOT","account":"prasadm","state":"Active"} ] } } \ No newline at end of file
