###########################################################
FROM nexus3.o-ran-sc.org:10002/o-ran-sc/bldr-ubuntu18-c-go:1.9.0 as submgrcore
+ARG GOVERSION=1.14
+
+ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/go/bin:/opt/go/${GOVERSION}/bin:/root/go/bin
+
+# Update CA certificates
+RUN apt update && apt install --reinstall -y \
+ ca-certificates \
+ && \
+ update-ca-certificates
+
RUN apt update && apt install -y iputils-ping net-tools curl tcpdump gdb valgrind
WORKDIR /tmp
contain E2 subscriptions only for one E2 Node.
Subscription Manager indicates to xApp in response notification if there has happened any error or timeout. xApp can send retry based on that information but
-resending should happen after Subscription Manager has processed the previous request completely otherwise the request is rejected. If timeout happens response
-notification contains information where it happened. Timeout can happen in E2, Routing Manager and SDL interface.
+resending should happen after Subscription Manager has processed the previous request completely, otherwise xApp will get successful response for the new request
+without that the request is actually retried. If timeout happens, response notification contains information where it happened. Timeout can happen in E2, Routing
+Manager and SDL interface.
If there is need to change REPORT or INSERT type subscription then previously made subscription need to be deleted first. If there are any REPORT or INSERT
type E2 subscription which need to change frequently, it is not good idea to bundle them with other REPORT or INSERT type E2 subscriptions in the same REST
`<https://wiki.o-ran-sc.org/display/RICP/Routing+Manager+and+Subscription+Manager>`_
- * Subscription Request message
+ * REST Subscription Request message
.. image:: images/REST_Subscription_Request.png
:width: 600
- :alt: Subscription Request message
+ :alt: REST Subscription Request message
- * Subscription RESTRequest Response message
+ * REST Subscription Response message
.. image:: images/REST_Subscription_Response.png
:width: 600
- :alt: REST Subscription Request Response message
+ :alt: REST Subscription Response message
- * Subscription Request Notification message
+ * REST Subscription Notification message
.. image:: images/REST_Subscription_Notification.png
:width: 600
If values are does not accepted then send function returns "unknown error".
If failure happens when Subscription Manager validates the REST request then error is returned instantly and processing of request is
- stopped. xApp receives bad request (HTTP response code 400) response.
+ stopped. xApp receives "Bad Request" (HTTP response code 400) response.
+
+ If failure happens when xApp resends the same request including REST request id but the subscription is not found from Subscription Manager's
+ records, then xApp receives "Not Found" (HTTP response code 404) response.
If failure response is received from E2 Node then REST notification is forwarded to xApp with appropriate error cause. The notification
contains REST request id, xApp instance id and zero E2 instance id.
replace gerrit.o-ran-sc.org/r/ric-plt/sdlgo => gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.7.0
-replace gerrit.o-ran-sc.org/r/ric-plt/xapp-frame => gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.8.5
+replace gerrit.o-ran-sc.org/r/ric-plt/xapp-frame => gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.9.3
replace gerrit.o-ran-sc.org/r/com/golog => gerrit.o-ran-sc.org/r/com/golog.git v0.0.2
gerrit.o-ran-sc.org/r/ric-plt/alarm-go.git/alarm v0.5.0/go.mod h1:AdEWKtERGvOQy9ybLhyhrb9w9LLVn8i9xzTwoR5n4BY=
gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.35 h1:TGXHb4DNY8on+ej4S9VUnk2HibIC/5chDy64OE+bQBQ=
gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.35/go.mod h1:QJ1uPPZosGbhxUWpUpeM5fLqFHdnWTrVnvW2DgyOCes=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.2.1 h1:3FFbXx55BODThXfyWAiz6cPXVELXFICDQUmJi13EoxM=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.2.1/go.mod h1:QJ1uPPZosGbhxUWpUpeM5fLqFHdnWTrVnvW2DgyOCes=
gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.35 h1:tkM3yE8UzmuH4nf9TqAmiNBSuIZ2CtcMRH2eBIYIzpQ=
gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.35/go.mod h1:G+4sUBMbLfQ+RrGS65U15tKmbnP+/1b5oLTPmMfyfT4=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.2.1 h1:8Z60JRsPgcS1Ona4fEh6d0/03nLq1WHoZcNnBsni5+g=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.2.1/go.mod h1:YaQ+XEI4PcAoISxp9wUpUr2TP0J7JihpQTD0G1Lpd4A=
gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.35 h1:LcxnUUDwsCzYEISKmkjkyYfg/lnLt8ofkPiGK69vNIA=
gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.35/go.mod h1:2bSaXTpECbZieB8bMnubTqMwF3n+mMBxlTaAXvcduNg=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.2.1 h1:BG3kste8PLVTG0m8CRB/VP2tAV5JImKueBGuOsUNcR8=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.2.1/go.mod h1:zX8rW6YEsagHrRGVW5YO50Ku/Csrpzsuvblhr4DbYi4=
gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.7.0 h1:mxlBo54jxwHHFmGYzFI+fBIkOGwarQP4dx2KBxQ8ln8=
gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.7.0/go.mod h1:KCHu4JkWnw2Ro6P747wU9S2t7zxFLmBNCiYvGZo3CHo=
gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.8.3 h1:C5nhnmSZLdysSiQ7vMkpNaKrooPwiBZ79dcXWRVtZTU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
-func (c *Control) GetOrCreateRestSubscription(p *models.SubscriptionParams, md5sum string, xAppRmrEndpoint string) (*RESTSubscription, string, string, error) {
+func (c *Control) GetOrCreateRestSubscription(p *models.SubscriptionParams, md5sum string, xAppRmrEndpoint string) (*RESTSubscription, string, error) {
var restSubId string
var restSubscription *RESTSubscription
// Subscription with id in REST request does not exist
xapp.Logger.Error("%s", err.Error())
c.UpdateCounter(cRestSubFailToXapp)
- return nil, "", models.SubscriptionInstanceRejectCauseRESTSubscriptionWithGivenIDDoesNotExist, err
+ return nil, "", err
}
if !exists {
}
}
- return restSubscription, restSubId, "", nil
+ return restSubscription, restSubId, nil
}
//-------------------------------------------------------------------
err := fmt.Errorf("ClientEndpoint == nil")
xapp.Logger.Error("%v", err)
c.UpdateCounter(cRestSubFailToXapp)
- return c.GetSubscriptionResponse(models.SubscriptionInstanceRejectCauseInvalidRESTRequestMessage, err.Error(), "SUBMGR", ""), common.SubscribeBadRequestCode
+ return nil, common.SubscribeBadRequestCode
}
_, xAppRmrEndpoint, err := ConstructEndpointAddresses(*p.ClientEndpoint)
if err != nil {
xapp.Logger.Error("%s", err.Error())
c.UpdateCounter(cRestSubFailToXapp)
- return c.GetSubscriptionResponse(models.SubscriptionInstanceRejectCauseInvalidRESTRequestMessage, err.Error(), "SUBMGR", ""), common.SubscribeBadRequestCode
+ return nil, common.SubscribeBadRequestCode
}
md5sum, err := CalculateRequestMd5sum(params)
xapp.Logger.Error("Failed to generate md5sum from incoming request - %s", err.Error())
}
- restSubscription, restSubId, rejectCause, err := c.GetOrCreateRestSubscription(p, md5sum, xAppRmrEndpoint)
+ restSubscription, restSubId, err := c.GetOrCreateRestSubscription(p, md5sum, xAppRmrEndpoint)
if err != nil {
- xapp.Logger.Error("Failed to get/allocate REST subscription")
- return c.GetSubscriptionResponse(rejectCause, err.Error(), "SUBMGR", ""), common.SubscribeBadRequestCode
+ xapp.Logger.Error("Subscription with id in REST request does not exist")
+ return nil, common.SubscribeNotFoundCode
}
subResp.SubscriptionID = &restSubId
restDuplicateCtrl.DeleteLastKnownRestSubsIdBasedOnMd5sum(md5sum)
c.registry.DeleteRESTSubscription(&restSubId)
c.UpdateCounter(cRestSubFailToXapp)
- return c.GetSubscriptionResponse(models.SubscriptionInstanceRejectCauseInvalidRESTRequestMessage, err.Error(), "SUBMGR", ""), common.SubscribeBadRequestCode
+ return nil, common.SubscribeBadRequestCode
}
duplicate := restDuplicateCtrl.IsDuplicateToOngoingTransaction(restSubId, md5sum)
e2SubscriptionDirectives, err := c.GetE2SubscriptionDirectives(p)
if err != nil {
xapp.Logger.Error("%s", err)
- return c.GetSubscriptionResponse(models.SubscriptionInstanceRejectCauseInvalidRESTRequestMessage, err.Error(), "SUBMGR", ""), common.SubscribeBadRequestCode
+ return nil, common.SubscribeBadRequestCode
}
go c.processSubscriptionRequests(restSubscription, &subReqList, p.ClientEndpoint, p.Meid, &restSubId, xAppRmrEndpoint, md5sum, e2SubscriptionDirectives)
return nil, fmt.Errorf("p.E2SubscriptionDirectives.E2RetryCount out of range (0-10): %v", *p.E2SubscriptionDirectives.E2RetryCount)
}
}
- if p.E2SubscriptionDirectives.RMRRoutingNeeded == nil {
- xapp.Logger.Error("p.E2SubscriptionDirectives.RMRRoutingNeeded == nil")
- e2SubscriptionDirectives.CreateRMRRoute = true
- } else {
- e2SubscriptionDirectives.CreateRMRRoute = *p.E2SubscriptionDirectives.RMRRoutingNeeded
- }
+ e2SubscriptionDirectives.CreateRMRRoute = p.E2SubscriptionDirectives.RMRRoutingNeeded
}
xapp.Logger.Debug("e2SubscriptionDirectives.E2TimeoutTimerValue: %v", e2SubscriptionDirectives.E2TimeoutTimerValue)
xapp.Logger.Debug("e2SubscriptionDirectives.E2MaxTryCount: %v", e2SubscriptionDirectives.E2MaxTryCount)
return e2SubscriptionDirectives, nil
}
-//-------------------------------------------------------------------
-//
-//-------------------------------------------------------------------
-func (c *Control) GetSubscriptionResponse(rejectCause string, errorCause string, errorSource string, timeoutType string) *models.SubscriptionResponse {
- subResp := models.SubscriptionResponse{}
- subscriptionInstance := models.SubscriptionInstance{}
- subscriptionInstance.RejectCause = &rejectCause
- subscriptionInstance.ErrorCause = &errorCause
- subscriptionInstance.ErrorSource = &errorSource
- if timeoutType != "" {
- subscriptionInstance.TimeoutType = &timeoutType
- }
- subResp.SubscriptionInstances = append(subResp.SubscriptionInstances, &subscriptionInstance)
- xapp.Logger.Error("etSubscriptionResponse() %+v", subscriptionInstance)
-
- return &subResp
-}
-
//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
SubscriptionID: restSubId,
SubscriptionInstances: []*models.SubscriptionInstance{
&models.SubscriptionInstance{E2EventInstanceID: &e2EventInstanceID,
- ErrorCause: &errorInfo.ErrorCause,
- ErrorSource: &errorInfo.ErrorSource,
- TimeoutType: &errorInfo.TimeoutType,
+ ErrorCause: errorInfo.ErrorCause,
+ ErrorSource: errorInfo.ErrorSource,
+ TimeoutType: errorInfo.TimeoutType,
XappEventInstanceID: &xAppEventInstanceID},
},
}
SubscriptionID: restSubId,
SubscriptionInstances: []*models.SubscriptionInstance{
&models.SubscriptionInstance{E2EventInstanceID: &e2EventInstanceID,
- ErrorCause: nil,
+ ErrorCause: "",
XappEventInstanceID: &xAppEventInstanceID},
},
}
fmt.Printf(" E2RetryCount = %v\n", *p.E2SubscriptionDirectives.E2RetryCount)
}
fmt.Printf(" E2TimeoutTimerValue = %v\n", p.E2SubscriptionDirectives.E2TimeoutTimerValue)
- if p.E2SubscriptionDirectives.RMRRoutingNeeded == nil {
- fmt.Println(" RMRRoutingNeeded == nil")
- } else {
- fmt.Printf(" RMRRoutingNeeded = %v\n", *p.E2SubscriptionDirectives.RMRRoutingNeeded)
- }
+ fmt.Printf(" RMRRoutingNeeded = %v\n", p.E2SubscriptionDirectives.RMRRoutingNeeded)
}
for _, subscriptionDetail := range p.SubscriptionDetails {
if p.RANFunctionID != nil {
// Subs Create
const subReqCount int = 1
- // const e2Timeout int64 = 2
- // const e2RetryCount int64 = 2
- // const routingNeeded bool = true
// In order to force both XAPP's to create their own subscriptions, force rtmgr to block a while so that 2nd create
// gets into execution before the rtmgrg responds for the first one.
waiter := rtmgrHttp.AllocNextSleep(10, true)
params := xappConn1.GetRESTSubsReqReportParams(subReqCount)
- // params.SetSubscriptionDirectives(e2Timeout, e2RetryCount, routingNeeded)
restSubId1 := xappConn1.SendRESTSubsReq(t, params)
xappConn2.SendRESTSubsReq(t, params)
})
const subReqCount int = 1
+ const e2Timeout int64 = 2
+ const e2RetryCount int64 = 1
+ const routingNeeded bool = true
params := xappConn1.GetRESTSubsReqReportParams(subReqCount)
+ params.SetSubscriptionDirectives(e2Timeout, e2RetryCount, routingNeeded)
restSubId := xappConn1.SendRESTSubsReq(t, params)
crereq1, cremsg1 := e2termConn1.RecvSubsReq(t)
if resp.SubscriptionInstances[0].E2EventInstanceID != nil {
e2RestIds.E2SubsId = uint32(*resp.SubscriptionInstances[0].E2EventInstanceID)
}
- if resp.SubscriptionInstances[0].ErrorCause != nil {
- e2RestIds.ErrorCause = *resp.SubscriptionInstances[0].ErrorCause
- } else {
- e2RestIds.ErrorCause = "nil"
- }
- if resp.SubscriptionInstances[0].ErrorSource != nil {
- e2RestIds.ErrorSource = *resp.SubscriptionInstances[0].ErrorSource
- } else {
- e2RestIds.ErrorSource = "nil"
- }
- if resp.SubscriptionInstances[0].TimeoutType != nil {
- e2RestIds.TimeoutType = *resp.SubscriptionInstances[0].TimeoutType
- } else {
- e2RestIds.TimeoutType = "nil"
- }
+ e2RestIds.ErrorCause = resp.SubscriptionInstances[0].ErrorCause
+ e2RestIds.ErrorSource = resp.SubscriptionInstances[0].ErrorSource
+ e2RestIds.TimeoutType = resp.SubscriptionInstances[0].TimeoutType
}
}
return e2RestIds
// Swagger generated code makes checks for the values that are inserted the subscription function
// If error cause is unknown and POST is not done, the problem is in the inserted values
tc.Error("======== REST subscription request failed %s ========", err.Error())
- if resp != nil {
- tc.PrintSubscriptionInsctanceErrorInfo(resp)
- } else {
- tc.Error("Subscribe resp == nil")
- }
return ""
}
tc.subscriptionId = *resp.SubscriptionID
return *resp.SubscriptionID
}
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-func (tc *E2Stub) PrintSubscriptionInsctanceErrorInfo(resp *clientmodel.SubscriptionResponse) {
- for _, subscriptionInstance := range resp.SubscriptionInstances {
- if subscriptionInstance != nil {
- if subscriptionInstance.RejectCause != nil {
- tc.Error("subscriptionInstance.RejectCause= %s", *subscriptionInstance.RejectCause)
- }
- if subscriptionInstance.ErrorCause != nil {
- tc.Error("subscriptionInstance.ErrorCause= %s", *subscriptionInstance.ErrorCause)
- }
- if subscriptionInstance.ErrorSource != nil {
- tc.Error("subscriptionInstance.ErrorSource= %s", *subscriptionInstance.ErrorSource)
- }
- if subscriptionInstance.TimeoutType != nil {
- tc.Error("subscriptionInstance.TimeoutType = %s", *subscriptionInstance.TimeoutType)
- }
- }
- }
-}
-
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
p.SubsReqParams.E2SubscriptionDirectives = E2SubscriptionDirectives
p.SubsReqParams.E2SubscriptionDirectives.E2RetryCount = &E2RetryCount
p.SubsReqParams.E2SubscriptionDirectives.E2TimeoutTimerValue = E2TimeoutTimerValue
- p.SubsReqParams.E2SubscriptionDirectives.RMRRoutingNeeded = &RMRRoutingNeeded
+ p.SubsReqParams.E2SubscriptionDirectives.RMRRoutingNeeded = RMRRoutingNeeded
}
func (p *RESTSubsReqParams) RemoveE2SubscriptionDirectives() {
e2SubscriptionDirectives := &clientmodel.SubscriptionParamsE2SubscriptionDirectives{}
e2SubscriptionDirectives.E2TimeoutTimerValue = e2Timeout
e2SubscriptionDirectives.E2RetryCount = &e2RetryCount
- e2SubscriptionDirectives.RMRRoutingNeeded = &routingNeeded
+ e2SubscriptionDirectives.RMRRoutingNeeded = routingNeeded
p.SubsReqParams.E2SubscriptionDirectives = e2SubscriptionDirectives
}