From 20268551c24210bde02a64af0a1cc91b006afa05 Mon Sep 17 00:00:00 2001 From: henrytk Date: Fri, 9 Jun 2017 13:26:01 +0100 Subject: [PATCH] Units handling in the Catalog We had several options how to implement that: * one plan and user provided json to specify number of units: we don't like this option * multiple plans and we hardcode number of units based on plan name which means we have to change broker code every time the plan changes : nah... * fork brokerAPI and modify the Catalog struct and do PR upstream: it's hard to extend this in a generic way by using json.RawMessage. The name of the field has to be known and specified as json unmarshaller option. So we would have to specify `json:"units,omitempty"` json unmarshaler option which is very compose specific. There is a go lang issue opened to fix that: https://github.com/golang/go/issues/15314 * do not use upstream Catalog and implement our own struct. Not possible - we have to return the type specified in the brokerapi interface to implement it: https://github.com/pivotal-cf/brokerapi/blob/0d62e62ec041b8ff39c0e304f437b4eabb4175fa/service_broker.go#L10 * extend external Catalog struct to include units field - not possible. Same reason as above I had to implement the sixth option. Now we have a new struct that partially copies upstream catalog structure but holds only fields (IDs and Units ) that we care about. This together with upstream catalog is wrrapped into one struct and stored in main broker structure so all interface methods have access to it. There is also new catalog.Load method that replaces catalog.New. It has two unmarshalling passes to fill upstream catalog and our Units struct. --- catalog/catalog.go | 70 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 5 deletions(-) diff --git a/catalog/catalog.go b/catalog/catalog.go index c840c0d..12a1a0a 100644 --- a/catalog/catalog.go +++ b/catalog/catalog.go @@ -2,20 +2,80 @@ package catalog import ( "encoding/json" + "fmt" "io" + "io/ioutil" "github.com/pivotal-cf/brokerapi" ) +type ComposeCatalog struct { + Catalog Catalog + ComposeUnits ComposeUnits +} + +// Catalog is an upstream Catalog struct type Catalog struct { Services []brokerapi.Service `json:"services"` } -func New(catalog io.Reader) (*Catalog, error) { - cp := &Catalog{} - err := json.NewDecoder(catalog).Decode(cp) +type ComposeUnits struct { + Services []Service `json:"services"` +} + +type Service struct { + ID string `json:"id"` + Name string `json:"name"` + Plans []ServicePlan `json:"plans"` +} + +type ServicePlan struct { + ID string `json:"id"` + Metadata ServicePlanMetadata `json:"metadata,omitempty"` +} + +type ServicePlanMetadata struct { + Units int `json:"units,omitempty"` +} + +func (c *ComposeCatalog) GetService(id string) (*Service, error) { + for _, service := range c.ComposeUnits.Services { + if service.ID == id { + return &service, nil + } + } + + return nil, fmt.Errorf("service: not found") +} + +func (s *Service) GetPlan(id string) (*ServicePlan, error) { + for _, plan := range s.Plans { + if plan.ID == id { + return &plan, nil + } + } + + return nil, fmt.Errorf("plan: not found") +} + +func (c *ComposeCatalog) Load(catalog io.Reader) error { + buf, err := ioutil.ReadAll(catalog) if err != nil { - return nil, err + return err } - return cp, nil + + err = json.Unmarshal(buf, &c.Catalog) + if err != nil { + return err + } + + err = json.Unmarshal(buf, &c.ComposeUnits) + if err != nil { + return err + } + + return nil +} +func (c *ComposeCatalog) Validate() error { + return nil }