blob: d9be8e8be31ea72f407e6529b0d7c6ab241bb605 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package model
import (
"fmt"
)
type ApiType int32
type Status int32
type RequestMethod int32
const (
Down Status = 0
Up Status = 1
Unknown Status = 2
)
const (
METHOD_UNSPECIFIED RequestMethod = 0 + iota
GET
HEAD
POST
PUT
DELETE
CONNECT
OPTIONS
TRACE
)
var RequestMethodName = map[int32]string{
0: "METHOD_UNSPECIFIED",
1: "GET",
2: "HEAD",
3: "POST",
4: "PUT",
5: "DELETE",
6: "CONNECT",
7: "OPTIONS",
8: "TRACE",
}
var RequestMethodValue = map[string]int32{
"METHOD_UNSPECIFIED": 0,
"GET": 1,
"HEAD": 2,
"POST": 3,
"PUT": 4,
"DELETE": 5,
"CONNECT": 6,
"OPTIONS": 7,
"TRACE": 8,
}
type Metadata struct {
Info map[string]MetadataValue
}
type MetadataValue any
const (
ApiTypeREST ApiType = 0 + iota // support for 1.0
ApiTypeGRPC
ApiTypeDUBBO
ApiTypeIstioGRPC
)
var (
StatusName = map[int32]string{
0: "Down",
1: "Up",
2: "Unknown",
}
StatusValue = map[string]int32{
"Down": 0,
"Up": 1,
"Unknown": 2,
}
ApiTypeName = map[int32]string{
0: REST_VALUE,
1: GRPC_VALUE,
2: DUBBO_VALUE,
}
ApiTypeValue = map[string]int32{
REST_VALUE: 0,
GRPC_VALUE: 1,
DUBBO_VALUE: 2,
ISTIOGRPC_VALUE: 3,
}
)
type (
// Address the address
Address struct {
SocketAddress SocketAddress `yaml:"socket_address" json:"socket_address" mapstructure:"socket_address"`
Name string `yaml:"name" json:"name" mapstructure:"name"`
}
// SocketAddress specify either a logical or physical address and port, which are
// used to tell server where to bind/listen, connect to upstream and find
// management servers
SocketAddress struct {
Address string `default:"0.0.0.0" yaml:"address" json:"address" mapstructure:"address"`
Port int `default:"8881" yaml:"port" json:"port" mapstructure:"port"`
ResolverName string `yaml:"resolver_name" json:"resolver_name" mapstructure:"resolver_name"`
Domains []string `yaml:"domains" json:"domains" mapstructure:"domains"`
CertsDir string `yaml:"certs_dir" json:"certs_dir" mapstructure:"certs_dir"`
}
// ConfigSource todo remove un-used
ConfigSource struct {
Path string `yaml:"path" json:"path" mapstructure:"path"`
ApiConfigSource ApiConfigSource `yaml:"api_config_source" json:"api_config_source" mapstructure:"api_config_source"`
}
// ApiConfigSource config the api info. compatible with envoy xDS API
// {
// "api_type": "...",
// "transport_api_version": "...",
// "cluster_names": [],
// "grpc_services": [],
// "refresh_delay": "{...}",
// "request_timeout": "{...}",
// "rate_limit_settings": "{...}",
// "set_node_on_first_message_only": "..."
// }
ApiConfigSource struct {
APIType ApiType `yaml:"omitempty" json:"omitempty"`
APITypeStr string `yaml:"api_type" json:"api_type" mapstructure:"api_type"`
ClusterName []string `yaml:"cluster_name" json:"cluster_name" mapstructure:"cluster_name"`
RefreshDelay string `yaml:"refresh_delay" json:"refresh_delay" mapstructure:"refresh_delay"`
RequestTimeout string `yaml:"request_timeout" json:"request_timeout" mapstructure:"request_timeout"`
GrpcServices []GrpcService `yaml:"grpc_services" json:"grpc_services" mapstructure:"grpc_services"`
//rate_limit_settings todo implement
//set_node_on_first_message_only todo implement
}
// GrpcService define grpc service context
GrpcService struct {
Timeout string `yaml:"timeout" json:"timeout" mapstructure:"timeout"`
InitialMetadata []HeaderValue `yaml:"initial_metadata" json:"initial_metadata" mapstructure:"initial_metadata"`
}
// HeaderValueOption
HeaderValueOption struct {
Header []HeaderValue `yaml:"header" json:"header" mapstructure:"header"`
Append []bool `yaml:"append" json:"append" mapstructure:"append"`
}
// HeaderValue
HeaderValue struct {
Key string `yaml:"key" json:"key" mapstructure:"key"`
Value string `yaml:"value" json:"value" mapstructure:"value"`
}
)
// GetAddress returns the string form used as a map key by health-check
// state, the cluster snapshot's addressByID, and external observability
// surfaces. Domain-mode addresses (Domains is non-empty) format as
// Domains[0]; bare-IP addresses format as "ip:port".
//
// Note: GetAddress() is NOT the string projection of Equal(). It is
// possible for two SocketAddresses with different identity (one
// domain-mode, one IP-mode) to format to the same string and still be
// !Equal — for example, SocketAddress{Domains: ["1.2.3.4:5"]} and
// SocketAddress{Address: "1.2.3.4", Port: 5} both produce "1.2.3.4:5"
// but compare unequal. Callers that need identity comparison must use
// Equal; callers that need a key for address-keyed runtime state (e.g.
// healthcheck deduplication by network endpoint) must use GetAddress
// consistently. Mixing the two within a single subsystem will produce
// the equivalence-class skew described in the cluster snapshot docs.
func (a SocketAddress) GetAddress() string {
if len(a.Domains) > 0 {
return a.Domains[0]
}
return fmt.Sprintf("%s:%v", a.Address, a.Port)
}
// Equal reports whether two SocketAddresses refer to the same upstream
// identity without allocating the formatted "address:port" string.
// Domain-mode addresses (Domains non-empty) compare on Domains[0];
// bare-IP addresses compare on Address+Port. Mixed-mode pairs (one
// domain, one IP+port) are reported unequal because they describe
// different upstreams even when their formatted forms collide.
//
// Equal is NOT a == over GetAddress(). See GetAddress godoc for the
// rationale and known divergence cases. Subsystems should pick one of
// {Equal, GetAddress} as their identity oracle and stick with it.
func (a SocketAddress) Equal(b SocketAddress) bool {
aHasDomain := len(a.Domains) > 0
bHasDomain := len(b.Domains) > 0
if aHasDomain != bHasDomain {
return false
}
if aHasDomain {
return a.Domains[0] == b.Domains[0]
}
return a.Address == b.Address && a.Port == b.Port
}