diff --git a/cmd/main.go b/cmd/main.go index 40a474d..7f39093 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -23,13 +23,14 @@ import ( "github.com/urfave/cli" "github.com/free5gc/chf/internal/logger" + "github.com/free5gc/chf/internal/repository" "github.com/free5gc/chf/pkg/factory" "github.com/free5gc/chf/pkg/service" logger_util "github.com/free5gc/util/logger" "github.com/free5gc/util/version" ) -var CHF = &service.ChfApp{} +var CHF *service.ChfApp func main() { defer func() { @@ -81,15 +82,16 @@ func action(cliCtx *cli.Context) error { return err } factory.ChfConfig = cfg + runtimeRepo := repository.NewRuntimeRepository(cfg) - chf, err := service.NewApp(ctx, cfg, tlsKeyLogPath) + chf, err := service.NewApp(ctx, runtimeRepo, tlsKeyLogPath) if err != nil { sigCh <- nil return err } CHF = chf - chf.Start() + chf.Start(tlsKeyLogPath) CHF.WaitRoutineStopped() return nil diff --git a/go.mod b/go.mod index 444933f..c1e12e6 100644 --- a/go.mod +++ b/go.mod @@ -88,11 +88,11 @@ require ( github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect go.opencensus.io v0.24.0 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/net v0.23.0 // indirect + golang.org/x/crypto v0.22.0 // indirect + golang.org/x/net v0.24.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect - golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.18.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/api v0.114.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 7cb3ea0..adb978f 100644 --- a/go.sum +++ b/go.sum @@ -572,8 +572,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -657,8 +657,8 @@ golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -686,8 +686,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -761,13 +761,13 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/internal/repository/runtime.go b/internal/repository/runtime.go new file mode 100644 index 0000000..9eb4fae --- /dev/null +++ b/internal/repository/runtime.go @@ -0,0 +1,26 @@ +package repository + +import ( + chf_context "github.com/free5gc/chf/internal/context" + "github.com/free5gc/chf/pkg/factory" +) + +type RuntimeRepository struct { + config *factory.Config + chfCtx *chf_context.CHFContext +} + +func NewRuntimeRepository(cfg *factory.Config) *RuntimeRepository { + return &RuntimeRepository{ + config: cfg, + chfCtx: chf_context.GetSelf(), + } +} + +func (rr RuntimeRepository) Config() *factory.Config { + return rr.config +} + +func (rr RuntimeRepository) Context() *chf_context.CHFContext { + return rr.chfCtx +} diff --git a/internal/sbi/api_convergedcharging.go b/internal/sbi/api_convergedcharging.go index 7864995..496019e 100644 --- a/internal/sbi/api_convergedcharging.go +++ b/internal/sbi/api_convergedcharging.go @@ -20,7 +20,6 @@ import ( "github.com/gin-gonic/gin" "github.com/free5gc/chf/internal/logger" - "github.com/free5gc/util/httpwrapper" ) // Index is the index handler. @@ -28,8 +27,8 @@ func Index(c *gin.Context) { c.String(http.StatusOK, "Hello World!") } -func (s *Server) getConvergenChargingEndpoints() []Endpoint { - return []Endpoint{ +func (s *Server) getConvergenChargingRoutes() []Route { + return []Route{ { Method: http.MethodGet, Pattern: "/", @@ -92,27 +91,9 @@ func (s *Server) ChargingdataChargingDataRefReleasePost(c *gin.Context) { c.JSON(http.StatusBadRequest, rsp) return } + chargingSessionId := c.Param("ChargingDataRef") - req := httpwrapper.NewRequest(c.Request, chargingDataReq) - req.Params["ChargingDataRef"] = c.Param("ChargingDataRef") - - rsp := s.Processor().HandleChargingdataRelease(req) - - for key, value := range rsp.Header { - c.Header(key, value[0]) - } - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.ChargingdataPostLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } + s.Processor().HandleChargingdataRelease(c, chargingDataReq, chargingSessionId) } // ChargingdataChargingDataRefUpdatePost @@ -144,27 +125,9 @@ func (s *Server) ChargingdataChargingDataRefUpdatePost(c *gin.Context) { c.JSON(http.StatusBadRequest, rsp) return } + chargingSessionId := c.Param("ChargingDataRef") - req := httpwrapper.NewRequest(c.Request, chargingDataReq) - req.Params["ChargingDataRef"] = c.Param("ChargingDataRef") - - rsp := s.Processor().HandleChargingdataUpdate(req) - - for key, value := range rsp.Header { - c.Header(key, value[0]) - } - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.ChargingdataPostLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } + s.Processor().HandleChargingdataUpdate(c, chargingDataReq, chargingSessionId) } // ChargingdataPost @@ -197,25 +160,7 @@ func (s *Server) ChargingdataPost(c *gin.Context) { return } - req := httpwrapper.NewRequest(c.Request, chargingDataReq) - - rsp := s.Processor().HandleChargingdataInitial(req) - - for key, value := range rsp.Header { - c.Header(key, value[0]) - } - responseBody, err := openapi.Serialize(rsp.Body, "application/json") - if err != nil { - logger.ChargingdataPostLog.Errorln(err) - problemDetails := models.ProblemDetails{ - Status: http.StatusInternalServerError, - Cause: "SYSTEM_FAILURE", - Detail: err.Error(), - } - c.JSON(http.StatusInternalServerError, problemDetails) - } else { - c.Data(rsp.Status, "application/json", responseBody) - } + s.Processor().HandleChargingdataInitial(c, chargingDataReq) } func (s *Server) RechargeGet(c *gin.Context) { diff --git a/internal/sbi/consumer/consumer.go b/internal/sbi/consumer/consumer.go index cb12f07..7f958be 100644 --- a/internal/sbi/consumer/consumer.go +++ b/internal/sbi/consumer/consumer.go @@ -1,31 +1,27 @@ package consumer import ( - "context" + "github.com/free5gc/chf/internal/repository" - "github.com/free5gc/chf/pkg/factory" "github.com/free5gc/openapi/Nnrf_NFDiscovery" "github.com/free5gc/openapi/Nnrf_NFManagement" - - chf_context "github.com/free5gc/chf/internal/context" ) -type chf interface { - Config() *factory.Config - Context() *chf_context.CHFContext - CancelContext() context.Context +type Chf interface { + // Consumer doesn't need any App component now } type Consumer struct { - chf + Chf + RuntimeRepository *repository.RuntimeRepository - // consumer services *nnrfService } -func NewConsumer(chf chf) (*Consumer, error) { +func NewConsumer(chf Chf, runtimeRepo *repository.RuntimeRepository) (*Consumer, error) { c := &Consumer{ - chf: chf, + Chf: chf, + RuntimeRepository: runtimeRepo, } c.nnrfService = &nnrfService{ diff --git a/internal/sbi/consumer/nf_discovery.go b/internal/sbi/consumer/nf_discovery.go deleted file mode 100644 index 87e65fd..0000000 --- a/internal/sbi/consumer/nf_discovery.go +++ /dev/null @@ -1,40 +0,0 @@ -package consumer - -import ( - "fmt" - "net/http" - - chf_context "github.com/free5gc/chf/internal/context" - "github.com/free5gc/chf/internal/logger" - "github.com/free5gc/openapi/Nnrf_NFDiscovery" - "github.com/free5gc/openapi/models" -) - -func SendSearchNFInstances( - nrfUri string, targetNfType, requestNfType models.NfType, param Nnrf_NFDiscovery.SearchNFInstancesParamOpts) ( - *models.SearchResult, error) { - // Set client and set url - configuration := Nnrf_NFDiscovery.NewConfiguration() - configuration.SetBasePath(nrfUri) - client := Nnrf_NFDiscovery.NewAPIClient(configuration) - - ctx, _, err := chf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_DISC, models.NfType_NRF) - if err != nil { - return nil, err - } - - result, res, err := client.NFInstancesStoreApi.SearchNFInstances(ctx, targetNfType, requestNfType, ¶m) - if err != nil { - logger.ConsumerLog.Errorf("SearchNFInstances failed: %+v", err) - } - defer func() { - if resCloseErr := res.Body.Close(); resCloseErr != nil { - logger.ConsumerLog.Errorf("NFInstancesStoreApi response body cannot close: %+v", resCloseErr) - } - }() - if res != nil && res.StatusCode == http.StatusTemporaryRedirect { - return nil, fmt.Errorf("Temporary Redirect For Non NRF Consumer") - } - - return &result, nil -} diff --git a/internal/sbi/consumer/nf_management_test.go.old b/internal/sbi/consumer/nf_management_test.go.old deleted file mode 100644 index 645360c..0000000 --- a/internal/sbi/consumer/nf_management_test.go.old +++ /dev/null @@ -1,50 +0,0 @@ -package consumer_test - -import ( - "github.com/free5gc/openapi/Nnrf_NFDiscovery" - "github.com/free5gc/openapi/models" - "github.com/free5gc/chf/consumer" - "github.com/free5gc/chf/factory" - chf_service "github.com/free5gc/chf/service" - "github.com/free5gc/util/mongoapi" - "flag" - nrf_service "free5gc/src/nrf/service" - "testing" - "time" - - "github.com/antihax/optional" - "github.com/urfave/cli" - "go.mongodb.org/mongo-driver/bson" -) - -var flags flag.FlagSet -var c = cli.NewContext(nil, &flags, nil) - -func nrfInit() { - nrf := &nrf_service.NRF{} - nrf.Initialize(c) - go nrf.Start() - time.Sleep(100 * time.Millisecond) -} -func TestRegisterNFInstance(t *testing.T) { - // init NRF - nrfInit() - // Clear DB - mongoapi.RestfulAPIDeleteMany("NfProfile", bson.M{}) - time.Sleep(50 * time.Millisecond) - // Init CHF and register to NRF - chf := chf_service.CHF{} - chf.Initialize(c) - go chf.Start() - time.Sleep(50 * time.Millisecond) - // Send NF Discovery to discover CHF - param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ - ServiceNames: optional.NewInterface([]models.ServiceName{models.ServiceName_NCHF_AM_POLICY_CONTROL, models.ServiceName_NCHF_BDTPOLICYCONTROL, models.ServiceName_NCHF_POLICYAUTHORIZATION, models.ServiceName_NCHF_SMPOLICYCONTROL, models.ServiceName_NCHF_UE_POLICY_CONTROL}), - } - result, err := consumer.SendSearchNFInstances(factory.ChfConfig.Configuration.NrfUri, models.NfType_CHF, models.NfType_UDR, param) - if err != nil { - t.Error(err.Error()) - } else if result.NfInstances == nil { - t.Error("NF Instances is nil") - } -} diff --git a/internal/sbi/consumer/nrf_service.go b/internal/sbi/consumer/nrf_service.go index 3981ec2..45cd1c2 100644 --- a/internal/sbi/consumer/nrf_service.go +++ b/internal/sbi/consumer/nrf_service.go @@ -76,7 +76,7 @@ func (s *nnrfService) SendSearchNFInstances( nrfUri string, targetNfType, requestNfType models.NfType, param Nnrf_NFDiscovery.SearchNFInstancesParamOpts) ( *models.SearchResult, error) { // Set client and set url - chfContext := s.consumer.chf.Context() + chfContext := s.consumer.RuntimeRepository.Context() client := s.getNFDiscClient(chfContext.NrfUri) @@ -109,7 +109,7 @@ func (s *nnrfService) SendDeregisterNFInstance() (problemDetails *models.Problem return pd, err } - chfContext := s.consumer.chf.Context() + chfContext := s.consumer.RuntimeRepository.Context() client := s.getNFManagementClient(chfContext.NrfUri) var res *http.Response @@ -136,7 +136,7 @@ func (s *nnrfService) SendDeregisterNFInstance() (problemDetails *models.Problem func (s *nnrfService) RegisterNFInstance(ctx context.Context) ( resouceNrfUri string, retrieveNfInstanceID string, err error) { - chfContext := s.consumer.chf.Context() + chfContext := s.consumer.RuntimeRepository.Context() client := s.getNFManagementClient(chfContext.NrfUri) nfProfile, err := s.buildNfProfile(chfContext) diff --git a/internal/sbi/processor/converged_charging.go b/internal/sbi/processor/converged_charging.go index 4dc7e70..4855873 100644 --- a/internal/sbi/processor/converged_charging.go +++ b/internal/sbi/processor/converged_charging.go @@ -9,6 +9,7 @@ import ( "time" charging_datatype "github.com/free5gc/chf/ccs_diameter/datatype" + "github.com/gin-gonic/gin" "golang.org/x/exp/constraints" "github.com/fiorix/go-diameter/diam/datatype" @@ -20,7 +21,6 @@ import ( "github.com/free5gc/chf/internal/rating" "github.com/free5gc/chf/internal/util" "github.com/free5gc/openapi/models" - "github.com/free5gc/util/httpwrapper" ) func min[T constraints.Ordered](a, b T) T { @@ -80,62 +80,63 @@ func (p *Processor) SendChargingNotification(notifyUri string, notifyRequest mod } } -func (p *Processor) HandleChargingdataInitial(request *httpwrapper.Request) *httpwrapper.Response { +func (p *Processor) HandleChargingdataInitial( + c *gin.Context, + chargingdata models.ChargingDataRequest, +) { logger.ChargingdataPostLog.Infof("HandleChargingdataInitial") - chargingdata := request.Body.(models.ChargingDataRequest) - response, locationURI, problemDetails := p.ChargingDataCreate(chargingdata) - respHeader := make(http.Header) - respHeader.Set("Location", locationURI) if response != nil { - return httpwrapper.NewResponse(http.StatusCreated, respHeader, response) + c.Header("Location", locationURI) + c.JSON(http.StatusCreated, response) + return } else if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) + c.JSON(int(problemDetails.Status), problemDetails) + return } problemDetails = &models.ProblemDetails{ Status: http.StatusForbidden, Cause: "UNSPECIFIED", } - return httpwrapper.NewResponse(http.StatusForbidden, nil, problemDetails) + c.JSON(int(problemDetails.Status), problemDetails) } -func (p *Processor) HandleChargingdataUpdate(request *httpwrapper.Request) *httpwrapper.Response { +func (p *Processor) HandleChargingdataUpdate( + c *gin.Context, + chargingdata models.ChargingDataRequest, + chargingSessionId string, +) { logger.ChargingdataPostLog.Infof("HandleChargingdataUpdate") - chargingdata := request.Body.(models.ChargingDataRequest) - chargingSessionId := request.Params["ChargingDataRef"] - response, problemDetails := p.ChargingDataUpdate(chargingdata, chargingSessionId) if response != nil { - return httpwrapper.NewResponse(http.StatusOK, nil, response) + c.JSON(http.StatusOK, response) + return } else if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) + c.JSON(int(problemDetails.Status), problemDetails) + return } problemDetails = &models.ProblemDetails{ Status: http.StatusForbidden, Cause: "UNSPECIFIED", } - return httpwrapper.NewResponse(http.StatusForbidden, nil, problemDetails) + c.JSON(int(problemDetails.Status), problemDetails) } -func (p *Processor) HandleChargingdataRelease(request *httpwrapper.Request) *httpwrapper.Response { +func (p *Processor) HandleChargingdataRelease( + c *gin.Context, + chargingdata models.ChargingDataRequest, + chargingSessionId string, +) { logger.ChargingdataPostLog.Infof("HandleChargingdateRelease") - chargingdata := request.Body.(models.ChargingDataRequest) - chargingSessionId := request.Params["ChargingDataRef"] problemDetails := p.ChargingDataRelease(chargingdata, chargingSessionId) - if problemDetails == nil { - return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) - } else if problemDetails != nil { - return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) - } - problemDetails = &models.ProblemDetails{ - Status: http.StatusForbidden, - Cause: "UNSPECIFIED", + c.Status(http.StatusBadRequest) + return } - return httpwrapper.NewResponse(http.StatusForbidden, nil, problemDetails) + c.JSON(int(problemDetails.Status), problemDetails) } func (p *Processor) ChargingDataCreate(chargingData models.ChargingDataRequest) (*models.ChargingDataResponse, diff --git a/internal/sbi/processor/processor.go b/internal/sbi/processor/processor.go index 8a470d8..d4fcdd6 100644 --- a/internal/sbi/processor/processor.go +++ b/internal/sbi/processor/processor.go @@ -1,22 +1,16 @@ package processor import ( - "context" - - chf_context "github.com/free5gc/chf/internal/context" - "github.com/free5gc/chf/internal/sbi/consumer" - "github.com/free5gc/chf/pkg/factory" + "github.com/free5gc/chf/internal/repository" ) -type chf interface { - Config() *factory.Config - Context() *chf_context.CHFContext - Consumer() *consumer.Consumer - CancelContext() context.Context +type Chf interface { + // Processor doesn't need any App component now } type Processor struct { - chf + Chf + RuntimeRepository *repository.RuntimeRepository } type HandlerResponse struct { @@ -25,9 +19,10 @@ type HandlerResponse struct { Body interface{} } -func NewProcessor(chf chf) (*Processor, error) { +func NewProcessor(chf Chf, runtimeRepo *repository.RuntimeRepository) (*Processor, error) { p := &Processor{ - chf: chf, + Chf: chf, + RuntimeRepository: runtimeRepo, } return p, nil } diff --git a/internal/sbi/server.go b/internal/sbi/server.go index dfb9bd1..381f622 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -13,6 +13,7 @@ import ( chf_context "github.com/free5gc/chf/internal/context" "github.com/free5gc/chf/internal/logger" + "github.com/free5gc/chf/internal/repository" "github.com/free5gc/chf/internal/sbi/consumer" "github.com/free5gc/chf/internal/sbi/processor" "github.com/free5gc/chf/internal/util" @@ -28,58 +29,56 @@ const ( CorsConfigMaxAge = 86400 ) -type Endpoint struct { +type Route struct { Method string Pattern string APIFunc gin.HandlerFunc } -func applyEndpoints(group *gin.RouterGroup, endpoints []Endpoint) { - for _, endpoint := range endpoints { - switch endpoint.Method { +func applyRoutes(group *gin.RouterGroup, routes []Route) { + for _, route := range routes { + switch route.Method { case "GET": - group.GET(endpoint.Pattern, endpoint.APIFunc) + group.GET(route.Pattern, route.APIFunc) case "POST": - group.POST(endpoint.Pattern, endpoint.APIFunc) + group.POST(route.Pattern, route.APIFunc) case "PUT": - group.PUT(endpoint.Pattern, endpoint.APIFunc) + group.PUT(route.Pattern, route.APIFunc) case "PATCH": - group.PATCH(endpoint.Pattern, endpoint.APIFunc) + group.PATCH(route.Pattern, route.APIFunc) case "DELETE": - group.DELETE(endpoint.Pattern, endpoint.APIFunc) + group.DELETE(route.Pattern, route.APIFunc) } } } type chf interface { - Config() *factory.Config - Context() *chf_context.CHFContext - CancelContext() context.Context Consumer() *consumer.Consumer Processor() *processor.Processor } type Server struct { chf + RuntimeRepository *repository.RuntimeRepository httpServer *http.Server router *gin.Engine } -func NewServer(chf chf, tlsKeyLogPath string) (*Server, error) { +func NewServer(chf chf, runtimeRepo *repository.RuntimeRepository, tlsKeyLogPath string) (*Server, error) { s := &Server{ - chf: chf, - router: logger_util.NewGinWithLogrus(logger.GinLog), + chf: chf, + RuntimeRepository: runtimeRepo, + router: logger_util.NewGinWithLogrus(logger.GinLog), } - endpoints := s.getConvergenChargingEndpoints() - // group := s.router.Group(openapi.ServiceBaseUri(models.ServiceName_NCHF_CONVERGEDCHARGING)) + routes := s.getConvergenChargingRoutes() group := s.router.Group(factory.ConvergedChargingResUriPrefix) routerAuthorizationCheck := util.NewRouterAuthorizationCheck(models.ServiceName_NCHF_CONVERGEDCHARGING) group.Use(func(c *gin.Context) { routerAuthorizationCheck.Check(c, chf_context.GetSelf()) }) - applyEndpoints(group, endpoints) + applyRoutes(group, routes) s.router.Use(cors.New(cors.Config{ AllowMethods: []string{"GET", "POST", "OPTIONS", "PUT", "PATCH", "DELETE"}, @@ -93,7 +92,7 @@ func NewServer(chf chf, tlsKeyLogPath string) (*Server, error) { MaxAge: CorsConfigMaxAge, })) - cfg := s.Config() + cfg := s.RuntimeRepository.Config() bindAddr := cfg.GetSbiBindingAddr() logger.SBILog.Infof("Binding addr: [%s]", bindAddr) var err error @@ -108,7 +107,7 @@ func NewServer(chf chf, tlsKeyLogPath string) (*Server, error) { func (s *Server) Run(traceCtx context.Context, wg *sync.WaitGroup) error { var err error - _, s.Context().NfId, err = s.Consumer().RegisterNFInstance(s.CancelContext()) + _, s.RuntimeRepository.Context().NfId, err = s.Consumer().RegisterNFInstance(context.Background()) if err != nil { logger.InitLog.Errorf("CHF register to NRF Error[%s]", err.Error()) } @@ -119,7 +118,7 @@ func (s *Server) Run(traceCtx context.Context, wg *sync.WaitGroup) error { return nil } -func (s *Server) Stop(traceCtx context.Context) { +func (s *Server) Stop() { const defaultShutdownTimeout time.Duration = 2 * time.Second if s.httpServer != nil { @@ -144,7 +143,7 @@ func (s *Server) startServer(wg *sync.WaitGroup) { logger.SBILog.Infof("Start SBI server (listen on %s)", s.httpServer.Addr) var err error - cfg := s.Config() + cfg := s.RuntimeRepository.Config() scheme := cfg.GetSbiScheme() if scheme == "http" { err = s.httpServer.ListenAndServe() diff --git a/pkg/service/init.go b/pkg/service/init.go index 950e8d6..8302083 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -12,45 +12,54 @@ import ( "github.com/free5gc/chf/internal/cgf" chf_context "github.com/free5gc/chf/internal/context" "github.com/free5gc/chf/internal/logger" + "github.com/free5gc/chf/internal/repository" "github.com/free5gc/chf/internal/sbi" "github.com/free5gc/chf/internal/sbi/consumer" "github.com/free5gc/chf/internal/sbi/processor" "github.com/free5gc/chf/pkg/abmf" - "github.com/free5gc/chf/pkg/factory" "github.com/free5gc/chf/pkg/rf" ) +var CHF *ChfApp + +var _ App = &ChfApp{} + +type App interface { + Consumer() *consumer.Consumer + Processor() *processor.Processor +} + type ChfApp struct { - cfg *factory.Config - chfCtx *chf_context.CHFContext + App + RuntimeRepo *repository.RuntimeRepository + ctx context.Context cancel context.CancelFunc + wg sync.WaitGroup sbiServer *sbi.Server consumer *consumer.Consumer processor *processor.Processor - wg sync.WaitGroup } -func NewApp(ctx context.Context, cfg *factory.Config, tlsKeyLogPath string) (*ChfApp, error) { +func NewApp(ctx context.Context, RuntimeRepo *repository.RuntimeRepository, tlsKeyLogPath string) (*ChfApp, error) { chf := &ChfApp{ - cfg: cfg, - wg: sync.WaitGroup{}, + RuntimeRepo: RuntimeRepo, + wg: sync.WaitGroup{}, } - chf.SetLogEnable(cfg.GetLogEnable()) - chf.SetLogLevel(cfg.GetLogLevel()) - chf.SetReportCaller(cfg.GetLogReportCaller()) + chf.SetLogEnable(RuntimeRepo.Config().GetLogEnable()) + chf.SetLogLevel(RuntimeRepo.Config().GetLogLevel()) + chf.SetReportCaller(RuntimeRepo.Config().GetLogReportCaller()) chf_context.Init() - chf.chfCtx = chf_context.GetSelf() - processor, err_p := processor.NewProcessor(chf) + processor, err_p := processor.NewProcessor(chf, chf.RuntimeRepo) if err_p != nil { return chf, err_p } chf.processor = processor - consumer, err := consumer.NewConsumer(chf) + consumer, err := consumer.NewConsumer(chf, chf.RuntimeRepo) if err != nil { return chf, err } @@ -58,18 +67,12 @@ func NewApp(ctx context.Context, cfg *factory.Config, tlsKeyLogPath string) (*Ch chf.ctx, chf.cancel = context.WithCancel(ctx) - if chf.sbiServer, err = sbi.NewServer(chf, tlsKeyLogPath); err != nil { + if chf.sbiServer, err = sbi.NewServer(chf, chf.RuntimeRepo, tlsKeyLogPath); err != nil { return nil, err } - return chf, nil -} - -func (a *ChfApp) Config() *factory.Config { - return a.cfg -} + CHF = chf -func (a *ChfApp) Context() *chf_context.CHFContext { - return a.chfCtx + return chf, nil } func (a *ChfApp) CancelContext() context.Context { @@ -92,7 +95,7 @@ func (c *ChfApp) SetLogEnable(enable bool) { return } - c.cfg.SetLogEnable(enable) + c.RuntimeRepo.Config().SetLogEnable(enable) if enable { logger.Log.SetOutput(os.Stderr) } else { @@ -113,21 +116,22 @@ func (c *ChfApp) SetLogLevel(level string) { return } - c.cfg.SetLogLevel(level) + c.RuntimeRepo.Config().SetLogLevel(level) logger.Log.SetLevel(lvl) } -func (a *ChfApp) SetReportCaller(reportCaller bool) { +func (c *ChfApp) SetReportCaller(reportCaller bool) { logger.MainLog.Infof("Report Caller is set to [%v]", reportCaller) if reportCaller == logger.Log.ReportCaller { return } - a.cfg.SetLogReportCaller(reportCaller) + c.RuntimeRepo.Config().SetLogReportCaller(reportCaller) logger.Log.SetReportCaller(reportCaller) } -func (a *ChfApp) Start() { +// tlsKeyLogPath have to remove after all NFs are refactor +func (a *ChfApp) Start(tlsKeyLogPath string) { logger.InitLog.Infoln("Server started") a.wg.Add(1) @@ -157,15 +161,14 @@ func (a *ChfApp) listenShutdownEvent() { }() <-a.ctx.Done() - - if a.sbiServer != nil { - a.sbiServer.Stop(context.Background()) - a.Terminate() - } + a.Terminate() } func (c *ChfApp) Terminate() { logger.MainLog.Infof("Terminating CHF...") + c.cancel() + c.CallServerStop() + // deregister with NRF problemDetails, err := c.Consumer().SendDeregisterNFInstance() if problemDetails != nil { @@ -178,9 +181,10 @@ func (c *ChfApp) Terminate() { logger.MainLog.Infof("CHF SBI Server terminated") } -func (a *ChfApp) Stop() { - a.cancel() - a.WaitRoutineStopped() +func (a *ChfApp) CallServerStop() { + if a.sbiServer != nil { + a.sbiServer.Stop() + } } func (a *ChfApp) WaitRoutineStopped() {