committed by
GitHub
36 changed files with 923 additions and 87 deletions
@ -0,0 +1,30 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2025 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.data.limit; |
||||
|
|
||||
|
public record RateLimitEntry(long capacity, long durationSeconds) { |
||||
|
|
||||
|
public static RateLimitEntry parse(String s) { |
||||
|
String[] parts = s.split(":"); |
||||
|
return new RateLimitEntry(Long.parseLong(parts[0]), Long.parseLong(parts[1])); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String toString() { |
||||
|
return capacity + ":" + durationSeconds; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,92 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2025 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.data.limit; |
||||
|
|
||||
|
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.Arrays; |
||||
|
import java.util.Collections; |
||||
|
import java.util.HashMap; |
||||
|
import java.util.HashSet; |
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
import java.util.Set; |
||||
|
import java.util.function.Function; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
public class RateLimitUtil { |
||||
|
|
||||
|
public static List<RateLimitEntry> parseConfig(String config) { |
||||
|
if (config == null || config.isEmpty()) { |
||||
|
return Collections.emptyList(); |
||||
|
} |
||||
|
return Arrays.stream(config.split(",")) |
||||
|
.map(RateLimitEntry::parse) |
||||
|
.toList(); |
||||
|
} |
||||
|
|
||||
|
public static Function<DefaultTenantProfileConfiguration, String> merge( |
||||
|
Function<DefaultTenantProfileConfiguration, String> configExtractor1, |
||||
|
Function<DefaultTenantProfileConfiguration, String> configExtractor2) { |
||||
|
return config -> { |
||||
|
String config1 = configExtractor1.apply(config); |
||||
|
String config2 = configExtractor2.apply(config); |
||||
|
return RateLimitUtil.mergeStrConfigs(config1, config2); // merges the configs
|
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
private static String mergeStrConfigs(String firstConfig, String secondConfig) { |
||||
|
List<RateLimitEntry> all = new ArrayList<>(); |
||||
|
all.addAll(parseConfig(firstConfig)); |
||||
|
all.addAll(parseConfig(secondConfig)); |
||||
|
|
||||
|
Map<Long, Long> merged = new HashMap<>(); |
||||
|
|
||||
|
for (RateLimitEntry entry : all) { |
||||
|
merged.merge(entry.durationSeconds(), entry.capacity(), Long::sum); |
||||
|
} |
||||
|
|
||||
|
return merged.entrySet().stream() |
||||
|
.sorted(Map.Entry.comparingByKey()) // optional: sort by duration
|
||||
|
.map(e -> e.getValue() + ":" + e.getKey()) |
||||
|
.collect(Collectors.joining(",")); |
||||
|
} |
||||
|
|
||||
|
public static boolean isValid(String configStr) { |
||||
|
List<RateLimitEntry> limitedApiEntries = parseConfig(configStr); |
||||
|
Set<Long> distinctDurations = new HashSet<>(); |
||||
|
for (RateLimitEntry entry : limitedApiEntries) { |
||||
|
if (!distinctDurations.add(entry.durationSeconds())) { |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
@Deprecated(forRemoval = true, since = "4.1") |
||||
|
public static String deduplicateByDuration(String configStr) { |
||||
|
if (configStr == null) { |
||||
|
return null; |
||||
|
} |
||||
|
Set<Long> distinctDurations = new HashSet<>(); |
||||
|
return parseConfig(configStr).stream() |
||||
|
.filter(entry -> distinctDurations.add(entry.durationSeconds())) |
||||
|
.map(RateLimitEntry::toString) |
||||
|
.collect(Collectors.joining(",")); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2025 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.data.validation; |
||||
|
|
||||
|
import jakarta.validation.Constraint; |
||||
|
import jakarta.validation.Payload; |
||||
|
|
||||
|
import java.lang.annotation.ElementType; |
||||
|
import java.lang.annotation.Retention; |
||||
|
import java.lang.annotation.RetentionPolicy; |
||||
|
import java.lang.annotation.Target; |
||||
|
|
||||
|
@Retention(RetentionPolicy.RUNTIME) |
||||
|
@Target({ElementType.FIELD, ElementType.METHOD}) |
||||
|
@Constraint(validatedBy = {}) |
||||
|
public @interface RateLimit { |
||||
|
|
||||
|
String message() default "rate limit has duplicate 'Per seconds' configuration."; |
||||
|
|
||||
|
String fieldName() default ""; |
||||
|
|
||||
|
Class<?>[] groups() default {}; |
||||
|
|
||||
|
Class<? extends Payload>[] payload() default {}; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,101 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2025 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.data.limit; |
||||
|
|
||||
|
import org.junit.jupiter.api.BeforeEach; |
||||
|
import org.junit.jupiter.api.Test; |
||||
|
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; |
||||
|
|
||||
|
import java.util.Arrays; |
||||
|
import java.util.Map; |
||||
|
import java.util.Set; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
import static org.mockito.Mockito.clearInvocations; |
||||
|
import static org.mockito.Mockito.mock; |
||||
|
import static org.mockito.Mockito.verify; |
||||
|
|
||||
|
class LimitedApiTest { |
||||
|
|
||||
|
private DefaultTenantProfileConfiguration config; |
||||
|
|
||||
|
@BeforeEach |
||||
|
void setUp() { |
||||
|
config = mock(DefaultTenantProfileConfiguration.class); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
void testCorrectConfigExtractorsUsed() { |
||||
|
Map<LimitedApi, Runnable> verifierMap = Map.ofEntries( |
||||
|
Map.entry(LimitedApi.ENTITY_EXPORT, () -> |
||||
|
verify(config).getTenantEntityExportRateLimit()), |
||||
|
Map.entry(LimitedApi.ENTITY_IMPORT, () -> |
||||
|
verify(config).getTenantEntityImportRateLimit()), |
||||
|
Map.entry(LimitedApi.NOTIFICATION_REQUESTS, () -> |
||||
|
verify(config).getTenantNotificationRequestsRateLimit()), |
||||
|
Map.entry(LimitedApi.NOTIFICATION_REQUESTS_PER_RULE, () -> |
||||
|
verify(config).getTenantNotificationRequestsPerRuleRateLimit()), |
||||
|
Map.entry(LimitedApi.REST_REQUESTS_PER_TENANT, () -> |
||||
|
verify(config).getTenantServerRestLimitsConfiguration()), |
||||
|
Map.entry(LimitedApi.REST_REQUESTS_PER_CUSTOMER, () -> |
||||
|
verify(config).getCustomerServerRestLimitsConfiguration()), |
||||
|
Map.entry(LimitedApi.WS_UPDATES_PER_SESSION, () -> |
||||
|
verify(config).getWsUpdatesPerSessionRateLimit()), |
||||
|
Map.entry(LimitedApi.CASSANDRA_WRITE_QUERIES_CORE, () -> |
||||
|
verify(config).getCassandraWriteQueryTenantCoreRateLimits()), |
||||
|
Map.entry(LimitedApi.CASSANDRA_READ_QUERIES_CORE, () -> |
||||
|
verify(config).getCassandraReadQueryTenantCoreRateLimits()), |
||||
|
Map.entry(LimitedApi.CASSANDRA_WRITE_QUERIES_RULE_ENGINE, () -> |
||||
|
verify(config).getCassandraWriteQueryTenantRuleEngineRateLimits()), |
||||
|
Map.entry(LimitedApi.CASSANDRA_READ_QUERIES_RULE_ENGINE, () -> |
||||
|
verify(config).getCassandraReadQueryTenantRuleEngineRateLimits()), |
||||
|
Map.entry(LimitedApi.CASSANDRA_READ_QUERIES_MONOLITH, () -> { |
||||
|
verify(config).getCassandraReadQueryTenantCoreRateLimits(); |
||||
|
verify(config).getCassandraReadQueryTenantRuleEngineRateLimits(); |
||||
|
}), |
||||
|
Map.entry(LimitedApi.CASSANDRA_WRITE_QUERIES_MONOLITH, () -> { |
||||
|
verify(config).getCassandraWriteQueryTenantCoreRateLimits(); |
||||
|
verify(config).getCassandraWriteQueryTenantRuleEngineRateLimits(); |
||||
|
}), |
||||
|
Map.entry(LimitedApi.EDGE_EVENTS, () -> |
||||
|
verify(config).getEdgeEventRateLimits()), |
||||
|
Map.entry(LimitedApi.EDGE_EVENTS_PER_EDGE, () -> |
||||
|
verify(config).getEdgeEventRateLimitsPerEdge()), |
||||
|
Map.entry(LimitedApi.EDGE_UPLINK_MESSAGES, () -> |
||||
|
verify(config).getEdgeUplinkMessagesRateLimits()), |
||||
|
Map.entry(LimitedApi.EDGE_UPLINK_MESSAGES_PER_EDGE, () -> |
||||
|
verify(config).getEdgeUplinkMessagesRateLimitsPerEdge()) |
||||
|
); |
||||
|
|
||||
|
Set<LimitedApi> expected = verifierMap.keySet(); |
||||
|
Set<LimitedApi> actual = Arrays.stream(LimitedApi.values()) |
||||
|
.filter(api -> api.getConfigExtractor() != null) |
||||
|
.collect(Collectors.toSet()); |
||||
|
|
||||
|
assertThat(expected) |
||||
|
.as("Verifier map should cover all LimitedApis with extractors") |
||||
|
.containsExactlyInAnyOrderElementsOf(actual); |
||||
|
|
||||
|
for (Map.Entry<LimitedApi, Runnable> entry : verifierMap.entrySet()) { |
||||
|
LimitedApi api = entry.getKey(); |
||||
|
api.getLimitConfig(config); |
||||
|
entry.getValue().run(); |
||||
|
clearInvocations(config); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,99 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2025 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.data.limit; |
||||
|
|
||||
|
import org.junit.jupiter.api.DisplayName; |
||||
|
import org.junit.jupiter.api.Test; |
||||
|
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.function.Function; |
||||
|
|
||||
|
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
|
||||
|
class RateLimitUtilTest { |
||||
|
|
||||
|
@Test |
||||
|
@DisplayName("LimitedApiUtil should parse single entry correctly") |
||||
|
void testParseSingleEntry() { |
||||
|
List<RateLimitEntry> entries = RateLimitUtil.parseConfig("100:60"); |
||||
|
|
||||
|
assertThat(entries).hasSize(1); |
||||
|
assertThat(entries.get(0).capacity()).isEqualTo(100); |
||||
|
assertThat(entries.get(0).durationSeconds()).isEqualTo(60); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
@DisplayName("LimitedApiUtil should parse multiple entries correctly") |
||||
|
void testParseMultipleEntries() { |
||||
|
List<RateLimitEntry> entries = RateLimitUtil.parseConfig("100:60,200:30"); |
||||
|
|
||||
|
assertThat(entries).hasSize(2); |
||||
|
assertThat(entries.get(0).capacity()).isEqualTo(100); |
||||
|
assertThat(entries.get(0).durationSeconds()).isEqualTo(60); |
||||
|
assertThat(entries.get(1).capacity()).isEqualTo(200); |
||||
|
assertThat(entries.get(1).durationSeconds()).isEqualTo(30); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
@DisplayName("LimitedApiUtil should return empty list for null or empty config") |
||||
|
void testParseEmptyConfig() { |
||||
|
assertThat(RateLimitUtil.parseConfig(null)).isEmpty(); |
||||
|
assertThat(RateLimitUtil.parseConfig("")).isEmpty(); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
@DisplayName("LimitedApiUtil should merge two configs by summing capacities with same durations") |
||||
|
void testMergeStrConfigs() { |
||||
|
Function<DefaultTenantProfileConfiguration, String> extractor1 = cfg -> "100:60,50:30"; |
||||
|
Function<DefaultTenantProfileConfiguration, String> extractor2 = cfg -> "200:60,25:10"; |
||||
|
|
||||
|
// Fake config instance (not used directly in lambda logic)
|
||||
|
DefaultTenantProfileConfiguration config = new DefaultTenantProfileConfiguration(); |
||||
|
|
||||
|
String result = RateLimitUtil.merge(extractor1, extractor2).apply(config); |
||||
|
|
||||
|
// Should be: 300:60 (100+200), 50:30, 25:10
|
||||
|
assertThat(result).isEqualTo("25:10,50:30,300:60"); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
@DisplayName("LimitedApiUtil should merge configs when one is empty") |
||||
|
void testMergeWithEmptyOne() { |
||||
|
Function<DefaultTenantProfileConfiguration, String> extractor1 = cfg -> "100:60"; |
||||
|
Function<DefaultTenantProfileConfiguration, String> extractor2 = cfg -> ""; |
||||
|
|
||||
|
// Fake config instance (not used directly in lambda logic)
|
||||
|
DefaultTenantProfileConfiguration config = new DefaultTenantProfileConfiguration(); |
||||
|
String result = RateLimitUtil.merge(extractor1, extractor2).apply(config); |
||||
|
|
||||
|
assertThat(result).isEqualTo("100:60"); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
@DisplayName("LimitedApiUtil should merge configs when both have distinct durations") |
||||
|
void testMergeWithDistinctDurations() { |
||||
|
Function<DefaultTenantProfileConfiguration, String> extractor1 = cfg -> "100:60"; |
||||
|
Function<DefaultTenantProfileConfiguration, String> extractor2 = cfg -> "200:10"; |
||||
|
|
||||
|
// Fake config instance (not used directly in lambda logic)
|
||||
|
DefaultTenantProfileConfiguration config = new DefaultTenantProfileConfiguration(); |
||||
|
String result = RateLimitUtil.merge(extractor1, extractor2).apply(config); |
||||
|
|
||||
|
assertThat(result).isEqualTo("200:10,100:60"); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,73 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
Copyright © 2016-2025 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. |
||||
|
|
||||
|
--> |
||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
<parent> |
||||
|
<groupId>org.thingsboard</groupId> |
||||
|
<version>4.1.0-SNAPSHOT</version> |
||||
|
<artifactId>common</artifactId> |
||||
|
</parent> |
||||
|
<groupId>org.thingsboard.common</groupId> |
||||
|
<artifactId>discovery-api</artifactId> |
||||
|
<packaging>jar</packaging> |
||||
|
|
||||
|
<name>Thingsboard Server Service Info Provider API</name> |
||||
|
<url>https://thingsboard.io</url> |
||||
|
|
||||
|
<properties> |
||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||
|
<main.dir>${basedir}/../..</main.dir> |
||||
|
</properties> |
||||
|
|
||||
|
<dependencies> |
||||
|
<dependency> |
||||
|
<groupId>org.thingsboard.common</groupId> |
||||
|
<artifactId>proto</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.thingsboard.common</groupId> |
||||
|
<artifactId>message</artifactId> |
||||
|
</dependency> |
||||
|
</dependencies> |
||||
|
|
||||
|
<build> |
||||
|
<plugins> |
||||
|
<plugin> |
||||
|
<groupId>org.apache.maven.plugins</groupId> |
||||
|
<artifactId>maven-source-plugin</artifactId> |
||||
|
<executions> |
||||
|
<execution> |
||||
|
<id>attach-sources</id> |
||||
|
<goals> |
||||
|
<goal>jar</goal> |
||||
|
</goals> |
||||
|
</execution> |
||||
|
</executions> |
||||
|
</plugin> |
||||
|
<plugin> |
||||
|
<groupId>org.apache.maven.plugins</groupId> |
||||
|
<artifactId>maven-deploy-plugin</artifactId> |
||||
|
<configuration> |
||||
|
<skip>false</skip> |
||||
|
</configuration> |
||||
|
</plugin> |
||||
|
</plugins> |
||||
|
</build> |
||||
|
|
||||
|
</project> |
||||
@ -0,0 +1,32 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2025 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.dao.service; |
||||
|
|
||||
|
import jakarta.validation.ConstraintValidator; |
||||
|
import jakarta.validation.ConstraintValidatorContext; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.thingsboard.server.common.data.limit.RateLimitUtil; |
||||
|
import org.thingsboard.server.common.data.validation.RateLimit; |
||||
|
|
||||
|
@Slf4j |
||||
|
public class RateLimitValidator implements ConstraintValidator<RateLimit, String> { |
||||
|
|
||||
|
@Override |
||||
|
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) { |
||||
|
return value == null || RateLimitUtil.isValid(value); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,40 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2025 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.dao.util; |
||||
|
|
||||
|
import lombok.Getter; |
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
|
import org.thingsboard.server.common.data.limit.LimitedApi; |
||||
|
|
||||
|
@Getter |
||||
|
public enum BufferedRateExecutorType { |
||||
|
|
||||
|
READ(LimitedApi.CASSANDRA_READ_QUERIES_CORE, LimitedApi.CASSANDRA_READ_QUERIES_RULE_ENGINE, LimitedApi.CASSANDRA_READ_QUERIES_MONOLITH), |
||||
|
WRITE(LimitedApi.CASSANDRA_WRITE_QUERIES_CORE, LimitedApi.CASSANDRA_WRITE_QUERIES_RULE_ENGINE, LimitedApi.CASSANDRA_WRITE_QUERIES_MONOLITH); |
||||
|
|
||||
|
private final LimitedApi coreLimitedApi; |
||||
|
private final LimitedApi ruleEngineLimitedApi; |
||||
|
private final LimitedApi monolithLimitedApi; |
||||
|
|
||||
|
private final String displayName = StringUtils.capitalize(name().toLowerCase()); |
||||
|
|
||||
|
BufferedRateExecutorType(LimitedApi coreLimitedApi, LimitedApi ruleEngineLimitedApi, LimitedApi monolithLimitedApi) { |
||||
|
this.coreLimitedApi = coreLimitedApi; |
||||
|
this.ruleEngineLimitedApi = ruleEngineLimitedApi; |
||||
|
this.monolithLimitedApi = monolithLimitedApi; |
||||
|
} |
||||
|
|
||||
|
} |
||||
Loading…
Reference in new issue