001/* 002 * Copyright (c) 2023. The BifroMQ Authors. All Rights Reserved. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * Unless required by applicable law or agreed to in writing, 009 * software distributed under the License is distributed on an "AS IS" BASIS, 010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 011 * See the License for the specific language governing permissions and limitations under the License. 012 */ 013 014package com.baidu.bifromq.plugin.settingprovider; 015 016import java.util.function.Predicate; 017import lombok.extern.slf4j.Slf4j; 018 019@Slf4j 020public enum Setting { 021 MQTT3Enabled(Boolean.class, val -> true, true), 022 MQTT4Enabled(Boolean.class, val -> true, true), 023 MQTT5Enabled(Boolean.class, val -> true, true), 024 DebugModeEnabled(Boolean.class, val -> true, false), 025 ForceTransient(Boolean.class, val -> true, false), 026 ByPassPermCheckError(Boolean.class, val -> true, true), 027 PayloadFormatValidationEnabled(Boolean.class, val -> true, true), 028 RetainEnabled(Boolean.class, val -> true, true), 029 WildcardSubscriptionEnabled(Boolean.class, val -> true, true), 030 SubscriptionIdentifierEnabled(Boolean.class, val -> true, true), 031 SharedSubscriptionEnabled(Boolean.class, val -> true, true), 032 MaximumQoS(Integer.class, val -> (int) val == 0 || (int) val == 1 || (int) val == 2, 2), 033 MaxTopicLevelLength(Integer.class, val -> (int) val > 0, 40), 034 MaxTopicLevels(Integer.class, val -> (int) val > 0, 16), 035 MaxTopicLength(Integer.class, val -> (int) val > 0 && (int) val < 65536, 255), 036 MaxTopicAlias(Integer.class, val -> (int) val >= 0 && (int) val < 65536, 10), 037 MaxSharedGroupMembers(Integer.class, val -> (int) val > 0, 200), 038 MaxTopicFiltersPerInbox(Integer.class, val -> (int) val > 0, 100), 039 MsgPubPerSec(Integer.class, val -> (int) val > 0 && (int) val <= 1000, 200), 040 ReceivingMaximum(Integer.class, val -> (int) val > 0 && (int) val <= 65535, 200), 041 InBoundBandWidth(Long.class, val -> (long) val >= 0, 512 * 1024L), 042 OutBoundBandWidth(Long.class, val -> (long) val >= 0, 512 * 1024L), 043 MaxUserPayloadBytes(Integer.class, val -> (int) val > 0 && (int) val <= 256 * 1024 * 1024, 256 * 1024), 044 MaxResendTimes(Integer.class, val -> (int) val >= 0, 3), 045 ResendTimeoutSeconds(Integer.class, val -> (int) val > 0, 10), 046 MaxTopicFiltersPerSub(Integer.class, val -> (int) val > 0 && (int) val <= 100, 10), 047 MaxSessionExpirySeconds(Integer.class, val -> (int) val > 0, 24 * 60 * 60), 048 SessionInboxSize(Integer.class, val -> (int) val > 0 && (int) val <= 65535, 1000), 049 QoS0DropOldest(Boolean.class, val -> true, false), 050 RetainMessageMatchLimit(Integer.class, val -> (int) val >= 0, 10); 051 052 public final Class<?> valueType; 053 private final Predicate<Object> validator; 054 private final Object defVal; 055 private volatile ISettingProvider settingProvider; 056 057 Setting(Class<?> valueType, Predicate<Object> validator, Object defValue) { 058 this.valueType = valueType; 059 this.validator = validator; 060 this.defVal = resolve(defValue); 061 assert isValid(defVal); 062 } 063 064 /** 065 * The current effective setting's value for given tenant 066 * 067 * @param tenantId the id of the calling tenant 068 * @return The effective value of the setting for the client 069 */ 070 public <R> R current(String tenantId) { 071 return settingProvider == null ? initialValue() : settingProvider.provide(this, tenantId); 072 } 073 074 075 /** 076 * Validate if provided value is a valid for the setting 077 * 078 * @param val the setting value to be verified 079 * @return true if the value is valid 080 */ 081 public <R> boolean isValid(R val) { 082 if (!valueType.isInstance(val)) { 083 return false; 084 } 085 return this.validator.test(val); 086 } 087 088 @SuppressWarnings("unchecked") 089 <R> R initialValue() { 090 return (R) defVal; 091 } 092 093 void setProvider(ISettingProvider provider) { 094 this.settingProvider = provider; 095 } 096 097 098 Object resolve(Object initial) { 099 String override = System.getProperty(name()); 100 if (override != null) { 101 try { 102 if (valueType == Integer.class) { 103 return Integer.parseInt(override); 104 } 105 if (valueType == Long.class) { 106 return Long.parseLong(override); 107 } 108 if (valueType == Boolean.class) { 109 return Boolean.parseBoolean(override); 110 } 111 } catch (Throwable e) { 112 log.error("Unable to parse setting value from system property: setting={}, value={}", 113 name(), override); 114 return initial; 115 } 116 } 117 return initial; 118 } 119}