dubbo.apache.org/dubbo-go/v3@v3.1.1/common/config/environment.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package config 19 20 import ( 21 "container/list" 22 "strings" 23 "sync" 24 ) 25 26 import ( 27 "dubbo.apache.org/dubbo-go/v3/config_center" 28 ) 29 30 // Environment 31 // There is dubbo.properties file and application level config center configuration which is higher than normal config center in java. So in java the 32 // configuration sequence will be config center > application level config center > dubbo.properties > spring bean configuration. 33 // But in go, neither the dubbo.properties file or application level config center configuration will not support for the time being. 34 // We just have config center configuration which can override configuration in consumer.yaml & provider.yaml. 35 // But for add these features in future ,I finish the environment struct following Environment class in java. 36 type Environment struct { 37 configCenterFirst bool 38 // externalConfigs sync.Map 39 externalConfigMap sync.Map 40 appExternalConfigMap sync.Map 41 dynamicConfiguration config_center.DynamicConfiguration 42 } 43 44 var ( 45 instance *Environment 46 once sync.Once 47 ) 48 49 // GetEnvInstance gets env instance by singleton 50 func GetEnvInstance() *Environment { 51 once.Do(func() { 52 instance = &Environment{configCenterFirst: true} 53 }) 54 return instance 55 } 56 57 // NewEnvInstance creates Environment instance 58 func NewEnvInstance() { 59 instance = &Environment{configCenterFirst: true} 60 } 61 62 // UpdateExternalConfigMap updates env externalConfigMap field 63 func (env *Environment) UpdateExternalConfigMap(externalMap map[string]string) { 64 for k, v := range externalMap { 65 env.externalConfigMap.Store(k, v) 66 } 67 env.externalConfigMap.Range(func(key, value interface{}) bool { 68 if _, ok := externalMap[key.(string)]; !ok { 69 env.externalConfigMap.Delete(key) 70 } 71 return true 72 }) 73 } 74 75 // UpdateAppExternalConfigMap updates env appExternalConfigMap field 76 func (env *Environment) UpdateAppExternalConfigMap(externalMap map[string]string) { 77 for k, v := range externalMap { 78 env.appExternalConfigMap.Store(k, v) 79 } 80 env.appExternalConfigMap.Range(func(key, value interface{}) bool { 81 if _, ok := externalMap[key.(string)]; !ok { 82 env.appExternalConfigMap.Delete(key) 83 } 84 return true 85 }) 86 } 87 88 // Configuration puts externalConfigMap and appExternalConfigMap into list 89 // List represents a doubly linked list. 90 func (env *Environment) Configuration() *list.List { 91 cfgList := list.New() 92 // The sequence would be: SystemConfiguration -> AppExternalConfiguration -> ExternalConfiguration -> AbstractConfig -> PropertiesConfiguration 93 cfgList.PushBack(newInmemoryConfiguration(&(env.appExternalConfigMap))) 94 cfgList.PushBack(newInmemoryConfiguration(&(env.externalConfigMap))) 95 return cfgList 96 } 97 98 // SetDynamicConfiguration sets value for dynamicConfiguration 99 func (env *Environment) SetDynamicConfiguration(dc config_center.DynamicConfiguration) { 100 env.dynamicConfiguration = dc 101 } 102 103 // GetDynamicConfiguration gets dynamicConfiguration 104 func (env *Environment) GetDynamicConfiguration() config_center.DynamicConfiguration { 105 return env.dynamicConfiguration 106 } 107 108 // InmemoryConfiguration stores config in memory 109 type InmemoryConfiguration struct { 110 store *sync.Map 111 } 112 113 func newInmemoryConfiguration(p *sync.Map) *InmemoryConfiguration { 114 return &InmemoryConfiguration{store: p} 115 } 116 117 // GetProperty gets value from InmemoryConfiguration instance by @key 118 func (conf *InmemoryConfiguration) GetProperty(key string) (bool, string) { 119 if conf.store == nil { 120 return false, "" 121 } 122 123 v, ok := conf.store.Load(key) 124 if ok { 125 return true, v.(string) 126 } 127 128 return false, "" 129 } 130 131 // GetSubProperty gets sub property from InmemoryConfiguration instance by @subkey 132 func (conf *InmemoryConfiguration) GetSubProperty(subKey string) map[string]struct{} { 133 if conf.store == nil { 134 return nil 135 } 136 137 properties := make(map[string]struct{}) 138 conf.store.Range(func(key, _ interface{}) bool { 139 if idx := strings.Index(key.(string), subKey); idx >= 0 { 140 after := key.(string)[idx+len(subKey):] 141 if i := strings.Index(after, "."); i >= 0 { 142 properties[after[0:strings.Index(after, ".")]] = struct{}{} 143 } 144 145 } 146 return true 147 }) 148 149 return properties 150 }