[VOL-3622] Stop and restart gRPC server
Change-Id: I443e7ed75f79dd90782a1a4342c8e4d3a7294488
diff --git a/internal/bbsim/api/grpc_api_server.go b/internal/bbsim/api/grpc_api_server.go
index 7ed8f8d..84d3478 100644
--- a/internal/bbsim/api/grpc_api_server.go
+++ b/internal/bbsim/api/grpc_api_server.go
@@ -20,6 +20,7 @@
"context"
"fmt"
"strings"
+ "time"
"github.com/opencord/bbsim/api/bbsim"
"github.com/opencord/bbsim/internal/bbsim/alarmsim"
@@ -128,6 +129,58 @@
return res, nil
}
+func (s BBSimServer) StopgRPCServer(ctx context.Context, req *bbsim.Empty) (*bbsim.Response, error) {
+ res := &bbsim.Response{}
+ res.StatusCode = int32(codes.OK)
+ res.Message = fmt.Sprintf("Openolt gRPC server stopped")
+ o := devices.GetOLT()
+
+ logger.Infof("Received request to stop Openolt gRPC Server")
+
+ o.StopOltServer()
+
+ return res, nil
+}
+
+func (s BBSimServer) StartgRPCServer(ctx context.Context, req *bbsim.Empty) (*bbsim.Response, error) {
+ res := &bbsim.Response{}
+ res.StatusCode = int32(codes.OK)
+ res.Message = fmt.Sprintf("Openolt gRPC server started")
+ o := devices.GetOLT()
+
+ logger.Infof("Received request to start Openolt gRPC Server")
+
+ _, err := o.StartOltServer()
+ if err != nil {
+ return nil, err
+ }
+
+ return res, nil
+}
+
+func (s BBSimServer) RestartgRPCServer(ctx context.Context, req *bbsim.Timeout) (*bbsim.Response, error) {
+ o := devices.GetOLT()
+ logger.Infof("Received request to restart Openolt gRPC Server in %v seconds", req.Delay)
+ o.StopOltServer()
+
+ res := &bbsim.Response{}
+ res.StatusCode = int32(codes.OK)
+ res.Message = fmt.Sprintf("Openolt gRPC server stopped, restarting in %v", req.Delay)
+
+ go func() {
+ time.Sleep(time.Duration(req.Delay) * time.Second)
+ _, err := o.StartOltServer()
+ if err != nil {
+ logger.WithFields(log.Fields{
+ "err": err,
+ }).Error("Cannot restart Openolt gRPC server")
+ }
+ logger.Infof("Openolt gRPC Server restarted after %v seconds", req.Delay)
+ }()
+
+ return res, nil
+}
+
func (s BBSimServer) SetLogLevel(ctx context.Context, req *bbsim.LogLevel) (*bbsim.LogLevel, error) {
common.SetLogLevel(log.StandardLogger(), req.Level, req.Caller)
diff --git a/internal/bbsim/devices/olt.go b/internal/bbsim/devices/olt.go
index beeffce..008e3be 100644
--- a/internal/bbsim/devices/olt.go
+++ b/internal/bbsim/devices/olt.go
@@ -48,6 +48,7 @@
type OltDevice struct {
sync.Mutex
+ oltServer *grpc.Server
// BBSIM Internals
ID int
@@ -79,7 +80,6 @@
}
var olt OltDevice
-var oltServer *grpc.Server
func GetOLT() *OltDevice {
return &olt
@@ -224,10 +224,9 @@
func (o *OltDevice) InitOlt() {
- if oltServer == nil {
- oltServer, _ = o.newOltServer()
+ if o.oltServer == nil {
+ o.oltServer, _ = o.StartOltServer()
} else {
- // FIXME there should never be a server running if we are initializing the OLT
oltLogger.Fatal("OLT server already running.")
}
@@ -267,12 +266,8 @@
return err
}
- // TODO handle hard poweroff (i.e. no indications sent to Voltha) vs soft poweroff
time.Sleep(1 * time.Second) // we need to give the OLT the time to respond to all the pending gRPC request before stopping the server
- if err := o.StopOltServer(); err != nil {
- oltLogger.Errorf("Error in stopping OLT server")
- return err
- }
+ o.StopOltServer()
if softReboot {
for _, pon := range o.Pons {
@@ -341,18 +336,28 @@
return grpcServer, nil
}
+// StartOltServer will create the grpc server that VOLTHA uses
+// to communicate with the device
+func (o *OltDevice) StartOltServer() (*grpc.Server, error) {
+ oltServer, err := o.newOltServer()
+ if err != nil {
+ oltLogger.WithFields(log.Fields{
+ "err": err,
+ }).Error("Cannot OLT gRPC server")
+ return nil, err
+ }
+ return oltServer, nil
+}
+
// StopOltServer stops the OpenOLT grpc server
-func (o *OltDevice) StopOltServer() error {
- // TODO handle poweroff vs graceful shutdown
- if oltServer != nil {
+func (o *OltDevice) StopOltServer() {
+ if o.oltServer != nil {
oltLogger.WithFields(log.Fields{
"oltId": o.SerialNumber,
}).Warnf("Stopping OLT gRPC server")
- oltServer.Stop()
- oltServer = nil
+ o.oltServer.Stop()
+ o.oltServer = nil
}
-
- return nil
}
// Device Methods
diff --git a/internal/bbsimctl/commands/olt.go b/internal/bbsimctl/commands/olt.go
index 5f6747e..bed3733 100644
--- a/internal/bbsimctl/commands/olt.go
+++ b/internal/bbsimctl/commands/olt.go
@@ -49,6 +49,15 @@
type OltReboot struct{}
+type StopGrpcServer struct{}
+
+type StartGrpcServer struct{}
+type RestartGrpcServer struct {
+ Args struct {
+ Delay uint32
+ } `positional-args:"yes" required:"yes"`
+}
+
type OltFlows struct{}
type OltPoweronAllOnus struct{}
@@ -66,6 +75,9 @@
Flows OltFlows `command:"flows"`
PoweronAllOnus OltPoweronAllOnus `command:"poweronAllONUs"`
ShutdownAllOnus OltShutdownAllOnus `command:"shutdownAllONUs"`
+ StopServer StopGrpcServer `command:"stopServer"`
+ StartServer StartGrpcServer `command:"startServer"`
+ RestartServer RestartGrpcServer `command:"restartServer"`
}
func RegisterOltCommands(parser *flags.Parser) {
@@ -184,6 +196,63 @@
return nil
}
+func (o *StopGrpcServer) Execute(args []string) error {
+ client, conn := connect()
+ defer conn.Close()
+
+ ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
+ defer cancel()
+
+ res, err := client.StopgRPCServer(ctx, &pb.Empty{})
+
+ if err != nil {
+ log.Fatalf("Cannot stop Openolt server: %v", err)
+ return err
+ }
+
+ fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
+ return nil
+}
+
+func (o *StartGrpcServer) Execute(args []string) error {
+ client, conn := connect()
+ defer conn.Close()
+
+ ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
+ defer cancel()
+
+ res, err := client.StartgRPCServer(ctx, &pb.Empty{})
+
+ if err != nil {
+ log.Fatalf("Cannot start Openolt server: %v", err)
+ return err
+ }
+
+ fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
+ return nil
+}
+
+func (o *RestartGrpcServer) Execute(args []string) error {
+ req := &pb.Timeout{
+ Delay: o.Args.Delay,
+ }
+ client, conn := connect()
+ defer conn.Close()
+
+ ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
+ defer cancel()
+
+ res, err := client.RestartgRPCServer(ctx, req)
+
+ if err != nil {
+ log.Fatalf("Cannot restart Openolt server: %v", err)
+ return err
+ }
+
+ fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
+ return nil
+}
+
func (o *OltFlows) Execute(args []string) error {
client, conn := connect()
defer conn.Close()