Merge pull request #133 from vijaykiran/limit-client

Limit#listResourceLimits implementation
This commit is contained in:
Adrian Cole 2011-11-10 03:42:01 -08:00
commit 304dda4823
10 changed files with 600 additions and 7 deletions

View File

@ -26,6 +26,7 @@ import org.jclouds.cloudstack.features.EventAsyncClient;
import org.jclouds.cloudstack.features.FirewallAsyncClient;
import org.jclouds.cloudstack.features.GuestOSAsyncClient;
import org.jclouds.cloudstack.features.HypervisorAsyncClient;
import org.jclouds.cloudstack.features.LimitAsyncClient;
import org.jclouds.cloudstack.features.LoadBalancerAsyncClient;
import org.jclouds.cloudstack.features.NATAsyncClient;
import org.jclouds.cloudstack.features.NetworkAsyncClient;
@ -157,4 +158,10 @@ public interface CloudStackAsyncClient {
@Delegate
EventAsyncClient getEventClient();
/**
* Provides synchronous access to Resource Limits
*/
@Delegate
LimitAsyncClient getLimitClient();
}

View File

@ -28,6 +28,7 @@ import org.jclouds.cloudstack.features.EventClient;
import org.jclouds.cloudstack.features.FirewallClient;
import org.jclouds.cloudstack.features.GuestOSClient;
import org.jclouds.cloudstack.features.HypervisorClient;
import org.jclouds.cloudstack.features.LimitClient;
import org.jclouds.cloudstack.features.LoadBalancerClient;
import org.jclouds.cloudstack.features.NATClient;
import org.jclouds.cloudstack.features.NetworkClient;
@ -35,8 +36,8 @@ import org.jclouds.cloudstack.features.OfferingClient;
import org.jclouds.cloudstack.features.SSHKeyPairClient;
import org.jclouds.cloudstack.features.SecurityGroupClient;
import org.jclouds.cloudstack.features.TemplateClient;
import org.jclouds.cloudstack.features.VirtualMachineClient;
import org.jclouds.cloudstack.features.VMGroupClient;
import org.jclouds.cloudstack.features.VirtualMachineClient;
import org.jclouds.cloudstack.features.ZoneClient;
import org.jclouds.concurrent.Timeout;
import org.jclouds.rest.annotations.Delegate;
@ -44,10 +45,10 @@ import org.jclouds.rest.annotations.Delegate;
/**
* Provides synchronous access to CloudStack.
* <p/>
*
*
* @author Adrian Cole
* @see CloudStackAsyncClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole
*/
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface CloudStackClient {
@ -160,4 +161,10 @@ public interface CloudStackClient {
@Delegate
EventClient getEventClient();
/**
* Provides synchronous access to Resource Limits
*/
@Delegate
LimitClient getLimitClient();
}

View File

@ -20,6 +20,7 @@ package org.jclouds.cloudstack.config;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import org.jclouds.cloudstack.CloudStackAsyncClient;
import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.features.AccountAsyncClient;
@ -38,6 +39,8 @@ import org.jclouds.cloudstack.features.GuestOSAsyncClient;
import org.jclouds.cloudstack.features.GuestOSClient;
import org.jclouds.cloudstack.features.HypervisorAsyncClient;
import org.jclouds.cloudstack.features.HypervisorClient;
import org.jclouds.cloudstack.features.LimitAsyncClient;
import org.jclouds.cloudstack.features.LimitClient;
import org.jclouds.cloudstack.features.LoadBalancerAsyncClient;
import org.jclouds.cloudstack.features.LoadBalancerClient;
import org.jclouds.cloudstack.features.NATAsyncClient;
@ -69,18 +72,16 @@ import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule;
import com.google.common.collect.ImmutableMap;
/**
* Configures the cloudstack connection.
*
*
* @author Adrian Cole
*/
@RequiresHttp
@ConfiguresRestClient
public class CloudStackRestClientModule extends RestClientModule<CloudStackClient, CloudStackAsyncClient> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>>builder()//
.put(ZoneClient.class, ZoneAsyncClient.class)//
.put(TemplateClient.class, TemplateAsyncClient.class)//
.put(OfferingClient.class, OfferingAsyncClient.class)//
@ -97,6 +98,7 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
.put(ConfigurationClient.class, ConfigurationAsyncClient.class)//
.put(AccountClient.class, AccountAsyncClient.class)//
.put(EventClient.class, EventAsyncClient.class)//
.put(LimitClient.class, LimitAsyncClient.class)//
.put(SSHKeyPairClient.class, SSHKeyPairAsyncClient.class)//
.put(VMGroupClient.class, VMGroupAsyncClient.class)//
.build();

View File

@ -0,0 +1,209 @@
/**
* 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.cloudstack.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.gson.annotations.SerializedName;
/**
* @author Vijay Kiran
*/
public class ResourceLimit implements Comparable<ResourceLimit> {
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String account;
private String domain;
private long domainId;
private int max;
private ResourceType resourceType;
public Builder account(String account) {
this.account = account;
return this;
}
public Builder domain(String domain) {
this.domain = domain;
return this;
}
public Builder domainId(long domainId) {
this.domainId = domainId;
return this;
}
public Builder max(int max) {
this.max = max;
return this;
}
public Builder resourceType(ResourceType resourceType) {
this.resourceType = resourceType;
return this;
}
public ResourceLimit build() {
return new ResourceLimit(account, domain, domainId, max, resourceType);
}
}
// for deserialization
ResourceLimit() {
}
private String account;
private String domain;
@SerializedName("domainid")
private long domainId;
private int max;
@SerializedName("resourcetype")
private ResourceType resourceType;
public ResourceLimit(String account, String domain, long domainId, int max, ResourceType resourceType) {
this.account = account;
this.domain = domain;
this.domainId = domainId;
this.max = max;
this.resourceType = resourceType;
}
public String getAccount() {
return account;
}
public String getDomain() {
return domain;
}
public long getDomainId() {
return domainId;
}
public int getMax() {
return max;
}
public ResourceType getResourceType() {
return resourceType;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ResourceLimit that = (ResourceLimit) o;
if (domainId != that.domainId) return false;
if (max != that.max) return false;
if (resourceType != that.resourceType) return false;
if (!account.equals(that.account)) return false;
if (!domain.equals(that.domain)) return false;
return true;
}
@Override
public int hashCode() {
int result = account.hashCode();
result = 31 * result + domain.hashCode();
result = 31 * result + (int) (domainId ^ (domainId >>> 32));
result = 31 * result + max;
return result;
}
@Override
public int compareTo(ResourceLimit that) {
return this.account.compareTo(that.account);
}
@Override
public String toString() {
return String.format("[account=%s, domain=%s, domainId=%d, max=%d, resourceType=%s]",
account, domain, domainId, max, resourceType);
}
/**
* Type of resource to update.
*/
public enum ResourceType {
/**
* 0 - Instance. Number of instances a user can create.
*/
INSTANCE(0),
/**
* 1 - IP. Number of public IP addresses a user can own.
*/
IP(1),
/**
* 2 - Volume. Number of disk volumes a user can create.
*/
VOLUME(2),
/**
* 3 - Snapshot. Number of snapshots a user can create.
*/
SNAPSHOT(3),
/**
* 4 - Template. Number of templates that a user can register/create.
*/
TEMPLATE(4),
UNRECOGNIZED(Integer.MAX_VALUE);
private int code;
private static final Map<Integer, ResourceType> INDEX = Maps.uniqueIndex(ImmutableSet.copyOf(ResourceType.values()),
new Function<ResourceType, Integer>() {
@Override
public Integer apply(ResourceType input) {
return input.code;
}
});
ResourceType(int code) {
this.code = code;
}
@Override
public String toString() {
return name();
}
public static ResourceType fromValue(String resourceType) {
Integer code = new Integer(checkNotNull(resourceType, "resourcetype"));
return INDEX.containsKey(code) ? INDEX.get(code) : UNRECOGNIZED;
}
}
}

View File

@ -0,0 +1,58 @@
/**
* 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.cloudstack.features;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.core.MediaType;
import java.util.Set;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.ResourceLimit;
import org.jclouds.cloudstack.domain.SshKeyPair;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.options.ListResourceLimitsOptions;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
/**
* Provides asynchronous access to CloudStack SSHKeyPair features.
*
* @author Vijay Kiran
* @see <a
* href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html"
* />
*/
@RequestFilters(QuerySigner.class)
@QueryParams(keys = "response", values = "json")
public interface LimitAsyncClient {
/**
* @see org.jclouds.cloudstack.features.LimitClient#listResourceLimits
*/
@GET
@QueryParams(keys = "command", values = "listResourceLimits")
@SelectJson("resourcelimit")
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<ResourceLimit>> listResourceLimits(ListResourceLimitsOptions... options);
}

View File

@ -0,0 +1,45 @@
/**
* 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.cloudstack.features;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jclouds.cloudstack.domain.ResourceLimit;
import org.jclouds.cloudstack.options.ListResourceLimitsOptions;
import org.jclouds.concurrent.Timeout;
/**
* Provides synchronous access to CloudStack resource limit API.
*
* @author Vijay Kiran
* @see <a
* href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html"
* />
*/
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface LimitClient {
/**
* List the resource limits.
*
* @param options if present, how to constrain the list
*/
Set<ResourceLimit> listResourceLimits(ListResourceLimitsOptions... options);
}

View File

@ -0,0 +1,137 @@
/**
* 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.cloudstack.options;
import com.google.common.collect.ImmutableSet;
import org.jclouds.http.options.BaseHttpRequestOptions;
/**
* @author Vijay Kiran
*/
public class ListResourceLimitsOptions extends BaseHttpRequestOptions {
public static final ListResourceLimitsOptions NONE = new ListResourceLimitsOptions();
/**
* Lists resource limits by account. Must be used with the domainId parameter.
*
* @param account - the account for which the resource limits are retrieved for.
* @return ListResourceLimitsOptions
*/
public ListResourceLimitsOptions account(String account, long domainId) {
this.queryParameters.replaceValues("account", ImmutableSet.of(account));
this.queryParameters.replaceValues("domainid", ImmutableSet.of(String.valueOf(domainId)));
return this;
}
/**
* Lists resource limits by domain ID. If used with the account parameter,
* lists resource limits for a specified account in a specified domain.
*
* @param domainId
* @return ListResourceLimitsOptions
*/
public ListResourceLimitsOptions domainId(long domainId) {
this.queryParameters.replaceValues("domainid", ImmutableSet.of(String.valueOf(domainId)));
return this;
}
/**
* Lists resource limits by ID.
*
* @param id of the resource limit.
* @return ListResourceLimitsOptions
*/
public ListResourceLimitsOptions id(long id) {
this.queryParameters.replaceValues("account", ImmutableSet.of(String.valueOf(id)));
return this;
}
/**
* List by keyword
*
* @param keyword
* @return ListResourceLimitsOptions
*/
public ListResourceLimitsOptions keyword(String keyword) {
this.queryParameters.replaceValues("keyword", ImmutableSet.of(keyword));
return this;
}
/**
* Type of resource to update. Values are 0, 1, 2, 3, and 4.
* <ul>
* <li>0 - Instance. Number of instances a user can create.</li>
* <li>1 - IP. Number of public IP addresses a user can own.</li>
* <li>2 - Volume. Number of disk volumes a user can create.</li>
* <li>3 - Snapshot. Number of snapshots a user can create.</li>
* <li>4 - Template. Number of templates that a user can register/create.</li>
* </ul>
*
* @param resourceType type of the resource to query for
* @return ListResourceLimitsOptions
*/
public ListResourceLimitsOptions resourceType(int resourceType) {
this.queryParameters.replaceValues("resourcetype", ImmutableSet.of(String.valueOf(resourceType)));
return this;
}
public static class Builder {
/**
* @see ListResourceLimitsOptions#account(String, long)
*/
public static ListResourceLimitsOptions account(String account, long domainId) {
ListResourceLimitsOptions options = new ListResourceLimitsOptions();
return options.account(account, domainId);
}
/**
* @see ListResourceLimitsOptions#domainId(long)
*/
public static ListResourceLimitsOptions domainId(long domainId) {
ListResourceLimitsOptions options = new ListResourceLimitsOptions();
return options.domainId(domainId);
}
/**
* @see ListResourceLimitsOptions#id(long)
*/
public static ListResourceLimitsOptions id(long id) {
ListResourceLimitsOptions options = new ListResourceLimitsOptions();
return options.id(id);
}
/**
* @see ListResourceLimitsOptions#keyword(String)
*/
public static ListResourceLimitsOptions keyword(String keyword) {
ListResourceLimitsOptions options = new ListResourceLimitsOptions();
return options.keyword(keyword);
}
/**
* @see ListResourceLimitsOptions#resourceType(int)
*/
public static ListResourceLimitsOptions resourceType(int resourceType) {
ListResourceLimitsOptions options = new ListResourceLimitsOptions();
return options.resourceType(resourceType);
}
}
}

View File

@ -0,0 +1,79 @@
/**
* 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.cloudstack.features;
import java.io.IOException;
import java.lang.reflect.Method;
import com.google.inject.TypeLiteral;
import org.jclouds.cloudstack.options.ListResourceLimitsOptions;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseFirstJsonValueNamed;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code LimitAsyncClient}
*
* @author Vijay Kiran
*/
@Test(groups = "unit", testName = "LimitAsyncClientTest")
public class LimitAsyncClientTest extends BaseCloudStackAsyncClientTest<LimitAsyncClient> {
public void testListResourceLimits() throws SecurityException, NoSuchMethodException, IOException {
Method method = LimitAsyncClient.class.getMethod("listResourceLimits", ListResourceLimitsOptions[].class);
HttpRequest httpRequest = processor.createRequest(method);
assertRequestLineEquals(httpRequest,
"GET http://localhost:8080/client/api?response=json&command=listResourceLimits HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ParseFirstJsonValueNamed.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testListResourceLimitsOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = LimitAsyncClient.class.getMethod("listResourceLimits", ListResourceLimitsOptions[].class);
HttpRequest httpRequest = processor.createRequest(method, ListResourceLimitsOptions.Builder.account("jclouds" , 23));
assertRequestLineEquals(httpRequest,
"GET http://localhost:8080/client/api?response=json&command=listResourceLimits&account=jclouds&domainid=23 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ParseFirstJsonValueNamed.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(httpRequest);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<LimitAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<LimitAsyncClient>>() {
};
}
}

View File

@ -0,0 +1,48 @@
/**
* 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.cloudstack.features;
import java.util.Set;
import org.jclouds.cloudstack.domain.ResourceLimit;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code LimitClient}
*
* @author Vijay Kiran
*/
@Test(groups = "live", singleThreaded = true, testName = "LimitClientLiveTest")
public class LimitClientLiveTest extends BaseCloudStackClientLiveTest {
public void testListResourceLimits() {
final Set<ResourceLimit> resourceLimits = client.getLimitClient().listResourceLimits();
for (ResourceLimit resourceLimit : resourceLimits) {
checkResourceLimit(resourceLimit);
}
}
private void checkResourceLimit(ResourceLimit resourceLimit) {
System.out.println(resourceLimit);
assert resourceLimit.getAccount() != null : resourceLimit;
assert resourceLimit.getDomain() != null : resourceLimit;
assert resourceLimit.getResourceType() != ResourceLimit.ResourceType.UNRECOGNIZED : resourceLimit;
}
}

View File

@ -0,0 +1 @@
{ "listresourcelimitsresponse" : { "count":5 ,"resourcelimit" : [ {"account":"jclouds","domainid":457,"domain":"AA000062-jclouds-dev","resourcetype":"0","max":-1}, {"account":"jclouds","domainid":457,"domain":"AA000062-jclouds-dev","resourcetype":"1","max":-1}, {"account":"jclouds","domainid":457,"domain":"AA000062-jclouds-dev","resourcetype":"2","max":-1}, {"account":"jclouds","domainid":457,"domain":"AA000062-jclouds-dev","resourcetype":"3","max":-1}, {"account":"jclouds","domainid":457,"domain":"AA000062-jclouds-dev","resourcetype":"4","max":-1} ] } }