Skip to content
This repository was archived by the owner on Aug 28, 2025. It is now read-only.

Commit 249f80a

Browse files
committed
simplidied buildKindRegistry
On-behalf-of: @SAP [email protected] Signed-off-by: Artem Shcherbatiuk <[email protected]>
1 parent 20546e2 commit 249f80a

File tree

2 files changed

+80
-59
lines changed

2 files changed

+80
-59
lines changed

gateway/resolver/resolver.go

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ type Provider interface {
2929
CustomQueriesProvider
3030
CommonResolver() graphql.FieldResolveFn
3131
SanitizeGroupName(string) string
32-
RuntimeClient() client.WithWatch
3332
RelationResolver(fieldName string, gvk schema.GroupVersionKind) graphql.FieldResolveFn
3433
}
3534

@@ -94,15 +93,6 @@ func (r *Service) ListItems(gvk schema.GroupVersionKind, scope v1.ResourceScope)
9493
list.SetGroupVersionKind(schema.GroupVersionKind{Group: gvk.Group, Version: gvk.Version, Kind: gvk.Kind + "List"})
9594

9695
var opts []client.ListOption
97-
if isResourceNamespaceScoped(scope) {
98-
namespace, err := getStringArg(p.Args, NamespaceArg, false)
99-
if err != nil {
100-
return nil, err
101-
}
102-
if namespace != "" {
103-
opts = append(opts, client.InNamespace(namespace))
104-
}
105-
}
10696

10797
if val, ok := p.Args[LabelSelectorArg].(string); ok && val != "" {
10898
selector, err := labels.Parse(val)
@@ -113,6 +103,16 @@ func (r *Service) ListItems(gvk schema.GroupVersionKind, scope v1.ResourceScope)
113103
opts = append(opts, client.MatchingLabelsSelector{Selector: selector})
114104
}
115105

106+
if isResourceNamespaceScoped(scope) {
107+
namespace, err := getStringArg(p.Args, NamespaceArg, false)
108+
if err != nil {
109+
return nil, err
110+
}
111+
if namespace != "" {
112+
opts = append(opts, client.InNamespace(namespace))
113+
}
114+
}
115+
116116
if err = r.runtimeClient.List(ctx, list, opts...); err != nil {
117117
log.Error().Err(err).Str("scope", string(scope)).Msg("Unable to list objects")
118118
return nil, err
@@ -463,11 +463,6 @@ func compareNumbers[T int64 | float64](a, b T) int {
463463
}
464464
}
465465

466-
// RuntimeClient returns the runtime client for use in relationship resolution
467-
func (r *Service) RuntimeClient() client.WithWatch {
468-
return r.runtimeClient
469-
}
470-
471466
// RelationResolver creates a GraphQL resolver for relation fields
472467
func (r *Service) RelationResolver(fieldName string, gvk schema.GroupVersionKind) graphql.FieldResolveFn {
473468
return r.relationResolver.CreateResolver(fieldName, gvk)

listener/pkg/apischema/builder.go

Lines changed: 70 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,40 @@ func (b *SchemaBuilder) buildKindRegistry() {
254254
}
255255

256256
// Index by lowercase kind name for consistent lookup
257-
b.kindRegistry[strings.ToLower(gvk.Kind)] = append(b.kindRegistry[strings.ToLower(gvk.Kind)], resourceInfo)
257+
key := strings.ToLower(gvk.Kind)
258+
b.kindRegistry[key] = append(b.kindRegistry[key], resourceInfo)
259+
}
260+
261+
// Ensure deterministic order for picks: sort each slice by Group, Version, Kind, SchemaKey
262+
for kindKey, infos := range b.kindRegistry {
263+
slices.SortFunc(infos, func(a, b ResourceInfo) int {
264+
if a.Group != b.Group {
265+
if a.Group < b.Group {
266+
return -1
267+
}
268+
return 1
269+
}
270+
if a.Version != b.Version {
271+
if a.Version < b.Version {
272+
return -1
273+
}
274+
return 1
275+
}
276+
if a.Kind != b.Kind {
277+
if a.Kind < b.Kind {
278+
return -1
279+
}
280+
return 1
281+
}
282+
if a.SchemaKey < b.SchemaKey {
283+
return -1
284+
}
285+
if a.SchemaKey > b.SchemaKey {
286+
return 1
287+
}
288+
return 0
289+
})
290+
b.kindRegistry[kindKey] = infos
258291
}
259292

260293
b.log.Debug().Int("kindCount", len(b.kindRegistry)).Msg("built kind registry for relationships")
@@ -266,51 +299,34 @@ func (b *SchemaBuilder) expandRelationships(schema *spec.Schema) {
266299
return
267300
}
268301

269-
// Create a copy of properties to avoid modifying while iterating
270-
originalProps := make(map[string]spec.Schema)
271-
for k, v := range schema.Properties {
272-
originalProps[k] = v
273-
}
302+
for propName := range schema.Properties {
303+
if !isRefProperty(propName) {
304+
continue
305+
}
274306

275-
for propName := range originalProps {
276-
if strings.HasSuffix(propName, "Ref") && propName != "Ref" {
277-
// Extract the base kind (e.g., "role" from "roleRef")
278-
baseKind := strings.TrimSuffix(propName, "Ref")
279-
b.log.Debug().Str("propName", propName).Str("baseKind", baseKind).Msg("Found Ref field")
280-
281-
// Find the first matching resource type for this kind
282-
lookupKey := strings.ToLower(baseKind)
283-
b.log.Debug().Str("lookupKey", lookupKey).Msg("Looking up in kind registry")
284-
if resourceTypes, exists := b.kindRegistry[lookupKey]; exists && len(resourceTypes) > 0 {
285-
b.log.Debug().Str("lookupKey", lookupKey).Int("resourceCount", len(resourceTypes)).Msg("Found matching resources")
286-
// Use the first matching resource type
287-
targetResource := resourceTypes[0]
288-
289-
// Generate field name (e.g., "role" for "roleRef")
290-
fieldName := strings.ToLower(baseKind)
291-
292-
// Add the relationship field
293-
if _, exists := schema.Properties[fieldName]; !exists {
294-
// Create a reference to the target schema
295-
refSchema := spec.Schema{
296-
SchemaProps: spec.SchemaProps{
297-
Ref: spec.MustCreateRef(fmt.Sprintf("#/definitions/%s.%s.%s",
298-
targetResource.Group, targetResource.Version, targetResource.Kind)),
299-
},
300-
}
301-
schema.Properties[fieldName] = refSchema
302-
303-
b.log.Info().
304-
Str("sourceField", propName).
305-
Str("targetField", fieldName).
306-
Str("targetKind", targetResource.Kind).
307-
Str("targetGroup", targetResource.Group).
308-
Msg("Added relationship field")
309-
}
310-
} else {
311-
b.log.Debug().Str("lookupKey", lookupKey).Msg("No matching resources found in kind registry")
312-
}
307+
baseKind := strings.TrimSuffix(propName, "Ref")
308+
lookupKey := strings.ToLower(baseKind)
309+
310+
resourceTypes, exists := b.kindRegistry[lookupKey]
311+
if !exists || len(resourceTypes) == 0 {
312+
continue
313+
}
314+
315+
fieldName := strings.ToLower(baseKind)
316+
if _, exists := schema.Properties[fieldName]; exists {
317+
continue
313318
}
319+
320+
target := resourceTypes[0]
321+
ref := spec.MustCreateRef(fmt.Sprintf("#/definitions/%s.%s.%s", target.Group, target.Version, target.Kind))
322+
schema.Properties[fieldName] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
323+
324+
b.log.Info().
325+
Str("sourceField", propName).
326+
Str("targetField", fieldName).
327+
Str("targetKind", target.Kind).
328+
Str("targetGroup", target.Group).
329+
Msg("Added relationship field")
314330
}
315331

316332
// Recursively process nested objects and write back modifications
@@ -322,6 +338,16 @@ func (b *SchemaBuilder) expandRelationships(schema *spec.Schema) {
322338
}
323339
}
324340

341+
func isRefProperty(name string) bool {
342+
if !strings.HasSuffix(name, "Ref") {
343+
return false
344+
}
345+
if name == "Ref" {
346+
return false
347+
}
348+
return true
349+
}
350+
325351
func (b *SchemaBuilder) Complete() ([]byte, error) {
326352
v3JSON, err := json.Marshal(&schemaResponse{
327353
Components: schemasComponentsWrapper{

0 commit comments

Comments
 (0)