Skip to content
This repository has been archived by the owner on May 6, 2022. It is now read-only.

Commit

Permalink
Catalog generation (#108)
Browse files Browse the repository at this point in the history
* Working on catalog generation.

* working pop.

* Working generator.

* Tests are more for demo.
  • Loading branch information
n3wscott authored and pmorie committed Mar 23, 2018
1 parent c57d7cd commit 87e2f17
Show file tree
Hide file tree
Showing 9 changed files with 694 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea/
158 changes: 158 additions & 0 deletions v2/generator/catalog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package generator

import (
"fmt"

"math/rand"

"sort"

"github.com/golang/glog"
"github.com/pmorie/go-open-service-broker-client/v2"
)

// GetCatalog will produce a valid GetCatalog response based on the generator settings.
func (g *Generator) GetCatalog() (*v2.CatalogResponse, error) {
if len(g.Services) == 0 {
return nil, fmt.Errorf("no services defined")
}

services := make([]v2.Service, len(g.Services))

for s, gs := range g.Services {
services[s].Plans = make([]v2.Plan, len(gs.Plans))
service := &services[s]
service.Name = g.ClassPool[s+g.ClassPoolOffset]
service.Description = g.description(s)
service.ID = IDFrom(g.ClassPool[s])
service.DashboardClient = g.dashboardClient(service.Name)

for property, count := range gs.FromPool {
switch property {
case Tags:
service.Tags = g.tagNames(s, count)
case Metadata:
service.Metadata = g.metaNames(s, count)
case Bindable:
service.Bindable = count > 0
case BindingsRetrievable:
service.BindingsRetrievable = count > 0
case Requires:
service.Requires = g.requiresNames(s, count)
}
}

planNames := g.planNames(s, len(service.Plans))
for p, gp := range gs.Plans {
plan := &service.Plans[p]
plan.Name = planNames[p]
plan.Description = g.description(1000 + 1000*s*p)
plan.ID = IDFrom(planNames[p])

for property, count := range gp.FromPool {
switch property {
case Metadata:
plan.Metadata = g.metaNames(1000+1000*s*p, count)
case Free:
isFree := count > 0
plan.Free = &isFree
}
}
}
}

return &v2.CatalogResponse{
Services: services,
}, nil
}

func getSliceWithoutDuplicates(count int, seed int64, list []string) []string {

if len(list) < count {
glog.Error("not enough items in list")
return []string{""}
}

rand.Seed(seed)

set := map[string]int32{}

// Get strings from list without duplicates
for len(set) < count {
x := rand.Int31n(int32(len(list)))
set[list[x]] = x
}

keys := []string(nil)
for k := range set {
keys = append(keys, k)
}
sort.Strings(keys)
return keys
}

func (g *Generator) description(seed int) string {
return getSliceWithoutDuplicates(1, int64(seed), g.DescriptionPool)[0]
}

func (g *Generator) planNames(seed, count int) []string {
return getSliceWithoutDuplicates(count, int64(seed), g.PlanPool)
}

func (g *Generator) tagNames(seed, count int) []string {
return getSliceWithoutDuplicates(count, int64(seed*1000+1000), g.TagPool)
}

func (g *Generator) requiresNames(seed, count int) []string {
return getSliceWithoutDuplicates(count, int64(seed*1000+2000), g.RequiresPool)
}

func (g *Generator) metaNames(seed, count int) map[string]interface{} {
key := getSliceWithoutDuplicates(count, int64(seed*1000+3000), g.MetadataPool)
value := getSliceWithoutDuplicates(count, int64(seed*3000+4000), g.MetadataPool)
meta := make(map[string]interface{}, count)
for i := 0; i < len(key); i++ {
meta[key[i]] = value[i]
}
return meta
}

func (g *Generator) dashboardClient(name string) *v2.DashboardClient {
return &v2.DashboardClient{
ID: IDFrom(fmt.Sprintf("%s%s", name, "id")),
Secret: IDFrom(fmt.Sprintf("%s%s", name, "secret")),
RedirectURI: "http://localhost:1234",
}
}

//
//const okCatalogBytes = `{
// "services": [{
// "name": "fake-service",
// "id": "acb56d7c-XXXX-XXXX-XXXX-feb140a59a66",
// "description": "fake service",
// "tags": ["tag1", "tag2"],
// "requires": ["route_forwarding"],
// "bindable": true,
// "bindings_retrievable": true,
// "metadata": {
// "a": "b",
// "c": "d"
// },
// "dashboard_client": {
// "id": "398e2f8e-XXXX-XXXX-XXXX-19a71ecbcf64",
// "secret": "277cabb0-XXXX-XXXX-XXXX-7822c0a90e5d",
// "redirect_uri": "http://localhost:1234"
// },
// "plan_updateable": true,
// "plans": [{
// "name": "fake-plan-1",
// "id": "d3031751-XXXX-XXXX-XXXX-a42377d3320e",
// "description": "description1",
// "metadata": {
// "b": "c",
// "d": "e"
// }
// }]
// }]
//}`
60 changes: 60 additions & 0 deletions v2/generator/catalog_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package generator

import (
"encoding/json"
"testing"

"github.com/golang/glog"
)

func TestGetCatalog(t *testing.T) {
g := &Generator{
Services: []Service{
{
Plans: []Plan{
{
FromPool: Pull{
Tags: 3,
Metadata: 4,
Free: 1,
},
},
{
FromPool: Pull{
Tags: 3,
Metadata: 4,
},
},
},
FromPool: Pull{
Tags: 3,
Metadata: 4,
BindingsRetrievable: 1,
Bindable: 1,
Requires: 2,
},
},
},
}
AssignPoolGoT(g)

catalog, err := g.GetCatalog()
if err != nil {
t.Errorf("Got error, %v", err)
}

catalogBytes, err := json.MarshalIndent(catalog, "", " ")

catalogJson := string(catalogBytes)

glog.Info(catalogJson)
}

func TestGetPlans(t *testing.T) {

g := Generator{
PlanPool: []string{"AAA", "BBB", "CCC", "DDD", "EEE"},
}
glog.Info(g.planNames(1, 5))
glog.Info(g.planNames(2, 5))
}
59 changes: 59 additions & 0 deletions v2/generator/generator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package generator

import (
"math/rand"
)

func CreateGenerator(serviceCount int, params Parameters) *Generator {
rand.Seed(params.Seed)
g := Generator{}
g.Services = make(Services, serviceCount)
for s, _ := range g.Services {
service := &g.Services[s]
// Fill out the service.
service.FromPool = Pull{}
if params.Services.Tags > 0 {
service.FromPool[Tags] = randn(params.Services.Tags)
}
if params.Services.Metadata > 0 {
service.FromPool[Metadata] = randn(params.Services.Metadata)
}
if params.Services.Requires > 0 {
service.FromPool[Requires] = randn(params.Services.Requires)
}
if params.Services.Bindable > 0 {
service.FromPool[Bindable] = randn(params.Services.Bindable)
}
if params.Services.BindingsRetrievable > 0 {
service.FromPool[BindingsRetrievable] = randn(params.Services.BindingsRetrievable)
}

// How many plans will this service have? Needs at least one.
planCount := randn(params.Services.Plans)
if planCount == 0 {
planCount = 1
}
service.Plans = make(Plans, planCount)

// Fill out the plan.
for p, _ := range service.Plans {
plan := &service.Plans[p]
plan.FromPool = Pull{}
if params.Plans.Metadata > 0 {
plan.FromPool[Metadata] = randn(params.Plans.Metadata)
}
if params.Plans.Bindable > 0 {
plan.FromPool[Bindable] = randn(params.Plans.Bindable)
}
if params.Plans.Free > 0 {
plan.FromPool[Free] = randn(params.Plans.Free)
}
}
}
return &g
}

// [0-n)
func randn(n int) int {
return int(rand.Int31n(int32(n)))
}
38 changes: 38 additions & 0 deletions v2/generator/generator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package generator

import (
"encoding/json"
"testing"

"github.com/golang/glog"
)

func TestCreateGenerator(t *testing.T) {
g := CreateGenerator(3, Parameters{
Services: ServiceRanges{
Plans: 5,
Tags: 6,
Metadata: 4,
Requires: 2,
Bindable: 10,
BindingsRetrievable: 1,
},
Plans: PlanRanges{
Metadata: 4,
Bindable: 10,
Free: 4,
},
})
AssignPoolGoT(g)

catalog, err := g.GetCatalog()
if err != nil {
t.Errorf("Got error, %v", err)
}

catalogBytes, err := json.MarshalIndent(catalog, "", " ")

catalogJson := string(catalogBytes)

glog.Info(catalogJson)
}
Loading

0 comments on commit 87e2f17

Please sign in to comment.