-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add replaceNSEName chain element (#1328)
* Add replaceNSEName chain element Signed-off-by: Artem Glazychev <artem.glazychev@xored.com> * Create passthrough chain element Signed-off-by: Artem Glazychev <artem.glazychev@xored.com>
- Loading branch information
1 parent
dc978c4
commit 7349b1f
Showing
8 changed files
with
353 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Copyright (c) 2022 Cisco and/or its affiliates. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
// 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 passthrough combines chain elements used in passthrough cases | ||
package passthrough | ||
|
||
import ( | ||
"github.com/networkservicemesh/api/pkg/api/networkservice" | ||
|
||
"github.com/networkservicemesh/sdk/pkg/networkservice/common/passthrough/replacelabels" | ||
"github.com/networkservicemesh/sdk/pkg/networkservice/common/passthrough/replacensename" | ||
"github.com/networkservicemesh/sdk/pkg/networkservice/core/chain" | ||
) | ||
|
||
// NewClient returns a combination for passthrough cases | ||
func NewClient(labels map[string]string) networkservice.NetworkServiceClient { | ||
return chain.NewNetworkServiceClient( | ||
replacelabels.NewClient(labels), | ||
replacensename.NewClient(), | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
pkg/networkservice/common/passthrough/replacelabels/client_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Copyright (c) 2022 Cisco and/or its affiliates. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
// 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 replacelabels_test | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"go.uber.org/goleak" | ||
|
||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/networkservicemesh/api/pkg/api/networkservice" | ||
|
||
"github.com/networkservicemesh/sdk/pkg/networkservice/common/passthrough/replacelabels" | ||
"github.com/networkservicemesh/sdk/pkg/networkservice/core/chain" | ||
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/checks/checkclose" | ||
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/checks/checkrequest" | ||
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/metadata" | ||
) | ||
|
||
func TestClient(t *testing.T) { | ||
t.Cleanup(func() { goleak.VerifyNone(t) }) | ||
|
||
chainLabels := map[string]string{"1": "A", "2": "B"} | ||
client := chain.NewNetworkServiceClient( | ||
metadata.NewClient(), | ||
replacelabels.NewClient(chainLabels), | ||
checkrequest.NewClient(t, func(t *testing.T, r *networkservice.NetworkServiceRequest) { | ||
require.Equal(t, chainLabels, r.Connection.Labels) | ||
}), | ||
checkclose.NewClient(t, func(t *testing.T, c *networkservice.Connection) { | ||
require.Equal(t, chainLabels, c.Labels) | ||
}), | ||
) | ||
|
||
// Create the request with any labels | ||
req := &networkservice.NetworkServiceRequest{ | ||
Connection: &networkservice.Connection{Id: "nsc-1", Labels: map[string]string{"3": "C"}}, | ||
} | ||
conn, err := client.Request(context.Background(), req) | ||
require.NoError(t, err) | ||
require.Equal(t, map[string]string{"3": "C"}, conn.Labels) | ||
|
||
_, err = client.Close(context.Background(), conn) | ||
require.NoError(t, err) | ||
} |
56 changes: 56 additions & 0 deletions
56
pkg/networkservice/common/passthrough/replacensename/client.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Copyright (c) 2022 Cisco and/or its affiliates. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
// 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 replacensename replaces NetworkServiceEndpointName if it was discovered before | ||
package replacensename | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/golang/protobuf/ptypes/empty" | ||
"google.golang.org/grpc" | ||
|
||
"github.com/networkservicemesh/api/pkg/api/networkservice" | ||
|
||
"github.com/networkservicemesh/sdk/pkg/networkservice/core/next" | ||
) | ||
|
||
type replaceNSEClient struct{} | ||
|
||
// NewClient creates new instance of NetworkServiceClient chain element, which replaces NetworkServiceEndpointName in the connection | ||
func NewClient() networkservice.NetworkServiceClient { | ||
return &replaceNSEClient{} | ||
} | ||
|
||
func (s *replaceNSEClient) Request(ctx context.Context, request *networkservice.NetworkServiceRequest, opts ...grpc.CallOption) (conn *networkservice.Connection, err error) { | ||
prevNseName := request.Connection.NetworkServiceEndpointName | ||
request.Connection.NetworkServiceEndpointName, _ = load(ctx) | ||
|
||
conn, err = next.Client(ctx).Request(ctx, request, opts...) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
store(ctx, conn.NetworkServiceEndpointName) | ||
conn.NetworkServiceEndpointName = prevNseName | ||
|
||
return conn, nil | ||
} | ||
|
||
func (s *replaceNSEClient) Close(ctx context.Context, conn *networkservice.Connection, opts ...grpc.CallOption) (*empty.Empty, error) { | ||
conn.NetworkServiceEndpointName, _ = loadAndDelete(ctx) | ||
return next.Client(ctx).Close(ctx, conn, opts...) | ||
} |
83 changes: 83 additions & 0 deletions
83
pkg/networkservice/common/passthrough/replacensename/client_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
// Copyright (c) 2022 Cisco and/or its affiliates. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
// 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 replacensename_test | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"go.uber.org/goleak" | ||
"google.golang.org/grpc" | ||
|
||
"github.com/golang/protobuf/ptypes/empty" | ||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/networkservicemesh/api/pkg/api/networkservice" | ||
|
||
"github.com/networkservicemesh/sdk/pkg/networkservice/common/passthrough/replacensename" | ||
"github.com/networkservicemesh/sdk/pkg/networkservice/core/chain" | ||
"github.com/networkservicemesh/sdk/pkg/networkservice/core/next" | ||
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/checks/checkclose" | ||
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/checks/checkrequest" | ||
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/metadata" | ||
) | ||
|
||
func TestClient(t *testing.T) { | ||
t.Cleanup(func() { goleak.VerifyNone(t) }) | ||
|
||
client := chain.NewNetworkServiceClient( | ||
metadata.NewClient(), | ||
replacensename.NewClient(), | ||
&setNSENameClient{name: "nse-name1"}, | ||
checkrequest.NewClient(t, func(t *testing.T, r *networkservice.NetworkServiceRequest) { | ||
require.Equal(t, "nse-name1", r.Connection.NetworkServiceEndpointName) | ||
}), | ||
checkclose.NewClient(t, func(t *testing.T, c *networkservice.Connection) { | ||
require.Equal(t, "nse-name1", c.NetworkServiceEndpointName) | ||
}), | ||
) | ||
req := &networkservice.NetworkServiceRequest{ | ||
Connection: &networkservice.Connection{Id: "nsc-1"}, | ||
} | ||
conn, err := client.Request(context.Background(), req) | ||
require.NoError(t, err) | ||
|
||
// Change NetworkServiceEndpointName to another name | ||
conn.NetworkServiceEndpointName = "nse-name2" | ||
conn, err = client.Request(context.Background(), req) | ||
require.Equal(t, "nse-name2", conn.NetworkServiceEndpointName) | ||
require.NoError(t, err) | ||
|
||
_, err = client.Close(context.Background(), conn) | ||
require.NoError(t, err) | ||
} | ||
|
||
// setNSENameClient sets NetworkServiceEndpointName only if it is empty | ||
type setNSENameClient struct { | ||
name string | ||
} | ||
|
||
func (s *setNSENameClient) Request(ctx context.Context, request *networkservice.NetworkServiceRequest, opts ...grpc.CallOption) (*networkservice.Connection, error) { | ||
if request.GetConnection().NetworkServiceEndpointName == "" { | ||
request.GetConnection().NetworkServiceEndpointName = s.name | ||
} | ||
return next.Client(ctx).Request(ctx, request, opts...) | ||
} | ||
|
||
func (s *setNSENameClient) Close(ctx context.Context, conn *networkservice.Connection, opts ...grpc.CallOption) (*empty.Empty, error) { | ||
return next.Client(ctx).Close(ctx, conn, opts...) | ||
} |
50 changes: 50 additions & 0 deletions
50
pkg/networkservice/common/passthrough/replacensename/metadata.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Copyright (c) 2022 Cisco and/or its affiliates. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
// 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 replacensename | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/metadata" | ||
) | ||
|
||
type keyType struct{} | ||
|
||
// store - stores the next network service endpoint name | ||
func store(ctx context.Context, nseName string) { | ||
metadata.Map(ctx, true).Store(keyType{}, nseName) | ||
} | ||
|
||
// load - returns the next network service endpoint name | ||
func load(ctx context.Context) (value string, ok bool) { | ||
rawValue, ok := metadata.Map(ctx, true).Load(keyType{}) | ||
if !ok { | ||
return | ||
} | ||
value, ok = rawValue.(string) | ||
return value, ok | ||
} | ||
|
||
// loadAndDelete - returns the next network service endpoint name and deletes it from the metadata | ||
func loadAndDelete(ctx context.Context) (value string, ok bool) { | ||
rawValue, ok := metadata.Map(ctx, true).LoadAndDelete(keyType{}) | ||
if !ok { | ||
return | ||
} | ||
value, ok = rawValue.(string) | ||
return value, ok | ||
} |
Oops, something went wrong.