Skip to content

Commit

Permalink
feat: modify component configuration during runtime (#762)
Browse files Browse the repository at this point in the history
  • Loading branch information
seeflood authored Aug 30, 2022
1 parent 28a10d8 commit 2021157
Show file tree
Hide file tree
Showing 26 changed files with 1,459 additions and 29 deletions.
3 changes: 3 additions & 0 deletions cmd/layotto/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
"strconv"
"time"

"mosn.io/layotto/pkg/grpc/lifecycle"

"mosn.io/layotto/components/oss"

aws_oss "mosn.io/layotto/components/oss/aws"
Expand Down Expand Up @@ -258,6 +260,7 @@ func NewRuntimeGrpcServer(data json.RawMessage, opts ...grpc.ServerOption) (mgrp
// register your gRPC API here
runtime.WithGrpcAPI(
default_api.NewGrpcAPI,
lifecycle.NewLifecycleAPI,
s3ext.NewS3Server,
),
// Hello
Expand Down
5 changes: 5 additions & 0 deletions cmd/layotto_multiple_api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
"strconv"
"time"

"mosn.io/layotto/pkg/grpc/lifecycle"

"mosn.io/layotto/components/oss"

aws_oss "mosn.io/layotto/components/oss/aws"
Expand Down Expand Up @@ -262,8 +264,11 @@ func NewRuntimeGrpcServer(data json.RawMessage, opts ...grpc.ServerOption) (mgrp
runtime.WithGrpcAPI(
// default GrpcAPI
default_api.NewGrpcAPI,
lifecycle.NewLifecycleAPI,

// a demo to show how to register your own gRPC API
helloworld_api.NewHelloWorldAPI,

// support Dapr API
// Currently it only support Dapr's InvokeService,secret API,state API and InvokeBinding API.
// Note: this feature is still in Alpha state and we don't recommend that you use it in your production environment.
Expand Down
5 changes: 5 additions & 0 deletions cmd/layotto_without_xds/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import (
"strconv"
"time"

s3ext "mosn.io/layotto/pkg/grpc/extension/s3"
"mosn.io/layotto/pkg/grpc/lifecycle"

"mosn.io/layotto/components/oss"

aws_oss "mosn.io/layotto/components/oss/aws"
Expand Down Expand Up @@ -241,6 +244,8 @@ func NewRuntimeGrpcServer(data json.RawMessage, opts ...grpc.ServerOption) (mgrp
// register your gRPC API here
runtime.WithGrpcAPI(
default_api.NewGrpcAPI,
lifecycle.NewLifecycleAPI,
s3ext.NewS3Server,
),
// Hello
runtime.WithHelloFactory(
Expand Down
16 changes: 13 additions & 3 deletions components/hello/helloworld/helloworld.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,22 @@ package helloworld

import (
"context"
"sync/atomic"

"mosn.io/layotto/components/hello"
)

type HelloWorld struct {
Say string
Say atomic.Value
}

func (hw *HelloWorld) ApplyConfig(ctx context.Context, metadata map[string]string) (err error) {
greetings, ok := metadata["hello"]
if !ok {
return nil
}
hw.Say.Store(greetings)
return nil
}

var _ hello.HelloService = &HelloWorld{}
Expand All @@ -33,12 +43,12 @@ func NewHelloWorld() hello.HelloService {
}

func (hw *HelloWorld) Init(config *hello.HelloConfig) error {
hw.Say = config.HelloString
hw.Say.Store(config.HelloString)
return nil
}

func (hw *HelloWorld) Hello(ctx context.Context, req *hello.HelloRequest) (*hello.HelloReponse, error) {
greetings := hw.Say
greetings, _ := hw.Say.Load().(string)
if req.Name != "" {
greetings = greetings + ", " + req.Name
}
Expand Down
22 changes: 22 additions & 0 deletions components/hello/helloworld/helloworld_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"context"
"testing"

"mosn.io/layotto/components/pkg/common"

"mosn.io/layotto/components/hello"
)

Expand All @@ -37,4 +39,24 @@ func TestHelloWorld(t *testing.T) {
if resp.HelloString != "Hi, Layotto" {
t.Fatalf("hello output failed")
}

// ApplyConfig, but nil
dc := hs.(common.DynamicComponent)
err := dc.ApplyConfig(context.Background(), nil)
if err != nil {
t.Fatalf("hello ApplyConfig failed")
}
if resp.HelloString != "Hi, Layotto" {
t.Fatalf("hello output failed")
}

// Apply new config
err = dc.ApplyConfig(context.Background(), map[string]string{"hello": "Bye"})
if err != nil {
t.Fatalf("hello ApplyConfig failed")
}
resp, _ = hs.Hello(context.Background(), req)
if resp.HelloString != "Bye, Layotto" {
t.Fatalf("hello output failed")
}
}
20 changes: 20 additions & 0 deletions components/pkg/common/dynamic_component.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2021 Layotto 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 common

import "context"

type DynamicComponent interface {
ApplyConfig(ctx context.Context, metadata map[string]string) (err error)
}
60 changes: 60 additions & 0 deletions demo/lifecycle/common/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package main

import (
"context"
"fmt"

"google.golang.org/grpc"

runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1"
)

func main() {
conn, err := grpc.Dial("127.0.0.1:34904", grpc.WithInsecure())
if err != nil {
panic(err)
}
// 1. invoke sayHello API
client := runtimev1pb.NewRuntimeClient(conn)
hello, err := client.SayHello(context.Background(), &runtimev1pb.SayHelloRequest{
ServiceName: "quick_start_demo",
Name: "eva",
})
if err != nil {
panic(err)
}
// validate the response value
if hello.Hello != "greeting, eva" {
panic(fmt.Errorf("Assertion failed! Result is %v", hello.Hello))
}
fmt.Println(hello.Hello)

// 2. invoke lifecycle API to modify the `sayHello` component configuration
c := runtimev1pb.NewLifecycleClient(conn)
metaData := make(map[string]string)
// change the configuration from "greeting" to "goodbye"
metaData["hello"] = "goodbye"
req := &runtimev1pb.DynamicConfiguration{ComponentConfig: &runtimev1pb.ComponentConfig{
Kind: "hellos",
Name: "quick_start_demo",
Metadata: metaData,
}}
_, err = c.ApplyConfiguration(context.Background(), req)
if err != nil {
panic(err)
}
// 3. invoke sayHello API again
client = runtimev1pb.NewRuntimeClient(conn)
hello, err = client.SayHello(context.Background(), &runtimev1pb.SayHelloRequest{
ServiceName: "quick_start_demo",
Name: "eva",
})
if err != nil {
panic(err)
}
// validate the response value. It should be different this time.
if hello.Hello != "goodbye, eva" {
panic(fmt.Errorf("Assertion failed! Result is %v", hello.Hello))
}
fmt.Println(hello.Hello)
}
1 change: 1 addition & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- [Use OSS API](en/start/oss/start.md)
- [API plugin: register your own API](en/start/api_plugin/helloworld.md)
<!--quickstart_generator-->
- [Use lifecycle API](en/start/lifecycle/start)
- As the data plane of istio
- [Integrate with istio 1.10.6](en/start/istio/)
- [Integrate with istio 1.5.x](en/start/istio/start.md)
Expand Down
Loading

0 comments on commit 2021157

Please sign in to comment.