blob: 943c021066b4f712d6e1ee2872352d19675e76a4 [file] [log] [blame]
Matteo Scandolo11006992019-08-28 11:29:46 -07001/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Matteo Scandolo4747d292019-08-05 11:50:18 -070017package main
18
19import (
20 "flag"
Matteo Scandolo11006992019-08-28 11:29:46 -070021 "github.com/opencord/bbsim/api/bbsim"
22 "github.com/opencord/bbsim/internal/bbsim/devices"
Matteo Scandolo4747d292019-08-05 11:50:18 -070023 log "github.com/sirupsen/logrus"
Matteo Scandolo84f7d482019-08-08 19:00:47 -070024 "google.golang.org/grpc"
25 "google.golang.org/grpc/reflection"
26 "net"
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070027 "os"
28 "runtime/pprof"
Matteo Scandolo4747d292019-08-05 11:50:18 -070029 "sync"
30)
31
32func getOpts() *CliOptions {
33
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070034 olt_id := flag.Int("olt_id", 0, "Number of OLT devices to be emulated (default is 1)")
35 nni := flag.Int("nni", 1, "Number of NNI ports per OLT device to be emulated (default is 1)")
36 pon := flag.Int("pon", 1, "Number of PON ports per OLT device to be emulated (default is 1)")
37 onu := flag.Int("onu", 1, "Number of ONU devices per PON port to be emulated (default is 1)")
38 profileCpu := flag.String("cpuprofile", "", "write cpu profile to file")
39
Matteo Scandolo4747d292019-08-05 11:50:18 -070040 flag.Parse()
41
42 o := new(CliOptions)
43
44 o.OltID = int(*olt_id)
45 o.NumNniPerOlt = int(*nni)
46 o.NumPonPerOlt = int(*pon)
47 o.NumOnuPerPon = int(*onu)
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070048 o.profileCpu = profileCpu
Matteo Scandolo4747d292019-08-05 11:50:18 -070049
50 return o
51}
52
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070053func startApiServer(channel chan bool, group *sync.WaitGroup) {
Matteo Scandolo84f7d482019-08-08 19:00:47 -070054 // TODO make configurable
55 address := "0.0.0.0:50070"
56 log.Debugf("APIServer Listening on: %v", address)
57 lis, err := net.Listen("tcp", address)
58 if err != nil {
59 log.Fatalf("APIServer failed to listen: %v", err)
60 }
61 grpcServer := grpc.NewServer()
62 bbsim.RegisterBBSimServer(grpcServer, BBSimServer{})
63
64 reflection.Register(grpcServer)
65
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070066 wg := sync.WaitGroup{}
67 wg.Add(1)
68
Matteo Scandolo84f7d482019-08-08 19:00:47 -070069 go grpcServer.Serve(lis)
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070070
71 for {
72 _, ok := <- channel
73 if !ok {
74 // if the olt channel is closed, stop the gRPC server
75 log.Warnf("Stopping API gRPC server")
76 grpcServer.Stop()
77 wg.Done()
78 break
79 }
80 }
81
82 wg.Wait()
83 group.Done()
84 return
Matteo Scandolo84f7d482019-08-08 19:00:47 -070085}
86
Matteo Scandolo4747d292019-08-05 11:50:18 -070087func init() {
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070088 // TODO make configurable both via CLI and via ENV (for the tests)
Matteo Scandolo3bc73742019-08-20 14:04:04 -070089 log.SetLevel(log.DebugLevel)
90 //log.SetLevel(log.TraceLevel)
Matteo Scandolo4747d292019-08-05 11:50:18 -070091 //log.SetReportCaller(true)
92}
93
94func main() {
Matteo Scandolo4747d292019-08-05 11:50:18 -070095 options := getOpts()
96
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070097 if *options.profileCpu != "" {
98 // start profiling
99 log.Infof("Creating profile file at: %s", *options.profileCpu)
100 f, err := os.Create(*options.profileCpu)
101 if err != nil {
102 log.Fatal(err)
103 }
104 pprof.StartCPUProfile(f)
105 }
106
Matteo Scandolo4747d292019-08-05 11:50:18 -0700107 log.WithFields(log.Fields{
108 "OltID": options.OltID,
109 "NumNniPerOlt": options.NumNniPerOlt,
110 "NumPonPerOlt": options.NumPonPerOlt,
111 "NumOnuPerPon": options.NumOnuPerPon,
112 }).Info("BroadBand Simulator is on")
113
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700114 // control channels, they are only closed when the goroutine needs to be terminated
115 oltDoneChannel := make(chan bool)
116 apiDoneChannel := make(chan bool)
117
Matteo Scandolo4747d292019-08-05 11:50:18 -0700118 wg := sync.WaitGroup{}
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700119 wg.Add(2)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700120
121
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700122 go devices.CreateOLT(options.OltID, options.NumNniPerOlt, options.NumPonPerOlt, options.NumOnuPerPon, &oltDoneChannel, &apiDoneChannel, &wg)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700123 log.Debugf("Created OLT with id: %d", options.OltID)
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700124 go startApiServer(apiDoneChannel, &wg)
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700125 log.Debugf("Started APIService")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700126
127 wg.Wait()
128
129 defer func() {
130 log.Info("BroadBand Simulator is off")
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700131 if *options.profileCpu != "" {
132 log.Info("Stopping profiler")
133 pprof.StopCPUProfile()
134 }
Matteo Scandolo4747d292019-08-05 11:50:18 -0700135 }()
136}