Skip to content

Commit

Permalink
* * * TMP * * *
Browse files Browse the repository at this point in the history
  • Loading branch information
Vladimir Popov committed Nov 24, 2020
1 parent fe601f8 commit 24a6093
Show file tree
Hide file tree
Showing 19 changed files with 331 additions and 321 deletions.
77 changes: 77 additions & 0 deletions pkg/networkservice/chains/client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Functional requirements

There are some common chain elements that we expect to have in every client chain to make NSM working. Instead of that,
there are few different scenarios when we need to create a client chain to initiate NSM request:
1. Client to NSMgr - simple case when there is an application requesting some L2/L3 connection from the NSMgr.
* no incoming L2/L3 request - client itself is a request generator
* single request receiver - clients requests only the NSMgr, we need only ony GRPC client
```
Client --Request--> NSMgr
| |
|---L2/L3 connection---|
| |
```
2. Server to NSMgr client - we already have application running as a NSM endpoint receiving request to L2/L3 connection,
but it also needs to request some other L2/L3 connection from the NSMgr.
* there is an incoming L2/L3 request - we need to generate an outgoing L2/L3 request, but the connection we return
is an incoming connection
* single request receiver - server requests only the NSMgr, we need only one GRPC client
```
... Endpoint --Request--> NSMgr
| | |
|---L2/L3 connection---|---L2/L3 connection---|
| | |
```
3. Server to endpoint client - we already have application running as a NSM endpoint receiving request to L2/L3
connection, but it also needs to request some other L2/L3 connection from some other endpoint.
* there is an incoming L2/L3 request - we need to generate an outgoing L2/L3 request, but the connection we return
is an incoming connection
* multiple request receivers - server requests different endpoints, we need multiple GRPC clients
```
... Endpoint --Request--> Endpoint
| | |
|---L2/L3 connection---|---L2/L3 connection---|
| | |
```
4. Proxy to NSMgr client - we already have application running as a NSM server, but it doesn't provide L2/L3
connection, it simply passes the request to the NSMgr.
* there is an incoming L2/L3 request but we simply forward it
* single request receiver - proxy requests only the NSMgr, we need only one GRPC client
```
... Proxy --Request--> NSMgr
| | |
|---------------L2/L3 connection--------------|
| | |
```
5. Proxy to endpoint client - we already have application running as a NSM server, but it doesn't provide L2/L3
connection, it simply passes the request to some other endpoint.
* there is an incoming L2/L3 request but we simply forward it
* multiple request receivers - proxy requests different endpoints, we need multiple GRPC clients.
```
... Proxy --Request--> Endpoint
| | |
|---------------L2/L3 connection--------------|
| | |
```
# Implementation
## client.NewClient(..., grpcCC, ...additionalFunctionality)
It is a solution for the (1.) case. Client appends `additionalFunctionality` to the default client chain and passes
incoming request to the NSMgr over the `grpcCC`. Since (4.) case doesn't need incoming request to be translated, this
also can be used for the (4.) case.
## client.NewServerClient(..., grpcCC, ...additionalFunctionality)
It is a solution for the (2.) case. It differs with `client.NewClient` because it generates new outgoing request and
passes it to the NSMgr over the `grpcCC` but returns incoming connection.
## client.NewServerClientFactory(..., ...additionalFunctionality)
It is a solution for the (3.) case. Now we don't have some predefined `grpcCC` and so we create a new GRPC client on
each new client URL received from the incoming request, then we process it like (2.)
## client.NewProxyClientFactory(..., ...additionalFunctionality)
It is a solution for the (5.) case. We create a new GRPC client on each new client URL received, but process like (1.)
43 changes: 23 additions & 20 deletions pkg/networkservice/chains/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,22 @@ package client
import (
"context"

"github.com/networkservicemesh/sdk/pkg/networkservice/common/updatetoken"
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/inject/injectpeer"

"github.com/networkservicemesh/api/pkg/api/networkservice"
"google.golang.org/grpc"

"github.com/networkservicemesh/sdk/pkg/networkservice/common/authorize"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/heal"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/refresh"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/translation"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/updatepath"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/updatetoken"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/chain"
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/inject/injectpeer"

"github.com/networkservicemesh/sdk/pkg/tools/token"
)

// NewClient - returns a NetworkServiceMesh client as a chain of the standard Client pieces plus whatever
// additional functionality is specified
// NewClient - returns a (1.), (4.) cases NSM client.
// - ctx - context for the lifecycle of the *Client* itself. Cancel when discarding the client.
// - name - name of the NetworkServiceMeshClient
// - onHeal - *networkservice.NetworkServiceClient. Since networkservice.NetworkServiceClient is an interface
Expand Down Expand Up @@ -71,21 +70,25 @@ func NewClient(ctx context.Context, name string, onHeal *networkservice.NetworkS
return rv
}

// NewClientFactory - returns a func(cc grpc.ClientConnInterface)that returns a standard Client pieces plus whatever
// additional functionality is specified
// - name - name of the NetworkServiceMeshClient
// - onHeal - *networkservice.NetworkServiceClient. Since networkservice.NetworkServiceClient is an interface
// (and thus a pointer) *networkservice.NetworkServiceClient is a double pointer. Meaning it
// points to a place that points to a place that implements networkservice.NetworkServiceClient
// This is done because when we use heal.NewClient as part of a chain, we may not *have*
// a pointer to this
// client used 'onHeal'. If we detect we need to heal, onHeal.Request is used to heal.
// If onHeal is nil, then we simply set onHeal to this client chain element
// If we are part of a larger chain or a server, we should pass the resulting chain into
// this constructor before we actually have a pointer to it.
// If onHeal nil, onHeal will be pointed to the returned networkservice.NetworkServiceClient
// - additionalFunctionality - any additional NetworkServiceClient chain elements to be included in the chain
func NewClientFactory(name string, onHeal *networkservice.NetworkServiceClient, tokenGenerator token.GeneratorFunc, additionalFunctionality ...networkservice.NetworkServiceClient) func(ctx context.Context, cc grpc.ClientConnInterface) networkservice.NetworkServiceClient {
// NewServerClient - returns a (2.) case NSM client.
func NewServerClient(ctx context.Context, name string, onHeal *networkservice.NetworkServiceClient, tokenGenerator token.GeneratorFunc, cc grpc.ClientConnInterface, additionalFunctionality ...networkservice.NetworkServiceClient) networkservice.NetworkServiceClient {
return chain.NewNetworkServiceClient(
translation.NewClient(),
NewClient(ctx, name, onHeal, tokenGenerator, cc, additionalFunctionality...),
)
}

// NewServerClientFactory - returns a (3.) case func(cc grpc.ClientConnInterface) NSM client factory.
func NewServerClientFactory(name string, onHeal *networkservice.NetworkServiceClient, tokenGenerator token.GeneratorFunc, additionalFunctionality ...networkservice.NetworkServiceClient) func(ctx context.Context, cc grpc.ClientConnInterface) networkservice.NetworkServiceClient {
return func(ctx context.Context, cc grpc.ClientConnInterface) networkservice.NetworkServiceClient {
return chain.NewNetworkServiceClient(
NewServerClient(ctx, name, onHeal, tokenGenerator, cc, additionalFunctionality...),
)
}
}

// NewProxyClientFactory - returns a (5.) case func(cc grpc.ClientConnInterface) NSM client factory.
func NewProxyClientFactory(name string, onHeal *networkservice.NetworkServiceClient, tokenGenerator token.GeneratorFunc, additionalFunctionality ...networkservice.NetworkServiceClient) func(ctx context.Context, cc grpc.ClientConnInterface) networkservice.NetworkServiceClient {
return func(ctx context.Context, cc grpc.ClientConnInterface) networkservice.NetworkServiceClient {
return NewClient(ctx, name, onHeal, tokenGenerator, cc, additionalFunctionality...)
}
Expand Down
38 changes: 0 additions & 38 deletions pkg/networkservice/chains/forwarder/translation_client.go

This file was deleted.

6 changes: 3 additions & 3 deletions pkg/networkservice/chains/nsmgr/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package nsmgr
import (
"context"

"github.com/networkservicemesh/sdk/pkg/networkservice/chains/client"
"github.com/networkservicemesh/sdk/pkg/registry/common/querycache"
"github.com/networkservicemesh/sdk/pkg/registry/core/next"

Expand All @@ -43,7 +44,6 @@ import (
"github.com/networkservicemesh/sdk/pkg/registry/core/nextwrap"
"github.com/networkservicemesh/sdk/pkg/registry/memory"

"github.com/networkservicemesh/sdk/pkg/networkservice/chains/client"
"github.com/networkservicemesh/sdk/pkg/networkservice/chains/endpoint"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/connect"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/discover"
Expand Down Expand Up @@ -115,11 +115,11 @@ func NewServer(ctx context.Context, nsmRegistration *registryapi.NetworkServiceE
interpose.NewServer(&interposeRegistry),
filtermechanisms.NewServer(&urlsRegistryServer),
connect.NewServer(ctx,
NewTranslationClient,
client.NewClientFactory(
client.NewProxyClientFactory(
nsmRegistration.Name,
addressof.NetworkServiceClient(adapters.NewServerToClient(rv)),
tokenGenerator,

newSendFDClient(), // Send passed files.
),
clientDialOptions...),
Expand Down
77 changes: 40 additions & 37 deletions pkg/networkservice/chains/nsmgr/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,10 @@ import (
kernelmech "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/kernel"
"github.com/networkservicemesh/api/pkg/api/registry"

"github.com/networkservicemesh/sdk/pkg/networkservice/common/clienturl"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/connect"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/connect/translation"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/mechanisms/kernel"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/adapters"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/next"
"github.com/networkservicemesh/sdk/pkg/tools/sandbox"
"github.com/networkservicemesh/sdk/pkg/tools/spanhelper"
)

func TestNSMGR_RemoteUsecase_Parallel(t *testing.T) {
Expand Down Expand Up @@ -242,15 +239,13 @@ func TestNSMGR_PassThroughRemote(t *testing.T) {
k := i
// Passtrough to the node i-1
additionalFunctionality = []networkservice.NetworkServiceServer{
clienturl.NewServer(domain.Nodes[i].NSMgr.URL),
connect.NewServer(ctx,
func() networkservice.NetworkServiceClient {
return newPassThroughTranslationClient(
adapters.NewClientToServer(
sandbox.NewServerClient(ctx, sandbox.GenerateTestToken, domain.Nodes[i].NSMgr.URL,
newPassTroughClient(
fmt.Sprintf("my-service-remote-%v", k-1),
fmt.Sprintf("endpoint-%v", k-1))
},
sandbox.NewClientFactory(sandbox.GenerateTestToken, kernel.NewClient()),
append(spanhelper.WithTracingDial(), grpc.WithBlock(), grpc.WithInsecure())...,
fmt.Sprintf("endpoint-%v", k-1)),
kernel.NewClient(),
),
),
}
}
Expand Down Expand Up @@ -286,11 +281,13 @@ func TestNSMGR_PassThroughRemote(t *testing.T) {
}

func TestNSMGR_PassThroughLocal(t *testing.T) {
nsesCount := 7
nsesCount := 2

defer goleak.VerifyNone(t, goleak.IgnoreCurrent())
logrus.SetOutput(ioutil.Discard)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
//logrus.SetOutput(ioutil.Discard)
logrus.SetLevel(logrus.WarnLevel)
//ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
domain := sandbox.NewBuilder(t).
SetNodesCount(1).
Expand All @@ -304,15 +301,13 @@ func TestNSMGR_PassThroughLocal(t *testing.T) {
if i != 0 {
k := i
additionalFunctionality = []networkservice.NetworkServiceServer{
clienturl.NewServer(domain.Nodes[0].NSMgr.URL),
connect.NewServer(ctx,
func() networkservice.NetworkServiceClient {
return newPassThroughTranslationClient(
adapters.NewClientToServer(
sandbox.NewServerClient(ctx, sandbox.GenerateTestToken, domain.Nodes[0].NSMgr.URL,
newPassTroughClient(
fmt.Sprintf("my-service-remote-%v", k-1),
fmt.Sprintf("endpoint-%v", k-1))
},
sandbox.NewClientFactory(sandbox.GenerateTestToken, kernel.NewClient()),
append(spanhelper.WithTracingDial(), grpc.WithBlock(), grpc.WithInsecure())...,
fmt.Sprintf("endpoint-%v", k-1)),
kernel.NewClient(),
),
),
}
}
Expand Down Expand Up @@ -347,20 +342,28 @@ func TestNSMGR_PassThroughLocal(t *testing.T) {
require.Equal(t, 5*(nsesCount-1)+5, len(conn.Path.PathSegments))
}

func newPassThroughTranslationClient(networkService, networkServiceEndpointName string) networkservice.NetworkServiceClient {
return new(translation.Builder).
WithRequestOptions(
func(request *networkservice.NetworkServiceRequest, _ *networkservice.Connection) {
request.Connection.NetworkService = networkService
request.Connection.NetworkServiceEndpointName = networkServiceEndpointName
},
translation.ReplaceMechanismPreferences(),
).
WithConnectionOptions(
translation.WithContext(),
translation.WithPathSegments(),
).
Build()
type passThroughClient struct {
networkService string
networkServiceEndpointName string
}

func newPassTroughClient(networkService, networkServiceEndpointName string) *passThroughClient {
return &passThroughClient{
networkService: networkService,
networkServiceEndpointName: networkServiceEndpointName,
}
}

func (c *passThroughClient) Request(ctx context.Context, request *networkservice.NetworkServiceRequest, opts ...grpc.CallOption) (*networkservice.Connection, error) {
request.Connection.NetworkService = c.networkService
request.Connection.NetworkServiceEndpointName = c.networkServiceEndpointName
return next.Client(ctx).Request(ctx, request, opts...)
}

func (c *passThroughClient) Close(ctx context.Context, conn *networkservice.Connection, opts ...grpc.CallOption) (*empty.Empty, error) {
conn.NetworkService = c.networkService
conn.NetworkServiceEndpointName = c.networkServiceEndpointName
return next.Client(ctx).Close(ctx, conn, opts...)
}

type counterServer struct {
Expand Down
34 changes: 0 additions & 34 deletions pkg/networkservice/chains/nsmgr/translation_client.go

This file was deleted.

4 changes: 1 addition & 3 deletions pkg/networkservice/chains/nsmgrproxy/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (

"github.com/networkservicemesh/sdk/pkg/networkservice/chains/client"
"github.com/networkservicemesh/sdk/pkg/networkservice/chains/endpoint"
"github.com/networkservicemesh/sdk/pkg/networkservice/chains/nsmgr"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/authorize"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/connect"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/externalips"
Expand All @@ -44,8 +43,7 @@ func NewServer(ctx context.Context, name string, tokenGenerator token.GeneratorF
swapip.NewServer(),
connect.NewServer(
ctx,
nsmgr.NewTranslationClient,
client.NewClientFactory(name,
client.NewProxyClientFactory(name,
nil,
tokenGenerator),
options...,
Expand Down
Loading

0 comments on commit 24a6093

Please sign in to comment.