http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/features/HostedServiceApi.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/features/HostedServiceApi.java b/azurecompute/src/main/java/org/jclouds/azurecompute/features/HostedServiceApi.java new file mode 100644 index 0000000..9e6b9a2 --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/features/HostedServiceApi.java @@ -0,0 +1,157 @@ +/* + * 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.azurecompute.features; + +import java.util.List; +import javax.inject.Named; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import org.jclouds.azurecompute.binders.BindCreateHostedServiceToXmlPayload; +import org.jclouds.azurecompute.domain.HostedService; +import org.jclouds.azurecompute.domain.HostedServiceWithDetailedProperties; +import org.jclouds.azurecompute.functions.ParseRequestIdHeader; +import org.jclouds.azurecompute.options.CreateHostedServiceOptions; +import org.jclouds.azurecompute.xml.HostedServiceHandler; +import org.jclouds.azurecompute.xml.HostedServiceWithDetailedPropertiesHandler; +import org.jclouds.azurecompute.xml.ListHostedServicesHandler; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.MapBinder; +import org.jclouds.rest.annotations.PayloadParam; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.XMLResponseParser; + +import static org.jclouds.Fallbacks.EmptyListOnNotFoundOr404; +import static org.jclouds.Fallbacks.NullOnNotFoundOr404; + +/** + * The Service Management API includes operations for managing the hosted services beneath your + * subscription. + * + * @see <a href="http://msdn.microsoft.com/en-us/library/ee460812">docs</a> + */ +@Path("/services/hostedservices") +@Headers(keys = "x-ms-version", values = "{jclouds.api-version}") +@Consumes(MediaType.APPLICATION_XML) +public interface HostedServiceApi { + + /** + * The List Hosted Services operation lists the hosted services available under the current + * subscription. + * + * @return the response object + */ + @Named("ListHostedServices") + @GET + @XMLResponseParser(ListHostedServicesHandler.class) + @Fallback(EmptyListOnNotFoundOr404.class) + List<HostedServiceWithDetailedProperties> list(); + + /** + * The Create Hosted Service operation creates a new hosted service in Windows Azure. + * + * @param name + * A name for the hosted service that is unique within Windows Azure. This name is the + * DNS prefix name and can be used to access the hosted service. + * + * For example: http://name.cloudapp.net// + * @param label + * The name can be used identify the storage account for your tracking purposes. The + * name can be up to 100 characters in length. + * @param location + * The location where the hosted service will be created. + * @return the requestId to track this async request progress + * + * @see <a href="http://msdn.microsoft.com/en-us/library/ee460812">docs</a> + */ + @Named("CreateHostedService") + @POST + @MapBinder(BindCreateHostedServiceToXmlPayload.class) + @Produces(MediaType.APPLICATION_XML) + @ResponseParser(ParseRequestIdHeader.class) + String createServiceWithLabelInLocation(@PayloadParam("name") String name, + @PayloadParam("label") String label, @PayloadParam("location") String location); + + /** + * same as {@link #createServiceWithLabelInLocation(String, String, String)} , except you can + * specify optional parameters such as extended properties or a description. + * + * @param options + * parameters such as extended properties or a description. + */ + @Named("CreateHostedService") + @POST + @MapBinder(BindCreateHostedServiceToXmlPayload.class) + @Produces(MediaType.APPLICATION_XML) + @ResponseParser(ParseRequestIdHeader.class) + String createServiceWithLabelInLocation(@PayloadParam("name") String name, + @PayloadParam("label") String label, @PayloadParam("location") String location, + @PayloadParam("options") CreateHostedServiceOptions options); + + /** + * The Get Hosted Service Properties operation retrieves system properties for the specified + * hosted service. These properties include the service name and service type; the name of the + * affinity group to which the service belongs, or its location if it is not part of an affinity + * group. + * + * @param name + * the unique DNS Prefix value in the Windows Azure Management Portal + */ + @Named("GetHostedServiceProperties") + @GET + @Path("/{name}") + @XMLResponseParser(HostedServiceHandler.class) + @Fallback(NullOnNotFoundOr404.class) + HostedService get(@PathParam("name") String name); + + /** + * like {@link #get(String)}, except additional data such as status and deployment information is + * returned. + * + * @param name + * the unique DNS Prefix value in the Windows Azure Management Portal + */ + @Named("GetHostedServiceProperties") + @GET + @Path("/{name}") + @QueryParams(keys = "embed-detail", values = "true") + @XMLResponseParser(HostedServiceWithDetailedPropertiesHandler.class) + @Fallback(NullOnNotFoundOr404.class) + HostedServiceWithDetailedProperties getDetails(@PathParam("name") String name); + + /** + * The Delete Hosted Service operation deletes the specified hosted service from Windows Azure. + * + * @param name + * the unique DNS Prefix value in the Windows Azure Management Portal + * + * @return request id or null, if not found + */ + @Named("DeleteHostedService") + @DELETE + @Path("/{name}") + @Fallback(NullOnNotFoundOr404.class) + @ResponseParser(ParseRequestIdHeader.class) + String delete(@PathParam("name") String name); +}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/features/ImageApi.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/features/ImageApi.java b/azurecompute/src/main/java/org/jclouds/azurecompute/features/ImageApi.java new file mode 100644 index 0000000..cdf7029 --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/features/ImageApi.java @@ -0,0 +1,99 @@ +/* + * 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.azurecompute.features; + +import java.util.List; +import javax.inject.Named; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import org.jclouds.azurecompute.binders.BindOSImageParamsToXmlPayload; +import org.jclouds.azurecompute.domain.Image; +import org.jclouds.azurecompute.domain.ImageParams; +import org.jclouds.azurecompute.functions.ImageParamsName; +import org.jclouds.azurecompute.functions.ParseRequestIdHeader; +import org.jclouds.azurecompute.xml.ListImagesHandler; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.ParamParser; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.XMLResponseParser; + +import static org.jclouds.Fallbacks.EmptyListOnNotFoundOr404; +import static org.jclouds.Fallbacks.NullOnNotFoundOr404; + +/** + * The Service Management API includes operations for managing the OS images in your subscription. + * + * @see <a href="http://msdn.microsoft.com/en-us/library/jj157175">docs</a> + */ +@Path("/services/images") +@Headers(keys = "x-ms-version", values = "{jclouds.api-version}") +@Consumes(MediaType.APPLICATION_XML) +public interface ImageApi { + + /** + * The List Hosted Services operation lists the hosted services available under the current + * subscription. + */ + @Named("ListImages") + @GET + @XMLResponseParser(ListImagesHandler.class) + @Fallback(EmptyListOnNotFoundOr404.class) + List<Image> list(); + + /** + * The Add OS Image operation adds an OS image that is currently stored in a storage account in your subscription to + * the image repository. + */ + @Named("AddImage") + @POST + @Produces(MediaType.APPLICATION_XML) + @ResponseParser(ParseRequestIdHeader.class) + String add(@BinderParam(BindOSImageParamsToXmlPayload.class) ImageParams params); + + /** + * The Update OS Image operation updates an OS image that in your image repository. + */ + @Named("UpdateImage") + @PUT + @Path("/{imageName}") + @Produces(MediaType.APPLICATION_XML) + @ResponseParser(ParseRequestIdHeader.class) + String update(@PathParam("imageName") @ParamParser(ImageParamsName.class) + @BinderParam(BindOSImageParamsToXmlPayload.class) ImageParams params); + + /** + * The Delete Hosted Service operation deletes the specified hosted service from Windows Azure. + * + * @param imageName + * the unique DNS Prefix value in the Windows Azure Management Portal + */ + @Named("DeleteImage") + @DELETE + @Path("/{imageName}") + @Fallback(NullOnNotFoundOr404.class) + @ResponseParser(ParseRequestIdHeader.class) + String delete(@PathParam("imageName") String imageName); +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/features/LocationApi.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/features/LocationApi.java b/azurecompute/src/main/java/org/jclouds/azurecompute/features/LocationApi.java new file mode 100644 index 0000000..1621139 --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/features/LocationApi.java @@ -0,0 +1,54 @@ +/* + * 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.azurecompute.features; + +import java.util.List; +import javax.inject.Named; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.core.MediaType; +import org.jclouds.azurecompute.domain.Location; +import org.jclouds.azurecompute.xml.ListLocationsHandler; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.XMLResponseParser; + +import static org.jclouds.Fallbacks.EmptyListOnNotFoundOr404; + +/** + * The Service Management API includes operations for listing the available data center locations + * for a hosted service in your subscription. + * <p/> + * + * @see <a href="http://msdn.microsoft.com/en-us/library/gg441299" /> + */ +@Path("/locations") +@Headers(keys = "x-ms-version", values = "{jclouds.api-version}") +@Consumes(MediaType.APPLICATION_XML) +public interface LocationApi { + + /** + * The List Locations operation lists all of the data center locations that are valid for your + * subscription. + */ + @Named("ListLocations") + @GET + @XMLResponseParser(ListLocationsHandler.class) + @Fallback(EmptyListOnNotFoundOr404.class) + List<Location> list(); +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/features/OperationApi.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/features/OperationApi.java b/azurecompute/src/main/java/org/jclouds/azurecompute/features/OperationApi.java new file mode 100644 index 0000000..5ee97a6 --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/features/OperationApi.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.azurecompute.features; + +import javax.inject.Named; +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.azurecompute.domain.Operation; +import org.jclouds.azurecompute.xml.OperationHandler; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.XMLResponseParser; + +import static org.jclouds.Fallbacks.NullOnNotFoundOr404; + +/** + * The Service Management API includes one operation for tracking the progress of asynchronous requests. + * + * @see <a href="http://msdn.microsoft.com/en-us/library/ee460796">docs</a> + */ +@Headers(keys = "x-ms-version", values = "{jclouds.api-version}") +@Consumes(MediaType.APPLICATION_XML) +public interface OperationApi { + + @Named("GetOperation") + @GET + @Path("/operations/{request-id}") + @XMLResponseParser(OperationHandler.class) + @Fallback(NullOnNotFoundOr404.class) + Operation get(@PathParam("request-id") String requestId); +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/features/VirtualMachineApi.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/features/VirtualMachineApi.java b/azurecompute/src/main/java/org/jclouds/azurecompute/features/VirtualMachineApi.java new file mode 100644 index 0000000..5067029 --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/features/VirtualMachineApi.java @@ -0,0 +1,87 @@ +/* + * 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.azurecompute.features; + +import javax.inject.Named; +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import org.jclouds.azurecompute.functions.ParseRequestIdHeader; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.Payload; +import org.jclouds.rest.annotations.PayloadParam; +import org.jclouds.rest.annotations.ResponseParser; + +/** + * The Service Management API includes operations for managing the virtual + * machines in your subscription. + * + * @see <a href="http://msdn.microsoft.com/en-us/library/jj157206">docs</a> + */ +@Path("/services/hostedservices/{serviceName}/deployments/{deploymentName}/roleinstances") +@Headers(keys = "x-ms-version", values = "{jclouds.api-version}") +@Consumes(MediaType.APPLICATION_XML) +// NOTE: MS Docs refer to the commands as Role, but in the description, it is always Virtual Machine. +public interface VirtualMachineApi { + + @Named("RestartRole") + @POST + // Warning : the url in the documentation is WRONG ! @see + // http://social.msdn.microsoft.com/Forums/pl-PL/WAVirtualMachinesforWindows/thread/7ba2367b-e450-49e0-89e4-46c240e9d213 + @Path("/{name}/Operations") + @Produces(MediaType.APPLICATION_XML) + @ResponseParser(ParseRequestIdHeader.class) + @Payload(value = "<RestartRoleOperation xmlns=\"http://schemas.microsoft.com/windowsazure\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><OperationType>RestartRoleOperation</OperationType></RestartRoleOperation>") + String restart(@PathParam("name") String name); + + /** + * http://msdn.microsoft.com/en-us/library/jj157201 + */ + @Named("CaptureRole") + @POST + @Path("/{name}/Operations") + @Produces(MediaType.APPLICATION_XML) + @ResponseParser(ParseRequestIdHeader.class) + @Payload(value = "<CaptureRoleOperation xmlns=\"http://schemas.microsoft.com/windowsazure\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><OperationType>CaptureRoleOperation</OperationType><PostCaptureAction>Delete</PostCaptureAction><TargetImageLabel>{imageLabel}</TargetImageLabel><TargetImageName>{imageName}</TargetImageName></CaptureRoleOperation>") + String capture(@PathParam("name") String name, @PayloadParam("imageName") String imageName, + @PayloadParam("imageLabel") String imageLabel); + + /** + * http://msdn.microsoft.com/en-us/library/jj157195 + */ + @Named("ShutdownRole") + @POST + @Path("/{name}/Operations") + @Produces(MediaType.APPLICATION_XML) + @ResponseParser(ParseRequestIdHeader.class) + @Payload(value = "<ShutdownRoleOperation xmlns=\"http://schemas.microsoft.com/windowsazure\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><OperationType>ShutdownRoleOperation</OperationType></ShutdownRoleOperation>") + String shutdown(@PathParam("name") String name); + + /** + * http://msdn.microsoft.com/en-us/library/jj157189 + */ + @Named("StartRole") + @POST + @Path("/{name}/Operations") + @Produces(MediaType.APPLICATION_XML) + @ResponseParser(ParseRequestIdHeader.class) + @Payload(value = "<StartRoleOperation xmlns=\"http://schemas.microsoft.com/windowsazure\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><OperationType>StartRoleOperation</OperationType></StartRoleOperation>") + String start(@PathParam("name") String name); +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/functions/ImageParamsName.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/functions/ImageParamsName.java b/azurecompute/src/main/java/org/jclouds/azurecompute/functions/ImageParamsName.java new file mode 100644 index 0000000..077b63c --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/functions/ImageParamsName.java @@ -0,0 +1,34 @@ +/* + * 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.azurecompute.functions; + +import com.google.common.base.Function; +import javax.inject.Singleton; +import org.jclouds.azurecompute.domain.ImageParams; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +@Singleton +public class ImageParamsName implements Function<Object, String> { + @Override + public String apply(Object input) { + checkArgument(checkNotNull(input, "input") instanceof ImageParams, + "this function is only valid for ImageParams!"); + return checkNotNull(ImageParams.class.cast(input), "ImageParams").getName(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/functions/ParseRequestIdHeader.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/functions/ParseRequestIdHeader.java b/azurecompute/src/main/java/org/jclouds/azurecompute/functions/ParseRequestIdHeader.java new file mode 100644 index 0000000..2a0d5aa --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/functions/ParseRequestIdHeader.java @@ -0,0 +1,44 @@ +/* + * 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.azurecompute.functions; + +import com.google.common.base.Function; +import javax.inject.Singleton; +import org.jclouds.http.HttpResponse; + +import static org.jclouds.http.HttpUtils.releasePayload; + +/** + * Parses an x-ms-request-id the header + * + * A value that uniquely identifies a request made against the management service. For an + * asynchronous operation, you can call get operation status with the value of the header to + * determine whether the operation is complete, has failed, or is still in progress. + */ +@Singleton +public class ParseRequestIdHeader implements Function<HttpResponse, String> { + + public String apply(HttpResponse from) { + releasePayload(from); + String requestId = from.getFirstHeaderOrNull("x-ms-request-id"); + if (requestId != null) { + return requestId; + } + throw new IllegalStateException("did not receive RequestId in: " + from); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/options/CreateHostedServiceOptions.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/options/CreateHostedServiceOptions.java b/azurecompute/src/main/java/org/jclouds/azurecompute/options/CreateHostedServiceOptions.java new file mode 100644 index 0000000..b4c49eb --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/options/CreateHostedServiceOptions.java @@ -0,0 +1,116 @@ +/* + * 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.azurecompute.options; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; +import com.google.common.base.Optional; +import java.util.Map; + +/** + * Optional parameters for creating a hosted service + * + * @see <a href="http://msdn.microsoft.com/en-us/library/gg441304" >docs</a> + */ +public class CreateHostedServiceOptions implements Cloneable { + + private Optional<String> description = Optional.absent(); + private Optional<Map<String, String>> extendedProperties = Optional.absent(); + + /** + * @see CreateHostedServiceOptions#getDescription() + */ + public CreateHostedServiceOptions description(String description) { + this.description = Optional.fromNullable(description); + return this; + } + + /** + * @see CreateHostedServiceOptions#getExtendedProperties() + */ + public CreateHostedServiceOptions extendedProperties(Map<String, String> extendedProperties) { + this.extendedProperties = Optional.fromNullable(extendedProperties); + return this; + } + + /** + * A description for the hosted service. The description can be up to 1024 characters in length. + */ + public Optional<String> getDescription() { + return description; + } + + /** + * Represents the name of an extended hosted service property. Each extended property must have + * both a defined name and value. You can have a maximum of 50 extended property name/value + * pairs. + * + * The maximum length of the Name element is 64 characters, only alphanumeric characters and + * underscores are valid in the Name, and the name must start with a letter. Each extended + * property value has a maximum length of 255 characters. + */ + public Optional<Map<String, String>> getExtendedProperties() { + return extendedProperties; + } + + public static class Builder { + + /** + * @see CreateHostedServiceOptions#getDescription() + */ + public static CreateHostedServiceOptions description(String description) { + return new CreateHostedServiceOptions().description(description); + } + + /** + * @see CreateHostedServiceOptions#getExtendedProperties() + */ + public static CreateHostedServiceOptions extendedProperties(Map<String, String> extendedProperties) { + return new CreateHostedServiceOptions().extendedProperties(extendedProperties); + } + } + + @Override + public CreateHostedServiceOptions clone() { + return new CreateHostedServiceOptions().description(description.orNull()).extendedProperties( + extendedProperties.orNull()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CreateHostedServiceOptions other = CreateHostedServiceOptions.class.cast(obj); + return Objects.equal(this.description, other.description) + && Objects.equal(this.extendedProperties, other.extendedProperties); + } + + @Override + public int hashCode() { + return Objects.hashCode(description, extendedProperties); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper("").omitNullValues().add("description", description.orNull()) + .add("extendedProperties", extendedProperties.orNull()).toString(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/KeyStoreSupplier.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/KeyStoreSupplier.java b/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/KeyStoreSupplier.java new file mode 100644 index 0000000..d4955e1 --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/KeyStoreSupplier.java @@ -0,0 +1,129 @@ +/* + * 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.azurecompute.suppliers; + +import com.google.common.base.Charsets; +import com.google.common.base.Supplier; +import com.google.common.io.ByteSource; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.util.Collection; +import javax.inject.Inject; +import javax.inject.Singleton; +import org.jclouds.crypto.Crypto; +import org.jclouds.crypto.Pems; +import org.jclouds.domain.Credentials; +import org.jclouds.location.Provider; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Throwables.propagate; + +/** + * TODO this code needs to be completely refactored. It needs to stop using KeyStore of at all possible and definitely + * the local filesystem. Please look at oauth for examples on how to do this via PEMs. + */ +@Deprecated +@Singleton +public class KeyStoreSupplier implements Supplier<KeyStore> { + private final Crypto crypto; + private final Supplier<Credentials> creds; + + @Inject + KeyStoreSupplier(Crypto crypto, @Provider Supplier<Credentials> creds) { + this.crypto = crypto; + this.creds = creds; + } + + @Override + public KeyStore get() { + Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null"); + String cert = checkNotNull(currentCreds.identity, "credential supplier returned null identity (should be cert)"); + String keyStorePassword = checkNotNull(currentCreds.credential, + "credential supplier returned null credential (should be keyStorePassword)"); + try { + KeyStore keyStore = KeyStore.getInstance("PKCS12"); + + File certFile = new File(checkNotNull(cert)); + if (certFile.isFile()) { // cert is path to pkcs12 file + FileInputStream stream = new FileInputStream(certFile); + try { + keyStore.load(stream, keyStorePassword.toCharArray()); + } finally { + stream.close(); + } + } else { // cert is PEM encoded, containing private key and certs + + // split in private key and certs + int privateKeyBeginIdx = cert.indexOf("-----BEGIN PRIVATE KEY"); + int privateKeyEndIdx = cert.indexOf("-----END PRIVATE KEY"); + String pemPrivateKey = cert.substring(privateKeyBeginIdx, privateKeyEndIdx + 26); + + StringBuilder pemCerts = new StringBuilder(); + int certsBeginIdx = 0; + + do { + certsBeginIdx = cert.indexOf("-----BEGIN CERTIFICATE", certsBeginIdx); + + if (certsBeginIdx >= 0) { + int certsEndIdx = cert.indexOf("-----END CERTIFICATE", certsBeginIdx) + 26; + pemCerts.append(cert.substring(certsBeginIdx, certsEndIdx)); + certsBeginIdx = certsEndIdx; + } + } while (certsBeginIdx != -1); + + // parse private key + KeySpec keySpec = Pems.privateKeySpec(ByteSource.wrap(pemPrivateKey.getBytes(Charsets.UTF_8))); + PrivateKey privateKey = crypto.rsaKeyFactory().generatePrivate(keySpec); + + // populate keystore with private key and certs + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + @SuppressWarnings("unchecked") + Collection<Certificate> certs = (Collection<Certificate>) cf.generateCertificates(new ByteArrayInputStream( + pemCerts.toString().getBytes(Charsets.UTF_8))); + keyStore.load(null); + keyStore.setKeyEntry("dummy", privateKey, keyStorePassword.toCharArray(), + certs.toArray(new java.security.cert.Certificate[0])); + + } + return keyStore; + } catch (NoSuchAlgorithmException e) { + throw propagate(e); + } catch (KeyStoreException e) { + throw propagate(e); + } catch (CertificateException e) { + throw propagate(e); + } catch (FileNotFoundException e) { + throw propagate(e); + } catch (IOException e) { + throw propagate(e); + } catch (InvalidKeySpecException e) { + throw propagate(e); + } + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/SSLContextWithKeysSupplier.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/SSLContextWithKeysSupplier.java b/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/SSLContextWithKeysSupplier.java new file mode 100644 index 0000000..1936bf8 --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/SSLContextWithKeysSupplier.java @@ -0,0 +1,80 @@ +/* + * 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.azurecompute.suppliers; + +import com.google.common.base.Supplier; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.UnrecoverableKeyException; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import org.jclouds.domain.Credentials; +import org.jclouds.http.HttpUtils; +import org.jclouds.http.config.SSLModule.TrustAllCerts; +import org.jclouds.location.Provider; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Throwables.propagate; + +/** + * TODO this code needs to be completely refactored. It needs to stop using KeyStore of at all possible and definitely + * the local filesystem. Please look at oauth for examples on how to do this via PEMs. + */ +@Deprecated +@Singleton +public class SSLContextWithKeysSupplier implements Supplier<SSLContext> { + private final Supplier<KeyStore> keyStore; + private final TrustManager[] trustManager; + private final Supplier<Credentials> creds; + + @Inject + SSLContextWithKeysSupplier(Supplier<KeyStore> keyStore, @Provider Supplier<Credentials> creds, HttpUtils utils, + TrustAllCerts trustAllCerts) { + this.keyStore = keyStore; + this.trustManager = utils.trustAllCerts() ? new TrustManager[] { trustAllCerts } : null; + this.creds = creds; + } + + @Override + public SSLContext get() { + Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null"); + String keyStorePassword = checkNotNull(currentCreds.credential, + "credential supplier returned null credential (should be keyStorePassword)"); + KeyManagerFactory kmf; + try { + kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(keyStore.get(), keyStorePassword.toCharArray()); + SSLContext sc = SSLContext.getInstance("TLS"); + sc.init(kmf.getKeyManagers(), trustManager, new SecureRandom()); + return sc; + } catch (NoSuchAlgorithmException e) { + throw propagate(e); + } catch (UnrecoverableKeyException e) { + throw propagate(e); + } catch (KeyStoreException e) { + throw propagate(e); + } catch (KeyManagementException e) { + throw propagate(e); + } + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/xml/AttachmentHandler.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/AttachmentHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/AttachmentHandler.java new file mode 100644 index 0000000..648cf26 --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/AttachmentHandler.java @@ -0,0 +1,58 @@ +/* + * 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.azurecompute.xml; + +import org.jclouds.azurecompute.domain.Disk.Attachment; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.util.SaxUtils; +import org.xml.sax.SAXException; + +/** + * @see <a href="http://msdn.microsoft.com/en-us/library/jj157176" >api</a> + */ +public class AttachmentHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Attachment> { + + private StringBuilder currentText = new StringBuilder(); + private Attachment.Builder builder = Attachment.builder(); + + @Override + public Attachment getResult() { + try { + return builder.build(); + } finally { + builder = Attachment.builder(); + } + } + + @Override + public void endElement(String uri, String name, String qName) throws SAXException { + if (qName.equals("HostedServiceName")) { + builder.hostedService(SaxUtils.currentOrNull(currentText)); + } else if (qName.equals("DeploymentName")) { + builder.deployment(SaxUtils.currentOrNull(currentText)); + } else if (qName.equals("RoleName")) { + builder.role(SaxUtils.currentOrNull(currentText)); + } + currentText.setLength(0); + } + + @Override + public void characters(char ch[], int start, int length) { + currentText.append(ch, start, length); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DeploymentHandler.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DeploymentHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DeploymentHandler.java new file mode 100644 index 0000000..8d92c72 --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DeploymentHandler.java @@ -0,0 +1,115 @@ +/* + * 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.azurecompute.xml; + +import com.google.common.collect.Lists; +import java.net.URI; +import java.util.List; +import org.jclouds.azurecompute.domain.Deployment; +import org.jclouds.azurecompute.domain.DeploymentSlot; +import org.jclouds.azurecompute.domain.DeploymentStatus; +import org.jclouds.azurecompute.domain.InstanceStatus; +import org.jclouds.azurecompute.domain.RoleSize; +import org.jclouds.http.functions.ParseSax; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; + +import static com.google.common.base.Charsets.UTF_8; +import static com.google.common.io.BaseEncoding.base64; +import static org.jclouds.util.SaxUtils.currentOrNull; +import static org.jclouds.util.SaxUtils.equalsOrSuffix; + +/** + * @see <a href="http://msdn.microsoft.com/en-us/library/ee460804" >api</a> + */ +public class DeploymentHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Deployment> { + + private List<String> elements = Lists.newArrayList(); + private StringBuilder currentText = new StringBuilder(); + private Deployment.Builder builder = Deployment.builder(); + + @Override + public Deployment getResult() { + try { + return builder.build(); + } finally { + builder = Deployment.builder(); + } + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + elements.add(qName); + } + + @Override + public void endElement(String uri, String name, String qName) throws SAXException { + if (equalsOrSuffix(qName, "Name") && "Deployment".equals(elements.get(elements.size() - 2))) { + builder.deploymentName(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "DeploymentSlot")) { + final String dpltSlot = currentOrNull(currentText); + if (dpltSlot != null) { + builder.deploymentSlot(DeploymentSlot.fromValue(dpltSlot)); + } + } else if (equalsOrSuffix(qName, "Status")) { + String deploymentStatus = currentOrNull(currentText); + if (deploymentStatus != null) { + builder.deploymentStatus(DeploymentStatus.fromValue(deploymentStatus)); + } + } else if (equalsOrSuffix(qName, "Label")) { + String label = currentOrNull(currentText); + if (label != null) { + builder.deploymentLabel(new String(base64().decode(label), UTF_8)); + } + } else if (equalsOrSuffix(qName, "Url")) { + final String url = currentOrNull(currentText); + if (url != null) { + builder.deploymentURL(URI.create(url)); + } + } else if (equalsOrSuffix(qName, "RoleName")) { + builder.roleName(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "InstanceName")) { + builder.instanceName(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "InstanceStatus")) { + String instanceStatus = currentOrNull(currentText); + if (instanceStatus != null) { + builder.instanceStatus(InstanceStatus.fromValue(instanceStatus)); + } + } else if (equalsOrSuffix(qName, "InstanceStateDetails")) { + builder.instanceStateDetails(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "InstanceErrorCode")) { + builder.instanceErrorCode(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "InstanceSize")) { + String instanceSize = currentOrNull(currentText); + if (instanceSize != null) { + builder.instanceSize(RoleSize.fromValue(instanceSize)); + } + } else if (equalsOrSuffix(qName, "IpAddress")) { + builder.privateIpAddress(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "Vip")) { + builder.publicIpAddress(currentOrNull(currentText)); + } + + currentText.setLength(0); + elements.remove(elements.size() - 1); + } + + @Override + public void characters(char ch[], int start, int length) { + currentText.append(ch, start, length); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DetailedHostedServicePropertiesHandler.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DetailedHostedServicePropertiesHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DetailedHostedServicePropertiesHandler.java new file mode 100644 index 0000000..2986d7d --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DetailedHostedServicePropertiesHandler.java @@ -0,0 +1,73 @@ +/* + * 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.azurecompute.xml; + +import javax.inject.Inject; +import org.jclouds.azurecompute.domain.DetailedHostedServiceProperties; +import org.jclouds.azurecompute.domain.HostedService.Status; +import org.jclouds.date.DateService; +import org.xml.sax.SAXException; + +import static org.jclouds.util.SaxUtils.currentOrNull; +import static org.jclouds.util.SaxUtils.equalsOrSuffix; + +/** + * @see <a href="http://msdn.microsoft.com/en-us/library/gg441293" >api</a> + */ +public class DetailedHostedServicePropertiesHandler extends HostedServicePropertiesHandler { + + private final DateService dateService; + + @Inject + private DetailedHostedServicePropertiesHandler(DateService dateService) { + this.dateService = dateService; + } + + private DetailedHostedServiceProperties.Builder builder = DetailedHostedServiceProperties.builder(); + + private String name; + + @Override + public DetailedHostedServiceProperties getResult() { + try { + return builder.fromHostedServiceProperties(super.getResult()).build(); + } finally { + builder = DetailedHostedServiceProperties.builder(); + } + } + + @Override + public void endElement(String uri, String name, String qName) throws SAXException { + if (equalsOrSuffix(qName, "DateCreated")) { + builder.created(dateService.iso8601SecondsDateParse(currentOrNull(currentText))); + } else if (equalsOrSuffix(qName, "DateLastModified")) { + builder.lastModified(dateService.iso8601SecondsDateParse(currentOrNull(currentText))); + } else if (equalsOrSuffix(qName, "Status")) { + String rawStatus = currentOrNull(currentText); + builder.rawStatus(rawStatus); + builder.status(Status.fromValue(rawStatus)); + } else if (equalsOrSuffix(qName, "Name")) { + this.name = currentOrNull(currentText); + } else if (equalsOrSuffix(qName, "Value")) { + builder.addExtendedProperty(this.name, currentOrNull(currentText)); + this.name = null; + } else { + super.endElement(uri, name, qName); + } + currentText.setLength(0); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DiskHandler.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DiskHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DiskHandler.java new file mode 100644 index 0000000..b592f95 --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DiskHandler.java @@ -0,0 +1,107 @@ +/* + * 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.azurecompute.xml; + +import java.net.URI; +import javax.inject.Inject; +import org.jclouds.azurecompute.domain.Disk; +import org.jclouds.azurecompute.domain.OSType; +import org.jclouds.http.functions.ParseSax; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; + +import static org.jclouds.util.SaxUtils.currentOrNull; +import static org.jclouds.util.SaxUtils.equalsOrSuffix; + +/** + * @see <a href="http://msdn.microsoft.com/en-us/library/jj157176" >api</a> + */ +public class DiskHandler extends + ParseSax.HandlerForGeneratedRequestWithResult<Disk> { + + private final AttachmentHandler attachmentHandler; + + @Inject + private DiskHandler(AttachmentHandler attachmentHandler) { + this.attachmentHandler = attachmentHandler; + } + + private StringBuilder currentText = new StringBuilder(); + private Disk.Builder builder = Disk.builder(); + + private boolean inAttachment; + + @Override + public Disk getResult() { + try { + return builder.build(); + } finally { + builder = Disk.builder(); + } + } + + @Override + public void startElement(String uri, String localName, String qName, + Attributes attributes) throws SAXException { + if (equalsOrSuffix(qName, "AttachedTo")) { + inAttachment = true; + } + } + + @Override + public void endElement(String uri, String name, String qName) + throws SAXException { + if (equalsOrSuffix(qName, "AttachedTo")) { + builder.attachedTo(attachmentHandler.getResult()); + inAttachment = false; + } else if (inAttachment) { + attachmentHandler.endElement(uri, name, qName); + } else if (equalsOrSuffix(qName, "OS")) { + builder.os(OSType.fromValue(currentOrNull(currentText))); + } else if (equalsOrSuffix(qName, "Name")) { + builder.name(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "LogicalDiskSizeInGB")) { + String gb = currentOrNull(currentText); + if (gb != null) + builder.logicalSizeInGB(Integer.parseInt(gb)); + } else if (equalsOrSuffix(qName, "Description")) { + builder.description(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "Location")) { + builder.location(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "AffinityGroup")) { + builder.affinityGroup(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "MediaLink")) { + String link = currentOrNull(currentText); + if (link != null) + builder.mediaLink(URI.create(link)); + } else if (equalsOrSuffix(qName, "SourceImageName")) { + builder.sourceImage(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "Label")) { + builder.label(currentOrNull(currentText)); + } + currentText.setLength(0); + } + + @Override + public void characters(char ch[], int start, int length) { + if (inAttachment) { + attachmentHandler.characters(ch, start, length); + } else { + currentText.append(ch, start, length); + } + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ErrorHandler.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ErrorHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ErrorHandler.java new file mode 100644 index 0000000..3d7f2f4 --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ErrorHandler.java @@ -0,0 +1,58 @@ +/* + * 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.azurecompute.xml; + +import org.jclouds.azurecompute.domain.Error; +import org.jclouds.azurecompute.domain.Error.Code; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.util.SaxUtils; +import org.xml.sax.SAXException; + +/** + * @see <a href="http://msdn.microsoft.com/en-us/library/ee460801" >api</a> + */ +public class ErrorHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Error> { + + private StringBuilder currentText = new StringBuilder(); + private Error.Builder builder = Error.builder(); + + @Override + public Error getResult() { + try { + return builder.build(); + } finally { + builder = Error.builder(); + } + } + + @Override + public void endElement(String uri, String name, String qName) throws SAXException { + if (qName.equals("Code")) { + String rawCode = SaxUtils.currentOrNull(currentText); + builder.rawCode(rawCode); + builder.code(Code.fromValue(rawCode)); + } else if (qName.equals("Message")) { + builder.message(SaxUtils.currentOrNull(currentText)); + } + currentText.setLength(0); + } + + @Override + public void characters(char ch[], int start, int length) { + currentText.append(ch, start, length); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/xml/HostedServiceHandler.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/HostedServiceHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/HostedServiceHandler.java new file mode 100644 index 0000000..2962c42 --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/HostedServiceHandler.java @@ -0,0 +1,93 @@ +/* + * 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.azurecompute.xml; + +import java.net.URI; +import javax.inject.Inject; +import org.jclouds.azurecompute.domain.HostedService; +import org.jclouds.azurecompute.domain.HostedService.Builder; +import org.jclouds.http.functions.ParseSax; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; + +import static org.jclouds.util.SaxUtils.currentOrNull; +import static org.jclouds.util.SaxUtils.equalsOrSuffix; + +/** + * @see <a href="http://msdn.microsoft.com/en-us/library/gg441293" >api</a> + */ +public class HostedServiceHandler extends ParseSax.HandlerForGeneratedRequestWithResult<HostedService> { + + private final HostedServicePropertiesHandler hostedServicePropertiesHandler; + + @Inject protected HostedServiceHandler(HostedServicePropertiesHandler hostedServicePropertiesHandler) { + this.hostedServicePropertiesHandler = hostedServicePropertiesHandler; + } + + private StringBuilder currentText = new StringBuilder(); + protected HostedService.Builder<?> builder = builder(); + + protected Builder<?> builder() { + return HostedService.builder(); + } + + private boolean inHostedServiceProperties; + + @Override + public HostedService getResult() { + try { + return builder.build(); + } finally { + builder = builder(); + } + } + + @Override + public void startElement(String url, String name, String qName, Attributes attributes) throws SAXException { + if (equalsOrSuffix(qName, "HostedServiceProperties")) { + inHostedServiceProperties = true; + } + if (inHostedServiceProperties) { + hostedServicePropertiesHandler.startElement(url, name, qName, attributes); + } + } + + @Override + public void endElement(String uri, String name, String qName) throws SAXException { + + if (equalsOrSuffix(qName, "HostedServiceProperties")) { + builder.properties(hostedServicePropertiesHandler.getResult()); + inHostedServiceProperties = false; + } else if (inHostedServiceProperties) { + hostedServicePropertiesHandler.endElement(uri, name, qName); + } else if (equalsOrSuffix(qName, "Url")) { + builder.url(URI.create(currentOrNull(currentText))); + } else if (equalsOrSuffix(qName, "ServiceName")) { + builder.name(currentOrNull(currentText)); + } + currentText.setLength(0); + } + + @Override + public void characters(char ch[], int start, int length) { + if (inHostedServiceProperties) { + hostedServicePropertiesHandler.characters(ch, start, length); + } else { + currentText.append(ch, start, length); + } + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/xml/HostedServicePropertiesHandler.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/HostedServicePropertiesHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/HostedServicePropertiesHandler.java new file mode 100644 index 0000000..835ce3a --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/HostedServicePropertiesHandler.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.azurecompute.xml; + +import org.jclouds.azurecompute.domain.HostedServiceProperties; +import org.jclouds.http.functions.ParseSax; +import org.xml.sax.SAXException; + +import static com.google.common.base.Charsets.UTF_8; +import static com.google.common.io.BaseEncoding.base64; +import static org.jclouds.util.SaxUtils.currentOrNull; +import static org.jclouds.util.SaxUtils.equalsOrSuffix; + +/** + * @see <a href="http://msdn.microsoft.com/en-us/library/gg441293" >api</a> + */ +public class HostedServicePropertiesHandler extends + ParseSax.HandlerForGeneratedRequestWithResult<HostedServiceProperties> { + + protected StringBuilder currentText = new StringBuilder(); + private HostedServiceProperties.Builder<?> builder = HostedServiceProperties.builder(); + + @Override + public HostedServiceProperties getResult() { + try { + return builder.build(); + } finally { + builder = HostedServiceProperties.builder(); + } + } + + @Override + public void endElement(String uri, String name, String qName) throws SAXException { + if (equalsOrSuffix(qName, "Description")) { + builder.description(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "Location")) { + builder.location(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "AffinityGroup")) { + builder.affinityGroup(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "Label")) { + builder.label(new String(base64().decode(currentOrNull(currentText)), UTF_8)); + } + currentText.setLength(0); + } + + @Override + public void characters(char ch[], int start, int length) { + currentText.append(ch, start, length); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/xml/HostedServiceWithDetailedPropertiesHandler.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/HostedServiceWithDetailedPropertiesHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/HostedServiceWithDetailedPropertiesHandler.java new file mode 100644 index 0000000..69193b1 --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/HostedServiceWithDetailedPropertiesHandler.java @@ -0,0 +1,42 @@ +/* + * 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.azurecompute.xml; + +import javax.inject.Inject; +import org.jclouds.azurecompute.domain.HostedServiceWithDetailedProperties; + +public class HostedServiceWithDetailedPropertiesHandler extends HostedServiceHandler { + + @Inject protected HostedServiceWithDetailedPropertiesHandler( + DetailedHostedServicePropertiesHandler hostedServicePropertiesHandler) { + super(hostedServicePropertiesHandler); + } + + @Override + protected HostedServiceWithDetailedProperties.Builder builder() { + return HostedServiceWithDetailedProperties.builder(); + } + + @Override + public HostedServiceWithDetailedProperties getResult() { + try { + return HostedServiceWithDetailedProperties.class.cast(builder.build()); + } finally { + builder = builder(); + } + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ImageHandler.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ImageHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ImageHandler.java new file mode 100644 index 0000000..08adfea --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ImageHandler.java @@ -0,0 +1,88 @@ +/* + * 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.azurecompute.xml; + +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import java.net.URI; +import org.jclouds.azurecompute.domain.Image; +import org.jclouds.azurecompute.domain.OSType; +import org.jclouds.http.functions.ParseSax; +import org.xml.sax.SAXException; + +import static org.jclouds.util.SaxUtils.currentOrNull; +import static org.jclouds.util.SaxUtils.equalsOrSuffix; + +/** + * @see <a href="http://msdn.microsoft.com/en-us/library/jj157191" >api</a> + */ +public class ImageHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Image> { + + private StringBuilder currentText = new StringBuilder(); + private Image.Builder builder = Image.builder(); + + @Override + public Image getResult() { + try { + return builder.build(); + } finally { + builder = Image.builder(); + } + } + + @Override + public void endElement(String uri, String name, String qName) throws SAXException { + if (equalsOrSuffix(qName, "OS")) { + builder.os(OSType.fromValue(currentOrNull(currentText))); + } else if (equalsOrSuffix(qName, "Name")) { + builder.name(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "LogicalSizeInGB")) { + String gb = currentOrNull(currentText); + if (gb != null) + builder.logicalSizeInGB(Integer.parseInt(gb)); + } else if (equalsOrSuffix(qName, "Description")) { + builder.description(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "Category")) { + builder.category(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "Location")) { + builder.location(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "AffinityGroup")) { + builder.affinityGroup(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "MediaLink")) { + String link = currentOrNull(currentText); + if (link != null) + builder.mediaLink(URI.create(link)); + } else if (equalsOrSuffix(qName, "Eula")) { + String eulaField = currentOrNull(currentText); + if (eulaField != null) { + for (String eula : Splitter.on(';').split(eulaField)) { + if ((eula = Strings.emptyToNull(eula.trim())) != null) { // Dirty data in RightScale eula field. + builder.eula(eula); + } + } + } + } else if (equalsOrSuffix(qName, "Label")) { + builder.label(currentOrNull(currentText)); + } + currentText.setLength(0); + } + + @Override + public void characters(char ch[], int start, int length) { + currentText.append(ch, start, length); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ListDisksHandler.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ListDisksHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ListDisksHandler.java new file mode 100644 index 0000000..fb6ea13 --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ListDisksHandler.java @@ -0,0 +1,73 @@ +/* + * 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.azurecompute.xml; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; +import com.google.inject.Inject; +import java.util.List; +import org.jclouds.azurecompute.domain.Disk; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.util.SaxUtils; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; + +public class ListDisksHandler extends ParseSax.HandlerForGeneratedRequestWithResult<List<Disk>> { + + private final DiskHandler diskHandler; + + private Builder<Disk> disks = ImmutableList.<Disk> builder(); + + private boolean inDisk; + + @Inject + public ListDisksHandler(final DiskHandler diskHandler) { + this.diskHandler = diskHandler; + } + + @Override + public List<Disk> getResult() { + return disks.build(); + } + + @Override + public void startElement(String url, String name, String qName, Attributes attributes) throws SAXException { + if (SaxUtils.equalsOrSuffix(qName, "Disk")) { + inDisk = true; + } + if (inDisk) { + diskHandler.startElement(url, name, qName, attributes); + } + } + + @Override + public void endElement(String uri, String name, String qName) throws SAXException { + if (qName.equals("Disk")) { + inDisk = false; + disks.add(diskHandler.getResult()); + } else if (inDisk) { + diskHandler.endElement(uri, name, qName); + } + } + + @Override + public void characters(char ch[], int start, int length) { + if (inDisk) { + diskHandler.characters(ch, start, length); + } + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ListHostedServicesHandler.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ListHostedServicesHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ListHostedServicesHandler.java new file mode 100644 index 0000000..875e787 --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ListHostedServicesHandler.java @@ -0,0 +1,78 @@ +/* + * 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.azurecompute.xml; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; +import com.google.inject.Inject; +import java.util.List; +import org.jclouds.azurecompute.domain.HostedServiceWithDetailedProperties; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.util.SaxUtils; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; + +/** + * @see <a href="http://msdn.microsoft.com/en-us/library/ee460781">doc</a> + */ +public class ListHostedServicesHandler extends + ParseSax.HandlerForGeneratedRequestWithResult<List<HostedServiceWithDetailedProperties>> { + + private final HostedServiceWithDetailedPropertiesHandler hostedServiceHandler; + + private Builder<HostedServiceWithDetailedProperties> hostedServices = ImmutableList + .<HostedServiceWithDetailedProperties> builder(); + + private boolean inHostedService; + + @Inject + public ListHostedServicesHandler(HostedServiceWithDetailedPropertiesHandler hostedServiceHandler) { + this.hostedServiceHandler = hostedServiceHandler; + } + + @Override + public List<HostedServiceWithDetailedProperties> getResult() { + return hostedServices.build(); + } + + @Override + public void startElement(String url, String name, String qName, Attributes attributes) throws SAXException { + if (SaxUtils.equalsOrSuffix(qName, "HostedService")) { + inHostedService = true; + } + if (inHostedService) { + hostedServiceHandler.startElement(url, name, qName, attributes); + } + } + + @Override + public void endElement(String uri, String name, String qName) throws SAXException { + if (qName.equals("HostedService")) { + inHostedService = false; + hostedServices.add(hostedServiceHandler.getResult()); + } else if (inHostedService) { + hostedServiceHandler.endElement(uri, name, qName); + } + } + + @Override + public void characters(char ch[], int start, int length) { + if (inHostedService) { + hostedServiceHandler.characters(ch, start, length); + } + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ListImagesHandler.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ListImagesHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ListImagesHandler.java new file mode 100644 index 0000000..beae350 --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ListImagesHandler.java @@ -0,0 +1,73 @@ +/* + * 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.azurecompute.xml; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; +import com.google.inject.Inject; +import java.util.List; +import org.jclouds.azurecompute.domain.Image; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.util.SaxUtils; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; + +public class ListImagesHandler extends ParseSax.HandlerForGeneratedRequestWithResult<List<Image>> { + + private final ImageHandler locationHandler; + + private Builder<Image> locations = ImmutableList.<Image> builder(); + + private boolean inOSImage; + + @Inject + public ListImagesHandler(ImageHandler locationHandler) { + this.locationHandler = locationHandler; + } + + @Override + public List<Image> getResult() { + return locations.build(); + } + + @Override + public void startElement(String url, String name, String qName, Attributes attributes) throws SAXException { + if (SaxUtils.equalsOrSuffix(qName, "OSImage")) { + inOSImage = true; + } + if (inOSImage) { + locationHandler.startElement(url, name, qName, attributes); + } + } + + @Override + public void endElement(String uri, String name, String qName) throws SAXException { + if (qName.equals("OSImage")) { + inOSImage = false; + locations.add(locationHandler.getResult()); + } else if (inOSImage) { + locationHandler.endElement(uri, name, qName); + } + } + + @Override + public void characters(char ch[], int start, int length) { + if (inOSImage) { + locationHandler.characters(ch, start, length); + } + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ListLocationsHandler.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ListLocationsHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ListLocationsHandler.java new file mode 100644 index 0000000..f257a6a --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ListLocationsHandler.java @@ -0,0 +1,73 @@ +/* + * 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.azurecompute.xml; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; +import com.google.inject.Inject; +import java.util.List; +import org.jclouds.azurecompute.domain.Location; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.util.SaxUtils; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; + +public class ListLocationsHandler extends ParseSax.HandlerForGeneratedRequestWithResult<List<Location>> { + + private final LocationHandler locationHandler; + + private Builder<Location> locations = ImmutableList.<Location> builder(); + + private boolean inLocation; + + @Inject + public ListLocationsHandler(LocationHandler locationHandler) { + this.locationHandler = locationHandler; + } + + @Override + public List<Location> getResult() { + return locations.build(); + } + + @Override + public void startElement(String url, String name, String qName, Attributes attributes) throws SAXException { + if (SaxUtils.equalsOrSuffix(qName, "Location")) { + inLocation = true; + } + if (inLocation) { + locationHandler.startElement(url, name, qName, attributes); + } + } + + @Override + public void endElement(String uri, String name, String qName) throws SAXException { + if (qName.equals("Location")) { + inLocation = false; + locations.add(locationHandler.getResult()); + } else if (inLocation) { + locationHandler.endElement(uri, name, qName); + } + } + + @Override + public void characters(char ch[], int start, int length) { + if (inLocation) { + locationHandler.characters(ch, start, length); + } + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6ab58bd2/azurecompute/src/main/java/org/jclouds/azurecompute/xml/LocationHandler.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/LocationHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/LocationHandler.java new file mode 100644 index 0000000..01d2b9e --- /dev/null +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/LocationHandler.java @@ -0,0 +1,57 @@ +/* + * 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.azurecompute.xml; + +import org.jclouds.azurecompute.domain.Location; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.util.SaxUtils; +import org.xml.sax.SAXException; + +/** + * @see <a href="http://msdn.microsoft.com/en-us/library/gg441293" >api</a> + */ +public class LocationHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Location> { + + private StringBuilder currentText = new StringBuilder(); + private Location.Builder builder = Location.builder(); + + @Override + public Location getResult() { + try { + return builder.build(); + } finally { + builder = Location.builder(); + } + } + + @Override + public void endElement(String uri, String name, String qName) throws SAXException { + if (qName.equals("Name")) { + builder.name(SaxUtils.currentOrNull(currentText)); + } else if (qName.equals("DisplayName")) { + builder.displayName(SaxUtils.currentOrNull(currentText)); + } else if (qName.equals("AvailableService")) { + builder.addAvailableService(SaxUtils.currentOrNull(currentText)); + } + currentText.setLength(0); + } + + @Override + public void characters(char ch[], int start, int length) { + currentText.append(ch, start, length); + } +}
