emissary/internal/agent/controller/app/app_repository.go

129 lines
2.7 KiB
Go

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{}