blob: ce0622c9ca5e76e9b6ef490f12b441a0f940cce8 [file] [log] [blame]
// Copyright Istio Authors
//
// Licensed 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 echo
import (
"fmt"
"reflect"
)
import (
"github.com/apache/dubbo-go-pixiu/pkg/config/protocol"
"github.com/apache/dubbo-go-pixiu/pkg/test/echo/common/scheme"
)
// NoServicePort defines the ServicePort value for a Port that is a workload-only port.
const NoServicePort = -1
// Port exposed by an Echo Instance
type Port struct {
// Name of this port
Name string
// Protocol to be used for the port.
Protocol protocol.Instance
// ServicePort number where the service can be reached. Does not necessarily
// map to the corresponding port numbers for the instances behind the
// service. If zero (default), a service port will be automatically generated for this port.
// If set to NoServicePort, this port will be assumed to be a workload-only port.
ServicePort int
// WorkloadPort number where the workload is listening for connections.
// This need not be the same as the ServicePort where the service is accessed.
WorkloadPort int
// TLS determines whether the connection will be plain text or TLS. By default this is false (plain text).
TLS bool
// ServerFirst determines whether the port will use server first communication, meaning the client will not send the first byte.
ServerFirst bool
// InstanceIP determines if echo will listen on the instance IP; otherwise, it will listen on wildcard
InstanceIP bool
// LocalhostIP determines if echo will listen on the localhost IP; otherwise, it will listen on wildcard
LocalhostIP bool
}
// IsWorkloadOnly returns true if there is no service port specified for this Port.
func (p Port) IsWorkloadOnly() bool {
return p.ServicePort == NoServicePort
}
// Scheme infers the scheme to be used based on the Protocol.
func (p Port) Scheme() (scheme.Instance, error) {
switch p.Protocol {
case protocol.GRPC, protocol.GRPCWeb, protocol.HTTP2:
return scheme.GRPC, nil
case protocol.HTTP:
return scheme.HTTP, nil
case protocol.HTTPS:
return scheme.HTTPS, nil
case protocol.TCP:
return scheme.TCP, nil
default:
return "", fmt.Errorf("failed creating call for port %s: unsupported protocol %s",
p.Name, p.Protocol)
}
}
type Ports []Port
func (ps Ports) Contains(p Port) bool {
for _, port := range ps {
if reflect.DeepEqual(port, p) {
return true
}
}
return false
}
// ForName returns the first port found with the given name.
func (ps Ports) ForName(name string) (Port, bool) {
for _, port := range ps {
if name == port.Name {
return port, true
}
}
return Port{}, false
}
// MustForName calls ForName and panics if not found.
func (ps Ports) MustForName(name string) Port {
p, found := ps.ForName(name)
if !found {
panic("port does not exist for name " + name)
}
return p
}
// ForProtocol returns the first port found with the given protocol.
func (ps Ports) ForProtocol(protocol protocol.Instance) (Port, bool) {
for _, p := range ps {
if p.Protocol == protocol {
return p, true
}
}
return Port{}, false
}
// ForServicePort returns the first port found with the given service port.
func (ps Ports) ForServicePort(port int) (Port, bool) {
for _, p := range ps {
if p.ServicePort == port {
return p, true
}
}
return Port{}, false
}
// MustForProtocol calls ForProtocol and panics if not found.
func (ps Ports) MustForProtocol(protocol protocol.Instance) Port {
p, found := ps.ForProtocol(protocol)
if !found {
panic("port does not exist for protocol " + protocol)
}
return p
}
// GetServicePorts returns the subset of ports that contain a service port.
func (ps Ports) GetServicePorts() Ports {
out := make(Ports, 0, len(ps))
for _, p := range ps {
if !p.IsWorkloadOnly() {
out = append(out, p)
}
}
return out
}
// GetWorkloadOnlyPorts returns the subset of ports that do not contain a service port.
func (ps Ports) GetWorkloadOnlyPorts() Ports {
out := make(Ports, 0, len(ps))
for _, p := range ps {
if p.IsWorkloadOnly() {
out = append(out, p)
}
}
return out
}