You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2016/10/20 11:09:40 UTC

jclouds-labs git commit: Added rate limit module

Repository: jclouds-labs
Updated Branches:
  refs/heads/master 2e3874301 -> a1684e2d8


Added rate limit module


Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/a1684e2d
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/a1684e2d
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/a1684e2d

Branch: refs/heads/master
Commit: a1684e2d8e3cb5e790decfef25c610d4c418fedd
Parents: 2e38743
Author: Ignasi Barrera <na...@apache.org>
Authored: Wed Oct 19 16:50:50 2016 +0200
Committer: Ignasi Barrera <na...@apache.org>
Committed: Wed Oct 19 16:50:50 2016 +0200

----------------------------------------------------------------------
 .../arm/AzureComputeProviderMetadata.java       | 22 +++++----
 .../arm/config/AzureComputeRateLimitModule.java | 30 ++++++++++++
 .../AzureComputeRateLimitExceededException.java | 51 ++++++++++++++++++++
 .../arm/handlers/AzureComputeErrorHandler.java  |  6 ++-
 .../handlers/AzureRateLimitRetryHandler.java    | 39 +++++++++++++++
 5 files changed, 137 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a1684e2d/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
index beac925..dd516ef 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
@@ -17,6 +17,7 @@
 package org.jclouds.azurecompute.arm;
 
 
+import static org.jclouds.Constants.PROPERTY_MAX_RATE_LIMIT_WAIT;
 import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.API_VERSION_PREFIX;
 import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_DATADISKSIZE;
 import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_SUBNET_ADDRESS_PREFIX;
@@ -30,6 +31,8 @@ import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RUL
 import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_REGEXP;
 import static org.jclouds.compute.config.ComputeServiceProperties.IMAGE_AUTHENTICATE_SUDO;
 import static org.jclouds.compute.config.ComputeServiceProperties.IMAGE_LOGIN_USER;
+import static org.jclouds.compute.config.ComputeServiceProperties.POLL_INITIAL_PERIOD;
+import static org.jclouds.compute.config.ComputeServiceProperties.POLL_MAX_PERIOD;
 import static org.jclouds.compute.config.ComputeServiceProperties.RESOURCENAME_DELIMITER;
 import static org.jclouds.compute.config.ComputeServiceProperties.RESOURCENAME_PREFIX;
 import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
@@ -56,7 +59,6 @@ import org.jclouds.azurecompute.arm.features.SubnetApi;
 import org.jclouds.azurecompute.arm.features.VMSizeApi;
 import org.jclouds.azurecompute.arm.features.VirtualMachineApi;
 import org.jclouds.azurecompute.arm.features.VirtualNetworkApi;
-import org.jclouds.compute.config.ComputeServiceProperties;
 import org.jclouds.providers.ProviderMetadata;
 import org.jclouds.providers.internal.BaseProviderMetadata;
 
@@ -80,20 +82,22 @@ public class AzureComputeProviderMetadata extends BaseProviderMetadata {
 
    public static Properties defaultProperties() {
       final Properties properties = AzureManagementApiMetadata.defaultProperties();
-      properties.put(ComputeServiceProperties.POLL_INITIAL_PERIOD, 1000);
-      properties.put(ComputeServiceProperties.POLL_MAX_PERIOD, 10000);
-      properties.setProperty(OPERATION_TIMEOUT, "46000000");
-      properties.setProperty(OPERATION_POLL_INITIAL_PERIOD, "5");
-      properties.setProperty(OPERATION_POLL_MAX_PERIOD, "15");
-      properties.setProperty(TCP_RULE_FORMAT, "tcp_%s-%s");
-      properties.setProperty(TCP_RULE_REGEXP, "tcp_\\d{1,5}-\\d{1,5}");
+      properties.put(POLL_INITIAL_PERIOD, 1000);
+      properties.put(POLL_MAX_PERIOD, 10000);
+      properties.put(OPERATION_TIMEOUT, 46000000);
+      properties.put(OPERATION_POLL_INITIAL_PERIOD, 5);
+      properties.put(OPERATION_POLL_MAX_PERIOD, 15);
+      // Default max wait in rate limit: 5m30s
+      properties.put(PROPERTY_MAX_RATE_LIMIT_WAIT, 330000);
+      properties.put(TCP_RULE_FORMAT, "tcp_%s-%s");
+      properties.put(TCP_RULE_REGEXP, "tcp_\\d{1,5}-\\d{1,5}");
       properties.put(RESOURCE, "https://management.azure.com/");
       properties.put(CREDENTIAL_TYPE, CLIENT_CREDENTIALS_SECRET.toString());
       properties.put(DEFAULT_VNET_ADDRESS_SPACE_PREFIX, "10.0.0.0/16");
       properties.put(DEFAULT_SUBNET_ADDRESS_PREFIX, "10.0.0.0/24");
       properties.put(RESOURCENAME_PREFIX, "jclouds");
       properties.put(RESOURCENAME_DELIMITER, "-");
-      properties.put(DEFAULT_DATADISKSIZE, "100");
+      properties.put(DEFAULT_DATADISKSIZE, 100);
       properties.put(IMAGE_PUBLISHERS, "Canonical,RedHat");
       // Default credentials for all images
       properties.put(IMAGE_LOGIN_USER, "jclouds:Password12345!");

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a1684e2d/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeRateLimitModule.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeRateLimitModule.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeRateLimitModule.java
new file mode 100644
index 0000000..3038b86
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeRateLimitModule.java
@@ -0,0 +1,30 @@
+/*
+ * 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.arm.config;
+
+import org.jclouds.azurecompute.arm.handlers.AzureRateLimitRetryHandler;
+import org.jclouds.http.HttpRetryHandler;
+import org.jclouds.http.annotation.ClientError;
+
+import com.google.inject.AbstractModule;
+
+public class AzureComputeRateLimitModule extends AbstractModule {
+   @Override
+   protected void configure() {
+      bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(AzureRateLimitRetryHandler.class);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a1684e2d/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/exceptions/AzureComputeRateLimitExceededException.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/exceptions/AzureComputeRateLimitExceededException.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/exceptions/AzureComputeRateLimitExceededException.java
new file mode 100644
index 0000000..d8d478e
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/exceptions/AzureComputeRateLimitExceededException.java
@@ -0,0 +1,51 @@
+/*
+ * 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.arm.exceptions;
+
+import org.jclouds.http.HttpResponse;
+import org.jclouds.rest.RateLimitExceededException;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+
+/**
+ * Provides detailed information for rate limit exceptions.
+ */
+@Beta
+public class AzureComputeRateLimitExceededException extends RateLimitExceededException {
+   private static final long serialVersionUID = 1L;
+   private static final String RATE_LIMIT_HEADER_PREFIX = "x-ms-ratelimit-remaining-";
+
+   public AzureComputeRateLimitExceededException(HttpResponse response) {
+      super(response.getStatusLine() + "\n" + rateLimitHeaders(response));
+   }
+
+   public AzureComputeRateLimitExceededException(HttpResponse response, Throwable cause) {
+      super(response.getStatusLine() + "\n" + rateLimitHeaders(response), cause);
+   }
+
+   private static Multimap<String, String> rateLimitHeaders(HttpResponse response) {
+      return Multimaps.filterKeys(response.getHeaders(), new Predicate<String>() {
+         @Override
+         public boolean apply(String input) {
+            return input.startsWith(RATE_LIMIT_HEADER_PREFIX);
+         }
+      });
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a1684e2d/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/handlers/AzureComputeErrorHandler.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/handlers/AzureComputeErrorHandler.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/handlers/AzureComputeErrorHandler.java
index 6532173..8492d51 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/handlers/AzureComputeErrorHandler.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/handlers/AzureComputeErrorHandler.java
@@ -20,6 +20,7 @@ import java.io.IOException;
 
 import javax.inject.Singleton;
 
+import org.jclouds.azurecompute.arm.exceptions.AzureComputeRateLimitExceededException;
 import org.jclouds.http.HttpCommand;
 import org.jclouds.http.HttpErrorHandler;
 import org.jclouds.http.HttpResponse;
@@ -65,11 +66,12 @@ public class AzureComputeErrorHandler implements HttpErrorHandler {
                   exception = new ResourceNotFoundException(message, exception);
                }
                break;
-
             case 409:
                exception = new IllegalStateException(message, exception);
                break;
-
+            case 429:
+               exception = new AzureComputeRateLimitExceededException(response, exception);
+               break;
             default:
          }
       } finally {

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a1684e2d/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/handlers/AzureRateLimitRetryHandler.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/handlers/AzureRateLimitRetryHandler.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/handlers/AzureRateLimitRetryHandler.java
new file mode 100644
index 0000000..ee5f5e5
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/handlers/AzureRateLimitRetryHandler.java
@@ -0,0 +1,39 @@
+/*
+ * 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.arm.handlers;
+
+import javax.inject.Singleton;
+
+import org.jclouds.http.HttpCommand;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.http.handlers.RateLimitRetryHandler;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
+import com.google.common.net.HttpHeaders;
+
+@Beta
+@Singleton
+public class AzureRateLimitRetryHandler extends RateLimitRetryHandler {
+
+   @Override
+   protected Optional<Long> millisToNextAvailableRequest(HttpCommand command, HttpResponse response) {
+      String secondsToNextAvailableRequest = response.getFirstHeaderOrNull(HttpHeaders.RETRY_AFTER);
+      return secondsToNextAvailableRequest != null ? Optional.of(Long.valueOf(secondsToNextAvailableRequest) * 1000)
+            : Optional.<Long> absent();
+   }
+}