From 1af249fcb4bb99feea1030f42e22ed8a65a3f025 Mon Sep 17 00:00:00 2001 From: AndrewVolosytnykhThingsboard Date: Tue, 1 Jun 2021 12:32:31 +0300 Subject: [PATCH] Updater added, improved server rate limits filter, cleaned redundant lines --- .../config/RateLimitProcessingFilter.java | 26 ++-- .../install/ThingsboardInstallService.java | 2 + .../update/DefaultDataUpdateService.java | 7 +- .../install/update/RateLimitsUpdater.java | 115 ++++++++++++++++++ .../server/common/msg/tools/TbRateLimits.java | 4 + .../tenant-profile-data.component.html | 13 -- 6 files changed, 143 insertions(+), 24 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/service/install/update/RateLimitsUpdater.java diff --git a/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java b/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java index 6d531925c6..75d15b18f2 100644 --- a/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java @@ -56,24 +56,30 @@ public class RateLimitProcessingFilter extends GenericFilterBean { SecurityUser user = getCurrentUser(); if (user != null && !user.isSystemAdmin()) { - var profile= tenantProfileCache.get(user.getTenantId()).getDefaultTenantProfileConfiguration(); + var profileConfiguration = tenantProfileCache.get(user.getTenantId()).getDefaultTenantProfileConfiguration(); - if(profile != null) { - if (StringUtils.isNotEmpty(profile.getRateLimitsTenantConfiguration())) { + if(profileConfiguration != null) { + if (user.isTenantAdmin() && StringUtils.isNotEmpty(profileConfiguration.getRateLimitsTenantConfiguration())) { + + TbRateLimits rateLimits = perTenantLimits.get(user.getTenantId()); + if(rateLimits == null || !rateLimits.getCurrentConfig().equals(profileConfiguration.getRateLimitsTenantConfiguration())) { + rateLimits = new TbRateLimits(profileConfiguration.getRateLimitsTenantConfiguration()); + perTenantLimits.put(user.getTenantId(), rateLimits); + } - TbRateLimits rateLimits = perTenantLimits.computeIfAbsent( - user.getTenantId(), id -> new TbRateLimits(profile.getRateLimitsTenantConfiguration()) - ); if (!rateLimits.tryConsume()) { errorResponseHandler.handle(new TbRateLimitsException(EntityType.TENANT), (HttpServletResponse) response); return; } } - if (StringUtils.isNotEmpty(profile.getRateLimitsCustomerConfiguration())) { + if (user.isCustomerUser() && StringUtils.isNotEmpty(profileConfiguration.getRateLimitsCustomerConfiguration())) { + + TbRateLimits rateLimits = perCustomerLimits.get(user.getCustomerId()); + if(rateLimits == null || !rateLimits.getCurrentConfig().equals(profileConfiguration.getRateLimitsCustomerConfiguration())) { + rateLimits = new TbRateLimits(profileConfiguration.getRateLimitsCustomerConfiguration()); + perCustomerLimits.put(user.getCustomerId(), rateLimits); + } - TbRateLimits rateLimits = perCustomerLimits.computeIfAbsent( - user.getCustomerId(), id -> new TbRateLimits(profile.getRateLimitsCustomerConfiguration()) - ); if (!rateLimits.tryConsume()) { errorResponseHandler.handle(new TbRateLimitsException(EntityType.CUSTOMER), (HttpServletResponse) response); return; diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index 267fb31ad7..9f9e78dc3d 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -203,6 +203,8 @@ public class ThingsboardInstallService { log.info("Updating system data..."); systemDataLoaderService.updateSystemWidgets(); break; + case "3.3.0": + dataUpdateService.updateData("3.3.0"); default: throw new RuntimeException("Unable to upgrade ThingsBoard, unsupported fromVersion: " + upgradeFromVersion); diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index b91c46417c..9d78fed87c 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -23,6 +23,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.profile.TbDeviceProfileNode; import org.thingsboard.rule.engine.profile.TbDeviceProfileNodeConfiguration; import org.thingsboard.server.common.data.EntityView; @@ -48,7 +49,6 @@ import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.timeseries.TimeseriesService; -import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.service.install.InstallScripts; import java.util.ArrayList; @@ -88,6 +88,9 @@ public class DefaultDataUpdateService implements DataUpdateService { @Autowired private AlarmDao alarmDao; + @Autowired + private RateLimitsUpdater rateLimitsUpdater; + @Override public void updateData(String fromVersion) throws Exception { switch (fromVersion) { @@ -108,6 +111,8 @@ public class DefaultDataUpdateService implements DataUpdateService { tenantsDefaultEdgeRuleChainUpdater.updateEntities(null); tenantsAlarmsCustomerUpdater.updateEntities(null); break; + case "3.3.0": + rateLimitsUpdater.updateEntities(null); default: throw new RuntimeException("Unable to update data, unsupported fromVersion: " + fromVersion); } diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/RateLimitsUpdater.java b/application/src/main/java/org/thingsboard/server/service/install/update/RateLimitsUpdater.java new file mode 100644 index 0000000000..aa11a12ff1 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/install/update/RateLimitsUpdater.java @@ -0,0 +1,115 @@ +/** + * Copyright © 2016-2021 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.service.install.update; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.StringUtils; +import org.thingsboard.server.common.data.TenantProfile; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.dao.tenant.TenantProfileService; + +@Component +class RateLimitsUpdater extends PaginatedUpdater { + @Value("${server.rest.limits.tenant.enabled}") + boolean tenantServerRateLimitsEnabled; + @Value("${server.rest.limits.customer.enabled}") + boolean customerServerRateLimitsEnabled; + @Value("${server.rest.limits.tenant.configuration}") + String tenantServerRateLimitsConfiguration; + @Value("${server.rest.limits.customer.configuration}") + String customerServerRateLimitsConfiguration; + + @Value("${server.ws.limits.max_sessions_per_tenant}") + private int wsLimitMaxSessionsPerTenant; + @Value("${server.ws.limits.max_sessions_per_customer}") + private int wsLimitMaxSessionsPerCustomer; + @Value("${server.ws.limits.max_sessions_per_regular_user}") + private int wsLimitMaxSessionsPerRegularUser; + @Value("${server.ws.limits.max_sessions_per_public_user}") + private int wsLimitMaxSessionsPerPublicUser; + @Value("${server.ws.limits.max_queue_per_ws_session}") + private int wsLimitQueuePerWsSession; + @Value("${server.ws.limits.max_subscriptions_per_tenant}") + private long wsLimitMaxSubscriptionsPerTenant; + @Value("${server.ws.limits.max_subscriptions_per_customer}") + private long wsLimitMaxSubscriptionsPerCustomer; + @Value("${server.ws.limits.max_subscriptions_per_regular_user}") + private long wsLimitMaxSubscriptionsPerRegularUser; + @Value("${server.ws.limits.max_subscriptions_per_public_user}") + private long wsLimitMaxSubscriptionsPerPublicUser; + @Value("${server.ws.limits.max_updates_per_session}") + private String wsLimitUpdatesPerSession; + + @Value("${cassandra.query.tenant_rate_limits.enabled}") + private boolean cassandraLimitsIsEnabled; + @Value("${cassandra.query.tenant_rate_limits.configuration}") + private String cassandraTenantLimitsConfiguration; + @Value("${cassandra.query.tenant_rate_limits.print_tenant_names}") + private boolean printTenantNames; + + @Autowired + private TenantProfileService tenantProfileService; + + @Override + protected boolean forceReportTotal() { + return true; + } + + @Override + protected String getName() { + return "Rate limits updater"; + } + + @Override + protected PageData findEntities(String id, PageLink pageLink) { + return tenantProfileService.findTenantProfiles(null, pageLink); + } + + @Override + protected void updateEntity(TenantProfile entity) { + var profileConfiguration = entity.getDefaultTenantProfileConfiguration(); + if (profileConfiguration != null) { + if (tenantServerRateLimitsEnabled && StringUtils.isNotEmpty(tenantServerRateLimitsConfiguration)) { + profileConfiguration.setRateLimitsTenantConfiguration(tenantServerRateLimitsConfiguration); + } + if (customerServerRateLimitsEnabled && StringUtils.isNotEmpty(customerServerRateLimitsConfiguration)) { + profileConfiguration.setRateLimitsCustomerConfiguration(customerServerRateLimitsConfiguration); + } + + profileConfiguration.setWsLimitMaxSessionsPerTenant(wsLimitMaxSessionsPerTenant); + profileConfiguration.setWsLimitMaxSessionsPerCustomer(wsLimitMaxSessionsPerCustomer); + profileConfiguration.setWsLimitMaxSessionsPerPublicUser(wsLimitMaxSessionsPerPublicUser); + profileConfiguration.setWsLimitMaxSessionsPerRegularUser(wsLimitMaxSessionsPerRegularUser); + profileConfiguration.setWsLimitMaxSubscriptionsPerTenant(wsLimitMaxSubscriptionsPerTenant); + profileConfiguration.setWsLimitMaxSubscriptionsPerCustomer(wsLimitMaxSubscriptionsPerCustomer); + profileConfiguration.setWsLimitMaxSubscriptionsPerPublicUser(wsLimitMaxSubscriptionsPerPublicUser); + profileConfiguration.setWsLimitMaxSubscriptionsPerRegularUser(wsLimitMaxSubscriptionsPerRegularUser); + profileConfiguration.setWsLimitQueuePerWsSession(wsLimitQueuePerWsSession); + + if (StringUtils.isNotEmpty(wsLimitUpdatesPerSession)) { + profileConfiguration.setWsLimitUpdatesPerSession(wsLimitUpdatesPerSession); + } + + if (cassandraLimitsIsEnabled) { + profileConfiguration.setCassandraTenantLimitsConfiguration(cassandraTenantLimitsConfiguration); + profileConfiguration.setPrintTenantNames(printTenantNames); + } + } + } +} diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/tools/TbRateLimits.java b/common/message/src/main/java/org/thingsboard/server/common/msg/tools/TbRateLimits.java index dc69406fe1..80fbaea65f 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/tools/TbRateLimits.java +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/tools/TbRateLimits.java @@ -19,6 +19,7 @@ import io.github.bucket4j.Bandwidth; import io.github.bucket4j.Bucket4j; import io.github.bucket4j.local.LocalBucket; import io.github.bucket4j.local.LocalBucketBuilder; +import lombok.Getter; import java.time.Duration; @@ -27,9 +28,12 @@ import java.time.Duration; */ public class TbRateLimits { private final LocalBucket bucket; + @Getter + private final String currentConfig; public TbRateLimits(String limitsConfiguration) { LocalBucketBuilder builder = Bucket4j.builder(); + currentConfig = limitsConfiguration; boolean initialized = false; for (String limitSrc : limitsConfiguration.split(",")) { long capacity = Long.parseLong(limitSrc.split(":")[0]); diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant-profile-data.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant-profile-data.component.html index 1fdc6aba83..4a979fb0cb 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant-profile-data.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant-profile-data.component.html @@ -16,19 +16,6 @@ -->
- - - - - - - - - - - - -