cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mlsoren...@apache.org
Subject [1/50] [abbrv] git commit: Add API throttling config items and APILimitChecker Adapter interface, add api limit checking in APIServer flow.
Date Fri, 18 Jan 2013 22:23:45 GMT
Add API throttling config items and APILimitChecker Adapter interface,
add api limit checking in APIServer flow.

Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/8d98daa1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/8d98daa1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/8d98daa1

Branch: refs/heads/add_remove_nics
Commit: 8d98daa1beb46fe61022727b25c9e5b75db5e630
Parents: dcbb0ec
Author: Min Chen <min.chen@citrix.com>
Authored: Wed Jan 9 16:11:23 2013 -0800
Committer: Min Chen <min.chen@citrix.com>
Committed: Wed Jan 9 16:11:23 2013 -0800

----------------------------------------------------------------------
 .../org/apache/cloudstack/acl/APILimitChecker.java |   28 +++++++++++++++
 api/src/org/apache/cloudstack/api/BaseCmd.java     |    1 +
 server/src/com/cloud/api/ApiServer.java            |   27 ++++++++++++++
 server/src/com/cloud/configuration/Config.java     |    6 +++-
 4 files changed, 61 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8d98daa1/api/src/org/apache/cloudstack/acl/APILimitChecker.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/acl/APILimitChecker.java b/api/src/org/apache/cloudstack/acl/APILimitChecker.java
new file mode 100644
index 0000000..3a1db70
--- /dev/null
+++ b/api/src/org/apache/cloudstack/acl/APILimitChecker.java
@@ -0,0 +1,28 @@
+// 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.apache.cloudstack.acl;
+
+import com.cloud.user.Account;
+import com.cloud.utils.component.Adapter;
+
+/**
+ * APILimitChecker checks if we should block an API request based on pre-set account based
api limit.
+ */
+public interface APILimitChecker extends Adapter {
+    // Interface for checking if the account is over its api limit
+    boolean isUnderLimit(Account account);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8d98daa1/api/src/org/apache/cloudstack/api/BaseCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java
index d964e70..ae13012 100644
--- a/api/src/org/apache/cloudstack/api/BaseCmd.java
+++ b/api/src/org/apache/cloudstack/api/BaseCmd.java
@@ -89,6 +89,7 @@ public abstract class BaseCmd {
     public static final int PARAM_ERROR = 431;
     public static final int UNSUPPORTED_ACTION_ERROR = 432;
     public static final int PAGE_LIMIT_EXCEED = 433;
+    public static final int API_LIMIT_EXCEED = 434;
 
     // Server error codes
     public static final int INTERNAL_ERROR = 530;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8d98daa1/server/src/com/cloud/api/ApiServer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java
index 56cef12..2bb7fdd 100755
--- a/server/src/com/cloud/api/ApiServer.java
+++ b/server/src/com/cloud/api/ApiServer.java
@@ -52,6 +52,7 @@ import javax.servlet.http.HttpSession;
 
 import com.cloud.utils.ReflectUtil;
 import org.apache.cloudstack.acl.APIAccessChecker;
+import org.apache.cloudstack.acl.APILimitChecker;
 import org.apache.cloudstack.acl.ControlledEntity;
 import org.apache.cloudstack.api.*;
 import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
@@ -141,6 +142,7 @@ public class ApiServer implements HttpRequestHandler {
     private static final Logger s_accessLogger = Logger.getLogger("apiserver." + ApiServer.class.getName());
 
     public static boolean encodeApiResponse = false;
+    public static boolean apiThrottlingEnabled = true;
     public static String jsonContentType = "text/javascript";
     private ApiDispatcher _dispatcher;
 
@@ -148,6 +150,8 @@ public class ApiServer implements HttpRequestHandler {
     @Inject private DomainManager _domainMgr = null;
     @Inject private AsyncJobManager _asyncMgr = null;
 
+    @Inject(adapter = APILimitChecker.class)
+    protected Adapters<APILimitChecker> _apiLimitCheckers;
     @Inject(adapter = APIAccessChecker.class)
     protected Adapters<APIAccessChecker> _apiAccessCheckers;
     @Inject(adapter = ApiDiscoveryService.class)
@@ -217,6 +221,7 @@ public class ApiServer implements HttpRequestHandler {
         if (jsonType != null) {
             jsonContentType = jsonType;
         }
+        apiThrottlingEnabled = Boolean.valueOf(configDao.getValue(Config.ApiLimitEnabled.key()));
 
         if (apiPort != null) {
             ListenerThread listenerThread = new ListenerThread(this, apiPort);
@@ -552,6 +557,14 @@ public class ApiServer implements HttpRequestHandler {
             // if userId not null, that mean that user is logged in
             if (userId != null) {
             	User user = ApiDBUtils.findUserById(userId);
+            	if (apiThrottlingEnabled){
+            	    // go through each API limit checker
+            	    if (!isRequestAllowed(user)) {
+            	        //FIXME: more detailed message regarding when he/she can retry
+                        s_logger.warn("The given user has reached his/her account api limit,
please retry later");
+                        throw new ServerApiException(BaseCmd.API_LIMIT_EXCEED, "The given
user has reached his/her account api limit");
+            	    }
+            	}
                 if (!isCommandAvailable(user, commandName)) {
                     s_logger.warn("The given command:" + commandName + " does not exist or
it is not available for user");
                     throw new ServerApiException(BaseCmd.UNSUPPORTED_ACTION_ERROR, "The given
command does not exist or it is not available for user");
@@ -791,6 +804,20 @@ public class ApiServer implements HttpRequestHandler {
         return true;
     }
 
+    private boolean isRequestAllowed(User user) {
+        Account account = ApiDBUtils.findAccountById(user.getAccountId());
+        if ( _accountMgr.isRootAdmin(account.getType()) ){
+            // no api throttling for root admin
+            return true;
+        }
+        for (APILimitChecker apiChecker : _apiLimitCheckers) {
+            // Fail the checking if any checker fails to verify
+            if (!apiChecker.isUnderLimit(account))
+                return false;
+        }
+        return true;
+    }
+
     private boolean isCommandAvailable(User user, String commandName) {
         for (APIAccessChecker apiChecker : _apiAccessCheckers) {
             // Fail the checking if any checker fails to verify

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8d98daa1/server/src/com/cloud/configuration/Config.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index b91fbdd..ae7651c 100755
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -358,8 +358,12 @@ public enum Config {
     DetailBatchQuerySize("Advanced", ManagementServer.class, Integer.class, "detail.batch.query.size",
"2000", "Default entity detail batch query size for listing", null),
 
 	ConcurrentSnapshotsThresholdPerHost("Advanced", ManagementServer.class, Long.class, "concurrent.snapshots.threshold.perhost",
-	                null, "Limits number of snapshots that can be handled by the host concurrently;
default is NULL - unlimited", null);
+	                null, "Limits number of snapshots that can be handled by the host concurrently;
default is NULL - unlimited", null),
 
+	// API throttling
+    ApiLimitInterval("Advanced", ManagementServer.class, Long.class, "api.throttling.interval",
"1", "The default time interval in seconds used to set account based api limit", null),
+    ApiLimitMax("Advanced", ManagementServer.class, Long.class, "api.throttling.max", "25",
"The max number of API requests within api.throttling.interval duration", null),
+    ApiLimitEnabled("Advanced", ManagementServer.class, Boolean.class, "api.throttling.enabled",
"true", "If true, api throttline feature is enabled", "true,false");
 
 	private final String _category;
 	private final Class<?> _componentClass;


Mime
View raw message