eventpath.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package pathing
  2. import (
  3. "fmt"
  4. "path"
  5. "time"
  6. )
  7. // 2006-01-02T15:04:05Z07:00
  8. // EventStorageTimeFormat is YYYYMMDDHHmmss
  9. const EventStorageTimeFormat = "20060102150405"
  10. // EventStoragePathFormatter is an implementation of the StoragePathFormatter interface for
  11. // a cluster separated storage path of the format:
  12. //
  13. // <root>/federated/<cluster>/<event>/<sub-paths...>/YYYYMMDDHHmmss
  14. type EventStoragePathFormatter struct {
  15. rootDir string
  16. clusterId string
  17. event string
  18. subPaths []string
  19. }
  20. // NewBingenStoragePathFormatter creates a StoragePathFormatter for a cluster separated storage path
  21. // with the given root directory, cluster id, pipeline, and resolution. To omit the resolution directory
  22. // structure, provide a `nil` resolution.
  23. func NewEventStoragePathFormatter(rootDir, clusterId, event string, subPaths ...string) (StoragePathFormatter[time.Time], error) {
  24. if clusterId == "" {
  25. return nil, fmt.Errorf("cluster id cannot be empty")
  26. }
  27. if event == "" {
  28. return nil, fmt.Errorf("event cannot be empty")
  29. }
  30. for _, subPath := range subPaths {
  31. if subPath == "" {
  32. return nil, fmt.Errorf("subpaths cannot be empty")
  33. }
  34. }
  35. return &EventStoragePathFormatter{
  36. rootDir: rootDir,
  37. clusterId: clusterId,
  38. event: event,
  39. subPaths: subPaths,
  40. }, nil
  41. }
  42. // RootDir returns the root directory of the storage path formatter.
  43. func (espf *EventStoragePathFormatter) RootDir() string {
  44. return espf.rootDir
  45. }
  46. // ToFullPath returns the full path to a file name within the storage directory using the format:
  47. //
  48. // <root>/federated/<cluster>/<event>/YYYYMMDDHHmm.json
  49. func (espf *EventStoragePathFormatter) ToFullPath(prefix string, timestamp time.Time, fileExt string) string {
  50. fileName := toEventFileName(prefix, timestamp, fileExt)
  51. return path.Join(
  52. espf.rootDir,
  53. espf.clusterId,
  54. espf.event,
  55. path.Join(espf.subPaths...),
  56. fileName,
  57. )
  58. }
  59. // toEventFileName formats the file name as <prefix>.<timestamp>. if a non-empty fileExt is provided,
  60. // then the file extension is appended to the file name.
  61. func toEventFileName(prefix string, timestamp time.Time, fileExt string) string {
  62. suffix := timestamp.Format(EventStorageTimeFormat)
  63. if fileExt != "" {
  64. suffix = fmt.Sprintf("%s.%s", suffix, fileExt)
  65. }
  66. if prefix == "" {
  67. return suffix
  68. }
  69. return fmt.Sprintf("%s.%s", prefix, suffix)
  70. }