diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 17123b5f16..6cb36218b0 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -82,46 +82,6 @@ dashboard: # Maximum allowed datapoints fetched by widgets max_datapoints_limit: "${DASHBOARD_MAX_DATAPOINTS_LIMIT:50000}" -#Quota parameters -quota: - host: - # Max allowed number of API requests in interval for single host - limit: "${QUOTA_HOST_LIMIT:10000}" - # Interval duration - intervalMs: "${QUOTA_HOST_INTERVAL_MS:60000}" - # Maximum silence duration for host after which Host removed from QuotaService. Must be bigger than intervalMs - ttlMs: "${QUOTA_HOST_TTL_MS:60000}" - # Interval for scheduled task that cleans expired records. TTL is used for expiring - cleanPeriodMs: "${QUOTA_HOST_CLEAN_PERIOD_MS:300000}" - # Enable Host API Limits - enabled: "${QUOTA_HOST_ENABLED:false}" - # Array of whitelist hosts - whitelist: "${QUOTA_HOST_WHITELIST:localhost,127.0.0.1}" - # Array of blacklist hosts - blacklist: "${QUOTA_HOST_BLACKLIST:}" - log: - topSize: "${QUOTA_HOST_LOG_TOP_SIZE:10}" - intervalMin: "${QUOTA_HOST_LOG_INTERVAL_MIN:2}" - rule: - tenant: - # Max allowed number of API requests in interval for single tenant - limit: "${QUOTA_TENANT_LIMIT:100000}" - # Interval duration - intervalMs: "${QUOTA_TENANT_INTERVAL_MS:60000}" - # Maximum silence duration for tenant after which Tenant removed from QuotaService. Must be bigger than intervalMs - ttlMs: "${QUOTA_TENANT_TTL_MS:60000}" - # Interval for scheduled task that cleans expired records. TTL is used for expiring - cleanPeriodMs: "${QUOTA_TENANT_CLEAN_PERIOD_MS:300000}" - # Enable Host API Limits - enabled: "${QUOTA_TENANT_ENABLED:true}" - # Array of whitelist tenants - whitelist: "${QUOTA_TENANT_WHITELIST:}" - # Array of blacklist tenants - blacklist: "${QUOTA_HOST_TENANT_BLACKLIST:}" - log: - topSize: "${QUOTA_TENANT_LOG_TOP_SIZE:10}" - intervalMin: "${QUOTA_TENANT_LOG_INTERVAL_MIN:2}" - database: entities: type: "${DATABASE_ENTITIES_TYPE:sql}" # cassandra OR sql diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java index 0e2a794a45..9cf36e3096 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java @@ -72,12 +72,6 @@ public class CoapTransportResource extends CoapResource { @Override public void handleGET(CoapExchange exchange) { - if (transportContext.getQuotaService().isQuotaExceeded(exchange.getSourceAddress().getHostAddress())) { - log.warn("CoAP Quota exceeded for [{}:{}] . Disconnect", exchange.getSourceAddress().getHostAddress(), exchange.getSourcePort()); - exchange.respond(ResponseCode.BAD_REQUEST); - return; - } - Optional featureType = getFeatureType(exchange.advanced().getRequest()); if (!featureType.isPresent()) { log.trace("Missing feature type parameter"); @@ -108,12 +102,6 @@ public class CoapTransportResource extends CoapResource { @Override public void handlePOST(CoapExchange exchange) { - if (transportContext.getQuotaService().isQuotaExceeded(exchange.getSourceAddress().getHostAddress())) { - log.warn("CoAP Quota exceeded for [{}:{}] . Disconnect", exchange.getSourceAddress().getHostAddress(), exchange.getSourcePort()); - exchange.respond(ResponseCode.BAD_REQUEST); - return; - } - Optional featureType = getFeatureType(exchange.advanced().getRequest()); if (!featureType.isPresent()) { log.trace("Missing feature type parameter"); diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportService.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportService.java index 278ca6d8c5..c0bd7f9c1b 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportService.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportService.java @@ -27,8 +27,6 @@ import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; import org.thingsboard.server.common.transport.SessionMsgProcessor; import org.thingsboard.server.common.transport.auth.DeviceAuthService; -import org.thingsboard.server.common.transport.quota.QuotaService; -import org.thingsboard.server.common.transport.quota.host.HostRequestsQuotaService; import org.thingsboard.server.transport.coap.adaptors.CoapTransportAdaptor; import javax.annotation.PostConstruct; diff --git a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java index b40fbc194f..18458d13ad 100644 --- a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java +++ b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java @@ -75,9 +75,6 @@ public class DeviceApiController { @RequestParam(value = "sharedKeys", required = false, defaultValue = "") String sharedKeys, HttpServletRequest httpRequest) { DeferredResult responseWriter = new DeferredResult<>(); - if (quotaExceeded(httpRequest, responseWriter)) { - return responseWriter; - } transportContext.getTransportService().process(ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> { GetAttributeRequestMsg.Builder request = GetAttributeRequestMsg.newBuilder().setRequestId(0); @@ -100,9 +97,6 @@ public class DeviceApiController { public DeferredResult postDeviceAttributes(@PathVariable("deviceToken") String deviceToken, @RequestBody String json, HttpServletRequest request) { DeferredResult responseWriter = new DeferredResult<>(); - if (quotaExceeded(request, responseWriter)) { - return responseWriter; - } transportContext.getTransportService().process(ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> { TransportService transportService = transportContext.getTransportService(); @@ -116,9 +110,6 @@ public class DeviceApiController { public DeferredResult postTelemetry(@PathVariable("deviceToken") String deviceToken, @RequestBody String json, HttpServletRequest request) { DeferredResult responseWriter = new DeferredResult(); - if (quotaExceeded(request, responseWriter)) { - return responseWriter; - } transportContext.getTransportService().process(ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> { TransportService transportService = transportContext.getTransportService(); @@ -133,9 +124,6 @@ public class DeviceApiController { @RequestParam(value = "timeout", required = false, defaultValue = "0") long timeout, HttpServletRequest httpRequest) { DeferredResult responseWriter = new DeferredResult<>(); - if (quotaExceeded(httpRequest, responseWriter)) { - return responseWriter; - } transportContext.getTransportService().process(ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> { TransportService transportService = transportContext.getTransportService(); @@ -153,9 +141,6 @@ public class DeviceApiController { @PathVariable("requestId") Integer requestId, @RequestBody String json, HttpServletRequest request) { DeferredResult responseWriter = new DeferredResult(); - if (quotaExceeded(request, responseWriter)) { - return responseWriter; - } transportContext.getTransportService().process(ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> { TransportService transportService = transportContext.getTransportService(); @@ -168,9 +153,6 @@ public class DeviceApiController { public DeferredResult postRpcRequest(@PathVariable("deviceToken") String deviceToken, @RequestBody String json, HttpServletRequest httpRequest) { DeferredResult responseWriter = new DeferredResult(); - if (quotaExceeded(httpRequest, responseWriter)) { - return responseWriter; - } transportContext.getTransportService().process(ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> { JsonObject request = new JsonParser().parse(json).getAsJsonObject(); @@ -189,9 +171,6 @@ public class DeviceApiController { @RequestParam(value = "timeout", required = false, defaultValue = "0") long timeout, HttpServletRequest httpRequest) { DeferredResult responseWriter = new DeferredResult<>(); - if (quotaExceeded(httpRequest, responseWriter)) { - return responseWriter; - } transportContext.getTransportService().process(ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> { TransportService transportService = transportContext.getTransportService(); @@ -204,16 +183,6 @@ public class DeviceApiController { return responseWriter; } - private boolean quotaExceeded(HttpServletRequest request, DeferredResult responseWriter) { - if (transportContext.getQuotaService().isQuotaExceeded(request.getRemoteAddr())) { - log.warn("REST Quota exceeded for [{}] . Disconnect", request.getRemoteAddr()); - responseWriter.setResult(new ResponseEntity<>(HttpStatus.BANDWIDTH_LIMIT_EXCEEDED)); - return true; - } else { - return false; - } - } - private static class DeviceAuthCallback implements TransportServiceCallback { private final TransportContext transportContext; private final DeferredResult responseWriter; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportContext.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportContext.java index 538daa1f9c..184ac49c25 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportContext.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportContext.java @@ -28,7 +28,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; import org.thingsboard.server.common.transport.TransportContext; import org.thingsboard.server.common.transport.TransportService; -import org.thingsboard.server.common.transport.quota.host.HostRequestsQuotaService; import org.thingsboard.server.kafka.TbNodeIdProvider; import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index 46a890f19e..da8b3a62ca 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -42,7 +42,6 @@ import org.thingsboard.server.common.transport.SessionMsgListener; import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.adaptor.AdaptorException; -import org.thingsboard.server.common.transport.quota.QuotaService; import org.thingsboard.server.common.msg.EncryptionUtil; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto; @@ -92,7 +91,6 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement private final MqttTransportContext context; private final MqttTransportAdaptor adaptor; private final TransportService transportService; - private final QuotaService quotaService; private final SslHandler sslHandler; private final ConcurrentMap mqttQoSMap; @@ -106,7 +104,6 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement this.context = context; this.transportService = context.getTransportService(); this.adaptor = context.getAdaptor(); - this.quotaService = context.getQuotaService(); this.sslHandler = context.getSslHandler(); this.mqttQoSMap = new ConcurrentHashMap<>(); this.deviceSessionCtx = new DeviceSessionCtx(sessionId, mqttQoSMap); @@ -129,13 +126,6 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement processDisconnect(ctx); return; } - - if (quotaService.isQuotaExceeded(address.getHostName())) { - log.warn("MQTT Quota exceeded for [{}:{}] . Disconnect", address.getHostName(), address.getPort()); - processDisconnect(ctx); - return; - } - deviceSessionCtx.setChannel(ctx); switch (msg.fixedHeader().messageType()) { case CONNECT: diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportContext.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportContext.java index ab429829e4..58aaa78989 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportContext.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportContext.java @@ -20,7 +20,6 @@ import lombok.Data; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.thingsboard.server.common.transport.quota.host.HostRequestsQuotaService; import org.thingsboard.server.kafka.TbNodeIdProvider; import javax.annotation.PostConstruct; @@ -43,9 +42,6 @@ public class TransportContext { @Autowired private TbNodeIdProvider nodeIdProvider; - @Autowired(required = false) - private HostRequestsQuotaService quotaService; - @Getter private ExecutorService executor; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/AbstractQuotaService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/AbstractQuotaService.java deleted file mode 100644 index 9d7bd1720c..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/AbstractQuotaService.java +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota; - -import org.thingsboard.server.common.transport.quota.inmemory.IntervalRegistryCleaner; -import org.thingsboard.server.common.transport.quota.inmemory.IntervalRegistryLogger; -import org.thingsboard.server.common.transport.quota.inmemory.KeyBasedIntervalRegistry; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; - -public class AbstractQuotaService implements QuotaService { - - private final KeyBasedIntervalRegistry requestRegistry; - private final RequestLimitPolicy requestsPolicy; - private final IntervalRegistryCleaner registryCleaner; - private final IntervalRegistryLogger registryLogger; - private final boolean enabled; - - public AbstractQuotaService(KeyBasedIntervalRegistry requestRegistry, RequestLimitPolicy requestsPolicy, - IntervalRegistryCleaner registryCleaner, IntervalRegistryLogger registryLogger, - boolean enabled) { - this.requestRegistry = requestRegistry; - this.requestsPolicy = requestsPolicy; - this.registryCleaner = registryCleaner; - this.registryLogger = registryLogger; - this.enabled = enabled; - } - - @PostConstruct - public void init() { - if (enabled) { - registryCleaner.schedule(); - registryLogger.schedule(); - } - } - - @PreDestroy - public void close() { - if (enabled) { - registryCleaner.stop(); - registryLogger.stop(); - } - } - - @Override - public boolean isQuotaExceeded(String key) { - if (enabled) { - long count = requestRegistry.tick(key); - return !requestsPolicy.isValid(count); - } - return false; - } -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/Clock.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/Clock.java deleted file mode 100644 index dcc2d2306c..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/Clock.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota; - -/** - * @author Vitaliy Paromskiy - * @version 1.0 - */ -public final class Clock { - - private static long time = 0L; - - private Clock() { - } - - - public static long millis() { - return time == 0 ? System.currentTimeMillis() : time; - } - - public static void setMillis(long millis) { - time = millis; - } - - public static void shift(long delta) { - time += delta; - } - - public static void reset() { - time = 0; - } -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/QuotaService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/QuotaService.java deleted file mode 100644 index f841749049..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/QuotaService.java +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota; - -/** - * @author Vitaliy Paromskiy - * @version 1.0 - */ -public interface QuotaService { - - boolean isQuotaExceeded(String key); -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/RequestLimitPolicy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/RequestLimitPolicy.java deleted file mode 100644 index 0ff1230b1c..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/RequestLimitPolicy.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota; - - -public abstract class RequestLimitPolicy { - - private final long limit; - - public RequestLimitPolicy(long limit) { - this.limit = limit; - } - - public boolean isValid(long currentValue) { - return currentValue <= limit; - } -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/host/HostIntervalRegistryCleaner.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/host/HostIntervalRegistryCleaner.java deleted file mode 100644 index ea75f5dc09..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/host/HostIntervalRegistryCleaner.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota.host; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.quota.inmemory.IntervalRegistryCleaner; - -@Component -public class HostIntervalRegistryCleaner extends IntervalRegistryCleaner { - - public HostIntervalRegistryCleaner(HostRequestIntervalRegistry intervalRegistry, - @Value("${quota.host.cleanPeriodMs}") long cleanPeriodMs) { - super(intervalRegistry, cleanPeriodMs); - } -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/host/HostIntervalRegistryLogger.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/host/HostIntervalRegistryLogger.java deleted file mode 100644 index 65767f1648..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/host/HostIntervalRegistryLogger.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota.host; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.quota.inmemory.IntervalRegistryLogger; - -import java.util.Map; -import java.util.concurrent.TimeUnit; - -@Component -@Slf4j -public class HostIntervalRegistryLogger extends IntervalRegistryLogger { - - private final long logIntervalMin; - - public HostIntervalRegistryLogger(@Value("${quota.host.log.topSize}") int topSize, - @Value("${quota.host.log.intervalMin}") long logIntervalMin, - HostRequestIntervalRegistry intervalRegistry) { - super(topSize, logIntervalMin, intervalRegistry); - this.logIntervalMin = logIntervalMin; - } - - protected void log(Map top, int uniqHosts, long requestsCount) { - long rps = requestsCount / TimeUnit.MINUTES.toSeconds(logIntervalMin); - StringBuilder builder = new StringBuilder("Quota Statistic : "); - builder.append("uniqHosts : ").append(uniqHosts).append("; "); - builder.append("requestsCount : ").append(requestsCount).append("; "); - builder.append("RPS : ").append(rps).append(" "); - builder.append("top -> "); - for (Map.Entry host : top.entrySet()) { - builder.append(host.getKey()).append(" : ").append(host.getValue()).append("; "); - } - - log.info(builder.toString()); - } -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/host/HostRequestIntervalRegistry.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/host/HostRequestIntervalRegistry.java deleted file mode 100644 index 9b3b4614e4..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/host/HostRequestIntervalRegistry.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota.host; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.quota.inmemory.KeyBasedIntervalRegistry; - -/** - * @author Vitaliy Paromskiy - * @version 1.0 - */ -@Component -@Slf4j -public class HostRequestIntervalRegistry extends KeyBasedIntervalRegistry { - - public HostRequestIntervalRegistry(@Value("${quota.host.intervalMs}") long intervalDurationMs, - @Value("${quota.host.ttlMs}") long ttlMs, - @Value("${quota.host.whitelist}") String whiteList, - @Value("${quota.host.blacklist}") String blackList) { - super(intervalDurationMs, ttlMs, whiteList, blackList, "host"); - } -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/host/HostRequestLimitPolicy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/host/HostRequestLimitPolicy.java deleted file mode 100644 index eeef9247e6..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/host/HostRequestLimitPolicy.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota.host; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.quota.RequestLimitPolicy; - -/** - * @author Vitaliy Paromskiy - * @version 1.0 - */ -@Component -public class HostRequestLimitPolicy extends RequestLimitPolicy { - - public HostRequestLimitPolicy(@Value("${quota.host.limit}") long limit) { - super(limit); - } - -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/host/HostRequestsQuotaService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/host/HostRequestsQuotaService.java deleted file mode 100644 index 69342b538b..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/host/HostRequestsQuotaService.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota.host; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import org.thingsboard.server.common.transport.quota.AbstractQuotaService; - -/** - * @author Vitaliy Paromskiy - * @version 1.0 - */ -@Service -@Slf4j -public class HostRequestsQuotaService extends AbstractQuotaService { - - public HostRequestsQuotaService(HostRequestIntervalRegistry requestRegistry, HostRequestLimitPolicy requestsPolicy, - HostIntervalRegistryCleaner registryCleaner, HostIntervalRegistryLogger registryLogger, - @Value("${quota.host.enabled}") boolean enabled) { - super(requestRegistry, requestsPolicy, registryCleaner, registryLogger, enabled); - } - -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/inmemory/IntervalCount.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/inmemory/IntervalCount.java deleted file mode 100644 index 0ac6c9b5e2..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/inmemory/IntervalCount.java +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota.inmemory; - - -import org.thingsboard.server.common.transport.quota.Clock; - -import java.util.concurrent.atomic.LongAdder; - -/** - * @author Vitaliy Paromskiy - * @version 1.0 - */ -public class IntervalCount { - - private final LongAdder adder = new LongAdder(); - private final long intervalDurationMs; - private volatile long startTime; - private volatile long lastTickTime; - - public IntervalCount(long intervalDurationMs) { - this.intervalDurationMs = intervalDurationMs; - startTime = Clock.millis(); - } - - public long resetIfExpiredAndTick() { - if (isExpired()) { - reset(); - } - tick(); - return adder.sum(); - } - - public long silenceDuration() { - return Clock.millis() - lastTickTime; - } - - public long getCount() { - return adder.sum(); - } - - private void tick() { - adder.add(1); - lastTickTime = Clock.millis(); - } - - private void reset() { - adder.reset(); - startTime = Clock.millis(); - } - - private boolean isExpired() { - return (Clock.millis() - startTime) > intervalDurationMs; - } -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/inmemory/IntervalRegistryCleaner.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/inmemory/IntervalRegistryCleaner.java deleted file mode 100644 index 0c510ff815..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/inmemory/IntervalRegistryCleaner.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota.inmemory; - -import lombok.extern.slf4j.Slf4j; - -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -/** - * @author Vitaliy Paromskiy - * @version 1.0 - */ -@Slf4j -public abstract class IntervalRegistryCleaner { - - private final KeyBasedIntervalRegistry intervalRegistry; - private final long cleanPeriodMs; - private ScheduledExecutorService executor; - - public IntervalRegistryCleaner(KeyBasedIntervalRegistry intervalRegistry, long cleanPeriodMs) { - this.intervalRegistry = intervalRegistry; - this.cleanPeriodMs = cleanPeriodMs; - } - - public void schedule() { - if (executor != null) { - throw new IllegalStateException("Registry Cleaner already scheduled"); - } - executor = Executors.newSingleThreadScheduledExecutor(); - executor.scheduleAtFixedRate(this::clean, cleanPeriodMs, cleanPeriodMs, TimeUnit.MILLISECONDS); - } - - public void stop() { - if (executor != null) { - executor.shutdown(); - } - } - - public void clean() { - try { - intervalRegistry.clean(); - } catch (RuntimeException ex) { - log.error("Could not clear Interval Registry", ex); - } - } - -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/inmemory/IntervalRegistryLogger.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/inmemory/IntervalRegistryLogger.java deleted file mode 100644 index 30399a140f..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/inmemory/IntervalRegistryLogger.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota.inmemory; - -import com.google.common.collect.MinMaxPriorityQueue; -import lombok.extern.slf4j.Slf4j; - -import java.util.Comparator; -import java.util.Map; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** - * @author Vitaliy Paromskiy - * @version 1.0 - */ -@Slf4j -public abstract class IntervalRegistryLogger { - - private final int topSize; - private final KeyBasedIntervalRegistry intervalRegistry; - private final long logIntervalMin; - private ScheduledExecutorService executor; - - public IntervalRegistryLogger(int topSize, long logIntervalMin, KeyBasedIntervalRegistry intervalRegistry) { - this.topSize = topSize; - this.logIntervalMin = logIntervalMin; - this.intervalRegistry = intervalRegistry; - } - - public void schedule() { - if (executor != null) { - throw new IllegalStateException("Registry Cleaner already scheduled"); - } - executor = Executors.newSingleThreadScheduledExecutor(); - executor.scheduleAtFixedRate(this::logStatistic, logIntervalMin, logIntervalMin, TimeUnit.MINUTES); - } - - public void stop() { - if (executor != null) { - executor.shutdown(); - } - } - - public void logStatistic() { - Map registryContent = intervalRegistry.getContent(); - int uniqHosts = registryContent.size(); - long requestsCount = registryContent.values().stream().mapToLong(i -> i).sum(); - Map top = getTopElements(registryContent); - log(top, uniqHosts, requestsCount); - } - - protected Map getTopElements(Map countMap) { - MinMaxPriorityQueue> topQueue = MinMaxPriorityQueue - .orderedBy(Comparator.comparing((Function, Long>) Map.Entry::getValue).reversed()) - .maximumSize(topSize) - .create(countMap.entrySet()); - - return topQueue.stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - } - - protected abstract void log(Map top, int uniqHosts, long requestsCount); -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/inmemory/KeyBasedIntervalRegistry.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/inmemory/KeyBasedIntervalRegistry.java deleted file mode 100644 index 0b0fef85e5..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/inmemory/KeyBasedIntervalRegistry.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota.inmemory; - -import com.google.common.collect.Sets; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; - -@Slf4j -public abstract class KeyBasedIntervalRegistry { - - private final Map hostCounts = new ConcurrentHashMap<>(); - private final long intervalDurationMs; - private final long ttlMs; - private final Set whiteList; - private final Set blackList; - - public KeyBasedIntervalRegistry(long intervalDurationMs, long ttlMs, String whiteList, String blackList, String name) { - this.intervalDurationMs = intervalDurationMs; - this.ttlMs = ttlMs; - this.whiteList = Sets.newHashSet(StringUtils.split(whiteList, ',')); - this.blackList = Sets.newHashSet(StringUtils.split(blackList, ',')); - validate(name); - } - - private void validate(String name) { - if (ttlMs < intervalDurationMs) { - log.warn("TTL for {} IntervalRegistry [{}] smaller than interval duration [{}]", name, ttlMs, intervalDurationMs); - } - log.info("Start {} KeyBasedIntervalRegistry with whitelist {}", name, whiteList); - log.info("Start {} KeyBasedIntervalRegistry with blacklist {}", name, blackList); - } - - public long tick(String clientHostId) { - IntervalCount intervalCount = hostCounts.computeIfAbsent(clientHostId, s -> new IntervalCount(intervalDurationMs)); - long currentCount = intervalCount.resetIfExpiredAndTick(); - if (whiteList.contains(clientHostId)) { - return 0; - } else if (blackList.contains(clientHostId)) { - return Long.MAX_VALUE; - } - return currentCount; - } - - public void clean() { - hostCounts.entrySet().removeIf(entry -> entry.getValue().silenceDuration() > ttlMs); - } - - public Map getContent() { - return hostCounts.entrySet().stream() - .collect(Collectors.toMap( - Map.Entry::getKey, - interval -> interval.getValue().getCount())); - } -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/tenant/TenantIntervalRegistryCleaner.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/tenant/TenantIntervalRegistryCleaner.java deleted file mode 100644 index 47b427840a..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/tenant/TenantIntervalRegistryCleaner.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota.tenant; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.quota.inmemory.IntervalRegistryCleaner; - -@Component -@ConditionalOnProperty(prefix = "quota.rule.tenant", value = "enabled", havingValue = "true", matchIfMissing = false) -public class TenantIntervalRegistryCleaner extends IntervalRegistryCleaner { - - public TenantIntervalRegistryCleaner(TenantMsgsIntervalRegistry intervalRegistry, - @Value("${quota.rule.tenant.cleanPeriodMs}") long cleanPeriodMs) { - super(intervalRegistry, cleanPeriodMs); - } -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/tenant/TenantIntervalRegistryLogger.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/tenant/TenantIntervalRegistryLogger.java deleted file mode 100644 index 3bdcf93d07..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/tenant/TenantIntervalRegistryLogger.java +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota.tenant; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.quota.inmemory.IntervalRegistryLogger; - -import java.util.Map; -import java.util.concurrent.TimeUnit; - -@Slf4j -@Component -@ConditionalOnProperty(prefix = "quota.rule.tenant", value = "enabled", havingValue = "true", matchIfMissing = false) -public class TenantIntervalRegistryLogger extends IntervalRegistryLogger { - - private final long logIntervalMin; - - public TenantIntervalRegistryLogger(@Value("${quota.rule.tenant.log.topSize}") int topSize, - @Value("${quota.rule.tenant.log.intervalMin}") long logIntervalMin, - TenantMsgsIntervalRegistry intervalRegistry) { - super(topSize, logIntervalMin, intervalRegistry); - this.logIntervalMin = logIntervalMin; - } - - protected void log(Map top, int uniqHosts, long requestsCount) { - long rps = requestsCount / TimeUnit.MINUTES.toSeconds(logIntervalMin); - StringBuilder builder = new StringBuilder("Tenant Quota Statistic : "); - builder.append("uniqTenants : ").append(uniqHosts).append("; "); - builder.append("requestsCount : ").append(requestsCount).append("; "); - builder.append("RPS : ").append(rps).append(" "); - builder.append("top -> "); - for (Map.Entry host : top.entrySet()) { - builder.append(host.getKey()).append(" : ").append(host.getValue()).append("; "); - } - - log.info(builder.toString()); - } -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/tenant/TenantMsgsIntervalRegistry.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/tenant/TenantMsgsIntervalRegistry.java deleted file mode 100644 index 3402e62472..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/tenant/TenantMsgsIntervalRegistry.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota.tenant; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.quota.inmemory.KeyBasedIntervalRegistry; - -@Component -@ConditionalOnProperty(prefix = "quota.rule.tenant", value = "enabled", havingValue = "true", matchIfMissing = false) -public class TenantMsgsIntervalRegistry extends KeyBasedIntervalRegistry { - - public TenantMsgsIntervalRegistry(@Value("${quota.rule.tenant.intervalMs}") long intervalDurationMs, - @Value("${quota.rule.tenant.ttlMs}") long ttlMs, - @Value("${quota.rule.tenant.whitelist}") String whiteList, - @Value("${quota.rule.tenant.blacklist}") String blackList) { - super(intervalDurationMs, ttlMs, whiteList, blackList, "Rule Tenant"); - } -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/tenant/TenantQuotaService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/tenant/TenantQuotaService.java deleted file mode 100644 index 875a666a28..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/tenant/TenantQuotaService.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota.tenant; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.quota.AbstractQuotaService; - -@Component -@ConditionalOnProperty(prefix = "quota.rule.tenant", value = "enabled", havingValue = "true", matchIfMissing = false) -public class TenantQuotaService extends AbstractQuotaService { - - public TenantQuotaService(TenantMsgsIntervalRegistry requestRegistry, TenantRequestLimitPolicy requestsPolicy, - TenantIntervalRegistryCleaner registryCleaner, TenantIntervalRegistryLogger registryLogger, - @Value("${quota.rule.tenant.enabled}") boolean enabled) { - super(requestRegistry, requestsPolicy, registryCleaner, registryLogger, enabled); - } -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/tenant/TenantRequestLimitPolicy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/tenant/TenantRequestLimitPolicy.java deleted file mode 100644 index c5dfc40480..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/quota/tenant/TenantRequestLimitPolicy.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota.tenant; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.quota.RequestLimitPolicy; - -@Component -@ConditionalOnProperty(prefix = "quota.rule.tenant", value = "enabled", havingValue = "true", matchIfMissing = false) -public class TenantRequestLimitPolicy extends RequestLimitPolicy { - - public TenantRequestLimitPolicy(@Value("${quota.rule.tenant.limit}") long limit) { - super(limit); - } -} diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/ClockTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/ClockTest.java deleted file mode 100644 index 403bdc65b3..0000000000 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/ClockTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * @author Vitaliy Paromskiy - * @version 1.0 - */ -public class ClockTest { - - @Before - public void init() { - Clock.reset(); - } - - @After - public void clear() { - Clock.reset(); - } - - @Test - public void defaultClockUseSystemTime() { - assertFalse(Clock.millis() > System.currentTimeMillis()); - } - - @Test - public void timeCanBeSet() { - Clock.setMillis(100L); - assertEquals(100L, Clock.millis()); - } - - @Test - public void clockCanBeReseted() { - Clock.setMillis(100L); - assertEquals(100L, Clock.millis()); - Clock.reset(); - assertFalse(Clock.millis() > System.currentTimeMillis()); - } - - @Test - public void timeIsShifted() { - Clock.setMillis(100L); - Clock.shift(50L); - assertEquals(150L, Clock.millis()); - } - -} \ No newline at end of file diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/HostRequestLimitPolicyTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/HostRequestLimitPolicyTest.java deleted file mode 100644 index 07e03ef0ac..0000000000 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/HostRequestLimitPolicyTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota; - -import org.junit.Test; -import org.thingsboard.server.common.transport.quota.host.HostRequestLimitPolicy; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * @author Vitaliy Paromskiy - * @version 1.0 - */ -public class HostRequestLimitPolicyTest { - - private HostRequestLimitPolicy limitPolicy = new HostRequestLimitPolicy(10L); - - @Test - public void ifCurrentValueLessThenLimitItIsValid() { - assertTrue(limitPolicy.isValid(9)); - } - - @Test - public void ifCurrentValueEqualsToLimitItIsValid() { - assertTrue(limitPolicy.isValid(10)); - } - - @Test - public void ifCurrentValueGreaterThenLimitItIsValid() { - assertFalse(limitPolicy.isValid(11)); - } - -} \ No newline at end of file diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/HostRequestsQuotaServiceTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/HostRequestsQuotaServiceTest.java deleted file mode 100644 index 37441e9d41..0000000000 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/HostRequestsQuotaServiceTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota; - -import org.junit.Before; -import org.junit.Test; -import org.thingsboard.server.common.transport.quota.host.HostIntervalRegistryCleaner; -import org.thingsboard.server.common.transport.quota.host.HostIntervalRegistryLogger; -import org.thingsboard.server.common.transport.quota.host.HostRequestIntervalRegistry; -import org.thingsboard.server.common.transport.quota.host.HostRequestLimitPolicy; -import org.thingsboard.server.common.transport.quota.host.HostRequestsQuotaService; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.*; - -/** - * @author Vitaliy Paromskiy - * @version 1.0 - */ -public class HostRequestsQuotaServiceTest { - - private HostRequestsQuotaService quotaService; - - private HostRequestIntervalRegistry requestRegistry = mock(HostRequestIntervalRegistry.class); - private HostRequestLimitPolicy requestsPolicy = mock(HostRequestLimitPolicy.class); - private HostIntervalRegistryCleaner registryCleaner = mock(HostIntervalRegistryCleaner.class); - private HostIntervalRegistryLogger registryLogger = mock(HostIntervalRegistryLogger.class); - - @Before - public void init() { - quotaService = new HostRequestsQuotaService(requestRegistry, requestsPolicy, registryCleaner, registryLogger, true); - } - - @Test - public void quotaExceededIfRequestCountBiggerThanAllowed() { - when(requestRegistry.tick("key")).thenReturn(10L); - when(requestsPolicy.isValid(10L)).thenReturn(false); - - assertTrue(quotaService.isQuotaExceeded("key")); - - verify(requestRegistry).tick("key"); - verify(requestsPolicy).isValid(10L); - verifyNoMoreInteractions(requestRegistry, requestsPolicy); - } - - @Test - public void quotaNotExceededIfRequestCountLessThanAllowed() { - when(requestRegistry.tick("key")).thenReturn(10L); - when(requestsPolicy.isValid(10L)).thenReturn(true); - - assertFalse(quotaService.isQuotaExceeded("key")); - - verify(requestRegistry).tick("key"); - verify(requestsPolicy).isValid(10L); - verifyNoMoreInteractions(requestRegistry, requestsPolicy); - } - - @Test - public void serviceCanBeDisabled() { - quotaService = new HostRequestsQuotaService(requestRegistry, requestsPolicy, registryCleaner, registryLogger, false); - assertFalse(quotaService.isQuotaExceeded("key")); - verifyNoMoreInteractions(requestRegistry, requestsPolicy); - } -} \ No newline at end of file diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/inmemory/HostRequestIntervalRegistryTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/inmemory/HostRequestIntervalRegistryTest.java deleted file mode 100644 index b49dd00bc9..0000000000 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/inmemory/HostRequestIntervalRegistryTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota.inmemory; - -import org.junit.Before; -import org.junit.Test; -import org.thingsboard.server.common.transport.quota.host.HostRequestIntervalRegistry; - -import static org.junit.Assert.assertEquals; - -/** - * @author Vitaliy Paromskiy - * @version 1.0 - */ -public class HostRequestIntervalRegistryTest { - - private HostRequestIntervalRegistry registry; - - @Before - public void init() { - registry = new HostRequestIntervalRegistry(10000L, 100L,"g1,g2", "b1"); - } - - @Test - public void newHostCreateNewInterval() { - assertEquals(1L, registry.tick("host1")); - } - - @Test - public void existingHostUpdated() { - registry.tick("aaa"); - assertEquals(1L, registry.tick("bbb")); - assertEquals(2L, registry.tick("aaa")); - } - - @Test - public void expiredIntervalsCleaned() throws InterruptedException { - registry.tick("aaa"); - Thread.sleep(150L); - registry.tick("bbb"); - registry.clean(); - assertEquals(1L, registry.tick("aaa")); - assertEquals(2L, registry.tick("bbb")); - } - - @Test - public void domainFromWhitelistNotCounted(){ - assertEquals(0L, registry.tick("g1")); - assertEquals(0L, registry.tick("g1")); - assertEquals(0L, registry.tick("g2")); - } - - @Test - public void domainFromBlackListReturnMaxValue(){ - assertEquals(Long.MAX_VALUE, registry.tick("b1")); - assertEquals(Long.MAX_VALUE, registry.tick("b1")); - } - - @Test - public void emptyWhitelistParsedOk(){ - registry = new HostRequestIntervalRegistry(10000L, 100L,"", "b1"); - assertEquals(1L, registry.tick("aaa")); - } - - @Test - public void emptyBlacklistParsedOk(){ - registry = new HostRequestIntervalRegistry(10000L, 100L,"", ""); - assertEquals(1L, registry.tick("aaa")); - } -} \ No newline at end of file diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/inmemory/IntervalCountTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/inmemory/IntervalCountTest.java deleted file mode 100644 index 4fdce61fd3..0000000000 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/inmemory/IntervalCountTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota.inmemory; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.thingsboard.server.common.transport.quota.Clock; - -import static org.junit.Assert.assertEquals; - -/** - * @author Vitaliy Paromskiy - * @version 1.0 - */ -public class IntervalCountTest { - - @Before - public void init() { - Clock.setMillis(1000L); - } - - @After - public void clear() { - Clock.reset(); - } - - @Test - public void ticksInSameIntervalAreSummed() { - IntervalCount intervalCount = new IntervalCount(100L); - assertEquals(1L, intervalCount.resetIfExpiredAndTick()); - Clock.shift(100); - assertEquals(2L, intervalCount.resetIfExpiredAndTick()); - } - - @Test - public void oldDataCleanedWhenIntervalExpired() { - IntervalCount intervalCount = new IntervalCount(100L); - assertEquals(1L, intervalCount.resetIfExpiredAndTick()); - Clock.shift(101); - assertEquals(1L, intervalCount.resetIfExpiredAndTick()); - } - - @Test - public void silenceDurationCalculatedFromLastTick() { - IntervalCount intervalCount = new IntervalCount(100L); - assertEquals(1L, intervalCount.resetIfExpiredAndTick()); - Clock.shift(10L); - assertEquals(10L, intervalCount.silenceDuration()); - } - -} \ No newline at end of file diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/inmemory/IntervalRegistryLoggerTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/inmemory/IntervalRegistryLoggerTest.java deleted file mode 100644 index 6e51420cd5..0000000000 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/quota/inmemory/IntervalRegistryLoggerTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed 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.thingsboard.server.common.transport.quota.inmemory; - -import com.google.common.collect.ImmutableMap; -import org.junit.Before; -import org.junit.Test; -import org.thingsboard.server.common.transport.quota.host.HostIntervalRegistryLogger; -import org.thingsboard.server.common.transport.quota.host.HostRequestIntervalRegistry; - -import java.util.Collections; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; - -/** - * @author Vitaliy Paromskiy - * @version 1.0 - */ -public class IntervalRegistryLoggerTest { - - private IntervalRegistryLogger logger; - - private HostRequestIntervalRegistry requestRegistry = mock(HostRequestIntervalRegistry.class); - - @Before - public void init() { - logger = new HostIntervalRegistryLogger(3, 10, requestRegistry); - } - - @Test - public void onlyMaxHostsCollected() { - Map map = ImmutableMap.of("a", 8L, "b", 3L, "c", 1L, "d", 3L); - Map actual = logger.getTopElements(map); - Map expected = ImmutableMap.of("a", 8L, "b", 3L, "d", 3L); - - assertEquals(expected, actual); - } - - @Test - public void emptyMapProcessedCorrectly() { - Map map = Collections.emptyMap(); - Map actual = logger.getTopElements(map); - Map expected = Collections.emptyMap(); - - assertEquals(expected, actual); - } - -} \ No newline at end of file diff --git a/transport/coap/src/main/resources/tb-coap-transport.yml b/transport/coap/src/main/resources/tb-coap-transport.yml index 822d104617..30351b0bfa 100644 --- a/transport/coap/src/main/resources/tb-coap-transport.yml +++ b/transport/coap/src/main/resources/tb-coap-transport.yml @@ -28,27 +28,6 @@ transport: tenant: "${TB_TRANSPORT_RATE_LIMITS_TENANT:1000:1,20000:60}" device: "${TB_TRANSPORT_RATE_LIMITS_DEVICE:10:1,300:60}" -#Quota parameters -quota: - host: - # Max allowed number of API requests in interval for single host - limit: "${QUOTA_HOST_LIMIT:10000}" - # Interval duration - intervalMs: "${QUOTA_HOST_INTERVAL_MS:60000}" - # Maximum silence duration for host after which Host removed from QuotaService. Must be bigger than intervalMs - ttlMs: "${QUOTA_HOST_TTL_MS:60000}" - # Interval for scheduled task that cleans expired records. TTL is used for expiring - cleanPeriodMs: "${QUOTA_HOST_CLEAN_PERIOD_MS:300000}" - # Enable Host API Limits - enabled: "${QUOTA_HOST_ENABLED:true}" - # Array of whitelist hosts - whitelist: "${QUOTA_HOST_WHITELIST:localhost,127.0.0.1}" - # Array of blacklist hosts - blacklist: "${QUOTA_HOST_BLACKLIST:}" - log: - topSize: 10 - intervalMin: 2 - kafka: enabled: true bootstrap.servers: "${TB_KAFKA_SERVERS:localhost:9092}" diff --git a/transport/http/src/main/resources/tb-http-transport.yml b/transport/http/src/main/resources/tb-http-transport.yml index 650bfdf1e9..001e08abdc 100644 --- a/transport/http/src/main/resources/tb-http-transport.yml +++ b/transport/http/src/main/resources/tb-http-transport.yml @@ -29,27 +29,6 @@ transport: tenant: "${TB_TRANSPORT_RATE_LIMITS_TENANT:1000:1,20000:60}" device: "${TB_TRANSPORT_RATE_LIMITS_DEVICE:10:1,300:60}" -#Quota parameters -quota: - host: - # Max allowed number of API requests in interval for single host - limit: "${QUOTA_HOST_LIMIT:10000}" - # Interval duration - intervalMs: "${QUOTA_HOST_INTERVAL_MS:60000}" - # Maximum silence duration for host after which Host removed from QuotaService. Must be bigger than intervalMs - ttlMs: "${QUOTA_HOST_TTL_MS:60000}" - # Interval for scheduled task that cleans expired records. TTL is used for expiring - cleanPeriodMs: "${QUOTA_HOST_CLEAN_PERIOD_MS:300000}" - # Enable Host API Limits - enabled: "${QUOTA_HOST_ENABLED:true}" - # Array of whitelist hosts - whitelist: "${QUOTA_HOST_WHITELIST:localhost,127.0.0.1}" - # Array of blacklist hosts - blacklist: "${QUOTA_HOST_BLACKLIST:}" - log: - topSize: 10 - intervalMin: 2 - kafka: enabled: true bootstrap.servers: "${TB_KAFKA_SERVERS:localhost:9092}" diff --git a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml index a0e86bb1c2..e37d14e874 100644 --- a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml +++ b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml @@ -51,27 +51,6 @@ transport: tenant: "${TB_TRANSPORT_RATE_LIMITS_TENANT:1000:1,20000:60}" device: "${TB_TRANSPORT_RATE_LIMITS_DEVICE:10:1,300:60}" -#Quota parameters -quota: - host: - # Max allowed number of API requests in interval for single host - limit: "${QUOTA_HOST_LIMIT:10000}" - # Interval duration - intervalMs: "${QUOTA_HOST_INTERVAL_MS:60000}" - # Maximum silence duration for host after which Host removed from QuotaService. Must be bigger than intervalMs - ttlMs: "${QUOTA_HOST_TTL_MS:60000}" - # Interval for scheduled task that cleans expired records. TTL is used for expiring - cleanPeriodMs: "${QUOTA_HOST_CLEAN_PERIOD_MS:300000}" - # Enable Host API Limits - enabled: "${QUOTA_HOST_ENABLED:true}" - # Array of whitelist hosts - whitelist: "${QUOTA_HOST_WHITELIST:localhost,127.0.0.1}" - # Array of blacklist hosts - blacklist: "${QUOTA_HOST_BLACKLIST:}" - log: - topSize: 10 - intervalMin: 2 - kafka: enabled: true bootstrap.servers: "${TB_KAFKA_SERVERS:localhost:9092}"