Merge "Changing output format for the BBSim scale pipeline plot"
diff --git a/Makefile b/Makefile
index 036735f..ee2b460 100644
--- a/Makefile
+++ b/Makefile
@@ -14,19 +14,44 @@
VERSION ?= $(shell cat ./VERSION)
DIFF ?= $(git diff --shortstat 2> /dev/null | tail -n1)
-GIT_STATUS ?= $(shell [[ $DIFF != "" ]] && echo "Dirty" || echo "Clean")
+GIT_STATUS ?= $(shell [ -z "$DIFF" ] && echo "Dirty" || echo "Clean")
## Docker related
DOCKER_TAG ?= ${VERSION}
DOCKER_REPOSITORY ?= ""
DOCKER_REGISTRY ?= ""
DOCKER_RUN_ARGS ?= ""
+DOCKER_PORTS ?= -p 50070:50070 -p 50060:50060 -p 50071:50071 -p 50072:50072 -p 50073:50073
+
+## protobuf related
+VOLTHA_PROTOS ?= $(shell GO111MODULE=on go list -f '{{ .Dir }}' -m github.com/opencord/voltha-protos)
+GOOGLEAPI ?= $(shell GO111MODULE=on go list -f '{{ .Dir }}' -m github.com/grpc-ecosystem/grpc-gateway)
+TOOLS_DIR := tools
+TOOLS_BIN := $(TOOLS_DIR)/bin/
+
+export PATH=$(shell echo $$PATH):$(PWD)/$(TOOLS_BIN)
# Public targets
-
all: help
-protos: api/bbsim/bbsim.pb.go # @HELP Build proto files
+# go installed tools.go
+GO_TOOLS := github.com/golang/protobuf/protoc-gen-go \
+ github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway \
+ github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
+
+# tools
+GO_TOOLS_BIN := $(addprefix $(TOOLS_BIN), $(notdir $(GO_TOOLS)))
+GO_TOOLS_VENDOR := $(addprefix vendor/, $(GO_TOOLS))
+
+TEST_PACKAGES := github.com/opencord/bbsim/cmd/... \
+ github.com/opencord/bbsim/internal/...
+
+setup_tools: $(GO_TOOLS_BIN)
+
+$(GO_TOOLS_BIN): $(GO_TOOLS_VENDOR)
+ GO111MODULE=on GOBIN="$(PWD)/$(TOOLS_BIN)" go install -mod=vendor $(GO_TOOLS)
+
+protos: dep setup_tools api/bbsim/bbsim.pb.go api/bbsim/bbsim.pb.gw.go api/legacy/bbsim.pb.go api/legacy/bbsim.pb.gw.go # @HELP Build proto files
dep: # @HELP Download the dependencies to the vendor folder
GO111MODULE=on go mod vendor
@@ -39,7 +64,7 @@
docker run --rm -v $(shell pwd):/bbsim ${DOCKER_REGISTRY}${DOCKER_REPOSITORY}bbsim-builder:${DOCKER_TAG} /bin/sh -c "cd /bbsim; make _build"
test: dep protos fmt # @HELP Execute unit tests
- GO111MODULE=on go test -v -mod vendor ./... -covermode count -coverprofile ./tests/results/go-test-coverage.out 2>&1 | tee ./tests/results/go-test-results.out
+ GO111MODULE=on go test -v -mod vendor $(TEST_PACKAGES) -covermode count -coverprofile ./tests/results/go-test-coverage.out 2>&1 | tee ./tests/results/go-test-results.out
go-junit-report < ./tests/results/go-test-results.out > ./tests/results/go-test-results.xml
gocover-cobertura < ./tests/results/go-test-coverage.out > ./tests/results/go-test-coverage.xml
@@ -53,15 +78,15 @@
docker push ${DOCKER_REGISTRY}${DOCKER_REPOSITORY}bbsim:${DOCKER_TAG}
docker-run: # @HELP Runs the container locally (available options: DOCKER_RUN_ARGS="-pon 2 -onu 2" make docker-run)
- docker run -d -p 50070:50070 -p 50060:50060 --privileged --rm --name bbsim ${DOCKER_REGISTRY}${DOCKER_REPOSITORY}bbsim:${DOCKER_TAG} /app/bbsim ${DOCKER_RUN_ARGS}
+ docker run -d ${DOCKER_PORTS} --privileged --rm --name bbsim ${DOCKER_REGISTRY}${DOCKER_REPOSITORY}bbsim:${DOCKER_TAG} /app/bbsim ${DOCKER_RUN_ARGS}
docker-run-dev: # @HELP Runs the container locally (intended for development purposes, not in detached mode)
- docker run -p 50070:50070 -p 50060:50060 --privileged --rm --name bbsim ${DOCKER_REGISTRY}${DOCKER_REPOSITORY}bbsim:${DOCKER_TAG} /app/bbsim ${DOCKER_RUN_ARGS}
+ docker run ${DOCKER_PORTS} --privileged --rm --name bbsim ${DOCKER_REGISTRY}${DOCKER_REPOSITORY}bbsim:${DOCKER_TAG} /app/bbsim ${DOCKER_RUN_ARGS}
.PHONY: docs
-docs: # @HELP Generate docs and opens them in the browser
- pushd docs; make doc_venv; make html; popd
- open docs/build/html/index.html
+docs: swagger # @HELP Generate docs and opens them in the browser
+ cd docs; make doc_venv; make html; cd -
+ @echo -e "\nBBSim documentation generated in file://${PWD}/docs/build/html/index.html"
# Release related items
# Generates binaries in $RELEASE_DIR with name $RELEASE_NAME-$RELEASE_OS_ARCH
@@ -79,7 +104,6 @@
export GOARCH=$(rel_arch) ;\
GO111MODULE=on go build -i -v -mod vendor \
-ldflags "-w -X main.buildTime=$(shell date +”%Y/%m/%d-%H:%M:%S”) \
- -X main.commitHash=$(shell git log --pretty=format:%H -n 1) \
-X main.gitStatus=${GIT_STATUS} \
-X main.version=${VERSION}" \
-o "$@" ./cmd/bbr
@@ -89,13 +113,13 @@
export GOARCH=$(rel_arch) ;\
GO111MODULE=on go build -i -v -mod vendor \
-ldflags "-w -X main.buildTime=$(shell date +”%Y/%m/%d-%H:%M:%S”) \
- -X main.commitHash=$(shell git log --pretty=format:%H -n 1) \
-X main.gitStatus=${GIT_STATUS} \
-X main.version=${VERSION}" \
-o "$@" ./cmd/bbsim
.PHONY: release $(RELEASE_BBR_BINS) $(RELEASE_BBSIM_BINS)
release: dep protos $(RELEASE_BBR_BINS) $(RELEASE_BBSIM_BINS) # @HELP Creates release ready bynaries for BBSimctl and BBR artifacts
+swagger: docs/swagger/bbsim/bbsim.swagger.json docs/swagger/leagacy/bbsim.swagger.json # @HELP Generate swagger documentation for BBSim API
help: # @HELP Print the command options
@echo
@@ -139,16 +163,37 @@
./cmd/bbsimctl
api/openolt/openolt.pb.go: api/openolt/openolt.proto
- @protoc -I . \
- -I${GOPATH}/src \
- -I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
+ @protoc -I. \
+ -I${GOOGLEAPI}/third_party/googleapis \
--go_out=plugins=grpc:./ \
$<
-api/bbsim/bbsim.pb.go: api/bbsim/bbsim.proto
- @protoc -I . \
- -I${GOPATH}/src \
- -I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
+api/bbsim/bbsim.pb.go api/bbsim/bbsim.pb.gw.go: api/bbsim/bbsim.proto api/bbsim/bbsim.yaml
+ @protoc -I. \
+ -I${GOOGLEAPI}/third_party/googleapis \
--go_out=plugins=grpc:./ \
+ --grpc-gateway_out=logtostderr=true,grpc_api_configuration=api/bbsim/bbsim.yaml,allow_delete_body=true:./ \
$<
+api/legacy/bbsim.pb.go api/legacy/bbsim.pb.gw.go: api/legacy/bbsim.proto
+ @protoc -I. \
+ -I${GOOGLEAPI}/third_party/googleapis/ \
+ -I${GOOGLEAPI}/ \
+ -I${VOLTHA_PROTOS}/protos/ \
+ --go_out=plugins=grpc:./ \
+ --grpc-gateway_out=logtostderr=true,allow_delete_body=true:./ \
+ $<
+
+docs/swagger/bbsim/bbsim.swagger.json: api/bbsim/bbsim.yaml
+ @protoc -I ./api \
+ -I${GOOGLEAPI}/ \
+ -I${VOLTHA_PROTOS}/protos/ \
+ --swagger_out=logtostderr=true,allow_delete_body=true,grpc_api_configuration=$<:docs/swagger/ \
+ api/bbsim/bbsim.proto
+
+docs/swagger/leagacy/bbsim.swagger.json: api/legacy/bbsim.proto
+ @protoc -I ./api \
+ -I${GOOGLEAPI}/ \
+ -I${VOLTHA_PROTOS}/protos/ \
+ --swagger_out=logtostderr=true,allow_delete_body=true:docs/swagger/ \
+ $<
\ No newline at end of file
diff --git a/api/bbsim/bbsim.yaml b/api/bbsim/bbsim.yaml
new file mode 100644
index 0000000..484ad3c
--- /dev/null
+++ b/api/bbsim/bbsim.yaml
@@ -0,0 +1,30 @@
+# Copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+type: google.api.Service
+config_version: 3
+
+http:
+ rules:
+ - selector: bbsim.BBSim.Version
+ get: "/v1/version"
+ - selector: bbsim.BBSim.GetOlt
+ get: "/v1/olt"
+ additional_bindings:
+ - get: "/v1/olt/status"
+ - selector: bbsim.BBSim.GetONUs
+ get: "/v1/olt/onus"
+ - selector: bbsim.BBSim.GetONU
+ get: "/v1/olt/onus/{SerialNumber}"
+
diff --git a/api/legacy/bbsim.proto b/api/legacy/bbsim.proto
new file mode 100644
index 0000000..fee9bec
--- /dev/null
+++ b/api/legacy/bbsim.proto
@@ -0,0 +1,232 @@
+// Copyright (c) 2018 Open Networking Foundation
+//
+// 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.
+
+syntax = "proto3";
+package legacy;
+
+import "google/api/annotations.proto";
+import "protoc-gen-swagger/options/annotations.proto";
+import "voltha_protos/openolt.proto";
+import "voltha_protos/tech_profile.proto";
+
+option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
+ info: {
+ title: "BBSim API";
+ version: "1.0";
+ contact: {
+ url: "http://opencord.org";
+ };
+ };
+ schemes: HTTP;
+ consumes: "application/json";
+ produces: "application/json";
+ responses: {
+ key: "404";
+ value: {
+ description: "Returned when the resource does not exist.";
+ schema: {
+ json_schema: {
+ type: STRING;
+ }
+ }
+ }
+ }
+};
+
+// OLT information
+message OLTInfo {
+ option deprecated = true;
+ int64 olt_id = 1;
+ string olt_serial = 2;
+ string olt_ip = 3;
+ string olt_state = 4;
+ string olt_vendor = 5;
+}
+
+// ONU information
+message ONUInfo {
+ uint32 onu_id = 1;
+ uint32 pon_port_id = 2;
+ // ONU serial number
+ string onu_serial = 3;
+ // ONU oper state
+ string oper_state = 4;
+ // ONU internal state
+ string onu_state = 5;
+ repeated uint32 gemports = 6;
+ Tconts tconts = 7;
+}
+
+// Bulk ONU operations
+message ONUs {
+ repeated ONUInfo onus = 1;
+}
+
+message ONURequest {
+ ONUInfo onu = 1;
+ ONUs onus_batch = 2;
+}
+
+// Port information
+message PortInfo {
+ string port_type = 1;
+ uint32 port_id = 2;
+ uint32 pon_port_max_onus = 3;
+ uint32 pon_port_active_onus = 4;
+ string port_state = 5;
+ string alarm_state = 6;
+}
+
+// Bulk port information
+message Ports {
+ repeated PortInfo ports = 1;
+}
+
+// BBSim status
+message OLTStatusResponse {
+ OLTInfo olt = 1;
+ repeated PortInfo ports = 2;
+}
+
+// BBSim response message
+message BBSimResponse {
+ string status_msg = 1;
+}
+
+// ONU alarm request
+message ONUAlarmRequest {
+ // ONU serial number
+ string onu_serial = 1;
+ // Alarm types are:
+ // "signaldegrade"
+ // "lossofomcichannel"
+ // "lossofploam"
+ string alarm_type = 2;
+ // "on"/"off" indicates raised or cleared alarm
+ string status = 3; }
+
+// OLT alarm request
+message OLTAlarmRequest {
+ uint32 port_id = 1;
+ string port_type = 2;
+ string status = 3;
+}
+
+// Device action
+message DeviceAction {
+ string device_type = 1; // ONU or OLT
+ string serial_number = 2; // Device serial number
+ string action = 3; // soft or hard reboot
+}
+
+message Tconts {
+ fixed32 uni_id = 4;
+ fixed32 port_no = 5;
+ repeated tech_profile.TrafficScheduler tconts = 3;
+}
+
+message Flows {
+ repeated openolt.Flow flows = 1;
+}
+
+message Empty {}
+
+service BBSimService {
+
+ // Get current status of OLT
+ rpc OLTStatus(Empty) returns (OLTStatusResponse) {
+ option deprecated = true;
+ option (google.api.http) = {
+ get : "/v0/olt"
+ additional_bindings {get : "/v0/olt/status"}
+ };
+ }
+
+ // Get status of a PON/NNI port
+ rpc PortStatus(PortInfo) returns (Ports) {
+ option deprecated = true;
+ option (google.api.http) = {
+ get : "/v0/olt/ports/{port_type}/{port_id}/status"
+ };
+ }
+
+ // Get status of all or specific ONUs
+ rpc ONUStatus(ONURequest) returns (ONUs) {
+ option deprecated = true;
+ option (google.api.http) = {
+ get : "/v0/olt/onus"
+ additional_bindings { get : "/v0/olt/onus/{onu.onu_serial}" }
+ additional_bindings { get : "/v0/olt/ports/{onu.pon_port_id}/onus/{onu.onu_id}" }
+ additional_bindings { get : "/v0/olt/ports/{onu.pon_port_id}/onus" }
+ };
+ }
+
+ // Single/bulk activate ONU(s) for specific PON port(s)
+ rpc ONUActivate(ONURequest) returns (BBSimResponse) {
+ option deprecated = true;
+ option (google.api.http) = {
+ post : "/v0/olt/onus"
+ body: "onus_batch"
+ additional_bindings { post : "/v0/olt/ports/{onu.pon_port_id}/onus" }
+ additional_bindings { post : "/v0/olt/ports/{onu.pon_port_id}/onus/{onu.onu_serial}" }
+ };
+ }
+
+ // Deactivate ONU(s) for specific PON port(s) specified by
+ // a given onu_serial, onu_id, or pon_port_id
+ rpc ONUDeactivate(ONURequest) returns (BBSimResponse) {
+ option deprecated = true;
+ option (google.api.http) = {
+ delete : "/v0/olt/onus"
+ body: "onus_batch"
+ additional_bindings { delete: "/v0/olt/onus/{onu.onu_serial}" }
+ additional_bindings { delete: "/v0/olt/ports/{onu.pon_port_id}/onus" }
+ additional_bindings { delete: "/v0/olt/ports/{onu.pon_port_id}/onus/{onu.onu_id}" }
+ };
+ }
+
+ // Generate ONU related alarms
+ rpc GenerateONUAlarm(ONUAlarmRequest) returns (BBSimResponse) {
+ option deprecated = true;
+ option (google.api.http) = {
+ post : "/v0/olt/onus/{onu_serial}/alarms/{alarm_type}/{status}"
+ };
+ }
+
+ // Generate OLT related alarms
+ rpc GenerateOLTAlarm(OLTAlarmRequest) returns (BBSimResponse) {
+ option deprecated = true;
+ option (google.api.http) = {
+ post : "/v0/olt/ports/{port_type}/{port_id}/alarms/los/{status}"
+ };
+ }
+
+ // Perform actions on OLT/ONU devices (e.g. reboot)
+ rpc PerformDeviceAction(DeviceAction) returns (BBSimResponse) {
+ option deprecated = true;
+ option (google.api.http) = {
+ patch: "/v0/{device_type}/action/{action}"
+ additional_bindings { patch : "/v0/olt/{device_type}/{serial_number}/action/{action}"}
+ };
+ }
+
+ // Get flows
+ rpc GetFlows(ONUInfo) returns(Flows) {
+ option deprecated = true;
+ option (google.api.http) = {
+ get: "/v0/olt/flows"
+ additional_bindings {get: "/v0/olt/onu/{onu_serial}/flows"}
+ };
+ }
+}
diff --git a/build/package/Dockerfile b/build/package/Dockerfile
index 73f3cca..86e15bb 100644
--- a/build/package/Dockerfile
+++ b/build/package/Dockerfile
@@ -29,24 +29,21 @@
&& mv /tmp/protoc3/bin/* /usr/local/bin/ \
&& mv /tmp/protoc3/include/* /usr/local/include/ \
&& go get -v github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway \
+ && go get -v github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger \
&& go get -v github.com/golang/protobuf/protoc-gen-go
WORKDIR /go/src/github.com/opencord/bbsim
ENV GO111MODULE=on
ENV GOPROXY=https://proxy.golang.org
-# get dependencies
-COPY go.mod go.sum ./
-COPY vendor ./vendor
-
# build the protos
COPY Makefile ./
COPY api ./api
-RUN make protos
# copy and build
COPY . ./
-RUN go mod vendor -v # we can't vendor dependencies unless the code is there
+RUN make dep # we cannot vendor dependencies unless the code is there
+RUN make protos
RUN make build-bbsim
RUN make build-bbsimctl
@@ -73,4 +70,4 @@
RUN chmod a+x /app/bbsim
RUN chmod a+x /usr/bin/bbsimctl
RUN bbsimctl completion bash >> $HOME/.bashrc
-CMD [ '/app/bbsim' ]
\ No newline at end of file
+CMD [ '/app/bbsim' ]
diff --git a/cmd/bbsim/bbsim.go b/cmd/bbsim/bbsim.go
index 53b6ae0..d8cfcf0 100644
--- a/cmd/bbsim/bbsim.go
+++ b/cmd/bbsim/bbsim.go
@@ -17,23 +17,30 @@
package main
import (
+ "context"
+ "net"
+ "net/http"
+ "os"
+ "os/signal"
+ "runtime/pprof"
+ "sync"
+ "syscall"
+
+ "github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/opencord/bbsim/api/bbsim"
+ "github.com/opencord/bbsim/api/legacy"
"github.com/opencord/bbsim/internal/bbsim/api"
"github.com/opencord/bbsim/internal/bbsim/devices"
"github.com/opencord/bbsim/internal/common"
log "github.com/sirupsen/logrus"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
- "net"
- "os"
- "runtime/pprof"
- "sync"
)
func startApiServer(channel chan bool, group *sync.WaitGroup) {
// TODO make configurable
address := "0.0.0.0:50070"
- log.Debugf("APIServer Listening on: %v", address)
+ log.Debugf("APIServer listening on: %v", address)
lis, err := net.Listen("tcp", address)
if err != nil {
log.Fatalf("APIServer failed to listen: %v", err)
@@ -43,25 +50,84 @@
reflection.Register(grpcServer)
- wg := sync.WaitGroup{}
- wg.Add(1)
-
go grpcServer.Serve(lis)
+ go startApiRestServer(channel, group, address)
- for {
- _, ok := <-channel
- if !ok {
- // if the olt channel is closed, stop the gRPC server
- log.Warnf("Stopping API gRPC server")
- grpcServer.Stop()
- wg.Done()
- break
- }
+ select {
+ case <-channel:
+ // if the api channel is closed, stop the gRPC server
+ grpcServer.Stop()
+ log.Warnf("Stopping API gRPC server")
}
- wg.Wait()
group.Done()
- return
+}
+
+// startApiRestServer method starts the REST server (grpc gateway) for BBSim.
+func startApiRestServer(channel chan bool, group *sync.WaitGroup, grpcAddress string) {
+ ctx := context.Background()
+ ctx, cancel := context.WithCancel(ctx)
+ defer cancel()
+
+ // TODO make configurable
+ address := "0.0.0.0:50071"
+
+ mux := runtime.NewServeMux()
+ opts := []grpc.DialOption{grpc.WithInsecure()}
+
+ if err := bbsim.RegisterBBSimHandlerFromEndpoint(ctx, mux, grpcAddress, opts); err != nil {
+ log.Errorf("Could not register API server: %v", err)
+ return
+ }
+
+ s := &http.Server{Addr: address, Handler: mux}
+
+ go func() {
+ log.Infof("REST API server listening on %s ...", address)
+ if err := s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+ log.Errorf("Could not start API server: %v", err)
+ return
+ }
+ }()
+
+ select {
+ case <-channel:
+ log.Warnf("Stopping API REST server")
+ s.Shutdown(ctx)
+ }
+
+ group.Done()
+}
+
+// This server aims to provide compatibility with the previous BBSim version. It is deprecated and will be removed in the future.
+func startLegacyApiServer(channel chan bool, group *sync.WaitGroup) {
+ // TODO make configurable
+ grpcAddress := "0.0.0.0:50072"
+ restAddress := "0.0.0.0:50073"
+
+ log.Debugf("Legacy APIServer listening on: %v", grpcAddress)
+ listener, err := net.Listen("tcp", grpcAddress)
+ if err != nil {
+ log.Fatalf("Legacy APIServer failed to listen: %v", err)
+ return
+ }
+ apiserver := grpc.NewServer()
+ legacy.RegisterBBSimServiceServer(apiserver, api.BBSimLegacyServer{})
+
+ go apiserver.Serve(listener)
+ // Start rest gateway for BBSim server
+ go api.StartRestGatewayService(channel, group, grpcAddress, restAddress)
+
+ select {
+ case <-channel:
+ // if the olt channel is closed, stop the gRPC server
+ log.Warnf("Stopping legacy API gRPC server")
+ apiserver.Stop()
+ break
+
+ }
+
+ group.Done()
}
func main() {
@@ -91,13 +157,26 @@
oltDoneChannel := make(chan bool)
apiDoneChannel := make(chan bool)
+ sigs := make(chan os.Signal, 1)
+ // stop API and OLT servers on SIGTERM
+ signal.Notify(sigs, syscall.SIGTERM)
+
+ go func() {
+ <-sigs
+ // TODO check when these servers should be shutdown
+ close(apiDoneChannel)
+ close(oltDoneChannel)
+ }()
+
wg := sync.WaitGroup{}
- wg.Add(2)
+ wg.Add(5)
olt := devices.CreateOLT(options.OltID, options.NumNniPerOlt, options.NumPonPerOlt, options.NumOnuPerPon, options.STag, options.CTagInit, &oltDoneChannel, &apiDoneChannel, false)
go devices.StartOlt(olt, &wg)
log.Debugf("Created OLT with id: %d", options.OltID)
go startApiServer(apiDoneChannel, &wg)
+ go startLegacyApiServer(apiDoneChannel, &wg)
+
log.Debugf("Started APIService")
wg.Wait()
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 3496da1..2fdbc75 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -11,4 +11,5 @@
sphinxcontrib-actdiag~=0.8.5
sphinxcontrib-blockdiag~=1.5.5
sphinxcontrib-nwdiag~=0.9.5
-sphinxcontrib-seqdiag~=0.8.5
\ No newline at end of file
+sphinxcontrib-seqdiag~=0.8.5
+sphinxcontrib-openapi~=0.5.0
\ No newline at end of file
diff --git a/docs/source/api.rst b/docs/source/api.rst
new file mode 100644
index 0000000..37c653b
--- /dev/null
+++ b/docs/source/api.rst
@@ -0,0 +1,17 @@
+.. _BBSimAPI:
+
+BBSimAPI
+--------
+
+BBSim exposes gRPC and REST APIs for external control of the simulated OLT. The API is defined using the protocol buffer specification in `api/bbsim/bbsim.proto`.
+By default, the gRPC server is started on port 50070 and the REST server is started on port 50071. The following endpoints are currently defined:
+
+.. openapi:: ../swagger/bbsim/bbsim.swagger.json
+
+Legacy BBSimAPI
+---------------
+
+Additionally, a legacy API is available, defined in `api/legacy/bbsim.proto`. This API is deprecated and will be removed once BBSim reaches feature parity with the legacz version.
+By default, the legacy gRPC server is started on port 50072 and the corresponding REST server is started on port 50073. The following endpoints are currently defined:
+
+.. openapi:: ../swagger/legacy/bbsim.swagger.json
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 0a9ac82..81910a3 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -53,6 +53,7 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
+ 'sphinxcontrib.openapi',
'sphinx.ext.graphviz'
]
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 184fcfa..9acc4d5 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -15,6 +15,7 @@
development-dependencies.rst
bbr.rst
bbsimctl.rst
+ api.rst
Quickstart
diff --git a/docs/swagger/bbsim/.gitignore b/docs/swagger/bbsim/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/docs/swagger/bbsim/.gitignore
diff --git a/docs/swagger/bbsim/bbsim.swagger.json b/docs/swagger/bbsim/bbsim.swagger.json
new file mode 100644
index 0000000..e124c5c
--- /dev/null
+++ b/docs/swagger/bbsim/bbsim.swagger.json
@@ -0,0 +1,252 @@
+{
+ "swagger": "2.0",
+ "info": {
+ "title": "bbsim/bbsim.proto",
+ "version": "version not set"
+ },
+ "schemes": [
+ "http",
+ "https"
+ ],
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "paths": {
+ "/v1/olt": {
+ "get": {
+ "operationId": "GetOlt",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/bbsimOlt"
+ }
+ }
+ },
+ "tags": [
+ "BBSim"
+ ]
+ }
+ },
+ "/v1/olt/onus": {
+ "get": {
+ "operationId": "GetONUs",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/bbsimONUs"
+ }
+ }
+ },
+ "tags": [
+ "BBSim"
+ ]
+ }
+ },
+ "/v1/olt/onus/{SerialNumber}": {
+ "get": {
+ "operationId": "GetONU",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/bbsimONU"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "SerialNumber",
+ "in": "path",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "tags": [
+ "BBSim"
+ ]
+ }
+ },
+ "/v1/olt/status": {
+ "get": {
+ "operationId": "GetOlt2",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/bbsimOlt"
+ }
+ }
+ },
+ "tags": [
+ "BBSim"
+ ]
+ }
+ },
+ "/v1/version": {
+ "get": {
+ "operationId": "Version",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/bbsimVersionNumber"
+ }
+ }
+ },
+ "tags": [
+ "BBSim"
+ ]
+ }
+ }
+ },
+ "definitions": {
+ "bbsimLogLevel": {
+ "type": "object",
+ "properties": {
+ "level": {
+ "type": "string"
+ },
+ "caller": {
+ "type": "boolean",
+ "format": "boolean"
+ }
+ }
+ },
+ "bbsimNNIPort": {
+ "type": "object",
+ "properties": {
+ "ID": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "OperState": {
+ "type": "string"
+ }
+ }
+ },
+ "bbsimONU": {
+ "type": "object",
+ "properties": {
+ "ID": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "SerialNumber": {
+ "type": "string"
+ },
+ "OperState": {
+ "type": "string"
+ },
+ "InternalState": {
+ "type": "string"
+ },
+ "PonPortID": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "STag": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "CTag": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "HwAddress": {
+ "type": "string"
+ },
+ "PortNo": {
+ "type": "integer",
+ "format": "int32"
+ }
+ }
+ },
+ "bbsimONUs": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/bbsimONU"
+ }
+ }
+ }
+ },
+ "bbsimOlt": {
+ "type": "object",
+ "properties": {
+ "ID": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "SerialNumber": {
+ "type": "string"
+ },
+ "OperState": {
+ "type": "string"
+ },
+ "InternalState": {
+ "type": "string"
+ },
+ "NNIPorts": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/bbsimNNIPort"
+ }
+ },
+ "PONPorts": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/bbsimPONPort"
+ }
+ }
+ }
+ },
+ "bbsimPONPort": {
+ "type": "object",
+ "properties": {
+ "ID": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "OperState": {
+ "type": "string"
+ }
+ }
+ },
+ "bbsimResponse": {
+ "type": "object",
+ "properties": {
+ "status_code": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "message": {
+ "type": "string"
+ }
+ }
+ },
+ "bbsimVersionNumber": {
+ "type": "object",
+ "properties": {
+ "version": {
+ "type": "string"
+ },
+ "buildTime": {
+ "type": "string"
+ },
+ "commitHash": {
+ "type": "string"
+ },
+ "gitStatus": {
+ "type": "string"
+ }
+ }
+ }
+ }
+}
diff --git a/docs/swagger/legacy/.gitignore b/docs/swagger/legacy/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/docs/swagger/legacy/.gitignore
diff --git a/docs/swagger/legacy/bbsim.swagger.json b/docs/swagger/legacy/bbsim.swagger.json
new file mode 100644
index 0000000..2873efd
--- /dev/null
+++ b/docs/swagger/legacy/bbsim.swagger.json
@@ -0,0 +1,1648 @@
+{
+ "swagger": "2.0",
+ "info": {
+ "title": "BBSim API",
+ "version": "1.0",
+ "contact": {
+ "url": "http://opencord.org"
+ }
+ },
+ "schemes": [
+ "http"
+ ],
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "paths": {
+ "/v0/olt": {
+ "get": {
+ "summary": "Get current status of OLT",
+ "operationId": "OLTStatus",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyOLTStatusResponse"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "tags": [
+ "BBSimService"
+ ]
+ }
+ },
+ "/v0/olt/flows": {
+ "get": {
+ "summary": "Get flows",
+ "operationId": "GetFlows",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyFlows"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "onu_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "pon_port_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu_serial",
+ "description": "ONU serial number.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "oper_state",
+ "description": "ONU oper state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu_state",
+ "description": "ONU internal state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "gemports",
+ "in": "query",
+ "required": false,
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "collectionFormat": "multi"
+ },
+ {
+ "name": "tconts.uni_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "tconts.port_no",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ }
+ },
+ "/v0/olt/onu/{onu_serial}/flows": {
+ "get": {
+ "summary": "Get flows",
+ "operationId": "GetFlows2",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyFlows"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "onu_serial",
+ "description": "ONU serial number",
+ "in": "path",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "onu_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "pon_port_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "oper_state",
+ "description": "ONU oper state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu_state",
+ "description": "ONU internal state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "gemports",
+ "in": "query",
+ "required": false,
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "collectionFormat": "multi"
+ },
+ {
+ "name": "tconts.uni_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "tconts.port_no",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ }
+ },
+ "/v0/olt/onus": {
+ "get": {
+ "summary": "Get status of all or specific ONUs",
+ "operationId": "ONUStatus",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyONUs"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "onu.onu_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.pon_port_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.onu_serial",
+ "description": "ONU serial number.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.oper_state",
+ "description": "ONU oper state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.onu_state",
+ "description": "ONU internal state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.gemports",
+ "in": "query",
+ "required": false,
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "collectionFormat": "multi"
+ },
+ {
+ "name": "onu.tconts.uni_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.tconts.port_no",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ },
+ "delete": {
+ "summary": "Deactivate ONU(s) for specific PON port(s) specified by\na given onu_serial, onu_id, or pon_port_id",
+ "operationId": "ONUDeactivate",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyBBSimResponse"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "body",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/legacyONUs"
+ }
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ },
+ "post": {
+ "summary": "Single/bulk activate ONU(s) for specific PON port(s)",
+ "operationId": "ONUActivate",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyBBSimResponse"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "body",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/legacyONUs"
+ }
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ }
+ },
+ "/v0/olt/onus/{onu.onu_serial}": {
+ "get": {
+ "summary": "Get status of all or specific ONUs",
+ "operationId": "ONUStatus2",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyONUs"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "onu.onu_serial",
+ "description": "ONU serial number",
+ "in": "path",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "onu.onu_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.pon_port_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.oper_state",
+ "description": "ONU oper state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.onu_state",
+ "description": "ONU internal state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.gemports",
+ "in": "query",
+ "required": false,
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "collectionFormat": "multi"
+ },
+ {
+ "name": "onu.tconts.uni_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.tconts.port_no",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ },
+ "delete": {
+ "summary": "Deactivate ONU(s) for specific PON port(s) specified by\na given onu_serial, onu_id, or pon_port_id",
+ "operationId": "ONUDeactivate2",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyBBSimResponse"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "onu.onu_serial",
+ "description": "ONU serial number",
+ "in": "path",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "onu.onu_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.pon_port_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.oper_state",
+ "description": "ONU oper state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.onu_state",
+ "description": "ONU internal state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.gemports",
+ "in": "query",
+ "required": false,
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "collectionFormat": "multi"
+ },
+ {
+ "name": "onu.tconts.uni_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.tconts.port_no",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ }
+ },
+ "/v0/olt/onus/{onu_serial}/alarms/{alarm_type}/{status}": {
+ "post": {
+ "summary": "Generate ONU related alarms",
+ "operationId": "GenerateONUAlarm",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyBBSimResponse"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "onu_serial",
+ "description": "ONU serial number",
+ "in": "path",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "alarm_type",
+ "description": "Alarm types are:\n \"signaldegrade\"\n \"lossofomcichannel\"\n \"lossofploam\"",
+ "in": "path",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "status",
+ "description": "\"on\"/\"off\" indicates raised or cleared alarm",
+ "in": "path",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ }
+ },
+ "/v0/olt/ports/{onu.pon_port_id}/onus": {
+ "get": {
+ "summary": "Get status of all or specific ONUs",
+ "operationId": "ONUStatus4",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyONUs"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "onu.pon_port_id",
+ "in": "path",
+ "required": true,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.onu_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.onu_serial",
+ "description": "ONU serial number.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.oper_state",
+ "description": "ONU oper state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.onu_state",
+ "description": "ONU internal state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.gemports",
+ "in": "query",
+ "required": false,
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "collectionFormat": "multi"
+ },
+ {
+ "name": "onu.tconts.uni_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.tconts.port_no",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ },
+ "delete": {
+ "summary": "Deactivate ONU(s) for specific PON port(s) specified by\na given onu_serial, onu_id, or pon_port_id",
+ "operationId": "ONUDeactivate3",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyBBSimResponse"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "onu.pon_port_id",
+ "in": "path",
+ "required": true,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.onu_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.onu_serial",
+ "description": "ONU serial number.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.oper_state",
+ "description": "ONU oper state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.onu_state",
+ "description": "ONU internal state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.gemports",
+ "in": "query",
+ "required": false,
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "collectionFormat": "multi"
+ },
+ {
+ "name": "onu.tconts.uni_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.tconts.port_no",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ },
+ "post": {
+ "summary": "Single/bulk activate ONU(s) for specific PON port(s)",
+ "operationId": "ONUActivate2",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyBBSimResponse"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "onu.pon_port_id",
+ "in": "path",
+ "required": true,
+ "type": "integer",
+ "format": "int64"
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ }
+ },
+ "/v0/olt/ports/{onu.pon_port_id}/onus/{onu.onu_id}": {
+ "get": {
+ "summary": "Get status of all or specific ONUs",
+ "operationId": "ONUStatus3",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyONUs"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "onu.pon_port_id",
+ "in": "path",
+ "required": true,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.onu_id",
+ "in": "path",
+ "required": true,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.onu_serial",
+ "description": "ONU serial number.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.oper_state",
+ "description": "ONU oper state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.onu_state",
+ "description": "ONU internal state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.gemports",
+ "in": "query",
+ "required": false,
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "collectionFormat": "multi"
+ },
+ {
+ "name": "onu.tconts.uni_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.tconts.port_no",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ },
+ "delete": {
+ "summary": "Deactivate ONU(s) for specific PON port(s) specified by\na given onu_serial, onu_id, or pon_port_id",
+ "operationId": "ONUDeactivate4",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyBBSimResponse"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "onu.pon_port_id",
+ "in": "path",
+ "required": true,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.onu_id",
+ "in": "path",
+ "required": true,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.onu_serial",
+ "description": "ONU serial number.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.oper_state",
+ "description": "ONU oper state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.onu_state",
+ "description": "ONU internal state.",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "onu.gemports",
+ "in": "query",
+ "required": false,
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "collectionFormat": "multi"
+ },
+ {
+ "name": "onu.tconts.uni_id",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.tconts.port_no",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ }
+ },
+ "/v0/olt/ports/{onu.pon_port_id}/onus/{onu.onu_serial}": {
+ "post": {
+ "summary": "Single/bulk activate ONU(s) for specific PON port(s)",
+ "operationId": "ONUActivate3",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyBBSimResponse"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "onu.pon_port_id",
+ "in": "path",
+ "required": true,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "onu.onu_serial",
+ "description": "ONU serial number",
+ "in": "path",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ }
+ },
+ "/v0/olt/ports/{port_type}/{port_id}/alarms/los/{status}": {
+ "post": {
+ "summary": "Generate OLT related alarms",
+ "operationId": "GenerateOLTAlarm",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyBBSimResponse"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "port_type",
+ "in": "path",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "port_id",
+ "in": "path",
+ "required": true,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "status",
+ "in": "path",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ }
+ },
+ "/v0/olt/ports/{port_type}/{port_id}/status": {
+ "get": {
+ "summary": "Get status of a PON/NNI port",
+ "operationId": "PortStatus",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyPorts"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "port_type",
+ "in": "path",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "port_id",
+ "in": "path",
+ "required": true,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "pon_port_max_onus",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "pon_port_active_onus",
+ "in": "query",
+ "required": false,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "port_state",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "alarm_state",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ }
+ },
+ "/v0/olt/status": {
+ "get": {
+ "summary": "Get current status of OLT",
+ "operationId": "OLTStatus2",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyOLTStatusResponse"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "tags": [
+ "BBSimService"
+ ]
+ }
+ },
+ "/v0/olt/{device_type}/{serial_number}/action/{action}": {
+ "patch": {
+ "summary": "Perform actions on OLT/ONU devices (e.g. reboot)",
+ "operationId": "PerformDeviceAction2",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyBBSimResponse"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "device_type",
+ "in": "path",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "serial_number",
+ "in": "path",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "action",
+ "in": "path",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ }
+ },
+ "/v0/{device_type}/action/{action}": {
+ "patch": {
+ "summary": "Perform actions on OLT/ONU devices (e.g. reboot)",
+ "operationId": "PerformDeviceAction",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/legacyBBSimResponse"
+ }
+ },
+ "404": {
+ "description": "Returned when the resource does not exist.",
+ "schema": {
+ "type": "string",
+ "format": "string"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "device_type",
+ "in": "path",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "action",
+ "in": "path",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "tags": [
+ "BBSimService"
+ ]
+ }
+ }
+ },
+ "definitions": {
+ "legacyBBSimResponse": {
+ "type": "object",
+ "properties": {
+ "status_msg": {
+ "type": "string"
+ }
+ },
+ "title": "BBSim response message"
+ },
+ "legacyFlows": {
+ "type": "object",
+ "properties": {
+ "flows": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/openoltFlow"
+ }
+ }
+ }
+ },
+ "legacyOLTInfo": {
+ "type": "object",
+ "properties": {
+ "olt_id": {
+ "type": "string",
+ "format": "int64"
+ },
+ "olt_serial": {
+ "type": "string"
+ },
+ "olt_ip": {
+ "type": "string"
+ },
+ "olt_state": {
+ "type": "string"
+ },
+ "olt_vendor": {
+ "type": "string"
+ }
+ },
+ "title": "OLT information"
+ },
+ "legacyOLTStatusResponse": {
+ "type": "object",
+ "properties": {
+ "olt": {
+ "$ref": "#/definitions/legacyOLTInfo"
+ },
+ "ports": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/legacyPortInfo"
+ }
+ }
+ },
+ "title": "BBSim status"
+ },
+ "legacyONUInfo": {
+ "type": "object",
+ "properties": {
+ "onu_id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "pon_port_id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "onu_serial": {
+ "type": "string",
+ "title": "ONU serial number"
+ },
+ "oper_state": {
+ "type": "string",
+ "title": "ONU oper state"
+ },
+ "onu_state": {
+ "type": "string",
+ "title": "ONU internal state"
+ },
+ "gemports": {
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "format": "int64"
+ }
+ },
+ "tconts": {
+ "$ref": "#/definitions/legacyTconts"
+ }
+ },
+ "title": "ONU information"
+ },
+ "legacyONUs": {
+ "type": "object",
+ "properties": {
+ "onus": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/legacyONUInfo"
+ }
+ }
+ },
+ "title": "Bulk ONU operations"
+ },
+ "legacyPortInfo": {
+ "type": "object",
+ "properties": {
+ "port_type": {
+ "type": "string"
+ },
+ "port_id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "pon_port_max_onus": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "pon_port_active_onus": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "port_state": {
+ "type": "string"
+ },
+ "alarm_state": {
+ "type": "string"
+ }
+ },
+ "title": "Port information"
+ },
+ "legacyPorts": {
+ "type": "object",
+ "properties": {
+ "ports": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/legacyPortInfo"
+ }
+ }
+ },
+ "title": "Bulk port information"
+ },
+ "legacyTconts": {
+ "type": "object",
+ "properties": {
+ "uni_id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "port_no": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "tconts": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/tech_profileTrafficScheduler"
+ }
+ }
+ }
+ },
+ "openoltAction": {
+ "type": "object",
+ "properties": {
+ "cmd": {
+ "$ref": "#/definitions/openoltActionCmd"
+ },
+ "o_vid": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "o_pbits": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "o_tpid": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "i_vid": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "i_pbits": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "i_tpid": {
+ "type": "integer",
+ "format": "int64"
+ }
+ }
+ },
+ "openoltActionCmd": {
+ "type": "object",
+ "properties": {
+ "add_outer_tag": {
+ "type": "boolean",
+ "format": "boolean"
+ },
+ "remove_outer_tag": {
+ "type": "boolean",
+ "format": "boolean"
+ },
+ "trap_to_host": {
+ "type": "boolean",
+ "format": "boolean"
+ }
+ }
+ },
+ "openoltClassifier": {
+ "type": "object",
+ "properties": {
+ "o_tpid": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "o_vid": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "i_tpid": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "i_vid": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "o_pbits": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "i_pbits": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "eth_type": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "dst_mac": {
+ "type": "string",
+ "format": "byte"
+ },
+ "src_mac": {
+ "type": "string",
+ "format": "byte"
+ },
+ "ip_proto": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "dst_ip": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "src_ip": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "src_port": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "dst_port": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "pkt_tag_type": {
+ "type": "string"
+ }
+ }
+ },
+ "openoltFlow": {
+ "type": "object",
+ "properties": {
+ "access_intf_id": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "onu_id": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "uni_id": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "flow_id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "flow_type": {
+ "type": "string"
+ },
+ "alloc_id": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "network_intf_id": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "gemport_id": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "classifier": {
+ "$ref": "#/definitions/openoltClassifier"
+ },
+ "action": {
+ "$ref": "#/definitions/openoltAction"
+ },
+ "priority": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "cookie": {
+ "type": "string",
+ "format": "uint64"
+ },
+ "port_no": {
+ "type": "integer",
+ "format": "int64"
+ }
+ }
+ },
+ "tech_profileAdditionalBW": {
+ "type": "string",
+ "enum": [
+ "AdditionalBW_None",
+ "AdditionalBW_NA",
+ "AdditionalBW_BestEffort",
+ "AdditionalBW_Auto"
+ ],
+ "default": "AdditionalBW_None"
+ },
+ "tech_profileDirection": {
+ "type": "string",
+ "enum": [
+ "UPSTREAM",
+ "DOWNSTREAM",
+ "BIDIRECTIONAL"
+ ],
+ "default": "UPSTREAM"
+ },
+ "tech_profileInferredAdditionBWIndication": {
+ "type": "string",
+ "enum": [
+ "InferredAdditionBWIndication_None",
+ "InferredAdditionBWIndication_Assured",
+ "InferredAdditionBWIndication_BestEffort"
+ ],
+ "default": "InferredAdditionBWIndication_None"
+ },
+ "tech_profileSchedulerConfig": {
+ "type": "object",
+ "properties": {
+ "direction": {
+ "$ref": "#/definitions/tech_profileDirection"
+ },
+ "additional_bw": {
+ "$ref": "#/definitions/tech_profileAdditionalBW"
+ },
+ "priority": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "weight": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "sched_policy": {
+ "$ref": "#/definitions/tech_profileSchedulingPolicy"
+ }
+ }
+ },
+ "tech_profileSchedulingPolicy": {
+ "type": "string",
+ "enum": [
+ "WRR",
+ "StrictPriority",
+ "Hybrid"
+ ],
+ "default": "WRR"
+ },
+ "tech_profileTrafficScheduler": {
+ "type": "object",
+ "properties": {
+ "direction": {
+ "$ref": "#/definitions/tech_profileDirection"
+ },
+ "alloc_id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "scheduler": {
+ "$ref": "#/definitions/tech_profileSchedulerConfig"
+ },
+ "traffic_shaping_info": {
+ "$ref": "#/definitions/tech_profileTrafficShapingInfo"
+ }
+ }
+ },
+ "tech_profileTrafficShapingInfo": {
+ "type": "object",
+ "properties": {
+ "cir": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "cbs": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "pir": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "pbs": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "gir": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "add_bw_ind": {
+ "$ref": "#/definitions/tech_profileInferredAdditionBWIndication"
+ }
+ }
+ }
+ }
+}
diff --git a/go.mod b/go.mod
index c3882e0..0e175f9 100644
--- a/go.mod
+++ b/go.mod
@@ -6,9 +6,9 @@
github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1 // indirect
github.com/cboling/omci v0.1.0
github.com/deckarep/golang-set v1.7.1 // indirect
- github.com/fullstorydev/grpcurl v1.3.2 // indirect
github.com/golang/protobuf v1.3.2
github.com/google/gopacket v1.1.17
+ github.com/grpc-ecosystem/grpc-gateway v1.11.3
github.com/jessevdk/go-flags v1.4.0
github.com/jhump/protoreflect v1.5.0
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 // indirect
@@ -20,6 +20,8 @@
github.com/sirupsen/logrus v1.4.2
github.com/stretchr/testify v1.4.0 // indirect
github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect
+ golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 // indirect
+ google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610
google.golang.org/grpc v1.22.1
gopkg.in/yaml.v2 v2.2.2
gotest.tools v2.2.0+incompatible
diff --git a/go.sum b/go.sum
index e0ebc88..84816cc 100644
--- a/go.sum
+++ b/go.sum
@@ -6,11 +6,13 @@
github.com/cboling/omci v0.1.0/go.mod h1:qE+T+qTEh/U1UaMidFdMv1eDOJ45WTKTBp2QmEvsWGQ=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ=
github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
-github.com/fullstorydev/grpcurl v1.3.2 h1:cJKWsBYMocdxXQvgbnhtLG810SL5MhKT4K7BagxRih8=
-github.com/fullstorydev/grpcurl v1.3.2/go.mod h1:kvk8xPCXOrwVd9zYdjy+xSOT4YWm6kyth4Y9NMfBns4=
+github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -21,63 +23,88 @@
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/gopacket v1.1.17 h1:rMrlX2ZY2UbvT+sdz3+6J+pp2z+msCq9MxTU6ymxbBY=
github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
+github.com/grpc-ecosystem/grpc-gateway v1.11.3 h1:h8+NsYENhxNTuq+dobk3+ODoJtwY4Fu0WQXsxJfL8aM=
+github.com/grpc-ecosystem/grpc-gateway v1.11.3/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jhump/protoreflect v1.5.0 h1:NgpVT+dX71c8hZnxHof2M7QDK7QtohIJ7DYycjnkyfc=
github.com/jhump/protoreflect v1.5.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
-github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/looplab/fsm v0.1.0 h1:Qte7Zdn/5hBNbXzP7yxVU4OIFHWXBovyTT2LaBTyC20=
github.com/looplab/fsm v0.1.0/go.mod h1:m2VaOfDHxqXBBMgc26m6yUOwkFn8H2AlJDE+jd/uafI=
github.com/opencord/cordctl v0.0.0-20190909161711-01e9c1f04bf4 h1:Odib2px8tyALzdbyztAAqdxmpmQ/pJahJ7uz8kN/rvk=
github.com/opencord/cordctl v0.0.0-20190909161711-01e9c1f04bf4/go.mod h1:/+3S0pwQUy7HeKnH0KfKp5W6hmh/LdZzuZTNT/m7vA4=
-github.com/opencord/omci-sim v0.0.0-20190717165025-5ff7bb17f1e9 h1:qUbCkEFUDEtOBeG6JfI2oMD6dmUa/zJldvBR59RhRdM=
-github.com/opencord/omci-sim v0.0.0-20190717165025-5ff7bb17f1e9/go.mod h1:W10NTwE0xK9Kh++wrflXPfkknMCaNKkb7Io/ihO4y3k=
-github.com/opencord/omci-sim v0.0.0-20190826212842-203314beba7e h1:LHHUbAUR0LyFEHxl1KhMbSTZMDs4HvDngwIpmvvFE6U=
-github.com/opencord/omci-sim v0.0.0-20190826212842-203314beba7e/go.mod h1:ToOkj7hkHgoet9XQDadKMhYqgA7qItZsi2j1Pk/mX6Y=
github.com/opencord/omci-sim v0.0.0-20191011202236-3687c57a7252 h1:CMRqdJmtqku04ImHZW5NtdRlc6RRcdxLOn5Ep/b9HBg=
github.com/opencord/omci-sim v0.0.0-20191011202236-3687c57a7252/go.mod h1:ToOkj7hkHgoet9XQDadKMhYqgA7qItZsi2j1Pk/mX6Y=
github.com/opencord/voltha-protos v0.0.0-20190813191205-792553b747df h1:j/gaZts38ij2uVVikbXGqlm6n3hts1s0zWzUnBI96C4=
github.com/opencord/voltha-protos v0.0.0-20190813191205-792553b747df/go.mod h1:MDGL9ai3XOPbiZ0tA8U7k4twK/T/P0Hh4gtjNxNk/qY=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c h1:+aPplBwWcHBo6q9xrfWdMrT9o4kltkmmvpemgIjep/8=
github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610 h1:Ygq9/SRJX9+dU0WCIICM8RkWvDw03lvB77hrhJnpxfU=
+google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
-google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.22.1 h1:/7cs52RnTJmD43s3uxzlq2U7nqVTd/37viQwMrMNlOM=
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
diff --git a/internal/bbsim/api/grpc_api_server.go b/internal/bbsim/api/grpc_api_server.go
index 0c209f8..9df725b 100644
--- a/internal/bbsim/api/grpc_api_server.go
+++ b/internal/bbsim/api/grpc_api_server.go
@@ -18,6 +18,7 @@
import (
"context"
+
"github.com/opencord/bbsim/api/bbsim"
"github.com/opencord/bbsim/internal/bbsim/devices"
"github.com/opencord/bbsim/internal/common"
@@ -39,7 +40,7 @@
}
func (s BBSimServer) Version(ctx context.Context, req *bbsim.Empty) (*bbsim.VersionNumber, error) {
- // TODO add a flag to specofy whether the tree was clean at this commit or not
+ // TODO add a flag to specify whether the tree was clean at this commit or not
return &bbsim.VersionNumber{
Version: version,
BuildTime: buildTime,
diff --git a/internal/bbsim/api/grpc_api_server_legacy.go b/internal/bbsim/api/grpc_api_server_legacy.go
new file mode 100644
index 0000000..0e9b67b
--- /dev/null
+++ b/internal/bbsim/api/grpc_api_server_legacy.go
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * 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 api
+
+import (
+ "context"
+ "net/http"
+ "sync"
+
+ "github.com/grpc-ecosystem/grpc-gateway/runtime"
+ "github.com/opencord/bbsim/api/legacy"
+ "github.com/opencord/bbsim/internal/bbsim/devices"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+)
+
+type BBSimLegacyServer struct {
+}
+
+// Response Constants
+const (
+ RequestAccepted = "API request accepted"
+ OLTNotEnabled = "OLT not enabled"
+ RequestFailed = "API request failed"
+ SoftReboot = "soft-reboot"
+ HardReboot = "hard-reboot"
+ DeviceTypeOlt = "olt"
+ DeviceTypeOnu = "onu"
+)
+
+// OLTStatus method returns the OLT status.
+func (s BBSimLegacyServer) OLTStatus(ctx context.Context, in *legacy.Empty) (*legacy.OLTStatusResponse, error) {
+ logger.Trace("OLTStatus request received")
+
+ olt := devices.GetOLT()
+ oltInfo := &legacy.OLTStatusResponse{
+ Olt: &legacy.OLTInfo{
+ OltId: int64(olt.ID),
+ OltVendor: "BBSIM",
+ OltSerial: olt.SerialNumber,
+ // OltIp: getOltIP().String(), // TODO
+ OltState: olt.OperState.Current(),
+ },
+ }
+
+ for _, nni := range olt.Nnis {
+ nniPortInfo := &legacy.PortInfo{
+ PortType: "nni",
+ PortId: uint32(nni.ID),
+ PortState: nni.OperState.Current(),
+ }
+ oltInfo.Ports = append(oltInfo.Ports, nniPortInfo)
+ }
+
+ for _, pon := range olt.Pons {
+ ponPortInfo := &legacy.PortInfo{
+ PortType: "pon",
+ PortId: uint32(pon.ID),
+ PonPortMaxOnus: uint32(olt.NumOnuPerPon),
+ PonPortActiveOnus: uint32(olt.NumPon),
+ PortState: pon.OperState.Current(),
+ }
+ oltInfo.Ports = append(oltInfo.Ports, ponPortInfo)
+ }
+
+ return oltInfo, nil
+}
+
+// PortStatus method returns Port status.
+func (s BBSimLegacyServer) PortStatus(ctx context.Context, in *legacy.PortInfo) (*legacy.Ports, error) {
+ logger.Trace("PortStatus() invoked")
+ ports := &legacy.Ports{}
+ switch portType := in.GetPortType(); portType {
+ case "pon":
+ portInfo, err := s.fetchPortDetail(in.PortId, portType)
+ if err != nil {
+ return ports, err
+ }
+ ports.Ports = append(ports.Ports, portInfo)
+ case "nni":
+ portInfo, _ := s.fetchPortDetail(in.PortId, portType)
+ ports.Ports = append(ports.Ports, portInfo)
+ default:
+ return &legacy.Ports{}, status.Errorf(codes.InvalidArgument, "Invalid port type")
+ }
+
+ return ports, nil
+}
+
+// ONUStatus method returns ONU status.
+func (s BBSimLegacyServer) ONUStatus(ctx context.Context, in *legacy.ONURequest) (*legacy.ONUs, error) {
+ logger.Trace("ONUStatus request received")
+ onuInfo := &legacy.ONUs{}
+
+ if in.GetOnu() != nil {
+ logger.Debugf("Received single ONU: %+v, %d\n", in.GetOnu().OnuId, in.GetOnu().PonPortId)
+ return s.handleONUStatusRequest(in.GetOnu())
+ }
+
+ logger.Debug("Received all ONUs status request")
+
+ // Get status of all ONUs
+ olt := devices.GetOLT()
+ for _, p := range olt.Pons {
+ for _, o := range p.Onus {
+ onuInfo.Onus = append(onuInfo.Onus, copyONUInfo(o))
+ }
+ }
+
+ return onuInfo, nil
+}
+
+// ONUActivate method handles ONU activate requests from user.
+func (s BBSimLegacyServer) ONUActivate(ctx context.Context, in *legacy.ONURequest) (*legacy.BBSimResponse, error) {
+ logger.Trace("ONUActivate request received")
+ logger.Error("Not implemented")
+
+ return &legacy.BBSimResponse{StatusMsg: RequestAccepted}, nil
+}
+
+// ONUDeactivate method handles ONU deactivation request.
+func (s BBSimLegacyServer) ONUDeactivate(ctx context.Context, in *legacy.ONURequest) (*legacy.BBSimResponse, error) {
+ logger.Info("ONUDeactivate request received")
+ logger.Error("Not implemented")
+
+ return &legacy.BBSimResponse{StatusMsg: RequestAccepted}, nil
+}
+
+// GenerateONUAlarm RPC generates alarm for the onu
+func (s BBSimLegacyServer) GenerateONUAlarm(ctx context.Context, in *legacy.ONUAlarmRequest) (*legacy.BBSimResponse, error) {
+ logger.Trace("GenerateONUAlarms() invoked")
+ logger.Error("Not implemented")
+
+ return nil, nil
+}
+
+// GenerateOLTAlarm RPC generates alarm for the OLT
+func (s BBSimLegacyServer) GenerateOLTAlarm(ctx context.Context, in *legacy.OLTAlarmRequest) (*legacy.BBSimResponse, error) {
+ logger.Trace("GenerateOLTAlarm() invoked")
+ logger.Error("Not implemented")
+
+ return &legacy.BBSimResponse{StatusMsg: RequestAccepted}, nil
+}
+
+// PerformDeviceAction rpc take the device request and performs OLT and ONU hard and soft reboot
+func (s BBSimLegacyServer) PerformDeviceAction(ctx context.Context, in *legacy.DeviceAction) (*legacy.BBSimResponse, error) {
+ logger.Trace("PerformDeviceAction() invoked")
+ logger.Error("Not implemented")
+
+ return &legacy.BBSimResponse{StatusMsg: RequestAccepted}, nil
+}
+
+// GetFlows returns all flows or flows for specified ONU
+func (s BBSimLegacyServer) GetFlows(ctx context.Context, in *legacy.ONUInfo) (*legacy.Flows, error) {
+ logger.Info("GetFlow request received")
+ logger.Error("Not implemented")
+
+ return &legacy.Flows{}, nil
+}
+
+// StartRestGatewayService method starts REST server for BBSim.
+func StartRestGatewayService(channel chan bool, group *sync.WaitGroup, grpcAddress string, hostandport string) {
+ ctx := context.Background()
+ ctx, cancel := context.WithCancel(ctx)
+ defer cancel()
+
+ mux := runtime.NewServeMux()
+ opts := []grpc.DialOption{grpc.WithInsecure()}
+
+ // Register REST endpoints
+ err := legacy.RegisterBBSimServiceHandlerFromEndpoint(ctx, mux, grpcAddress, opts)
+ if err != nil {
+ logger.Error("%v", err)
+ return
+ }
+
+ s := &http.Server{Addr: hostandport, Handler: mux}
+
+ go func() {
+ logger.Infof("legacy REST API server listening on %s ...", hostandport)
+ if err := s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+ logger.Errorf("Could not start legacy API server: %v", err)
+ return
+ }
+ }()
+
+ select {
+ case <-channel:
+ logger.Warnf("Stopping legacy API REST server")
+ s.Shutdown(ctx)
+ group.Done()
+ }
+ return
+}
diff --git a/internal/bbsim/api/legacy_api_handler.go b/internal/bbsim/api/legacy_api_handler.go
new file mode 100644
index 0000000..c56e963
--- /dev/null
+++ b/internal/bbsim/api/legacy_api_handler.go
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * 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 api
+
+import (
+ "encoding/hex"
+ "errors"
+ "net"
+ "strconv"
+
+ "github.com/opencord/bbsim/api/legacy"
+ api "github.com/opencord/bbsim/api/legacy"
+ "github.com/opencord/bbsim/internal/bbsim/devices"
+ "github.com/opencord/voltha-protos/go/openolt"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+)
+
+// Constants for reboot delays
+const (
+ OltRebootDelay = 40
+ OnuSoftRebootDelay = 10
+ OnuHardRebootDelay = 30
+)
+
+// handleONUStatusRequest process ONU status request
+func (s BBSimLegacyServer) handleONUStatusRequest(in *api.ONUInfo) (*api.ONUs, error) {
+ logger.Trace("handleONUStatusRequest() invoked")
+ onuInfo := &api.ONUs{}
+ olt := devices.GetOLT()
+
+ if in.OnuSerial != "" { // Get status of a single ONU by SerialNumber
+ onu, err := olt.FindOnuBySn(in.OnuSerial)
+ if err != nil {
+ logger.Errorf("ONU error: %+v", err)
+ return onuInfo, status.Errorf(codes.NotFound, "Unable to retrieve ONU %s", in.OnuSerial)
+ }
+ onuInfo.Onus = append(onuInfo.Onus, copyONUInfo(onu))
+ } else {
+ if in.OnuId != 0 { // Get status of a single ONU by ONU-ID
+ onu, err := olt.FindOnuById(in.PonPortId, in.OnuId)
+ if err != nil {
+ logger.Errorf("ONU error: %+v", err)
+ return onuInfo, status.Errorf(codes.NotFound, "Unable to retrieve ONU with ID %d", in.OnuId)
+ }
+
+ onuInfo.Onus = append(onuInfo.Onus, copyONUInfo(onu))
+ } else { // Get status of all ONUs
+ for _, p := range olt.Pons {
+ for _, o := range p.Onus {
+ onuInfo.Onus = append(onuInfo.Onus, copyONUInfo(o))
+ }
+ }
+ }
+ }
+
+ return onuInfo, nil
+}
+
+func copyONUInfo(onu *devices.Onu) *api.ONUInfo {
+ onuData := &api.ONUInfo{
+ OnuId: onu.ID,
+ PonPortId: onu.PonPortID,
+ OnuSerial: onu.Sn(),
+ OnuState: onu.InternalState.Current(),
+ OperState: onu.OperState.Current(),
+ }
+
+ return onuData
+}
+
+func (s BBSimLegacyServer) fetchPortDetail(intfID uint32, portType string) (*api.PortInfo, error) {
+ logger.Tracef("fetchPortDetail() invoked %s-%d", portType, intfID)
+ olt := devices.GetOLT()
+
+ switch portType {
+ case "pon":
+ for _, pon := range olt.Pons {
+ if pon.ID == intfID {
+ ponPortInfo := &api.PortInfo{
+ PortType: "pon",
+ PortId: uint32(pon.ID),
+ PonPortMaxOnus: uint32(olt.NumOnuPerPon),
+ PonPortActiveOnus: uint32(olt.NumPon),
+ PortState: pon.OperState.Current(),
+ }
+ return ponPortInfo, nil
+ }
+ }
+ case "nni":
+ for _, nni := range olt.Nnis {
+ if nni.ID == intfID {
+ nniPortInfo := &legacy.PortInfo{
+ PortType: "nni",
+ PortId: uint32(nni.ID),
+ PortState: nni.OperState.Current(),
+ }
+ return nniPortInfo, nil
+ }
+ }
+ }
+
+ portInfo := &api.PortInfo{}
+ return portInfo, status.Errorf(codes.NotFound, "Invalid port %s-%d", portType, intfID)
+}
+
+func getOpenoltSerialNumber(SerialNumber string) (*openolt.SerialNumber, error) {
+ var VendorIDLength = 4
+ var SerialNumberLength = 12
+
+ if len(SerialNumber) != SerialNumberLength {
+ logger.Error("Invalid serial number %s", SerialNumber)
+ return nil, errors.New("invalid serial number")
+ }
+ // First four characters are vendorId
+ vendorID := SerialNumber[:VendorIDLength]
+ vendorSpecific := SerialNumber[VendorIDLength:]
+
+ vsbyte, _ := hex.DecodeString(vendorSpecific)
+
+ // Convert to Openolt serial number
+ serialNum := new(openolt.SerialNumber)
+ serialNum.VendorId = []byte(vendorID)
+ serialNum.VendorSpecific = vsbyte
+
+ return serialNum, nil
+}
+
+// ConvB2S converts byte array to string
+func ConvB2S(b []byte) string {
+ s := ""
+ for _, i := range b {
+ s = s + strconv.FormatInt(int64(i/16), 16) + strconv.FormatInt(int64(i%16), 16)
+ }
+ return s
+}
+
+func getOltIP() net.IP {
+ // TODO make this better
+ conn, err := net.Dial("udp", "8.8.8.8:80")
+ if err != nil {
+ logger.Error(err.Error())
+ return net.IP{}
+ }
+ defer func() {
+ err := conn.Close()
+ if err != nil {
+ logger.Error(err.Error())
+ }
+ }()
+
+ localAddr := conn.LocalAddr().(*net.UDPAddr)
+
+ return localAddr.IP
+}
diff --git a/internal/bbsim/devices/nni.go b/internal/bbsim/devices/nni.go
index 3a36287..ad01f2f 100644
--- a/internal/bbsim/devices/nni.go
+++ b/internal/bbsim/devices/nni.go
@@ -74,34 +74,43 @@
// sendNniPacket will send a packet out of the NNI interface.
// We will send upstream only DHCP packets and drop anything else
func sendNniPacket(packet gopacket.Packet) error {
- if isDhcp := packetHandlers.IsDhcpPacket(packet); !isDhcp {
+ isDhcp := packetHandlers.IsDhcpPacket(packet)
+ isLldp := packetHandlers.IsLldpPacket(packet)
+
+ if isDhcp == false && isLldp == false {
nniLogger.WithFields(log.Fields{
"packet": packet,
}).Trace("Dropping NNI packet as it's not DHCP")
+ return nil
}
- packet, err := packetHandlers.PopDoubleTag(packet)
- if err != nil {
- nniLogger.WithFields(log.Fields{
- "packet": packet,
- }).Errorf("Can't remove double tags from packet: %v", err)
- return err
- }
+ if isDhcp {
+ packet, err := packetHandlers.PopDoubleTag(packet)
+ if err != nil {
+ nniLogger.WithFields(log.Fields{
+ "packet": packet,
+ }).Errorf("Can't remove double tags from packet: %v", err)
+ return err
+ }
- handle, err := getVethHandler(nniVeth)
- if err != nil {
- return err
- }
+ handle, err := getVethHandler(nniVeth)
+ if err != nil {
+ return err
+ }
- err = handle.WritePacketData(packet.Data())
- if err != nil {
- nniLogger.WithFields(log.Fields{
- "packet": packet,
- }).Errorf("Failed to send packet out of the NNI: %s", err)
- return err
- }
+ err = handle.WritePacketData(packet.Data())
+ if err != nil {
+ nniLogger.WithFields(log.Fields{
+ "packet": packet,
+ }).Errorf("Failed to send packet out of the NNI: %s", err)
+ return err
+ }
- nniLogger.Infof("Sent packet out of NNI")
+ nniLogger.Infof("Sent packet out of NNI")
+ } else if isLldp {
+ // TODO rework this when BBSim supports data-plane packets
+ nniLogger.Trace("Received LLDP Packet, ignoring it")
+ }
return nil
}
diff --git a/internal/bbsim/devices/olt.go b/internal/bbsim/devices/olt.go
index bfaa5fd..2a31eb2 100644
--- a/internal/bbsim/devices/olt.go
+++ b/internal/bbsim/devices/olt.go
@@ -20,6 +20,9 @@
"context"
"errors"
"fmt"
+ "net"
+ "sync"
+
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/looplab/fsm"
@@ -30,8 +33,6 @@
"github.com/opencord/voltha-protos/go/tech_profile"
log "github.com/sirupsen/logrus"
"google.golang.org/grpc"
- "net"
- "sync"
)
var oltLogger = log.WithFields(log.Fields{
@@ -436,7 +437,7 @@
// returns an ONU with a given Serial Number
func (o OltDevice) FindOnuBySn(serialNumber string) (*Onu, error) {
- // TODO this function can be a perfoormance bottlenec when we have many ONUs,
+ // TODO this function can be a performance bottleneck when we have many ONUs,
// memoizing it will remove the bottleneck
for _, pon := range o.Pons {
for _, onu := range pon.Onus {
@@ -451,7 +452,7 @@
// returns an ONU with a given interface/Onu Id
func (o OltDevice) FindOnuById(intfId uint32, onuId uint32) (*Onu, error) {
- // TODO this function can be a performance bottlenec when we have many ONUs,
+ // TODO this function can be a performance bottleneck when we have many ONUs,
// memoizing it will remove the bottleneck
for _, pon := range o.Pons {
if pon.ID == intfId {
@@ -467,7 +468,7 @@
// returns an ONU with a given Mac Address
func (o OltDevice) FindOnuByMacAddress(mac net.HardwareAddr) (*Onu, error) {
- // TODO this function can be a perfoormance bottlenec when we have many ONUs,
+ // TODO this function can be a performance bottleneck when we have many ONUs,
// memoizing it will remove the bottleneck
for _, pon := range o.Pons {
for _, onu := range pon.Onus {
@@ -631,6 +632,7 @@
devinfo.FlowIdStart = 1
devinfo.FlowIdEnd = 16383
devinfo.DeviceSerialNumber = o.SerialNumber
+ devinfo.DeviceId = net.HardwareAddr{0xA, 0xA, 0xA, 0xA, 0xA, byte(o.ID)}.String()
return devinfo, nil
}
diff --git a/internal/bbsim/devices/pon.go b/internal/bbsim/devices/pon.go
index f27510f..ac1bdb7 100644
--- a/internal/bbsim/devices/pon.go
+++ b/internal/bbsim/devices/pon.go
@@ -20,6 +20,7 @@
"bytes"
"errors"
"fmt"
+
"github.com/looplab/fsm"
"github.com/opencord/voltha-protos/go/openolt"
)
diff --git a/internal/bbsim/packetHandlers/filters.go b/internal/bbsim/packetHandlers/filters.go
index b43b677..9ada88c 100644
--- a/internal/bbsim/packetHandlers/filters.go
+++ b/internal/bbsim/packetHandlers/filters.go
@@ -30,6 +30,13 @@
return false
}
+func IsLldpPacket(pkt gopacket.Packet) bool {
+ if layer := pkt.Layer(layers.LayerTypeLinkLayerDiscovery); layer != nil {
+ return true
+ }
+ return false
+}
+
// return true if the packet is coming in the OLT from the NNI port
// it uses the ack to check if the source is the one we assigned to the
// dhcp server
diff --git a/internal/bbsim/packetHandlers/filters_test.go b/internal/bbsim/packetHandlers/filters_test.go
index 6064e68..8d5f96a 100644
--- a/internal/bbsim/packetHandlers/filters_test.go
+++ b/internal/bbsim/packetHandlers/filters_test.go
@@ -62,6 +62,50 @@
assert.Equal(t, res, false)
}
+func Test_IsLldpPacket_True(t *testing.T) {
+ layer := &layers.LinkLayerDiscovery{
+ PortID: layers.LLDPPortID{
+ ID: []byte{1, 2, 3, 4},
+ Subtype: layers.LLDPPortIDSubtypeMACAddr,
+ },
+ ChassisID: layers.LLDPChassisID{
+ ID: []byte{1, 2, 3, 4},
+ Subtype: layers.LLDPChassisIDSubTypeMACAddr,
+ },
+ }
+
+ buffer := gopacket.NewSerializeBuffer()
+ opts := gopacket.SerializeOptions{FixLengths: true}
+ err := gopacket.SerializeLayers(buffer, opts, layer)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ packet := gopacket.NewPacket(buffer.Bytes(), layers.LayerTypeLinkLayerDiscovery, gopacket.DecodeOptions{})
+
+ res := packetHandlers.IsLldpPacket(packet)
+ assert.Equal(t, res, true)
+}
+
+func Test_IsLldpPacket_False(t *testing.T) {
+ eth := &layers.Ethernet{
+ DstMAC: net.HardwareAddr{0x2e, 0x60, 0x70, 0x13, 0x15, 0x16},
+ SrcMAC: net.HardwareAddr{0x2e, 0x60, 0x70, 0x13, 0x15, 0x17},
+ }
+
+ buffer := gopacket.NewSerializeBuffer()
+ opts := gopacket.SerializeOptions{FixLengths: true}
+ err := gopacket.SerializeLayers(buffer, opts, eth)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ ethernetPkt := gopacket.NewPacket(buffer.Bytes(), layers.LayerTypeEthernet, gopacket.DecodeOptions{})
+
+ res := packetHandlers.IsLldpPacket(ethernetPkt)
+ assert.Equal(t, res, false)
+}
+
func Test_IsIncomingPacket_True(t *testing.T) {
eth := &layers.IPv4{
SrcIP: net.ParseIP("192.168.254.1"),
diff --git a/tools/.gitignore b/tools/.gitignore
new file mode 100644
index 0000000..08c9828
--- /dev/null
+++ b/tools/.gitignore
@@ -0,0 +1,3 @@
+*
+!.gitignore
+!main.go
diff --git a/tools/main.go b/tools/main.go
new file mode 100644
index 0000000..b387490
--- /dev/null
+++ b/tools/main.go
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * 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.
+ */
+
+// +build tools
+
+package tools
+
+import (
+ // protocol buffer compiler plugins
+ _ "github.com/golang/protobuf/protoc-gen-go"
+ _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway"
+ _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger"
+)