diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..56871d5 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,381 @@ + +# options for analysis running +run: + # Number of operating system threads (`GOMAXPROCS`) that can execute golangci-lint simultaneously. + # If it is explicitly set to 0 (i.e. not the default) then golangci-lint will automatically set the value to match Linux container CPU quota. + # Default: the number of logical CPUs in the machine + concurrency: 4 + + # timeout for analysis, e.g. 30s, 5m, default is 1m + timeout: 3m + + # exit code when at least one issue was found, default is 1 + issues-exit-code: 1 + + # include test files or not, default is true + tests: true + + # list of build tags, all linters use it. Default is empty list. + build-tags: [] + + # If set, we pass it to "go list -mod={option}". From "go help modules": + # If invoked with -mod=readonly, the go command is disallowed from the implicit + # automatic updating of go.mod described above. Instead, it fails when any changes + # to go.mod are needed. This setting is most useful to check that go.mod does + # not need updates, such as in a continuous integration and testing system. + # If invoked with -mod=vendor, the go command assumes that the vendor + # directory holds the correct copies of dependencies and ignores + # the dependency descriptions in go.mod. + # + # Allowed values: readonly|vendor|mod + # Default: "" + # modules-download-mode: readonly + + # Allow multiple parallel golangci-lint instances running. + # If false, golangci-lint acquires file lock on start. + # Default: false + allow-parallel-runners: true + + # Allow multiple golangci-lint instances running, but serialize them around a lock. + # If false, golangci-lint exits with an error if it fails to acquire file lock on start. + # Default: false + allow-serial-runners: true + + go: '1.21' + +# output configuration options +output: + # colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number" + formats: + - format: "colored-line-number" + path: stdout + + # print lines of code with issue, default is true + print-issued-lines: true + # print linter name in the end of issue text, default is true + print-linter-name: true + # make issues output unique by line, default is true + uniq-by-line: true + + # Sort results by the order defined in `sort-order`. + # Default: false + sort-results: true + sort-order: + - linter + - severity + - file # filepath, line, and column. + show-stats: true + +# all available settings of specific linters +linters-settings: + errcheck: + # report about not checking of errors in type assertions: `a := b.(MyStruct)`; + # default is false: such cases aren't reported by default. + check-type-assertions: false + # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`; + # default is false: such cases aren't reported by default. + check-blank: true + # [deprecated] comma-separated list of pairs of the form pkg:regex + # the regex is used to ignore names within pkg. (default "fmt:.*"). + # see https://github.com/kisielk/errcheck#the-deprecated-method for details + #ignore: fmt:.*,io/ioutil:^Read.* + # path to a file containing a list of functions to exclude from checking + # see https://github.com/kisielk/errcheck#excluding-functions for details + #exclude: /path/to/file.txt + + goconst: + # minimal length of string constant, 3 by default + min-len: 5 + # Minimum occurrences of constant string count to trigger issue, 3 by default + min-occurrences: 3 + # Exclude strings matching the given regular expression. + # Default: "" + ignore-strings: "get|post|put|delete|patch|options|head" + + gocritic: + # Which checks should be enabled; can't be combined with 'disabled-checks'; + # See https://go-critic.github.io/overview#checks-overview + # To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run` + # By default list of stable checks is used. + enabled-checks: [] + #- rangeValCopy + # Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty + disabled-checks: + - regexpMust + # Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks. + # Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags". + enabled-tags: + - diagnostic + - performance + disabled-tags: + - experimental + + # settings passed to gocritic + # The settings key is the name of a supported gocritic checker. + # The list of supported checkers can be find in https://go-critic.github.io/overview. + settings: + captLocal: # must be valid enabled check name + # Whether to restrict checker to params only. + paramsOnly: true + rangeValCopy: + # Size in bytes that makes the warning trigger. Default: 128 + # This size shoulb be smaller + sizeThreshold: 512 + hugeParam: + # Size in bytes that makes the warning trigger. Default: 80 + # This size shoulb be smaller + sizeThreshold: 512 + ifElseChain: + # Min number of if-else blocks that makes the warning trigger. + # Default: 2 + minThreshold: 4 + + godox: + # report any comments starting with keywords, this is useful for TODO or FIXME comments that + # might be left in the code accidentally and should be resolved before merging + keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting + #- TODO + - FIXME + - BUG + #- NOTE + #- OPTIMIZE # marks code that should be optimized before merging + #- HACK # marks hack-arounds that should be removed before merging + - XXX # Fatal! Important problem + + gofmt: + # simplify code: gofmt with `-s` option, true by default + simplify: true + + govet: + enable-all: false + # enable or disable analyzers by name + enable: + - atomicalign + - shadow + - printf + + # settings per analyzer + settings: + # analyzer name, run `go tool vet help` to see all analyzers + printf: + funcs: # run `go tool vet help printf` to see available settings for `printf` analyzer + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf + shadow: + # Whether to be strict about shadowing; can be noisy. + # Default: false + strict: true + + depguard: + rules: + # Name of a rule. + main: + # Used to determine the package matching priority. + # There are three different modes: `original`, `strict`, and `lax`. + # Default: "original" + list-mode: original + deny: + - pkg: github.com/sirupsen/logrus + desc: "logging is allowed only by logutils.Log" + + lll: + # max line length, lines longer will be reported. Default is 120. + # '\t' is counted as 1 character by default, and can be changed with the tab-width option + line-length: 120 + # tab width in spaces. Default to 1. + tab-width: 1 + + nakedret: + # make an issue if func has more lines of code than this setting and it has naked returns; default is 30 + max-func-lines: 30 + + testpackage: + # regexp pattern to skip files + skip-regexp: (export|internal)_test\.go + + unused: + # Mark all struct fields that have been written to as used. + # Default: true + field-writes-are-uses: true + # Treat IncDec statement (e.g. `i++` or `i--`) as both read and write operation instead of just write. + # Default: false + post-statements-are-reads: true + # Mark all exported identifiers as used. + # Default: true + exported-is-used: true + # Mark all exported fields as used. + # default: true + exported-fields-are-used: true + # Mark all function parameters as used. + # default: true + parameters-are-used: true + # Mark all local variables as used. + # default: true + local-variables-are-used: true + # Mark all identifiers inside generated files as used. + # Default: true + generated-is-used: true + + whitespace: + multi-if: false # Enforces newlines (or comments) after every multi-line if statement + multi-func: false # Enforces newlines (or comments) after every multi-line function signature + + gci: + sections: + - standard + - default + - prefix(github.com/free5gc) + + # Skip generated files. + # Default: true + skip-generated: true + + # Enable custom order of sections. + # If `true`, make the section order the same as the order of `sections`. + # Default: false + custom-order: true + + misspell: + locale: US + ignore-words: [] + + gomnd: + # !important in golangci-lint v1.58.0, gomnd is replaced by mnd + # List of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description. + # Default: ["argument", "case", "condition", "operation", "return", "assign"] + checks: + # - argument + - case + # - condition + - operation + - return + # - assign + # List of numbers to exclude from analysis. + # The numbers should be written as string. + # Values always ignored: "1", "1.0", "0" and "0.0" + # Default: [] + ignored-numbers: [] + # List of file patterns to exclude from analysis. + # Values always ignored: `.+_test.go` + # Default: [] + ignored-files: [] + # List of function patterns to exclude from analysis. + # Following functions are always ignored: `time.Date`, + # `strconv.FormatInt`, `strconv.FormatUint`, `strconv.FormatFloat`, + # `strconv.ParseInt`, `strconv.ParseUint`, `strconv.ParseFloat`. + # Default: [] + ignored-functions: + - 'os\.Mkdir' + - 'os\.MkdirAll' + - '^math\.' + - '^http\.StatusText$' + + # custom: + # Each custom linter should have a unique name. + +linters: + disable-all: true + enable: + - errcheck + - goconst + # - gocritic + - godox + - gofmt + - govet + - lll + - nakedret + # - testpackage + - staticcheck + - unused + - whitespace + - gci + - misspell + - gosimple + # - gomnd + - ineffassign + - typecheck + - gofumpt + # - unconvert + # - predeclared + - noctx + - dogsled + - bodyclose + - asciicheck + # - dupl + + # Enable only fast linters from enabled linters set (first run won't be fast) + # Default: false + fast: true + + +issues: + # List of regexps of issue texts to exclude, empty list by default. + # But independently from this option we use default exclude patterns, + # it can be disabled by `exclude-use-default: false`. To list all + # excluded by default patterns execute `golangci-lint run --help` + exclude: [] + # Excluding configuration per-path, per-linter, per-text and per-source + exclude-rules: [] + # Exclude some linters from running on tests files. + # Independently from option `exclude` we use default exclude patterns, + # it can be disabled by this option. To list all + # excluded by default patterns execute `golangci-lint run --help`. + # Default value for this option is true. + exclude-use-default: false + # The default value is false. If set to true exclude and exclude-rules + # regular expressions become case sensitive. + exclude-case-sensitive: false + # The list of ids of default excludes to include or disable. By default it's empty. + include: [] + #- EXC0002 # disable excluding of issues about comments from golint + # Maximum issues count per one linter. Set to 0 to disable. Default is 50. + #max-issues-per-linter: 0 + # Maximum count of issues with the same text. Set to 0 to disable. Default is 3. + #max-same-issues: 0 + # Show only new issues: if there are unstaged changes or untracked files, + # only those changes are analyzed, else only changes in HEAD~ are analyzed. + # It's a super-useful option for integration of golangci-lint into existing + # large codebase. It's not practical to fix all existing issues at the moment + # of integration: much better don't allow issues in new code. + # Default is false. + new: false + # Show only new issues created after git revision `REV` + new-from-rev: "" + # Show only new issues created in git patch with set file path. + #new-from-patch: path/to/patch/file + +severity: + # Set the default severity for issues. + # + # If severity rules are defined and the issues do not match or no severity is provided to the rule + # this will be the default severity applied. + # Severities should match the supported severity names of the selected out format. + # - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity + # - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#SeverityLevel + # - GitHub: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message + # - TeamCity: https://www.jetbrains.com/help/teamcity/service-messages.html#Inspection+Instance + # + # `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...) + # + # Default: "" + default-severity: error + + # The default value is false. + # If set to true severity-rules regular expressions become case sensitive. + case-sensitive: false + + # When a list of severity rules are provided, severity information will be added to lint issues. + # Severity rules have the same filtering capability as exclude rules + # except you are allowed to specify one matcher per severity rule. + # + # `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...) + # + # Only affects out formats that support setting severity information. + # + # Default: [] + rules: + - linters: + - gomnd + severity: info \ No newline at end of file diff --git a/cdr/asn/ber_marshal.go b/cdr/asn/ber_marshal.go index d42299e..10ee7f0 100644 --- a/cdr/asn/ber_marshal.go +++ b/cdr/asn/ber_marshal.go @@ -278,7 +278,7 @@ func makeField(v reflect.Value, params fieldParameters) (encoder, error) { tempParams := parseFieldParameters(structType.Field(i).Tag.Get("ber")) if tempParams.optional { if v.Field(i).IsNil() { - //berTrace( + // berTrace( // 3, fmt.Sprintf("Field \"%s\" in %s is OPTIONAL and not present", structType.Field(i).Name, structType) // ) s[i] = bytesEncoder(nil) diff --git a/cdr/asn/ber_test.go b/cdr/asn/ber_test.go index 2605b51..0cf2e73 100644 --- a/cdr/asn/ber_test.go +++ b/cdr/asn/ber_test.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/binary" "encoding/hex" + "fmt" "reflect" "testing" @@ -453,7 +454,7 @@ func TestParseInt64(t *testing.T) { } for i, tc := range testCases { - t.Run(string(tc), func(t *testing.T) { + t.Run(fmt.Sprintf("%x", tc), func(t *testing.T) { r, err := parseInt64(tc) require.NoError(t, err) require.Equal(t, origInts[i/3], r) diff --git a/cdr/asn/ber_unmarshal.go b/cdr/asn/ber_unmarshal.go index b63dbdf..7246368 100644 --- a/cdr/asn/ber_unmarshal.go +++ b/cdr/asn/ber_unmarshal.go @@ -306,9 +306,9 @@ func ParseField(v reflect.Value, bytes []byte, params fieldParameters) error { var valArray [][]byte var next int64 for offset := int64(talOff); offset < int64(len(bytes)); offset = next { - talNow, talOffNow, err := parseTagAndLength(bytes[offset:]) - if err != nil { - return err + talNow, talOffNow, errParse := parseTagAndLength(bytes[offset:]) + if errParse != nil { + return errParse } next = offset + int64(talOffNow) + talNow.len if next > int64(len(bytes)) { @@ -320,9 +320,9 @@ func ParseField(v reflect.Value, bytes []byte, params fieldParameters) error { sliceLen := len(valArray) newSlice := reflect.MakeSlice(sliceType, sliceLen, sliceLen) for i := 0; i < sliceLen; i++ { - err := ParseField(newSlice.Index(i), valArray[i], params) - if err != nil { - return err + errParse := ParseField(newSlice.Index(i), valArray[i], params) + if errParse != nil { + return errParse } } diff --git a/cdr/cdrConvert/sbiToCdr.go b/cdr/cdrConvert/sbiToCdr.go index 5036f4d..43574b4 100644 --- a/cdr/cdrConvert/sbiToCdr.go +++ b/cdr/cdrConvert/sbiToCdr.go @@ -10,7 +10,9 @@ import ( "github.com/free5gc/openapi/models" ) -func MultiUnitUsageToCdr(multiUnitUsageList []models.MultipleUnitUsage) []cdrType.MultipleUnitUsage { +func MultiUnitUsageToCdr( + multiUnitUsageList []models.ChfConvergedChargingMultipleUnitUsage, +) []cdrType.MultipleUnitUsage { cdrMultiUnitUsageList := make([]cdrType.MultipleUnitUsage, 0, len(multiUnitUsageList)) for _, multiUnitUsage := range multiUnitUsageList { @@ -34,7 +36,9 @@ func MultiUnitUsageToCdr(multiUnitUsageList []models.MultipleUnitUsage) []cdrTyp // TODO // Only convert Local Sequence Number, Uplink, Downlink, Total Volumn, Service Specific Units currently. -func UsedUnitContainerToCdr(usedUnitContainerList []models.UsedUnitContainer) []cdrType.UsedUnitContainer { +func UsedUnitContainerToCdr( + usedUnitContainerList []models.ChfConvergedChargingUsedUnitContainer, +) []cdrType.UsedUnitContainer { cdrUsedUnitContainerList := make([]cdrType.UsedUnitContainer, 0, len(usedUnitContainerList)) for _, usedUnitContainer := range usedUnitContainerList { @@ -61,7 +65,7 @@ func UsedUnitContainerToCdr(usedUnitContainerList []models.UsedUnitContainer) [] } // TODO convert type Trigger -func TriggersToCdr(triggers []models.Trigger) []cdrType.Trigger { +func TriggersToCdr(triggers []models.ChfConvergedChargingTrigger) []cdrType.Trigger { cdrTriggers := make([]cdrType.Trigger, 0, len(triggers)) return cdrTriggers diff --git a/cdr/cdrFile/cdrFile.go b/cdr/cdrFile/cdrFile.go index 9657652..95436a5 100644 --- a/cdr/cdrFile/cdrFile.go +++ b/cdr/cdrFile/cdrFile.go @@ -244,7 +244,7 @@ func (cdrf CdrFileHeader) Encoding() []byte { fmt.Println("CdrFileHeader failed:", err) } - //Number of CDRs in file + // Number of CDRs in file if err := binary.Write(buf, binary.BigEndian, cdrf.NumberOfCdrsInFile); err != nil { fmt.Println("CdrFileHeader failed:", err) } @@ -289,12 +289,12 @@ func (cdrf CdrFileHeader) Encoding() []byte { fmt.Println("CdrFileHeader failed:", err) } - // "High Release Identifer" extension + // "High Release Identifier" extension if err := binary.Write(buf, binary.BigEndian, cdrf.HighReleaseIdentifierExtension); err != nil { fmt.Println("CdrFileHeader failed:", err) } - // "Low Release Identifer" extension + // "Low Release Identifier" extension if err := binary.Write(buf, binary.BigEndian, cdrf.LowReleaseIdentifierExtension); err != nil { fmt.Println("CdrFileHeader failed:", err) } @@ -379,7 +379,7 @@ func (cdfFile CDRFile) Encoding(fileName string) { } // fmt.Printf("Encoded: %b\n", buf.Bytes()) - err := os.WriteFile(fileName, buf.Bytes(), 0666) + err := os.WriteFile(fileName, buf.Bytes(), 0o666) if err != nil { panic(err) } diff --git a/cdr/cdrFile/cdrfile_test.go b/cdr/cdrFile/cdrfile_test.go index 60a9a26..7b72ca2 100644 --- a/cdr/cdrFile/cdrfile_test.go +++ b/cdr/cdrFile/cdrfile_test.go @@ -2,10 +2,9 @@ package cdrFile import ( "fmt" - // "reflect" - "testing" - "strconv" "os" + "strconv" + "testing" "github.com/stretchr/testify/require" ) @@ -26,26 +25,28 @@ func TestCdrFile(t *testing.T) { NumberOfCdrsInFile: 1, FileSequenceNumber: 11, FileClosureTriggerReason: 4, - IpAddressOfNodeThatGeneratedFile: [20]byte{0xa, 0xb, 0xa, 0xb, 0xa, 0xb, 0xa, 0xb, 0xa, 0xb, 0xa, 0xb, 0xa, 0xb, 0xa, 0xb, 0xa, 0xb, 0xa, 0xb}, - LostCdrIndicator: 4, - LengthOfCdrRouteingFilter: 4, - CDRRouteingFilter: []byte("abcd"), - LengthOfPrivateExtension: 5, - PrivateExtension: []byte("fghjk"), // vendor specific + IpAddressOfNodeThatGeneratedFile: [20]byte{ + 0xa, 0xb, 0xa, 0xb, 0xa, 0xb, 0xa, 0xb, 0xa, 0xb, 0xa, 0xb, 0xa, 0xb, 0xa, 0xb, 0xa, 0xb, 0xa, 0xb, + }, + LostCdrIndicator: 4, + LengthOfCdrRouteingFilter: 4, + CDRRouteingFilter: []byte("abcd"), + LengthOfPrivateExtension: 5, + PrivateExtension: []byte("fghjk"), // vendor specific HighReleaseIdentifierExtension: 2, LowReleaseIdentifierExtension: 3, }, CdrList: []CDR{{ - Hdr:CdrHeader { - CdrLength :3, - ReleaseIdentifier :Rel6, // octet 3 bit 6..8 - VersionIdentifier :3, // otcet 3 bit 1..5 - DataRecordFormat :UnalignedPackedEncodingRules, // octet 4 bit 6..8 - TsNumber : TS32253, // octet 4 bit 1..5 - ReleaseIdentifierExtension :4, + Hdr: CdrHeader{ + CdrLength: 3, + ReleaseIdentifier: Rel6, // octet 3 bit 6..8 + VersionIdentifier: 3, // otcet 3 bit 1..5 + DataRecordFormat: UnalignedPackedEncodingRules, // octet 4 bit 6..8 + TsNumber: TS32253, // octet 4 bit 1..5 + ReleaseIdentifierExtension: 4, }, - CdrByte:[]byte("abc"), - },}, + CdrByte: []byte("abc"), + }}, } cdrFile2 := CDRFile{ @@ -61,55 +62,57 @@ func TestCdrFile(t *testing.T) { NumberOfCdrsInFile: 3, FileSequenceNumber: 65, FileClosureTriggerReason: 2, - IpAddressOfNodeThatGeneratedFile: [20]byte{0xc, 0xd, 0xc, 0xd, 0xc, 0xd, 0xc, 0xd, 0xc, 0xd, 0xc, 0xd, 0xc, 0xd, 0xc, 0xd, 0xc, 0xd, 0xc, 0xd}, - LostCdrIndicator: 4, - LengthOfCdrRouteingFilter: 5, - CDRRouteingFilter: []byte("gfdss"), - LengthOfPrivateExtension: 7, - PrivateExtension: []byte("abcdefg"), // vendor specific - HighReleaseIdentifierExtension: 1, - LowReleaseIdentifierExtension: 2, + IpAddressOfNodeThatGeneratedFile: [20]byte{ + 0xc, 0xd, 0xc, 0xd, 0xc, 0xd, 0xc, 0xd, 0xc, 0xd, 0xc, 0xd, 0xc, 0xd, 0xc, 0xd, 0xc, 0xd, 0xc, 0xd, + }, + LostCdrIndicator: 4, + LengthOfCdrRouteingFilter: 5, + CDRRouteingFilter: []byte("gfdss"), + LengthOfPrivateExtension: 7, + PrivateExtension: []byte("abcdefg"), // vendor specific + HighReleaseIdentifierExtension: 1, + LowReleaseIdentifierExtension: 2, }, CdrList: []CDR{ { - Hdr:CdrHeader { - CdrLength :3, - ReleaseIdentifier :Rel6, - VersionIdentifier :3, - DataRecordFormat :UnalignedPackedEncodingRules, - TsNumber : TS32253, - ReleaseIdentifierExtension :4, + Hdr: CdrHeader{ + CdrLength: 3, + ReleaseIdentifier: Rel6, + VersionIdentifier: 3, + DataRecordFormat: UnalignedPackedEncodingRules, + TsNumber: TS32253, + ReleaseIdentifierExtension: 4, }, - CdrByte:[]byte("abc"), + CdrByte: []byte("abc"), }, { - Hdr:CdrHeader { - CdrLength :6, - ReleaseIdentifier :Rel5, - VersionIdentifier :2, - DataRecordFormat :AlignedPackedEncodingRules1, - TsNumber : TS32205, - ReleaseIdentifierExtension :2, + Hdr: CdrHeader{ + CdrLength: 6, + ReleaseIdentifier: Rel5, + VersionIdentifier: 2, + DataRecordFormat: AlignedPackedEncodingRules1, + TsNumber: TS32205, + ReleaseIdentifierExtension: 2, }, - CdrByte:[]byte("ghjklm"), + CdrByte: []byte("ghjklm"), }, { - Hdr:CdrHeader { - CdrLength :2, - ReleaseIdentifier :Rel9, - VersionIdentifier :3, - DataRecordFormat :AlignedPackedEncodingRules1, - TsNumber : TS32225, - ReleaseIdentifierExtension :1, + Hdr: CdrHeader{ + CdrLength: 2, + ReleaseIdentifier: Rel9, + VersionIdentifier: 3, + DataRecordFormat: AlignedPackedEncodingRules1, + TsNumber: TS32225, + ReleaseIdentifierExtension: 1, }, - CdrByte:[]byte("cv"), + CdrByte: []byte("cv"), }, }, } testCases := []struct { - name string - in CDRFile + name string + in CDRFile }{ {"cdrfile1", cdrFile1}, {"cdrfile2", cdrFile2}, @@ -117,7 +120,7 @@ func TestCdrFile(t *testing.T) { for i, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - fileName := "encoding"+strconv.Itoa(i)+".txt" + fileName := "encoding" + strconv.Itoa(i) + ".txt" tc.in.Encoding(fileName) newCdrFile := CDRFile{} newCdrFile.Decoding(fileName) diff --git a/cmd/main.go b/cmd/main.go index 233fd31..6817e6b 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -108,7 +108,7 @@ func initLogFile(logNfPath []string) (string, error) { nfDir, _ := filepath.Split(path) tmpDir := filepath.Join(nfDir, "key") - if err := os.MkdirAll(tmpDir, 0775); err != nil { + if err := os.MkdirAll(tmpDir, 0o775); err != nil { logger.InitLog.Errorf("Make directory %s failed: %+v", tmpDir, err) return "", err } diff --git a/go.mod b/go.mod index 51a125c..56434ca 100644 --- a/go.mod +++ b/go.mod @@ -9,27 +9,28 @@ require ( github.com/fclairamb/ftpserverlib v0.21.0 github.com/fclairamb/go-log v0.4.1 github.com/fiorix/go-diameter v3.0.2+incompatible - github.com/free5gc/openapi v1.0.9-0.20240730084323-449098e08462 + github.com/free5gc/openapi v1.0.9-0.20240823100026-6a9f667e914f github.com/free5gc/util v1.0.6 github.com/gin-gonic/gin v1.9.1 github.com/google/uuid v1.3.0 github.com/ishidawataru/sctp v0.0.0-20230406120618-7ff4192f6ff2 // indirect github.com/jlaffaye/ftp v0.1.0 - github.com/sirupsen/logrus v1.9.0 - github.com/stretchr/testify v1.8.3 + github.com/sirupsen/logrus v1.9.3 + github.com/stretchr/testify v1.8.4 github.com/urfave/cli v1.22.5 go.mongodb.org/mongo-driver v1.11.3 gopkg.in/yaml.v2 v2.4.0 ) require ( + github.com/h2non/gock v1.2.0 github.com/pkg/errors v0.9.1 + go.uber.org/mock v0.4.0 golang.org/x/exp v0.0.0-20231127185646-65229373498e ) require ( cloud.google.com/go/compute v1.19.1 // indirect - github.com/antihax/optional v1.0.0 // indirect github.com/aws/aws-sdk-go v1.44.177 // indirect github.com/bytedance/sonic v1.9.1 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect @@ -41,8 +42,11 @@ require ( github.com/fclairamb/afero-gdrive v0.3.0 // indirect github.com/fclairamb/afero-s3 v0.3.1 // indirect github.com/fclairamb/afero-snd v0.1.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-mail/mail v2.3.1+incompatible // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect @@ -87,6 +91,11 @@ require ( github.com/xdg-go/stringprep v1.0.3 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.49.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect golang.org/x/arch v0.3.0 // indirect golang.org/x/crypto v0.22.0 // indirect golang.org/x/net v0.24.0 // indirect @@ -101,6 +110,5 @@ require ( google.golang.org/protobuf v1.33.0 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect - gopkg.in/h2non/gock.v1 v1.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 2739d8c..a609108 100644 --- a/go.sum +++ b/go.sum @@ -61,7 +61,6 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -145,12 +144,14 @@ github.com/fclairamb/go-log v0.0.0-20210717204555-d370617e3635/go.mod h1:iqmym8a github.com/fclairamb/go-log v0.0.0-20210725225107-80efc81cb386/go.mod h1:iqmym8aI6xBbZXnZSPjElrmQrlEwjwEemOmIzKaTBM8= github.com/fclairamb/go-log v0.4.1 h1:rLtdSG9x2pK41AIAnE8WYpl05xBJfw1ZyYxZaXFcBsM= github.com/fclairamb/go-log v0.4.1/go.mod h1:sw1KvnkZ4wKCYkvy4SL3qVZcJSWFP8Ure4pM3z+KNn4= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fiorix/go-diameter v3.0.2+incompatible h1:PLk2NkqMYILlEdeiz0hJVB3xcuuL+Gc9iCaEgjfbs5w= github.com/fiorix/go-diameter v3.0.2+incompatible/go.mod h1:GgNrDCADT8o3k8zV1UsI473j8CFdLGY9ikZYDNEeYU8= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/free5gc/openapi v1.0.9-0.20240730084323-449098e08462 h1:bK9UWqOhoddpAW9RfZRp4DPZNnPfEUeHvo4I86YAuzA= -github.com/free5gc/openapi v1.0.9-0.20240730084323-449098e08462/go.mod h1:afeuEQ21QCQDxZHnFjCmYrq3gBi+cd/WDNSUbaMcILo= +github.com/free5gc/openapi v1.0.9-0.20240823100026-6a9f667e914f h1:b//Fa0CvIDU7fufqMcrEgbVUqpubokK/lFgkTxN3fGM= +github.com/free5gc/openapi v1.0.9-0.20240823100026-6a9f667e914f/go.mod h1:aKw6uGzEibGDrn9++w4/JpWxaaUBo7GaqsvuFKU9fl4= github.com/free5gc/util v1.0.6 h1:dBt9drcXtYKE/cY5XuQcuffgsYclPIpIArhSeS6M+DQ= github.com/free5gc/util v1.0.6/go.mod h1:eSGN7POUM8LNTvg/E591XR6447a6/w1jFWGKNZPHcXw= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -175,6 +176,11 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-mail/mail v2.3.1+incompatible h1:UzNOn0k5lpfVtO31cK3hn6I4VEVGhe3lX8AJBAxXExM= github.com/go-mail/mail v2.3.1+incompatible/go.mod h1:VPWjmmNyRsWXQZHVHT3g0YbIINUkSmuKOiLIDkWbL6M= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= @@ -245,8 +251,8 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -282,6 +288,8 @@ github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51 github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/h2non/gock v1.2.0 h1:K6ol8rfrRkUOefooBC8elXoaNGYkpp7y2qcxGG6BzUE= +github.com/h2non/gock v1.2.0/go.mod h1:tNhoxHYW2W42cYkYb1WqzdbYIieALC99kpYr7rH/BQk= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/consul/api v1.8.1/go.mod h1:sDjTOq0yUyv5G4h+BqSea7Fn6BU+XbolEz1952UB+mk= @@ -457,8 +465,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= @@ -483,8 +491,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -533,8 +542,20 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.49.0 h1:RtcvQ4iw3w9NBB5yRwgA4sSa82rfId7n4atVpvKx3bY= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.49.0/go.mod h1:f/PbKbRd4cdUICWell6DmzvVJ7QrmBgFrRHjXmAXbK4= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -966,8 +987,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= -gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk= gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/internal/abmf/abmf.go b/internal/abmf/abmf.go index 65155d8..117ea80 100644 --- a/internal/abmf/abmf.go +++ b/internal/abmf/abmf.go @@ -5,16 +5,16 @@ import ( "strconv" "time" - chf_context "github.com/free5gc/chf/internal/context" - "github.com/free5gc/chf/pkg/factory" - "github.com/fiorix/go-diameter/diam" "github.com/fiorix/go-diameter/diam/datatype" "github.com/fiorix/go-diameter/diam/dict" "github.com/fiorix/go-diameter/diam/sm/smpeer" + charging_code "github.com/free5gc/chf/ccs_diameter/code" charging_datatype "github.com/free5gc/chf/ccs_diameter/datatype" + chf_context "github.com/free5gc/chf/internal/context" "github.com/free5gc/chf/internal/logger" + "github.com/free5gc/chf/pkg/factory" ) func SendAccountDebitRequest( @@ -25,7 +25,6 @@ func SendAccountDebitRequest( abmfDiameter := factory.ChfConfig.Configuration.AbmfDiameter addr := abmfDiameter.HostIPv4 + ":" + strconv.Itoa(abmfDiameter.Port) conn, err := ue.AbmfClient.DialNetworkTLS(abmfDiameter.Protocol, addr, abmfDiameter.Tls.Pem, abmfDiameter.Tls.Key) - if err != nil { return nil, err } @@ -54,8 +53,8 @@ func SendAccountDebitRequest( select { case m := <-ue.AcctChan: var cca charging_datatype.AccountDebitResponse - if err := m.Unmarshal(&cca); err != nil { - return nil, fmt.Errorf("Failed to parse message from %v", err) + if errMarshal := m.Unmarshal(&cca); err != nil { + return nil, fmt.Errorf("Failed to parse message from %v", errMarshal) } return &cca, nil diff --git a/internal/cgf/cgf.go b/internal/cgf/cgf.go index 770b182..7dba1b9 100644 --- a/internal/cgf/cgf.go +++ b/internal/cgf/cgf.go @@ -16,9 +16,10 @@ import ( "github.com/fclairamb/ftpserver/config" "github.com/fclairamb/ftpserver/server" ftpserver "github.com/fclairamb/ftpserverlib" + "github.com/jlaffaye/ftp" + "github.com/free5gc/chf/internal/logger" "github.com/free5gc/chf/pkg/factory" - "github.com/jlaffaye/ftp" ) type Cgf struct { @@ -52,6 +53,7 @@ type FtpConfig struct { } var cgf *Cgf + var CGFEnable bool = false func OpenServer(ctx context.Context, wg *sync.WaitGroup) *Cgf { @@ -92,8 +94,8 @@ func OpenServer(ctx context.Context, wg *sync.WaitGroup) *Cgf { encoder := json.NewEncoder(file) encoder.SetIndent("", " ") - if err := encoder.Encode(cgf.ftpConfig); err != nil { - panic(err) + if errEncode := encoder.Encode(cgf.ftpConfig); errEncode != nil { + panic(errEncode) } conf, errConfig := config.NewConfig("/tmp/config.json", logger.FtpServerLog) @@ -165,7 +167,6 @@ func SendCDR(supi string) error { if cgf.conn == nil { err := Login() - if err != nil { return err } @@ -176,7 +177,6 @@ func SendCDR(supi string) error { if ping_err != nil { logger.CgfLog.Infof("Faile to ping FTP server, relogin...") err := Login() - if err != nil { return err } @@ -225,8 +225,10 @@ func SendCDR(supi string) error { return nil } -const FTP_LOGIN_RETRY_NUMBER = 3 -const FTP_LOGIN_RETRY_WAITING_TIME = 1 * time.Second // second +const ( + FTP_LOGIN_RETRY_NUMBER = 3 + FTP_LOGIN_RETRY_WAITING_TIME = 1 * time.Second // second +) func (f *Cgf) Serve(ctx context.Context, wg *sync.WaitGroup) { go func() { @@ -288,9 +290,9 @@ func (f *Cgf) Terminate() { } for _, file := range files { - if _, err := os.Stat(file); err == nil { + if _, errStat := os.Stat(file); errStat == nil { logger.CgfLog.Infof("Remove CDR file: " + file) - if err := os.Remove(file); err != nil { + if errRemove := os.Remove(file); errRemove != nil { logger.CgfLog.Warnf("Failed to remove CDR file: %s\n", file) } } diff --git a/internal/context/chf_context_init.go b/internal/context/chf_context_init.go index 2d90f23..cbf67e0 100644 --- a/internal/context/chf_context_init.go +++ b/internal/context/chf_context_init.go @@ -87,12 +87,14 @@ func InitChfContext(context *CHFContext) { context.Url = string(context.UriScheme) + "://" + context.RegisterIPv4 + ":" + strconv.Itoa(context.SBIPort) - context.NfService = make(map[models.ServiceName]models.NfService) + context.NfService = make(map[models.ServiceName]models.NrfNfManagementNfService) AddNfServices(&context.NfService, config, context) } -func AddNfServices(serviceMap *map[models.ServiceName]models.NfService, config *factory.Config, context *CHFContext) { - var nfService models.NfService +func AddNfServices( + serviceMap *map[models.ServiceName]models.NrfNfManagementNfService, config *factory.Config, context *CHFContext, +) { + var nfService models.NrfNfManagementNfService var ipEndPoints []models.IpEndPoint var nfServiceVersions []models.NfServiceVersion services := *serviceMap @@ -103,7 +105,7 @@ func AddNfServices(serviceMap *map[models.ServiceName]models.NfService, config * var ipEndPoint models.IpEndPoint ipEndPoint.Ipv4Address = context.RegisterIPv4 ipEndPoint.Port = int32(context.SBIPort) - ipEndPoint.Transport = models.TransportProtocol_TCP + ipEndPoint.Transport = models.NrfNfManagementTransportProtocol_TCP ipEndPoints = append(ipEndPoints, ipEndPoint) var nfServiceVersion models.NfServiceVersion @@ -114,7 +116,7 @@ func AddNfServices(serviceMap *map[models.ServiceName]models.NfService, config * nfService.Scheme = context.UriScheme nfService.NfServiceStatus = models.NfServiceStatus_REGISTERED - nfService.IpEndPoints = &ipEndPoints - nfService.Versions = &nfServiceVersions + nfService.IpEndPoints = ipEndPoints + nfService.Versions = nfServiceVersions services[models.ServiceName_NCHF_CONVERGEDCHARGING] = nfService } diff --git a/internal/context/context.go b/internal/context/context.go index b30f991..ccfac5d 100644 --- a/internal/context/context.go +++ b/internal/context/context.go @@ -7,6 +7,7 @@ import ( "sync" "github.com/fiorix/go-diameter/diam/sm" + "github.com/free5gc/chf/internal/logger" "github.com/free5gc/openapi/models" "github.com/free5gc/openapi/oauth" @@ -16,7 +17,6 @@ import ( var chfContext CHFContext func Init() { - InitChfContext(&chfContext) } @@ -34,7 +34,7 @@ type CHFContext struct { BindingIPv4 string RegisterIPv4 string SBIPort int - NfService map[models.ServiceName]models.NfService + NfService map[models.ServiceName]models.NrfNfManagementNfService RecordSequenceNumber map[string]int64 LocalRecordSequenceNumber uint64 NrfUri string @@ -115,12 +115,12 @@ func (c *CHFContext) GetSelfID() string { return c.NfId } -func (c *CHFContext) GetTokenCtx(serviceName models.ServiceName, targetNF models.NfType) ( +func (c *CHFContext) GetTokenCtx(serviceName models.ServiceName, targetNF models.NrfNfManagementNfType) ( context.Context, *models.ProblemDetails, error, ) { if !c.OAuth2Required { return context.TODO(), nil, nil } - return oauth.GetTokenCtx(models.NfType_CHF, targetNF, + return oauth.GetTokenCtx(models.NrfNfManagementNfType_CHF, targetNF, c.NfId, c.NrfUri, string(serviceName)) } diff --git a/internal/context/ue_context.go b/internal/context/ue_context.go index 5e85b5a..41e0f49 100644 --- a/internal/context/ue_context.go +++ b/internal/context/ue_context.go @@ -9,6 +9,7 @@ import ( "github.com/fiorix/go-diameter/diam/datatype" "github.com/fiorix/go-diameter/diam/dict" "github.com/fiorix/go-diameter/diam/sm" + charging_datatype "github.com/free5gc/chf/ccs_diameter/datatype" "github.com/free5gc/chf/cdr/cdrType" "github.com/free5gc/chf/pkg/factory" @@ -54,6 +55,7 @@ func (ue *ChfUe) FindRatingGroup(ratingGroup int32) bool { } return false } + func (ue *ChfUe) init() { config := factory.ChfConfig diff --git a/internal/logger/logger.go b/internal/logger/logger.go index 5b91a91..8263014 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -3,8 +3,9 @@ package logger import ( golog "github.com/fclairamb/go-log" adapter "github.com/fclairamb/go-log/logrus" - logger_util "github.com/free5gc/util/logger" "github.com/sirupsen/logrus" + + logger_util "github.com/free5gc/util/logger" ) var ( @@ -16,6 +17,7 @@ var ( CtxLog *logrus.Entry SBILog *logrus.Entry ConsumerLog *logrus.Entry + ProcLog *logrus.Entry GinLog *logrus.Entry ChargingdataPostLog *logrus.Entry NotifyEventLog *logrus.Entry @@ -42,6 +44,7 @@ func init() { CtxLog = NfLog.WithField(logger_util.FieldCategory, "CTX") SBILog = NfLog.WithField(logger_util.FieldCategory, "SBI") ConsumerLog = NfLog.WithField(logger_util.FieldCategory, "Consumer") + ProcLog = NfLog.WithField(logger_util.FieldCategory, "Proc") GinLog = NfLog.WithField(logger_util.FieldCategory, "GIN") ChargingdataPostLog = NfLog.WithField(logger_util.FieldCategory, "ChargingPost") NotifyEventLog = NfLog.WithField(logger_util.FieldCategory, "NotifyEvent") diff --git a/internal/rating/rating.go b/internal/rating/rating.go index ff98b1b..66e89f4 100644 --- a/internal/rating/rating.go +++ b/internal/rating/rating.go @@ -5,16 +5,16 @@ import ( "strconv" "time" - chf_context "github.com/free5gc/chf/internal/context" - "github.com/free5gc/chf/pkg/factory" - "github.com/fiorix/go-diameter/diam" "github.com/fiorix/go-diameter/diam/datatype" "github.com/fiorix/go-diameter/diam/dict" "github.com/fiorix/go-diameter/diam/sm/smpeer" + charging_code "github.com/free5gc/chf/ccs_diameter/code" charging_datatype "github.com/free5gc/chf/ccs_diameter/datatype" + chf_context "github.com/free5gc/chf/internal/context" "github.com/free5gc/chf/internal/logger" + "github.com/free5gc/chf/pkg/factory" ) func SendServiceUsageRequest( @@ -51,8 +51,8 @@ func SendServiceUsageRequest( select { case m := <-ue.RatingChan: var sua charging_datatype.ServiceUsageResponse - if err := m.Unmarshal(&sua); err != nil { - return nil, fmt.Errorf("Failed to parse message from %v", err) + if errMarshal := m.Unmarshal(&sua); errMarshal != nil { + return nil, fmt.Errorf("Failed to parse message from %v", errMarshal) } return &sua, nil case <-time.After(5 * time.Second): diff --git a/internal/sbi/api_convergedcharging.go b/internal/sbi/api_convergedcharging.go index 496019e..0fbc100 100644 --- a/internal/sbi/api_convergedcharging.go +++ b/internal/sbi/api_convergedcharging.go @@ -1,7 +1,8 @@ /* * Nchf_ConvergedCharging * - * ConvergedCharging Service © 2021, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved. + * ConvergedCharging Service + * © 2021, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved. * * API version: 3.0.3 * Generated by: OpenAPI Generator (https://openapi-generator.tech) @@ -14,25 +15,21 @@ import ( "strconv" "strings" - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/models" - "github.com/gin-gonic/gin" "github.com/free5gc/chf/internal/logger" + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" ) -// Index is the index handler. -func Index(c *gin.Context) { - c.String(http.StatusOK, "Hello World!") -} - func (s *Server) getConvergenChargingRoutes() []Route { return []Route{ { Method: http.MethodGet, Pattern: "/", - APIFunc: Index, + APIFunc: func(c *gin.Context) { + c.String(http.StatusOK, "Hello free5GC!") + }, }, { Method: http.MethodPost, @@ -64,7 +61,7 @@ func (s *Server) getConvergenChargingRoutes() []Route { // ChargingdataChargingDataRefReleasePost - func (s *Server) ChargingdataChargingDataRefReleasePost(c *gin.Context) { - var chargingDataReq models.ChargingDataRequest + var chargingDataReq models.ChfConvergedChargingChargingDataRequest requestBody, err := c.GetRawData() if err != nil { @@ -98,7 +95,7 @@ func (s *Server) ChargingdataChargingDataRefReleasePost(c *gin.Context) { // ChargingdataChargingDataRefUpdatePost func (s *Server) ChargingdataChargingDataRefUpdatePost(c *gin.Context) { - var chargingDataReq models.ChargingDataRequest + var chargingDataReq models.ChfConvergedChargingChargingDataRequest requestBody, err := c.GetRawData() if err != nil { @@ -132,7 +129,7 @@ func (s *Server) ChargingdataChargingDataRefUpdatePost(c *gin.Context) { // ChargingdataPost func (s *Server) ChargingdataPost(c *gin.Context) { - var chargingDataReq models.ChargingDataRequest + var chargingDataReq models.ChfConvergedChargingChargingDataRequest requestBody, err := c.GetRawData() if err != nil { diff --git a/internal/sbi/api_offlineonlycharging.go b/internal/sbi/api_offlineonlycharging.go new file mode 100644 index 0000000..28454d0 --- /dev/null +++ b/internal/sbi/api_offlineonlycharging.go @@ -0,0 +1,60 @@ +/* + * Nchf_OfflineOnlyCharging + * + * ConvergedCharging Service + * © 2021, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved. + * + * API version: 3.0.3 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package sbi + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func (s *Server) getOfflineOnlyChargingRoutes() []Route { + return []Route{ + { + Name: "Index", + Method: http.MethodGet, + Pattern: "/", + APIFunc: func(c *gin.Context) { + c.String(http.StatusOK, "Hello free5GC!") + }, + }, + { + Name: "OfflinechargingdataOfflineChargingDataRefReleasePost", + Method: http.MethodPost, + Pattern: "/offlinechargingdata/:OfflineChargingDataRef/release", + APIFunc: s.OfflinechargingdataOfflineChargingDataRefReleasePost, + }, + { + Name: "OfflinechargingdataOfflineChargingDataRefUpdatePost", + Method: http.MethodPost, + Pattern: "/offlinechargingdata/:OfflineChargingDataRef/update", + APIFunc: s.OfflinechargingdataOfflineChargingDataRefUpdatePost, + }, + { + Name: "OfflinechargingdataPost", + Method: http.MethodPost, + Pattern: "/offlinechargingdata", + APIFunc: s.OfflinechargingdataPost, + }, + } +} + +func (s *Server) OfflinechargingdataOfflineChargingDataRefReleasePost(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{}) +} + +func (s *Server) OfflinechargingdataOfflineChargingDataRefUpdatePost(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{}) +} + +func (s *Server) OfflinechargingdataPost(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{}) +} diff --git a/internal/sbi/api_spendinglimitcontrol.go b/internal/sbi/api_spendinglimitcontrol.go new file mode 100644 index 0000000..6987ca8 --- /dev/null +++ b/internal/sbi/api_spendinglimitcontrol.go @@ -0,0 +1,60 @@ +/* + * Nchf_SpendingLimitControl + * + * ConvergedCharging Service + * © 2021, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved. + * + * API version: 3.0.3 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package sbi + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func (s *Server) getSpendingLimitControlRoutes() []Route { + return []Route{ + { + Name: "Index", + Method: http.MethodGet, + Pattern: "/", + APIFunc: func(c *gin.Context) { + c.String(http.StatusOK, "Hello free5GC!") + }, + }, + { + Name: "SubscriptionsPost", + Method: http.MethodPost, + Pattern: "/subscriptions", + APIFunc: s.SubscriptionsPost, + }, + { + Name: "SubscriptionsSubscriptionIdDelete", + Method: http.MethodDelete, + Pattern: "/subscriptions/:subscriptionId", + APIFunc: s.SubscriptionsSubscriptionIdDelete, + }, + { + Name: "SubscriptionsSubscriptionIdPut", + Method: http.MethodPut, + Pattern: "/subscriptions/:subscriptionId", + APIFunc: s.SubscriptionsSubscriptionIdPut, + }, + } +} + +func (s *Server) SubscriptionsPost(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{}) +} + +func (s *Server) SubscriptionsSubscriptionIdDelete(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{}) +} + +func (s *Server) SubscriptionsSubscriptionIdPut(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{}) +} diff --git a/internal/sbi/consumer/consumer.go b/internal/sbi/consumer/consumer.go index 49de227..9919ee0 100644 --- a/internal/sbi/consumer/consumer.go +++ b/internal/sbi/consumer/consumer.go @@ -2,9 +2,8 @@ package consumer import ( "github.com/free5gc/chf/pkg/app" - - "github.com/free5gc/openapi/Nnrf_NFDiscovery" - "github.com/free5gc/openapi/Nnrf_NFManagement" + Nnrf_NFDiscovery "github.com/free5gc/openapi/nrf/NFDiscovery" + Nnrf_NFManagement "github.com/free5gc/openapi/nrf/NFManagement" ) type ConsumerChf interface { diff --git a/internal/sbi/consumer/nrf_service.go b/internal/sbi/consumer/nrf_service.go index b115a62..ff8efab 100644 --- a/internal/sbi/consumer/nrf_service.go +++ b/internal/sbi/consumer/nrf_service.go @@ -2,19 +2,18 @@ package consumer import ( "context" - "fmt" - "net/http" "strings" "sync" "time" + "github.com/pkg/errors" + chf_context "github.com/free5gc/chf/internal/context" "github.com/free5gc/chf/internal/logger" "github.com/free5gc/openapi" - "github.com/free5gc/openapi/Nnrf_NFDiscovery" - "github.com/free5gc/openapi/Nnrf_NFManagement" "github.com/free5gc/openapi/models" - "github.com/pkg/errors" + Nnrf_NFDiscovery "github.com/free5gc/openapi/nrf/NFDiscovery" + Nnrf_NFManagement "github.com/free5gc/openapi/nrf/NFManagement" ) type nnrfService struct { @@ -34,7 +33,7 @@ func (s *nnrfService) getNFManagementClient(uri string) *Nnrf_NFManagement.APICl s.nfMngmntMu.RLock() client, ok := s.nfMngmntClients[uri] if ok { - defer s.nfMngmntMu.RUnlock() + s.nfMngmntMu.RUnlock() return client } @@ -56,7 +55,7 @@ func (s *nnrfService) getNFDiscClient(uri string) *Nnrf_NFDiscovery.APIClient { s.nfDiscMu.RLock() client, ok := s.nfDiscClients[uri] if ok { - defer s.nfDiscMu.RUnlock() + s.nfDiscMu.RUnlock() return client } @@ -67,110 +66,98 @@ func (s *nnrfService) getNFDiscClient(uri string) *Nnrf_NFDiscovery.APIClient { s.nfDiscMu.RUnlock() s.nfDiscMu.Lock() defer s.nfDiscMu.Unlock() + s.nfDiscClients[uri] = client return client } func (s *nnrfService) SendSearchNFInstances( - nrfUri string, targetNfType, requestNfType models.NfType, param Nnrf_NFDiscovery.SearchNFInstancesParamOpts, + nrfUri string, targetNfType, + requestNfType models.NrfNfManagementNfType, + param Nnrf_NFDiscovery.SearchNFInstancesRequest, ) ( *models.SearchResult, error, ) { - // Set client and set url chfContext := s.consumer.Context() client := s.getNFDiscClient(chfContext.NrfUri) - ctx, _, err := chf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_DISC, models.NfType_NRF) + ctx, _, err := s.consumer.Context().GetTokenCtx(models.ServiceName_NNRF_DISC, models.NrfNfManagementNfType_NRF) if err != nil { return nil, err } - result, res, err := client.NFInstancesStoreApi.SearchNFInstances(ctx, targetNfType, requestNfType, ¶m) - if err != nil { + res, err := client.NFInstancesStoreApi.SearchNFInstances(ctx, ¶m) + if err != nil || res == nil { logger.ConsumerLog.Errorf("SearchNFInstances failed: %+v", err) + return nil, 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") - } - + result := res.SearchResult return &result, nil } -func (s *nnrfService) SendDeregisterNFInstance() (problemDetails *models.ProblemDetails, err error) { +func (s *nnrfService) SendDeregisterNFInstance() (*models.ProblemDetails, error) { logger.ConsumerLog.Infof("Send Deregister NFInstance") - ctx, pd, err := chf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_NFM, models.NfType_NRF) + ctx, pd, err := chf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_NFM, models.NrfNfManagementNfType_NRF) if err != nil { return pd, err } chfContext := s.consumer.Context() client := s.getNFManagementClient(chfContext.NrfUri) + request := &Nnrf_NFManagement.DeregisterNFInstanceRequest{ + NfInstanceID: &chfContext.NfId, + } - var res *http.Response - - res, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(ctx, chfContext.NfId) - if err == nil { - return problemDetails, err - } else if res != nil { - defer func() { - if resCloseErr := res.Body.Close(); resCloseErr != nil { - logger.ConsumerLog.Errorf("DeregisterNFInstance response cannot close: %+v", resCloseErr) - } - }() - if res.Status != err.Error() { - return problemDetails, err + _, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(ctx, request) + if apiErr, ok := err.(openapi.GenericOpenAPIError); ok { + // API error + if deregNfError, okDeg := apiErr.Model().(Nnrf_NFManagement.DeregisterNFInstanceError); okDeg { + return &deregNfError.ProblemDetails, err } - problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem - } else { - err = openapi.ReportError("server no response") + return nil, err } - return problemDetails, err + return nil, err } func (s *nnrfService) RegisterNFInstance(ctx context.Context) ( - resouceNrfUri string, retrieveNfInstanceID string, err error) { + resouceNrfUri string, retrieveNfInstanceID string, err error, +) { chfContext := s.consumer.Context() - client := s.getNFManagementClient(chfContext.NrfUri) nfProfile, err := s.buildNfProfile(chfContext) if err != nil { return "", "", errors.Wrap(err, "RegisterNFInstance buildNfProfile()") } - var nf models.NfProfile - var res *http.Response + var nf models.NrfNfManagementNfProfile + var res *Nnrf_NFManagement.RegisterNFInstanceResponse + registerNFInstanceRequest := &Nnrf_NFManagement.RegisterNFInstanceRequest{ + NfInstanceID: &chfContext.NfId, + NrfNfManagementNfProfile: &nfProfile, + } for { select { case <-ctx.Done(): return "", "", errors.Errorf("Context Cancel before RegisterNFInstance") default: } - nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(ctx, chfContext.NfId, nfProfile) + res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(ctx, registerNFInstanceRequest) if err != nil || res == nil { logger.ConsumerLog.Errorf("CHF register to NRF Error[%v]", err) time.Sleep(2 * time.Second) continue } - defer func() { - if resCloseErr := res.Body.Close(); resCloseErr != nil { - logger.ConsumerLog.Errorf("RegisterNFInstance response body cannot close: %+v", resCloseErr) - } - }() - status := res.StatusCode - if status == http.StatusOK { + nf = res.NrfNfManagementNfProfile + + // http.StatusOK + if res.Location == "" { // NFUpdate break - } else if status == http.StatusCreated { + } else { // http.StatusCreated // NFRegister - resourceUri := res.Header.Get("Location") + resourceUri := res.Location resouceNrfUri = resourceUri[:strings.Index(resourceUri, "/nnrf-nfm/")] retrieveNfInstanceID = resourceUri[strings.LastIndex(resourceUri, "/")+1:] @@ -188,32 +175,31 @@ func (s *nnrfService) RegisterNFInstance(ctx context.Context) ( } break - } else { - fmt.Println(fmt.Errorf("handler returned wrong status code %d", status)) - fmt.Println("NRF return wrong status code", status) } } return resouceNrfUri, retrieveNfInstanceID, err } -func (s *nnrfService) buildNfProfile(chfContext *chf_context.CHFContext) (profile models.NfProfile, err error) { +func (s *nnrfService) buildNfProfile( + chfContext *chf_context.CHFContext, +) (profile models.NrfNfManagementNfProfile, err error) { profile.NfInstanceId = chfContext.NfId - profile.NfType = models.NfType_CHF - profile.NfStatus = models.NfStatus_REGISTERED + profile.NfType = models.NrfNfManagementNfType_CHF + profile.NfStatus = models.NrfNfManagementNfStatus_REGISTERED profile.Ipv4Addresses = append(profile.Ipv4Addresses, chfContext.RegisterIPv4) - services := []models.NfService{} + services := []models.NrfNfManagementNfService{} for _, nfService := range chfContext.NfService { services = append(services, nfService) } if len(services) > 0 { - profile.NfServices = &services + profile.NfServices = services } profile.ChfInfo = &models.ChfInfo{ // Todo // SupiRanges: &[]models.SupiRange{ // { - // //from TS 29.510 6.1.6.2.9 example2 - // //no need to set supirange in this moment 2019/10/4 + // // from TS 29.510 6.1.6.2.9 example2 + // // no need to set supirange in this moment 2019/10/4 // Start: "123456789040000", // End: "123456789059999", // Pattern: "^imsi-12345678904[0-9]{4}$", diff --git a/internal/sbi/consumer/nrf_service_test.go b/internal/sbi/consumer/nrf_service_test.go new file mode 100644 index 0000000..a7b7c59 --- /dev/null +++ b/internal/sbi/consumer/nrf_service_test.go @@ -0,0 +1,70 @@ +package consumer + +import ( + "context" + "testing" + + "github.com/h2non/gock" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" + + chf_context "github.com/free5gc/chf/internal/context" + "github.com/free5gc/chf/pkg/app" + "github.com/free5gc/openapi" +) + +func Test_nnrfService_RegisterNFInstance(t *testing.T) { + defer gock.Off() // Flush pending mocks after test execution + + openapi.InterceptH2CClient() + defer openapi.RestoreH2CClient() + + gock.New("http://127.0.0.10:8000"). + Put("/nnrf-nfm/v1/nf-instances/1"). + Reply(201). + JSON(map[string]string{}) + + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mockApp := app.NewMockApp(ctrl) + consumer, err := NewConsumer(mockApp) + require.NoError(t, err) + + mockApp.EXPECT().Context().Times(1).Return( + &chf_context.CHFContext{ + NrfUri: "http://127.0.0.10:8000", + NfId: "1", + }, + ) + + _, _, err = consumer.RegisterNFInstance(context.Background()) + require.NoError(t, err) +} + +func Test_nnrfService_SendDeregisterNFInstance(t *testing.T) { + defer gock.Off() // Flush pending mocks after test execution + + openapi.InterceptH2CClient() + defer openapi.RestoreH2CClient() + + gock.New("http://127.0.0.10:8000"). + Delete("/nnrf-nfm/v1/nf-instances/1"). + Reply(204). + JSON(map[string]string{}) + + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mockApp := app.NewMockApp(ctrl) + consumer, err := NewConsumer(mockApp) + require.NoError(t, err) + + mockApp.EXPECT().Context().Times(1).Return( + &chf_context.CHFContext{ + NrfUri: "http://127.0.0.10:8000", + NfId: "1", + }, + ) + + _, err = consumer.SendDeregisterNFInstance() + require.NoError(t, err) +} diff --git a/internal/sbi/processor/cdr.go b/internal/sbi/processor/cdr.go index fb4ab90..7be2efc 100644 --- a/internal/sbi/processor/cdr.go +++ b/internal/sbi/processor/cdr.go @@ -1,6 +1,7 @@ package processor import ( + "fmt" "strings" "time" @@ -14,7 +15,10 @@ import ( ) func (p *Processor) OpenCDR( - chargingData models.ChargingDataRequest, ue *chf_context.ChfUe, sessionId string, partialRecord bool, + chargingData models.ChfConvergedChargingChargingDataRequest, + ue *chf_context.ChfUe, + sessionId string, + partialRecord bool, ) (*cdrType.CHFRecord, error) { // 32.298 5.1.5.0.1 for CHF CDR field var chfCdr cdrType.ChargingRecord @@ -126,7 +130,6 @@ func (p *Processor) OpenCDR( consumerInfo.NetworkFunctionPLMNIdentifier = &cdrType.PLMNId{ Value: plmnIdByte.Value, } - } logger.ChargingdataPostLog.Infof("%s charging event", chargingData.NfConsumerIdentification.NodeFunctionality) switch chargingData.NfConsumerIdentification.NodeFunctionality { @@ -197,7 +200,13 @@ func (p *Processor) OpenCDR( return &cdr, nil } -func (p *Processor) UpdateCDR(record *cdrType.CHFRecord, chargingData models.ChargingDataRequest) error { +func (p *Processor) UpdateCDR( + record *cdrType.CHFRecord, chargingData models.ChfConvergedChargingChargingDataRequest, +) error { + if record == nil { + return fmt.Errorf("CHFRecord is nil") + } + // map SBI IE to CDR field chfCdr := record.ChargingFunctionRecord diff --git a/internal/sbi/processor/converged_charging.go b/internal/sbi/processor/converged_charging.go index 4855873..cbc27e5 100644 --- a/internal/sbi/processor/converged_charging.go +++ b/internal/sbi/processor/converged_charging.go @@ -8,11 +8,11 @@ import ( "strings" "time" - charging_datatype "github.com/free5gc/chf/ccs_diameter/datatype" + "github.com/fiorix/go-diameter/diam/datatype" "github.com/gin-gonic/gin" "golang.org/x/exp/constraints" - "github.com/fiorix/go-diameter/diam/datatype" + charging_datatype "github.com/free5gc/chf/ccs_diameter/datatype" "github.com/free5gc/chf/cdr/cdrType" "github.com/free5gc/chf/internal/abmf" "github.com/free5gc/chf/internal/cgf" @@ -20,6 +20,7 @@ import ( "github.com/free5gc/chf/internal/logger" "github.com/free5gc/chf/internal/rating" "github.com/free5gc/chf/internal/util" + Nchf_ConvergedCharging "github.com/free5gc/openapi/chf/ConvergedCharging" "github.com/free5gc/openapi/models" ) @@ -56,33 +57,20 @@ func (p *Processor) NotifyRecharge(ueId string, rg int32) { func (p *Processor) SendChargingNotification(notifyUri string, notifyRequest models.ChargingNotifyRequest) { client := util.GetNchfChargingNotificationCallbackClient() logger.NotifyEventLog.Warn("Send Charging Notification to SMF: uri: ", notifyUri) - httpResponse, err := client.DefaultCallbackApi.ChargingNotification(context.Background(), notifyUri, notifyRequest) + chargingNotifyRequest := Nchf_ConvergedCharging.NewPostChargingNotificationRequest() + chargingNotifyRequest.SetChargingNotifyRequest(notifyRequest) + _, err := client.DefaultApi.PostChargingNotification(context.Background(), notifyUri, chargingNotifyRequest) if err != nil { - if httpResponse != nil { - logger.NotifyEventLog.Warnf("Charging Notification Error[%s]", httpResponse.Status) - } else { - logger.NotifyEventLog.Warnf("Charging Notification Failed[%s]", err.Error()) - } - return - } else if httpResponse == nil { - logger.NotifyEventLog.Warnln("Charging Notification[HTTP Response is nil]") + logger.NotifyEventLog.Warnf("Charging Notification Failed[%s]", err.Error()) return } - defer func() { - if resCloseErr := httpResponse.Body.Close(); resCloseErr != nil { - logger.NotifyEventLog.Errorf("NFInstancesStoreApi response body cannot close: %+v", resCloseErr) - } - }() - if httpResponse.StatusCode != http.StatusOK && httpResponse.StatusCode != http.StatusNoContent { - logger.NotifyEventLog.Warnf("Charging Notification Failed") - } else { - logger.NotifyEventLog.Tracef("Charging Notification Success") - } + + logger.NotifyEventLog.Tracef("Charging Notification Success") } func (p *Processor) HandleChargingdataInitial( c *gin.Context, - chargingdata models.ChargingDataRequest, + chargingdata models.ChfConvergedChargingChargingDataRequest, ) { logger.ChargingdataPostLog.Infof("HandleChargingdataInitial") response, locationURI, problemDetails := p.ChargingDataCreate(chargingdata) @@ -104,7 +92,7 @@ func (p *Processor) HandleChargingdataInitial( func (p *Processor) HandleChargingdataUpdate( c *gin.Context, - chargingdata models.ChargingDataRequest, + chargingdata models.ChfConvergedChargingChargingDataRequest, chargingSessionId string, ) { logger.ChargingdataPostLog.Infof("HandleChargingdataUpdate") @@ -126,7 +114,7 @@ func (p *Processor) HandleChargingdataUpdate( func (p *Processor) HandleChargingdataRelease( c *gin.Context, - chargingdata models.ChargingDataRequest, + chargingdata models.ChfConvergedChargingChargingDataRequest, chargingSessionId string, ) { logger.ChargingdataPostLog.Infof("HandleChargingdateRelease") @@ -139,9 +127,13 @@ func (p *Processor) HandleChargingdataRelease( c.JSON(int(problemDetails.Status), problemDetails) } -func (p *Processor) ChargingDataCreate(chargingData models.ChargingDataRequest) (*models.ChargingDataResponse, - string, *models.ProblemDetails) { - var responseBody models.ChargingDataResponse +func (p *Processor) ChargingDataCreate( + chargingData models.ChfConvergedChargingChargingDataRequest, +) ( + *models.ChfConvergedChargingChargingDataResponse, + string, *models.ProblemDetails, +) { + var responseBody models.ChfConvergedChargingChargingDataResponse var chargingSessionId string self := chf_context.GetSelf() @@ -217,8 +209,8 @@ func (p *Processor) ChargingDataCreate(chargingData models.ChargingDataRequest) } func (p *Processor) ChargingDataUpdate( - chargingData models.ChargingDataRequest, chargingSessionId string, -) (*models.ChargingDataResponse, *models.ProblemDetails) { + chargingData models.ChfConvergedChargingChargingDataRequest, chargingSessionId string, +) (*models.ChfConvergedChargingChargingDataResponse, *models.ProblemDetails) { var records []*cdrType.CHFRecord self := chf_context.GetSelf() @@ -294,7 +286,8 @@ func (p *Processor) ChargingDataUpdate( } func (p *Processor) ChargingDataRelease( - chargingData models.ChargingDataRequest, chargingSessionId string) *models.ProblemDetails { + chargingData models.ChfConvergedChargingChargingDataRequest, chargingSessionId string, +) *models.ProblemDetails { self := chf_context.GetSelf() ueId := chargingData.SubscriberIdentifier ue, ok := self.ChfUeFindBySupi(ueId) @@ -317,6 +310,7 @@ func (p *Processor) ChargingDataRelease( if err != nil { problemDetails := &models.ProblemDetails{ Status: http.StatusBadRequest, + Cause: err.Error(), } return problemDetails } @@ -341,14 +335,14 @@ func (p *Processor) ChargingDataRelease( } func (p *Processor) BuildOnlineChargingDataCreateResopone( - ue *chf_context.ChfUe, chargingData models.ChargingDataRequest, -) models.ChargingDataResponse { + ue *chf_context.ChfUe, chargingData models.ChfConvergedChargingChargingDataRequest, +) models.ChfConvergedChargingChargingDataResponse { logger.ChargingdataPostLog.Info("In Build Online Charging Data Create Resopone") ue.NotifyUri = chargingData.NotifyUri multipleUnitInformation, _ := sessionChargingReservation(chargingData) - responseBody := models.ChargingDataResponse{ + responseBody := models.ChfConvergedChargingChargingDataResponse{ MultipleUnitInformation: multipleUnitInformation, } @@ -356,15 +350,15 @@ func (p *Processor) BuildOnlineChargingDataCreateResopone( } func (p *Processor) BuildConvergedChargingDataUpdateResopone( - chargingData models.ChargingDataRequest, -) (models.ChargingDataResponse, bool) { + chargingData models.ChfConvergedChargingChargingDataRequest, +) (models.ChfConvergedChargingChargingDataResponse, bool) { var partialRecord bool logger.ChargingdataPostLog.Info("In BuildConvergedChargingDataUpdateResopone") multipleUnitInformation, partialRecord := sessionChargingReservation(chargingData) - responseBody := models.ChargingDataResponse{ + responseBody := models.ChfConvergedChargingChargingDataResponse{ MultipleUnitInformation: multipleUnitInformation, } @@ -395,7 +389,9 @@ func getUnitCost(ue *chf_context.ChfUe, rg int32, sur *charging_datatype.Service } // 32.296 6.2.2.3.1: Service usage request method with reservation -func sessionChargingReservation(chargingData models.ChargingDataRequest) ([]models.MultipleUnitInformation, bool) { +func sessionChargingReservation( + chargingData models.ChfConvergedChargingChargingDataRequest, +) ([]models.MultipleUnitInformation, bool) { var multipleUnitInformation []models.MultipleUnitInformation var partialRecord bool var subscriberIdentifier *charging_datatype.SubscriptionId @@ -454,8 +450,8 @@ func sessionChargingReservation(chargingData models.ChargingDataRequest) ([]mode switch usedUnit.QuotaManagementIndicator { case models.QuotaManagementIndicator_OFFLINE_CHARGING: unitInformation.Triggers = append(unitInformation.Triggers, - models.Trigger{ - TriggerType: models.TriggerType_QUOTA_THRESHOLD, + models.ChfConvergedChargingTrigger{ + TriggerType: models.ChfConvergedChargingTriggerType_QUOTA_THRESHOLD, TriggerCategory: models.TriggerCategory_IMMEDIATE_REPORT, }, ) @@ -469,12 +465,13 @@ func sessionChargingReservation(chargingData models.ChargingDataRequest) ([]mode // Check if partial record is needed partialRecord = true switch t := trigger; { - case t == models.Trigger{ - TriggerType: models.TriggerType_VOLUME_LIMIT, - TriggerCategory: models.TriggerCategory_IMMEDIATE_REPORT}: - case t.TriggerType == models.TriggerType_MAX_NUMBER_OF_CHANGES_IN_CHARGING_CONDITIONS: - case t.TriggerType == models.TriggerType_MANAGEMENT_INTERVENTION: - case t.TriggerType == models.TriggerType_FINAL: + case t == models.ChfConvergedChargingTrigger{ + TriggerType: models.ChfConvergedChargingTriggerType_VOLUME_LIMIT, + TriggerCategory: models.TriggerCategory_IMMEDIATE_REPORT, + }: + case t.TriggerType == models.ChfConvergedChargingTriggerType_MAX_NUMBER_OF_CHANGES_IN_CHARGING_CONDITIONS: + case t.TriggerType == models.ChfConvergedChargingTriggerType_MANAGEMENT_INTERVENTION: + case t.TriggerType == models.ChfConvergedChargingTriggerType_FINAL: ue.RatingType[rg] = charging_datatype.REQ_SUBTYPE_DEBIT partialRecord = false } @@ -572,8 +569,8 @@ func sessionChargingReservation(chargingData models.ChargingDataRequest) ([]mode if ue.RatingType[rg] == charging_datatype.REQ_SUBTYPE_RESERVE { unitInformation.Triggers = append(unitInformation.Triggers, - models.Trigger{ - TriggerType: models.TriggerType_QUOTA_THRESHOLD, + models.ChfConvergedChargingTrigger{ + TriggerType: models.ChfConvergedChargingTriggerType_QUOTA_THRESHOLD, TriggerCategory: models.TriggerCategory_IMMEDIATE_REPORT, }, ) @@ -582,8 +579,8 @@ func sessionChargingReservation(chargingData models.ChargingDataRequest) ([]mode } unitInformation.Triggers = append(unitInformation.Triggers, - models.Trigger{ - TriggerType: models.TriggerType_QUOTA_EXHAUSTED, + models.ChfConvergedChargingTrigger{ + TriggerType: models.ChfConvergedChargingTriggerType_QUOTA_EXHAUSTED, TriggerCategory: models.TriggerCategory_IMMEDIATE_REPORT, }, ) @@ -598,8 +595,8 @@ func sessionChargingReservation(chargingData models.ChargingDataRequest) ([]mode // The timer of VolumeLimit is remain in SMF if ue.VolumeLimit != 0 { unitInformation.Triggers = append(unitInformation.Triggers, - models.Trigger{ - TriggerType: models.TriggerType_VOLUME_LIMIT, + models.ChfConvergedChargingTrigger{ + TriggerType: models.ChfConvergedChargingTriggerType_VOLUME_LIMIT, TriggerCategory: models.TriggerCategory_DEFERRED_REPORT, VolumeLimit: ue.VolumeLimit, }, @@ -609,8 +606,8 @@ func sessionChargingReservation(chargingData models.ChargingDataRequest) ([]mode // VolumeLimit for PDU session only need to add once if ue.VolumeLimitPDU != 0 && unitUsageNum == 0 { unitInformation.Triggers = append(unitInformation.Triggers, - models.Trigger{ - TriggerType: models.TriggerType_VOLUME_LIMIT, + models.ChfConvergedChargingTrigger{ + TriggerType: models.ChfConvergedChargingTriggerType_VOLUME_LIMIT, TriggerCategory: models.TriggerCategory_IMMEDIATE_REPORT, VolumeLimit: ue.VolumeLimitPDU, }, @@ -620,8 +617,8 @@ func sessionChargingReservation(chargingData models.ChargingDataRequest) ([]mode // The timer of QuotaValidityTime is remain in UPF if ue.QuotaValidityTime != 0 { unitInformation.Triggers = append(unitInformation.Triggers, - models.Trigger{ - TriggerType: models.TriggerType_VALIDITY_TIME, + models.ChfConvergedChargingTrigger{ + TriggerType: models.ChfConvergedChargingTriggerType_VALIDITY_TIME, TriggerCategory: models.TriggerCategory_IMMEDIATE_REPORT, }, ) @@ -630,7 +627,7 @@ func sessionChargingReservation(chargingData models.ChargingDataRequest) ([]mode case charging_datatype.REQ_SUBTYPE_DEBIT: logger.ChargingdataPostLog.Info("Debit mode, will not grant unit") - // retrived tarrif for final pricing + // retrieved tarrif for final pricing sur.ServiceRating = &charging_datatype.ServiceRating{ ServiceIdentifier: datatype.Unsigned32(rg), ConsumedUnits: datatype.Unsigned32(totalUsedUnit), @@ -683,8 +680,8 @@ func sessionChargingReservation(chargingData models.ChargingDataRequest) ([]mode ue.ReservedQuota[rg] = 0 unitInformation.Triggers = append(unitInformation.Triggers, - models.Trigger{ - TriggerType: models.TriggerType_QUOTA_EXHAUSTED, + models.ChfConvergedChargingTrigger{ + TriggerType: models.ChfConvergedChargingTriggerType_QUOTA_EXHAUSTED, TriggerCategory: models.TriggerCategory_IMMEDIATE_REPORT, }, ) diff --git a/internal/sbi/routes.go b/internal/sbi/routes.go index 124bbf8..82767aa 100644 --- a/internal/sbi/routes.go +++ b/internal/sbi/routes.go @@ -3,6 +3,7 @@ package sbi import "github.com/gin-gonic/gin" type Route struct { + Name string Method string Pattern string APIFunc gin.HandlerFunc diff --git a/internal/sbi/server.go b/internal/sbi/server.go index 2b52221..4cb5189 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -9,19 +9,18 @@ import ( "sync" "time" - "github.com/free5gc/chf/pkg/app" - "github.com/free5gc/chf/pkg/factory" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" - chf_context "github.com/free5gc/chf/internal/context" "github.com/free5gc/chf/internal/logger" "github.com/free5gc/chf/internal/sbi/consumer" "github.com/free5gc/chf/internal/sbi/processor" "github.com/free5gc/chf/internal/util" + "github.com/free5gc/chf/pkg/app" + "github.com/free5gc/chf/pkg/factory" "github.com/free5gc/openapi/models" "github.com/free5gc/util/httpwrapper" logger_util "github.com/free5gc/util/logger" - "github.com/gin-gonic/gin" - "github.com/sirupsen/logrus" ) type ServerChf interface { @@ -45,14 +44,7 @@ func NewServer(chf ServerChf, tlsKeyLogPath string) (*Server, error) { router: logger_util.NewGinWithLogrus(logger.GinLog), } - 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()) - }) - applyRoutes(group, routes) - + s.router = newRouter(s) cfg := s.Config() bindAddr := cfg.GetSbiBindingAddr() logger.SBILog.Infof("Binding addr: [%s]", bindAddr) @@ -66,6 +58,47 @@ func NewServer(chf ServerChf, tlsKeyLogPath string) (*Server, error) { return s, nil } +func newRouter(s *Server) *gin.Engine { + router := logger_util.NewGinWithLogrus(logger.GinLog) + + for _, serviceName := range s.Config().Configuration.ServiceNameList { + switch models.ServiceName(serviceName) { + case models.ServiceName_NCHF_CONVERGEDCHARGING: + chfConvergedChargingGroup := router.Group(factory.ConvergedChargingResUriPrefix) + chfConvergedChargingGroup.Use(func(c *gin.Context) { + // oauth middleware + util.NewRouterAuthorizationCheck(models.ServiceName(serviceName)).Check(c, s.Context()) + }) + chfConvergedChargingRoutes := s.getConvergenChargingRoutes() + applyRoutes(chfConvergedChargingGroup, chfConvergedChargingRoutes) + + case models.ServiceName_NCHF_OFFLINEONLYCHARGING: + chfOfflineOnlyChargingGroup := router.Group(factory.OfflineOnlyChargingResUriPrefix) + chfOfflineOnlyChargingGroup.Use(func(c *gin.Context) { + // oauth middleware + util.NewRouterAuthorizationCheck(models.ServiceName(serviceName)).Check(c, s.Context()) + }) + + chfOfflineOnlyChargingGroupRoutes := s.getOfflineOnlyChargingRoutes() + applyRoutes(chfOfflineOnlyChargingGroup, chfOfflineOnlyChargingGroupRoutes) + + case models.ServiceName_NCHF_SPENDINGLIMITCONTROL: + chfSpendingLimitControlGroup := router.Group(factory.SpendingLimitControlResUriPrefix) + chfSpendingLimitControlGroup.Use(func(c *gin.Context) { + // oauth middleware + util.NewRouterAuthorizationCheck(models.ServiceName(serviceName)).Check(c, s.Context()) + }) + chfSpendingLimitControlRoutes := s.getSpendingLimitControlRoutes() + applyRoutes(chfSpendingLimitControlGroup, chfSpendingLimitControlRoutes) + + default: + logger.SBILog.Warnf("Unsupported service name: %s", serviceName) + } + } + + return router +} + func (s *Server) Run(traceCtx context.Context, wg *sync.WaitGroup) error { var err error _, s.Context().NfId, err = s.Consumer().RegisterNFInstance(s.CancelContext()) diff --git a/internal/util/chf_util.go b/internal/util/chf_util.go index e678c32..bb718a6 100644 --- a/internal/util/chf_util.go +++ b/internal/util/chf_util.go @@ -1,7 +1,7 @@ package util import ( - "github.com/free5gc/openapi/Nchf_ConvergedCharging" + Nchf_ConvergedCharging "github.com/free5gc/openapi/chf/ConvergedCharging" ) func GetNchfChargingNotificationCallbackClient() *Nchf_ConvergedCharging.APIClient { diff --git a/internal/util/router_auth_check.go b/internal/util/router_auth_check.go index 2544f18..b00f49b 100644 --- a/internal/util/router_auth_check.go +++ b/internal/util/router_auth_check.go @@ -3,10 +3,11 @@ package util import ( "net/http" + "github.com/gin-gonic/gin" + chf_context "github.com/free5gc/chf/internal/context" "github.com/free5gc/chf/internal/logger" "github.com/free5gc/openapi/models" - "github.com/gin-gonic/gin" ) type NFContextGetter func() *chf_context.CHFContext @@ -24,7 +25,6 @@ func NewRouterAuthorizationCheck(serviceName models.ServiceName) *RouterAuthoriz func (rac *RouterAuthorizationCheck) Check(c *gin.Context, chfContext chf_context.NFContext) { token := c.Request.Header.Get("Authorization") err := chfContext.AuthorizationCheck(token, rac.serviceName) - if err != nil { logger.UtilLog.Debugf("RouterAuthorizationCheck::Check Unauthorized: %s", err.Error()) c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()}) diff --git a/internal/util/router_auth_check_test.go b/internal/util/router_auth_check_test.go index aea10fe..bda0adf 100644 --- a/internal/util/router_auth_check_test.go +++ b/internal/util/router_auth_check_test.go @@ -5,9 +5,10 @@ import ( "net/http/httptest" "testing" - "github.com/free5gc/openapi/models" "github.com/gin-gonic/gin" "github.com/pkg/errors" + + "github.com/free5gc/openapi/models" ) const ( diff --git a/pkg/abmf/abmf.go b/pkg/abmf/abmf.go index 5af91d8..c3474c4 100644 --- a/pkg/abmf/abmf.go +++ b/pkg/abmf/abmf.go @@ -19,23 +19,22 @@ import ( "bytes" "context" "math" + _ "net/http/pprof" "strconv" "sync" "time" - _ "net/http/pprof" - - charging_datatype "github.com/free5gc/chf/ccs_diameter/datatype" - "github.com/free5gc/chf/pkg/factory" - "github.com/free5gc/util/mongoapi" - "go.mongodb.org/mongo-driver/bson" - "github.com/fiorix/go-diameter/diam" "github.com/fiorix/go-diameter/diam/datatype" "github.com/fiorix/go-diameter/diam/dict" "github.com/fiorix/go-diameter/diam/sm" + "go.mongodb.org/mongo-driver/bson" + + charging_datatype "github.com/free5gc/chf/ccs_diameter/datatype" charging_dict "github.com/free5gc/chf/ccs_diameter/dict" "github.com/free5gc/chf/internal/logger" + "github.com/free5gc/chf/pkg/factory" + "github.com/free5gc/util/mongoapi" ) const chargingDatasColl = "policyData.ues.chargingData" @@ -82,9 +81,9 @@ func OpenServer(ctx context.Context, wg *sync.WaitGroup) { abmfDiameter := factory.ChfConfig.Configuration.AbmfDiameter addr := abmfDiameter.HostIPv4 + ":" + strconv.Itoa(abmfDiameter.Port) go func() { - err := diam.ListenAndServeTLS(addr, abmfDiameter.Tls.Pem, abmfDiameter.Tls.Key, mux, nil) - if err != nil { - logger.AcctLog.Errorf("ABMF server fail to listen: %V", err) + errListen := diam.ListenAndServeTLS(addr, abmfDiameter.Tls.Pem, abmfDiameter.Tls.Key, mux, nil) + if errListen != nil { + logger.AcctLog.Errorf("ABMF server fail to listen: %V", errListen) } }() } @@ -209,7 +208,6 @@ func handleCCR() diam.HandlerFunc { }, MultipleServicesCreditControl: creditControl, } - } logger.AcctLog.Infof("UE [%s], Rating group [%d], quota [%d]", subscriberId, rg, quota) diff --git a/pkg/app/mock.go b/pkg/app/mock.go new file mode 100644 index 0000000..ad759ef --- /dev/null +++ b/pkg/app/mock.go @@ -0,0 +1,129 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: app.go +// +// Generated by this command: +// +// mockgen -source=app.go -package=app +// + +// Package app is a generated GoMock package. +package app + +import ( + reflect "reflect" + + context "github.com/free5gc/chf/internal/context" + factory "github.com/free5gc/chf/pkg/factory" + gomock "go.uber.org/mock/gomock" +) + +// MockApp is a mock of App interface. +type MockApp struct { + ctrl *gomock.Controller + recorder *MockAppMockRecorder +} + +// MockAppMockRecorder is the mock recorder for MockApp. +type MockAppMockRecorder struct { + mock *MockApp +} + +// NewMockApp creates a new mock instance. +func NewMockApp(ctrl *gomock.Controller) *MockApp { + mock := &MockApp{ctrl: ctrl} + mock.recorder = &MockAppMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockApp) EXPECT() *MockAppMockRecorder { + return m.recorder +} + +// Config mocks base method. +func (m *MockApp) Config() *factory.Config { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Config") + ret0, _ := ret[0].(*factory.Config) + return ret0 +} + +// Config indicates an expected call of Config. +func (mr *MockAppMockRecorder) Config() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Config", reflect.TypeOf((*MockApp)(nil).Config)) +} + +// Context mocks base method. +func (m *MockApp) Context() *context.CHFContext { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Context") + ret0, _ := ret[0].(*context.CHFContext) + return ret0 +} + +// Context indicates an expected call of Context. +func (mr *MockAppMockRecorder) Context() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockApp)(nil).Context)) +} + +// SetLogEnable mocks base method. +func (m *MockApp) SetLogEnable(enable bool) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetLogEnable", enable) +} + +// SetLogEnable indicates an expected call of SetLogEnable. +func (mr *MockAppMockRecorder) SetLogEnable(enable any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLogEnable", reflect.TypeOf((*MockApp)(nil).SetLogEnable), enable) +} + +// SetLogLevel mocks base method. +func (m *MockApp) SetLogLevel(level string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetLogLevel", level) +} + +// SetLogLevel indicates an expected call of SetLogLevel. +func (mr *MockAppMockRecorder) SetLogLevel(level any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLogLevel", reflect.TypeOf((*MockApp)(nil).SetLogLevel), level) +} + +// SetReportCaller mocks base method. +func (m *MockApp) SetReportCaller(reportCaller bool) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetReportCaller", reportCaller) +} + +// SetReportCaller indicates an expected call of SetReportCaller. +func (mr *MockAppMockRecorder) SetReportCaller(reportCaller any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReportCaller", reflect.TypeOf((*MockApp)(nil).SetReportCaller), reportCaller) +} + +// Start mocks base method. +func (m *MockApp) Start() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Start") +} + +// Start indicates an expected call of Start. +func (mr *MockAppMockRecorder) Start() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Start", reflect.TypeOf((*MockApp)(nil).Start)) +} + +// Terminate mocks base method. +func (m *MockApp) Terminate() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Terminate") +} + +// Terminate indicates an expected call of Terminate. +func (mr *MockAppMockRecorder) Terminate() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Terminate", reflect.TypeOf((*MockApp)(nil).Terminate)) +} diff --git a/pkg/factory/config.go b/pkg/factory/config.go index 9806f43..dd86cab 100644 --- a/pkg/factory/config.go +++ b/pkg/factory/config.go @@ -12,20 +12,23 @@ import ( "sync" "github.com/asaskevich/govalidator" + "github.com/free5gc/chf/internal/logger" ) const ( - ChfDefaultTLSKeyLogPath = "./log/chfsslkey.log" - ChfDefaultTLSPemPath = "./cert/chf.pem" - ChfDefaultTLSKeyPath = "./cert/chf.key" - ChfDefaultConfigPath = "./config/chfcfg.yaml" - ChfSbiDefaultIPv4 = "127.0.0.113" - ChfSbiDefaultPort = 8000 - ChfSbiDefaultScheme = "https" - ChfDefaultNrfUri = "https://127.0.0.10:8000" - CgfDefaultCdrFilePath = "/tmp" - ConvergedChargingResUriPrefix = "/nchf-convergedcharging/v3" + ChfDefaultTLSKeyLogPath = "./log/chfsslkey.log" + ChfDefaultTLSPemPath = "./cert/chf.pem" + ChfDefaultTLSKeyPath = "./cert/chf.key" + ChfDefaultConfigPath = "./config/chfcfg.yaml" + ChfSbiDefaultIPv4 = "127.0.0.113" + ChfSbiDefaultPort = 8000 + ChfSbiDefaultScheme = "https" + ChfDefaultNrfUri = "https://127.0.0.10:8000" + CgfDefaultCdrFilePath = "/tmp" + ConvergedChargingResUriPrefix = "/nchf-convergedcharging/v3" + OfflineOnlyChargingResUriPrefix = "/nchf-offlineonlycharging/v1" + SpendingLimitControlResUriPrefix = "/nchf-spendinglimitcontrol/v1" ) type Config struct { @@ -84,6 +87,8 @@ func (c *Configuration) validate() (bool, error) { for index, serviceName := range c.ServiceNameList { switch { case serviceName == "nchf-convergedcharging": + case serviceName == "nchf-offlineonlycharging": + case serviceName == "nchf-spendinglimitcontrol": default: err := errors.New("Invalid serviceNameList[" + strconv.Itoa(index) + "]: " + serviceName + ", should be nchf-convergedcharging.") diff --git a/pkg/factory/factory.go b/pkg/factory/factory.go index 1196f03..08cdec7 100644 --- a/pkg/factory/factory.go +++ b/pkg/factory/factory.go @@ -8,9 +8,9 @@ import ( "fmt" "os" + "github.com/asaskevich/govalidator" "gopkg.in/yaml.v2" - "github.com/asaskevich/govalidator" "github.com/free5gc/chf/internal/logger" ) @@ -34,6 +34,7 @@ func InitConfigFactory(f string, cfg *Config) error { return nil } + func ReadConfig(cfgPath string) (*Config, error) { cfg := &Config{} if err := InitConfigFactory(cfgPath, cfg); err != nil { diff --git a/pkg/rf/rating.go b/pkg/rf/rating.go index 44b74ae..d166182 100644 --- a/pkg/rf/rating.go +++ b/pkg/rf/rating.go @@ -20,23 +20,23 @@ import ( "context" "log" "math" + _ "net/http/pprof" "strconv" "strings" "sync" "time" - _ "net/http/pprof" - "github.com/fiorix/go-diameter/diam" "github.com/fiorix/go-diameter/diam/datatype" "github.com/fiorix/go-diameter/diam/dict" "github.com/fiorix/go-diameter/diam/sm" + "go.mongodb.org/mongo-driver/bson" + charging_datatype "github.com/free5gc/chf/ccs_diameter/datatype" charging_dict "github.com/free5gc/chf/ccs_diameter/dict" "github.com/free5gc/chf/internal/logger" "github.com/free5gc/chf/pkg/factory" "github.com/free5gc/util/mongoapi" - "go.mongodb.org/mongo-driver/bson" ) const chargingDatasColl = "policyData.ues.chargingData" @@ -81,9 +81,9 @@ func OpenServer(ctx context.Context, wg *sync.WaitGroup) { rfDiameter := factory.ChfConfig.Configuration.RfDiameter addr := rfDiameter.HostIPv4 + ":" + strconv.Itoa(rfDiameter.Port) go func() { - err := diam.ListenAndServeTLS(addr, rfDiameter.Tls.Pem, rfDiameter.Tls.Key, mux, nil) + errListen := diam.ListenAndServeTLS(addr, rfDiameter.Tls.Pem, rfDiameter.Tls.Key, mux, nil) if err != nil { - log.Fatal(err) + log.Fatal(errListen) } }() } diff --git a/pkg/service/init.go b/pkg/service/init.go index a2f270b..4c596f3 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -104,7 +104,6 @@ func (c *ChfApp) SetLogEnable(enable bool) { logger.Log.SetOutput(os.Stderr) } else { logger.Log.SetOutput(io.Discard) - } }