storage.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package pricing
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "sync"
  8. "github.com/opencost/opencost/core/pkg/storage"
  9. )
  10. type StoragePricingStore struct {
  11. store storage.Storage
  12. path string
  13. mu sync.RWMutex
  14. }
  15. func NewStoragePricingStore(ctx context.Context, store storage.Storage, path string) (*StoragePricingStore, error) {
  16. if store == nil {
  17. return nil, errors.New("nil storage")
  18. }
  19. if path == "" {
  20. return nil, errors.New("empty path")
  21. }
  22. sps := &StoragePricingStore{
  23. store: store,
  24. path: path,
  25. }
  26. exists, err := store.Exists(path)
  27. if err != nil {
  28. return nil, fmt.Errorf("checking pricing path %q: %w", path, err)
  29. }
  30. if !exists {
  31. if err := sps.SetPricingSet(ctx, &PricingSet{}); err != nil {
  32. return nil, fmt.Errorf("initializing empty pricing set at %q: %w", path, err)
  33. }
  34. }
  35. return sps, nil
  36. }
  37. func (sps *StoragePricingStore) GetPricingSet(ctx context.Context) (*PricingSet, error) {
  38. sps.mu.RLock()
  39. defer sps.mu.RUnlock()
  40. data, err := sps.store.Read(sps.path)
  41. if err != nil {
  42. return nil, fmt.Errorf("reading path '%s': %w", sps.path, err)
  43. }
  44. var pricing PricingSet
  45. err = json.Unmarshal(data, &pricing)
  46. if err != nil {
  47. return nil, fmt.Errorf("decoding pricing: %w", err)
  48. }
  49. return &pricing, nil
  50. }
  51. func (sps *StoragePricingStore) SetPricingSet(ctx context.Context, pricing *PricingSet) error {
  52. sps.mu.Lock()
  53. defer sps.mu.Unlock()
  54. if pricing == nil {
  55. return errors.New("nil pricing")
  56. }
  57. data, err := json.Marshal(pricing)
  58. if err != nil {
  59. return fmt.Errorf("encoding pricing: %w", err)
  60. }
  61. err = sps.store.Write(sps.path, data)
  62. if err != nil {
  63. return fmt.Errorf("writing pricing: %w", err)
  64. }
  65. return nil
  66. }