You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ad...@apache.org on 2014/10/05 19:50:19 UTC
[11/20] JCLOUDS-664 Updating Azure compute provider
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/45ef2a18/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/45ef2a18/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/45ef2a18/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/45ef2a18/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/45ef2a18/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/45ef2a18/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/45ef2a18/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/45ef2a18/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..18ab095
--- /dev/null
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/options/CreateHostedServiceOptions.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.options;
+
+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 Objects.toStringHelper("").omitNullValues().add("description", description.orNull())
+ .add("extendedProperties", extendedProperties.orNull()).toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/45ef2a18/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/45ef2a18/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/45ef2a18/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..5bde45e
--- /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 = new StringBuilder();
+ }
+
+ @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/45ef2a18/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/45ef2a18/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..ad77ab4
--- /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 = new StringBuilder();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/45ef2a18/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..3d933b2
--- /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 = new StringBuilder();
+ }
+
+ @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/45ef2a18/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..04dca23
--- /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 = new StringBuilder();
+ }
+
+ @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/45ef2a18/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..04f009a
--- /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 = new StringBuilder();
+ }
+
+ @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/45ef2a18/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..d3962c5
--- /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 = new StringBuilder();
+ }
+
+ @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/45ef2a18/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/45ef2a18/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..1182c64
--- /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 = new StringBuilder();
+ }
+
+ @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/45ef2a18/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/45ef2a18/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/45ef2a18/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/45ef2a18/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/45ef2a18/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..d2e229a
--- /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 = new StringBuilder();
+ }
+
+ @Override
+ public void characters(char ch[], int start, int length) {
+ currentText.append(ch, start, length);
+ }
+}