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  }