Skip to content

Commit

Permalink
[common] OCTRL-805 allow to group entries in subfolders
Browse files Browse the repository at this point in the history
  • Loading branch information
knopers8 committed Apr 26, 2024
1 parent 14adf0a commit 0190768
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 33 deletions.
12 changes: 12 additions & 0 deletions apricot/local/servicehttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,12 @@ func NewHttpService(service configuration.Service) (svr *http.Server) {
// GET /components/{component}/{runtype}/{rolename}/{entry}/resolve, assumes this is not a raw path, returns a raw path
// like {component}/{runtype}/{rolename}/{entry}
apiComponentQuery.HandleFunc("/resolve", httpsvc.ApiResolveComponentQuery).Methods(http.MethodGet)
apiComponentQuery.HandleFunc("/{subentry}/resolve", httpsvc.ApiResolveComponentQuery).Methods(http.MethodGet)
// GET /components/{component}/{runtype}/{rolename}/{entry}, accepts raw or non-raw path, returns payload
// that may be processed or not depending on process=true or false
apiComponentQuery.HandleFunc("", httpsvc.ApiGetComponentConfiguration).Methods(http.MethodGet)
apiComponentQuery.HandleFunc("/", httpsvc.ApiGetComponentConfiguration).Methods(http.MethodGet)
apiComponentQuery.HandleFunc("/{subentry}", httpsvc.ApiGetComponentConfiguration).Methods(http.MethodGet)

// inventory API

Expand Down Expand Up @@ -406,6 +408,11 @@ func (httpsvc *HttpService) ApiResolveComponentQuery(w http.ResponseWriter, r *h
return
}

subentry, hasSubentry := queryParams["subentry"]
if hasSubentry {
entry = entry + "/" + subentry
}

resolved, err := httpsvc.svc.ResolveComponentQuery(&componentcfg.Query{
Component: component,
RunType: runType,
Expand Down Expand Up @@ -484,6 +491,11 @@ func (httpsvc *HttpService) ApiGetComponentConfiguration(w http.ResponseWriter,
return
}

subentry, hasSubentry := queryParams["subentry"]
if hasSubentry {
entry = entry + "/" + subentry
}

queryArgs := r.URL.Query()
processS := queryArgs.Get("process")
process, err := strconv.ParseBool(processS)
Expand Down
56 changes: 23 additions & 33 deletions configuration/componentcfg/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const (

var (
// component /RUNTYPE /rolename /entry @timestamp
inputFullRegex = regexp.MustCompile(`^([a-zA-Z0-9-_]+)(\/[A-Z0-9-_]+){1}(\/[a-z-A-Z0-9-_]+){1}(\/[a-z-A-Z0-9-_]+){1}(\@[0-9]+)?$`)
inputFullRegex = regexp.MustCompile(`^([a-zA-Z0-9-_]+)(\/[A-Z0-9-_]+){1}(\/[a-z-A-Z0-9-_]+){1}(\/[a-z-A-Z0-9-_/]+){1}(\@[0-9]+)?$`)
// component /RUNTYPE /rolename
inputEntriesRegex = regexp.MustCompile(`^([a-zA-Z0-9-_]+)(\/[A-Z0-9-_]+){1}(\/[a-z-A-Z0-9-_]+){1}$`)
inputParametersRegex = regexp.MustCompile(`^([a-zA-Z0-9-_]+=[a-zA-Z0-9-_,]+)(&[a-zA-Z0-9-_]+=[a-zA-Z0-9-_,"\[\]]+)*$`)
Expand Down Expand Up @@ -110,39 +110,29 @@ func NewQuery(path string) (p *Query, err error) {
}
path = strings.TrimSpace(path)
if IsStringValidQueryPathWithOptionalTimestamp(path) {
if strings.Contains(path, "@") {
// coconut conf show component/FLAVOR/rolename/entry@timestamp
arg := strings.Replace(path, "@", SEPARATOR, 1)
params := strings.Split(arg, SEPARATOR)
p.Component = params[0]
// Convert FLAVOR to pb-provided enum
typedFlavor, ok := apricotpb.RunType_value[params[1]]
if !ok {
err = E_BAD_KEY
return
}
p.RunType = apricotpb.RunType(typedFlavor)
p.RoleName = params[2]
p.EntryKey = params[3]
p.Timestamp = params[4]
} else if strings.Contains(path, SEPARATOR) {
// coconut conf show component/FLAVOR/rolename/entry
params := strings.Split(path, SEPARATOR)
p.Component = params[0]
// Convert FLAVOR to pb-provided enum
typedFlavor, ok := apricotpb.RunType_value[params[1]]
if !ok {
err = E_BAD_KEY
return
}
p.RunType = apricotpb.RunType(typedFlavor)
p.RoleName = params[2]
p.EntryKey = params[3]
// and if we received a raw path (with / instead of @ before timestamp):
if len(params) > 4 && len(params[4]) > 0 {
p.Timestamp = params[4]
}

matches := inputFullRegex.FindAllStringSubmatch(path, -1)

if len(matches) != 1 {
err = E_BAD_KEY
return
}
captureGroups := matches[0][1:] // the first element is the full query, we don't need it
if len(captureGroups) < 4 && len(captureGroups) > 5 {
err = E_BAD_KEY
return
}
p.Component = captureGroups[0]
// Convert FLAVOR to pb-provided enum
typedFlavor, ok := apricotpb.RunType_value[strings.TrimPrefix(captureGroups[1], "/")]
if !ok {
err = E_BAD_KEY
return
}
p.RunType = apricotpb.RunType(typedFlavor)
p.RoleName = strings.TrimPrefix(captureGroups[2], "/")
p.EntryKey = strings.TrimPrefix(captureGroups[3], "/")
p.Timestamp = strings.TrimPrefix(captureGroups[4], "@")
} else {
err = E_BAD_KEY
return
Expand Down
27 changes: 27 additions & 0 deletions configuration/componentcfg/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,21 @@ var _ = Describe("query", func() {
It("should be able to generalize to a query for any role name", func() {
Expect(q.WithFallbackRunType().Path()).To(Equal("qc/ANY/pp/ctp-raw-qc@1234"))
})
It("should recognize the RunType correctly", func() {
Expect(q.RunType.String()).To(Equal("PHYSICS"))
})
It("should recognize the RoleName correctly", func() {
Expect(q.RoleName).To(Equal("pp"))
})
It("should recognize the Component correctly", func() {
Expect(q.Component).To(Equal("qc"))
})
It("should recognize the EntryKey correctly", func() {
Expect(q.EntryKey).To(Equal("ctp-raw-qc"))
})
It("should recognize the Timestamp correctly", func() {
Expect(q.Timestamp).To(Equal("1234"))
})
})

When("creating a new query with the full path but no timestamp", func() {
Expand Down Expand Up @@ -72,6 +87,18 @@ var _ = Describe("query", func() {
})
})

When("creating a new query with entry having a subdirectory", func() {
BeforeEach(func() {
q, err = componentcfg.NewQuery("qc/ANY/any/tpc/clusters")
})
It("should be parsed without reporting errors", func() {
Expect(err).To(BeNil())
})
It("the entry should be correctly recognized", func() {
Expect(q.EntryKey).To(Equal("tpc/clusters"))
})
})

Describe("dealing with incorrectly formatted queries", func() {
When("query is empty", func() {
BeforeEach(func() {
Expand Down

0 comments on commit 0190768

Please sign in to comment.