25 changed files with 427 additions and 88 deletions
@ -0,0 +1,30 @@ |
|||
/** |
|||
* 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; |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
/** |
|||
* 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); |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
/** |
|||
* 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<String, Long> 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<String, Long> host : top.entrySet()) { |
|||
builder.append(host.getKey()).append(" : ").append(host.getValue()).append("; "); |
|||
} |
|||
|
|||
log.info(builder.toString()); |
|||
} |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
/** |
|||
* 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"); |
|||
} |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
/** |
|||
* 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); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
/** |
|||
* 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.stereotype.Component; |
|||
import org.thingsboard.server.common.transport.quota.inmemory.IntervalRegistryCleaner; |
|||
|
|||
@Component |
|||
public class TenantIntervalRegistryCleaner extends IntervalRegistryCleaner { |
|||
|
|||
public TenantIntervalRegistryCleaner(TenantMsgsIntervalRegistry intervalRegistry, |
|||
@Value("${quota.rule.tenant.cleanPeriodMs}") long cleanPeriodMs) { |
|||
super(intervalRegistry, cleanPeriodMs); |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
/** |
|||
* 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.stereotype.Component; |
|||
import org.thingsboard.server.common.transport.quota.inmemory.IntervalRegistryLogger; |
|||
|
|||
import java.util.Map; |
|||
import java.util.concurrent.TimeUnit; |
|||
|
|||
@Slf4j |
|||
@Component |
|||
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<String, Long> 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<String, Long> host : top.entrySet()) { |
|||
builder.append(host.getKey()).append(" : ").append(host.getValue()).append("; "); |
|||
} |
|||
|
|||
log.info(builder.toString()); |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
/** |
|||
* 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.stereotype.Component; |
|||
import org.thingsboard.server.common.transport.quota.inmemory.KeyBasedIntervalRegistry; |
|||
|
|||
@Component |
|||
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"); |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
/** |
|||
* 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.stereotype.Component; |
|||
import org.thingsboard.server.common.transport.quota.AbstractQuotaService; |
|||
|
|||
@Component |
|||
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); |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
/** |
|||
* 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.stereotype.Component; |
|||
import org.thingsboard.server.common.transport.quota.RequestLimitPolicy; |
|||
|
|||
@Component |
|||
public class TenantRequestLimitPolicy extends RequestLimitPolicy { |
|||
|
|||
public TenantRequestLimitPolicy(@Value("${quota.rule.tenant.limit}") long limit) { |
|||
super(limit); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue