Skip to content

Commit bb6481f

Browse files
committed
better rest mapper init
On-behalf-of: @SAP [email protected] Signed-off-by: Artem Shcherbatiuk <[email protected]>
1 parent 5499458 commit bb6481f

File tree

2 files changed

+43
-18
lines changed

2 files changed

+43
-18
lines changed

gateway/manager/targetcluster/cluster.go

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919
"github.com/openmfp/kubernetes-graphql-gateway/gateway/schema"
2020

2121
// for REST mapper
22-
apiutil "sigs.k8s.io/controller-runtime/pkg/client/apiutil"
22+
meta "k8s.io/apimachinery/pkg/api/meta"
2323
)
2424

2525
// FileData represents the data extracted from a schema file
@@ -56,6 +56,7 @@ type TargetCluster struct {
5656
name string
5757
client client.WithWatch
5858
restCfg *rest.Config
59+
restMapper meta.RESTMapper
5960
handler *GraphQLHandler
6061
graphqlServer *GraphQLServer
6162
log *logger.Logger
@@ -68,16 +69,18 @@ func NewTargetCluster(
6869
log *logger.Logger,
6970
appCfg appConfig.Config,
7071
roundTripperFactory func(http.RoundTripper, rest.TLSClientConfig) http.RoundTripper,
72+
restMapper meta.RESTMapper,
7173
) (*TargetCluster, error) {
7274
fileData, err := readSchemaFile(schemaFilePath)
7375
if err != nil {
7476
return nil, fmt.Errorf("failed to read schema file: %w", err)
7577
}
7678

7779
cluster := &TargetCluster{
78-
appCfg: appCfg,
79-
name: name,
80-
log: log,
80+
appCfg: appCfg,
81+
name: name,
82+
log: log,
83+
restMapper: restMapper,
8184
}
8285

8386
// Connect to cluster - use metadata if available, otherwise fall back to standard config
@@ -133,6 +136,11 @@ func (tc *TargetCluster) connect(appCfg appConfig.Config, metadata *ClusterMetad
133136
return fmt.Errorf("failed to create cluster client: %w", err)
134137
}
135138

139+
// Create RESTMapper if not provided
140+
if tc.restMapper == nil {
141+
return fmt.Errorf("rest mapper is required")
142+
}
143+
136144
return nil
137145
}
138146

@@ -168,25 +176,15 @@ func buildConfigFromMetadata(metadata *ClusterMetadata, log *logger.Logger) (*re
168176
}
169177

170178
// createHandler creates the GraphQL schema and handler
171-
func (tc *TargetCluster) createHandler(definitions map[string]interface{}, appCfg appConfig.Config) error {
179+
func (tc *TargetCluster) createHandler(definitions map[string]any, appCfg appConfig.Config) error {
172180
// Convert definitions to spec format
173181
specDefs, err := convertToSpecDefinitions(definitions)
174182
if err != nil {
175183
return fmt.Errorf("failed to convert definitions: %w", err)
176184
}
177185

178-
// Build RESTMapper for this cluster (used by relation resolver)
179-
httpClient, err := rest.HTTPClientFor(tc.restCfg)
180-
if err != nil {
181-
return fmt.Errorf("failed to create HTTP client: %w", err)
182-
}
183-
restMapper, err := apiutil.NewDynamicRESTMapper(tc.restCfg, httpClient)
184-
if err != nil {
185-
return fmt.Errorf("failed to create REST mapper: %w", err)
186-
}
187-
188186
// Create resolver
189-
resolverProvider := resolver.New(tc.log, tc.client, restMapper)
187+
resolverProvider := resolver.New(tc.log, tc.client, tc.restMapper)
190188

191189
// Create schema gateway
192190
schemaGateway, err := schema.New(tc.log, specDefs, resolverProvider)
@@ -261,7 +259,7 @@ func readSchemaFile(filePath string) (*FileData, error) {
261259
}
262260

263261
// convertToSpecDefinitions converts map definitions to go-openapi spec format
264-
func convertToSpecDefinitions(definitions map[string]interface{}) (spec.Definitions, error) {
262+
func convertToSpecDefinitions(definitions map[string]any) (spec.Definitions, error) {
265263
data, err := json.Marshal(definitions)
266264
if err != nil {
267265
return nil, fmt.Errorf("failed to marshal definitions: %w", err)

gateway/manager/targetcluster/registry.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import (
1414
appConfig "github.com/openmfp/kubernetes-graphql-gateway/common/config"
1515
"github.com/openmfp/kubernetes-graphql-gateway/gateway/manager/roundtripper"
1616
"k8s.io/client-go/rest"
17+
18+
// mapper
19+
apiutil "sigs.k8s.io/controller-runtime/pkg/client/apiutil"
1720
)
1821

1922
// contextKey is a custom type for context keys to avoid collisions
@@ -61,8 +64,32 @@ func (cr *ClusterRegistry) LoadCluster(schemaFilePath string) error {
6164
Str("file", schemaFilePath).
6265
Msg("Loading target cluster")
6366

67+
// Build RESTMapper upfront to avoid hidden init
68+
fileData, err := readSchemaFile(schemaFilePath)
69+
if err != nil {
70+
return fmt.Errorf("failed to read schema file: %w", err)
71+
}
72+
if fileData.ClusterMetadata == nil {
73+
return fmt.Errorf("cluster %s requires cluster metadata in schema file", name)
74+
}
75+
cfg, err := buildConfigFromMetadata(fileData.ClusterMetadata, cr.log)
76+
if err != nil {
77+
return fmt.Errorf("failed to build config from metadata: %w", err)
78+
}
79+
if cr.roundTripperFactory != nil {
80+
cfg.Wrap(func(rt http.RoundTripper) http.RoundTripper { return cr.roundTripperFactory(rt, cfg.TLSClientConfig) })
81+
}
82+
httpClient, err := rest.HTTPClientFor(cfg)
83+
if err != nil {
84+
return fmt.Errorf("failed to create HTTP client: %w", err)
85+
}
86+
restMapper, err := apiutil.NewDynamicRESTMapper(cfg, httpClient)
87+
if err != nil {
88+
return fmt.Errorf("failed to create REST mapper: %w", err)
89+
}
90+
6491
// Create or update cluster
65-
cluster, err := NewTargetCluster(name, schemaFilePath, cr.log, cr.appCfg, cr.roundTripperFactory)
92+
cluster, err := NewTargetCluster(name, schemaFilePath, cr.log, cr.appCfg, cr.roundTripperFactory, restMapper)
6693
if err != nil {
6794
return fmt.Errorf("failed to create target cluster %s: %w", name, err)
6895
}

0 commit comments

Comments
 (0)