4267a229创建于 2024年8月2日历史提交
/*
    Copyright (c) [2023] [squallzhao]
    fountain is licensed under APACHE LICENSE, VERSION 2.0.
    You can use this software according to the terms and conditions of the APACHE LICENSE, VERSION 2.0.
    You may obtain a copy of APACHE LICENSE, VERSION 2.0 at: https://www.apache.org/licenses/LICENSE-2.0
*/
package microservice.registry;

import net.http.*
import std.io.*
import encoding.url.*
import std.fs.*
import encoding.json.*
import microservice.trace.*

public class EurekaRegistry <: IRegistry  {
   var cfg: Config = Config()
   let client = ClientBuilder().build()
   let localIp = getLocalIp()

   public func register(serviceName: String, port: Int64): Bool{
      Logger.trace("register serviceName="+serviceName+",registrycenter url="+cfg.url)
      let data = formatRegisterPost(serviceName,this.localIp,port,"MyOwn")
      var b = ByteArrayStream()
      b.write(data.toArray())

      var req = HttpRequestBuilder().method("POST")
        .url(cfg.url+"/"+serviceName)
        .header("Content-Type","application/json")
        .body(b)
        .build()

      let v = client.send(req)
      return true;
   }

   public func deregister(serviceName: String, port: Int64): Bool{
       var b = ByteArrayStream()
       b.write("".toArray())

       var req = HttpRequestBuilder().method("DELETE")
        .url(cfg.url+"/"+serviceName+"/"+getInstanceId(serviceName,port))
        .header("Content-Type","application/json")
        .body(b)
        .build()

       let v = client.send(req)
       return true;
   }
   
   public func heartBeat(serviceName: String, port: Int64): Bool{
       var b = ByteArrayStream()
       b.write("".toArray())
       var req = HttpRequestBuilder().method("PUT")
        .url(cfg.url+"/"+serviceName+"/"+getInstanceId(serviceName,port))
        .header("Content-Type","application/json")
        .body(b)
        .build()

       let v = client.send(req)
       return true;
   } 
   
   public func discovery(serviceName: String): String{
       var req = HttpRequestBuilder().method("GET")
        .url(cfg.url+"/"+serviceName)
        .header("Content-Type","application/json")
        .header("Accept","application/json")
        .build()

       let v = client.send(req)
       return StringReader(v.body).readToEnd()
   }
   
   public func config(cfg: Config): IRegistry{
       this.cfg = cfg
       return this;
   }

   func getInstanceId(serviceName: String, port: Int64): String{
       return serviceName+":"+this.localIp+":${port}"
   }
   
   func formatRegisterPost(serviceName:String, ipAddr:String, port:Int64, dataCenterName:String):String{
        var map = JsonObject()
        var instMap = JsonObject()
        instMap.put("instanceId", JsonString(serviceName+":"+ipAddr+":"+"${port}"))
        instMap.put("app", JsonString(serviceName))
        instMap.put("ipAddr",JsonString(ipAddr))
        instMap.put("hostName",JsonString(ipAddr))
        instMap.put("status",JsonString("UP"))
        var portMap = JsonObject()
        portMap.put("$",JsonInt(port))
        portMap.put("@enabled",JsonBool(false))
        var dataCenterInfoMap = JsonObject()
        dataCenterInfoMap.put("@class",JsonString("com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo"))
        dataCenterInfoMap.put("name",JsonString(dataCenterName))
        var metaDataMap = JsonObject()
        metaDataMap.put("@class",JsonString("java.util.Collections$EmptyMap"))
        instMap.put("port",portMap)
        instMap.put("dataCenterInfo",dataCenterInfoMap)
        instMap.put("metadata",metaDataMap)
        map.put("instance",instMap)
        return map.toJsonString()
   }

}