Mostly integration test work:
* Switches A1's three test receivers (integration tests) over to golang; this was mostly done to learn the go xapp framework and they are identical in functionality.
* Upgrades the version of rmr in A1 and all integration receivers to 1.13.*
* Uses a much fancier Docker build to reduce the size of a1's image. The python:3.7-alpine image itself is 98MB and A1 is now only ~116MB, so we're done optimizing A1's container size.
Issue-ID: RICAPP-61
Change-Id: Ic2004a5b457c55c730575aa8326e61b01e8546da
Signed-off-by: Tommy Carpenter <tc677g@att.com>
diff --git a/integration_tests/testxappcode/Dockerfile-delay-receiver b/integration_tests/testxappcode/Dockerfile-delay-receiver
new file mode 100644
index 0000000..15c6f28
--- /dev/null
+++ b/integration_tests/testxappcode/Dockerfile-delay-receiver
@@ -0,0 +1,46 @@
+# ==================================================================================
+# Copyright (c) 2020 Nokia
+# Copyright (c) 2020 AT&T Intellectual Property.
+#
+# 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.
+# ==================================================================================
+
+# This Dockerfile uses a two stage Docker build
+
+FROM nexus3.o-ran-sc.org:10004/bldr-alpine3-go:1-rmr1.13.1
+
+# go will complain if there is a go.mod at the root of the GOPATH so we can't.
+RUN mkdir myxapp
+COPY receiver.go myxapp/receiver.go
+COPY go.mod myxapp/go.mod
+
+# do the build
+WORKDIR myxapp
+ENV GO111MODULE on
+ENV GO_ENABLED 0
+ENV GOOS linux
+RUN go build -a -installsuffix cgo -o receiver receiver.go
+
+# 2nd stage
+FROM alpine:3.11
+COPY --from=0 /usr/local/lib64/libnng.so* /usr/local/lib64/
+COPY --from=0 /usr/local/lib64/librmr_nng* /usr/local/lib64/
+COPY --from=0 /go/myxapp/receiver .
+COPY delay-config-file.yaml .
+
+# rmr setup
+RUN mkdir -p /opt/route/
+ENV LD_LIBRARY_PATH /usr/local/lib:/usr/local/lib64
+ENV RMR_SEED_RT /opt/route/local.rt
+
+CMD ["./receiver", "-f", "delay-config-file.yaml"]
diff --git a/integration_tests/testxappcode/Dockerfile-query-receiver b/integration_tests/testxappcode/Dockerfile-query-receiver
new file mode 100644
index 0000000..20fb082
--- /dev/null
+++ b/integration_tests/testxappcode/Dockerfile-query-receiver
@@ -0,0 +1,46 @@
+# ==================================================================================
+# Copyright (c) 2020 Nokia
+# Copyright (c) 2020 AT&T Intellectual Property.
+#
+# 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.
+# ==================================================================================
+
+# This Dockerfile uses a two stage Docker build
+
+FROM nexus3.o-ran-sc.org:10004/bldr-alpine3-go:1-rmr1.13.1
+
+# go will complain if there is a go.mod at the root of the GOPATH so we can't.
+RUN mkdir myxapp
+COPY receiver.go myxapp/receiver.go
+COPY go.mod myxapp/go.mod
+
+# do the build
+WORKDIR myxapp
+ENV GO111MODULE on
+ENV GO_ENABLED 0
+ENV GOOS linux
+RUN go build -a -installsuffix cgo -o receiver receiver.go
+
+# 2nd stage
+FROM alpine:3.11
+COPY --from=0 /usr/local/lib64/libnng.so* /usr/local/lib64/
+COPY --from=0 /usr/local/lib64/librmr_nng* /usr/local/lib64/
+COPY --from=0 /go/myxapp/receiver .
+COPY query-config-file.yaml .
+
+# rmr setup
+RUN mkdir -p /opt/route/
+ENV LD_LIBRARY_PATH /usr/local/lib:/usr/local/lib64
+ENV RMR_SEED_RT /opt/route/local.rt
+
+CMD ["./receiver", "-f", "query-config-file.yaml"]
diff --git a/integration_tests/testxappcode/Dockerfile-test-receiver b/integration_tests/testxappcode/Dockerfile-test-receiver
new file mode 100644
index 0000000..174af0e
--- /dev/null
+++ b/integration_tests/testxappcode/Dockerfile-test-receiver
@@ -0,0 +1,47 @@
+# ==================================================================================
+# Copyright (c) 2020 Nokia
+# Copyright (c) 2020 AT&T Intellectual Property.
+#
+# 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.
+# ==================================================================================
+
+# This Dockerfile uses a two stage Docker build
+
+# The first stage is defined here: https://gerrit.o-ran-sc.org/r/gitweb?p=ci-management.git;a=blob;f=docker/bldr-alpine3-go/Dockerfile;h=a1e31f07e6113d4a02202793ace6ebc780d71583;hb=3711ffcbfe06f6c872bf4a0871eb5f2a2fcd83ae
+FROM nexus3.o-ran-sc.org:10004/bldr-alpine3-go:1-rmr1.13.1
+
+# go will complain if there is a go.mod at the root of the GOPATH so we can't.
+RUN mkdir myxapp
+COPY receiver.go myxapp/receiver.go
+COPY go.mod myxapp/go.mod
+
+# do the build
+WORKDIR myxapp
+ENV GO111MODULE on
+ENV GO_ENABLED 0
+ENV GOOS linux
+RUN go build -a -installsuffix cgo -o receiver receiver.go
+
+# 2nd stage
+FROM alpine:3.11
+COPY --from=0 /usr/local/lib64/libnng.so* /usr/local/lib64/
+COPY --from=0 /usr/local/lib64/librmr_nng* /usr/local/lib64/
+COPY --from=0 /go/myxapp/receiver .
+COPY test-config-file.yaml .
+
+# rmr setup
+RUN mkdir -p /opt/route/
+ENV LD_LIBRARY_PATH /usr/local/lib:/usr/local/lib64
+ENV RMR_SEED_RT /opt/route/local.rt
+
+CMD ["./receiver", "-f", "test-config-file.yaml"]
diff --git a/integration_tests/testxappcode/delay-config-file.yaml b/integration_tests/testxappcode/delay-config-file.yaml
new file mode 100755
index 0000000..8db59f7
--- /dev/null
+++ b/integration_tests/testxappcode/delay-config-file.yaml
@@ -0,0 +1,38 @@
+# Copyright (c) 2019-2020 AT&T Intellectual Property.
+# Copyright (c) 2019-2020 Nokia.
+#
+# 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.
+
+"local":
+ "host": ":8080"
+"logger":
+ "level": 4
+"rmr":
+ "protPort": "tcp:4563"
+ "maxSize": 4096
+ "numWorkers": 1
+"db":
+ "host": "dbaas"
+ "port": 6379
+ "namespaces": ["sdl", "rnib"]
+"test":
+ "mode": "forwarder"
+ "mtype": 10004
+ "subId": 1111
+ "size": 100
+ "rate": 10
+ "amount": 10
+ "rounds": 1
+ "store": 0
+ "waitForAck": 0
+
diff --git a/integration_tests/testxappcode/go.mod b/integration_tests/testxappcode/go.mod
new file mode 100644
index 0000000..9a5691f
--- /dev/null
+++ b/integration_tests/testxappcode/go.mod
@@ -0,0 +1,20 @@
+go 1.13
+
+module gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/example-xapp
+
+require (
+ gerrit.o-ran-sc.org/r/ric-plt/xapp-frame v0.0.24
+ github.com/go-openapi/errors v0.19.3 // indirect
+ github.com/go-openapi/runtime v0.19.11 // indirect
+ github.com/go-openapi/spec v0.19.6 // indirect
+ github.com/go-openapi/strfmt v0.19.4 // indirect
+ github.com/go-openapi/swag v0.19.7 // indirect
+ github.com/go-openapi/validate v0.19.6 // indirect
+ github.com/jessevdk/go-flags v1.4.0 // indirect
+)
+
+replace gerrit.o-ran-sc.org/r/ric-plt/xapp-frame => gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.24
+
+replace gerrit.o-ran-sc.org/r/ric-plt/sdlgo => gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.5.0
+
+replace gerrit.o-ran-sc.org/r/com/golog => gerrit.o-ran-sc.org/r/com/golog.git v0.0.1
diff --git a/integration_tests/testxappcode/query-config-file.yaml b/integration_tests/testxappcode/query-config-file.yaml
new file mode 100755
index 0000000..871d166
--- /dev/null
+++ b/integration_tests/testxappcode/query-config-file.yaml
@@ -0,0 +1,38 @@
+# Copyright (c) 2019-2020 AT&T Intellectual Property.
+# Copyright (c) 2019-2020 Nokia.
+#
+# 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.
+
+"local":
+ "host": ":8080"
+"logger":
+ "level": 4
+"rmr":
+ "protPort": "tcp:4564"
+ "maxSize": 4096
+ "numWorkers": 1
+"db":
+ "host": "dbaas"
+ "port": 6379
+ "namespaces": ["sdl", "rnib"]
+"test":
+ "mode": "forwarder"
+ "mtype": 10004
+ "subId": 1111
+ "size": 100
+ "rate": 10
+ "amount": 10
+ "rounds": 1
+ "store": 0
+ "waitForAck": 0
+
diff --git a/integration_tests/testxappcode/receiver.go b/integration_tests/testxappcode/receiver.go
new file mode 100755
index 0000000..9012094
--- /dev/null
+++ b/integration_tests/testxappcode/receiver.go
@@ -0,0 +1,227 @@
+/*
+==================================================================================
+ Copyright (c) 2020 AT&T Intellectual Property.
+ Copyright (c) 2020 Nokia
+
+ 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 main
+
+import (
+ "encoding/json"
+ "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
+ "os"
+ "strconv"
+ "time"
+)
+
+var delay int // used for the delay receiver
+var handlerID string // used for the delay receiver too
+var doQuery bool // used for the query receiver
+
+type a1Receiver struct {
+ msgChan chan *xapp.RMRParams
+ appReady bool
+ rmrReady bool
+}
+
+type policyRequest struct {
+ Operation string `json:"operation"`
+ PolicyTypeID int `json:"policy_type_id"`
+ PolicyInstanceID string `json:"policy_instance_id"`
+ Pay interface{} `json:"payload"`
+}
+
+type policyRequestResponse struct {
+ PolicyTypeID int `json:"policy_type_id"`
+ PolicyInstanceID string `json:"policy_instance_id"`
+ HandlerID string `json:"handler_id"`
+ Status string `json:"status"`
+}
+
+type policyQuery struct {
+ PolicyTypeID int `json:"policy_type_id"`
+}
+
+func (e *a1Receiver) sendMsgRetry(params *xapp.RMRParams) {
+ // helper for rmr that handles retries and sleep
+ retries := 0
+ for { // just keep trying until it works
+ if e.rmrReady { // we must wait for ready, else SendMsg will blow with a nullptr
+ if ok := xapp.Rmr.SendMsg(params); ok {
+ xapp.Logger.Info("Msg successfully sent after %d retries!", retries)
+ return
+ }
+ retries++
+ //xapp.Logger.Info("Query failed to send...")
+ } else {
+ xapp.Logger.Info("rmr not ready...")
+ time.Sleep(time.Duration(1) * time.Second)
+ }
+ }
+}
+
+func (e *a1Receiver) handlePolicyReq(msg *xapp.RMRParams) {
+
+ // unmarshal the request
+ var dat policyRequest
+ if err := json.Unmarshal(msg.Payload, &dat); err != nil {
+ panic(err)
+ }
+
+ var status string
+ switch dat.Operation {
+ case "CREATE":
+ status = "OK"
+ case "DELETE":
+ status = "DELETED"
+ }
+
+ // form the response
+ res := &policyRequestResponse{
+ dat.PolicyTypeID,
+ dat.PolicyInstanceID,
+ "test_receiver",
+ status,
+ }
+
+ outgoing, err := json.Marshal(res)
+ if err != nil {
+ panic(err)
+ }
+
+ /*
+ WARNING:
+ we want to use rts here. However, the current go xapp framework rts is broken.
+ */
+ params := &xapp.RMRParams{
+ Mtype: 20011,
+ Payload: outgoing,
+ }
+
+ if delay > 0 {
+ xapp.Logger.Info("Xapp is sleeping...")
+ time.Sleep(time.Duration(delay) * time.Second) // so much work to replicate python's time.sleep(5)...
+ }
+
+ e.sendMsgRetry(params)
+
+ xapp.Logger.Info("Policy response sent!")
+}
+
+func (e *a1Receiver) sendQuery() {
+ // form the query
+ res := &policyQuery{
+ 1006001,
+ }
+ outgoing, err := json.Marshal(res)
+ if err != nil {
+ panic(err)
+ }
+ params := &xapp.RMRParams{
+ Mtype: 20012,
+ Payload: outgoing,
+ }
+
+ for {
+ /* We do this in a loop here, because even when the query first works, it could be the case that
+ a1 does not even have the type yet, or there are no instances yet. In this integration test,
+ we just keep pounding away so that eventually a1 returns the list this int test is looking for.
+ A real xapp would NOT call the query in a loop like this.
+ */
+ e.sendMsgRetry(params)
+ xapp.Logger.Info("Query sent successfully")
+ time.Sleep(time.Duration(1) * time.Second)
+ }
+}
+
+func (e *a1Receiver) messageLoop() {
+ for {
+ xapp.Logger.Info("Waiting for message..")
+
+ msg := <-e.msgChan
+
+ xapp.Logger.Info("Message received!")
+ defer xapp.Rmr.Free(msg.Mbuf)
+
+ switch msg.Mtype {
+ case 20010:
+ e.handlePolicyReq(msg)
+ default:
+ panic("Unexpected message type!")
+ }
+ }
+}
+
+// Consume: This named function is a required callback for e to use the xapp interface. it is called on all received rmr messages.
+func (e *a1Receiver) Consume(rp *xapp.RMRParams) (err error) {
+ e.msgChan <- rp
+ return
+}
+
+func (e *a1Receiver) Run() {
+ // Set MDC (read: name visible in the logs)
+ xapp.Logger.SetMdc(handlerID, "0.1.0")
+
+ /* from reading the xapp frame code...
+ this SetReadyCB sets off a chain of events..
+ it sets readycb and readycbparams at the module level in xapp.go
+ nothing happens yet..
+ when the xapp is ran with` xapp.Run, this callback actually gets passed into the Rmr client which is not exposed in the xapp
+ Rmr.SetReadyCB(xappReadyCb, nil)
+ This "primes" the rmr client with it's own readycb, which is now set to this callback function
+ When the rmr client is ready, it invokes the callback
+ so basically, when rmr is ready, this function is invoked
+ I think the xapp frame code could have been greatly simplified by just passing this into the invocation of Run() and then just passing that into the rmr client init!
+ */
+ xapp.SetReadyCB(func(d interface{}) { e.rmrReady = true }, true)
+
+ // start message loop. We cannot wait for e.rmrReady here since that doesn't get populated until Run() runs.
+ go e.messageLoop()
+
+ if doQuery {
+ // we are in the query tester; kick off a loop that does that until it works
+ go e.sendQuery()
+ }
+
+ xapp.Run(e)
+}
+
+func newA1Receiver(appReady, rmrReady bool) *a1Receiver {
+ return &a1Receiver{
+ msgChan: make(chan *xapp.RMRParams),
+ rmrReady: rmrReady,
+ appReady: appReady,
+ }
+}
+
+func main() {
+
+ delay = 0
+ if d, ok := os.LookupEnv("TEST_RCV_SEC_DELAY"); ok {
+ delay, _ = strconv.Atoi(d)
+ }
+
+ handlerID = "test_receiver"
+ if hid, ok := os.LookupEnv("HANDLER_ID"); ok {
+ handlerID = hid
+ }
+
+ doQuery = false
+ if _, ok := os.LookupEnv("DO_QUERY"); ok {
+ doQuery = true
+ }
+
+ newA1Receiver(true, false).Run()
+}
diff --git a/integration_tests/testxappcode/test-config-file.yaml b/integration_tests/testxappcode/test-config-file.yaml
new file mode 100755
index 0000000..cd59770
--- /dev/null
+++ b/integration_tests/testxappcode/test-config-file.yaml
@@ -0,0 +1,38 @@
+# Copyright (c) 2019-2020 AT&T Intellectual Property.
+# Copyright (c) 2019-2020 Nokia.
+#
+# 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.
+
+"local":
+ "host": ":8080"
+"logger":
+ "level": 4
+"rmr":
+ "protPort": "tcp:4560"
+ "maxSize": 4096
+ "numWorkers": 1
+"db":
+ "host": "dbaas"
+ "port": 6379
+ "namespaces": ["sdl", "rnib"]
+"test":
+ "mode": "forwarder"
+ "mtype": 10004
+ "subId": 1111
+ "size": 100
+ "rate": 10
+ "amount": 10
+ "rounds": 1
+ "store": 0
+ "waitForAck": 0
+