Issue 158: added response parser for ProductPackage

This commit is contained in:
Adrian Cole 2011-09-01 17:42:46 -07:00
parent 7f3ca1ad70
commit 1f14adf4ea
7 changed files with 560 additions and 11 deletions

View File

@ -0,0 +1,189 @@
/**
* 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.softlayer.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set;
import javax.annotation.Nullable;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
/**
* The SoftLayer_Product_Item data type contains general information relating to
* a single SoftLayer product.
*
* @author Adrian Cole
* @see <a href=
* "http://sldn.softlayer.com/reference/datatypes/SoftLayer_Product_Item"
* />
*/
public class ProductItem implements Comparable<ProductItem> {
// TODO there are more elements than this.
public static Builder builder() {
return new Builder();
}
public static class Builder {
private long id = -1;
private String description;
private String units;
private Float capacity;
private Set<ProductItemPrice> prices = Sets.newLinkedHashSet();
public Builder id(long id) {
this.id = id;
return this;
}
public Builder description(String description) {
this.description = description;
return this;
}
public Builder units(String units) {
this.units = units;
return this;
}
public Builder capacity(Float capacity) {
this.capacity = capacity;
return this;
}
public Builder price(ProductItemPrice prices) {
this.prices.add(checkNotNull(prices, "prices"));
return this;
}
public Builder prices(Iterable<ProductItemPrice> prices) {
this.prices = ImmutableSet.<ProductItemPrice> copyOf(checkNotNull(prices, "prices"));
return this;
}
public ProductItem build() {
return new ProductItem(id, description, units, capacity, prices);
}
public static Builder fromProductItem(ProductItem in) {
return ProductItem.builder().id(in.getId()).description(in.getDescription()).units(in.getUnits())
.capacity(in.getCapacity()).prices(in.getPrices());
}
}
private long id = -1;
private String description;
private String units;
private Float capacity;
private Set<ProductItemPrice> prices = Sets.newLinkedHashSet();
// for deserializer
ProductItem() {
}
public ProductItem(long id, String description, String units, Float capacity, Iterable<ProductItemPrice> prices) {
this.id = id;
this.description = description;
this.units = units;
this.capacity = capacity;
this.prices = ImmutableSet.<ProductItemPrice> copyOf(checkNotNull(prices, "prices"));
}
@Override
public int compareTo(ProductItem arg0) {
return new Long(id).compareTo(arg0.getId());
}
/**
* @return The unique identifier of a specific location.
*/
public long getId() {
return id;
}
/**
* @return A product's description
*/
public String getDescription() {
return description;
}
/**
* @return The unit of measurement that a product item is measured in.
*/
@Nullable
public String getUnits() {
return units;
}
/**
* @return Some Product Items have capacity information such as RAM and
* bandwidth, and others. This provides the numerical representation
* of the capacity given in the description of this product item.
*/
@Nullable
public Float getCapacity() {
return capacity;
}
/**
*
* @return A product item's prices.
*/
public Set<ProductItemPrice> getPrices() {
return prices;
}
public Builder toBuilder() {
return Builder.fromProductItem(this);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ProductItem other = (ProductItem) obj;
if (id != other.id)
return false;
return true;
}
@Override
public String toString() {
return "ProductItem [id=" + id + ", description=" + description + ", units=" + units + ", capacity=" + capacity
+ ", prices=" + prices + "]";
}
}

View File

@ -0,0 +1,143 @@
/**
* 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.softlayer.domain;
import javax.annotation.Nullable;
/**
* The SoftLayer_Product_Item_Price data type contains general information
* relating to a single SoftLayer product item price. You can find out what
* packages each price is in as well as which category under which this price is
* sold. All prices are returned in Floating point values measured in US Dollars
* ($USD).
*
* @author Adrian Cole
* @see <a href=
* "http://sldn.softlayer.com/reference/datatypes/SoftLayer_Product_Item_Price"
* />
*/
public class ProductItemPrice implements Comparable<ProductItemPrice> {
// TODO there are more elements than this.
public static Builder builder() {
return new Builder();
}
public static class Builder {
private long id = -1;
private long itemId = -1;
private Float recurringFee;
private Float hourlyRecurringFee;
public Builder id(long id) {
this.id = id;
return this;
}
public Builder itemId(long itemId) {
this.itemId = itemId;
return this;
}
public Builder recurringFee(Float recurringFee) {
this.recurringFee = recurringFee;
return this;
}
public Builder hourlyRecurringFee(Float hourlyRecurringFee) {
this.hourlyRecurringFee = hourlyRecurringFee;
return this;
}
public ProductItemPrice build() {
return new ProductItemPrice(id, itemId, recurringFee, hourlyRecurringFee);
}
public static Builder fromPrice(ProductItemPrice in) {
return ProductItemPrice.builder().id(in.getId()).itemId(in.getItemId())
.hourlyRecurringFee(in.getHourlyRecurringFee()).recurringFee(in.getRecurringFee());
}
}
private long id = -1;
private long itemId = -1;
private Float recurringFee;
private Float hourlyRecurringFee;
// for deserializer
ProductItemPrice() {
}
public ProductItemPrice(long id, long itemId, Float recurringFee, Float hourlyRecurringFee) {
this.id = id;
this.itemId = itemId;
this.recurringFee = recurringFee;
this.hourlyRecurringFee = hourlyRecurringFee;
}
@Override
public int compareTo(ProductItemPrice arg0) {
return new Long(id).compareTo(arg0.getId());
}
/**
* @return The unique identifier of a Product Item Price.
*/
public long getId() {
return id;
}
/**
* @return The unique identifier for a product Item
*/
public long getItemId() {
return itemId;
}
/**
* @return A recurring fee is a fee that happens every billing period. This
* fee is represented as a Floating point decimal in US dollars
* ($USD).
*/
@Nullable
public Float getRecurringFee() {
return recurringFee;
}
/**
* @return The hourly price for this item, should this item be part of an
* hourly pricing package.
*/
@Nullable
public Float getHourlyRecurringFee() {
return hourlyRecurringFee;
}
public Builder toBuilder() {
return Builder.fromPrice(this);
}
@Override
public String toString() {
return "[id=" + id + ", itemId=" + itemId + ", recurringFee=" + recurringFee + ", hourlyRecurringFee="
+ hourlyRecurringFee + "]";
}
}

View File

@ -0,0 +1,174 @@
/**
* 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.softlayer.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
/**
* The SoftLayer_Product_Package data type contains information about packages
* from which orders can be generated. Packages contain general information
* regarding what is in them, where they are currently sold, availability, and
* pricing.
*
* @author Adrian Cole
* @see <a href=
* "http://sldn.softlayer.com/reference/datatypes/SoftLayer_Product_Package"
* />
*/
public class ProductPackage implements Comparable<ProductPackage> {
// TODO there are more elements than this.
public static Builder builder() {
return new Builder();
}
public static class Builder {
private long id = -1;
private String name;
private String description;
private Set<ProductItem> items = Sets.newLinkedHashSet();
public Builder id(long id) {
this.id = id;
return this;
}
public Builder name(String name) {
this.name = name;
return this;
}
public Builder description(String description) {
this.description = description;
return this;
}
public Builder productItem(ProductItem items) {
this.items.add(checkNotNull(items, "items"));
return this;
}
public Builder items(Iterable<ProductItem> items) {
this.items = ImmutableSet.<ProductItem> copyOf(checkNotNull(items, "items"));
return this;
}
public ProductPackage build() {
return new ProductPackage(id, name, description, items);
}
public static Builder fromProductPackage(ProductPackage in) {
return ProductPackage.builder().id(in.getId()).name(in.getName()).description(in.getDescription())
.items(in.getItems());
}
}
private long id = -1;
private String name;
private String description;
private Set<ProductItem> items = Sets.newLinkedHashSet();
// for deserializer
ProductPackage() {
}
public ProductPackage(long id, String name, String description, Iterable<ProductItem> items) {
this.id = id;
this.name = name;
this.description = description;
this.items = ImmutableSet.<ProductItem> copyOf(checkNotNull(items, "items"));
}
@Override
public int compareTo(ProductPackage arg0) {
return new Long(id).compareTo(arg0.getId());
}
/**
* @return A package's internal identifier. Everything regarding a
* SoftLayer_Product_Package is tied back to this id.
*/
public long getId() {
return id;
}
/**
* @return The description of the package. For server packages, this is
* usually a detailed description of processor type and count.
*/
public String getName() {
return name;
}
/**
* @return A generic description of the processor type and count. This
* includes HTML, so you may want to strip these tags if you plan to
* use it.
*/
public String getDescription() {
return description;
}
/**
*
* @return A collection of valid items available for purchase in this
* package.
*/
public Set<ProductItem> getItems() {
return items;
}
public Builder toBuilder() {
return Builder.fromProductPackage(this);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ProductPackage other = (ProductPackage) obj;
if (id != other.id)
return false;
return true;
}
@Override
public String toString() {
return "ProductPackage [id=" + id + ", name=" + name + ", description=" + description + ", items=" + items + "]";
}
}

View File

@ -18,13 +18,18 @@
*/
package org.jclouds.softlayer.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.core.MediaType;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.softlayer.domain.ProductPackage;
import com.google.common.util.concurrent.ListenableFuture;
@ -47,9 +52,9 @@ public interface ProductPackageAsyncClient {
@GET
@Path("/SoftLayer_Product_Package/{id}.json")
@QueryParams(keys = "objectMask", values = PRODUCT_MASK)
// @Consumes(MediaType.APPLICATION_JSON)
// @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<String> getProductPackage(@PathParam("id") long id);
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<ProductPackage> getProductPackage(@PathParam("id") long id);
}

View File

@ -21,6 +21,7 @@ package org.jclouds.softlayer.features;
import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.softlayer.domain.ProductPackage;
/**
* Provides synchronous access to ProductPackage.
@ -30,7 +31,7 @@ import org.jclouds.concurrent.Timeout;
* @see <a href="http://sldn.softlayer.com/wiki/index.php/REST" />
* @author Adrian Cole
*/
@Timeout(duration = 4, timeUnit = TimeUnit.SECONDS)
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface ProductPackageClient {
/**
@ -39,6 +40,6 @@ public interface ProductPackageClient {
* id of the product package
* @return product package or null if not found
*/
String getProductPackage(long id);
ProductPackage getProductPackage(long id);
}

View File

@ -22,8 +22,8 @@ import java.io.IOException;
import java.lang.reflect.Method;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ReturnStringIf2xx;
import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
@ -44,12 +44,12 @@ public class ProductPackageAsyncClientTest extends BaseSoftLayerAsyncClientTest<
assertRequestLineEquals(
httpRequest,
"GET https://api.softlayer.com/rest/v3/SoftLayer_Product_Package/1234.json?objectMask=items HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ReturnStringIf2xx.class);
assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);

View File

@ -18,6 +18,11 @@
*/
package org.jclouds.softlayer.features;
import static org.testng.Assert.assertTrue;
import org.jclouds.softlayer.domain.ProductItem;
import org.jclouds.softlayer.domain.ProductItemPrice;
import org.jclouds.softlayer.domain.ProductPackage;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
@ -38,7 +43,39 @@ public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest {
@Test
public void testGetProductPackage() {
client.getProductPackage(46);
ProductPackage response = client.getProductPackage(46);
assert null != response;
assert response.getId() > 0 : response;
assert response.getName() != null : response;
assert response.getDescription() != null : response;
assertTrue(response.getItems().size() >= 0);
for (ProductItem item : response.getItems()) {
// ProductItem newDetails = client.getProductItem(item.getId());
// assertEquals(item.getId(), newDetails.getId());
checkProductItem(item);
}
}
private void checkProductItem(ProductItem item) {
assert item.getId() > 0 : item;
assert item.getDescription() != null : item;
// units and capacity may be null
assertTrue(item.getPrices().size() >= 0);
for (ProductItemPrice price : item.getPrices()) {
// ProductItemPrice newDetails =
// client.getProductItemPrice(price.getId());
// assertEquals(item.getId(), newDetails.getId());
checkPrice(price);
}
}
private void checkPrice(ProductItemPrice price) {
assert price.getId() > 0 : price;
assert price.getItemId() > 0 : price;
assert price.getRecurringFee() != null || price.getHourlyRecurringFee() != null : price;
}
}