gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/grpc/xds/internal/xdsclient/client.go (about) 1 /* 2 * 3 * Copyright 2019 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * 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 19 // Package xdsclient implements a full fledged gRPC client for the xDS API used 20 // by the xds resolver and balancer implementations. 21 package xdsclient 22 23 import ( 24 "fmt" 25 "sync" 26 "time" 27 28 "gitee.com/ks-custle/core-gm/grpc/internal/cache" 29 "gitee.com/ks-custle/core-gm/grpc/internal/grpclog" 30 "gitee.com/ks-custle/core-gm/grpc/internal/grpcsync" 31 "gitee.com/ks-custle/core-gm/grpc/xds/internal/xdsclient/bootstrap" 32 "gitee.com/ks-custle/core-gm/grpc/xds/internal/xdsclient/xdsresource" 33 ) 34 35 // clientImpl is the real implementation of the xds client. The exported Client 36 // is a wrapper of this struct with a ref count. 37 // 38 // Implements UpdateHandler interface. 39 // TODO(easwars): Make a wrapper struct which implements this interface in the 40 // style of ccBalancerWrapper so that the Client type does not implement these 41 // exported methods. 42 type clientImpl struct { 43 done *grpcsync.Event 44 config *bootstrap.Config 45 46 // authorityMu protects the authority fields. It's necessary because an 47 // authority is created when it's used. 48 authorityMu sync.Mutex 49 // authorities is a map from ServerConfig to authority. So that 50 // different authorities sharing the same ServerConfig can share the 51 // authority. 52 // 53 // The key is **ServerConfig.String()**, not the authority name. 54 // 55 // An authority is either in authorities, or idleAuthorities, 56 // never both. 57 authorities map[string]*authority 58 // idleAuthorities keeps the authorities that are not used (the last 59 // watch on it was canceled). They are kept in the cache and will be deleted 60 // after a timeout. The key is ServerConfig.String(). 61 // 62 // An authority is either in authorities, or idleAuthorities, 63 // never both. 64 idleAuthorities *cache.TimeoutCache 65 66 logger *grpclog.PrefixLogger 67 watchExpiryTimeout time.Duration 68 } 69 70 // newWithConfig returns a new xdsClient with the given config. 71 func newWithConfig(config *bootstrap.Config, watchExpiryTimeout time.Duration, idleAuthorityDeleteTimeout time.Duration) (_ *clientImpl, retErr error) { 72 c := &clientImpl{ 73 done: grpcsync.NewEvent(), 74 config: config, 75 watchExpiryTimeout: watchExpiryTimeout, 76 77 authorities: make(map[string]*authority), 78 idleAuthorities: cache.NewTimeoutCache(idleAuthorityDeleteTimeout), 79 } 80 81 defer func() { 82 if retErr != nil { 83 c.Close() 84 } 85 }() 86 87 c.logger = prefixLogger(c) 88 c.logger.Infof("Created ClientConn to xDS management server: %s", config.XDSServer) 89 90 c.logger.Infof("Created") 91 return c, nil 92 } 93 94 // BootstrapConfig returns the configuration read from the bootstrap file. 95 // Callers must treat the return value as read-only. 96 func (c *clientRefCounted) BootstrapConfig() *bootstrap.Config { 97 return c.config 98 } 99 100 // Close closes the gRPC connection to the management server. 101 func (c *clientImpl) Close() { 102 if c.done.HasFired() { 103 return 104 } 105 c.done.Fire() 106 // TODO: Should we invoke the registered callbacks here with an error that 107 // the client is closed? 108 109 // Note that Close needs to check for nils even if some of them are always 110 // set in the constructor. This is because the constructor defers Close() in 111 // error cases, and the fields might not be set when the error happens. 112 113 c.authorityMu.Lock() 114 for _, a := range c.authorities { 115 a.close() 116 } 117 c.idleAuthorities.Clear(true) 118 c.authorityMu.Unlock() 119 120 c.logger.Infof("Shutdown") 121 } 122 123 func (c *clientImpl) filterChainUpdateValidator(fc *xdsresource.FilterChain) error { 124 if fc == nil { 125 return nil 126 } 127 return c.securityConfigUpdateValidator(fc.SecurityCfg) 128 } 129 130 func (c *clientImpl) securityConfigUpdateValidator(sc *xdsresource.SecurityConfig) error { 131 if sc == nil { 132 return nil 133 } 134 if sc.IdentityInstanceName != "" { 135 if _, ok := c.config.CertProviderConfigs[sc.IdentityInstanceName]; !ok { 136 return fmt.Errorf("identitiy certificate provider instance name %q missing in bootstrap configuration", sc.IdentityInstanceName) 137 } 138 } 139 if sc.RootInstanceName != "" { 140 if _, ok := c.config.CertProviderConfigs[sc.RootInstanceName]; !ok { 141 return fmt.Errorf("root certificate provider instance name %q missing in bootstrap configuration", sc.RootInstanceName) 142 } 143 } 144 return nil 145 } 146 147 func (c *clientImpl) updateValidator(u interface{}) error { 148 switch update := u.(type) { 149 case xdsresource.ListenerUpdate: 150 if update.InboundListenerCfg == nil || update.InboundListenerCfg.FilterChains == nil { 151 return nil 152 } 153 return update.InboundListenerCfg.FilterChains.Validate(c.filterChainUpdateValidator) 154 case xdsresource.ClusterUpdate: 155 return c.securityConfigUpdateValidator(update.SecurityCfg) 156 default: 157 // We currently invoke this update validation function only for LDS and 158 // CDS updates. In the future, if we wish to invoke it for other xDS 159 // updates, corresponding plumbing needs to be added to those unmarshal 160 // functions. 161 } 162 return nil 163 }