package app import ( "context" "sync" "forge.cadoles.com/arcad/edge/pkg/app" "forge.cadoles.com/arcad/edge/pkg/bundle" appModule "forge.cadoles.com/arcad/edge/pkg/module/app" "github.com/pkg/errors" "gitlab.com/wpetit/goweb/logger" ) type GetURLFunc func(context.Context, *app.Manifest) (string, error) type AppRepository struct { getURL GetURLFunc bundles []string mutex sync.RWMutex } // Get implements app.Repository func (r *AppRepository) Get(ctx context.Context, id app.ID) (*app.Manifest, error) { r.mutex.RLock() defer r.mutex.RUnlock() manifest, err := r.findManifest(ctx, id) if err != nil { return nil, errors.WithStack(err) } return manifest, nil } // GetURL implements app.Repository func (r *AppRepository) GetURL(ctx context.Context, id app.ID) (string, error) { r.mutex.RLock() defer r.mutex.RUnlock() manifest, err := r.findManifest(ctx, id) if err != nil { return "", errors.WithStack(err) } url, err := r.getURL(ctx, manifest) if err != nil { return "", errors.WithStack(err) } return url, nil } // List implements app.Repository func (r *AppRepository) List(ctx context.Context) ([]*app.Manifest, error) { r.mutex.RLock() defer r.mutex.RUnlock() manifests := make([]*app.Manifest, 0) for _, path := range r.bundles { bundleCtx := logger.With(ctx, logger.F("path", path)) bundle, err := bundle.FromPath(path) if err != nil { logger.Error(bundleCtx, "could not load bundle", logger.E(errors.WithStack(err))) continue } manifest, err := app.LoadManifest(bundle) if err != nil { logger.Error(bundleCtx, "could not load manifest", logger.E(errors.WithStack(err))) continue } manifests = append(manifests, manifest) } return manifests, nil } func (r *AppRepository) Update(getURL GetURLFunc, bundles []string) { r.mutex.Lock() defer r.mutex.Unlock() r.getURL = getURL r.bundles = bundles } func (r *AppRepository) findManifest(ctx context.Context, id app.ID) (*app.Manifest, error) { for _, path := range r.bundles { bundleCtx := logger.With(ctx, logger.F("path", path)) bundle, err := bundle.FromPath(path) if err != nil { logger.Error(bundleCtx, "could not load bundle", logger.E(errors.WithStack(err))) continue } manifest, err := app.LoadManifest(bundle) if err != nil { logger.Error(bundleCtx, "could not load manifest", logger.E(errors.WithStack(err))) continue } if manifest.ID != id { continue } return manifest, nil } return nil, errors.WithStack(appModule.ErrNotFound) } func NewAppRepository() *AppRepository { return &AppRepository{ getURL: func(ctx context.Context, m *app.Manifest) (string, error) { return "", errors.New("unavailable") }, bundles: []string{}, } } var _ appModule.Repository = &AppRepository{}