Xapp registration/deregistration to RIC 54/5354/4 v0.7.0
authorwahidw <abdulwahid.w@nokia.com>
Tue, 15 Dec 2020 12:17:09 +0000 (12:17 +0000)
committerwahidw <abdulwahid.w@nokia.com>
Thu, 17 Dec 2020 00:14:23 +0000 (00:14 +0000)
Signed-off-by: wahidw <abdulwahid.w@nokia.com>
Change-Id: I62104203e6f2de9359a2ab184966395f4c758b48

14 files changed:
pkg/models/config_metadata.go [new file with mode: 0644]
pkg/models/x_app_config.go [new file with mode: 0644]
pkg/models/xapp_config_list.go [new file with mode: 0644]
pkg/restapi/doc.go
pkg/restapi/embedded_spec.go
pkg/restapi/operations/xapp/get_xapp_config_list.go [new file with mode: 0644]
pkg/restapi/operations/xapp/get_xapp_config_list_parameters.go [new file with mode: 0644]
pkg/restapi/operations/xapp/get_xapp_config_list_responses.go [new file with mode: 0644]
pkg/restapi/operations/xapp/get_xapp_config_list_urlbuilder.go [new file with mode: 0644]
pkg/restapi/operations/xapp_framework_api.go
pkg/xapp/restapi.go
pkg/xapp/subscription.go
pkg/xapp/xapp.go
pkg/xapp/xapp_test.go

diff --git a/pkg/models/config_metadata.go b/pkg/models/config_metadata.go
new file mode 100644 (file)
index 0000000..f564287
--- /dev/null
@@ -0,0 +1,121 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+package models
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+       "encoding/json"
+
+       strfmt "github.com/go-openapi/strfmt"
+
+       "github.com/go-openapi/errors"
+       "github.com/go-openapi/swag"
+       "github.com/go-openapi/validate"
+)
+
+// ConfigMetadata config metadata
+// swagger:model ConfigMetadata
+type ConfigMetadata struct {
+
+       // The type of the content
+       // Required: true
+       // Enum: [json xml other]
+       ConfigType *string `json:"configType"`
+
+       // Name of the xApp
+       // Required: true
+       XappName *string `json:"xappName"`
+}
+
+// Validate validates this config metadata
+func (m *ConfigMetadata) Validate(formats strfmt.Registry) error {
+       var res []error
+
+       if err := m.validateConfigType(formats); err != nil {
+               res = append(res, err)
+       }
+
+       if err := m.validateXappName(formats); err != nil {
+               res = append(res, err)
+       }
+
+       if len(res) > 0 {
+               return errors.CompositeValidationError(res...)
+       }
+       return nil
+}
+
+var configMetadataTypeConfigTypePropEnum []interface{}
+
+func init() {
+       var res []string
+       if err := json.Unmarshal([]byte(`["json","xml","other"]`), &res); err != nil {
+               panic(err)
+       }
+       for _, v := range res {
+               configMetadataTypeConfigTypePropEnum = append(configMetadataTypeConfigTypePropEnum, v)
+       }
+}
+
+const (
+
+       // ConfigMetadataConfigTypeJSON captures enum value "json"
+       ConfigMetadataConfigTypeJSON string = "json"
+
+       // ConfigMetadataConfigTypeXML captures enum value "xml"
+       ConfigMetadataConfigTypeXML string = "xml"
+
+       // ConfigMetadataConfigTypeOther captures enum value "other"
+       ConfigMetadataConfigTypeOther string = "other"
+)
+
+// prop value enum
+func (m *ConfigMetadata) validateConfigTypeEnum(path, location string, value string) error {
+       if err := validate.Enum(path, location, value, configMetadataTypeConfigTypePropEnum); err != nil {
+               return err
+       }
+       return nil
+}
+
+func (m *ConfigMetadata) validateConfigType(formats strfmt.Registry) error {
+
+       if err := validate.Required("configType", "body", m.ConfigType); err != nil {
+               return err
+       }
+
+       // value enum
+       if err := m.validateConfigTypeEnum("configType", "body", *m.ConfigType); err != nil {
+               return err
+       }
+
+       return nil
+}
+
+func (m *ConfigMetadata) validateXappName(formats strfmt.Registry) error {
+
+       if err := validate.Required("xappName", "body", m.XappName); err != nil {
+               return err
+       }
+
+       return nil
+}
+
+// MarshalBinary interface implementation
+func (m *ConfigMetadata) MarshalBinary() ([]byte, error) {
+       if m == nil {
+               return nil, nil
+       }
+       return swag.WriteJSON(m)
+}
+
+// UnmarshalBinary interface implementation
+func (m *ConfigMetadata) UnmarshalBinary(b []byte) error {
+       var res ConfigMetadata
+       if err := swag.ReadJSON(b, &res); err != nil {
+               return err
+       }
+       *m = res
+       return nil
+}
diff --git a/pkg/models/x_app_config.go b/pkg/models/x_app_config.go
new file mode 100644 (file)
index 0000000..076e314
--- /dev/null
@@ -0,0 +1,90 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+package models
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+       strfmt "github.com/go-openapi/strfmt"
+
+       "github.com/go-openapi/errors"
+       "github.com/go-openapi/swag"
+       "github.com/go-openapi/validate"
+)
+
+// XAppConfig x app config
+// swagger:model XAppConfig
+type XAppConfig struct {
+
+       // Configuration in JSON format
+       // Required: true
+       Config interface{} `json:"config"`
+
+       // metadata
+       // Required: true
+       Metadata *ConfigMetadata `json:"metadata"`
+}
+
+// Validate validates this x app config
+func (m *XAppConfig) Validate(formats strfmt.Registry) error {
+       var res []error
+
+       if err := m.validateConfig(formats); err != nil {
+               res = append(res, err)
+       }
+
+       if err := m.validateMetadata(formats); err != nil {
+               res = append(res, err)
+       }
+
+       if len(res) > 0 {
+               return errors.CompositeValidationError(res...)
+       }
+       return nil
+}
+
+func (m *XAppConfig) validateConfig(formats strfmt.Registry) error {
+
+       if err := validate.Required("config", "body", m.Config); err != nil {
+               return err
+       }
+
+       return nil
+}
+
+func (m *XAppConfig) validateMetadata(formats strfmt.Registry) error {
+
+       if err := validate.Required("metadata", "body", m.Metadata); err != nil {
+               return err
+       }
+
+       if m.Metadata != nil {
+               if err := m.Metadata.Validate(formats); err != nil {
+                       if ve, ok := err.(*errors.Validation); ok {
+                               return ve.ValidateName("metadata")
+                       }
+                       return err
+               }
+       }
+
+       return nil
+}
+
+// MarshalBinary interface implementation
+func (m *XAppConfig) MarshalBinary() ([]byte, error) {
+       if m == nil {
+               return nil, nil
+       }
+       return swag.WriteJSON(m)
+}
+
+// UnmarshalBinary interface implementation
+func (m *XAppConfig) UnmarshalBinary(b []byte) error {
+       var res XAppConfig
+       if err := swag.ReadJSON(b, &res); err != nil {
+               return err
+       }
+       *m = res
+       return nil
+}
diff --git a/pkg/models/xapp_config_list.go b/pkg/models/xapp_config_list.go
new file mode 100644 (file)
index 0000000..e57ed02
--- /dev/null
@@ -0,0 +1,45 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+package models
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+       "strconv"
+
+       strfmt "github.com/go-openapi/strfmt"
+
+       "github.com/go-openapi/errors"
+       "github.com/go-openapi/swag"
+)
+
+// XappConfigList xapp config list
+// swagger:model XappConfigList
+type XappConfigList []*XAppConfig
+
+// Validate validates this xapp config list
+func (m XappConfigList) Validate(formats strfmt.Registry) error {
+       var res []error
+
+       for i := 0; i < len(m); i++ {
+               if swag.IsZero(m[i]) { // not required
+                       continue
+               }
+
+               if m[i] != nil {
+                       if err := m[i].Validate(formats); err != nil {
+                               if ve, ok := err.(*errors.Validation); ok {
+                                       return ve.ValidateName(strconv.Itoa(i))
+                               }
+                               return err
+                       }
+               }
+
+       }
+
+       if len(res) > 0 {
+               return errors.CompositeValidationError(res...)
+       }
+       return nil
+}
index 8cc5aad..c73c1aa 100644 (file)
@@ -17,6 +17,7 @@ This is the initial REST API for RIC subscription
 
     Produces:
     - application/json
+    - application/xml
 
 swagger:meta
 */
index 8cb57e1..dd67843 100644 (file)
@@ -34,6 +34,30 @@ func init() {
   "host": "hostname",
   "basePath": "/ric/v1",
   "paths": {
+    "/config": {
+      "get": {
+        "produces": [
+          "application/json",
+          "application/xml"
+        ],
+        "tags": [
+          "xapp"
+        ],
+        "summary": "Returns the configuration of all xapps",
+        "operationId": "getXappConfigList",
+        "responses": {
+          "200": {
+            "description": "successful query of xApp config",
+            "schema": {
+              "$ref": "#/definitions/XappConfigList"
+            }
+          },
+          "500": {
+            "description": "Internal error"
+          }
+        }
+      }
+    },
     "/subscriptions": {
       "get": {
         "produces": [
@@ -187,6 +211,28 @@ func init() {
         }
       }
     },
+    "ConfigMetadata": {
+      "type": "object",
+      "required": [
+        "xappName",
+        "configType"
+      ],
+      "properties": {
+        "configType": {
+          "description": "The type of the content",
+          "type": "string",
+          "enum": [
+            "json",
+            "xml",
+            "other"
+          ]
+        },
+        "xappName": {
+          "description": "Name of the xApp",
+          "type": "string"
+        }
+      }
+    },
     "EventTrigger": {
       "type": "object",
       "properties": {
@@ -443,6 +489,28 @@ func init() {
         "policy",
         "report"
       ]
+    },
+    "XAppConfig": {
+      "type": "object",
+      "required": [
+        "metadata",
+        "config"
+      ],
+      "properties": {
+        "config": {
+          "description": "Configuration in JSON format",
+          "type": "object"
+        },
+        "metadata": {
+          "$ref": "#/definitions/ConfigMetadata"
+        }
+      }
+    },
+    "XappConfigList": {
+      "type": "array",
+      "items": {
+        "$ref": "#/definitions/XAppConfig"
+      }
     }
   }
 }`))
@@ -463,6 +531,30 @@ func init() {
   "host": "hostname",
   "basePath": "/ric/v1",
   "paths": {
+    "/config": {
+      "get": {
+        "produces": [
+          "application/json",
+          "application/xml"
+        ],
+        "tags": [
+          "xapp"
+        ],
+        "summary": "Returns the configuration of all xapps",
+        "operationId": "getXappConfigList",
+        "responses": {
+          "200": {
+            "description": "successful query of xApp config",
+            "schema": {
+              "$ref": "#/definitions/XappConfigList"
+            }
+          },
+          "500": {
+            "description": "Internal error"
+          }
+        }
+      }
+    },
     "/subscriptions": {
       "get": {
         "produces": [
@@ -616,6 +708,28 @@ func init() {
         }
       }
     },
+    "ConfigMetadata": {
+      "type": "object",
+      "required": [
+        "xappName",
+        "configType"
+      ],
+      "properties": {
+        "configType": {
+          "description": "The type of the content",
+          "type": "string",
+          "enum": [
+            "json",
+            "xml",
+            "other"
+          ]
+        },
+        "xappName": {
+          "description": "Name of the xApp",
+          "type": "string"
+        }
+      }
+    },
     "EventTrigger": {
       "type": "object",
       "properties": {
@@ -872,6 +986,28 @@ func init() {
         "policy",
         "report"
       ]
+    },
+    "XAppConfig": {
+      "type": "object",
+      "required": [
+        "metadata",
+        "config"
+      ],
+      "properties": {
+        "config": {
+          "description": "Configuration in JSON format",
+          "type": "object"
+        },
+        "metadata": {
+          "$ref": "#/definitions/ConfigMetadata"
+        }
+      }
+    },
+    "XappConfigList": {
+      "type": "array",
+      "items": {
+        "$ref": "#/definitions/XAppConfig"
+      }
     }
   }
 }`))
diff --git a/pkg/restapi/operations/xapp/get_xapp_config_list.go b/pkg/restapi/operations/xapp/get_xapp_config_list.go
new file mode 100644 (file)
index 0000000..9fc02d3
--- /dev/null
@@ -0,0 +1,58 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+package xapp
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the generate command
+
+import (
+       "net/http"
+
+       middleware "github.com/go-openapi/runtime/middleware"
+)
+
+// GetXappConfigListHandlerFunc turns a function with the right signature into a get xapp config list handler
+type GetXappConfigListHandlerFunc func(GetXappConfigListParams) middleware.Responder
+
+// Handle executing the request and returning a response
+func (fn GetXappConfigListHandlerFunc) Handle(params GetXappConfigListParams) middleware.Responder {
+       return fn(params)
+}
+
+// GetXappConfigListHandler interface for that can handle valid get xapp config list params
+type GetXappConfigListHandler interface {
+       Handle(GetXappConfigListParams) middleware.Responder
+}
+
+// NewGetXappConfigList creates a new http.Handler for the get xapp config list operation
+func NewGetXappConfigList(ctx *middleware.Context, handler GetXappConfigListHandler) *GetXappConfigList {
+       return &GetXappConfigList{Context: ctx, Handler: handler}
+}
+
+/*GetXappConfigList swagger:route GET /config xapp getXappConfigList
+
+Returns the configuration of all xapps
+
+*/
+type GetXappConfigList struct {
+       Context *middleware.Context
+       Handler GetXappConfigListHandler
+}
+
+func (o *GetXappConfigList) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
+       route, rCtx, _ := o.Context.RouteInfo(r)
+       if rCtx != nil {
+               r = rCtx
+       }
+       var Params = NewGetXappConfigListParams()
+
+       if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
+               o.Context.Respond(rw, r, route.Produces, route, err)
+               return
+       }
+
+       res := o.Handler.Handle(Params) // actually handle the request
+
+       o.Context.Respond(rw, r, route.Produces, route, res)
+
+}
diff --git a/pkg/restapi/operations/xapp/get_xapp_config_list_parameters.go b/pkg/restapi/operations/xapp/get_xapp_config_list_parameters.go
new file mode 100644 (file)
index 0000000..0339c0f
--- /dev/null
@@ -0,0 +1,45 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+package xapp
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+       "net/http"
+
+       "github.com/go-openapi/errors"
+       "github.com/go-openapi/runtime/middleware"
+)
+
+// NewGetXappConfigListParams creates a new GetXappConfigListParams object
+// no default values defined in spec.
+func NewGetXappConfigListParams() GetXappConfigListParams {
+
+       return GetXappConfigListParams{}
+}
+
+// GetXappConfigListParams contains all the bound params for the get xapp config list operation
+// typically these are obtained from a http.Request
+//
+// swagger:parameters getXappConfigList
+type GetXappConfigListParams struct {
+
+       // HTTP Request Object
+       HTTPRequest *http.Request `json:"-"`
+}
+
+// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
+// for simple values it will use straight method calls.
+//
+// To ensure default values, the struct must have been initialized with NewGetXappConfigListParams() beforehand.
+func (o *GetXappConfigListParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
+       var res []error
+
+       o.HTTPRequest = r
+
+       if len(res) > 0 {
+               return errors.CompositeValidationError(res...)
+       }
+       return nil
+}
diff --git a/pkg/restapi/operations/xapp/get_xapp_config_list_responses.go b/pkg/restapi/operations/xapp/get_xapp_config_list_responses.go
new file mode 100644 (file)
index 0000000..bddbfea
--- /dev/null
@@ -0,0 +1,85 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+package xapp
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+       "net/http"
+
+       "github.com/go-openapi/runtime"
+
+       models "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/models"
+)
+
+// GetXappConfigListOKCode is the HTTP code returned for type GetXappConfigListOK
+const GetXappConfigListOKCode int = 200
+
+/*GetXappConfigListOK successful query of xApp config
+
+swagger:response getXappConfigListOK
+*/
+type GetXappConfigListOK struct {
+
+       /*
+         In: Body
+       */
+       Payload models.XappConfigList `json:"body,omitempty"`
+}
+
+// NewGetXappConfigListOK creates GetXappConfigListOK with default headers values
+func NewGetXappConfigListOK() *GetXappConfigListOK {
+
+       return &GetXappConfigListOK{}
+}
+
+// WithPayload adds the payload to the get xapp config list o k response
+func (o *GetXappConfigListOK) WithPayload(payload models.XappConfigList) *GetXappConfigListOK {
+       o.Payload = payload
+       return o
+}
+
+// SetPayload sets the payload to the get xapp config list o k response
+func (o *GetXappConfigListOK) SetPayload(payload models.XappConfigList) {
+       o.Payload = payload
+}
+
+// WriteResponse to the client
+func (o *GetXappConfigListOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
+
+       rw.WriteHeader(200)
+       payload := o.Payload
+       if payload == nil {
+               // return empty array
+               payload = models.XappConfigList{}
+       }
+
+       if err := producer.Produce(rw, payload); err != nil {
+               panic(err) // let the recovery middleware deal with this
+       }
+}
+
+// GetXappConfigListInternalServerErrorCode is the HTTP code returned for type GetXappConfigListInternalServerError
+const GetXappConfigListInternalServerErrorCode int = 500
+
+/*GetXappConfigListInternalServerError Internal error
+
+swagger:response getXappConfigListInternalServerError
+*/
+type GetXappConfigListInternalServerError struct {
+}
+
+// NewGetXappConfigListInternalServerError creates GetXappConfigListInternalServerError with default headers values
+func NewGetXappConfigListInternalServerError() *GetXappConfigListInternalServerError {
+
+       return &GetXappConfigListInternalServerError{}
+}
+
+// WriteResponse to the client
+func (o *GetXappConfigListInternalServerError) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
+
+       rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
+
+       rw.WriteHeader(500)
+}
diff --git a/pkg/restapi/operations/xapp/get_xapp_config_list_urlbuilder.go b/pkg/restapi/operations/xapp/get_xapp_config_list_urlbuilder.go
new file mode 100644 (file)
index 0000000..6c0df06
--- /dev/null
@@ -0,0 +1,87 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+package xapp
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the generate command
+
+import (
+       "errors"
+       "net/url"
+       golangswaggerpaths "path"
+)
+
+// GetXappConfigListURL generates an URL for the get xapp config list operation
+type GetXappConfigListURL struct {
+       _basePath string
+}
+
+// WithBasePath sets the base path for this url builder, only required when it's different from the
+// base path specified in the swagger spec.
+// When the value of the base path is an empty string
+func (o *GetXappConfigListURL) WithBasePath(bp string) *GetXappConfigListURL {
+       o.SetBasePath(bp)
+       return o
+}
+
+// SetBasePath sets the base path for this url builder, only required when it's different from the
+// base path specified in the swagger spec.
+// When the value of the base path is an empty string
+func (o *GetXappConfigListURL) SetBasePath(bp string) {
+       o._basePath = bp
+}
+
+// Build a url path and query string
+func (o *GetXappConfigListURL) Build() (*url.URL, error) {
+       var _result url.URL
+
+       var _path = "/config"
+
+       _basePath := o._basePath
+       if _basePath == "" {
+               _basePath = "/ric/v1"
+       }
+       _result.Path = golangswaggerpaths.Join(_basePath, _path)
+
+       return &_result, nil
+}
+
+// Must is a helper function to panic when the url builder returns an error
+func (o *GetXappConfigListURL) Must(u *url.URL, err error) *url.URL {
+       if err != nil {
+               panic(err)
+       }
+       if u == nil {
+               panic("url can't be nil")
+       }
+       return u
+}
+
+// String returns the string representation of the path with query string
+func (o *GetXappConfigListURL) String() string {
+       return o.Must(o.Build()).String()
+}
+
+// BuildFull builds a full url with scheme, host, path and query string
+func (o *GetXappConfigListURL) BuildFull(scheme, host string) (*url.URL, error) {
+       if scheme == "" {
+               return nil, errors.New("scheme is required for a full url on GetXappConfigListURL")
+       }
+       if host == "" {
+               return nil, errors.New("host is required for a full url on GetXappConfigListURL")
+       }
+
+       base, err := o.Build()
+       if err != nil {
+               return nil, err
+       }
+
+       base.Scheme = scheme
+       base.Host = host
+       return base, nil
+}
+
+// StringFull returns the string representation of a complete url
+func (o *GetXappConfigListURL) StringFull(scheme, host string) string {
+       return o.Must(o.BuildFull(scheme, host)).String()
+}
index 10da039..c2ef01b 100644 (file)
@@ -23,6 +23,7 @@ import (
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/restapi/operations/policy"
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/restapi/operations/query"
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/restapi/operations/report"
+       "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/restapi/operations/xapp"
 )
 
 // NewXappFrameworkAPI creates a new XappFramework instance
@@ -42,12 +43,16 @@ func NewXappFrameworkAPI(spec *loads.Document) *XappFrameworkAPI {
                BearerAuthenticator: security.BearerAuth,
                JSONConsumer:        runtime.JSONConsumer(),
                JSONProducer:        runtime.JSONProducer(),
+               XMLProducer:         runtime.XMLProducer(),
                CommonUnsubscribeHandler: common.UnsubscribeHandlerFunc(func(params common.UnsubscribeParams) middleware.Responder {
                        return middleware.NotImplemented("operation CommonUnsubscribe has not yet been implemented")
                }),
                QueryGetAllSubscriptionsHandler: query.GetAllSubscriptionsHandlerFunc(func(params query.GetAllSubscriptionsParams) middleware.Responder {
                        return middleware.NotImplemented("operation QueryGetAllSubscriptions has not yet been implemented")
                }),
+               XappGetXappConfigListHandler: xapp.GetXappConfigListHandlerFunc(func(params xapp.GetXappConfigListParams) middleware.Responder {
+                       return middleware.NotImplemented("operation XappGetXappConfigList has not yet been implemented")
+               }),
                PolicySubscribePolicyHandler: policy.SubscribePolicyHandlerFunc(func(params policy.SubscribePolicyParams) middleware.Responder {
                        return middleware.NotImplemented("operation PolicySubscribePolicy has not yet been implemented")
                }),
@@ -84,11 +89,15 @@ type XappFrameworkAPI struct {
 
        // JSONProducer registers a producer for a "application/json" mime type
        JSONProducer runtime.Producer
+       // XMLProducer registers a producer for a "application/xml" mime type
+       XMLProducer runtime.Producer
 
        // CommonUnsubscribeHandler sets the operation handler for the unsubscribe operation
        CommonUnsubscribeHandler common.UnsubscribeHandler
        // QueryGetAllSubscriptionsHandler sets the operation handler for the get all subscriptions operation
        QueryGetAllSubscriptionsHandler query.GetAllSubscriptionsHandler
+       // XappGetXappConfigListHandler sets the operation handler for the get xapp config list operation
+       XappGetXappConfigListHandler xapp.GetXappConfigListHandler
        // PolicySubscribePolicyHandler sets the operation handler for the subscribe policy operation
        PolicySubscribePolicyHandler policy.SubscribePolicyHandler
        // ReportSubscribeReportHandler sets the operation handler for the subscribe report operation
@@ -156,6 +165,10 @@ func (o *XappFrameworkAPI) Validate() error {
                unregistered = append(unregistered, "JSONProducer")
        }
 
+       if o.XMLProducer == nil {
+               unregistered = append(unregistered, "XMLProducer")
+       }
+
        if o.CommonUnsubscribeHandler == nil {
                unregistered = append(unregistered, "common.UnsubscribeHandler")
        }
@@ -164,6 +177,10 @@ func (o *XappFrameworkAPI) Validate() error {
                unregistered = append(unregistered, "query.GetAllSubscriptionsHandler")
        }
 
+       if o.XappGetXappConfigListHandler == nil {
+               unregistered = append(unregistered, "xapp.GetXappConfigListHandler")
+       }
+
        if o.PolicySubscribePolicyHandler == nil {
                unregistered = append(unregistered, "policy.SubscribePolicyHandler")
        }
@@ -228,6 +245,9 @@ func (o *XappFrameworkAPI) ProducersFor(mediaTypes []string) map[string]runtime.
                case "application/json":
                        result["application/json"] = o.JSONProducer
 
+               case "application/xml":
+                       result["application/xml"] = o.XMLProducer
+
                }
 
                if p, ok := o.customProducers[mt]; ok {
@@ -280,6 +300,11 @@ func (o *XappFrameworkAPI) initHandlerCache() {
        }
        o.handlers["GET"]["/subscriptions"] = query.NewGetAllSubscriptions(o.context, o.QueryGetAllSubscriptionsHandler)
 
+       if o.handlers["GET"] == nil {
+               o.handlers["GET"] = make(map[string]http.Handler)
+       }
+       o.handlers["GET"]["/config"] = xapp.NewGetXappConfigList(o.context, o.XappGetXappConfigListHandler)
+
        if o.handlers["POST"] == nil {
                o.handlers["POST"] = make(map[string]http.Handler)
        }
index 6562dc5..46e81f6 100755 (executable)
@@ -22,14 +22,19 @@ package xapp
 import (
        "encoding/json"
        "github.com/gorilla/mux"
+       "github.com/spf13/viper"
        "io/ioutil"
        "net/http"
+       "os"
+
+       "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/models"
 )
 
 const (
-       ReadyURL  = "/ric/v1/health/ready"
-       AliveURL  = "/ric/v1/health/alive"
-       ConfigURL = "/ric/v1/cm/{name}"
+       ReadyURL     = "/ric/v1/health/ready"
+       AliveURL     = "/ric/v1/health/alive"
+       ConfigURL    = "/ric/v1/cm/{name}"
+       AppConfigURL = "/ric/v1/config"
 )
 
 type StatusCb func() bool
@@ -49,6 +54,7 @@ func NewRouter() *Router {
        r.InjectRoute(ReadyURL, readyHandler, "GET")
        r.InjectRoute(AliveURL, aliveHandler, "GET")
        r.InjectRoute(ConfigURL, configHandler, "POST")
+       r.InjectRoute(AppConfigURL, appconfigHandler, "GET")
 
        return r
 }
@@ -130,3 +136,36 @@ func respondWithJSON(w http.ResponseWriter, code int, payload interface{}) {
                w.Write(response)
        }
 }
+
+func appconfigHandler(w http.ResponseWriter, r *http.Request) {
+
+       Logger.Info("Inside appconfigHandler")
+
+       var appconfig models.XappConfigList
+       var metadata models.ConfigMetadata
+       var xappconfig models.XAppConfig
+       name := viper.GetString("name")
+       configtype := "json"
+       metadata.XappName = &name
+       metadata.ConfigType = &configtype
+
+       configFile, err := os.Open("/opt/ric/config/config-file.json")
+       if err != nil {
+               Logger.Error("Cannot open config file: %v", err)
+               respondWithJSON(w, http.StatusInternalServerError, nil)
+               // return nil,errors.New("Could Not parse the config file")
+       }
+
+       body, err := ioutil.ReadAll(configFile)
+
+       defer configFile.Close()
+
+       xappconfig.Metadata = &metadata
+       xappconfig.Config = string(body)
+
+       appconfig = append(appconfig, &xappconfig)
+
+       respondWithJSON(w, http.StatusOK, appconfig)
+
+       //return appconfig,nil
+}
index 4ecc262..bf140c4 100755 (executable)
@@ -33,6 +33,7 @@ import (
        "net/http"
        "os"
        "time"
+       //"errors"
 
        apiclient "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/clientapi"
        apicommon "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/clientapi/common"
@@ -47,6 +48,7 @@ import (
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/restapi/operations/policy"
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/restapi/operations/query"
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/restapi/operations/report"
+       //"gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/restapi/operations/xapp"
 )
 
 type SubscriptionHandler func(models.SubscriptionType, interface{}) (*models.SubscriptionResponse, error)
@@ -149,6 +151,16 @@ func (r *Subscriber) Listen(createSubscription SubscriptionHandler, getSubscript
                        return common.NewUnsubscribeInternalServerError()
                })
 
+       // XApp: Get Config
+       /*api.XappGetXappConfigListHandler = xapp.GetXappConfigListHandlerFunc(
+                       func(p xapp.GetXappConfigListParams) middleware.Responder {
+                   Logger.Info("Hitting xapp config")
+                               if resp,err := r.getXappConfig(); err == nil {
+                                       return xapp.NewGetXappConfigListOK().WithPayload(resp)
+                               }
+                               return xapp.NewGetXappConfigListInternalServerError()
+                   })*/
+
        server := restapi.NewServer(api)
        defer server.Shutdown()
        server.Host = r.localAddr
@@ -262,3 +274,32 @@ func (r *Subscriber) QuerySubscriptions() (models.SubscriptionList, error) {
 func (r *Subscriber) CreateTransport() *apiclient.RICSubscription {
        return apiclient.New(httptransport.New(r.remoteHost, r.remoteUrl, r.remoteProt), strfmt.Default)
 }
+
+/*func (r *Subscriber) getXappConfig() (appconfig models.XappConfigList, err error) {
+
+    Logger.Error("Inside getXappConfig")
+
+               var metadata models.ConfigMetadata
+        var xappconfig models.XAppConfig
+        name := viper.GetString("name")
+        configtype := "json"
+               metadata.XappName = &name
+               metadata.ConfigType = &configtype
+
+        configFile, err := os.Open("/opt/ric/config/config-file.json")
+        if err != nil {
+                Logger.Error("Cannot open config file: %v", err)
+                return nil,errors.New("Could Not parse the config file")
+        }
+
+        body, err := ioutil.ReadAll(configFile)
+
+        defer configFile.Close()
+
+               xappconfig.Metadata = &metadata
+               xappconfig.Config = body
+
+        appconfig = append(appconfig,&xappconfig)
+
+               return appconfig,nil
+}*/
index 1ab7ee0..2bf7799 100755 (executable)
 package xapp
 
 import (
+       "bytes"
+       "encoding/json"
        "fmt"
        "github.com/spf13/viper"
+       "io/ioutil"
        "net/http"
        "os"
        "os/signal"
+       "strings"
        "sync/atomic"
        "syscall"
        "time"
@@ -67,6 +71,140 @@ func XappReadyCb(params interface{}) {
        }
 }
 
+func xappShutdownCb() {
+       SendDeregistermsg()
+       Logger.Info("Wait for xapp to get unregistered")
+       time.Sleep(10 * time.Second)
+}
+
+func registerxapp() {
+       var (
+               retries int = 10
+       )
+       for retries > 0 {
+               name, _ := os.Hostname()
+               httpservicename := "SERVICE_RICXAPP_" + strings.ToUpper(name) + "_HTTP_PORT"
+               httpendpoint := os.Getenv(strings.Replace(httpservicename, "-", "_", -1))
+               urlString := strings.Split(httpendpoint, "//")
+               // Added this check to make UT pass
+               if urlString[0] == "" {
+                       return
+               }
+               resp, err := http.Get(fmt.Sprintf("http://%s/ric/v1/health/ready", urlString[1]))
+               retries -= 1
+               time.Sleep(5 * time.Second)
+               if err != nil {
+                       Logger.Error("Error in health check: %v", err)
+               }
+               if err == nil {
+                       retries -= 10
+                       Logger.Info("Health Probe Success with resp.StatusCode is %v", resp.StatusCode)
+                       if resp.StatusCode >= 200 && resp.StatusCode <= 299 {
+                               go SendRegistermsg()
+                       }
+               } else {
+                       Logger.Info("Health Probe failed, retrying...")
+               }
+       }
+}
+
+func SendRegistermsg() {
+       name, _ := os.Hostname()
+       xappname := viper.GetString("name")
+       xappversion := viper.GetString("version")
+       appnamespace := os.Getenv("APP_NAMESPACE")
+       if appnamespace == "" {
+               appnamespace = "ricxapp"
+       }
+       httpservicename := "SERVICE_" + strings.ToUpper(appnamespace) + "_" + strings.ToUpper(name) + "_HTTP_PORT"
+       rmrservicename := "SERVICE_" + strings.ToUpper(appnamespace) + "_" + strings.ToUpper(name) + "_RMR_PORT"
+       httpendpointstr := os.Getenv(strings.Replace(httpservicename, "-", "_", -1))
+       rmrendpointstr := os.Getenv(strings.Replace(rmrservicename, "-", "_", -1))
+       httpendpoint := strings.Split(httpendpointstr, "//")
+       rmrendpoint := strings.Split(rmrendpointstr, "//")
+       if httpendpoint[0] == "" || rmrendpoint[0] == "" {
+               return
+       }
+
+       pltnamespace := os.Getenv("PLT_NAMESPACE")
+       if pltnamespace == "" {
+               pltnamespace = "ricplt"
+       }
+
+       configpath := "/ric/v1/config"
+
+       requestBody, err := json.Marshal(map[string]string{
+               "appName":         name,
+               "httpEndpoint":    httpendpoint[1],
+               "rmrEndpoint":     rmrendpoint[1],
+               "appInstanceName": xappname,
+               "appVersion":      xappversion,
+               "configPath":      configpath,
+       })
+
+       if err != nil {
+               Logger.Info("Error while compiling request to appmgr: %v", err)
+       } else {
+               url := fmt.Sprintf("http://service-%v-appmgr-http.%v:8080/ric/v1/register", pltnamespace, pltnamespace)
+               resp, err := http.Post(url, "application/json", bytes.NewBuffer(requestBody))
+               Logger.Info(" Resp is %v", resp)
+               if err != nil {
+                       Logger.Info("Error  compiling request to appmgr: %v", err)
+               }
+               Logger.Info("Registering request sent. Response received is :%v", resp)
+
+               if resp != nil {
+                       body, err := ioutil.ReadAll(resp.Body)
+                       Logger.Info("Post body is %v", resp.Body)
+                       if err != nil {
+                               Logger.Info("rsp: Error  compiling request to appmgr: %v", string(body))
+                       }
+                       defer resp.Body.Close()
+               }
+       }
+}
+
+func SendDeregistermsg() {
+
+       name, _ := os.Hostname()
+       xappname := viper.GetString("name")
+
+       appnamespace := os.Getenv("APP_NAMESPACE")
+       if appnamespace == "" {
+               appnamespace = "ricxapp"
+       }
+       pltnamespace := os.Getenv("PLT_NAMESPACE")
+       if pltnamespace == "" {
+               pltnamespace = "ricplt"
+       }
+
+       requestBody, err := json.Marshal(map[string]string{
+               "appName":         name,
+               "appInstanceName": xappname,
+       })
+
+       if err != nil {
+               Logger.Info("Error while compiling request to appmgr: %v", err)
+       } else {
+               url := fmt.Sprintf("http://service-%v-appmgr-http.%v:8080/ric/v1/deregister", pltnamespace, pltnamespace)
+               resp, err := http.Post(url, "application/json", bytes.NewBuffer(requestBody))
+               Logger.Info(" Resp is %v", resp)
+               if err != nil {
+                       Logger.Info("Error  compiling request to appmgr: %v", err)
+               }
+               Logger.Info("Deregistering request sent. Response received is :%v", resp)
+
+               if resp != nil {
+                       body, err := ioutil.ReadAll(resp.Body)
+                       Logger.Info("Post body is %v", resp.Body)
+                       if err != nil {
+                               Logger.Info("rsp: Error  compiling request to appmgr: %v", string(body))
+                       }
+                       defer resp.Body.Close()
+               }
+       }
+}
+
 func SetShutdownCB(cb ShutdownCB) {
        shutdownCb = cb
 }
@@ -143,13 +281,14 @@ func init() {
 func RunWithParams(c MessageConsumer, sdlcheck bool) {
        Rmr = NewRMRClient()
        Rmr.SetReadyCB(XappReadyCb, nil)
-
+       SetShutdownCB(xappShutdownCb)
        host := fmt.Sprintf(":%d", GetPortData("http").Port)
        go http.ListenAndServe(host, Resource.router)
        Logger.Info(fmt.Sprintf("Xapp started, listening on: %s", host))
        if sdlcheck {
                Sdl.TestConnection()
        }
+       go registerxapp()
        Rmr.Start(c)
 }
 
index 04bbbb8..173b57f 100755 (executable)
 package xapp
 
 import (
+       "bytes"
        "github.com/gorilla/mux"
        "github.com/spf13/viper"
+       "github.com/stretchr/testify/assert"
        "net/http"
        "net/http/httptest"
-       "github.com/stretchr/testify/assert"
        "os"
        "strings"
        "testing"
        "time"
-       "bytes"
 )
 
 //var _ = func() bool {
@@ -118,8 +118,8 @@ func TestMessagesReceivedSuccessfully(t *testing.T) {
                params.Payload = []byte{1, 2, 3, 4, 5, 6}
                params.Meid = &RMRMeid{PlmnID: "1234", EnbID: "7788", RanName: "RanName-1234"}
                params.Xid = "TestXID"
-               
-               if i % 2 == 0 {
+
+               if i%2 == 0 {
                        Rmr.SendMsg(params)
                } else {
                        Rmr.SendWithRetry(params, false, 1)
@@ -332,11 +332,11 @@ func TestAddConfigChangeListener(t *testing.T) {
 
 func TestConfigAccess(t *testing.T) {
        Logger.Info("CASE: AddConfigChangeListener")
-       
-       assert.Equal(t,  Config.GetString("name"), "xapp")
-       assert.Equal(t,  Config.GetInt("controls.logger.level"), 3)
-       assert.Equal(t,  Config.GetUint32("controls.logger.level"), uint32(3))
-       assert.Equal(t,  Config.GetBool("controls.waitForSdl"), false)
+
+       assert.Equal(t, Config.GetString("name"), "xapp")
+       assert.Equal(t, Config.GetInt("controls.logger.level"), 3)
+       assert.Equal(t, Config.GetUint32("controls.logger.level"), uint32(3))
+       assert.Equal(t, Config.GetBool("controls.waitForSdl"), false)
        Config.Get("controls")
        Config.GetStringSlice("messaging.ports")
        Config.GetStringMap("messaging.ports")
@@ -354,7 +354,7 @@ func TestNewSubscriber(t *testing.T) {
 }
 
 func TestNewRMRClient(t *testing.T) {
-       c := map[string]interface{} {"protPort": "tcp:4560"}
+       c := map[string]interface{}{"protPort": "tcp:4560"}
        viper.Set("rmr", c)
        assert.NotNil(t, NewRMRClient(), "NewRMRClient failed")
 
@@ -423,6 +423,23 @@ func TestConfigHandler(t *testing.T) {
        executeRequest(req, handleFunc)
 }
 
+func TestappconfigHandler(t *testing.T) {
+       Logger.Error("CASE: TestappconfigHandler")
+       req, _ := http.NewRequest("POST", "/ric/v1/config", bytes.NewBuffer([]byte{}))
+       handleFunc := http.HandlerFunc(appconfigHandler)
+       executeRequest(req, handleFunc)
+}
+
+func TestSendRegistermsg(t *testing.T) {
+       Logger.Error("CASE: TestSendRegistermsg")
+       SendRegistermsg()
+}
+
+func TestSendDeregistermsg(t *testing.T) {
+       Logger.Error("CASE: TestSendDeregistermsg")
+       SendDeregistermsg()
+}
+
 func TestMisc(t *testing.T) {
        Logger.Info("CASE: TestMisc")