diff --git a/client/pom.xml b/client/pom.xml
index cf384a6fd06c..bbf3be806684 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -108,11 +108,6 @@
cloud-plugin-dedicated-resources
${project.version}
-
- org.apache.cloudstack
- cloud-plugin-api-limit-account-based
- ${project.version}
-
org.apache.cloudstack
cloud-plugin-api-discovery
diff --git a/plugins/api/rate-limit/pom.xml b/plugins/api/rate-limit/pom.xml
deleted file mode 100644
index 72c904c9d81c..000000000000
--- a/plugins/api/rate-limit/pom.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
- 4.0.0
- cloud-plugin-api-limit-account-based
- Apache CloudStack Plugin - API Rate Limit
-
- org.apache.cloudstack
- cloudstack-plugins
- 4.12.0.0-SNAPSHOT
- ../../pom.xml
-
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
- always
- -Xmx2048m -XX:MaxPermSize=1024m
-
- org/apache/cloudstack/ratelimit/integration/*
-
-
-
-
-
-
diff --git a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/api/command/admin/ratelimit/ResetApiLimitCmd.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/api/command/admin/ratelimit/ResetApiLimitCmd.java
deleted file mode 100644
index fab68e3856cd..000000000000
--- a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/api/command/admin/ratelimit/ResetApiLimitCmd.java
+++ /dev/null
@@ -1,106 +0,0 @@
-// 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.api.command.admin.ratelimit;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.AccountResponse;
-import org.apache.cloudstack.api.response.ApiLimitResponse;
-import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.ratelimit.ApiRateLimitService;
-
-import com.cloud.configuration.Config;
-import com.cloud.user.Account;
-
-@APICommand(name = "resetApiLimit", responseObject = ApiLimitResponse.class, description = "Reset api count",
- requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ResetApiLimitCmd extends BaseCmd {
- private static final Logger s_logger = Logger.getLogger(ResetApiLimitCmd.class.getName());
-
- private static final String s_name = "resetapilimitresponse";
-
- @Inject
- ApiRateLimitService _apiLimitService;
-
- @Inject
- ConfigurationDao _configDao;
-
- /////////////////////////////////////////////////////
- //////////////// API parameters /////////////////////
- /////////////////////////////////////////////////////
-
- @ACL
- @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.UUID, entityType = AccountResponse.class, description = "the ID of the acount whose limit to be reset")
- private Long accountId;
-
- /////////////////////////////////////////////////////
- /////////////////// Accessors ///////////////////////
- /////////////////////////////////////////////////////
-
- public Long getAccountId() {
- return accountId;
- }
-
- public void setAccountId(Long accountId) {
- this.accountId = accountId;
- }
-
- /////////////////////////////////////////////////////
- /////////////// API Implementation///////////////////
- /////////////////////////////////////////////////////
-
- @Override
- public String getCommandName() {
- return s_name;
- }
-
- @Override
- public long getEntityOwnerId() {
- Account account = CallContext.current().getCallingAccount();
- if (account != null) {
- return account.getId();
- }
-
- return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
- }
-
- @Override
- public void execute() {
- boolean apiLimitEnabled = Boolean.parseBoolean(_configDao.getValue(Config.ApiLimitEnabled.key()));
- if (!apiLimitEnabled) {
- throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "This api is only available when api.throttling.enabled = true.");
- }
- boolean result = _apiLimitService.resetApiLimit(this.accountId);
- if (result) {
- SuccessResponse response = new SuccessResponse(getCommandName());
- this.setResponseObject(response);
- } else {
- throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to reset api limit counter");
- }
- }
-}
diff --git a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/api/command/user/ratelimit/GetApiLimitCmd.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/api/command/user/ratelimit/GetApiLimitCmd.java
deleted file mode 100644
index 51b2064fa900..000000000000
--- a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/api/command/user/ratelimit/GetApiLimitCmd.java
+++ /dev/null
@@ -1,79 +0,0 @@
-// 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.api.command.user.ratelimit;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.ApiLimitResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.ratelimit.ApiRateLimitService;
-
-import com.cloud.configuration.Config;
-import com.cloud.user.Account;
-
-@APICommand(name = "getApiLimit", responseObject = ApiLimitResponse.class, description = "Get API limit count for the caller",
- requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class GetApiLimitCmd extends BaseCmd {
- private static final Logger s_logger = Logger.getLogger(GetApiLimitCmd.class.getName());
-
- private static final String s_name = "getapilimitresponse";
-
- @Inject
- ApiRateLimitService _apiLimitService;
-
- @Inject
- ConfigurationDao _configDao;
-
- /////////////////////////////////////////////////////
- /////////////// API Implementation///////////////////
- /////////////////////////////////////////////////////
-
- @Override
- public String getCommandName() {
- return s_name;
- }
-
- @Override
- public long getEntityOwnerId() {
- Account account = CallContext.current().getCallingAccount();
- if (account != null) {
- return account.getId();
- }
-
- return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
- }
-
- @Override
- public void execute() {
- boolean apiLimitEnabled = Boolean.parseBoolean(_configDao.getValue(Config.ApiLimitEnabled.key()));
- if (!apiLimitEnabled) {
- throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "This api is only available when api.throttling.enabled = true.");
- }
- Account caller = CallContext.current().getCallingAccount();
- ApiLimitResponse response = _apiLimitService.searchApiLimit(caller);
- response.setResponseName(getCommandName());
- response.setObjectName("apilimit");
- this.setResponseObject(response);
- }
-}
diff --git a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/api/response/ApiLimitResponse.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/api/response/ApiLimitResponse.java
deleted file mode 100644
index ddd5fa3ded7d..000000000000
--- a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/api/response/ApiLimitResponse.java
+++ /dev/null
@@ -1,87 +0,0 @@
-// 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.api.response;
-
-import com.google.gson.annotations.SerializedName;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseResponse;
-
-import com.cloud.serializer.Param;
-
-public class ApiLimitResponse extends BaseResponse {
- @SerializedName(ApiConstants.ACCOUNT_ID)
- @Param(description = "the account uuid of the api remaining count")
- private String accountId;
-
- @SerializedName(ApiConstants.ACCOUNT)
- @Param(description = "the account name of the api remaining count")
- private String accountName;
-
- @SerializedName("apiIssued")
- @Param(description = "number of api already issued")
- private int apiIssued;
-
- @SerializedName("apiAllowed")
- @Param(description = "currently allowed number of apis")
- private int apiAllowed;
-
- @SerializedName("expireAfter")
- @Param(description = "seconds left to reset counters")
- private long expireAfter;
-
- public void setAccountId(String accountId) {
- this.accountId = accountId;
- }
-
- public void setAccountName(String accountName) {
- this.accountName = accountName;
- }
-
- public void setApiIssued(int apiIssued) {
- this.apiIssued = apiIssued;
- }
-
- public void setApiAllowed(int apiAllowed) {
- this.apiAllowed = apiAllowed;
- }
-
- public void setExpireAfter(long duration) {
- this.expireAfter = duration;
- }
-
- public String getAccountId() {
- return accountId;
- }
-
- public String getAccountName() {
- return accountName;
- }
-
- public int getApiIssued() {
- return apiIssued;
- }
-
- public int getApiAllowed() {
- return apiAllowed;
- }
-
- public long getExpireAfter() {
- return expireAfter;
- }
-
-}
diff --git a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/ApiRateLimitService.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/ApiRateLimitService.java
deleted file mode 100644
index bb97f5a6ee09..000000000000
--- a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/ApiRateLimitService.java
+++ /dev/null
@@ -1,39 +0,0 @@
-// 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.ratelimit;
-
-import org.apache.cloudstack.api.response.ApiLimitResponse;
-
-import com.cloud.user.Account;
-import com.cloud.utils.component.PluggableService;
-
-/**
- * Provide API rate limit service
- *
- */
-public interface ApiRateLimitService extends PluggableService {
-
- public ApiLimitResponse searchApiLimit(Account caller);
-
- public boolean resetApiLimit(Long accountId);
-
- public void setTimeToLive(int timeToLive);
-
- public void setMaxAllowed(int max);
-
- public void setEnabled(boolean enabled);
-}
diff --git a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/ApiRateLimitServiceImpl.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/ApiRateLimitServiceImpl.java
deleted file mode 100644
index e35a332c54d1..000000000000
--- a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/ApiRateLimitServiceImpl.java
+++ /dev/null
@@ -1,202 +0,0 @@
-// 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.ratelimit;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import net.sf.ehcache.Cache;
-import net.sf.ehcache.CacheManager;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.acl.APIChecker;
-import org.apache.cloudstack.api.command.admin.ratelimit.ResetApiLimitCmd;
-import org.apache.cloudstack.api.command.user.ratelimit.GetApiLimitCmd;
-import org.apache.cloudstack.api.response.ApiLimitResponse;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-
-import com.cloud.configuration.Config;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.RequestLimitException;
-import com.cloud.user.Account;
-import com.cloud.user.AccountService;
-import com.cloud.user.User;
-import com.cloud.utils.component.AdapterBase;
-
-@Component
-public class ApiRateLimitServiceImpl extends AdapterBase implements APIChecker, ApiRateLimitService {
- private static final Logger s_logger = Logger.getLogger(ApiRateLimitServiceImpl.class);
-
- /**
- * True if api rate limiting is enabled
- */
- private boolean enabled = false;
-
- /**
- * Fixed time duration where api rate limit is set, in seconds
- */
- private int timeToLive = 1;
-
- /**
- * Max number of api requests during timeToLive duration.
- */
- private int maxAllowed = 30;
-
- private LimitStore _store = null;
-
- @Inject
- AccountService _accountService;
-
- @Inject
- ConfigurationDao _configDao;
-
- @Override
- public boolean configure(String name, Map params) throws ConfigurationException {
- super.configure(name, params);
-
- if (_store == null) {
- // get global configured duration and max values
- String isEnabled = _configDao.getValue(Config.ApiLimitEnabled.key());
- if (isEnabled != null) {
- enabled = Boolean.parseBoolean(isEnabled);
- }
- String duration = _configDao.getValue(Config.ApiLimitInterval.key());
- if (duration != null) {
- timeToLive = Integer.parseInt(duration);
- }
- String maxReqs = _configDao.getValue(Config.ApiLimitMax.key());
- if (maxReqs != null) {
- maxAllowed = Integer.parseInt(maxReqs);
- }
- // create limit store
- EhcacheLimitStore cacheStore = new EhcacheLimitStore();
- int maxElements = 10000;
- String cachesize = _configDao.getValue(Config.ApiLimitCacheSize.key());
- if (cachesize != null) {
- maxElements = Integer.parseInt(cachesize);
- }
- CacheManager cm = CacheManager.create();
- Cache cache = new Cache("api-limit-cache", maxElements, false, false, timeToLive, timeToLive);
- cm.addCache(cache);
- s_logger.info("Limit Cache created with timeToLive=" + timeToLive + ", maxAllowed=" + maxAllowed + ", maxElements=" + maxElements);
- cacheStore.setCache(cache);
- _store = cacheStore;
-
- }
-
- return true;
- }
-
- @Override
- public ApiLimitResponse searchApiLimit(Account caller) {
- ApiLimitResponse response = new ApiLimitResponse();
- response.setAccountId(caller.getUuid());
- response.setAccountName(caller.getAccountName());
- StoreEntry entry = _store.get(caller.getId());
- if (entry == null) {
-
- /* Populate the entry, thus unlocking any underlying mutex */
- entry = _store.create(caller.getId(), timeToLive);
- response.setApiIssued(0);
- response.setApiAllowed(maxAllowed);
- response.setExpireAfter(timeToLive);
- } else {
- response.setApiIssued(entry.getCounter());
- response.setApiAllowed(maxAllowed - entry.getCounter());
- response.setExpireAfter(entry.getExpireDuration());
- }
-
- return response;
- }
-
- @Override
- public boolean resetApiLimit(Long accountId) {
- if (accountId != null) {
- _store.create(accountId, timeToLive);
- } else {
- _store.resetCounters();
- }
- return true;
- }
-
- @Override
- public boolean checkAccess(User user, String apiCommandName) throws PermissionDeniedException {
- // check if api rate limiting is enabled or not
- if (!enabled) {
- return true;
- }
- Long accountId = user.getAccountId();
- Account account = _accountService.getAccount(accountId);
- if (_accountService.isRootAdmin(account.getId())) {
- // no API throttling on root admin
- return true;
- }
- StoreEntry entry = _store.get(accountId);
-
- if (entry == null) {
-
- /* Populate the entry, thus unlocking any underlying mutex */
- entry = _store.create(accountId, timeToLive);
- }
-
- /* Increment the client count and see whether we have hit the maximum allowed clients yet. */
- int current = entry.incrementAndGet();
-
- if (current <= maxAllowed) {
- s_logger.trace("account (" + account.getAccountId() + "," + account.getAccountName() + ") has current count = " + current);
- return true;
- } else {
- long expireAfter = entry.getExpireDuration();
- // for this exception, we can just show the same message to user and admin users.
- String msg = "The given user has reached his/her account api limit, please retry after " + expireAfter + " ms.";
- s_logger.warn(msg);
- throw new RequestLimitException(msg);
- }
- }
-
- @Override
- public List> getCommands() {
- List> cmdList = new ArrayList>();
- cmdList.add(ResetApiLimitCmd.class);
- cmdList.add(GetApiLimitCmd.class);
- return cmdList;
- }
-
- @Override
- public void setTimeToLive(int timeToLive) {
- this.timeToLive = timeToLive;
- }
-
- @Override
- public void setMaxAllowed(int max) {
- maxAllowed = max;
-
- }
-
- @Override
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
-
- }
-
-}
diff --git a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/EhcacheLimitStore.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/EhcacheLimitStore.java
deleted file mode 100644
index 3840c49ba190..000000000000
--- a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/EhcacheLimitStore.java
+++ /dev/null
@@ -1,91 +0,0 @@
-// 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.ratelimit;
-
-import net.sf.ehcache.Ehcache;
-import net.sf.ehcache.Element;
-import net.sf.ehcache.constructs.blocking.BlockingCache;
-import net.sf.ehcache.constructs.blocking.LockTimeoutException;
-
-/**
- * A Limit store implementation using Ehcache.
- *
- */
-public class EhcacheLimitStore implements LimitStore {
-
- private BlockingCache cache;
-
- public void setCache(Ehcache cache) {
- BlockingCache ref;
-
- if (!(cache instanceof BlockingCache)) {
- ref = new BlockingCache(cache);
- cache.getCacheManager().replaceCacheWithDecoratedCache(cache, new BlockingCache(cache));
- } else {
- ref = (BlockingCache)cache;
- }
-
- this.cache = ref;
- }
-
- @Override
- public StoreEntry create(Long key, int timeToLive) {
- StoreEntryImpl result = new StoreEntryImpl(timeToLive);
- Element element = new Element(key, result);
- element.setTimeToLive(timeToLive);
- cache.put(element);
- return result;
- }
-
- @Override
- public StoreEntry get(Long key) {
-
- Element entry = null;
-
- try {
-
- /* This may block. */
- entry = cache.get(key);
- } catch (LockTimeoutException e) {
- throw new RuntimeException();
- } catch (RuntimeException e) {
-
- /* Release the lock that may have been acquired. */
- cache.put(new Element(key, null));
- }
-
- StoreEntry result = null;
-
- if (entry != null) {
-
- /*
- * We don't need to check isExpired() on the result, since ehcache takes care of expiring entries for us.
- * c.f. the get(Key) implementation in this class.
- */
- result = (StoreEntry)entry.getObjectValue();
- }
-
- return result;
- }
-
- @Override
- public void resetCounters() {
- cache.removeAll();
-
- }
-
-}
diff --git a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/LimitStore.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/LimitStore.java
deleted file mode 100644
index f564b389df74..000000000000
--- a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/LimitStore.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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.ratelimit;
-
-/**
- * Interface to define how an api limit store should work.
- *
- */
-public interface LimitStore {
-
- /**
- * Returns a store entry for the given account. A value of null means that there is no
- * such entry and the calling client must call create to avoid
- * other clients potentially being blocked without any hope of progressing. A non-null
- * entry means that it has not expired and can be used to determine whether the current client should be allowed to
- * proceed with the rate-limited action or not.
- *
- */
- StoreEntry get(Long account);
-
- /**
- * Creates a new store entry
- *
- * @param account
- * the user account, key to the store
- * @param timeToLiveInSecs
- * the positive time-to-live in seconds
- * @return a non-null entry
- */
- StoreEntry create(Long account, int timeToLiveInSecs);
-
- void resetCounters();
-
-}
diff --git a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/StoreEntry.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/StoreEntry.java
deleted file mode 100644
index ce493ac17907..000000000000
--- a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/StoreEntry.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// 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.ratelimit;
-
-/**
- * Interface for each entry in LimitStore.
- *
- */
-public interface StoreEntry {
-
- int getCounter();
-
- int incrementAndGet();
-
- boolean isExpired();
-
- long getExpireDuration(); /* seconds to reset counter */
-}
diff --git a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/StoreEntryImpl.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/StoreEntryImpl.java
deleted file mode 100644
index f870489fb45a..000000000000
--- a/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/StoreEntryImpl.java
+++ /dev/null
@@ -1,59 +0,0 @@
-// 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.ratelimit;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Implementation of limit store entry.
- *
- */
-public class StoreEntryImpl implements StoreEntry {
-
- private final long expiry;
-
- private final AtomicInteger counter;
-
- StoreEntryImpl(int timeToLive) {
- this.expiry = System.currentTimeMillis() + timeToLive * 1000;
- this.counter = new AtomicInteger(0);
- }
-
- @Override
- public boolean isExpired() {
- return System.currentTimeMillis() > expiry;
- }
-
- @Override
- public long getExpireDuration() {
- if (isExpired())
- return 0; // already expired
- else {
- return expiry - System.currentTimeMillis();
- }
- }
-
- @Override
- public int incrementAndGet() {
- return this.counter.incrementAndGet();
- }
-
- @Override
- public int getCounter() {
- return this.counter.get();
- }
-}
diff --git a/plugins/api/rate-limit/src/main/resources/META-INF/cloudstack/rate-limit/module.properties b/plugins/api/rate-limit/src/main/resources/META-INF/cloudstack/rate-limit/module.properties
deleted file mode 100644
index c998a87d9370..000000000000
--- a/plugins/api/rate-limit/src/main/resources/META-INF/cloudstack/rate-limit/module.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-# 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.
-name=rate-limit
-parent=api
\ No newline at end of file
diff --git a/plugins/api/rate-limit/src/main/resources/META-INF/cloudstack/rate-limit/spring-rate-limit-context.xml b/plugins/api/rate-limit/src/main/resources/META-INF/cloudstack/rate-limit/spring-rate-limit-context.xml
deleted file mode 100644
index d25c57cb0c5b..000000000000
--- a/plugins/api/rate-limit/src/main/resources/META-INF/cloudstack/rate-limit/spring-rate-limit-context.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
diff --git a/plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/ApiRateLimitTest.java b/plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/ApiRateLimitTest.java
deleted file mode 100644
index a16179eed51e..000000000000
--- a/plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/ApiRateLimitTest.java
+++ /dev/null
@@ -1,253 +0,0 @@
-// 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.ratelimit;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.Collections;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import javax.naming.ConfigurationException;
-
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import org.apache.cloudstack.api.response.ApiLimitResponse;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-
-import com.cloud.configuration.Config;
-import com.cloud.exception.RequestLimitException;
-import com.cloud.user.Account;
-import com.cloud.user.AccountService;
-import com.cloud.user.AccountVO;
-import com.cloud.user.User;
-import com.cloud.user.UserVO;
-
-public class ApiRateLimitTest {
-
- static ApiRateLimitServiceImpl s_limitService = new ApiRateLimitServiceImpl();
- static AccountService s_accountService = mock(AccountService.class);
- static ConfigurationDao s_configDao = mock(ConfigurationDao.class);
- private static long s_acctIdSeq = 5L;
- private static Account s_testAccount;
-
- @BeforeClass
-public static void setUp() throws ConfigurationException {
-
- when(s_configDao.getValue(Config.ApiLimitInterval.key())).thenReturn(null);
- when(s_configDao.getValue(Config.ApiLimitMax.key())).thenReturn(null);
- when(s_configDao.getValue(Config.ApiLimitCacheSize.key())).thenReturn(null);
- when(s_configDao.getValue(Config.ApiLimitEnabled.key())).thenReturn("true"); // enable api rate limiting
- s_limitService._configDao = s_configDao;
-
- s_limitService.configure("ApiRateLimitTest", Collections. emptyMap());
-
- s_limitService._accountService = s_accountService;
-
- // Standard responses
- AccountVO acct = new AccountVO(s_acctIdSeq);
- acct.setType(Account.ACCOUNT_TYPE_NORMAL);
- acct.setAccountName("demo");
- s_testAccount = acct;
-
- when(s_accountService.getAccount(5L)).thenReturn(s_testAccount);
- when(s_accountService.isRootAdmin(5L)).thenReturn(false);
- }
-
- @Before
- public void testSetUp() {
- // reset counter for each test
- s_limitService.resetApiLimit(null);
- }
-
- private User createFakeUser() {
- UserVO user = new UserVO();
- user.setAccountId(s_acctIdSeq);
- return user;
- }
-
- private boolean isUnderLimit(User key) {
- try {
- s_limitService.checkAccess(key, null);
- return true;
- } catch (RequestLimitException ex) {
- return false;
- }
- }
-
- @Test
- public void sequentialApiAccess() {
- int allowedRequests = 1;
- s_limitService.setMaxAllowed(allowedRequests);
- s_limitService.setTimeToLive(1);
-
- User key = createFakeUser();
- assertTrue("Allow for the first request", isUnderLimit(key));
-
- assertFalse("Second request should be blocked, since we assume that the two api " + " accesses take less than a second to perform", isUnderLimit(key));
- }
-
- @Test
- public void canDoReasonableNumberOfApiAccessPerSecond() throws Exception {
- int allowedRequests = 200;
- s_limitService.setMaxAllowed(allowedRequests);
- s_limitService.setTimeToLive(1);
-
- User key = createFakeUser();
-
- for (int i = 0; i < allowedRequests; i++) {
- assertTrue("We should allow " + allowedRequests + " requests per second, but failed at request " + i, isUnderLimit(key));
- }
-
- assertFalse("We should block >" + allowedRequests + " requests per second", isUnderLimit(key));
- }
-
- @Test
- public void multipleClientsCanAccessWithoutBlocking() throws Exception {
- int allowedRequests = 200;
- s_limitService.setMaxAllowed(allowedRequests);
- s_limitService.setTimeToLive(1);
-
- final User key = createFakeUser();
-
- int clientCount = allowedRequests;
- Runnable[] clients = new Runnable[clientCount];
- final boolean[] isUsable = new boolean[clientCount];
-
- final CountDownLatch startGate = new CountDownLatch(1);
-
- final CountDownLatch endGate = new CountDownLatch(clientCount);
-
- for (int i = 0; i < isUsable.length; ++i) {
- final int j = i;
- clients[j] = new Runnable() {
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run() {
- try {
- startGate.await();
-
- isUsable[j] = isUnderLimit(key);
-
- } catch (InterruptedException e) {
- e.printStackTrace();
- } finally {
- endGate.countDown();
- }
- }
- };
- }
-
- ExecutorService executor = Executors.newFixedThreadPool(clientCount);
-
- for (Runnable runnable : clients) {
- executor.execute(runnable);
- }
-
- startGate.countDown();
-
- endGate.await();
-
- for (boolean b : isUsable) {
- assertTrue("Concurrent client request should be allowed within limit", b);
- }
- }
-
- @Test
- public void expiryOfCounterIsSupported() throws Exception {
- int allowedRequests = 1;
- s_limitService.setMaxAllowed(allowedRequests);
- s_limitService.setTimeToLive(1);
-
- User key = createFakeUser();
-
- assertTrue("The first request should be allowed", isUnderLimit(key));
-
- // Allow the token to expire
- Thread.sleep(1020);
-
- assertTrue("Another request after interval should be allowed as well", isUnderLimit(key));
- }
-
- @Test
- public void verifyResetCounters() throws Exception {
- int allowedRequests = 1;
- s_limitService.setMaxAllowed(allowedRequests);
- s_limitService.setTimeToLive(1);
-
- User key = createFakeUser();
-
- assertTrue("The first request should be allowed", isUnderLimit(key));
-
- assertFalse("Another request should be blocked", isUnderLimit(key));
-
- s_limitService.resetApiLimit(key.getAccountId());
-
- assertTrue("Another request should be allowed after reset counter", isUnderLimit(key));
- }
-
- @Test
- public void verifySearchCounter() throws Exception {
- int allowedRequests = 10;
- s_limitService.setMaxAllowed(allowedRequests);
- s_limitService.setTimeToLive(1);
-
- User key = createFakeUser();
-
- for (int i = 0; i < 5; i++) {
- assertTrue("Issued 5 requests", isUnderLimit(key));
- }
-
- ApiLimitResponse response = s_limitService.searchApiLimit(s_testAccount);
- assertEquals("apiIssued is incorrect", 5, response.getApiIssued());
- assertEquals("apiAllowed is incorrect", 5, response.getApiAllowed());
- // using <= to account for inaccurate System.currentTimeMillis() clock in Windows environment
- assertTrue("expiredAfter is incorrect", response.getExpireAfter() <= 1000);
-
- }
-
- @Test
- public void disableApiLimit() throws Exception {
- try {
- int allowedRequests = 200;
- s_limitService.setMaxAllowed(allowedRequests);
- s_limitService.setTimeToLive(1);
- s_limitService.setEnabled(false);
-
- User key = createFakeUser();
-
- for (int i = 0; i < allowedRequests + 1; i++) {
- assertTrue("We should allow more than " + allowedRequests + " requests per second when api throttling is disabled.", isUnderLimit(key));
- }
- } finally {
- s_limitService.setEnabled(true); // enable api throttling to avoid
- // impacting other testcases
- }
-
- }
-
-}
diff --git a/plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/integration/APITest.java b/plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/integration/APITest.java
deleted file mode 100644
index bfe3468de667..000000000000
--- a/plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/integration/APITest.java
+++ /dev/null
@@ -1,204 +0,0 @@
-// 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
-// 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.ratelimit.integration;
-
-import java.io.BufferedReader;
-import java.io.EOFException;
-import java.io.InputStreamReader;
-import java.math.BigInteger;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.HashMap;
-import java.util.Iterator;
-
-import com.google.gson.Gson;
-
-import org.apache.cloudstack.api.response.SuccessResponse;
-
-import com.cloud.api.ApiGsonHelper;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-/**
- * Base class for API Test
- *
- */
-public abstract class APITest {
-
- protected String rootUrl = "http://localhost:8080/client/api";
- protected String sessionKey = null;
- protected String cookieToSent = null;
-
- /**
- * Sending an api request through Http GET
- * @param command command name
- * @param params command query parameters in a HashMap
- * @return http request response string
- */
- protected String sendRequest(String command, HashMap params) {
- try {
- // Construct query string
- StringBuilder sBuilder = new StringBuilder();
- sBuilder.append("command=");
- sBuilder.append(command);
- if (params != null && params.size() > 0) {
- Iterator keys = params.keySet().iterator();
- while (keys.hasNext()) {
- String key = keys.next();
- sBuilder.append("&");
- sBuilder.append(key);
- sBuilder.append("=");
- sBuilder.append(URLEncoder.encode(params.get(key), "UTF-8"));
- }
- }
-
- // Construct request url
- String reqUrl = rootUrl + "?" + sBuilder.toString();
-
- // Send Http GET request
- URL url = new URL(reqUrl);
- HttpURLConnection conn = (HttpURLConnection)url.openConnection();
- conn.setRequestMethod("GET");
-
- if (!command.equals("login") && cookieToSent != null) {
- // add the cookie to a request
- conn.setRequestProperty("Cookie", cookieToSent);
- }
- conn.connect();
-
- if (command.equals("login")) {
- // if it is login call, store cookie
- String headerName = null;
- for (int i = 1; (headerName = conn.getHeaderFieldKey(i)) != null; i++) {
- if (headerName.equals("Set-Cookie")) {
- String cookie = conn.getHeaderField(i);
- cookie = cookie.substring(0, cookie.indexOf(";"));
- String cookieName = cookie.substring(0, cookie.indexOf("="));
- String cookieValue = cookie.substring(cookie.indexOf("=") + 1, cookie.length());
- cookieToSent = cookieName + "=" + cookieValue;
- }
- }
- }
-
- // Get the response
- StringBuilder response = new StringBuilder();
- BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
- String line;
- try {
- while ((line = rd.readLine()) != null) {
- response.append(line);
- }
- } catch (EOFException ex) {
- // ignore this exception
- System.out.println("EOF exception due to java bug");
- }
- rd.close();
-
- return response.toString();
-
- } catch (Exception e) {
- throw new CloudRuntimeException("Problem with sending api request", e);
- }
- }
-
- protected String createMD5String(String password) {
- MessageDigest md5;
- try {
- md5 = MessageDigest.getInstance("MD5");
- } catch (NoSuchAlgorithmException e) {
- throw new CloudRuntimeException("Error", e);
- }
-
- md5.reset();
- BigInteger pwInt = new BigInteger(1, md5.digest(password.getBytes()));
-
- // make sure our MD5 hash value is 32 digits long...
- StringBuffer sb = new StringBuffer();
- String pwStr = pwInt.toString(16);
- int padding = 32 - pwStr.length();
- for (int i = 0; i < padding; i++) {
- sb.append('0');
- }
- sb.append(pwStr);
- return sb.toString();
- }
-
- protected Object fromSerializedString(String result, Class> repCls) {
- try {
- if (result != null && !result.isEmpty()) {
- // get real content
- int start;
- int end;
- if (repCls == LoginResponse.class || repCls == SuccessResponse.class) {
-
- start = result.indexOf('{', result.indexOf('{') + 1); // find
- // the
- // second
- // {
-
- end = result.lastIndexOf('}', result.lastIndexOf('}') - 1); // find
- // the
- // second
- // }
- // backwards
-
- } else {
- // get real content
- start = result.indexOf('{', result.indexOf('{', result.indexOf('{') + 1) + 1); // find
- // the
- // third
- // {
- end = result.lastIndexOf('}', result.lastIndexOf('}', result.lastIndexOf('}') - 1) - 1); // find
- // the
- // third
- // }
- // backwards
- }
- if (start < 0 || end < 0) {
- throw new CloudRuntimeException("Response format is wrong: " + result);
- }
- String content = result.substring(start, end + 1);
- Gson gson = ApiGsonHelper.getBuilder().create();
- return gson.fromJson(content, repCls);
- }
- return null;
- } catch (RuntimeException e) {
- throw new CloudRuntimeException("Caught runtime exception when doing GSON deserialization on: " + result, e);
- }
- }
-
- /**
- * Login call
- * @param username user name
- * @param password password (plain password, we will do MD5 hash here for you)
- * @return login response string
- */
- protected void login(String username, String password) {
- //String md5Psw = createMD5String(password);
- // send login request
- HashMap params = new HashMap();
- params.put("response", "json");
- params.put("username", username);
- params.put("password", password);
- String result = this.sendRequest("login", params);
- LoginResponse loginResp = (LoginResponse)fromSerializedString(result, LoginResponse.class);
- sessionKey = loginResp.getSessionkey();
-
- }
-}
diff --git a/plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/integration/LoginResponse.java b/plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/integration/LoginResponse.java
deleted file mode 100644
index 97cdccef8d66..000000000000
--- a/plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/integration/LoginResponse.java
+++ /dev/null
@@ -1,139 +0,0 @@
-// 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
-// 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.ratelimit.integration;
-
-import com.google.gson.annotations.SerializedName;
-
-import org.apache.cloudstack.api.BaseResponse;
-
-import com.cloud.serializer.Param;
-
-/**
- * Login Response object
- *
- */
-public class LoginResponse extends BaseResponse {
-
- @SerializedName("timeout")
- @Param(description = "session timeout period")
- private String timeout;
-
- @SerializedName("sessionkey")
- @Param(description = "login session key")
- private String sessionkey;
-
- @SerializedName("username")
- @Param(description = "login username")
- private String username;
-
- @SerializedName("userid")
- @Param(description = "login user internal uuid")
- private String userid;
-
- @SerializedName("firstname")
- @Param(description = "login user firstname")
- private String firstname;
-
- @SerializedName("lastname")
- @Param(description = "login user lastname")
- private String lastname;
-
- @SerializedName("account")
- @Param(description = "login user account type")
- private String account;
-
- @SerializedName("domainid")
- @Param(description = "login user domain id")
- private String domainid;
-
- @SerializedName("type")
- @Param(description = "login user type")
- private int type;
-
- public String getTimeout() {
- return timeout;
- }
-
- public void setTimeout(String timeout) {
- this.timeout = timeout;
- }
-
- public String getSessionkey() {
- return sessionkey;
- }
-
- public void setSessionkey(String sessionkey) {
- this.sessionkey = sessionkey;
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getUserid() {
- return userid;
- }
-
- public void setUserid(String userid) {
- this.userid = userid;
- }
-
- public String getFirstname() {
- return firstname;
- }
-
- public void setFirstname(String firstname) {
- this.firstname = firstname;
- }
-
- public String getLastname() {
- return lastname;
- }
-
- public void setLastname(String lastname) {
- this.lastname = lastname;
- }
-
- public String getAccount() {
- return account;
- }
-
- public void setAccount(String account) {
- this.account = account;
- }
-
- public String getDomainid() {
- return domainid;
- }
-
- public void setDomainid(String domainid) {
- this.domainid = domainid;
- }
-
- public int getType() {
- return type;
- }
-
- public void setType(int type) {
- this.type = type;
- }
-
-}
diff --git a/plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/integration/RateLimitIntegrationTest.java b/plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/integration/RateLimitIntegrationTest.java
deleted file mode 100644
index aa8167273473..000000000000
--- a/plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/integration/RateLimitIntegrationTest.java
+++ /dev/null
@@ -1,208 +0,0 @@
-// 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
-// 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.ratelimit.integration;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.util.HashMap;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import org.apache.cloudstack.api.response.ApiLimitResponse;
-import org.apache.cloudstack.api.response.SuccessResponse;
-
-import com.cloud.utils.exception.CloudRuntimeException;
-
-/**
- * Test fixture to do integration rate limit test.
- * Currently we commented out this test suite since it requires a real MS and Db running.
- */
-public class RateLimitIntegrationTest extends APITest {
-
- private static int apiMax = 25; // assuming ApiRateLimitService set api.throttling.max = 25
-
- @Before
- public void setup() {
- // always reset count for each testcase
- login("admin", "password");
-
- // issue reset api limit calls
- final HashMap params = new HashMap();
- params.put("response", "json");
- params.put("sessionkey", sessionKey);
- String resetResult = sendRequest("resetApiLimit", params);
- assertNotNull("Reset count failed!", fromSerializedString(resetResult, SuccessResponse.class));
-
- }
-
- @Test
- public void testNoApiLimitOnRootAdmin() throws Exception {
- // issue list Accounts calls
- final HashMap params = new HashMap();
- params.put("response", "json");
- params.put("listAll", "true");
- params.put("sessionkey", sessionKey);
- // assuming ApiRateLimitService set api.throttling.max = 25
- int clientCount = 26;
- Runnable[] clients = new Runnable[clientCount];
- final boolean[] isUsable = new boolean[clientCount];
-
- final CountDownLatch startGate = new CountDownLatch(1);
-
- final CountDownLatch endGate = new CountDownLatch(clientCount);
-
- for (int i = 0; i < isUsable.length; ++i) {
- final int j = i;
- clients[j] = new Runnable() {
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run() {
- try {
- startGate.await();
-
- sendRequest("listAccounts", params);
-
- isUsable[j] = true;
-
- } catch (CloudRuntimeException e) {
- isUsable[j] = false;
- e.printStackTrace();
- } catch (InterruptedException e) {
- e.printStackTrace();
- } finally {
- endGate.countDown();
- }
- }
- };
- }
-
- ExecutorService executor = Executors.newFixedThreadPool(clientCount);
-
- for (Runnable runnable : clients) {
- executor.execute(runnable);
- }
-
- startGate.countDown();
-
- endGate.await();
-
- int rejectCount = 0;
- for (int i = 0; i < isUsable.length; ++i) {
- if (!isUsable[i])
- rejectCount++;
- }
-
- assertEquals("No request should be rejected!", 0, rejectCount);
-
- }
-
- @Test
- public void testApiLimitOnUser() throws Exception {
- // log in using normal user
- login("demo", "password");
- // issue list Accounts calls
- final HashMap params = new HashMap();
- params.put("response", "json");
- params.put("listAll", "true");
- params.put("sessionkey", sessionKey);
-
- int clientCount = apiMax + 1;
- Runnable[] clients = new Runnable[clientCount];
- final boolean[] isUsable = new boolean[clientCount];
-
- final CountDownLatch startGate = new CountDownLatch(1);
-
- final CountDownLatch endGate = new CountDownLatch(clientCount);
-
- for (int i = 0; i < isUsable.length; ++i) {
- final int j = i;
- clients[j] = new Runnable() {
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run() {
- try {
- startGate.await();
-
- sendRequest("listAccounts", params);
-
- isUsable[j] = true;
-
- } catch (CloudRuntimeException e) {
- isUsable[j] = false;
- e.printStackTrace();
- } catch (InterruptedException e) {
- e.printStackTrace();
- } finally {
- endGate.countDown();
- }
- }
- };
- }
-
- ExecutorService executor = Executors.newFixedThreadPool(clientCount);
-
- for (Runnable runnable : clients) {
- executor.execute(runnable);
- }
-
- startGate.countDown();
-
- endGate.await();
-
- int rejectCount = 0;
- for (int i = 0; i < isUsable.length; ++i) {
- if (!isUsable[i])
- rejectCount++;
- }
-
- assertEquals("Only one request should be rejected!", 1, rejectCount);
-
- }
-
- @Test
- public void testGetApiLimitOnUser() throws Exception {
- // log in using normal user
- login("demo", "password");
-
- // issue an api call
- HashMap params = new HashMap();
- params.put("response", "json");
- params.put("listAll", "true");
- params.put("sessionkey", sessionKey);
- sendRequest("listAccounts", params);
-
- // issue get api limit calls
- final HashMap params2 = new HashMap();
- params2.put("response", "json");
- params2.put("sessionkey", sessionKey);
- String getResult = sendRequest("getApiLimit", params2);
- ApiLimitResponse getLimitResp = (ApiLimitResponse)fromSerializedString(getResult, ApiLimitResponse.class);
- assertEquals("Issued api count is incorrect!", 2, getLimitResp.getApiIssued()); // should be 2 apis issues plus this getlimit api
- assertEquals("Allowed api count is incorrect!", apiMax - 2, getLimitResp.getApiAllowed());
- }
-}
diff --git a/plugins/pom.xml b/plugins/pom.xml
index 7e693af5bbef..8662e345e9d4 100755
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -55,7 +55,6 @@
alert-handlers/syslog-alerts
api/discovery
- api/rate-limit
api/solidfire-intg-test
ca/root-ca