Skip to content
This repository has been archived by the owner on Sep 17, 2018. It is now read-only.

Commit

Permalink
Units handling in the Catalog
Browse files Browse the repository at this point in the history
We had several options how to implement that:

* one plan and user provided json to specify number of units: we dont
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 speciefied 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:
golang/go#15314

* do not use upstream Catalog and implement our own struct. Not posible
- we have to return the type specified in the brokerapi interface to
implemet 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
partialy copies upstream catalog structure but holds only fields (IDs
and Units ) that we care about. This together with upstream catalog is
wrrapped into on 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.
  • Loading branch information
Piotr Komborski committed May 26, 2017
1 parent a9b38b9 commit b5d9900
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 26 deletions.
50 changes: 40 additions & 10 deletions broker/broker.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,62 @@ import (
)

type Broker struct {
Compose *composeapi.Client
Config *config.Config
Catalog *catalog.Catalog
Logger *lager.Logger
Compose *composeapi.Client
Config *config.Config
ComposeCatalog *catalog.ComposeCatalog
Logger *lager.Logger
}

func New(compose *composeapi.Client, config *config.Config, catalog *catalog.Catalog, logger *lager.Logger) (*Broker, error) {
func New(compose *composeapi.Client, config *config.Config, catalog *catalog.ComposeCatalog, logger *lager.Logger) (*Broker, error) {
if compose == nil {
return nil, fmt.Errorf("broker: composer should not be nil")
}

broker := Broker{
Compose: compose,
Config: config,
Catalog: catalog,
Logger: logger,
Compose: compose,
Config: config,
ComposeCatalog: catalog,
Logger: logger,
}

return &broker, nil
}

func (b *Broker) Services(context context.Context) []brokerapi.Service {
return b.Catalog.Services
return b.ComposeCatalog.Catalog.Services
}

func (b *Broker) Provision(context context.Context, instanceID string, details brokerapi.ProvisionDetails, asyncAllowed bool) (brokerapi.ProvisionedServiceSpec, error) {
/*
datacenter := composeapi.Datacenter.Provider + composeapi.Datacenter.Region
params := composeapi.DeploymentParams{
Name: instanceID,
AccountID: composeapi.Account.ID,
Datacenter: datacenter,
DatabaseType: catalog.Catalog.Services.[]
}
type ProvisionDetails struct {
ServiceID string `json:"service_id"`
PlanID string `json:"plan_id"`
OrganizationGUID string `json:"organization_guid"`
SpaceGUID string `json:"space_guid"`
RawParameters json.RawMessage `json:"parameters,omitempty"`
}
type DeploymentParams struct {
Name string `json:"name"`
AccountID string `json:"account_id"`
ClusterID string `json:"cluster_id,omitempty"`
Datacenter string `json:"datacenter,omitempty"`
DatabaseType string `json:"type"`
Version string `json:"version,omitempty"`
Units int `json:"units,omitempty"`
SSL bool `json:"ssl,omitempty"`
WiredTiger bool `json:"wired_tiger,omitempty"`
}
b.Compose.CreateDeployment(params) */

return brokerapi.ProvisionedServiceSpec{}, fmt.Errorf("%s", "Can't provision an instance")
}

Expand Down
45 changes: 40 additions & 5 deletions catalog/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,54 @@ package catalog
import (
"encoding/json"
"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"`
Plans []ServicePlan `json:"plans"`
}

type ServicePlan struct {
ID string `json:"id"`
Metadata ServiceMetadata `json:"metadata,omitempty"`
}

type ServiceMetadata struct {
Units int `json:"units,omitempty"`
}

func (c *ComposeCatalog) Load(catalog io.Reader) error {
buf, err := ioutil.ReadAll(catalog)
if err != nil {
return err
}

err = json.Unmarshal(buf, &c.Catalog)
if err != nil {
return nil, err
return err
}
return cp, nil

err = json.Unmarshal(buf, &c.ComposeUnits)
if err != nil {
return err
}

return nil
}
13 changes: 6 additions & 7 deletions examples/catalog.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"services":[
{
"id":"1",
"id":"36f8bf47-c9e7-46d9-880f-5dfc838d05cb",
"name":"mongo",
"description":"Compose MongoDB instance",
"requires":[],
Expand All @@ -19,17 +19,16 @@
},
"plans":[
{
"id":"1",
"name":"Mongo small",
"id":"fdfd4fc1-ce69-451c-a436-c2e2795b9abe",
"name":"small",
"description":"Small plan",
"metadata":{
"bullets":[
"1 unit"
],
"bullets":[],
"units": 1,
"costs":[
{
"amount":{
"GBP":1
"USD":35
},
"unit":"MONTHLY"
}
Expand Down
5 changes: 3 additions & 2 deletions integration_tests/broker_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,11 @@ func TestSuite(t *testing.T) {
]
}
`)
newCatalog, err := catalog.New(catalogData)

newCatalog := catalog.ComposeCatalog{}
err = newCatalog.Load(catalogData)
Expect(err).ToNot(HaveOccurred())

broker := broker.New(config, newCatalog, &logger)
compose, err := composeapi.NewClient(config.APIToken)
Expect(err).NotTo(HaveOccurred())
broker, err := broker.New(compose, config, &newCatalog, &logger)
Expand Down
6 changes: 4 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"

"code.cloudfoundry.org/lager"

"github.com/alphagov/paas-compose-broker/broker"
"github.com/alphagov/paas-compose-broker/catalog"
"github.com/alphagov/paas-compose-broker/config"
Expand Down Expand Up @@ -35,7 +36,8 @@ func main() {
logger.Error("opening catalog file", err)
os.Exit(1)
}
newCatalog, err := catalog.New(catalogFile)
newCatalog := catalog.ComposeCatalog{}
err = newCatalog.Load(catalogFile)
if err != nil {
logger.Error("loading catalog", err)
os.Exit(1)
Expand All @@ -51,7 +53,7 @@ func main() {
os.Exit(1)
}

broker, err := broker.New(compose, config, newCatalog, &logger)
broker, err := broker.New(compose, config, &newCatalog, &logger)
if err != nil {
logger.Error("could not initialise broker", err)
os.Exit(1)
Expand Down

0 comments on commit b5d9900

Please sign in to comment.