github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/bundle/resolver.go (about) 1 package bundle 2 3 import ( 4 "context" 5 6 "github.com/kyma-incubator/compass/components/director/pkg/resource" 7 8 dataloader "github.com/kyma-incubator/compass/components/director/internal/dataloaders" 9 10 "github.com/kyma-incubator/compass/components/director/internal/model" 11 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 12 "github.com/kyma-incubator/compass/components/director/pkg/str" 13 14 "github.com/kyma-incubator/compass/components/director/pkg/persistence" 15 16 "github.com/kyma-incubator/compass/components/director/pkg/log" 17 "github.com/pkg/errors" 18 19 "github.com/kyma-incubator/compass/components/director/pkg/graphql" 20 ) 21 22 // BundleService missing godoc 23 // 24 //go:generate mockery --name=BundleService --output=automock --outpkg=automock --case=underscore --disable-version-string 25 type BundleService interface { 26 Create(ctx context.Context, resourceType resource.Type, resourceID string, in model.BundleCreateInput) (string, error) 27 Update(ctx context.Context, resourceType resource.Type, id string, in model.BundleUpdateInput) error 28 Delete(ctx context.Context, resourceType resource.Type, id string) error 29 Get(ctx context.Context, id string) (*model.Bundle, error) 30 } 31 32 // BundleConverter missing godoc 33 // 34 //go:generate mockery --name=BundleConverter --output=automock --outpkg=automock --case=underscore --disable-version-string 35 type BundleConverter interface { 36 ToGraphQL(in *model.Bundle) (*graphql.Bundle, error) 37 CreateInputFromGraphQL(in graphql.BundleCreateInput) (model.BundleCreateInput, error) 38 UpdateInputFromGraphQL(in graphql.BundleUpdateInput) (*model.BundleUpdateInput, error) 39 } 40 41 // BundleInstanceAuthService missing godoc 42 // 43 //go:generate mockery --name=BundleInstanceAuthService --output=automock --outpkg=automock --case=underscore --disable-version-string 44 type BundleInstanceAuthService interface { 45 GetForBundle(ctx context.Context, id string, bundleID string) (*model.BundleInstanceAuth, error) 46 List(ctx context.Context, id string) ([]*model.BundleInstanceAuth, error) 47 } 48 49 // BundleInstanceAuthConverter missing godoc 50 // 51 //go:generate mockery --name=BundleInstanceAuthConverter --output=automock --outpkg=automock --case=underscore --disable-version-string 52 type BundleInstanceAuthConverter interface { 53 ToGraphQL(in *model.BundleInstanceAuth) (*graphql.BundleInstanceAuth, error) 54 MultipleToGraphQL(in []*model.BundleInstanceAuth) ([]*graphql.BundleInstanceAuth, error) 55 } 56 57 // APIService missing godoc 58 // 59 //go:generate mockery --name=APIService --output=automock --outpkg=automock --case=underscore --disable-version-string 60 type APIService interface { 61 ListByBundleIDs(ctx context.Context, bundleIDs []string, pageSize int, cursor string) ([]*model.APIDefinitionPage, error) 62 GetForBundle(ctx context.Context, id string, bundleID string) (*model.APIDefinition, error) 63 CreateInBundle(ctx context.Context, resourceType resource.Type, resourceID string, bundleID string, in model.APIDefinitionInput, spec *model.SpecInput) (string, error) 64 DeleteAllByBundleID(ctx context.Context, bundleID string) error 65 } 66 67 // APIConverter missing godoc 68 // 69 //go:generate mockery --name=APIConverter --output=automock --outpkg=automock --case=underscore --disable-version-string 70 type APIConverter interface { 71 ToGraphQL(in *model.APIDefinition, spec *model.Spec, bundleRef *model.BundleReference) (*graphql.APIDefinition, error) 72 MultipleToGraphQL(in []*model.APIDefinition, specs []*model.Spec, bundleRefs []*model.BundleReference) ([]*graphql.APIDefinition, error) 73 MultipleInputFromGraphQL(in []*graphql.APIDefinitionInput) ([]*model.APIDefinitionInput, []*model.SpecInput, error) 74 } 75 76 // EventService missing godoc 77 // 78 //go:generate mockery --name=EventService --output=automock --outpkg=automock --case=underscore --disable-version-string 79 type EventService interface { 80 ListByBundleIDs(ctx context.Context, bundleIDs []string, pageSize int, cursor string) ([]*model.EventDefinitionPage, error) 81 GetForBundle(ctx context.Context, id string, bundleID string) (*model.EventDefinition, error) 82 CreateInBundle(ctx context.Context, resourceType resource.Type, resourceID string, bundleID string, in model.EventDefinitionInput, spec *model.SpecInput) (string, error) 83 DeleteAllByBundleID(ctx context.Context, bundleID string) error 84 } 85 86 // EventConverter missing godoc 87 // 88 //go:generate mockery --name=EventConverter --output=automock --outpkg=automock --case=underscore --disable-version-string 89 type EventConverter interface { 90 ToGraphQL(in *model.EventDefinition, spec *model.Spec, bundleReference *model.BundleReference) (*graphql.EventDefinition, error) 91 MultipleToGraphQL(in []*model.EventDefinition, specs []*model.Spec, bundleRefs []*model.BundleReference) ([]*graphql.EventDefinition, error) 92 MultipleInputFromGraphQL(in []*graphql.EventDefinitionInput) ([]*model.EventDefinitionInput, []*model.SpecInput, error) 93 } 94 95 // DocumentService missing godoc 96 // 97 //go:generate mockery --name=DocumentService --output=automock --outpkg=automock --case=underscore --disable-version-string 98 type DocumentService interface { 99 GetForBundle(ctx context.Context, id string, bundleID string) (*model.Document, error) 100 CreateInBundle(ctx context.Context, resourceType resource.Type, resourceID string, bundleID string, in model.DocumentInput) (string, error) 101 ListByBundleIDs(ctx context.Context, bundleIDs []string, pageSize int, cursor string) ([]*model.DocumentPage, error) 102 } 103 104 // DocumentConverter missing godoc 105 // 106 //go:generate mockery --name=DocumentConverter --output=automock --outpkg=automock --case=underscore --disable-version-string 107 type DocumentConverter interface { 108 ToGraphQL(in *model.Document) *graphql.Document 109 MultipleToGraphQL(in []*model.Document) []*graphql.Document 110 MultipleInputFromGraphQL(in []*graphql.DocumentInput) ([]*model.DocumentInput, error) 111 } 112 113 // SpecService missing godoc 114 // 115 //go:generate mockery --name=SpecService --output=automock --outpkg=automock --case=underscore --disable-version-string 116 type SpecService interface { 117 GetByReferenceObjectID(ctx context.Context, resourceType resource.Type, objectType model.SpecReferenceObjectType, objectID string) (*model.Spec, error) 118 ListByReferenceObjectIDs(ctx context.Context, objectType model.SpecReferenceObjectType, objectIDs []string) ([]*model.Spec, error) 119 } 120 121 // BundleReferenceService missing godoc 122 // 123 //go:generate mockery --name=BundleReferenceService --output=automock --outpkg=automock --case=underscore --disable-version-string 124 type BundleReferenceService interface { 125 GetForBundle(ctx context.Context, objectType model.BundleReferenceObjectType, objectID, bundleID *string) (*model.BundleReference, error) 126 ListByBundleIDs(ctx context.Context, objectType model.BundleReferenceObjectType, bundleIDs []string, pageSize int, cursor string) ([]*model.BundleReference, map[string]int, error) 127 } 128 129 // ApplicationService is responsible for the service-layer Application operations. 130 // 131 //go:generate mockery --name=ApplicationService --output=automock --outpkg=automock --case=underscore --disable-version-string 132 type ApplicationService interface { 133 UpdateBaseURL(ctx context.Context, appID, targetURL string) error 134 } 135 136 // Resolver missing godoc 137 type Resolver struct { 138 transact persistence.Transactioner 139 140 bundleSvc BundleService 141 bundleInstanceAuthSvc BundleInstanceAuthService 142 bundleReferenceSvc BundleReferenceService 143 apiSvc APIService 144 eventSvc EventService 145 documentSvc DocumentService 146 appSvc ApplicationService 147 148 bundleConverter BundleConverter 149 bundleInstanceAuthConverter BundleInstanceAuthConverter 150 apiConverter APIConverter 151 eventConverter EventConverter 152 documentConverter DocumentConverter 153 154 specService SpecService 155 } 156 157 // NewResolver missing godoc 158 func NewResolver( 159 transact persistence.Transactioner, 160 bundleSvc BundleService, 161 bundleInstanceAuthSvc BundleInstanceAuthService, 162 bundleReferenceSvc BundleReferenceService, 163 apiSvc APIService, 164 eventSvc EventService, 165 documentSvc DocumentService, 166 bundleConverter BundleConverter, 167 bundleInstanceAuthConverter BundleInstanceAuthConverter, 168 apiConv APIConverter, 169 eventConv EventConverter, 170 documentConv DocumentConverter, 171 specSerice SpecService, 172 appSvc ApplicationService) *Resolver { 173 return &Resolver{ 174 transact: transact, 175 bundleConverter: bundleConverter, 176 bundleSvc: bundleSvc, 177 bundleInstanceAuthSvc: bundleInstanceAuthSvc, 178 bundleReferenceSvc: bundleReferenceSvc, 179 apiSvc: apiSvc, 180 eventSvc: eventSvc, 181 documentSvc: documentSvc, 182 bundleInstanceAuthConverter: bundleInstanceAuthConverter, 183 apiConverter: apiConv, 184 eventConverter: eventConv, 185 documentConverter: documentConv, 186 specService: specSerice, 187 appSvc: appSvc, 188 } 189 } 190 191 // AddBundle missing godoc 192 func (r *Resolver) AddBundle(ctx context.Context, applicationID string, in graphql.BundleCreateInput) (*graphql.Bundle, error) { 193 tx, err := r.transact.Begin() 194 if err != nil { 195 return nil, err 196 } 197 defer r.transact.RollbackUnlessCommitted(ctx, tx) 198 199 log.C(ctx).Infof("Adding bundle to Application with id %s", applicationID) 200 201 ctx = persistence.SaveToContext(ctx, tx) 202 203 convertedIn, err := r.bundleConverter.CreateInputFromGraphQL(in) 204 if err != nil { 205 return nil, errors.Wrap(err, "while converting input from GraphQL") 206 } 207 208 id, err := r.bundleSvc.Create(ctx, resource.Application, applicationID, convertedIn) 209 if err != nil { 210 return nil, err 211 } 212 213 bndl, err := r.bundleSvc.Get(ctx, id) 214 if err != nil { 215 return nil, err 216 } 217 218 if len(in.APIDefinitions) > 0 { 219 if err = r.appSvc.UpdateBaseURL(ctx, *bndl.ApplicationID, in.APIDefinitions[0].TargetURL); err != nil { 220 return nil, errors.Wrapf(err, "while trying to update baseURL") 221 } 222 } 223 224 gqlBundle, err := r.bundleConverter.ToGraphQL(bndl) 225 if err != nil { 226 return nil, errors.Wrapf(err, "while converting Bundle with id %s to GraphQL", id) 227 } 228 229 err = tx.Commit() 230 if err != nil { 231 return nil, err 232 } 233 234 log.C(ctx).Infof("Bundle with id %s successfully added to Application with id %s", id, applicationID) 235 return gqlBundle, nil 236 } 237 238 // UpdateBundle missing godoc 239 func (r *Resolver) UpdateBundle(ctx context.Context, id string, in graphql.BundleUpdateInput) (*graphql.Bundle, error) { 240 tx, err := r.transact.Begin() 241 if err != nil { 242 return nil, err 243 } 244 defer r.transact.RollbackUnlessCommitted(ctx, tx) 245 246 log.C(ctx).Infof("Updating Bundle with id %s", id) 247 248 ctx = persistence.SaveToContext(ctx, tx) 249 250 convertedIn, err := r.bundleConverter.UpdateInputFromGraphQL(in) 251 if err != nil { 252 return nil, errors.Wrapf(err, "while converting converting GraphQL input to Bundle with id %s", id) 253 } 254 255 err = r.bundleSvc.Update(ctx, resource.Application, id, *convertedIn) 256 if err != nil { 257 return nil, err 258 } 259 260 bndl, err := r.bundleSvc.Get(ctx, id) 261 if err != nil { 262 return nil, err 263 } 264 265 gqlBndl, err := r.bundleConverter.ToGraphQL(bndl) 266 if err != nil { 267 return nil, errors.Wrapf(err, "while converting Bundle with id %s to GraphQL", id) 268 } 269 270 err = tx.Commit() 271 if err != nil { 272 return nil, err 273 } 274 275 log.C(ctx).Infof("Bundle with id %s successfully updated.", id) 276 return gqlBndl, nil 277 } 278 279 // DeleteBundle missing godoc 280 func (r *Resolver) DeleteBundle(ctx context.Context, id string) (*graphql.Bundle, error) { 281 tx, err := r.transact.Begin() 282 if err != nil { 283 return nil, err 284 } 285 defer r.transact.RollbackUnlessCommitted(ctx, tx) 286 287 log.C(ctx).Infof("Deleting Bundle with id %s", id) 288 289 ctx = persistence.SaveToContext(ctx, tx) 290 291 bndl, err := r.bundleSvc.Get(ctx, id) 292 if err != nil { 293 return nil, err 294 } 295 296 err = r.apiSvc.DeleteAllByBundleID(ctx, id) 297 if err != nil { 298 return nil, err 299 } 300 301 err = r.eventSvc.DeleteAllByBundleID(ctx, id) 302 if err != nil { 303 return nil, err 304 } 305 306 err = r.bundleSvc.Delete(ctx, resource.Application, id) 307 if err != nil { 308 return nil, err 309 } 310 311 deletedBndl, err := r.bundleConverter.ToGraphQL(bndl) 312 if err != nil { 313 return nil, errors.Wrapf(err, "while converting Bundle with id %s to GraphQL", id) 314 } 315 316 err = tx.Commit() 317 if err != nil { 318 return nil, err 319 } 320 321 log.C(ctx).Infof("Bundle with id %s successfully deleted.", id) 322 return deletedBndl, nil 323 } 324 325 // InstanceAuth missing godoc 326 func (r *Resolver) InstanceAuth(ctx context.Context, obj *graphql.Bundle, id string) (*graphql.BundleInstanceAuth, error) { 327 if obj == nil { 328 return nil, apperrors.NewInternalError("Bundle cannot be empty") 329 } 330 331 tx, err := r.transact.Begin() 332 if err != nil { 333 return nil, err 334 } 335 defer r.transact.RollbackUnlessCommitted(ctx, tx) 336 337 ctx = persistence.SaveToContext(ctx, tx) 338 339 bndl, err := r.bundleInstanceAuthSvc.GetForBundle(ctx, id, obj.ID) 340 if err != nil { 341 if apperrors.IsNotFoundError(err) { 342 return nil, tx.Commit() 343 } 344 return nil, err 345 } 346 347 gqlAuth, err := r.bundleInstanceAuthConverter.ToGraphQL(bndl) 348 if err != nil { 349 return nil, err 350 } 351 352 err = tx.Commit() 353 if err != nil { 354 return nil, err 355 } 356 357 return gqlAuth, nil 358 } 359 360 // InstanceAuths missing godoc 361 func (r *Resolver) InstanceAuths(ctx context.Context, obj *graphql.Bundle) ([]*graphql.BundleInstanceAuth, error) { 362 if obj == nil { 363 return nil, apperrors.NewInternalError("Bundle cannot be empty") 364 } 365 366 tx, err := r.transact.Begin() 367 if err != nil { 368 return nil, err 369 } 370 defer r.transact.RollbackUnlessCommitted(ctx, tx) 371 ctx = persistence.SaveToContext(ctx, tx) 372 373 bndlInstanceAuths, err := r.bundleInstanceAuthSvc.List(ctx, obj.ID) 374 if err != nil { 375 return nil, err 376 } 377 378 gqlAuths, err := r.bundleInstanceAuthConverter.MultipleToGraphQL(bndlInstanceAuths) 379 if err != nil { 380 return nil, err 381 } 382 383 err = tx.Commit() 384 if err != nil { 385 return nil, err 386 } 387 388 return gqlAuths, nil 389 } 390 391 // APIDefinition missing godoc 392 func (r *Resolver) APIDefinition(ctx context.Context, obj *graphql.Bundle, id string) (*graphql.APIDefinition, error) { 393 tx, err := r.transact.Begin() 394 if err != nil { 395 return nil, err 396 } 397 defer r.transact.RollbackUnlessCommitted(ctx, tx) 398 399 ctx = persistence.SaveToContext(ctx, tx) 400 401 api, err := r.apiSvc.GetForBundle(ctx, id, obj.ID) 402 if err != nil { 403 if apperrors.IsNotFoundError(err) { 404 return nil, tx.Commit() 405 } 406 return nil, err 407 } 408 409 spec, err := r.specService.GetByReferenceObjectID(ctx, resource.Application, model.APISpecReference, api.ID) 410 if err != nil { 411 return nil, errors.Wrapf(err, "while getting spec for APIDefinition with id %q", api.ID) 412 } 413 414 bndlRef, err := r.bundleReferenceSvc.GetForBundle(ctx, model.BundleAPIReference, &api.ID, nil) 415 if err != nil { 416 return nil, errors.Wrapf(err, "while getting bundle reference for APIDefinition with id %q", api.ID) 417 } 418 419 gqlAPI, err := r.apiConverter.ToGraphQL(api, spec, bndlRef) 420 if err != nil { 421 return nil, errors.Wrapf(err, "while converting APIDefinition with id %q to graphQL", api.ID) 422 } 423 424 err = tx.Commit() 425 if err != nil { 426 return nil, err 427 } 428 429 return gqlAPI, nil 430 } 431 432 // APIDefinitions missing godoc 433 func (r *Resolver) APIDefinitions(ctx context.Context, obj *graphql.Bundle, group *string, first *int, after *graphql.PageCursor) (*graphql.APIDefinitionPage, error) { 434 param := dataloader.ParamAPIDef{ID: obj.ID, Ctx: ctx, First: first, After: after} 435 return dataloader.APIDefFor(ctx).APIDefByID.Load(param) 436 } 437 438 // APIDefinitionsDataLoader missing godoc 439 func (r *Resolver) APIDefinitionsDataLoader(keys []dataloader.ParamAPIDef) ([]*graphql.APIDefinitionPage, []error) { 440 if len(keys) == 0 { 441 return nil, []error{apperrors.NewInternalError("No Bundles found")} 442 } 443 444 if keys[0].First == nil { 445 return nil, []error{apperrors.NewInvalidDataError("missing required parameter 'first'")} 446 } 447 448 ctx := keys[0].Ctx 449 first := keys[0].First 450 451 bundleIDs := make([]string, 0, len(keys)) 452 for _, key := range keys { 453 bundleIDs = append(bundleIDs, key.ID) 454 } 455 456 var cursor string 457 if keys[0].After != nil { 458 cursor = string(*keys[0].After) 459 } 460 461 tx, err := r.transact.Begin() 462 if err != nil { 463 return nil, []error{err} 464 } 465 defer r.transact.RollbackUnlessCommitted(ctx, tx) 466 467 ctx = persistence.SaveToContext(ctx, tx) 468 469 apiDefPages, err := r.apiSvc.ListByBundleIDs(ctx, bundleIDs, *first, cursor) 470 if err != nil { 471 return nil, []error{err} 472 } 473 474 var apiDefIDs []string 475 for _, page := range apiDefPages { 476 for _, apiDefinition := range page.Data { 477 apiDefIDs = append(apiDefIDs, apiDefinition.ID) 478 } 479 } 480 481 specs, err := r.specService.ListByReferenceObjectIDs(ctx, model.APISpecReference, apiDefIDs) 482 if err != nil { 483 return nil, []error{err} 484 } 485 486 references, _, err := r.bundleReferenceSvc.ListByBundleIDs(ctx, model.BundleAPIReference, bundleIDs, *first, cursor) 487 if err != nil { 488 return nil, []error{err} 489 } 490 491 refsByBundleID := map[string][]*model.BundleReference{} 492 for _, ref := range references { 493 refsByBundleID[*ref.BundleID] = append(refsByBundleID[*ref.BundleID], ref) 494 } 495 496 apiDefIDtoSpec := make(map[string]*model.Spec) 497 for _, spec := range specs { 498 apiDefIDtoSpec[spec.ObjectID] = spec 499 } 500 501 gqlAPIDefs := make([]*graphql.APIDefinitionPage, 0, len(apiDefPages)) 502 for i, apisPage := range apiDefPages { 503 apiSpecs := make([]*model.Spec, 0, len(apisPage.Data)) 504 apiBundleRefs := make([]*model.BundleReference, 0, len(apisPage.Data)) 505 for _, api := range apisPage.Data { 506 apiSpecs = append(apiSpecs, apiDefIDtoSpec[api.ID]) 507 br, err := getBundleReferenceForAPI(api.ID, refsByBundleID[bundleIDs[i]]) 508 if err != nil { 509 return nil, []error{err} 510 } 511 apiBundleRefs = append(apiBundleRefs, br) 512 } 513 514 gqlAPIs, err := r.apiConverter.MultipleToGraphQL(apisPage.Data, apiSpecs, apiBundleRefs) 515 if err != nil { 516 return nil, []error{errors.Wrapf(err, "while converting api definitions")} 517 } 518 519 gqlAPIDefs = append(gqlAPIDefs, &graphql.APIDefinitionPage{Data: gqlAPIs, TotalCount: apisPage.TotalCount, PageInfo: &graphql.PageInfo{ 520 StartCursor: graphql.PageCursor(apisPage.PageInfo.StartCursor), 521 EndCursor: graphql.PageCursor(apisPage.PageInfo.EndCursor), 522 HasNextPage: apisPage.PageInfo.HasNextPage, 523 }}) 524 } 525 526 err = tx.Commit() 527 if err != nil { 528 return nil, []error{err} 529 } 530 531 log.C(ctx).Infof("Successfully fetched api definitions for bundles %v", bundleIDs) 532 return gqlAPIDefs, nil 533 } 534 535 // EventDefinition missing godoc 536 func (r *Resolver) EventDefinition(ctx context.Context, obj *graphql.Bundle, id string) (*graphql.EventDefinition, error) { 537 tx, err := r.transact.Begin() 538 if err != nil { 539 return nil, err 540 } 541 defer r.transact.RollbackUnlessCommitted(ctx, tx) 542 543 ctx = persistence.SaveToContext(ctx, tx) 544 545 eventAPI, err := r.eventSvc.GetForBundle(ctx, id, obj.ID) 546 if err != nil { 547 if apperrors.IsNotFoundError(err) { 548 return nil, tx.Commit() 549 } 550 return nil, err 551 } 552 553 spec, err := r.specService.GetByReferenceObjectID(ctx, resource.Application, model.EventSpecReference, eventAPI.ID) 554 if err != nil { 555 return nil, errors.Wrapf(err, "while getting spec for EventDefinition with id %q", eventAPI.ID) 556 } 557 558 bndlRef, err := r.bundleReferenceSvc.GetForBundle(ctx, model.BundleEventReference, &eventAPI.ID, nil) 559 if err != nil { 560 return nil, errors.Wrapf(err, "while getting bundle reference for EventDefinition with id %q", eventAPI.ID) 561 } 562 563 gqlEvent, err := r.eventConverter.ToGraphQL(eventAPI, spec, bndlRef) 564 if err != nil { 565 return nil, errors.Wrapf(err, "while converting EventDefinition with id %q to graphQL", eventAPI.ID) 566 } 567 568 err = tx.Commit() 569 if err != nil { 570 return nil, err 571 } 572 573 return gqlEvent, nil 574 } 575 576 // EventDefinitions missing godoc 577 func (r *Resolver) EventDefinitions(ctx context.Context, obj *graphql.Bundle, group *string, first *int, after *graphql.PageCursor) (*graphql.EventDefinitionPage, error) { 578 param := dataloader.ParamEventDef{ID: obj.ID, Ctx: ctx, First: first, After: after} 579 return dataloader.EventDefFor(ctx).EventDefByID.Load(param) 580 } 581 582 // EventDefinitionsDataLoader missing godoc 583 func (r *Resolver) EventDefinitionsDataLoader(keys []dataloader.ParamEventDef) ([]*graphql.EventDefinitionPage, []error) { 584 if len(keys) == 0 { 585 return nil, []error{apperrors.NewInternalError("No Bundles found")} 586 } 587 588 if keys[0].First == nil { 589 return nil, []error{apperrors.NewInvalidDataError("missing required parameter 'first'")} 590 } 591 592 ctx := keys[0].Ctx 593 first := keys[0].First 594 595 bundleIDs := make([]string, 0, len(keys)) 596 for _, key := range keys { 597 bundleIDs = append(bundleIDs, key.ID) 598 } 599 600 var cursor string 601 if keys[0].After != nil { 602 cursor = string(*keys[0].After) 603 } 604 605 tx, err := r.transact.Begin() 606 if err != nil { 607 return nil, []error{err} 608 } 609 defer r.transact.RollbackUnlessCommitted(ctx, tx) 610 611 ctx = persistence.SaveToContext(ctx, tx) 612 613 eventAPIDefPages, err := r.eventSvc.ListByBundleIDs(ctx, bundleIDs, *first, cursor) 614 if err != nil { 615 return nil, []error{err} 616 } 617 618 var eventAPIDefIDs []string 619 for _, page := range eventAPIDefPages { 620 for _, eventAPIDefinition := range page.Data { 621 eventAPIDefIDs = append(eventAPIDefIDs, eventAPIDefinition.ID) 622 } 623 } 624 625 specs, err := r.specService.ListByReferenceObjectIDs(ctx, model.EventSpecReference, eventAPIDefIDs) 626 if err != nil { 627 return nil, []error{err} 628 } 629 630 references, _, err := r.bundleReferenceSvc.ListByBundleIDs(ctx, model.BundleEventReference, bundleIDs, *first, cursor) 631 if err != nil { 632 return nil, []error{err} 633 } 634 635 eventAPIDefIDtoSpec := make(map[string]*model.Spec) 636 for _, spec := range specs { 637 eventAPIDefIDtoSpec[spec.ObjectID] = spec 638 } 639 640 eventAPIDefIDtoRef := make(map[string]*model.BundleReference) 641 for _, reference := range references { 642 eventAPIDefIDtoRef[*reference.ObjectID] = reference 643 } 644 645 gqlEventDefs := make([]*graphql.EventDefinitionPage, 0, len(eventAPIDefPages)) 646 for _, eventPage := range eventAPIDefPages { 647 eventSpecs := make([]*model.Spec, 0, len(eventPage.Data)) 648 eventBundleRefs := make([]*model.BundleReference, 0, len(eventPage.Data)) 649 for _, event := range eventPage.Data { 650 eventSpecs = append(eventSpecs, eventAPIDefIDtoSpec[event.ID]) 651 eventBundleRefs = append(eventBundleRefs, eventAPIDefIDtoRef[event.ID]) 652 } 653 654 gqlEvents, err := r.eventConverter.MultipleToGraphQL(eventPage.Data, eventSpecs, eventBundleRefs) 655 if err != nil { 656 return nil, []error{errors.Wrapf(err, "while converting event definitions")} 657 } 658 659 gqlEventDefs = append(gqlEventDefs, &graphql.EventDefinitionPage{Data: gqlEvents, TotalCount: eventPage.TotalCount, PageInfo: &graphql.PageInfo{ 660 StartCursor: graphql.PageCursor(eventPage.PageInfo.StartCursor), 661 EndCursor: graphql.PageCursor(eventPage.PageInfo.EndCursor), 662 HasNextPage: eventPage.PageInfo.HasNextPage, 663 }}) 664 } 665 666 err = tx.Commit() 667 if err != nil { 668 return nil, []error{err} 669 } 670 671 log.C(ctx).Infof("Successfully fetched event definitions for bundles %v", bundleIDs) 672 return gqlEventDefs, nil 673 } 674 675 // Document missing godoc 676 func (r *Resolver) Document(ctx context.Context, obj *graphql.Bundle, id string) (*graphql.Document, error) { 677 tx, err := r.transact.Begin() 678 if err != nil { 679 return nil, err 680 } 681 defer r.transact.RollbackUnlessCommitted(ctx, tx) 682 683 ctx = persistence.SaveToContext(ctx, tx) 684 685 eventAPI, err := r.documentSvc.GetForBundle(ctx, id, obj.ID) 686 if err != nil { 687 if apperrors.IsNotFoundError(err) { 688 return nil, tx.Commit() 689 } 690 return nil, err 691 } 692 693 err = tx.Commit() 694 if err != nil { 695 return nil, err 696 } 697 698 return r.documentConverter.ToGraphQL(eventAPI), nil 699 } 700 701 // Documents missing godoc 702 func (r *Resolver) Documents(ctx context.Context, obj *graphql.Bundle, first *int, after *graphql.PageCursor) (*graphql.DocumentPage, error) { 703 param := dataloader.ParamDocument{ID: obj.ID, Ctx: ctx, First: first, After: after} 704 return dataloader.DocumentFor(ctx).DocumentByID.Load(param) 705 } 706 707 // DocumentsDataLoader missing godoc 708 func (r *Resolver) DocumentsDataLoader(keys []dataloader.ParamDocument) ([]*graphql.DocumentPage, []error) { 709 if len(keys) == 0 { 710 return nil, []error{apperrors.NewInternalError("No Bundles found")} 711 } 712 713 if keys[0].First == nil { 714 return nil, []error{apperrors.NewInvalidDataError("missing required parameter 'first'")} 715 } 716 717 ctx := keys[0].Ctx 718 first := keys[0].First 719 720 bundleIDs := make([]string, 0, len(keys)) 721 for _, key := range keys { 722 bundleIDs = append(bundleIDs, key.ID) 723 } 724 725 var cursor string 726 if keys[0].After != nil { 727 cursor = string(*keys[0].After) 728 } 729 730 tx, err := r.transact.Begin() 731 if err != nil { 732 return nil, []error{err} 733 } 734 defer r.transact.RollbackUnlessCommitted(ctx, tx) 735 736 ctx = persistence.SaveToContext(ctx, tx) 737 738 documentPages, err := r.documentSvc.ListByBundleIDs(ctx, bundleIDs, *first, cursor) 739 if err != nil { 740 return nil, []error{err} 741 } 742 743 err = tx.Commit() 744 if err != nil { 745 return nil, []error{err} 746 } 747 748 gqlDocumentPages := make([]*graphql.DocumentPage, 0, len(documentPages)) 749 for _, page := range documentPages { 750 gqlDocuments := r.documentConverter.MultipleToGraphQL(page.Data) 751 752 gqlDocumentPages = append(gqlDocumentPages, &graphql.DocumentPage{ 753 Data: gqlDocuments, 754 TotalCount: page.TotalCount, 755 PageInfo: &graphql.PageInfo{ 756 StartCursor: graphql.PageCursor(page.PageInfo.StartCursor), 757 EndCursor: graphql.PageCursor(page.PageInfo.EndCursor), 758 HasNextPage: page.PageInfo.HasNextPage, 759 }, 760 }) 761 } 762 763 return gqlDocumentPages, nil 764 } 765 766 func getBundleReferenceForAPI(apiID string, bundleReferences []*model.BundleReference) (*model.BundleReference, error) { 767 for _, br := range bundleReferences { 768 if str.PtrStrToStr(br.ObjectID) == apiID { 769 return br, nil 770 } 771 } 772 return nil, errors.Errorf("could not find BundleReference for API with id %s", apiID) 773 }