github.com/polarismesh/polaris@v1.17.8/apiserver/eurekaserver/access.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 eurekaserver 19 20 import ( 21 "context" 22 "encoding/xml" 23 "fmt" 24 "net/http" 25 "strings" 26 27 "github.com/emicklei/go-restful/v3" 28 29 api "github.com/polarismesh/polaris/common/api/v1" 30 "github.com/polarismesh/polaris/common/utils" 31 ) 32 33 const ( 34 ParamAppId string = "appId" 35 ParamInstId string = "instId" 36 ParamValue string = "value" 37 ParamVip string = "vipAddress" 38 ParamSVip string = "svipAddress" 39 HeaderNamespace string = "x-namespace" 40 ) 41 42 // GetEurekaServer eureka web server 43 func (h *EurekaServer) GetEurekaServer() *restful.WebService { 44 ws := new(restful.WebService) 45 46 ws.Path("/eureka").Consumes(restful.MIME_JSON, restful.MIME_OCTET, restful.MIME_XML).Produces(restful.MIME_JSON, 47 restful.MIME_XML) 48 h.addDiscoverAccess(ws) 49 return ws 50 } 51 52 // GetEurekaV1Server eureka v1 web server 53 func (h *EurekaServer) GetEurekaV1Server() *restful.WebService { 54 ws := new(restful.WebService) 55 56 ws.Path("/eureka/v1").Consumes(restful.MIME_JSON, restful.MIME_OCTET, restful.MIME_XML).Produces(restful.MIME_JSON, 57 restful.MIME_XML) 58 h.addDiscoverAccess(ws) 59 return ws 60 } 61 62 // GetEurekaV2Server eureka v2 web server 63 func (h *EurekaServer) GetEurekaV2Server() *restful.WebService { 64 ws := new(restful.WebService) 65 66 ws.Path("/eureka/v2").Consumes(restful.MIME_JSON, restful.MIME_OCTET, restful.MIME_XML).Produces(restful.MIME_JSON, 67 restful.MIME_XML) 68 h.addDiscoverAccess(ws) 69 return ws 70 } 71 72 // addDiscoverAccess 增加服务发现接口 73 func (h *EurekaServer) addDiscoverAccess(ws *restful.WebService) { 74 // Register new application instance 75 ws.Route(ws.POST(fmt.Sprintf("/apps/{%s}", ParamAppId)).To(h.RegisterApplication)). 76 Param(ws.PathParameter(ParamAppId, "applicationId").DataType("string")) 77 // De-register application instance 78 ws.Route(ws.DELETE(fmt.Sprintf("/apps/{%s}/{%s}", ParamAppId, ParamInstId)).To(h.CancelInstance)). 79 Param(ws.PathParameter(ParamAppId, "applicationId").DataType("string")). 80 Param(ws.PathParameter(ParamInstId, "instanceId").DataType("string")) 81 // Send application instance heartbeat 82 ws.Route(ws.PUT(fmt.Sprintf("/apps/{%s}/{%s}", ParamAppId, ParamInstId)).To(h.RenewInstance)). 83 Param(ws.PathParameter(ParamAppId, "applicationId").DataType("string")). 84 Param(ws.PathParameter(ParamInstId, "instanceId").DataType("string")) 85 // Query for all instances 86 ws.Route(ws.GET("/apps").To(h.GetAllApplications)) 87 // Query for all instances(delta) 88 ws.Route(ws.GET("/apps/delta").To(h.GetDeltaApplications)) 89 // Query for all appID instances 90 ws.Route(ws.GET(fmt.Sprintf("/apps/{%s}", ParamAppId)).To(h.GetApplication)). 91 Param(ws.PathParameter(ParamAppId, "applicationId").DataType("string")) 92 // Query for a specific appID/instanceID 93 ws.Route(ws.GET(fmt.Sprintf("/apps/{%s}/{%s}", ParamAppId, ParamInstId)).To(h.GetAppInstance)). 94 Param(ws.PathParameter(ParamAppId, "applicationId").DataType("string")). 95 Param(ws.PathParameter(ParamInstId, "instanceId").DataType("string")) 96 // Take instance out of service 97 ws.Route(ws.PUT(fmt.Sprintf("/apps/{%s}/{%s}/status", ParamAppId, ParamInstId)).To(h.UpdateStatus)). 98 Param(ws.PathParameter(ParamAppId, "applicationId").DataType("string")). 99 Param(ws.PathParameter(ParamInstId, "instanceId").DataType("string")) 100 // Move instance back into service (remove override) 101 ws.Route(ws.DELETE(fmt.Sprintf("/apps/{%s}/{%s}/status", ParamAppId, ParamInstId)).To(h.DeleteStatus)). 102 Param(ws.PathParameter(ParamAppId, "applicationId").DataType("string")). 103 Param(ws.PathParameter(ParamInstId, "instanceId").DataType("string")) 104 // Query for a specific instanceID 105 ws.Route(ws.GET(fmt.Sprintf("/instances/{%s}", ParamInstId)).To(h.GetInstance)). 106 Param(ws.PathParameter(ParamInstId, "instanceId").DataType("string")) 107 // Update metadata 108 ws.Route(ws.PUT(fmt.Sprintf("/apps/{%s}/{%s}/metadata", ParamAppId, ParamInstId)).To(h.UpdateMetadata)). 109 Param(ws.PathParameter(ParamAppId, "applicationId").DataType("string")). 110 Param(ws.PathParameter(ParamInstId, "instanceId").DataType("string")) 111 // Query for all instances under a particular vip address 112 ws.Route(ws.GET(fmt.Sprintf("/vips/{%s}", ParamVip)).To(h.QueryByVipAddress)). 113 Param(ws.PathParameter(ParamVip, "vipAddress").DataType("string")) 114 // Query for all instances under a particular secure vip address 115 ws.Route(ws.GET(fmt.Sprintf("/svips/{%s}", ParamSVip)).To(h.QueryBySVipAddress)). 116 Param(ws.PathParameter(ParamSVip, "svipAddress").DataType("string")) 117 // Query for handling batch replication request 118 ws.Route(ws.POST("/peerreplication/batch").To(h.BatchReplication)) 119 } 120 121 func parseAcceptValue(acceptValue string) map[string]bool { 122 var values map[string]bool 123 blankValues := strings.Split(acceptValue, ",") 124 if len(blankValues) > 0 { 125 values = make(map[string]bool, len(blankValues)) 126 for _, blankValue := range blankValues { 127 values[strings.TrimSpace(blankValue)] = true 128 } 129 } 130 return values 131 } 132 133 // GetAllApplications 全量拉取服务实例信息 134 func (h *EurekaServer) GetAllApplications(req *restful.Request, rsp *restful.Response) { 135 namespace := readNamespaceFromRequest(req, h.namespace) 136 appsRespCache := h.workers.Get(namespace).GetCachedAppsWithLoad() 137 remoteAddr := req.Request.RemoteAddr 138 acceptValue := getParamFromEurekaRequestHeader(req, restful.HEADER_Accept) 139 if err := writeResponse(parseAcceptValue(acceptValue), appsRespCache, req, rsp); nil != err { 140 eurekalog.Errorf("[EurekaServer]fail to write applications, client: %s, err: %v", remoteAddr, err) 141 } 142 } 143 144 func writePolarisStatusCode(req *restful.Request, statusCode uint32) { 145 req.SetAttribute(statusCodeHeader, statusCode) 146 } 147 148 // GetApplication 拉取单个服务实例信息 149 func (h *EurekaServer) GetApplication(req *restful.Request, rsp *restful.Response) { 150 appId := readAppIdFromRequest(req) 151 152 remoteAddr := req.Request.RemoteAddr 153 namespace := readNamespaceFromRequest(req, h.namespace) 154 appsRespCache := h.workers.Get(namespace).GetCachedAppsWithLoad() 155 apps := appsRespCache.AppsResp.Applications 156 app := apps.GetApplication(appId) 157 if app == nil { 158 eurekalog.Errorf("[EurekaServer]service %s not found, client: %s", appId, remoteAddr) 159 writePolarisStatusCode(req, api.NotFoundService) 160 writeHeader(http.StatusNotFound, rsp) 161 return 162 } 163 164 appResp := ApplicationResponse{Application: app} 165 var output interface{} 166 output = appResp.Application 167 168 acceptValue := getParamFromEurekaRequestHeader(req, restful.HEADER_Accept) 169 if len(acceptValue) > 0 && acceptValue == restful.MIME_JSON { 170 output = appResp 171 } 172 if err := writeEurekaResponse(acceptValue, output, req, rsp); nil != err { 173 eurekalog.Errorf("[EurekaServer]fail to write application, client: %s, err: %v", remoteAddr, err) 174 } 175 } 176 177 // GetAppInstance 拉取应用下某个实例的信息 178 func (h *EurekaServer) GetAppInstance(req *restful.Request, rsp *restful.Response) { 179 remoteAddr := req.Request.RemoteAddr 180 appId := readAppIdFromRequest(req) 181 if len(appId) == 0 { 182 eurekalog.Errorf("[EurekaServer] fail to parse request uri, uri: %s, client: %s, err: %s", 183 req.Request.RequestURI, remoteAddr, "service name is empty") 184 writePolarisStatusCode(req, api.InvalidServiceName) 185 writeHeader(http.StatusBadRequest, rsp) 186 return 187 } 188 instId := req.PathParameter(ParamInstId) 189 if len(instId) == 0 { 190 eurekalog.Errorf("[EUREKA-SERVER] fail to parse request uri, uri: %s, client: %s, err: %s", 191 req.Request.RequestURI, remoteAddr, "instance id is required") 192 writePolarisStatusCode(req, api.InvalidInstanceID) 193 writeHeader(http.StatusBadRequest, rsp) 194 return 195 } 196 namespace := readNamespaceFromRequest(req, h.namespace) 197 appsRespCache := h.workers.Get(namespace).GetCachedAppsWithLoad() 198 apps := appsRespCache.AppsResp.Applications 199 app := apps.GetApplication(appId) 200 if app == nil { 201 eurekalog.Errorf("[EurekaServer]service %s not found, client: %s", appId, remoteAddr) 202 writePolarisStatusCode(req, api.NotFoundService) 203 writeHeader(http.StatusNotFound, rsp) 204 return 205 } 206 ins := app.GetInstance(instId) 207 if ins == nil { 208 eurekalog.Errorf("[EurekaServer]instance %s not found, service: %s, client: %s", instId, appId, remoteAddr) 209 writePolarisStatusCode(req, api.NotFoundInstance) 210 writeHeader(http.StatusNotFound, rsp) 211 return 212 } 213 214 insResp := InstanceResponse{InstanceInfo: ins} 215 var output interface{} 216 output = insResp.InstanceInfo 217 acceptValue := getParamFromEurekaRequestHeader(req, restful.HEADER_Accept) 218 if len(acceptValue) > 0 && acceptValue == restful.MIME_JSON { 219 output = insResp 220 } 221 if err := writeEurekaResponse(acceptValue, output, req, rsp); nil != err { 222 eurekalog.Errorf("[EurekaServer]fail to write instance, client: %s, err: %v", remoteAddr, err) 223 } 224 } 225 226 func writeEurekaResponse(acceptValue string, output interface{}, req *restful.Request, rsp *restful.Response) error { 227 return writeEurekaResponseWithCode(acceptValue, output, req, rsp, api.ExecuteSuccess) 228 } 229 230 func writeEurekaResponseWithCode( 231 acceptValue string, output interface{}, req *restful.Request, rsp *restful.Response, statusCode uint32) error { 232 writePolarisStatusCode(req, statusCode) 233 var err error 234 if len(acceptValue) > 0 && acceptValue == restful.MIME_JSON { 235 err = rsp.WriteAsJson(output) 236 } else { 237 err = rsp.WriteAsXml(output) 238 } 239 240 return err 241 } 242 243 const ( 244 MimeJsonWild = "application/*+json" 245 ) 246 247 func writeResponse(acceptValues map[string]bool, appsRespCache *ApplicationsRespCache, 248 req *restful.Request, rsp *restful.Response) error { 249 writePolarisStatusCode(req, api.ExecuteSuccess) 250 var err error 251 if len(acceptValues) > 0 && (hasKey(acceptValues, restful.MIME_JSON) || hasKey(acceptValues, MimeJsonWild)) { 252 if len(appsRespCache.JsonBytes) > 0 { 253 // 直接使用只读缓存返回 254 rsp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON) 255 rsp.WriteHeader(http.StatusOK) 256 _, err = rsp.Write(appsRespCache.JsonBytes) 257 } else { 258 err = rsp.WriteAsJson(appsRespCache.AppsResp) 259 } 260 } else { 261 if len(appsRespCache.XmlBytes) > 0 { 262 rsp.Header().Set(restful.HEADER_ContentType, restful.MIME_XML) 263 rsp.WriteHeader(http.StatusOK) 264 _, err = rsp.Write([]byte(xml.Header)) 265 if err != nil { 266 return err 267 } 268 _, err = rsp.Write(appsRespCache.XmlBytes) 269 return err 270 } 271 err = rsp.WriteAsXml(appsRespCache.AppsResp.Applications) 272 } 273 return err 274 } 275 276 // GetDeltaApplications 增量拉取服务实例信息 277 func (h *EurekaServer) GetDeltaApplications(req *restful.Request, rsp *restful.Response) { 278 namespace := readNamespaceFromRequest(req, h.namespace) 279 work := h.workers.Get(namespace) 280 appsRespCache := work.GetDeltaApps() 281 if nil == appsRespCache { 282 ctx := work.StartWorker() 283 if nil != ctx { 284 <-ctx.Done() 285 } 286 appsRespCache = work.GetDeltaApps() 287 } 288 remoteAddr := req.Request.RemoteAddr 289 acceptValue := getParamFromEurekaRequestHeader(req, restful.HEADER_Accept) 290 if err := writeResponse(parseAcceptValue(acceptValue), appsRespCache, req, rsp); nil != err { 291 eurekalog.Errorf("[EurekaServer]fail to write delta applications, client: %s, err: %v", remoteAddr, err) 292 } 293 } 294 295 func convertInstancePorts(instance *InstanceInfo) error { 296 var err error 297 if nil != instance.Port { 298 if err = instance.Port.convertPortValue(); nil != err { 299 return err 300 } 301 if err = instance.Port.convertEnableValue(); nil != err { 302 return err 303 } 304 } 305 if nil != instance.SecurePort { 306 if err = instance.SecurePort.convertPortValue(); nil != err { 307 return err 308 } 309 if err = instance.SecurePort.convertEnableValue(); nil != err { 310 return err 311 } 312 } 313 return nil 314 } 315 316 func checkRegisterRequest(registrationRequest *RegistrationRequest, req *restful.Request, rsp *restful.Response) bool { 317 var err error 318 remoteAddr := req.Request.RemoteAddr 319 if nil == registrationRequest.Instance { 320 eurekalog.Errorf("[EUREKA-SERVER] fail to parse register request, uri: %s, client: %s, err: %s", 321 req.Request.RequestURI, remoteAddr, "instance content required") 322 writePolarisStatusCode(req, api.EmptyRequest) 323 writeHeader(http.StatusBadRequest, rsp) 324 return false 325 } 326 if len(registrationRequest.Instance.InstanceId) == 0 && len(registrationRequest.Instance.HostName) == 0 { 327 eurekalog.Errorf("[EUREKA-SERVER] fail to parse register request, uri: %s, client: %s, err: %s", 328 req.Request.RequestURI, remoteAddr, "instance id required") 329 writePolarisStatusCode(req, api.InvalidInstanceID) 330 writeHeader(http.StatusBadRequest, rsp) 331 } 332 err = convertInstancePorts(registrationRequest.Instance) 333 if nil != err { 334 eurekalog.Errorf("[EUREKA-SERVER] fail to parse instance register request, "+ 335 "invalid port value, client: %s, err: %v", remoteAddr, err) 336 writePolarisStatusCode(req, api.InvalidInstancePort) 337 writeHeader(http.StatusBadRequest, rsp) 338 } 339 return true 340 } 341 342 // RegisterApplication 服务注册 343 func (h *EurekaServer) RegisterApplication(req *restful.Request, rsp *restful.Response) { 344 remoteAddr := req.Request.RemoteAddr 345 appId := readAppIdFromRequest(req) 346 347 if len(appId) == 0 { 348 eurekalog.Errorf("[EurekaServer] fail to parse request uri, uri: %s, client: %s, err: %s", 349 req.Request.RequestURI, remoteAddr, "service name is empty") 350 writePolarisStatusCode(req, api.InvalidServiceName) 351 writeHeader(http.StatusBadRequest, rsp) 352 return 353 } 354 registrationRequest := &RegistrationRequest{} 355 acceptValue := getParamFromEurekaRequestHeader(req, restful.HEADER_ContentType) 356 var err error 357 if acceptValue == restful.MIME_XML { 358 instance := &InstanceInfo{} 359 registrationRequest.Instance = instance 360 err = req.ReadEntity(&instance) 361 } else { 362 err = req.ReadEntity(registrationRequest) 363 } 364 if nil != err { 365 eurekalog.Errorf("[EUREKA-SERVER] fail to parse instance register request, uri: %s, client: %s, err: %v", 366 req.Request.RequestURI, remoteAddr, err) 367 writePolarisStatusCode(req, api.ParseException) 368 writeHeader(http.StatusBadRequest, rsp) 369 return 370 } 371 372 if !checkRegisterRequest(registrationRequest, req, rsp) { 373 return 374 } 375 376 token, err := getAuthFromEurekaRequestHeader(req) 377 if err != nil { 378 eurekalog.Infof("[EUREKA-SERVER]instance (instId=%s, appId=%s) get basic auth info fail, code is %d", 379 registrationRequest.Instance.InstanceId, appId, api.ExecuteException) 380 writePolarisStatusCode(req, api.ExecuteException) 381 writeHeader(http.StatusUnauthorized, rsp) 382 return 383 } 384 385 ctx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, token) 386 387 namespace := readNamespaceFromRequest(req, h.namespace) 388 eurekalog.Infof( 389 "[EUREKA-SERVER]received instance register request, "+ 390 "client: %s, namespace: %s, instId: %s, appId: %s, ipAddr: %s", 391 remoteAddr, namespace, registrationRequest.Instance.InstanceId, appId, registrationRequest.Instance.IpAddr) 392 code := h.registerInstances(ctx, namespace, appId, registrationRequest.Instance, false) 393 if code == api.ExecuteSuccess || code == api.ExistedResource || code == api.SameInstanceRequest { 394 eurekalog.Infof( 395 "[EUREKA-SERVER]instance (namespace=%s, instId=%s, appId=%s) has been registered successfully,"+ 396 " code is %d", 397 namespace, registrationRequest.Instance.InstanceId, appId, code) 398 writePolarisStatusCode(req, code) 399 writeHeader(http.StatusNoContent, rsp) 400 return 401 } 402 eurekalog.Errorf("[EUREKA-SERVER]instance (namespace=%s, instId=%s, appId=%s) has been registered failed, "+ 403 "code is %d", 404 namespace, registrationRequest.Instance.InstanceId, appId, code) 405 writePolarisStatusCode(req, code) 406 writeHeader(int(code/1000), rsp) 407 } 408 409 // UpdateStatus 更新服务状态 410 func (h *EurekaServer) UpdateStatus(req *restful.Request, rsp *restful.Response) { 411 remoteAddr := req.Request.RemoteAddr 412 appId := readAppIdFromRequest(req) 413 if len(appId) == 0 { 414 eurekalog.Errorf("[EurekaServer] fail to parse request uri, uri: %s, client: %s, err: %s", 415 req.Request.RequestURI, remoteAddr, "service name is empty") 416 writePolarisStatusCode(req, api.InvalidServiceName) 417 writeHeader(http.StatusBadRequest, rsp) 418 return 419 } 420 instId := req.PathParameter(ParamInstId) 421 if len(instId) == 0 { 422 eurekalog.Errorf("[EUREKA-SERVER] fail to parse request uri, uri: %s, client: %s, err: %s", 423 req.Request.RequestURI, remoteAddr, "instance id is required") 424 writePolarisStatusCode(req, api.InvalidInstanceID) 425 writeHeader(http.StatusBadRequest, rsp) 426 return 427 } 428 status := req.QueryParameter(ParamValue) 429 namespace := readNamespaceFromRequest(req, h.namespace) 430 eurekalog.Infof("[EUREKA-SERVER]received instance updateStatus request, "+ 431 "client: %s, namespace: %s, instId: %s, appId: %s, status: %s", 432 remoteAddr, namespace, instId, appId, status) 433 // check status 434 if status == StatusUnknown { 435 writePolarisStatusCode(req, api.ExecuteSuccess) 436 writeHeader(http.StatusOK, rsp) 437 return 438 } 439 ctx := context.WithValue(context.Background(), sourceFromEureka{}, true) 440 code := h.updateStatus(ctx, namespace, appId, instId, status, false) 441 writePolarisStatusCode(req, code) 442 if code == api.ExecuteSuccess || code == api.NoNeedUpdate { 443 eurekalog.Infof("[EUREKA-SERVER] instance (namespace=%s, instId=%s, appId=%s) has been updated successfully", 444 namespace, instId, appId) 445 writeHeader(http.StatusOK, rsp) 446 return 447 } 448 eurekalog.Errorf("[EUREKA-SERVER] instance (namespace=%s, instId=%s, appId=%s) has been updated failed, "+ 449 "code is %d", 450 namespace, instId, appId, code) 451 if code == api.NotFoundResource { 452 writeHeader(http.StatusNotFound, rsp) 453 return 454 } 455 writeHeader(int(code/1000), rsp) 456 } 457 458 // DeleteStatus 关闭强制隔离 459 func (h *EurekaServer) DeleteStatus(req *restful.Request, rsp *restful.Response) { 460 remoteAddr := req.Request.RemoteAddr 461 appId := readAppIdFromRequest(req) 462 if len(appId) == 0 { 463 eurekalog.Errorf("[EurekaServer] fail to parse request uri, uri: %s, client: %s, err: %s", 464 req.Request.RequestURI, remoteAddr, "service name is empty") 465 writePolarisStatusCode(req, api.InvalidServiceName) 466 writeHeader(http.StatusBadRequest, rsp) 467 return 468 } 469 instId := req.PathParameter(ParamInstId) 470 if len(instId) == 0 { 471 eurekalog.Errorf("[EUREKA-SERVER] fail to parse request uri, uri: %s, client: %s, err: %s", 472 req.Request.RequestURI, remoteAddr, "instance id is required") 473 writePolarisStatusCode(req, api.InvalidInstanceID) 474 writeHeader(http.StatusBadRequest, rsp) 475 return 476 } 477 478 namespace := readNamespaceFromRequest(req, h.namespace) 479 480 eurekalog.Infof("[EUREKA-SERVER]received instance status delete request, "+ 481 "client: %s,namespace=%s, instId=%s, appId=%s", 482 remoteAddr, namespace, instId, appId) 483 484 ctx := context.WithValue(context.Background(), sourceFromEureka{}, true) 485 code := h.updateStatus(ctx, namespace, appId, instId, StatusUp, false) 486 writePolarisStatusCode(req, code) 487 if code == api.ExecuteSuccess { 488 eurekalog.Infof("[EUREKA-SERVER]instance status (namespace=%s, instId=%s, appId=%s) "+ 489 "has been deleted successfully", 490 namespace, instId, appId) 491 writeHeader(http.StatusOK, rsp) 492 return 493 } 494 eurekalog.Errorf("[EUREKA-SERVER]instance status (namespace=%s, instId=%s, appId=%s) "+ 495 "has been deleted failed, code is %d", 496 namespace, instId, appId, code) 497 if code == api.NotFoundResource { 498 writeHeader(http.StatusNotFound, rsp) 499 return 500 } 501 writeHeader(int(code/1000), rsp) 502 } 503 504 // RenewInstance 更新实例状态 505 func (h *EurekaServer) RenewInstance(req *restful.Request, rsp *restful.Response) { 506 remoteAddr := req.Request.RemoteAddr 507 appId := readAppIdFromRequest(req) 508 if len(appId) == 0 { 509 eurekalog.Errorf("[EurekaServer] fail to parse request uri, uri: %s, client: %s, err: %s", 510 req.Request.RequestURI, remoteAddr, "service name is empty") 511 writePolarisStatusCode(req, api.InvalidServiceName) 512 writeHeader(http.StatusBadRequest, rsp) 513 return 514 } 515 instId := req.PathParameter(ParamInstId) 516 if len(instId) == 0 { 517 eurekalog.Errorf("[EUREKA-SERVER] fail to parse request uri, uri: %s, client: %s, err: %s", 518 req.Request.RequestURI, remoteAddr, "instance id is required") 519 writePolarisStatusCode(req, api.InvalidInstanceID) 520 writeHeader(http.StatusBadRequest, rsp) 521 return 522 } 523 namespace := readNamespaceFromRequest(req, h.namespace) 524 code := h.renew(context.Background(), namespace, appId, instId, false) 525 writePolarisStatusCode(req, code) 526 if code == api.ExecuteSuccess || code == api.HeartbeatExceedLimit { 527 writeHeader(http.StatusOK, rsp) 528 return 529 } 530 eurekalog.Errorf("[EUREKA-SERVER]instance (namespace=%s, instId=%s, appId=%s) heartbeat failed, code is %d", 531 namespace, instId, appId, code) 532 if code == api.NotFoundResource { 533 writeHeader(http.StatusNotFound, rsp) 534 return 535 } 536 writeHeader(int(code/1000), rsp) 537 } 538 539 // CancelInstance 实例反注册 540 func (h *EurekaServer) CancelInstance(req *restful.Request, rsp *restful.Response) { 541 appId := readAppIdFromRequest(req) 542 remoteAddr := req.Request.RemoteAddr 543 if len(appId) == 0 { 544 eurekalog.Errorf("[EurekaServer] fail to parse request uri, uri: %s, client: %s, err: %s", 545 req.Request.RequestURI, remoteAddr, "service name is empty") 546 writePolarisStatusCode(req, api.InvalidServiceName) 547 writeHeader(http.StatusBadRequest, rsp) 548 return 549 } 550 instId := req.PathParameter(ParamInstId) 551 if len(instId) == 0 { 552 eurekalog.Errorf("[EUREKA-SERVER] fail to parse request uri, uri: %s, client: %s, err: %s", 553 req.Request.RequestURI, remoteAddr, "instance id is required") 554 writePolarisStatusCode(req, api.InvalidInstanceID) 555 writeHeader(http.StatusBadRequest, rsp) 556 return 557 } 558 namespace := readNamespaceFromRequest(req, h.namespace) 559 eurekalog.Infof("[EUREKA-SERVER]received instance deregistered request, "+ 560 "client: %s, namespace: %s, instId: %s, appId: %s", 561 remoteAddr, namespace, instId, appId) 562 code := h.deregisterInstance(context.Background(), namespace, appId, instId, false) 563 writePolarisStatusCode(req, code) 564 if code == api.ExecuteSuccess || code == api.NotFoundResource || code == api.SameInstanceRequest { 565 writeHeader(http.StatusOK, rsp) 566 eurekalog.Infof("[EUREKA-SERVER]instance (namespace=%s, instId=%s, appId=%s) "+ 567 "has been deregistered successfully, code is %d", 568 namespace, instId, appId, code) 569 return 570 } 571 eurekalog.Errorf("[EUREKA-SERVER]instance (namespace=%s, instId=%s, appId=%s) has been deregistered failed,"+ 572 " code is %d", 573 namespace, instId, appId, code) 574 writeHeader(int(code/1000), rsp) 575 } 576 577 // GetInstance query instance by id 578 func (h *EurekaServer) GetInstance(req *restful.Request, rsp *restful.Response) { 579 remoteAddr := req.Request.RemoteAddr 580 instId := req.PathParameter(ParamInstId) 581 if len(instId) == 0 { 582 eurekalog.Errorf("[EUREKA-SERVER] fail to parse request uri, uri: %s, client: %s, err: %s", 583 req.Request.RequestURI, remoteAddr, "instance id is required") 584 writePolarisStatusCode(req, api.InvalidInstanceID) 585 writeHeader(http.StatusBadRequest, rsp) 586 return 587 } 588 namespace := readNamespaceFromRequest(req, h.namespace) 589 appsRespCache := h.workers.Get(namespace).GetCachedAppsWithLoad() 590 apps := appsRespCache.AppsResp.Applications 591 instance := apps.GetInstance(instId) 592 if nil == instance { 593 writePolarisStatusCode(req, api.NotFoundInstance) 594 writeHeader(http.StatusNotFound, rsp) 595 return 596 } 597 insResp := InstanceResponse{InstanceInfo: instance} 598 var output interface{} 599 output = insResp.InstanceInfo 600 acceptValue := getParamFromEurekaRequestHeader(req, restful.HEADER_Accept) 601 if len(acceptValue) > 0 && acceptValue == restful.MIME_JSON { 602 output = insResp 603 } 604 if err := writeEurekaResponse(acceptValue, output, req, rsp); nil != err { 605 eurekalog.Errorf("[EurekaServer]fail to write instance, client: %s, err: %v", remoteAddr, err) 606 } 607 } 608 609 // UpdateMetadata updateStatus instance metadata 610 func (h *EurekaServer) UpdateMetadata(req *restful.Request, rsp *restful.Response) { 611 remoteAddr := req.Request.RemoteAddr 612 appId := readAppIdFromRequest(req) 613 if len(appId) == 0 { 614 eurekalog.Errorf("[EurekaServer] fail to parse request uri, uri: %s, client: %s, err: %s", 615 req.Request.RequestURI, remoteAddr, "service name is empty") 616 writePolarisStatusCode(req, api.InvalidServiceName) 617 writeHeader(http.StatusBadRequest, rsp) 618 return 619 } 620 instId := req.PathParameter(ParamInstId) 621 if len(instId) == 0 { 622 eurekalog.Errorf("[EUREKA-SERVER] fail to parse request uri, uri: %s, client: %s, err: %s", 623 req.Request.RequestURI, remoteAddr, "instance id is required") 624 writePolarisStatusCode(req, api.InvalidInstanceID) 625 writeHeader(http.StatusBadRequest, rsp) 626 return 627 } 628 namespace := readNamespaceFromRequest(req, h.namespace) 629 queryValues := req.Request.URL.Query() 630 metadataMap := make(map[string]string, len(queryValues)) 631 for key, values := range queryValues { 632 if len(values) == 0 { 633 metadataMap[key] = "" 634 continue 635 } 636 metadataMap[key] = values[0] 637 } 638 code := h.updateMetadata(context.Background(), namespace, appId, instId, metadataMap) 639 writePolarisStatusCode(req, code) 640 if code == api.ExecuteSuccess { 641 eurekalog.Infof("[EUREKA-SERVER]instance metadata (namespace=%s, instId=%s, appId=%s) has been updated successfully", 642 namespace, instId, appId) 643 writeHeader(http.StatusOK, rsp) 644 return 645 } 646 eurekalog.Errorf("[EUREKA-SERVER]instance metadata (namespace=%s, instId=%s, appId=%s) has been updated failed, "+ 647 "code is %d", 648 namespace, instId, appId, code) 649 if code == api.NotFoundResource { 650 writeHeader(http.StatusNotFound, rsp) 651 return 652 } 653 writeHeader(int(code/1000), rsp) 654 } 655 656 // QueryByVipAddress query for all instances under a particular vip address 657 func (h *EurekaServer) QueryByVipAddress(req *restful.Request, rsp *restful.Response) { 658 remoteAddr := req.Request.RemoteAddr 659 vipAddress := req.PathParameter(ParamVip) 660 if len(vipAddress) == 0 { 661 eurekalog.Errorf("[EurekaServer] fail to parse request uri, uri: %s, client: %s, err: %s", 662 req.Request.RequestURI, remoteAddr, "vip address is empty") 663 writePolarisStatusCode(req, api.InvalidParameter) 664 writeHeader(http.StatusBadRequest, rsp) 665 return 666 } 667 668 namespace := readNamespaceFromRequest(req, h.namespace) 669 appsRespCache := h.workers.Get(namespace).GetVipApps(VipCacheKey{ 670 entityType: entityTypeVip, 671 targetVipAddress: formatReadName(vipAddress), 672 }) 673 acceptValue := getParamFromEurekaRequestHeader(req, restful.HEADER_Accept) 674 if err := writeResponse(parseAcceptValue(acceptValue), appsRespCache, req, rsp); nil != err { 675 eurekalog.Errorf("[EurekaServer]fail to write vip applications, client: %s, err: %v", remoteAddr, err) 676 } 677 } 678 679 // QueryBySVipAddress query for all instances under a particular secure vip address 680 func (h *EurekaServer) QueryBySVipAddress(req *restful.Request, rsp *restful.Response) { 681 remoteAddr := req.Request.RemoteAddr 682 vipAddress := req.PathParameter(ParamSVip) 683 if len(vipAddress) == 0 { 684 eurekalog.Errorf("[EurekaServer] fail to parse request uri, uri: %s, client: %s, err: %s", 685 req.Request.RequestURI, remoteAddr, "svip address is empty") 686 writePolarisStatusCode(req, api.InvalidParameter) 687 writeHeader(http.StatusBadRequest, rsp) 688 return 689 } 690 namespace := readNamespaceFromRequest(req, h.namespace) 691 appsRespCache := h.workers.Get(namespace).GetVipApps(VipCacheKey{ 692 entityType: entityTypeSVip, 693 targetVipAddress: formatReadName(vipAddress), 694 }) 695 acceptValue := getParamFromEurekaRequestHeader(req, restful.HEADER_Accept) 696 if err := writeResponse(parseAcceptValue(acceptValue), appsRespCache, req, rsp); nil != err { 697 eurekalog.Errorf("[EurekaServer]fail to write svip applications, client: %s, err: %v", remoteAddr, err) 698 } 699 }