1package client 2 3import ( 4 "fmt" 5 6 "github.com/splitio/go-split-commons/v3/dtos" 7 "github.com/splitio/go-split-commons/v3/storage" 8 "github.com/splitio/go-toolkit/v4/logging" 9) 10 11// SplitManager provides information of the currently stored splits 12type SplitManager struct { 13 splitStorage storage.SplitStorageConsumer 14 validator inputValidation 15 logger logging.LoggerInterface 16 factory *SplitFactory 17 initTelemetry storage.TelemetryConfigProducer 18} 19 20// SplitView is a partial representation of a currently stored split 21type SplitView struct { 22 Name string `json:"name"` 23 TrafficType string `json:"trafficType"` 24 Killed bool `json:"killed"` 25 Treatments []string `json:"treatments"` 26 ChangeNumber int64 `json:"changeNumber"` 27 Configs map[string]string `json:"configs"` 28} 29 30func newSplitView(splitDto *dtos.SplitDTO) *SplitView { 31 treatments := make([]string, 0) 32 for _, condition := range splitDto.Conditions { 33 for _, partition := range condition.Partitions { 34 treatments = append(treatments, partition.Treatment) 35 } 36 } 37 return &SplitView{ 38 ChangeNumber: splitDto.ChangeNumber, 39 Killed: splitDto.Killed, 40 Name: splitDto.Name, 41 TrafficType: splitDto.TrafficTypeName, 42 Treatments: treatments, 43 Configs: splitDto.Configurations, 44 } 45} 46 47// SplitNames returns a list with the name of all the currently stored splits 48func (m *SplitManager) SplitNames() []string { 49 if m.isDestroyed() { 50 m.logger.Error("Client has already been destroyed - no calls possible") 51 return []string{} 52 } 53 54 if !m.isReady() { 55 m.logger.Warning("SplitNames: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method") 56 m.initTelemetry.RecordNonReadyUsage() 57 } 58 59 return m.splitStorage.SplitNames() 60} 61 62// Splits returns a list of a partial view of every currently stored split 63func (m *SplitManager) Splits() []SplitView { 64 if m.isDestroyed() { 65 m.logger.Error("Client has already been destroyed - no calls possible") 66 return []SplitView{} 67 } 68 69 if !m.isReady() { 70 m.logger.Warning("Splits: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method") 71 m.initTelemetry.RecordNonReadyUsage() 72 } 73 74 splitViews := make([]SplitView, 0) 75 splits := m.splitStorage.All() 76 for _, split := range splits { 77 splitViews = append(splitViews, *newSplitView(&split)) 78 } 79 return splitViews 80} 81 82// Split returns a partial view of a particular split 83func (m *SplitManager) Split(feature string) *SplitView { 84 if m.isDestroyed() { 85 m.logger.Error("Client has already been destroyed - no calls possible") 86 return nil 87 } 88 89 if !m.isReady() { 90 m.logger.Warning("Split: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method") 91 m.initTelemetry.RecordNonReadyUsage() 92 } 93 94 err := m.validator.ValidateManagerInputs(feature) 95 if err != nil { 96 m.logger.Error(err.Error()) 97 return nil 98 } 99 100 split := m.splitStorage.Split(feature) 101 if split != nil { 102 return newSplitView(split) 103 } 104 m.logger.Error(fmt.Sprintf("Split: you passed %s that does not exist in this environment, please double check what Splits exist in the web console.", feature)) 105 return nil 106} 107 108// BlockUntilReady Calls BlockUntilReady on factory to block manager on readiness 109func (m *SplitManager) BlockUntilReady(timer int) error { 110 return m.factory.BlockUntilReady(timer) 111} 112 113func (m *SplitManager) isDestroyed() bool { 114 return m.factory.IsDestroyed() 115} 116 117func (m *SplitManager) isReady() bool { 118 return m.factory.IsReady() 119} 120