github.com/rakutentech/cli@v6.12.5-0.20151006231303-24468b65536e+incompatible/cf/actors/plan_builder/plan_builder.go (about)

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