github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/cmd/director/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "crypto/tls" 6 "encoding/json" 7 "github.com/kyma-incubator/compass/components/director/internal/domain/destination" 8 "net/http" 9 "net/url" 10 "os" 11 "time" 12 13 "github.com/kyma-incubator/compass/components/director/internal/domain/destination/destinationcreator" 14 "github.com/kyma-incubator/compass/components/director/internal/domain/formationconstraint/operators" 15 16 "github.com/kyma-incubator/compass/components/director/internal/domain/formationconstraint" 17 "github.com/kyma-incubator/compass/components/director/internal/domain/formationtemplateconstraintreferences" 18 19 "github.com/kyma-incubator/compass/components/director/pkg/applicationtenancy" 20 21 databuilder "github.com/kyma-incubator/compass/components/director/internal/domain/webhook/datainputbuilder" 22 23 "github.com/kyma-incubator/compass/components/director/internal/domain/formationassignment" 24 "github.com/kyma-incubator/compass/components/director/internal/formationmapping" 25 26 "github.com/kyma-incubator/compass/components/director/internal/domain/apptemplate" 27 28 authpkg "github.com/kyma-incubator/compass/components/director/pkg/auth" 29 webhookclient "github.com/kyma-incubator/compass/components/director/pkg/webhook_client" 30 31 "github.com/kyma-incubator/compass/components/director/pkg/retry" 32 33 runtimectx "github.com/kyma-incubator/compass/components/director/internal/domain/runtime_context" 34 35 "github.com/kyma-incubator/compass/components/director/internal/domain/formationtemplate" 36 37 "github.com/kyma-incubator/compass/components/director/internal/domain/formation" 38 "github.com/kyma-incubator/compass/components/director/internal/domain/subscription" 39 40 kube "github.com/kyma-incubator/compass/components/director/pkg/kubernetes" 41 v1 "k8s.io/api/core/v1" 42 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 43 "k8s.io/apimachinery/pkg/watch" 44 "k8s.io/client-go/kubernetes" 45 46 "github.com/kyma-incubator/compass/components/director/pkg/accessstrategy" 47 "github.com/kyma-incubator/compass/components/director/pkg/certloader" 48 49 "github.com/kyma-incubator/compass/components/director/internal/info" 50 51 "github.com/kyma-incubator/compass/components/director/internal/authenticator/claims" 52 mp_authenticator "github.com/kyma-incubator/compass/components/director/pkg/auth-middleware" 53 54 gqlgen "github.com/99designs/gqlgen/graphql" 55 "github.com/99designs/gqlgen/graphql/handler" 56 "github.com/99designs/gqlgen/graphql/playground" 57 "github.com/dlmiddlecote/sqlstats" 58 "github.com/gorilla/mux" 59 dataloader "github.com/kyma-incubator/compass/components/director/internal/dataloaders" 60 "github.com/kyma-incubator/compass/components/director/internal/domain" 61 "github.com/kyma-incubator/compass/components/director/internal/domain/api" 62 "github.com/kyma-incubator/compass/components/director/internal/domain/application" 63 "github.com/kyma-incubator/compass/components/director/internal/domain/auth" 64 "github.com/kyma-incubator/compass/components/director/internal/domain/bundle" 65 "github.com/kyma-incubator/compass/components/director/internal/domain/bundleinstanceauth" 66 "github.com/kyma-incubator/compass/components/director/internal/domain/bundlereferences" 67 "github.com/kyma-incubator/compass/components/director/internal/domain/document" 68 "github.com/kyma-incubator/compass/components/director/internal/domain/eventdef" 69 "github.com/kyma-incubator/compass/components/director/internal/domain/fetchrequest" 70 "github.com/kyma-incubator/compass/components/director/internal/domain/integrationsystem" 71 "github.com/kyma-incubator/compass/components/director/internal/domain/label" 72 "github.com/kyma-incubator/compass/components/director/internal/domain/labeldef" 73 "github.com/kyma-incubator/compass/components/director/internal/domain/oauth20" 74 "github.com/kyma-incubator/compass/components/director/internal/domain/onetimetoken" 75 "github.com/kyma-incubator/compass/components/director/internal/domain/runtime" 76 "github.com/kyma-incubator/compass/components/director/internal/domain/scenarioassignment" 77 "github.com/kyma-incubator/compass/components/director/internal/domain/schema" 78 "github.com/kyma-incubator/compass/components/director/internal/domain/spec" 79 "github.com/kyma-incubator/compass/components/director/internal/domain/tenant" 80 "github.com/kyma-incubator/compass/components/director/internal/domain/version" 81 "github.com/kyma-incubator/compass/components/director/internal/domain/webhook" 82 errorpresenter "github.com/kyma-incubator/compass/components/director/internal/error_presenter" 83 "github.com/kyma-incubator/compass/components/director/internal/features" 84 "github.com/kyma-incubator/compass/components/director/internal/healthz" 85 "github.com/kyma-incubator/compass/components/director/internal/metrics" 86 "github.com/kyma-incubator/compass/components/director/internal/model" 87 "github.com/kyma-incubator/compass/components/director/internal/packagetobundles" 88 panichandler "github.com/kyma-incubator/compass/components/director/internal/panic_handler" 89 "github.com/kyma-incubator/compass/components/director/internal/statusupdate" 90 "github.com/kyma-incubator/compass/components/director/internal/uid" 91 pkgadapters "github.com/kyma-incubator/compass/components/director/pkg/adapters" 92 configprovider "github.com/kyma-incubator/compass/components/director/pkg/config" 93 "github.com/kyma-incubator/compass/components/director/pkg/correlation" 94 "github.com/kyma-incubator/compass/components/director/pkg/executor" 95 "github.com/kyma-incubator/compass/components/director/pkg/graphql" 96 timeouthandler "github.com/kyma-incubator/compass/components/director/pkg/handler" 97 "github.com/kyma-incubator/compass/components/director/pkg/header" 98 httputil "github.com/kyma-incubator/compass/components/director/pkg/http" 99 "github.com/kyma-incubator/compass/components/director/pkg/inputvalidation" 100 "github.com/kyma-incubator/compass/components/director/pkg/log" 101 "github.com/kyma-incubator/compass/components/director/pkg/normalizer" 102 "github.com/kyma-incubator/compass/components/director/pkg/operation" 103 "github.com/kyma-incubator/compass/components/director/pkg/operation/k8s" 104 panicrecovery "github.com/kyma-incubator/compass/components/director/pkg/panic_recovery" 105 "github.com/kyma-incubator/compass/components/director/pkg/persistence" 106 "github.com/kyma-incubator/compass/components/director/pkg/resource" 107 "github.com/kyma-incubator/compass/components/director/pkg/scenario" 108 "github.com/kyma-incubator/compass/components/director/pkg/scope" 109 "github.com/kyma-incubator/compass/components/director/pkg/signal" 110 "github.com/kyma-incubator/compass/components/operations-controller/client" 111 "github.com/pkg/errors" 112 "github.com/prometheus/client_golang/prometheus" 113 "github.com/prometheus/client_golang/prometheus/promhttp" 114 "github.com/vrischmann/envconfig" 115 cr "sigs.k8s.io/controller-runtime" 116 ) 117 118 const envPrefix = "APP" 119 120 type config struct { 121 Address string `envconfig:"default=127.0.0.1:3000"` 122 123 InternalAddress string `envconfig:"default=127.0.0.1:3002"` 124 AppURL string `envconfig:"APP_URL"` 125 126 ClientTimeout time.Duration `envconfig:"default=105s"` 127 ServerTimeout time.Duration `envconfig:"default=110s"` 128 129 Database persistence.DatabaseConfig 130 APIEndpoint string `envconfig:"default=/graphql"` 131 OperationPath string `envconfig:"default=/operation"` 132 LastOperationPath string `envconfig:"default=/last_operation"` 133 PlaygroundAPIEndpoint string `envconfig:"default=/graphql"` 134 ConfigurationFile string 135 ConfigurationFileReload time.Duration `envconfig:"default=1m"` 136 137 Log log.Config 138 139 MetricsAddress string `envconfig:"default=127.0.0.1:3003"` 140 MetricsConfig metrics.Config 141 142 JWKSEndpoint string `envconfig:"default=file://hack/default-jwks.json"` 143 JWKSSyncPeriod time.Duration `envconfig:"default=5m"` 144 AllowJWTSigningNone bool `envconfig:"default=false"` 145 ClientIDHTTPHeaderKey string `envconfig:"default=client_user,APP_CLIENT_ID_HTTP_HEADER"` 146 147 RuntimeJWKSCachePeriod time.Duration `envconfig:"default=5m"` 148 149 PairingAdapterCfg configprovider.PairingAdapterConfig 150 151 OneTimeToken onetimetoken.Config 152 OAuth20 oauth20.Config 153 154 Features features.Config 155 156 SelfRegConfig configprovider.SelfRegConfig 157 158 OperationsNamespace string `envconfig:"default=compass-system"` 159 160 DisableAsyncMode bool `envconfig:"default=false"` 161 162 HealthConfig healthz.Config `envconfig:"APP_HEALTH_CONFIG_INDICATORS"` 163 164 ReadyConfig healthz.ReadyConfig 165 166 InfoConfig info.Config 167 168 FormationMappingCfg formationmapping.Config 169 170 DataloaderMaxBatch int `envconfig:"default=200"` 171 DataloaderWait time.Duration `envconfig:"default=10ms"` 172 173 CertLoaderConfig certloader.Config 174 175 SubscriptionConfig subscription.Config 176 177 TenantOnDemandConfig tenant.FetchOnDemandAPIConfig 178 179 RetryConfig retry.Config 180 181 DestinationCreatorConfig *destinationcreator.Config 182 183 SkipSSLValidation bool `envconfig:"default=false,APP_HTTP_CLIENT_SKIP_SSL_VALIDATION"` 184 185 ORDWebhookMappings string `envconfig:"APP_ORD_WEBHOOK_MAPPINGS"` 186 TenantMappingConfigPath string `envconfig:"APP_TENANT_MAPPING_CONFIG_PATH"` 187 TenantMappingCallbackURL string `envconfig:"APP_TENANT_MAPPING_CALLBACK_URL"` 188 189 ExternalClientCertSecretName string `envconfig:"APP_EXTERNAL_CLIENT_CERT_SECRET_NAME"` 190 ExtSvcClientCertSecretName string `envconfig:"APP_EXT_SVC_CLIENT_CERT_SECRET_NAME"` 191 192 ApplicationTemplateProductLabel string `envconfig:"APP_APPLICATION_TEMPLATE_PRODUCT_LABEL"` 193 } 194 195 func main() { 196 ctx, cancel := context.WithCancel(context.Background()) 197 198 defer cancel() 199 200 term := make(chan os.Signal) 201 signal.HandleInterrupts(ctx, cancel, term) 202 203 cfg := config{} 204 err := envconfig.InitWithPrefix(&cfg, envPrefix) 205 exitOnError(err, "Error while loading app config") 206 207 ctx, err = log.Configure(ctx, &cfg.Log) 208 exitOnError(err, "Failed to configure Logger") 209 logger := log.C(ctx) 210 211 ordWebhookMapping, err := application.UnmarshalMappings(cfg.ORDWebhookMappings) 212 exitOnError(err, "Error while loading ORD Webhook Mappings") 213 214 tenantMappingConfig, err := apptemplate.UnmarshalTenantMappingConfig(cfg.TenantMappingConfigPath) 215 exitOnError(err, "Error while loading Tenant mapping config") 216 217 transact, closeFunc, err := persistence.Configure(ctx, cfg.Database) 218 exitOnError(err, "Error while establishing the connection to the database") 219 220 defer func() { 221 err := closeFunc() 222 exitOnError(err, "Error while closing the connection to the database") 223 }() 224 225 cfgProvider := createAndRunConfigProvider(ctx, cfg) 226 227 logger.Infof("Registering metrics collectors...") 228 metricsCollector := metrics.NewCollector(cfg.MetricsConfig) 229 dbStatsCollector := sqlstats.NewStatsCollector("director", transact) 230 prometheus.MustRegister(metricsCollector, dbStatsCollector) 231 232 k8sClient, err := kube.NewKubernetesClientSet(ctx, time.Second, time.Minute, time.Minute) 233 exitOnError(err, "Error while creating kubernetes client") 234 235 pa, err := getPairingAdaptersMapping(ctx, k8sClient, cfg.PairingAdapterCfg) 236 exitOnError(err, "Error while getting pairing adapters configuration") 237 238 startPairingAdaptersWatcher(ctx, k8sClient, pa, cfg.PairingAdapterCfg) 239 240 httpClient := &http.Client{ 241 Timeout: cfg.ClientTimeout, 242 Transport: httputil.NewCorrelationIDTransport(httputil.NewHTTPTransportWrapper(http.DefaultTransport.(*http.Transport))), 243 CheckRedirect: func(req *http.Request, via []*http.Request) error { 244 return http.ErrUseLastResponse 245 }, 246 } 247 248 securedHTTPClient := authpkg.PrepareHTTPClientWithSSLValidation(cfg.ClientTimeout, cfg.SkipSSLValidation) 249 250 cfg.SelfRegConfig.ClientTimeout = cfg.ClientTimeout 251 252 internalClientTransport := &http.Transport{ 253 TLSClientConfig: &tls.Config{ 254 InsecureSkipVerify: cfg.SkipSSLValidation, 255 }, 256 } 257 258 internalFQDNHTTPClient := &http.Client{ 259 Timeout: cfg.ClientTimeout, 260 Transport: httputil.NewCorrelationIDTransport(httputil.NewServiceAccountTokenTransport(httputil.NewHTTPTransportWrapper(http.DefaultTransport.(*http.Transport)))), 261 } 262 263 internalGatewayHTTPClient := &http.Client{ 264 Timeout: cfg.ClientTimeout, 265 Transport: httputil.NewCorrelationIDTransport(httputil.NewServiceAccountTokenTransportWithHeader(httputil.NewHTTPTransportWrapper(internalClientTransport), mp_authenticator.AuthorizationHeaderKey)), 266 } 267 268 appRepo := applicationRepo() 269 270 adminURL, err := url.Parse(cfg.OAuth20.URL) 271 exitOnError(err, "Error while parsing Hydra URL") 272 273 certCache, err := certloader.StartCertLoader(ctx, cfg.CertLoaderConfig) 274 exitOnError(err, "Failed to initialize certificate loader") 275 276 accessStrategyExecutorProvider := accessstrategy.NewDefaultExecutorProvider(certCache, cfg.ExternalClientCertSecretName, cfg.ExtSvcClientCertSecretName) 277 retryHTTPExecutor := retry.NewHTTPExecutor(&cfg.RetryConfig) 278 279 mtlsHTTPClient := authpkg.PrepareMTLSClientWithSSLValidation(cfg.ClientTimeout, certCache, cfg.SkipSSLValidation, cfg.ExternalClientCertSecretName) 280 extSvcMtlsHTTPClient := authpkg.PrepareMTLSClient(cfg.ClientTimeout, certCache, cfg.ExtSvcClientCertSecretName) 281 rootResolver, err := domain.NewRootResolver( 282 &normalizer.DefaultNormalizator{}, 283 transact, 284 cfgProvider, 285 cfg.OneTimeToken, 286 cfg.OAuth20, 287 pa, 288 cfg.Features, 289 metricsCollector, 290 retryHTTPExecutor, 291 httpClient, 292 internalFQDNHTTPClient, 293 internalGatewayHTTPClient, 294 securedHTTPClient, 295 mtlsHTTPClient, 296 extSvcMtlsHTTPClient, 297 cfg.SelfRegConfig, 298 cfg.OneTimeToken.Length, 299 adminURL, 300 accessStrategyExecutorProvider, 301 cfg.SubscriptionConfig, 302 cfg.TenantOnDemandConfig, 303 ordWebhookMapping, 304 tenantMappingConfig, 305 cfg.TenantMappingCallbackURL, 306 cfg.ApplicationTemplateProductLabel, 307 cfg.DestinationCreatorConfig, 308 ) 309 exitOnError(err, "Failed to initialize root resolver") 310 311 gqlCfg := graphql.Config{ 312 Resolvers: rootResolver, 313 Directives: graphql.DirectiveRoot{ 314 Async: getAsyncDirective(ctx, cfg, transact, appRepo, tenantMappingConfig), 315 HasScenario: scenario.NewDirective(transact, label.NewRepository(label.NewConverter()), bundleRepo(), bundleInstanceAuthRepo()).HasScenario, 316 HasScopes: scope.NewDirective(cfgProvider, &scope.HasScopesErrorProvider{}).VerifyScopes, 317 Sanitize: scope.NewDirective(cfgProvider, &scope.SanitizeErrorProvider{}).VerifyScopes, 318 Validate: inputvalidation.NewDirective().Validate, 319 SynchronizeApplicationTenancy: applicationtenancy.NewDirective(transact, tenant.NewService(tenant.NewRepository(tenant.NewConverter()), uid.NewService(), tenant.NewConverter()), applicationSvc(transact, cfg, securedHTTPClient, mtlsHTTPClient, extSvcMtlsHTTPClient, certCache, ordWebhookMapping)).SynchronizeApplicationTenancy, 320 }, 321 } 322 323 executableSchema := graphql.NewExecutableSchema(gqlCfg) 324 claimsValidator := claims.NewValidator(transact, runtimeSvc(transact, cfg, tenantMappingConfig, httpClient, mtlsHTTPClient, extSvcMtlsHTTPClient), runtimeCtxSvc(transact, cfg, httpClient, mtlsHTTPClient, extSvcMtlsHTTPClient), appTemplateSvc(), applicationSvc(transact, cfg, httpClient, mtlsHTTPClient, extSvcMtlsHTTPClient, certCache, ordWebhookMapping), intSystemSvc(), cfg.Features.SubscriptionProviderLabelKey, cfg.Features.ConsumerSubaccountLabelKey, cfg.Features.TokenPrefix) 325 326 logger.Infof("Registering GraphQL endpoint on %s...", cfg.APIEndpoint) 327 authMiddleware := mp_authenticator.New(httpClient, cfg.JWKSEndpoint, cfg.AllowJWTSigningNone, cfg.ClientIDHTTPHeaderKey, claimsValidator) 328 329 if cfg.JWKSSyncPeriod != 0 { 330 logger.Infof("JWKS synchronization enabled. Sync period: %v", cfg.JWKSSyncPeriod) 331 periodicExecutor := executor.NewPeriodic(cfg.JWKSSyncPeriod, func(ctx context.Context) { 332 err := authMiddleware.SynchronizeJWKS(ctx) 333 if err != nil { 334 logger.WithError(err).Errorf("An error has occurred while synchronizing JWKS: %v", err) 335 } 336 }) 337 go periodicExecutor.Run(ctx) 338 } 339 340 packageToBundlesMiddleware := packagetobundles.NewHandler(transact) 341 342 statusMiddleware := statusupdate.New(transact, statusupdate.NewRepository()) 343 344 const ( 345 healthzEndpoint = "/healthz" 346 livezEndpoint = "/livez" 347 readyzEndpoint = "/readyz" 348 ) 349 350 mainRouter := mux.NewRouter() 351 mainRouter.HandleFunc("/", playground.Handler("Dataloader", cfg.PlaygroundAPIEndpoint)) 352 353 mainRouter.Use(panicrecovery.NewPanicRecoveryMiddleware(), correlation.AttachCorrelationIDToContext(), log.RequestLogger( 354 healthzEndpoint, livezEndpoint, readyzEndpoint, 355 ), header.AttachHeadersToContext()) 356 presenter := errorpresenter.NewPresenter(uid.NewService()) 357 358 gqlAPIRouter := mainRouter.PathPrefix(cfg.APIEndpoint).Subrouter() 359 gqlAPIRouter.Use(authMiddleware.Handler()) 360 gqlAPIRouter.Use(packageToBundlesMiddleware.Handler()) 361 gqlAPIRouter.Use(statusMiddleware.Handler()) 362 gqlAPIRouter.Use(dataloader.HandlerBundle(rootResolver.BundlesDataloader, cfg.DataloaderMaxBatch, cfg.DataloaderWait)) 363 gqlAPIRouter.Use(dataloader.HandlerAPIDef(rootResolver.APIDefinitionsDataloader, cfg.DataloaderMaxBatch, cfg.DataloaderWait)) 364 gqlAPIRouter.Use(dataloader.HandlerEventDef(rootResolver.EventDefinitionsDataloader, cfg.DataloaderMaxBatch, cfg.DataloaderWait)) 365 gqlAPIRouter.Use(dataloader.HandlerDocument(rootResolver.DocumentsDataloader, cfg.DataloaderMaxBatch, cfg.DataloaderWait)) 366 gqlAPIRouter.Use(dataloader.HandlerFetchRequestAPIDef(rootResolver.FetchRequestAPIDefDataloader, cfg.DataloaderMaxBatch, cfg.DataloaderWait)) 367 gqlAPIRouter.Use(dataloader.HandlerFetchRequestEventDef(rootResolver.FetchRequestEventDefDataloader, cfg.DataloaderMaxBatch, cfg.DataloaderWait)) 368 gqlAPIRouter.Use(dataloader.HandlerFetchRequestDocument(rootResolver.FetchRequestDocumentDataloader, cfg.DataloaderMaxBatch, cfg.DataloaderWait)) 369 gqlAPIRouter.Use(dataloader.HandlerRuntimeContext(rootResolver.RuntimeContextsDataloader, cfg.DataloaderMaxBatch, cfg.DataloaderWait)) 370 gqlAPIRouter.Use(dataloader.HandlerFormationAssignment(rootResolver.FormationAssignmentsDataLoader, cfg.DataloaderMaxBatch, cfg.DataloaderWait)) 371 gqlAPIRouter.Use(dataloader.HandlerFormationStatus(rootResolver.StatusDataLoader, cfg.DataloaderMaxBatch, cfg.DataloaderWait)) 372 gqlAPIRouter.Use(dataloader.HandlerFormationConstraint(rootResolver.FormationConstraintsDataLoader, cfg.DataloaderMaxBatch, cfg.DataloaderWait)) 373 operationMiddleware := operation.NewMiddleware(cfg.AppURL + cfg.LastOperationPath) 374 375 gqlServ := handler.NewDefaultServer(executableSchema) 376 gqlServ.Use(log.NewGqlLoggingInterceptor()) 377 gqlServ.Use(metrics.NewInstrumentGraphqlRequestInterceptor(metricsCollector)) 378 379 gqlServ.Use(operationMiddleware) 380 gqlServ.SetErrorPresenter(presenter.Do) 381 gqlServ.SetRecoverFunc(panichandler.RecoverFn) 382 383 gqlAPIRouter.HandleFunc("", metricsCollector.GraphQLHandlerWithInstrumentation(gqlServ)) 384 385 operationHandler := operation.NewHandler(transact, func(ctx context.Context, tenantID, resourceID string) (model.Entity, error) { 386 return appRepo.GetByID(ctx, tenantID, resourceID) 387 }, tenant.LoadFromContext) 388 389 operationsAPIRouter := mainRouter.PathPrefix(cfg.LastOperationPath).Subrouter() 390 operationsAPIRouter.Use(authMiddleware.Handler()) 391 operationsAPIRouter.HandleFunc("/{resource_type}/{resource_id}", operationHandler.ServeHTTP) 392 393 operationUpdaterHandler := operation.NewUpdateOperationHandler(transact, map[resource.Type]operation.ResourceUpdaterFunc{ 394 resource.Application: appUpdaterFunc(appRepo), 395 }, map[resource.Type]operation.ResourceDeleterFunc{ 396 resource.Application: func(ctx context.Context, id string) error { 397 return appRepo.DeleteGlobal(ctx, id) 398 }, 399 }) 400 401 internalRouter := mux.NewRouter() 402 internalRouter.Use(correlation.AttachCorrelationIDToContext(), log.RequestLogger(), header.AttachHeadersToContext()) 403 internalOperationsAPIRouter := internalRouter.PathPrefix(cfg.OperationPath).Subrouter() 404 internalOperationsAPIRouter.HandleFunc("", operationUpdaterHandler.ServeHTTP) 405 406 logger.Infof("Registering readiness endpoint...") 407 schemaRepo := schema.NewRepository() 408 ready := healthz.NewReady(transact, cfg.ReadyConfig, schemaRepo) 409 mainRouter.HandleFunc(readyzEndpoint, healthz.NewReadinessHandler(ready)) 410 411 logger.Infof("Registering liveness endpoint...") 412 mainRouter.HandleFunc(livezEndpoint, healthz.NewLivenessHandler()) 413 414 logger.Infof("Registering health endpoint...") 415 health, err := healthz.New(ctx, cfg.HealthConfig) 416 exitOnError(err, "Could not initialize health") 417 health.RegisterIndicator(healthz.NewIndicator(healthz.DBIndicatorName, healthz.NewDBIndicatorFunc(transact))).Start() 418 mainRouter.HandleFunc(healthzEndpoint, healthz.NewHealthHandler(health)) 419 420 logger.Infof("Registering info endpoint...") 421 mainRouter.HandleFunc(cfg.InfoConfig.APIEndpoint, info.NewInfoHandler(ctx, cfg.InfoConfig, certCache)) 422 423 fmAuthMiddleware := createFormationMappingAuthenticator(transact, cfg, cfg.DestinationCreatorConfig, appRepo, httpClient, mtlsHTTPClient, extSvcMtlsHTTPClient) 424 fmHandler := createFormationMappingHandler(transact, appRepo, cfg, cfg.DestinationCreatorConfig, httpClient, mtlsHTTPClient, extSvcMtlsHTTPClient) 425 426 asyncFormationAssignmentStatusRouter := mainRouter.PathPrefix(cfg.FormationMappingCfg.AsyncAPIPathPrefix).Subrouter() 427 asyncFormationAssignmentStatusRouter.Use(authMiddleware.Handler(), fmAuthMiddleware.FormationAssignmentHandler()) // order is important 428 429 asyncFormationStatusRouter := mainRouter.PathPrefix(cfg.FormationMappingCfg.AsyncAPIPathPrefix).Subrouter() 430 asyncFormationStatusRouter.Use(authMiddleware.Handler(), fmAuthMiddleware.FormationHandler()) // order is important 431 432 logger.Infof("Registering formation tenant mapping endpoints...") 433 asyncFormationAssignmentStatusRouter.HandleFunc(cfg.FormationMappingCfg.AsyncFormationAssignmentStatusAPIEndpoint, fmHandler.UpdateFormationAssignmentStatus).Methods(http.MethodPatch) 434 asyncFormationStatusRouter.HandleFunc(cfg.FormationMappingCfg.AsyncFormationStatusAPIEndpoint, fmHandler.UpdateFormationStatus).Methods(http.MethodPatch) 435 436 examplesServer := http.FileServer(http.Dir("./examples/")) 437 mainRouter.PathPrefix("/examples/").Handler(http.StripPrefix("/examples/", examplesServer)) 438 439 metricsHandler := http.NewServeMux() 440 metricsHandler.Handle("/metrics", promhttp.Handler()) 441 442 runMetricsSrv, shutdownMetricsSrv := createServer(ctx, cfg.MetricsAddress, metricsHandler, "metrics", cfg.ServerTimeout) 443 runMainSrv, shutdownMainSrv := createServer(ctx, cfg.Address, mainRouter, "main", cfg.ServerTimeout) 444 runInternalSrv, shutdownInternalSrv := createServer(ctx, cfg.InternalAddress, internalRouter, "internal", cfg.ServerTimeout) 445 446 go func() { 447 <-ctx.Done() 448 // Interrupt signal received - shut down the servers 449 shutdownMetricsSrv() 450 shutdownInternalSrv() 451 shutdownMainSrv() 452 }() 453 454 go runMetricsSrv() 455 go runInternalSrv() 456 runMainSrv() 457 } 458 459 func getPairingAdaptersMapping(ctx context.Context, k8sClient *kubernetes.Clientset, adaptersCfg configprovider.PairingAdapterConfig) (*pkgadapters.Adapters, error) { 460 logger := log.C(ctx) 461 logger.Infof("Getting pairing adapter configuration from the cluster...") 462 cm, err := k8sClient.CoreV1().ConfigMaps(adaptersCfg.ConfigmapNamespace).Get(ctx, adaptersCfg.ConfigmapName, metav1.GetOptions{}) 463 if err != nil { 464 return nil, err 465 } 466 467 adaptersMap := make(map[string]string) 468 if err = json.Unmarshal([]byte(cm.Data[adaptersCfg.ConfigmapKey]), &adaptersMap); err != nil { 469 return nil, err 470 } 471 472 logger.Infof("Successfully read pairing adapters configuration from the cluster") 473 474 a := pkgadapters.NewAdapters() 475 a.Update(adaptersMap) 476 477 logger.Infof("Successfully updated pairing adapters configuration") 478 479 return a, nil 480 } 481 482 func startPairingAdaptersWatcher(ctx context.Context, k8sClient *kubernetes.Clientset, adapters *pkgadapters.Adapters, adaptersCfg configprovider.PairingAdapterConfig) { 483 processEventsFunc := func(ctx context.Context, events <-chan watch.Event) { 484 for { 485 select { 486 case <-ctx.Done(): 487 return 488 case ev, ok := <-events: 489 if !ok { 490 return 491 } 492 switch ev.Type { 493 case watch.Added: 494 fallthrough 495 case watch.Modified: 496 log.C(ctx).Info("Updating pairing adapter configuration...") 497 cm, ok := ev.Object.(*v1.ConfigMap) 498 if !ok { 499 log.C(ctx).Error("Unexpected error: object is not configmap. Try again") 500 continue 501 } 502 aCfg, found := cm.Data[adaptersCfg.ConfigmapKey] 503 if !found { 504 log.C(ctx).Errorf("Did not find the expected key: %s in the pairing adapter configmap", adaptersCfg.ConfigmapKey) 505 return 506 } 507 adaptersCM := make(map[string]string) 508 if err := json.Unmarshal([]byte(aCfg), &adaptersCM); err != nil { 509 log.C(ctx).Error("error while unmarshalling adapters configuration") 510 return 511 } 512 adapters.Update(adaptersCM) 513 log.C(ctx).Info("Successfully updated in memory pairing adapter configuration") 514 case watch.Deleted: 515 log.C(ctx).Info("Delete event is received, removing pairing adapter configuration") 516 adapters.Update(nil) 517 case watch.Error: 518 log.C(ctx).Error("Error event is received, stop pairing adapter configmap watcher and try again...") 519 return 520 } 521 } 522 } 523 } 524 525 cmManager := k8sClient.CoreV1().ConfigMaps(adaptersCfg.ConfigmapNamespace) 526 w := kube.NewWatcher(ctx, cmManager, processEventsFunc, time.Second, adaptersCfg.ConfigmapName, adaptersCfg.WatcherCorrelationID) 527 go w.Run(ctx) 528 } 529 530 func createAndRunConfigProvider(ctx context.Context, cfg config) *configprovider.Provider { 531 provider := configprovider.NewProvider(cfg.ConfigurationFile) 532 err := provider.Load() 533 exitOnError(err, "Error on loading configuration file") 534 executor.NewPeriodic(cfg.ConfigurationFileReload, func(ctx context.Context) { 535 if err := provider.Load(); err != nil { 536 exitOnError(err, "Error from Reloader watch") 537 } 538 log.C(ctx).Infof("Successfully reloaded configuration file.") 539 }).Run(ctx) 540 541 return provider 542 } 543 544 func exitOnError(err error, context string) { 545 if err != nil { 546 wrappedError := errors.Wrap(err, context) 547 log.D().Fatal(wrappedError) 548 } 549 } 550 551 func createServer(ctx context.Context, address string, handler http.Handler, name string, timeout time.Duration) (func(), func()) { 552 handlerWithTimeout, err := timeouthandler.WithTimeout(handler, timeout) 553 exitOnError(err, "Error while configuring tenant mapping handler") 554 555 srv := &http.Server{ 556 Addr: address, 557 Handler: handlerWithTimeout, 558 ReadHeaderTimeout: timeout, 559 } 560 561 runFn := func() { 562 log.C(ctx).Infof("Running %s server on %s...", name, address) 563 if err := srv.ListenAndServe(); err != http.ErrServerClosed { 564 log.C(ctx).WithError(err).Errorf("An error has occurred with %s HTTP server when ListenAndServe: %v", name, err) 565 } 566 } 567 568 shutdownFn := func() { 569 log.C(ctx).Infof("Shutting down %s server...", name) 570 if err := srv.Shutdown(context.Background()); err != nil { 571 log.C(ctx).WithError(err).Errorf("An error has occurred while shutting down HTTP server %s: %v", name, err) 572 } 573 } 574 575 return runFn, shutdownFn 576 } 577 578 func bundleInstanceAuthRepo() bundleinstanceauth.Repository { 579 authConverter := auth.NewConverter() 580 581 return bundleinstanceauth.NewRepository(bundleinstanceauth.NewConverter(authConverter)) 582 } 583 584 func bundleRepo() bundle.BundleRepository { 585 authConverter := auth.NewConverter() 586 frConverter := fetchrequest.NewConverter(authConverter) 587 versionConverter := version.NewConverter() 588 specConverter := spec.NewConverter(frConverter) 589 eventAPIConverter := eventdef.NewConverter(versionConverter, specConverter) 590 docConverter := document.NewConverter(frConverter) 591 apiConverter := api.NewConverter(versionConverter, specConverter) 592 593 return bundle.NewRepository(bundle.NewConverter(authConverter, apiConverter, eventAPIConverter, docConverter)) 594 } 595 596 func applicationRepo() application.ApplicationRepository { 597 authConverter := auth.NewConverter() 598 599 versionConverter := version.NewConverter() 600 frConverter := fetchrequest.NewConverter(authConverter) 601 specConverter := spec.NewConverter(frConverter) 602 603 apiConverter := api.NewConverter(versionConverter, specConverter) 604 eventAPIConverter := eventdef.NewConverter(versionConverter, specConverter) 605 docConverter := document.NewConverter(frConverter) 606 607 webhookConverter := webhook.NewConverter(authConverter) 608 bundleConverter := bundle.NewConverter(authConverter, apiConverter, eventAPIConverter, docConverter) 609 610 appConverter := application.NewConverter(webhookConverter, bundleConverter) 611 612 return application.NewRepository(appConverter) 613 } 614 615 func webhookService(tenantMappingConfig map[string]interface{}, callbackURL string) webhook.WebhookService { 616 uidSvc := uid.NewService() 617 authConverter := auth.NewConverter() 618 619 webhookConverter := webhook.NewConverter(authConverter) 620 webhookRepo := webhook.NewRepository(webhookConverter) 621 622 tenantConverter := tenant.NewConverter() 623 tenantRepo := tenant.NewRepository(tenantConverter) 624 625 labelConverter := label.NewConverter() 626 labelRepo := label.NewRepository(labelConverter) 627 labelDefinitionConverter := labeldef.NewConverter() 628 labelDefinitionRepo := labeldef.NewRepository(labelDefinitionConverter) 629 labelSvc := label.NewLabelService(labelRepo, labelDefinitionRepo, uidSvc) 630 631 tenantSvc := tenant.NewServiceWithLabels(tenantRepo, uidSvc, labelRepo, labelSvc, tenantConverter) 632 return webhook.NewService(webhookRepo, applicationRepo(), uidSvc, tenantSvc, tenantMappingConfig, callbackURL) 633 } 634 635 func getAsyncDirective(ctx context.Context, cfg config, transact persistence.Transactioner, appRepo application.ApplicationRepository, tenantMappingConfig map[string]interface{}) func(context.Context, interface{}, gqlgen.Resolver, graphql.OperationType, *graphql.WebhookType, *string) (res interface{}, err error) { 636 resourceFetcherFunc := func(ctx context.Context, tenantID, resourceID string) (model.Entity, error) { 637 return appRepo.GetByID(ctx, tenantID, resourceID) 638 } 639 640 scheduler, err := buildScheduler(ctx, cfg) 641 exitOnError(err, "Error while creating operations scheduler") 642 643 return operation.NewDirective(transact, webhookService(tenantMappingConfig, cfg.TenantMappingCallbackURL).ListAllApplicationWebhooks, resourceFetcherFunc, appUpdaterFunc(appRepo), tenant.LoadFromContext, scheduler).HandleOperation 644 } 645 646 func buildScheduler(ctx context.Context, config config) (operation.Scheduler, error) { 647 if config.DisableAsyncMode { 648 log.C(ctx).Info("Async operations are disabled") 649 return &operation.DisabledScheduler{}, nil 650 } 651 652 cfg, err := cr.GetConfig() 653 exitOnError(err, "Failed to get cluster config for operations k8s client") 654 655 cfg.Timeout = config.ClientTimeout 656 k8sClient, err := client.NewForConfig(cfg) 657 if err != nil { 658 return nil, err 659 } 660 operationsK8sClient := k8sClient.Operations(config.OperationsNamespace) 661 662 return k8s.NewScheduler(operationsK8sClient), nil 663 } 664 665 func appUpdaterFunc(appRepo application.ApplicationRepository) operation.ResourceUpdaterFunc { 666 return func(ctx context.Context, id string, ready bool, errorMsg *string, appStatusCondition model.ApplicationStatusCondition) error { 667 app, err := appRepo.GetGlobalByID(ctx, id) 668 if err != nil { 669 return err 670 } 671 app.Status = &model.ApplicationStatus{ 672 Condition: appStatusCondition, 673 Timestamp: time.Now(), 674 } 675 app.Ready = ready 676 app.Error = errorMsg 677 return appRepo.TechnicalUpdate(ctx, app) 678 } 679 } 680 681 func runtimeSvc(transact persistence.Transactioner, cfg config, tenantMappingConfig map[string]interface{}, securedHTTPClient, mtlsHTTPClient, extSvcMtlsHTTPClient *http.Client) claims.RuntimeService { 682 asaConverter := scenarioassignment.NewConverter() 683 authConverter := auth.NewConverter() 684 webhookConverter := webhook.NewConverter(authConverter) 685 frConverter := fetchrequest.NewConverter(authConverter) 686 versionConverter := version.NewConverter() 687 docConverter := document.NewConverter(frConverter) 688 specConverter := spec.NewConverter(frConverter) 689 apiConverter := api.NewConverter(versionConverter, specConverter) 690 eventAPIConverter := eventdef.NewConverter(versionConverter, specConverter) 691 bundleConverter := bundle.NewConverter(authConverter, apiConverter, eventAPIConverter, docConverter) 692 appConverter := application.NewConverter(webhookConverter, bundleConverter) 693 appTemplateConverter := apptemplate.NewConverter(appConverter, webhookConverter) 694 labelConverter := label.NewConverter() 695 labelDefinitionConverter := labeldef.NewConverter() 696 runtimeContextConverter := runtimectx.NewConverter() 697 runtimeConverter := runtime.NewConverter(webhookConverter) 698 tenantConverter := tenant.NewConverter() 699 formationConv := formation.NewConverter() 700 formationTemplateConverter := formationtemplate.NewConverter(webhookConverter) 701 formationConstraintConverter := formationconstraint.NewConverter() 702 formationTemplateConstraintReferencesConverter := formationtemplateconstraintreferences.NewConverter() 703 formationAssignmentConv := formationassignment.NewConverter() 704 705 appRepo := application.NewRepository(appConverter) 706 webhookRepo := webhook.NewRepository(webhookConverter) 707 appTemplateRepo := apptemplate.NewRepository(appTemplateConverter) 708 asaRepo := scenarioassignment.NewRepository(asaConverter) 709 labelRepo := label.NewRepository(labelConverter) 710 labelDefinitionRepo := labeldef.NewRepository(labelDefinitionConverter) 711 runtimeRepo := runtime.NewRepository(runtimeConverter) 712 runtimeContextRepo := runtimectx.NewRepository(runtimeContextConverter) 713 tenantRepo := tenant.NewRepository(tenantConverter) 714 formationRepo := formation.NewRepository(formationConv) 715 formationTemplateRepo := formationtemplate.NewRepository(formationTemplateConverter) 716 formationConstraintRepo := formationconstraint.NewRepository(formationConstraintConverter) 717 formationTemplateConstraintReferencesRepo := formationtemplateconstraintreferences.NewRepository(formationTemplateConstraintReferencesConverter) 718 formationAssignmentRepo := formationassignment.NewRepository(formationAssignmentConv) 719 720 webhookClient := webhookclient.NewClient(securedHTTPClient, mtlsHTTPClient, extSvcMtlsHTTPClient) 721 webhookDataInputBuilder := databuilder.NewWebhookDataInputBuilder(appRepo, appTemplateRepo, runtimeRepo, runtimeContextRepo, labelRepo) 722 723 uidSvc := uid.NewService() 724 labelSvc := label.NewLabelService(labelRepo, labelDefinitionRepo, uidSvc) 725 labelDefinitionSvc := labeldef.NewService(labelDefinitionRepo, labelRepo, asaRepo, tenantRepo, uidSvc) 726 asaSvc := scenarioassignment.NewService(asaRepo, labelDefinitionSvc) 727 tenantSvc := tenant.NewServiceWithLabels(tenantRepo, uidSvc, labelRepo, labelSvc, tenantConverter) 728 formationConstraintSvc := formationconstraint.NewService(formationConstraintRepo, formationTemplateConstraintReferencesRepo, uidSvc, formationConstraintConverter) 729 constraintEngine := operators.NewConstraintEngine(transact, formationConstraintSvc, tenantSvc, asaSvc, nil, formationRepo, labelRepo, labelSvc, appRepo, runtimeContextRepo, formationTemplateRepo, formationAssignmentRepo, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 730 notificationsBuilder := formation.NewNotificationsBuilder(webhookConverter, constraintEngine, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 731 notificationsGenerator := formation.NewNotificationsGenerator(appRepo, appTemplateRepo, runtimeRepo, runtimeContextRepo, labelRepo, webhookRepo, webhookDataInputBuilder, notificationsBuilder) 732 notificationSvc := formation.NewNotificationService(tenantRepo, webhookClient, notificationsGenerator, constraintEngine, webhookConverter, formationTemplateRepo) 733 faNotificationSvc := formationassignment.NewFormationAssignmentNotificationService(formationAssignmentRepo, webhookConverter, webhookRepo, tenantRepo, webhookDataInputBuilder, formationRepo, notificationsBuilder, runtimeContextRepo, labelSvc, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 734 formationAssignmentStatusSvc := formationassignment.NewFormationAssignmentStatusService(formationAssignmentRepo, constraintEngine, faNotificationSvc) 735 formationAssignmentSvc := formationassignment.NewService(formationAssignmentRepo, uidSvc, appRepo, runtimeRepo, runtimeContextRepo, notificationSvc, faNotificationSvc, labelSvc, formationRepo, formationAssignmentStatusSvc, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 736 formationStatusSvc := formation.NewFormationStatusService(formationRepo, labelDefinitionRepo, labelDefinitionSvc, notificationSvc, constraintEngine) 737 formationSvc := formation.NewService(transact, appRepo, labelDefinitionRepo, labelRepo, formationRepo, formationTemplateRepo, labelSvc, uidSvc, labelDefinitionSvc, asaRepo, asaSvc, tenantSvc, runtimeRepo, runtimeContextRepo, formationAssignmentSvc, faNotificationSvc, notificationSvc, constraintEngine, webhookRepo, formationStatusSvc, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 738 runtimeContextSvc := runtimectx.NewService(runtimeContextRepo, labelRepo, runtimeRepo, labelSvc, formationSvc, tenantSvc, uidSvc) 739 740 return runtime.NewService(runtimeRepo, labelRepo, labelSvc, uidSvc, formationSvc, tenantSvc, webhookService(tenantMappingConfig, cfg.TenantMappingCallbackURL), runtimeContextSvc, cfg.Features.ProtectedLabelPattern, cfg.Features.ImmutableLabelPattern, cfg.Features.RuntimeTypeLabelKey, cfg.Features.KymaRuntimeTypeLabelValue, cfg.Features.KymaApplicationNamespaceValue) 741 } 742 743 func runtimeCtxSvc(transact persistence.Transactioner, cfg config, securedHTTPClient, mtlsHTTPClient, extSvcMtlsHTTPClient *http.Client) claims.RuntimeCtxService { 744 runtimeContextConverter := runtimectx.NewConverter() 745 labelConverter := label.NewConverter() 746 labelDefinitionConverter := labeldef.NewConverter() 747 asaConverter := scenarioassignment.NewConverter() 748 tenantConverter := tenant.NewConverter() 749 authConverter := auth.NewConverter() 750 webhookConverter := webhook.NewConverter(authConverter) 751 runtimeConverter := runtime.NewConverter(webhookConverter) 752 formationConv := formation.NewConverter() 753 formationTemplateConverter := formationtemplate.NewConverter(webhookConverter) 754 frConverter := fetchrequest.NewConverter(authConverter) 755 versionConverter := version.NewConverter() 756 docConverter := document.NewConverter(frConverter) 757 specConverter := spec.NewConverter(frConverter) 758 apiConverter := api.NewConverter(versionConverter, specConverter) 759 eventAPIConverter := eventdef.NewConverter(versionConverter, specConverter) 760 bundleConverter := bundle.NewConverter(authConverter, apiConverter, eventAPIConverter, docConverter) 761 appConverter := application.NewConverter(webhookConverter, bundleConverter) 762 appRepo := application.NewRepository(appConverter) 763 webhookRepo := webhook.NewRepository(webhookConverter) 764 appTemplateConverter := apptemplate.NewConverter(appConverter, webhookConverter) 765 formationConstraintConverter := formationconstraint.NewConverter() 766 formationTemplateConstraintReferencesConverter := formationtemplateconstraintreferences.NewConverter() 767 768 appTemplateRepo := apptemplate.NewRepository(appTemplateConverter) 769 runtimeContextRepo := runtimectx.NewRepository(runtimeContextConverter) 770 labelRepo := label.NewRepository(labelConverter) 771 labelDefinitionRepo := labeldef.NewRepository(labelDefinitionConverter) 772 asaRepo := scenarioassignment.NewRepository(asaConverter) 773 tenantRepo := tenant.NewRepository(tenantConverter) 774 runtimeRepo := runtime.NewRepository(runtimeConverter) 775 formationRepo := formation.NewRepository(formationConv) 776 formationTemplateRepo := formationtemplate.NewRepository(formationTemplateConverter) 777 formationConstraintRepo := formationconstraint.NewRepository(formationConstraintConverter) 778 formationTemplateConstraintReferencesRepo := formationtemplateconstraintreferences.NewRepository(formationTemplateConstraintReferencesConverter) 779 780 uidSvc := uid.NewService() 781 labelSvc := label.NewLabelService(labelRepo, labelDefinitionRepo, uidSvc) 782 labelDefinitionSvc := labeldef.NewService(labelDefinitionRepo, labelRepo, asaRepo, tenantRepo, uidSvc) 783 asaSvc := scenarioassignment.NewService(asaRepo, labelDefinitionSvc) 784 tenantSvc := tenant.NewServiceWithLabels(tenantRepo, uidSvc, labelRepo, labelSvc, tenantConverter) 785 webhookClient := webhookclient.NewClient(securedHTTPClient, mtlsHTTPClient, extSvcMtlsHTTPClient) 786 formationAssignmentConv := formationassignment.NewConverter() 787 formationAssignmentRepo := formationassignment.NewRepository(formationAssignmentConv) 788 webhookDataInputBuilder := databuilder.NewWebhookDataInputBuilder(appRepo, appTemplateRepo, runtimeRepo, runtimeContextRepo, labelRepo) 789 formationConstraintSvc := formationconstraint.NewService(formationConstraintRepo, formationTemplateConstraintReferencesRepo, uidSvc, formationConstraintConverter) 790 constraintEngine := operators.NewConstraintEngine(transact, formationConstraintSvc, tenantSvc, asaSvc, nil, formationRepo, labelRepo, labelSvc, appRepo, runtimeContextRepo, formationTemplateRepo, formationAssignmentRepo, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 791 notificationsBuilder := formation.NewNotificationsBuilder(webhookConverter, constraintEngine, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 792 notificationsGenerator := formation.NewNotificationsGenerator(appRepo, appTemplateRepo, runtimeRepo, runtimeContextRepo, labelRepo, webhookRepo, webhookDataInputBuilder, notificationsBuilder) 793 notificationSvc := formation.NewNotificationService(tenantRepo, webhookClient, notificationsGenerator, constraintEngine, webhookConverter, formationTemplateRepo) 794 faNotificationSvc := formationassignment.NewFormationAssignmentNotificationService(formationAssignmentRepo, webhookConverter, webhookRepo, tenantRepo, webhookDataInputBuilder, formationRepo, notificationsBuilder, runtimeContextRepo, labelSvc, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 795 formationAssignmentStatusSvc := formationassignment.NewFormationAssignmentStatusService(formationAssignmentRepo, constraintEngine, faNotificationSvc) 796 formationAssignmentSvc := formationassignment.NewService(formationAssignmentRepo, uidSvc, appRepo, runtimeRepo, runtimeContextRepo, notificationSvc, faNotificationSvc, labelSvc, formationRepo, formationAssignmentStatusSvc, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 797 formationStatusSvc := formation.NewFormationStatusService(formationRepo, labelDefinitionRepo, labelDefinitionSvc, notificationSvc, constraintEngine) 798 formationSvc := formation.NewService(transact, appRepo, labelDefinitionRepo, labelRepo, formationRepo, formationTemplateRepo, labelSvc, uidSvc, labelDefinitionSvc, asaRepo, asaSvc, tenantSvc, runtimeRepo, runtimeContextRepo, formationAssignmentSvc, faNotificationSvc, notificationSvc, constraintEngine, webhookRepo, formationStatusSvc, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 799 800 return runtimectx.NewService(runtimeContextRepo, labelRepo, runtimeRepo, labelSvc, formationSvc, tenantSvc, uidSvc) 801 } 802 803 func appTemplateSvc() claims.ApplicationTemplateService { 804 uidSvc := uid.NewService() 805 authConverter := auth.NewConverter() 806 versionConverter := version.NewConverter() 807 808 frConverter := fetchrequest.NewConverter(authConverter) 809 specConverter := spec.NewConverter(frConverter) 810 eventAPIConverter := eventdef.NewConverter(versionConverter, specConverter) 811 docConverter := document.NewConverter(frConverter) 812 apiConverter := api.NewConverter(versionConverter, specConverter) 813 bundleConverter := bundle.NewConverter(authConverter, apiConverter, eventAPIConverter, docConverter) 814 webhookConverter := webhook.NewConverter(authConverter) 815 appConverter := application.NewConverter(webhookConverter, bundleConverter) 816 appTemplateConv := apptemplate.NewConverter(appConverter, webhookConverter) 817 appTemplateRepo := apptemplate.NewRepository(appTemplateConv) 818 819 webhookRepo := webhook.NewRepository(webhookConverter) 820 821 labelConverter := label.NewConverter() 822 labelRepo := label.NewRepository(labelConverter) 823 labelDefConverter := labeldef.NewConverter() 824 labelDefRepo := labeldef.NewRepository(labelDefConverter) 825 labelSvc := label.NewLabelService(labelRepo, labelDefRepo, uidSvc) 826 appRepo := application.NewRepository(appConverter) 827 828 return apptemplate.NewService(appTemplateRepo, webhookRepo, uidSvc, labelSvc, labelRepo, appRepo) 829 } 830 831 func applicationSvc(transact persistence.Transactioner, cfg config, securedHTTPClient, mtlsHTTPClient, extSvcMtlsHTTPClient *http.Client, certCache certloader.Cache, ordWebhookMapping []application.ORDWebhookMapping) claims.ApplicationService { 832 uidSvc := uid.NewService() 833 authConverter := auth.NewConverter() 834 webhookConverter := webhook.NewConverter(authConverter) 835 runtimeConverter := runtime.NewConverter(webhookConverter) 836 runtimeRepo := runtime.NewRepository(runtimeConverter) 837 838 intSysConverter := integrationsystem.NewConverter() 839 intSysRepo := integrationsystem.NewRepository(intSysConverter) 840 841 webhookRepo := webhook.NewRepository(webhookConverter) 842 843 labelConverter := label.NewConverter() 844 labelRepo := label.NewRepository(labelConverter) 845 labelDefConverter := labeldef.NewConverter() 846 labelDefRepo := labeldef.NewRepository(labelDefConverter) 847 labelSvc := label.NewLabelService(labelRepo, labelDefRepo, uidSvc) 848 assignmentConv := scenarioassignment.NewConverter() 849 scenarioAssignmentRepo := scenarioassignment.NewRepository(assignmentConv) 850 tenantConverter := tenant.NewConverter() 851 tenantRepo := tenant.NewRepository(tenantConverter) 852 853 scenariosSvc := labeldef.NewService(labelDefRepo, labelRepo, scenarioAssignmentRepo, tenantRepo, uidSvc) 854 855 frConverter := fetchrequest.NewConverter(authConverter) 856 docConverter := document.NewConverter(frConverter) 857 docRepo := document.NewRepository(docConverter) 858 859 fetchRequestRepo := fetchrequest.NewRepository(frConverter) 860 861 docSvc := document.NewService(docRepo, fetchRequestRepo, uidSvc) 862 versionConverter := version.NewConverter() 863 specConverter := spec.NewConverter(frConverter) 864 apiConverter := api.NewConverter(versionConverter, specConverter) 865 apiRepo := api.NewRepository(apiConverter) 866 specRepo := spec.NewRepository(specConverter) 867 fetchRequestSvc := fetchrequest.NewService(fetchRequestRepo, securedHTTPClient, accessstrategy.NewDefaultExecutorProvider(certCache, cfg.ExternalClientCertSecretName, cfg.ExtSvcClientCertSecretName)) 868 specSvc := spec.NewService(specRepo, fetchRequestRepo, uidSvc, fetchRequestSvc) 869 bundleReferenceConv := bundlereferences.NewConverter() 870 bundleReferenceRepo := bundlereferences.NewRepository(bundleReferenceConv) 871 bundleReferenceSvc := bundlereferences.NewService(bundleReferenceRepo, uidSvc) 872 apiSvc := api.NewService(apiRepo, uidSvc, specSvc, bundleReferenceSvc) 873 eventAPIConverter := eventdef.NewConverter(versionConverter, specConverter) 874 eventAPIRepo := eventdef.NewRepository(eventAPIConverter) 875 876 eventAPISvc := eventdef.NewService(eventAPIRepo, uidSvc, specSvc, bundleReferenceSvc) 877 bundleConverter := bundle.NewConverter(authConverter, apiConverter, eventAPIConverter, docConverter) 878 bundleRepo := bundle.NewRepository(bundleConverter) 879 880 bundleSvc := bundle.NewService(bundleRepo, apiSvc, eventAPISvc, docSvc, uidSvc) 881 formationConv := formation.NewConverter() 882 formationTemplateConverter := formationtemplate.NewConverter(webhookConverter) 883 formationRepo := formation.NewRepository(formationConv) 884 formationTemplateRepo := formationtemplate.NewRepository(formationTemplateConverter) 885 886 scenarioAssignmentSvc := scenarioassignment.NewService(scenarioAssignmentRepo, scenariosSvc) 887 tntSvc := tenant.NewServiceWithLabels(tenantRepo, uidSvc, labelRepo, labelSvc, tenantConverter) 888 889 runtimeContextConv := runtimectx.NewConverter() 890 runtimeContextRepo := runtimectx.NewRepository(runtimeContextConv) 891 892 appConverter := application.NewConverter(webhookConverter, bundleConverter) 893 applicationRepo := application.NewRepository(appConverter) 894 895 appTemplateConverter := apptemplate.NewConverter(appConverter, webhookConverter) 896 appTemplateRepo := apptemplate.NewRepository(appTemplateConverter) 897 898 formationConstraintConverter := formationconstraint.NewConverter() 899 formationConstraintRepo := formationconstraint.NewRepository(formationConstraintConverter) 900 901 formationTemplateConstraintReferencesConverter := formationtemplateconstraintreferences.NewConverter() 902 formationTemplateConstraintReferencesRepo := formationtemplateconstraintreferences.NewRepository(formationTemplateConstraintReferencesConverter) 903 904 webhookClient := webhookclient.NewClient(securedHTTPClient, mtlsHTTPClient, extSvcMtlsHTTPClient) 905 formationAssignmentConv := formationassignment.NewConverter() 906 formationAssignmentRepo := formationassignment.NewRepository(formationAssignmentConv) 907 webhookDataInputBuilder := databuilder.NewWebhookDataInputBuilder(applicationRepo, appTemplateRepo, runtimeRepo, runtimeContextRepo, labelRepo) 908 formationConstraintSvc := formationconstraint.NewService(formationConstraintRepo, formationTemplateConstraintReferencesRepo, uidSvc, formationConstraintConverter) 909 constraintEngine := operators.NewConstraintEngine(transact, formationConstraintSvc, tntSvc, scenarioAssignmentSvc, nil, formationRepo, labelRepo, labelSvc, applicationRepo, runtimeContextRepo, formationTemplateRepo, formationAssignmentRepo, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 910 notificationsBuilder := formation.NewNotificationsBuilder(webhookConverter, constraintEngine, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 911 notificationsGenerator := formation.NewNotificationsGenerator(applicationRepo, appTemplateRepo, runtimeRepo, runtimeContextRepo, labelRepo, webhookRepo, webhookDataInputBuilder, notificationsBuilder) 912 notificationSvc := formation.NewNotificationService(tenantRepo, webhookClient, notificationsGenerator, constraintEngine, webhookConverter, formationTemplateRepo) 913 faNotificationSvc := formationassignment.NewFormationAssignmentNotificationService(formationAssignmentRepo, webhookConverter, webhookRepo, tenantRepo, webhookDataInputBuilder, formationRepo, notificationsBuilder, runtimeContextRepo, labelSvc, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 914 formationAssignmentStatusSvc := formationassignment.NewFormationAssignmentStatusService(formationAssignmentRepo, constraintEngine, faNotificationSvc) 915 formationAssignmentSvc := formationassignment.NewService(formationAssignmentRepo, uidSvc, applicationRepo, runtimeRepo, runtimeContextRepo, notificationSvc, faNotificationSvc, labelSvc, formationRepo, formationAssignmentStatusSvc, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 916 formationStatusSvc := formation.NewFormationStatusService(formationRepo, labelDefRepo, scenariosSvc, notificationSvc, constraintEngine) 917 formationSvc := formation.NewService(transact, applicationRepo, labelDefRepo, labelRepo, formationRepo, formationTemplateRepo, labelSvc, uidSvc, scenariosSvc, scenarioAssignmentRepo, scenarioAssignmentSvc, tntSvc, runtimeRepo, runtimeContextRepo, formationAssignmentSvc, faNotificationSvc, notificationSvc, constraintEngine, webhookRepo, formationStatusSvc, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 918 919 return application.NewService(&normalizer.DefaultNormalizator{}, nil, applicationRepo, webhookRepo, runtimeRepo, labelRepo, intSysRepo, labelSvc, bundleSvc, uidSvc, formationSvc, cfg.SelfRegConfig.SelfRegisterDistinguishLabelKey, ordWebhookMapping) 920 } 921 922 func intSystemSvc() claims.IntegrationSystemService { 923 intSysConverter := integrationsystem.NewConverter() 924 intSysRepo := integrationsystem.NewRepository(intSysConverter) 925 return integrationsystem.NewService(intSysRepo, uid.NewService()) 926 } 927 928 func createFormationMappingAuthenticator(transact persistence.Transactioner, cfg config, destinationCreatorConfig *destinationcreator.Config, appRepo application.ApplicationRepository, securedHTTPClient, mtlsHTTPClient, extSvcMtlsHTTPClient *http.Client) *formationmapping.Authenticator { 929 formationAssignmentConv := formationassignment.NewConverter() 930 authConverter := auth.NewConverter() 931 webhookConverter := webhook.NewConverter(authConverter) 932 frConverter := fetchrequest.NewConverter(authConverter) 933 versionConverter := version.NewConverter() 934 specConverter := spec.NewConverter(frConverter) 935 docConverter := document.NewConverter(frConverter) 936 eventAPIConverter := eventdef.NewConverter(versionConverter, specConverter) 937 apiConverter := api.NewConverter(versionConverter, specConverter) 938 bundleConverter := bundle.NewConverter(authConverter, apiConverter, eventAPIConverter, docConverter) 939 appConverter := application.NewConverter(webhookConverter, bundleConverter) 940 appTemplateConverter := apptemplate.NewConverter(appConverter, webhookConverter) 941 tenantConverter := tenant.NewConverter() 942 formationConv := formation.NewConverter() 943 formationTemplateConverter := formationtemplate.NewConverter(webhookConverter) 944 destinationConv := destination.NewConverter() 945 946 appTemplateRepo := apptemplate.NewRepository(appTemplateConverter) 947 labelRepo := label.NewRepository(label.NewConverter()) 948 formationAssignmentRepo := formationassignment.NewRepository(formationAssignmentConv) 949 runtimeContextRepo := runtimectx.NewRepository(runtimectx.NewConverter()) 950 webhookRepo := webhook.NewRepository(webhookConverter) 951 runtimeRepo := runtime.NewRepository(runtime.NewConverter(webhook.NewConverter(auth.NewConverter()))) 952 tenantRepo := tenant.NewRepository(tenantConverter) 953 formationRepo := formation.NewRepository(formationConv) 954 formationTemplateRepo := formationtemplate.NewRepository(formationTemplateConverter) 955 destinationRepo := destination.NewRepository(destinationConv) 956 957 webhookClient := webhookclient.NewClient(securedHTTPClient, mtlsHTTPClient, extSvcMtlsHTTPClient) 958 webhookDataInputBuilder := databuilder.NewWebhookDataInputBuilder(appRepo, appTemplateRepo, runtimeRepo, runtimeContextRepo, labelRepo) 959 960 labelDefinitionConverter := labeldef.NewConverter() 961 asaConverter := scenarioassignment.NewConverter() 962 formationConstraintConverter := formationconstraint.NewConverter() 963 formationTemplateConstraintReferencesConverter := formationtemplateconstraintreferences.NewConverter() 964 labelDefinitionRepo := labeldef.NewRepository(labelDefinitionConverter) 965 asaRepo := scenarioassignment.NewRepository(asaConverter) 966 formationConstraintRepo := formationconstraint.NewRepository(formationConstraintConverter) 967 formationTemplateConstraintReferencesRepo := formationtemplateconstraintreferences.NewRepository(formationTemplateConstraintReferencesConverter) 968 uidSvc := uid.NewService() 969 labelDefinitionSvc := labeldef.NewService(labelDefinitionRepo, labelRepo, asaRepo, tenantRepo, uidSvc) 970 asaSvc := scenarioassignment.NewService(asaRepo, labelDefinitionSvc) 971 labelSvc := label.NewLabelService(labelRepo, labelDefinitionRepo, uidSvc) 972 tenantSvc := tenant.NewServiceWithLabels(tenantRepo, uidSvc, labelRepo, labelSvc, tenantConverter) 973 formationConstraintSvc := formationconstraint.NewService(formationConstraintRepo, formationTemplateConstraintReferencesRepo, uidSvc, formationConstraintConverter) 974 destinationSvc := destination.NewService(mtlsHTTPClient, destinationCreatorConfig, transact, applicationRepo(), runtimeRepo, runtimeContextRepo, labelRepo, destinationRepo, tenantRepo, uidSvc) 975 constraintEngine := operators.NewConstraintEngine(transact, formationConstraintSvc, tenantSvc, asaSvc, destinationSvc, formationRepo, labelRepo, labelSvc, appRepo, runtimeContextRepo, formationTemplateRepo, formationAssignmentRepo, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 976 notificationsBuilder := formation.NewNotificationsBuilder(webhookConverter, constraintEngine, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 977 notificationSvc := formation.NewNotificationService(tenantRepo, webhookClient, nil, constraintEngine, webhookConverter, formationTemplateRepo) 978 faNotificationSvc := formationassignment.NewFormationAssignmentNotificationService(formationAssignmentRepo, webhookConverter, webhookRepo, tenantRepo, webhookDataInputBuilder, formationRepo, notificationsBuilder, runtimeContextRepo, labelSvc, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 979 formationAssignmentStatusSvc := formationassignment.NewFormationAssignmentStatusService(formationAssignmentRepo, constraintEngine, faNotificationSvc) 980 formationAssignmentSvc := formationassignment.NewService(formationAssignmentRepo, uid.NewService(), appRepo, runtimeRepo, runtimeContextRepo, notificationSvc, faNotificationSvc, labelSvc, formationRepo, formationAssignmentStatusSvc, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 981 982 return formationmapping.NewFormationMappingAuthenticator(transact, formationAssignmentSvc, runtimeRepo, runtimeContextRepo, appRepo, appTemplateRepo, labelRepo, formationRepo, formationTemplateRepo, tenantRepo, cfg.SubscriptionConfig.ConsumerSubaccountLabelKey) 983 } 984 985 func createFormationMappingHandler(transact persistence.Transactioner, appRepo application.ApplicationRepository, cfg config, destinationCreatorConfig *destinationcreator.Config, securedHTTPClient, mtlsHTTPClient, extSvcMtlsHTTPClient *http.Client) *formationmapping.Handler { 986 formationAssignmentConv := formationassignment.NewConverter() 987 authConverter := auth.NewConverter() 988 webhookConverter := webhook.NewConverter(authConverter) 989 frConverter := fetchrequest.NewConverter(authConverter) 990 versionConverter := version.NewConverter() 991 specConverter := spec.NewConverter(frConverter) 992 docConverter := document.NewConverter(frConverter) 993 apiConverter := api.NewConverter(versionConverter, specConverter) 994 eventAPIConverter := eventdef.NewConverter(versionConverter, specConverter) 995 bundleConverter := bundle.NewConverter(authConverter, apiConverter, eventAPIConverter, docConverter) 996 appConverter := application.NewConverter(webhookConverter, bundleConverter) 997 appTemplateConverter := apptemplate.NewConverter(appConverter, webhookConverter) 998 formationConv := formation.NewConverter() 999 formationTemplateConverter := formationtemplate.NewConverter(webhookConverter) 1000 labelDefinitionConverter := labeldef.NewConverter() 1001 asaConverter := scenarioassignment.NewConverter() 1002 tenantConverter := tenant.NewConverter() 1003 formationConstraintConverter := formationconstraint.NewConverter() 1004 formationTemplateConstraintReferencesConverter := formationtemplateconstraintreferences.NewConverter() 1005 destinationConv := destination.NewConverter() 1006 1007 labelRepo := label.NewRepository(label.NewConverter()) 1008 formationAssignmentRepo := formationassignment.NewRepository(formationAssignmentConv) 1009 appTemplateRepo := apptemplate.NewRepository(appTemplateConverter) 1010 runtimeRepo := runtime.NewRepository(runtime.NewConverter(webhook.NewConverter(auth.NewConverter()))) 1011 runtimeContextRepo := runtimectx.NewRepository(runtimectx.NewConverter()) 1012 webhookRepo := webhook.NewRepository(webhookConverter) 1013 labelDefRepo := labeldef.NewRepository(labeldef.NewConverter()) 1014 formationRepo := formation.NewRepository(formationConv) 1015 formationTemplateRepo := formationtemplate.NewRepository(formationTemplateConverter) 1016 labelDefinitionRepo := labeldef.NewRepository(labelDefinitionConverter) 1017 asaRepo := scenarioassignment.NewRepository(asaConverter) 1018 tenantRepo := tenant.NewRepository(tenantConverter) 1019 formationConstraintRepo := formationconstraint.NewRepository(formationConstraintConverter) 1020 formationTemplateConstraintReferencesRepo := formationtemplateconstraintreferences.NewRepository(formationTemplateConstraintReferencesConverter) 1021 destinationRepo := destination.NewRepository(destinationConv) 1022 1023 webhookClient := webhookclient.NewClient(securedHTTPClient, mtlsHTTPClient, extSvcMtlsHTTPClient) 1024 webhookDataInputBuilder := databuilder.NewWebhookDataInputBuilder(appRepo, appTemplateRepo, runtimeRepo, runtimeContextRepo, labelRepo) 1025 1026 uidSvc := uid.NewService() 1027 labelDefinitionSvc := labeldef.NewService(labelDefinitionRepo, labelRepo, asaRepo, tenantRepo, uidSvc) 1028 asaSvc := scenarioassignment.NewService(asaRepo, labelDefinitionSvc) 1029 labelSvc := label.NewLabelService(labelRepo, labelDefinitionRepo, uidSvc) 1030 tenantSvc := tenant.NewServiceWithLabels(tenantRepo, uidSvc, labelRepo, labelSvc, tenantConverter) 1031 formationConstraintSvc := formationconstraint.NewService(formationConstraintRepo, formationTemplateConstraintReferencesRepo, uidSvc, formationConstraintConverter) 1032 destinationSvc := destination.NewService(mtlsHTTPClient, destinationCreatorConfig, transact, applicationRepo(), runtimeRepo, runtimeContextRepo, labelRepo, destinationRepo, tenantRepo, uidSvc) 1033 constraintEngine := operators.NewConstraintEngine(transact, formationConstraintSvc, tenantSvc, asaSvc, destinationSvc, formationRepo, labelRepo, labelSvc, appRepo, runtimeContextRepo, formationTemplateRepo, formationAssignmentRepo, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 1034 notificationsBuilder := formation.NewNotificationsBuilder(webhookConverter, constraintEngine, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 1035 notificationsGenerator := formation.NewNotificationsGenerator(appRepo, appTemplateRepo, runtimeRepo, runtimeContextRepo, labelRepo, webhookRepo, webhookDataInputBuilder, notificationsBuilder) 1036 notificationSvc := formation.NewNotificationService(tenantRepo, webhookClient, notificationsGenerator, constraintEngine, webhookConverter, formationTemplateRepo) 1037 faNotificationSvc := formationassignment.NewFormationAssignmentNotificationService(formationAssignmentRepo, webhookConverter, webhookRepo, tenantRepo, webhookDataInputBuilder, formationRepo, notificationsBuilder, runtimeContextRepo, labelSvc, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 1038 formationAssignmentStatusSvc := formationassignment.NewFormationAssignmentStatusService(formationAssignmentRepo, constraintEngine, faNotificationSvc) 1039 formationAssignmentSvc := formationassignment.NewService(formationAssignmentRepo, uid.NewService(), appRepo, runtimeRepo, runtimeContextRepo, notificationSvc, faNotificationSvc, labelSvc, formationRepo, formationAssignmentStatusSvc, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 1040 formationStatusSvc := formation.NewFormationStatusService(formationRepo, labelDefRepo, labelDefinitionSvc, notificationSvc, constraintEngine) 1041 formationSvc := formation.NewService(transact, appRepo, labelDefRepo, labelRepo, formationRepo, formationTemplateRepo, labelSvc, uidSvc, labelDefinitionSvc, asaRepo, asaSvc, tenantSvc, runtimeRepo, runtimeContextRepo, formationAssignmentSvc, faNotificationSvc, notificationSvc, constraintEngine, webhookRepo, formationStatusSvc, cfg.Features.RuntimeTypeLabelKey, cfg.Features.ApplicationTypeLabelKey) 1042 1043 fmHandler := formationmapping.NewFormationMappingHandler(transact, formationAssignmentSvc, formationAssignmentStatusSvc, faNotificationSvc, formationSvc, formationStatusSvc) 1044 1045 return fmHandler 1046 }