Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support thrift and pb multi service #1217

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
eda0157
add: WithOnlyAcceptingHTTP2Traffic option and methodSvcMap
Marina-Sakai Jan 5, 2024
f8ec712
feat: server initialization method svc map
Marina-Sakai Jan 5, 2024
8aa2954
feat: message with svcMap and methodSvcMap, pass svcName through tran…
Marina-Sakai Jan 5, 2024
ed6ab91
feat: provide users with a wrapped RegisterService
Marina-Sakai Jan 5, 2024
9582807
feat: handle generic svc and method name
Marina-Sakai Jan 5, 2024
415bd8a
feat: get svcInfo from svc name or method name
Marina-Sakai Jan 5, 2024
b495376
feat: server handler to handle multi service
Marina-Sakai Jan 5, 2024
17ef5f0
fix: add func according to message interface change
Marina-Sakai Jan 5, 2024
1807a59
fix: decode mock func
Marina-Sakai Jan 5, 2024
acd524c
refactor: no need to check by generic method name
Marina-Sakai Jan 5, 2024
63d8796
fix: lint
Marina-Sakai Jan 5, 2024
c535b32
fix: lint
Marina-Sakai Jan 5, 2024
a872a08
fix: delete unnecessary part
Marina-Sakai Jan 5, 2024
edaade9
fix: put svcname into transinfo logic
Marina-Sakai Jan 8, 2024
ec704f3
test: add tests
Marina-Sakai Jan 8, 2024
d1fe994
fix: lint
Marina-Sakai Jan 8, 2024
5995a76
fix: return fallbacksvc if any
Marina-Sakai Jan 9, 2024
4cc8aeb
fix: remove unecessary comment
Marina-Sakai Jan 9, 2024
66dd713
fix: rename
Marina-Sakai Jan 9, 2024
80296c8
fix: delete unnecessary method
Marina-Sakai Jan 9, 2024
2f0ff47
fix: generic logic
Marina-Sakai Jan 9, 2024
d136b1a
fix: delete unnecessary field
Marina-Sakai Jan 9, 2024
d2cce7b
fix: nits
Marina-Sakai Jan 9, 2024
75cbb85
chore: delete unnecessary comment
Marina-Sakai Jan 9, 2024
91a6e3d
fix: only call and oneway is enough to pass transinfo
Marina-Sakai Jan 10, 2024
f6ffd78
fix: handle nil svcInfo
Marina-Sakai Jan 10, 2024
bdd6fd3
fix: handle nil svcInfo
Marina-Sakai Jan 10, 2024
d5bece9
fix: add serverpkg variable
Marina-Sakai Jan 11, 2024
db92bbd
fix: protoc plugin serverpkg logic
Marina-Sakai Jan 11, 2024
9c59d3f
fix: NewData logic
Marina-Sakai Jan 12, 2024
b43e93c
chore: rename option
Marina-Sakai Jan 16, 2024
9a70786
fix: use one map, get svcName inside ttheader domain
Marina-Sakai Jan 17, 2024
1448ddc
feat: add ttheader client meta handler
Marina-Sakai Jan 18, 2024
08312b3
feat: RegisterOption
Marina-Sakai Jan 18, 2024
c2b1883
fix: target svcInfo is always non-nil inside NewData
Marina-Sakai Jan 18, 2024
ef42271
fix: change WithOnlyAcceptingHTTP2Traffic to WithRefuseTrafficWithout…
Marina-Sakai Jan 22, 2024
359f4de
feat: remove unused logic
Marina-Sakai Jan 23, 2024
da32a6d
chore: rename SetServiceInfo
Marina-Sakai Jan 23, 2024
431292e
chore: remove unnecessary argument
Marina-Sakai Jan 23, 2024
cd7b62f
chore: add comments
Marina-Sakai Jan 23, 2024
6e092d6
fix: skip calling GetMethodInfo when svcInfo is nil
Marina-Sakai Jan 23, 2024
88a7ecc
refactor: no need isFallback
Marina-Sakai Jan 24, 2024
e3f452d
fix: no need ClientTTHeaderHandler for generic
Marina-Sakai Jan 24, 2024
3ee53f6
feat: check combine service
Marina-Sakai Jan 24, 2024
8ff9497
fix: revert. remove the variables for generated code
Marina-Sakai Jan 26, 2024
c19c817
fix: simplify the code
Marina-Sakai Jan 26, 2024
45f8663
fix: check if svcName exists
Marina-Sakai Jan 26, 2024
202bb4a
fix: check combine service logic
Marina-Sakai Jan 26, 2024
1257f27
refactor: smaller function
Marina-Sakai Jan 26, 2024
ffa2d88
fix: test
Marina-Sakai Jan 26, 2024
8d28897
refactor: separate into small funcs and use string builder
Marina-Sakai Jan 29, 2024
ee038c6
feat: fallback service for debug
Marina-Sakai Jan 29, 2024
f4afe05
test: add service tests
Marina-Sakai Jan 29, 2024
1110383
fix: external method name and add a comment
Marina-Sakai Jan 30, 2024
c362637
refactor: extract findAndSetDefaultService
Marina-Sakai Feb 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion client/service_inline.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ func NewServiceInlineClient(svcInfo *serviceinfo.ServiceInfo, s ServerInitialInf
kc.opt = client.NewOptions(opts)
kc.serverEps = s.Endpoints()
kc.serverOpt = s.Option()
kc.serverOpt.RemoteOpt.SvcMap = s.GetServiceInfos()
kc.serverOpt.RemoteOpt.TargetSvcInfo = svcInfo
kc.serverOpt.RemoteOpt.SvcSearchMap = s.GetServiceInfos()
if err := kc.init(); err != nil {
_ = kc.Close()
return nil, err
Expand Down
25 changes: 24 additions & 1 deletion internal/mocks/serviceinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
const (
MockServiceName = "MockService"
MockService2Name = "MockService2"
MockService3Name = "MockService3"
MockMethod string = "mock"
Mock2Method string = "mock2"
MockExceptionMethod string = "mockException"
Expand Down Expand Up @@ -66,7 +67,7 @@ func newServiceInfo() *serviceinfo.ServiceInfo {
return svcInfo
}

// ServiceInfo return mock serviceInfo
// Service2Info return mock serviceInfo
func Service2Info() *serviceinfo.ServiceInfo {
return myServiceService2Info
}
Expand All @@ -88,6 +89,28 @@ func newService2Info() *serviceinfo.ServiceInfo {
return svcInfo
}

// Service3Info return mock serviceInfo
func Service3Info() *serviceinfo.ServiceInfo {
return myServiceService3Info
}

var myServiceService3Info = newService3Info()

func newService3Info() *serviceinfo.ServiceInfo {
methods := map[string]serviceinfo.MethodInfo{
"mock": serviceinfo.NewMethodInfo(mockHandler, NewMockArgs, NewMockResult, false),
}

svcInfo := &serviceinfo.ServiceInfo{
ServiceName: MockService3Name,
Methods: methods,
Extra: map[string]interface{}{
"PackageName": "mock",
},
}
return svcInfo
}

func mockHandler(ctx context.Context, handler, args, result interface{}) error {
a := args.(*myServiceMockArgs)
r := result.(*myServiceMockResult)
Expand Down
2 changes: 2 additions & 0 deletions internal/server/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ type Options struct {
BackupOpt backup.Options

Streaming stream.StreamingConfig

RefuseTrafficWithoutServiceName bool
}

type Limit struct {
Expand Down
41 changes: 41 additions & 0 deletions internal/server/register_option.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2024 CloudWeGo 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 server

// RegisterOption is the only way to config service registration.
type RegisterOption struct {
F func(o *RegisterOptions)
}

// RegisterOptions is used to config service registration.
type RegisterOptions struct {
IsFallbackService bool
}

// NewRegisterOptions creates a register options.
func NewRegisterOptions(opts []RegisterOption) *RegisterOptions {
o := &RegisterOptions{}
ApplyRegisterOptions(opts, o)
return o
}

// ApplyRegisterOptions applies the given register options.
func ApplyRegisterOptions(opts []RegisterOption, o *RegisterOptions) {
for _, op := range opts {
op.F(o)

Check warning on line 39 in internal/server/register_option.go

View check run for this annotation

Codecov / codecov/patch

internal/server/register_option.go#L39

Added line #L39 was not covered by tests
}
}
7 changes: 4 additions & 3 deletions pkg/diagnosis/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ func RegisterProbeFunc(svc Service, name ProbeName, pf ProbeFunc) {
// If you want to register other info, please use RegisterProbeFunc(ProbeName, ProbeFunc) to do that.
const (
// Common
ChangeEventsKey ProbeName = "events"
ServiceInfosKey ProbeName = "service_infos"
OptionsKey ProbeName = "options"
ChangeEventsKey ProbeName = "events"
ServiceInfosKey ProbeName = "service_infos"
FallbackServiceKey ProbeName = "fallback_service"
OptionsKey ProbeName = "options"

// Client
DestServiceKey ProbeName = "dest_service"
Expand Down
8 changes: 8 additions & 0 deletions pkg/generic/binarythrift_codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ var _ remote.Message = &mockMessage{}
type mockMessage struct {
RPCInfoFunc func() rpcinfo.RPCInfo
ServiceInfoFunc func() *serviceinfo.ServiceInfo
SetServiceInfoFunc func(svcName, methodName string) (*serviceinfo.ServiceInfo, error)
DataFunc func() interface{}
NewDataFunc func(method string) (ok bool)
MessageTypeFunc func() remote.MessageType
Expand Down Expand Up @@ -198,6 +199,13 @@ func (m *mockMessage) ServiceInfo() (si *serviceinfo.ServiceInfo) {
return
}

func (m *mockMessage) SpecifyServiceInfo(svcName, methodName string) (si *serviceinfo.ServiceInfo, err error) {
if m.SetServiceInfoFunc != nil {
return m.SetServiceInfoFunc(svcName, methodName)
}
return nil, nil
}

func (m *mockMessage) Data() interface{} {
if m.DataFunc != nil {
return m.DataFunc()
Expand Down
4 changes: 4 additions & 0 deletions pkg/generic/json_test/generic_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

"github.com/cloudwego/kitex/client"
"github.com/cloudwego/kitex/client/genericclient"
"github.com/cloudwego/kitex/internal/mocks"
kt "github.com/cloudwego/kitex/internal/mocks/thrift"
"github.com/cloudwego/kitex/internal/test"
"github.com/cloudwego/kitex/pkg/generic"
Expand Down Expand Up @@ -269,6 +270,9 @@
if err := svr.RegisterService(serviceInfo(), handler); err != nil {
panic(err)
}
if err := svr.RegisterService(mocks.ServiceInfo(), mocks.MyServiceHandler()); err != nil {
panic(err)

Check warning on line 274 in pkg/generic/json_test/generic_init.go

View check run for this annotation

Codecov / codecov/patch

pkg/generic/json_test/generic_init.go#L274

Added line #L274 was not covered by tests
}
go func() {
err := svr.Run()
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions pkg/remote/codec/header_codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,11 @@ func fillBasicInfoOfTTHeader(msg remote.Message) {
fi.SetServiceName(v)
}
}
if ink, ok := msg.RPCInfo().Invocation().(rpcinfo.InvocationSetter); ok {
if svcName, ok := msg.TransInfo().TransStrInfo()[transmeta.HeaderIDLServiceName]; ok {
ink.SetServiceName(svcName)
}
}
} else {
ti := remoteinfo.AsRemoteInfo(msg.RPCInfo().To())
if ti != nil {
Expand Down
18 changes: 15 additions & 3 deletions pkg/remote/codec/header_codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/cloudwego/kitex/pkg/remote/transmeta"
"github.com/cloudwego/kitex/pkg/rpcinfo"
"github.com/cloudwego/kitex/pkg/rpcinfo/remoteinfo"
"github.com/cloudwego/kitex/pkg/serviceinfo"
tm "github.com/cloudwego/kitex/pkg/transmeta"
"github.com/cloudwego/kitex/transport"
)
Expand Down Expand Up @@ -306,8 +307,18 @@ var (
)

func initServerRecvMsg() remote.Message {
var req interface{}
msg := remote.NewMessage(req, mocks.ServiceInfo(), mockSvrRPCInfo, remote.Call, remote.Server)
svcInfo := mocks.ServiceInfo()
svcSearchMap := map[string]*serviceinfo.ServiceInfo{
remote.BuildMultiServiceKey(mocks.MockServiceName, mocks.MockMethod): svcInfo,
remote.BuildMultiServiceKey(mocks.MockServiceName, mocks.MockExceptionMethod): svcInfo,
remote.BuildMultiServiceKey(mocks.MockServiceName, mocks.MockErrorMethod): svcInfo,
remote.BuildMultiServiceKey(mocks.MockServiceName, mocks.MockOnewayMethod): svcInfo,
mocks.MockMethod: svcInfo,
mocks.MockExceptionMethod: svcInfo,
mocks.MockErrorMethod: svcInfo,
mocks.MockOnewayMethod: svcInfo,
}
msg := remote.NewMessageWithNewer(svcInfo, svcSearchMap, mockSvrRPCInfo, remote.Call, remote.Server, false)
return msg
}

Expand Down Expand Up @@ -367,14 +378,15 @@ func prepareIntKVInfo() map[uint16]string {
}

func prepareStrKVInfo() map[string]string {
kvInfo := map[string]string{}
kvInfo := map[string]string{transmeta.HeaderIDLServiceName: mocks.MockServiceName}
return kvInfo
}

func prepareStrKVInfoWithGDPRToken() map[string]string {
kvInfo := map[string]string{
transmeta.GDPRToken: "mockToken",
transmeta.HeaderTransRemoteAddr: "mockRemoteAddr",
transmeta.HeaderIDLServiceName: mocks.MockServiceName,
}
return kvInfo
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/remote/codec/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,17 @@ func SetOrCheckMethodName(methodName string, message remote.Message) error {
if message.RPCRole() == remote.Client {
return fmt.Errorf("wrong method name, expect=%s, actual=%s", callMethodName, methodName)
}
svcInfo := message.ServiceInfo()
svcInfo, err := message.SpecifyServiceInfo(ink.ServiceName(), methodName)
if err != nil {
return err
}
if ink, ok := ink.(rpcinfo.InvocationSetter); ok {
ink.SetMethodName(methodName)
ink.SetPackageName(svcInfo.GetPackageName())
ink.SetServiceName(svcInfo.ServiceName)
} else {
return errors.New("the interface Invocation doesn't implement InvocationSetter")
}
if mt := svcInfo.MethodInfo(methodName); mt == nil {
return remote.NewTransErrorWithMsg(remote.UnknownMethod, fmt.Sprintf("unknown method %s", methodName))
}

// unknown method doesn't set methodName for RPCInfo.To(), or lead inconsistent with old version
rpcinfo.AsMutableEndpointInfo(ri.To()).SetMethod(methodName)
Expand Down
20 changes: 18 additions & 2 deletions pkg/remote/codec/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,34 @@ import (
"github.com/cloudwego/kitex/internal/test"
"github.com/cloudwego/kitex/pkg/remote"
"github.com/cloudwego/kitex/pkg/rpcinfo"
"github.com/cloudwego/kitex/pkg/serviceinfo"
)

func TestSetOrCheckMethodName(t *testing.T) {
var req interface{}
ri := rpcinfo.NewRPCInfo(nil, rpcinfo.NewEndpointInfo("", "mock", nil, nil),
rpcinfo.NewServerInvocation(), rpcinfo.NewRPCConfig(), rpcinfo.NewRPCStats())
msg := remote.NewMessage(req, mocks.ServiceInfo(), ri, remote.Call, remote.Server)
svcInfo := mocks.ServiceInfo()
svcSearchMap := map[string]*serviceinfo.ServiceInfo{
remote.BuildMultiServiceKey(mocks.MockServiceName, mocks.MockMethod): svcInfo,
remote.BuildMultiServiceKey(mocks.MockServiceName, mocks.MockExceptionMethod): svcInfo,
remote.BuildMultiServiceKey(mocks.MockServiceName, mocks.MockErrorMethod): svcInfo,
remote.BuildMultiServiceKey(mocks.MockServiceName, mocks.MockOnewayMethod): svcInfo,
mocks.MockMethod: svcInfo,
mocks.MockExceptionMethod: svcInfo,
mocks.MockErrorMethod: svcInfo,
mocks.MockOnewayMethod: svcInfo,
}
msg := remote.NewMessageWithNewer(svcInfo, svcSearchMap, ri, remote.Call, remote.Server, false)
err := SetOrCheckMethodName("mock", msg)
test.Assert(t, err == nil)
ri = msg.RPCInfo()
test.Assert(t, ri.Invocation().ServiceName() == mocks.MockServiceName)
test.Assert(t, ri.Invocation().PackageName() == "mock")
test.Assert(t, ri.Invocation().MethodName() == "mock")
test.Assert(t, ri.To().Method() == "mock")

msg = remote.NewMessageWithNewer(svcInfo, map[string]*serviceinfo.ServiceInfo{}, ri, remote.Call, remote.Server, false)
err = SetOrCheckMethodName("dummy", msg)
test.Assert(t, err != nil)
test.Assert(t, err.Error() == "unknown method dummy")
}
Loading
Loading