github.com/liamawhite/cli-with-i18n@v6.32.1-0.20171122084555-dede0a5c3448+incompatible/cf/actors/planbuilder/plan_builder.go (about) 1 package planbuilder 2 3 import ( 4 "github.com/liamawhite/cli-with-i18n/cf/api" 5 "github.com/liamawhite/cli-with-i18n/cf/api/organizations" 6 "github.com/liamawhite/cli-with-i18n/cf/models" 7 ) 8 9 //go:generate counterfeiter . PlanBuilder 10 11 type PlanBuilder interface { 12 AttachOrgsToPlans([]models.ServicePlanFields) ([]models.ServicePlanFields, error) 13 AttachOrgToPlans([]models.ServicePlanFields, string) ([]models.ServicePlanFields, error) 14 GetPlansForServiceForOrg(string, string) ([]models.ServicePlanFields, error) 15 GetPlansForServiceWithOrgs(string) ([]models.ServicePlanFields, error) 16 GetPlansForManyServicesWithOrgs([]string) ([]models.ServicePlanFields, error) 17 GetPlansForService(string) ([]models.ServicePlanFields, error) 18 GetPlansVisibleToOrg(string) ([]models.ServicePlanFields, error) 19 } 20 21 var ( 22 OrgToPlansVisibilityMap *map[string][]string 23 PlanToOrgsVisibilityMap *map[string][]string 24 ) 25 26 type Builder struct { 27 servicePlanRepo api.ServicePlanRepository 28 servicePlanVisibilityRepo api.ServicePlanVisibilityRepository 29 orgRepo organizations.OrganizationRepository 30 } 31 32 func NewBuilder(plan api.ServicePlanRepository, vis api.ServicePlanVisibilityRepository, org organizations.OrganizationRepository) Builder { 33 return Builder{ 34 servicePlanRepo: plan, 35 servicePlanVisibilityRepo: vis, 36 orgRepo: org, 37 } 38 } 39 40 func (builder Builder) AttachOrgToPlans(plans []models.ServicePlanFields, orgName string) ([]models.ServicePlanFields, error) { 41 visMap, err := builder.buildPlanToOrgVisibilityMap(orgName) 42 if err != nil { 43 return nil, err 44 } 45 for planIndex := range plans { 46 plan := &plans[planIndex] 47 plan.OrgNames = visMap[plan.GUID] 48 } 49 50 return plans, nil 51 } 52 53 func (builder Builder) AttachOrgsToPlans(plans []models.ServicePlanFields) ([]models.ServicePlanFields, error) { 54 visMap, err := builder.buildPlanToOrgsVisibilityMap() 55 if err != nil { 56 return nil, err 57 } 58 for planIndex := range plans { 59 plan := &plans[planIndex] 60 plan.OrgNames = visMap[plan.GUID] 61 } 62 63 return plans, nil 64 } 65 66 func (builder Builder) GetPlansForServiceForOrg(serviceGUID string, orgName string) ([]models.ServicePlanFields, error) { 67 plans, err := builder.servicePlanRepo.Search(map[string]string{"service_guid": serviceGUID}) 68 if err != nil { 69 return nil, err 70 } 71 72 plans, err = builder.AttachOrgToPlans(plans, orgName) 73 if err != nil { 74 return nil, err 75 } 76 return plans, nil 77 } 78 79 func (builder Builder) GetPlansForService(serviceGUID string) ([]models.ServicePlanFields, error) { 80 plans, err := builder.servicePlanRepo.Search(map[string]string{"service_guid": serviceGUID}) 81 if err != nil { 82 return nil, err 83 } 84 return plans, nil 85 } 86 87 func (builder Builder) GetPlansForServiceWithOrgs(serviceGUID string) ([]models.ServicePlanFields, error) { 88 plans, err := builder.GetPlansForService(serviceGUID) 89 if err != nil { 90 return nil, err 91 } 92 93 plans, err = builder.AttachOrgsToPlans(plans) 94 if err != nil { 95 return nil, err 96 } 97 return plans, nil 98 } 99 100 func (builder Builder) GetPlansForManyServicesWithOrgs(serviceGUIDs []string) ([]models.ServicePlanFields, error) { 101 plans, err := builder.servicePlanRepo.ListPlansFromManyServices(serviceGUIDs) 102 if err != nil { 103 return nil, err 104 } 105 106 plans, err = builder.AttachOrgsToPlans(plans) 107 if err != nil { 108 return nil, err 109 } 110 return plans, nil 111 } 112 113 func (builder Builder) GetPlansVisibleToOrg(orgName string) ([]models.ServicePlanFields, error) { 114 var plansToReturn []models.ServicePlanFields 115 allPlans, err := builder.servicePlanRepo.Search(nil) 116 117 planToOrgsVisMap, err := builder.buildPlanToOrgsVisibilityMap() 118 if err != nil { 119 return nil, err 120 } 121 122 orgToPlansVisMap := builder.buildOrgToPlansVisibilityMap(planToOrgsVisMap) 123 124 filterOrgPlans := orgToPlansVisMap[orgName] 125 126 for _, plan := range allPlans { 127 if builder.containsGUID(filterOrgPlans, plan.GUID) { 128 plan.OrgNames = planToOrgsVisMap[plan.GUID] 129 plansToReturn = append(plansToReturn, plan) 130 } else if plan.Public { 131 plansToReturn = append(plansToReturn, plan) 132 } 133 } 134 135 return plansToReturn, nil 136 } 137 138 func (builder Builder) containsGUID(guidSlice []string, guid string) bool { 139 for _, g := range guidSlice { 140 if g == guid { 141 return true 142 } 143 } 144 return false 145 } 146 147 func (builder Builder) buildPlanToOrgVisibilityMap(orgName string) (map[string][]string, error) { 148 // Since this map doesn't ever change, we memoize it for performance 149 orgLookup := make(map[string]string) 150 151 org, err := builder.orgRepo.FindByName(orgName) 152 if err != nil { 153 return nil, err 154 } 155 orgLookup[org.GUID] = org.Name 156 157 visibilities, err := builder.servicePlanVisibilityRepo.List() 158 if err != nil { 159 return nil, err 160 } 161 162 visMap := make(map[string][]string) 163 for _, vis := range visibilities { 164 if _, exists := orgLookup[vis.OrganizationGUID]; exists { 165 visMap[vis.ServicePlanGUID] = append(visMap[vis.ServicePlanGUID], orgLookup[vis.OrganizationGUID]) 166 } 167 } 168 169 return visMap, nil 170 } 171 172 func (builder Builder) buildPlanToOrgsVisibilityMap() (map[string][]string, error) { 173 // Since this map doesn't ever change, we memoize it for performance 174 if PlanToOrgsVisibilityMap == nil { 175 orgLookup := make(map[string]string) 176 177 visibilities, err := builder.servicePlanVisibilityRepo.List() 178 if err != nil { 179 return nil, err 180 } 181 182 orgGUIDs := builder.getUniqueOrgGUIDsFromVisibilities(visibilities) 183 184 orgs, err := builder.orgRepo.GetManyOrgsByGUID(orgGUIDs) 185 if err != nil { 186 return nil, err 187 } 188 189 for _, org := range orgs { 190 orgLookup[org.GUID] = org.Name 191 } 192 193 visMap := make(map[string][]string) 194 for _, vis := range visibilities { 195 visMap[vis.ServicePlanGUID] = append(visMap[vis.ServicePlanGUID], orgLookup[vis.OrganizationGUID]) 196 } 197 198 PlanToOrgsVisibilityMap = &visMap 199 } 200 201 return *PlanToOrgsVisibilityMap, nil 202 } 203 204 func (builder Builder) getUniqueOrgGUIDsFromVisibilities(visibilities []models.ServicePlanVisibilityFields) (orgGUIDs []string) { 205 for _, visibility := range visibilities { 206 found := false 207 for _, orgGUID := range orgGUIDs { 208 if orgGUID == visibility.OrganizationGUID { 209 found = true 210 break 211 } 212 } 213 if !found { 214 orgGUIDs = append(orgGUIDs, visibility.OrganizationGUID) 215 } 216 } 217 return 218 } 219 220 func (builder Builder) buildOrgToPlansVisibilityMap(planToOrgsMap map[string][]string) map[string][]string { 221 if OrgToPlansVisibilityMap == nil { 222 visMap := make(map[string][]string) 223 for planGUID, orgNames := range planToOrgsMap { 224 for _, orgName := range orgNames { 225 visMap[orgName] = append(visMap[orgName], planGUID) 226 } 227 } 228 OrgToPlansVisibilityMap = &visMap 229 } 230 231 return *OrgToPlansVisibilityMap 232 }