mirror of https://github.com/apache/jclouds.git
Issue 158: Can now place orders via VirtualGuestClient. Additional support classes present
This commit is contained in:
parent
b14ecb86d5
commit
3bd0c20856
|
@ -0,0 +1,130 @@
|
||||||
|
/**
|
||||||
|
* 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.binders;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.json.Json;
|
||||||
|
import org.jclouds.rest.Binder;
|
||||||
|
import org.jclouds.softlayer.domain.ProductItemPrice;
|
||||||
|
import org.jclouds.softlayer.domain.ProductOrder;
|
||||||
|
import org.jclouds.softlayer.domain.VirtualGuest;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a ProductOrder into a json string
|
||||||
|
* valid for placing an order via the softlayer api
|
||||||
|
* The String is set into the payload of the HttpRequest
|
||||||
|
*
|
||||||
|
* @author Jason King
|
||||||
|
*/
|
||||||
|
public class ProductOrderToJson implements Binder {
|
||||||
|
|
||||||
|
private Json json;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ProductOrderToJson(Json json) {
|
||||||
|
this.json = json;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
|
||||||
|
ProductOrder order = ProductOrder.class.cast(input);
|
||||||
|
request.setPayload(buildJson(order));
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a Json string suitable for sending to the softlayer api
|
||||||
|
* @param order
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String buildJson(ProductOrder order) {
|
||||||
|
|
||||||
|
Iterable<Price> prices = Iterables.transform(order.getPrices(),
|
||||||
|
new Function<ProductItemPrice,Price>() {
|
||||||
|
@Override
|
||||||
|
public Price apply(ProductItemPrice productItemPrice) {
|
||||||
|
return new Price(productItemPrice.getId());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Iterable<HostnameAndDomain> hosts = Iterables.transform(order.getVirtualGuests(),
|
||||||
|
new Function<VirtualGuest,HostnameAndDomain>() {
|
||||||
|
@Override
|
||||||
|
public HostnameAndDomain apply(VirtualGuest virtualGuest) {
|
||||||
|
return new HostnameAndDomain(virtualGuest.getHostname(),virtualGuest.getDomain());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OrderData data = new OrderData(order.getPackageId(),order.getLocation(),
|
||||||
|
Sets.newLinkedHashSet(prices),Sets.newLinkedHashSet(hosts),
|
||||||
|
order.getQuantity(),order.getUseHourlyPricing());
|
||||||
|
|
||||||
|
return json.toJson(ImmutableMap.of("parameters", ImmutableList.<OrderData>of(data)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class OrderData {
|
||||||
|
private String complexType = "SoftLayer_Container_Product_Order_Virtual_Guest";
|
||||||
|
private long packageId = -1;
|
||||||
|
private String location;
|
||||||
|
private Set<Price> prices;
|
||||||
|
private Set<HostnameAndDomain> virtualGuests;
|
||||||
|
private long quantity;
|
||||||
|
private boolean useHourlyPricing;
|
||||||
|
|
||||||
|
public OrderData( long packageId, String location,
|
||||||
|
Set<Price> prices,Set<HostnameAndDomain> virtualGuests,
|
||||||
|
long quantity, boolean useHourlyPricing ) {
|
||||||
|
this.packageId = packageId;
|
||||||
|
this.location = location;
|
||||||
|
this.prices = prices;
|
||||||
|
this.virtualGuests = virtualGuests;
|
||||||
|
this.quantity = quantity;
|
||||||
|
this.useHourlyPricing = useHourlyPricing;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class HostnameAndDomain {
|
||||||
|
private String hostname;
|
||||||
|
private String domain;
|
||||||
|
|
||||||
|
public HostnameAndDomain(String hostname,String domain) {
|
||||||
|
this.hostname = hostname;
|
||||||
|
this.domain = domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Price {
|
||||||
|
private long id;
|
||||||
|
|
||||||
|
public Price(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,219 @@
|
||||||
|
/**
|
||||||
|
* 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 com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.base.Strings.emptyToNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jason King
|
||||||
|
* @see <a href= "http://sldn.softlayer.com/reference/datatypes/SoftLayer_Container_Product_Order_Virtual_Guest"
|
||||||
|
* />
|
||||||
|
*/
|
||||||
|
public class ProductOrder {
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
private long packageId = -1;
|
||||||
|
private Set<ProductItemPrice> prices = Sets.newLinkedHashSet();
|
||||||
|
private Set<VirtualGuest> virtualGuests = Sets.newLinkedHashSet();
|
||||||
|
private String location;
|
||||||
|
private long quantity;
|
||||||
|
private boolean useHourlyPricing;
|
||||||
|
|
||||||
|
public Builder packageId(long packageId) {
|
||||||
|
this.packageId = packageId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a price to the order
|
||||||
|
* All that is required to send in is the price ID of each item desired to be ordered.
|
||||||
|
* @param prices
|
||||||
|
* The Prices of the item desired to be ordered
|
||||||
|
*/
|
||||||
|
public Builder price(ProductItemPrice prices) {
|
||||||
|
this.prices.add(checkNotNull(prices, "prices"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds multiple prices to the order, overwriting any existing ones
|
||||||
|
* All that is required to send in is the price ID of each item desired to be ordered.
|
||||||
|
* @param prices
|
||||||
|
* The Prices of the items desired to be ordered
|
||||||
|
*/
|
||||||
|
public Builder prices(Iterable<ProductItemPrice> prices) {
|
||||||
|
this.prices = ImmutableSet.<ProductItemPrice> copyOf(checkNotNull(prices, "prices"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a virtualGuest to the order
|
||||||
|
* @param virtualGuest
|
||||||
|
* The virtualGuest to add. Needs domain and hostname.
|
||||||
|
*/
|
||||||
|
public Builder virtualGuest(VirtualGuest virtualGuest) {
|
||||||
|
this.virtualGuests.add(checkNotNull(virtualGuest, "virtualGuest"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder virtualGuests(Iterable<VirtualGuest> virtualGuests) {
|
||||||
|
this.virtualGuests = ImmutableSet.<VirtualGuest> copyOf(checkNotNull(virtualGuests, "virtualGuests"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder location(String location) {
|
||||||
|
this.location = location;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder quantity(long quantity) {
|
||||||
|
this.quantity = quantity;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder useHourlyPricing(Boolean useHourlyPricing) {
|
||||||
|
this.useHourlyPricing = useHourlyPricing;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProductOrder build() {
|
||||||
|
return new ProductOrder(packageId, location,prices, virtualGuests, quantity, useHourlyPricing);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder fromProductOrder(ProductOrder in) {
|
||||||
|
return ProductOrder.builder().packageId(in.getPackageId())
|
||||||
|
.location(in.getLocation())
|
||||||
|
.prices(in.getPrices())
|
||||||
|
.virtualGuests(in.getVirtualGuests())
|
||||||
|
.quantity(in.getQuantity())
|
||||||
|
.useHourlyPricing(in.getUseHourlyPricing());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private long packageId = -1;
|
||||||
|
private String location;
|
||||||
|
private Set<ProductItemPrice> prices = Sets.newLinkedHashSet();
|
||||||
|
private Set<VirtualGuest> virtualGuests = Sets.newLinkedHashSet();
|
||||||
|
private long quantity;
|
||||||
|
private boolean useHourlyPricing;
|
||||||
|
|
||||||
|
// for deserializer
|
||||||
|
ProductOrder() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProductOrder(long packageId, String location, Iterable<ProductItemPrice> prices, Iterable<VirtualGuest> virtualGuest, long quantity, boolean useHourlyPricing) {
|
||||||
|
this.packageId = packageId;
|
||||||
|
this.location = checkNotNull(emptyToNull(location),"location cannot be null or empty:"+location);
|
||||||
|
this.prices = ImmutableSet.<ProductItemPrice> copyOf(checkNotNull(prices, "prices"));
|
||||||
|
this.virtualGuests = ImmutableSet.<VirtualGuest> copyOf(checkNotNull(virtualGuest, "virtualGuest"));
|
||||||
|
this.quantity = quantity;
|
||||||
|
this.useHourlyPricing = useHourlyPricing;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The package id of an order. This is required.
|
||||||
|
*/
|
||||||
|
public long getPackageId() {
|
||||||
|
return packageId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The region keyname or specific location keyname where the order should be provisioned.
|
||||||
|
*/
|
||||||
|
public String getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the item prices in this order.
|
||||||
|
* All that is required to be present is the price ID
|
||||||
|
* @return the prices.
|
||||||
|
*/
|
||||||
|
public Set<ProductItemPrice> getPrices() {
|
||||||
|
return prices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the virtual guests in this order.
|
||||||
|
* @return the the virtual guests.
|
||||||
|
*/
|
||||||
|
public Set<VirtualGuest> getVirtualGuests() {
|
||||||
|
return virtualGuests;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getQuantity() {
|
||||||
|
return quantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getUseHourlyPricing() {
|
||||||
|
return useHourlyPricing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return Builder.fromProductOrder(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
ProductOrder that = (ProductOrder) o;
|
||||||
|
|
||||||
|
if (packageId != that.packageId) return false;
|
||||||
|
if (quantity != that.quantity) return false;
|
||||||
|
if (useHourlyPricing != that.useHourlyPricing) return false;
|
||||||
|
if (location != null ? !location.equals(that.location) : that.location != null)
|
||||||
|
return false;
|
||||||
|
if (prices != null ? !prices.equals(that.prices) : that.prices != null)
|
||||||
|
return false;
|
||||||
|
if (virtualGuests != null ? !virtualGuests.equals(that.virtualGuests) : that.virtualGuests != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = (int) (packageId ^ (packageId >>> 32));
|
||||||
|
result = 31 * result + (location != null ? location.hashCode() : 0);
|
||||||
|
result = 31 * result + (prices != null ? prices.hashCode() : 0);
|
||||||
|
result = 31 * result + (virtualGuests != null ? virtualGuests.hashCode() : 0);
|
||||||
|
result = 31 * result + (int) (quantity ^ (quantity >>> 32));
|
||||||
|
result = 31 * result + (useHourlyPricing ? 1 : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "[packageId=" + packageId + ", location=" + location + ", prices=" + prices
|
||||||
|
+ ", virtualGuests=" + virtualGuests +", quantity=" + quantity + ", useHourlyPricing=" + useHourlyPricing + "]";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jason King
|
||||||
|
* @see <a href= "http://sldn.softlayer.com/reference/datatypes/SoftLayer_Container_Product_Order_Receipt"
|
||||||
|
* />
|
||||||
|
*/
|
||||||
|
public class ProductOrderReceipt implements Comparable<ProductOrderReceipt> {
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
private long orderId = -1;
|
||||||
|
|
||||||
|
public Builder orderId(long orderId) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProductOrderReceipt build() {
|
||||||
|
return new ProductOrderReceipt(orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder fromAddress(ProductOrderReceipt in) {
|
||||||
|
return ProductOrderReceipt.builder().orderId(in.getOrderId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private long orderId = -1;
|
||||||
|
|
||||||
|
// for deserializer
|
||||||
|
ProductOrderReceipt() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProductOrderReceipt(long orderId) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(ProductOrderReceipt arg0) {
|
||||||
|
return new Long(orderId).compareTo(arg0.getOrderId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return unique identifier for the order.
|
||||||
|
*/
|
||||||
|
public long getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return Builder.fromAddress(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + (int) (orderId ^ (orderId >>> 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;
|
||||||
|
ProductOrderReceipt other = (ProductOrderReceipt) obj;
|
||||||
|
if (orderId != other.orderId)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[orderId=" + orderId + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -43,7 +43,31 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
private String domain;
|
||||||
|
private String hostname;
|
||||||
|
|
||||||
|
|
||||||
|
public Builder domain(String domain) {
|
||||||
|
this.domain = domain;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder hostname(String hostname) {
|
||||||
|
this.hostname = hostname;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VirtualGuest build() {
|
||||||
|
return new VirtualGuest(-1, null, true, domain,null,hostname,
|
||||||
|
-1,null,-1, null,-1,null,null,null,
|
||||||
|
true,-1,-1,null,null,null,null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder fromVirtualGuest(VirtualGuest in) {
|
||||||
|
return VirtualGuest.builder()
|
||||||
|
.domain(in.getDomain())
|
||||||
|
.hostname(in.getHostname());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static enum State {
|
public static enum State {
|
||||||
|
@ -389,7 +413,10 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
|
||||||
return false;
|
return false;
|
||||||
} else if (!uuid.equals(other.uuid))
|
} else if (!uuid.equals(other.uuid))
|
||||||
return false;
|
return false;
|
||||||
if (!billingItem.equals(other.billingItem))
|
if (billingItem == null) {
|
||||||
|
if (other.billingItem != null)
|
||||||
|
return false;
|
||||||
|
} else if (!billingItem.equals(other.billingItem))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,24 +18,23 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.softlayer.features;
|
package org.jclouds.softlayer.features;
|
||||||
|
|
||||||
import java.util.Set;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
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.http.filters.BasicAuthentication;
|
||||||
|
import org.jclouds.rest.annotations.BinderParam;
|
||||||
import org.jclouds.rest.annotations.ExceptionParser;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.annotations.QueryParams;
|
import org.jclouds.rest.annotations.QueryParams;
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
|
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
|
||||||
|
import org.jclouds.softlayer.binders.ProductOrderToJson;
|
||||||
|
import org.jclouds.softlayer.domain.ProductOrder;
|
||||||
|
import org.jclouds.softlayer.domain.ProductOrderReceipt;
|
||||||
import org.jclouds.softlayer.domain.VirtualGuest;
|
import org.jclouds.softlayer.domain.VirtualGuest;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import javax.ws.rs.*;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides asynchronous access to VirtualGuest via their REST API.
|
* Provides asynchronous access to VirtualGuest via their REST API.
|
||||||
|
@ -123,4 +122,14 @@ public interface VirtualGuestAsyncClient {
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||||
ListenableFuture<Boolean> cancelService(@PathParam("id") long id);
|
ListenableFuture<Boolean> cancelService(@PathParam("id") long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jclouds.softlayer.features.VirtualGuestClient#orderVirtualGuest
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("/SoftLayer_Product_Order/placeOrder.json")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<ProductOrderReceipt> orderVirtualGuest(@BinderParam(ProductOrderToJson.class)ProductOrder order);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@ import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.jclouds.concurrent.Timeout;
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
import org.jclouds.softlayer.domain.ProductOrder;
|
||||||
|
import org.jclouds.softlayer.domain.ProductOrderReceipt;
|
||||||
import org.jclouds.softlayer.domain.VirtualGuest;
|
import org.jclouds.softlayer.domain.VirtualGuest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,4 +100,13 @@ public interface VirtualGuestClient {
|
||||||
* @return true or false
|
* @return true or false
|
||||||
*/
|
*/
|
||||||
boolean cancelService(long id);
|
boolean cancelService(long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this method for placing server orders and additional services orders.
|
||||||
|
* @param order
|
||||||
|
* Details required to order.
|
||||||
|
* @return A receipt for the order
|
||||||
|
* @see <a href="http://sldn.softlayer.com/reference/services/SoftLayer_Product_Order/placeOrder" />
|
||||||
|
*/
|
||||||
|
ProductOrderReceipt orderVirtualGuest(ProductOrder order);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
package org.jclouds.softlayer.reference;
|
package org.jclouds.softlayer.reference;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Sets;
|
import org.jclouds.softlayer.domain.ProductItemPrice;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -34,16 +34,16 @@ public interface SoftLayerConstants {
|
||||||
*/
|
*/
|
||||||
public static final String PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME = "jclouds.softlayer.virtualguest.package-name";
|
public static final String PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME = "jclouds.softlayer.virtualguest.package-name";
|
||||||
|
|
||||||
public static final Set<Long> DEFAULT_VIRTUAL_GUEST_PRICES = ImmutableSet.<Long>builder()
|
public static final Set<ProductItemPrice> DEFAULT_VIRTUAL_GUEST_PRICES = ImmutableSet.<ProductItemPrice>builder()
|
||||||
.add(1639L) // 100 GB (SAN)
|
.add(ProductItemPrice.builder().id(1639L).build()) // 100 GB (SAN)
|
||||||
.add(21L) // 1 IP Address
|
.add(ProductItemPrice.builder().id(21L).build()) // 1 IP Address
|
||||||
.add(55L) // Host Ping
|
.add(ProductItemPrice.builder().id(55L).build()) // Host Ping
|
||||||
.add(58L) // Automated Notification
|
.add(ProductItemPrice.builder().id(58L).build()) // Automated Notification
|
||||||
.add(1800L) // 0 GB Bandwidth
|
.add(ProductItemPrice.builder().id(1800L).build()) // 0 GB Bandwidth
|
||||||
.add(57L) // Email and Ticket
|
.add(ProductItemPrice.builder().id(57L).build()) // Email and Ticket
|
||||||
.add(274L) // 1000 Mbps Public & Private Networks
|
.add(ProductItemPrice.builder().id(274L).build()) // 1000 Mbps Public & Private Networks
|
||||||
.add(905L) // Reboot / Remote Console
|
.add(ProductItemPrice.builder().id(905L).build()) // Reboot / Remote Console
|
||||||
.add(418L) // Nessus Vulnerability Assessment & Reporting
|
.add(ProductItemPrice.builder().id(418L).build()) // Nessus Vulnerability Assessment & Reporting
|
||||||
.add(420L) // Unlimited SSL VPN Users & 1 PPTP VPN User per account
|
.add(ProductItemPrice.builder().id(420L).build()) // Unlimited SSL VPN Users & 1 PPTP VPN User per account
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,11 +147,11 @@ public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest {
|
||||||
@Test
|
@Test
|
||||||
public void testPricesForLaunchingGuestVM() {
|
public void testPricesForLaunchingGuestVM() {
|
||||||
Iterable<ProductItem> ramItems = Iterables.filter(cloudServerProductPackage.getItems(),
|
Iterable<ProductItem> ramItems = Iterables.filter(cloudServerProductPackage.getItems(),
|
||||||
Predicates.and(categoryCode("ram"), capacity(1.0f)));
|
Predicates.and(categoryCode("ram"), capacity(2.0f)));
|
||||||
|
|
||||||
Map<Float, ProductItem> ramToProductItem = Maps.uniqueIndex(ramItems, ProductItems.capacity());
|
Map<Float, ProductItem> ramToProductItem = Maps.uniqueIndex(ramItems, ProductItems.capacity());
|
||||||
|
|
||||||
ProductItemPrice ramPrice = ProductItems.price().apply(ramToProductItem.get(1.0f));
|
ProductItemPrice ramPrice = ProductItems.price().apply(ramToProductItem.get(2.0f));
|
||||||
|
|
||||||
Iterable<ProductItem> cpuItems = Iterables.filter(cloudServerProductPackage.getItems(), Predicates.and(units("PRIVATE_CORE"), capacity(2.0f)));
|
Iterable<ProductItem> cpuItems = Iterables.filter(cloudServerProductPackage.getItems(), Predicates.and(units("PRIVATE_CORE"), capacity(2.0f)));
|
||||||
Map<Float, ProductItem> coresToProductItem = Maps.uniqueIndex(cpuItems, ProductItems.capacity());
|
Map<Float, ProductItem> coresToProductItem = Maps.uniqueIndex(cpuItems, ProductItems.capacity());
|
||||||
|
@ -162,13 +162,27 @@ public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest {
|
||||||
Map<String, ProductItem> osToProductItem = Maps.uniqueIndex(operatingSystems, ProductItems.description());
|
Map<String, ProductItem> osToProductItem = Maps.uniqueIndex(operatingSystems, ProductItems.description());
|
||||||
ProductItemPrice osPrice = ProductItems.price().apply(osToProductItem.get("Ubuntu Linux 8 LTS Hardy Heron - Minimal Install (64 bit)"));
|
ProductItemPrice osPrice = ProductItems.price().apply(osToProductItem.get("Ubuntu Linux 8 LTS Hardy Heron - Minimal Install (64 bit)"));
|
||||||
|
|
||||||
Set<Long> prices = Sets.<Long>newLinkedHashSet();
|
Set<ProductItemPrice> prices = Sets.<ProductItemPrice>newLinkedHashSet();
|
||||||
prices.addAll(SoftLayerConstants.DEFAULT_VIRTUAL_GUEST_PRICES);
|
prices.addAll(SoftLayerConstants.DEFAULT_VIRTUAL_GUEST_PRICES);
|
||||||
prices.add(ramPrice.getId());
|
prices.add(ramPrice);
|
||||||
prices.add(cpuPrice.getId());
|
prices.add(cpuPrice);
|
||||||
prices.add(osPrice.getId());
|
prices.add(osPrice);
|
||||||
|
|
||||||
//This should be everything needed to launch Ubuntu Hardy Heron with 1GB Ram and 2 CPU Cores
|
VirtualGuest guest = VirtualGuest.builder().domain("jclouds.org")
|
||||||
|
.hostname("livetest")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
String location = ""+Iterables.get(cloudServerProductPackage.getDatacenters(),0).getId();
|
||||||
|
ProductOrder order = ProductOrder.builder()
|
||||||
|
.packageId(cloudServerPackageId)
|
||||||
|
.location(location)
|
||||||
|
.quantity(1)
|
||||||
|
.useHourlyPricing(true)
|
||||||
|
.prices(prices)
|
||||||
|
.virtualGuest(guest)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//ProductOrderReceipt receipt = context.getApi().getVirtualGuestClient().orderVirtualGuest(order);
|
||||||
//TODO: There must be a more concise way of expressing this logic.
|
//TODO: There must be a more concise way of expressing this logic.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,9 @@ public class VirtualGuestClientLiveTest extends BaseSoftLayerClientLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkVirtualGuest(VirtualGuest vg) {
|
private void checkVirtualGuest(VirtualGuest vg) {
|
||||||
|
if (vg.getBillingItem()==null) return;//Quotes and shutting down guests
|
||||||
|
checkBillingItem(vg.getBillingItem());
|
||||||
|
|
||||||
assert vg.getAccountId() > 0 : vg;
|
assert vg.getAccountId() > 0 : vg;
|
||||||
assert vg.getCreateDate() != null : vg;
|
assert vg.getCreateDate() != null : vg;
|
||||||
assert vg.getDomain() != null : vg;
|
assert vg.getDomain() != null : vg;
|
||||||
|
@ -72,8 +75,6 @@ public class VirtualGuestClientLiveTest extends BaseSoftLayerClientLiveTest {
|
||||||
assert vg.getUuid() != null : vg;
|
assert vg.getUuid() != null : vg;
|
||||||
assert vg.getPrimaryBackendIpAddress() != null : vg;
|
assert vg.getPrimaryBackendIpAddress() != null : vg;
|
||||||
assert vg.getPrimaryIpAddress() != null : vg;
|
assert vg.getPrimaryIpAddress() != null : vg;
|
||||||
|
|
||||||
checkBillingItem(vg.getBillingItem());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkBillingItem(BillingItemVirtualGuest billingItem) {
|
private void checkBillingItem(BillingItemVirtualGuest billingItem) {
|
||||||
|
|
Loading…
Reference in New Issue