github.com/polarismesh/polaris@v1.17.8/common/model/instance.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package model 19 20 import ( 21 "strings" 22 "time" 23 24 "github.com/golang/protobuf/ptypes/wrappers" 25 apimodel "github.com/polarismesh/specification/source/go/api/v1/model" 26 apiservice "github.com/polarismesh/specification/source/go/api/v1/service_manage" 27 28 commontime "github.com/polarismesh/polaris/common/time" 29 "github.com/polarismesh/polaris/common/utils" 30 ) 31 32 const ( 33 MetadataInstanceLastHeartbeatTime = "internal-lastheartbeat" 34 ) 35 36 // Instance 组合了api的Instance对象 37 type Instance struct { 38 Proto *apiservice.Instance 39 ServiceID string 40 ServicePlatformID string 41 // Valid Whether it is deleted by logic 42 Valid bool 43 // ModifyTime Update time of instance 44 ModifyTime time.Time 45 } 46 47 // ID get id 48 func (i *Instance) ID() string { 49 if i.Proto == nil { 50 return "" 51 } 52 return i.Proto.GetId().GetValue() 53 } 54 55 // Service get service 56 func (i *Instance) Service() string { 57 if i.Proto == nil { 58 return "" 59 } 60 return i.Proto.GetService().GetValue() 61 } 62 63 // Namespace get namespace 64 func (i *Instance) Namespace() string { 65 if i.Proto == nil { 66 return "" 67 } 68 return i.Proto.GetNamespace().GetValue() 69 } 70 71 // VpcID get vpcid 72 func (i *Instance) VpcID() string { 73 if i.Proto == nil { 74 return "" 75 } 76 return i.Proto.GetVpcId().GetValue() 77 } 78 79 // Host get host 80 func (i *Instance) Host() string { 81 if i.Proto == nil { 82 return "" 83 } 84 return i.Proto.GetHost().GetValue() 85 } 86 87 // Port get port 88 func (i *Instance) Port() uint32 { 89 if i.Proto == nil { 90 return 0 91 } 92 return i.Proto.GetPort().GetValue() 93 } 94 95 // Protocol get protocol 96 func (i *Instance) Protocol() string { 97 if i.Proto == nil { 98 return "" 99 } 100 return i.Proto.GetProtocol().GetValue() 101 } 102 103 // Version get version 104 func (i *Instance) Version() string { 105 if i.Proto == nil { 106 return "" 107 } 108 return i.Proto.GetVersion().GetValue() 109 } 110 111 // Priority gets priority 112 func (i *Instance) Priority() uint32 { 113 if i.Proto == nil { 114 return 0 115 } 116 return i.Proto.GetPriority().GetValue() 117 } 118 119 // Weight get weight 120 func (i *Instance) Weight() uint32 { 121 if i.Proto == nil { 122 return 0 123 } 124 return i.Proto.GetWeight().GetValue() 125 } 126 127 // EnableHealthCheck get enables health check 128 func (i *Instance) EnableHealthCheck() bool { 129 if i.Proto == nil { 130 return false 131 } 132 return i.Proto.GetEnableHealthCheck().GetValue() 133 } 134 135 // HealthCheck get health check 136 func (i *Instance) HealthCheck() *apiservice.HealthCheck { 137 if i.Proto == nil { 138 return nil 139 } 140 return i.Proto.GetHealthCheck() 141 } 142 143 // Healthy get healthy 144 func (i *Instance) Healthy() bool { 145 if i.Proto == nil { 146 return false 147 } 148 return i.Proto.GetHealthy().GetValue() 149 } 150 151 // Isolate get isolate 152 func (i *Instance) Isolate() bool { 153 if i.Proto == nil { 154 return false 155 } 156 return i.Proto.GetIsolate().GetValue() 157 } 158 159 // Location gets location 160 func (i *Instance) Location() *apimodel.Location { 161 if i.Proto == nil { 162 return nil 163 } 164 return i.Proto.GetLocation() 165 } 166 167 // Metadata get metadata 168 func (i *Instance) Metadata() map[string]string { 169 if i.Proto == nil { 170 return nil 171 } 172 return i.Proto.GetMetadata() 173 } 174 175 // LogicSet get logic set 176 func (i *Instance) LogicSet() string { 177 if i.Proto == nil { 178 return "" 179 } 180 return i.Proto.GetLogicSet().GetValue() 181 } 182 183 // Ctime get ctime 184 func (i *Instance) Ctime() string { 185 if i.Proto == nil { 186 return "" 187 } 188 return i.Proto.GetCtime().GetValue() 189 } 190 191 // Mtime get mtime 192 func (i *Instance) Mtime() string { 193 if i.Proto == nil { 194 return "" 195 } 196 return i.Proto.GetMtime().GetValue() 197 } 198 199 // Revision get revision 200 func (i *Instance) Revision() string { 201 if i.Proto == nil { 202 return "" 203 } 204 return i.Proto.GetRevision().GetValue() 205 } 206 207 // ServiceToken get service token 208 func (i *Instance) ServiceToken() string { 209 if i.Proto == nil { 210 return "" 211 } 212 return i.Proto.GetServiceToken().GetValue() 213 } 214 215 // MallocProto malloc proto if proto is null 216 func (i *Instance) MallocProto() { 217 if i.Proto == nil { 218 i.Proto = &apiservice.Instance{} 219 } 220 } 221 222 // InstanceStore 对应store层(database)的对象 223 type InstanceStore struct { 224 ID string 225 ServiceID string 226 Host string 227 VpcID string 228 Port uint32 229 Protocol string 230 Version string 231 HealthStatus int 232 Isolate int 233 Weight uint32 234 EnableHealthCheck int 235 CheckType int32 236 TTL uint32 237 Priority uint32 238 Revision string 239 LogicSet string 240 Region string 241 Zone string 242 Campus string 243 Meta map[string]string 244 Flag int 245 CreateTime int64 246 ModifyTime int64 247 } 248 249 // ExpandInstanceStore 包含服务名的store信息 250 type ExpandInstanceStore struct { 251 ServiceName string 252 Namespace string 253 ServiceToken string 254 ServicePlatformID string 255 ServiceInstance *InstanceStore 256 } 257 258 // Store2Instance store的数据转换为组合了api的数据结构 259 func Store2Instance(is *InstanceStore) *Instance { 260 ins := &Instance{ 261 Proto: &apiservice.Instance{ 262 Id: &wrappers.StringValue{Value: is.ID}, 263 VpcId: &wrappers.StringValue{Value: is.VpcID}, 264 Host: &wrappers.StringValue{Value: is.Host}, 265 Port: &wrappers.UInt32Value{Value: is.Port}, 266 Protocol: &wrappers.StringValue{Value: is.Protocol}, 267 Version: &wrappers.StringValue{Value: is.Version}, 268 Priority: &wrappers.UInt32Value{Value: is.Priority}, 269 Weight: &wrappers.UInt32Value{Value: is.Weight}, 270 EnableHealthCheck: &wrappers.BoolValue{Value: Int2bool(is.EnableHealthCheck)}, 271 Healthy: &wrappers.BoolValue{Value: Int2bool(is.HealthStatus)}, 272 Location: &apimodel.Location{ 273 Region: &wrappers.StringValue{Value: is.Region}, 274 Zone: &wrappers.StringValue{Value: is.Zone}, 275 Campus: &wrappers.StringValue{Value: is.Campus}, 276 }, 277 Isolate: &wrappers.BoolValue{Value: Int2bool(is.Isolate)}, 278 Metadata: is.Meta, 279 LogicSet: &wrappers.StringValue{Value: is.LogicSet}, 280 Ctime: &wrappers.StringValue{Value: commontime.Int64Time2String(is.CreateTime)}, 281 Mtime: &wrappers.StringValue{Value: commontime.Int64Time2String(is.ModifyTime)}, 282 Revision: &wrappers.StringValue{Value: is.Revision}, 283 }, 284 ServiceID: is.ServiceID, 285 Valid: flag2valid(is.Flag), 286 ModifyTime: time.Unix(is.ModifyTime, 0), 287 } 288 // 如果不存在checkType,即checkType==-1。HealthCheck置为nil 289 if is.CheckType != -1 { 290 ins.Proto.HealthCheck = &apiservice.HealthCheck{ 291 Type: apiservice.HealthCheck_HealthCheckType(is.CheckType), 292 Heartbeat: &apiservice.HeartbeatHealthCheck{ 293 Ttl: &wrappers.UInt32Value{Value: is.TTL}, 294 }, 295 } 296 } 297 // 如果location不为空,那么填充一下location 298 if is.Region != "" { 299 ins.Proto.Location = &apimodel.Location{ 300 Region: &wrappers.StringValue{Value: is.Region}, 301 Zone: &wrappers.StringValue{Value: is.Zone}, 302 Campus: &wrappers.StringValue{Value: is.Campus}, 303 } 304 } 305 306 return ins 307 } 308 309 // ExpandStore2Instance 扩展store转换 310 func ExpandStore2Instance(es *ExpandInstanceStore) *Instance { 311 out := Store2Instance(es.ServiceInstance) 312 out.Proto.Service = &wrappers.StringValue{Value: es.ServiceName} 313 out.Proto.Namespace = &wrappers.StringValue{Value: es.Namespace} 314 if es.ServiceToken != "" { 315 out.Proto.ServiceToken = &wrappers.StringValue{Value: es.ServiceToken} 316 } 317 out.ServicePlatformID = es.ServicePlatformID 318 return out 319 } 320 321 // CreateInstanceModel 创建存储层服务实例模型 322 func CreateInstanceModel(serviceID string, req *apiservice.Instance) *Instance { 323 // 默认为健康的 324 healthy := true 325 if req.GetHealthy() != nil { 326 healthy = req.GetHealthy().GetValue() 327 } 328 329 // 默认为不隔离的 330 isolate := false 331 if req.GetIsolate() != nil { 332 isolate = req.GetIsolate().GetValue() 333 } 334 335 // 权重默认是100 336 var weight uint32 = 100 337 if req.GetWeight() != nil { 338 weight = req.GetWeight().GetValue() 339 } 340 341 instance := &Instance{ 342 ServiceID: serviceID, 343 } 344 345 protoIns := &apiservice.Instance{ 346 Id: req.GetId(), 347 Host: utils.NewStringValue(strings.TrimSpace(req.GetHost().GetValue())), 348 VpcId: req.GetVpcId(), 349 Port: req.GetPort(), 350 Protocol: req.GetProtocol(), 351 Version: req.GetVersion(), 352 Priority: req.GetPriority(), 353 Weight: utils.NewUInt32Value(weight), 354 Healthy: utils.NewBoolValue(healthy), 355 Isolate: utils.NewBoolValue(isolate), 356 Location: req.Location, 357 Metadata: req.Metadata, 358 LogicSet: req.GetLogicSet(), 359 Revision: utils.NewStringValue(utils.NewUUID()), // 更新版本号 360 } 361 362 // health Check,healthCheck不能为空,且没有显示把enable_health_check置为false 363 // 如果create的时候,打开了healthCheck,那么实例模式是unhealthy,必须要一次心跳才会healthy 364 if req.GetHealthCheck().GetHeartbeat() != nil && 365 (req.GetEnableHealthCheck() == nil || req.GetEnableHealthCheck().GetValue()) { 366 protoIns.EnableHealthCheck = utils.NewBoolValue(true) 367 protoIns.HealthCheck = req.HealthCheck 368 protoIns.HealthCheck.Type = apiservice.HealthCheck_HEARTBEAT 369 // ttl range: (0, 60] 370 ttl := protoIns.GetHealthCheck().GetHeartbeat().GetTtl().GetValue() 371 if ttl == 0 || ttl > 60 { 372 if protoIns.HealthCheck.Heartbeat.Ttl == nil { 373 protoIns.HealthCheck.Heartbeat.Ttl = utils.NewUInt32Value(5) 374 } 375 protoIns.HealthCheck.Heartbeat.Ttl.Value = 5 376 } 377 } 378 379 instance.Proto = protoIns 380 return instance 381 }