mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2024-12-16 03:29:01 +08:00
183 lines
4.9 KiB
Go
183 lines
4.9 KiB
Go
package pb
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/seaweedfs/seaweedfs/weed/pb/master_pb"
|
|
"github.com/seaweedfs/seaweedfs/weed/util"
|
|
"net"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type ServerAddress string
|
|
type ServerAddresses string
|
|
type ServerSrvAddress string
|
|
|
|
func NewServerAddress(host string, port int, grpcPort int) ServerAddress {
|
|
if grpcPort == 0 || grpcPort == port+10000 {
|
|
return ServerAddress(util.JoinHostPort(host, port))
|
|
}
|
|
return ServerAddress(util.JoinHostPort(host, port) + "." + strconv.Itoa(grpcPort))
|
|
}
|
|
|
|
func NewServerAddressWithGrpcPort(address string, grpcPort int) ServerAddress {
|
|
if grpcPort == 0 {
|
|
return ServerAddress(address)
|
|
}
|
|
_, port, _ := hostAndPort(address)
|
|
if uint64(grpcPort) == port+10000 {
|
|
return ServerAddress(address)
|
|
}
|
|
return ServerAddress(address + "." + strconv.Itoa(grpcPort))
|
|
}
|
|
|
|
func NewServerAddressFromDataNode(dn *master_pb.DataNodeInfo) ServerAddress {
|
|
return NewServerAddressWithGrpcPort(dn.Id, int(dn.GrpcPort))
|
|
}
|
|
|
|
func NewServerAddressFromLocation(dn *master_pb.Location) ServerAddress {
|
|
return NewServerAddressWithGrpcPort(dn.Url, int(dn.GrpcPort))
|
|
}
|
|
|
|
func (sa ServerAddress) String() string {
|
|
return sa.ToHttpAddress()
|
|
}
|
|
|
|
func (sa ServerAddress) ToHttpAddress() string {
|
|
portsSepIndex := strings.LastIndex(string(sa), ":")
|
|
if portsSepIndex < 0 {
|
|
return string(sa)
|
|
}
|
|
if portsSepIndex+1 >= len(sa) {
|
|
return string(sa)
|
|
}
|
|
ports := string(sa[portsSepIndex+1:])
|
|
sepIndex := strings.LastIndex(string(ports), ".")
|
|
if sepIndex >= 0 {
|
|
host := string(sa[0:portsSepIndex])
|
|
return net.JoinHostPort(host, ports[0:sepIndex])
|
|
}
|
|
return string(sa)
|
|
}
|
|
|
|
func (sa ServerAddress) ToGrpcAddress() string {
|
|
portsSepIndex := strings.LastIndex(string(sa), ":")
|
|
if portsSepIndex < 0 {
|
|
return string(sa)
|
|
}
|
|
if portsSepIndex+1 >= len(sa) {
|
|
return string(sa)
|
|
}
|
|
ports := string(sa[portsSepIndex+1:])
|
|
sepIndex := strings.LastIndex(ports, ".")
|
|
if sepIndex >= 0 {
|
|
host := string(sa[0:portsSepIndex])
|
|
return net.JoinHostPort(host, ports[sepIndex+1:])
|
|
}
|
|
return ServerToGrpcAddress(string(sa))
|
|
}
|
|
|
|
// LookUp may return an error for some records along with successful lookups - make sure you do not
|
|
// discard `addresses` even if `err == nil`
|
|
func (r ServerSrvAddress) LookUp() (addresses []ServerAddress, err error) {
|
|
_, records, lookupErr := net.LookupSRV("", "", string(r))
|
|
if lookupErr != nil {
|
|
err = fmt.Errorf("lookup SRV address %s: %v", r, lookupErr)
|
|
}
|
|
for _, srv := range records {
|
|
address := fmt.Sprintf("%s:%d", srv.Target, srv.Port)
|
|
addresses = append(addresses, ServerAddress(address))
|
|
}
|
|
return
|
|
}
|
|
|
|
// ToServiceDiscovery expects one of: a comma-separated list of ip:port, like
|
|
//
|
|
// 10.0.0.1:9999,10.0.0.2:24:9999
|
|
//
|
|
// OR an SRV Record prepended with 'dnssrv+', like:
|
|
//
|
|
// dnssrv+_grpc._tcp.master.consul
|
|
// dnssrv+_grpc._tcp.headless.default.svc.cluster.local
|
|
// dnssrv+seaweed-master.master.consul
|
|
func (sa ServerAddresses) ToServiceDiscovery() (sd *ServerDiscovery) {
|
|
sd = &ServerDiscovery{}
|
|
prefix := "dnssrv+"
|
|
if strings.HasPrefix(string(sa), prefix) {
|
|
trimmed := strings.TrimPrefix(string(sa), prefix)
|
|
srv := ServerSrvAddress(trimmed)
|
|
sd.srvRecord = &srv
|
|
} else {
|
|
sd.list = sa.ToAddresses()
|
|
}
|
|
return
|
|
}
|
|
|
|
func (sa ServerAddresses) ToAddresses() (addresses []ServerAddress) {
|
|
parts := strings.Split(string(sa), ",")
|
|
for _, address := range parts {
|
|
if address != "" {
|
|
addresses = append(addresses, ServerAddress(address))
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (sa ServerAddresses) ToAddressMap() (addresses map[string]ServerAddress) {
|
|
addresses = make(map[string]ServerAddress)
|
|
for _, address := range sa.ToAddresses() {
|
|
addresses[string(address)] = address
|
|
}
|
|
return
|
|
}
|
|
|
|
func (sa ServerAddresses) ToAddressStrings() (addresses []string) {
|
|
parts := strings.Split(string(sa), ",")
|
|
for _, address := range parts {
|
|
addresses = append(addresses, address)
|
|
}
|
|
return
|
|
}
|
|
|
|
func ToAddressStrings(addresses []ServerAddress) []string {
|
|
var strings []string
|
|
for _, addr := range addresses {
|
|
strings = append(strings, string(addr))
|
|
}
|
|
return strings
|
|
}
|
|
func ToAddressStringsFromMap(addresses map[string]ServerAddress) []string {
|
|
var strings []string
|
|
for _, addr := range addresses {
|
|
strings = append(strings, string(addr))
|
|
}
|
|
return strings
|
|
}
|
|
func FromAddressStrings(strings []string) []ServerAddress {
|
|
var addresses []ServerAddress
|
|
for _, addr := range strings {
|
|
addresses = append(addresses, ServerAddress(addr))
|
|
}
|
|
return addresses
|
|
}
|
|
|
|
func ParseUrl(input string) (address ServerAddress, path string, err error) {
|
|
if !strings.HasPrefix(input, "http://") {
|
|
return "", "", fmt.Errorf("url %s needs prefix 'http://'", input)
|
|
}
|
|
input = input[7:]
|
|
pathSeparatorIndex := strings.Index(input, "/")
|
|
hostAndPorts := input
|
|
if pathSeparatorIndex > 0 {
|
|
path = input[pathSeparatorIndex:]
|
|
hostAndPorts = input[0:pathSeparatorIndex]
|
|
}
|
|
commaSeparatorIndex := strings.Index(input, ":")
|
|
if commaSeparatorIndex < 0 {
|
|
err = fmt.Errorf("port should be specified in %s", input)
|
|
return
|
|
}
|
|
address = ServerAddress(hostAndPorts)
|
|
return
|
|
}
|