Skip to content

Commit

Permalink
Merge pull request #866 from pivotal-cf-experimental/create-binding-s…
Browse files Browse the repository at this point in the history
…chema

Add service broker create binding schema
  • Loading branch information
tusing authored Aug 4, 2017
2 parents 0c43c90 + 2bca4c3 commit c12ec74
Show file tree
Hide file tree
Showing 16 changed files with 604 additions and 213 deletions.
25 changes: 23 additions & 2 deletions app/models/services/service_plan.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,32 @@ class ServicePlan < Sequel::Model

add_association_dependencies service_plan_visibilities: :destroy

export_attributes :name, :free, :description, :service_guid, :extra, :unique_id, :public, :bindable, :active, :create_instance_schema, :update_instance_schema
export_attributes :name,
:free,
:description,
:service_guid,
:extra,
:unique_id,
:public,
:bindable,
:active,
:create_instance_schema,
:update_instance_schema,
:create_binding_schema

export_attributes_from_methods bindable: :bindable?

import_attributes :name, :free, :description, :service_guid, :extra, :unique_id, :public, :bindable, :create_instance_schema, :update_instance_schema
import_attributes :name,
:free,
:description,
:service_guid,
:extra,
:unique_id,
:public,
:bindable,
:create_instance_schema,
:update_instance_schema,
:create_binding_schema

strip_attributes :name

Expand Down
9 changes: 8 additions & 1 deletion app/presenters/v2/service_plan_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def entity_hash(controller, plan, opts, depth, parents, orphans=nil)
entity.merge!(schemas)
entity.delete('create_instance_schema')
entity.delete('update_instance_schema')
entity.delete('create_binding_schema')

entity
end
Expand All @@ -22,14 +23,20 @@ def entity_hash(controller, plan, opts, depth, parents, orphans=nil)
def present_schemas(plan)
create_instance_schema = parse_schema(plan.create_instance_schema)
update_instance_schema = parse_schema(plan.update_instance_schema)
create_binding_schema = parse_schema(plan.create_binding_schema)
{
'schemas' => {
'service_instance' => {
'create' => {
'parameters' => create_instance_schema
},
'update' => {
'parameters' => update_instance_schema
'parameters' => update_instance_schema
}
},
'service_binding' => {
'create' => {
'parameters' => create_binding_schema
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Sequel.migration do
change do
add_column :service_plans, :create_binding_schema, :text, null: true
end
end
3 changes: 2 additions & 1 deletion lib/services/service_brokers/service_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ def update_or_create_plans(catalog)
active: true,
extra: catalog_plan.metadata.try(:to_json),
create_instance_schema: catalog_plan.schemas.create_instance.try(:to_json),
update_instance_schema: catalog_plan.schemas.update_instance.try(:to_json)
update_instance_schema: catalog_plan.schemas.update_instance.try(:to_json),
create_binding_schema: catalog_plan.schemas.create_binding.try(:to_json)
})
@services_event_repository.with_service_plan_event(plan) do
plan.save(changed: true)
Expand Down
50 changes: 33 additions & 17 deletions lib/services/service_brokers/v2/catalog_schemas.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
module VCAP::Services::ServiceBrokers::V2
class CatalogSchemas
attr_reader :errors, :create_instance, :update_instance
attr_reader :errors, :create_instance, :update_instance, :create_binding

def initialize(schemas)
@errors = VCAP::Services::ValidationErrors.new
return unless schemas

return unless validate_structure(schemas, [])
service_instance_path = ['service_instance']
return unless validate_structure(schemas, service_instance_path)

create_schema = get_method('create', schemas)
@create_instance = Schema.new(create_schema) if create_schema
setup_instance_schemas(schemas)
setup_binding_schemas(schemas)
end

def setup_instance_schemas(schemas)
path = ['service_instance']
if validate_structure(schemas, path)
create_schema = get_method_params(path + ['create'], schemas)
@create_instance = Schema.new(create_schema) if create_schema

update_schema = get_method_params(path + ['update'], schemas)
@update_instance = Schema.new(update_schema) if update_schema
end
end

update_schema = get_method('update', schemas)
@update_instance = Schema.new(update_schema) if update_schema
def setup_binding_schemas(schemas)
path = ['service_binding']
if validate_structure(schemas, path)
binding_schema = get_method_params(path + ['create'], schemas)
@create_binding = Schema.new(binding_schema) if binding_schema
end
end

def valid?
Expand All @@ -28,6 +41,10 @@ def valid?
add_schema_validation_errors(update_instance.errors, 'service_instance.update.parameters')
end

if create_binding && !create_binding.validate
add_schema_validation_errors(create_binding.errors, 'service_binding.create.parameters')
end

errors.empty?
end

Expand All @@ -52,14 +69,18 @@ def validate_structure(schemas, path)
true
end

def get_method(method, schema)
path = ['service_instance', method]
def get_method_params(path, schema)
return unless validate_structure(schema, path)

path = ['service_instance', method, 'parameters']
path << 'parameters'
return unless validate_structure(schema, path)

schema['service_instance'][method]['parameters']
schema.dig(*path)
end

def add_schema_type_error_msg(path, value)
path = path.empty? ? '' : " #{path.join('.')}"
errors.add("Schemas#{path} must be a hash, but has value #{value.inspect}")
end

def add_schema_validation_errors(schema_errors, path)
Expand All @@ -69,10 +90,5 @@ def add_schema_validation_errors(schema_errors, path)
end
end
end

def add_schema_type_error_msg(path, value)
path = path.empty? ? '' : " #{path.join('.')}"
errors.add("Schemas#{path} must be a hash, but has value #{value.inspect}")
end
end
end
85 changes: 81 additions & 4 deletions spec/acceptance/broker_api_compatibility/broker_api_v2.13_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

let(:create_instance_schema) { { '$schema' => 'http://json-schema.org/draft-04/schema#', 'type' => 'object' } }
let(:update_instance_schema) { { '$schema' => 'http://json-schema.org/draft-04/schema#', 'type' => 'object' } }
let(:create_binding_schema) { { '$schema' => 'http://json-schema.org/draft-04/schema#', 'type' => 'object' } }
let(:schemas) {
{
'service_instance' => {
Expand All @@ -15,6 +16,11 @@
'update' => {
'parameters' => update_instance_schema
}
},
'service_binding' => {
'create' => {
'parameters' => create_binding_schema
}
}
}
}
Expand All @@ -28,7 +34,7 @@
end

context 'when a broker catalog defines a service instance' do
context 'with a create plan schema' do
context 'with a valid create schema' do
let(:create_instance_schema) {
{
'$schema' => 'http://json-schema.org/draft-04/schema#',
Expand All @@ -55,7 +61,7 @@
end
end

context 'with an update plan schema' do
context 'with a valid update schema' do
let(:update_instance_schema) {
{
'$schema' => 'http://json-schema.org/draft-04/schema#',
Expand All @@ -82,7 +88,7 @@
end
end

context 'with an invalid create plan schema' do
context 'with an invalid create schema' do
before do
update_broker(default_catalog(plan_schemas: { 'service_instance' => { 'create' => true } }))
end
Expand All @@ -95,7 +101,7 @@
end
end

context 'with an invalid update plan schema' do
context 'with an invalid update schema' do
before do
update_broker(default_catalog(plan_schemas: { 'service_instance' => { 'update' => true } }))
end
Expand All @@ -108,5 +114,76 @@
end
end
end

context 'when a broker catalog defines a service binding' do
context 'with a valid create schema' do
let(:create_binding_schema) {
{
'$schema' => 'http://json-schema.org/draft-04/schema#',
'type' => 'object'
}
}

it 'responds with the schema for a service plan entry' do
get("/v2/service_plans/#{@plan_guid}",
{}.to_json,
json_headers(admin_headers))

parsed_body = MultiJson.load(last_response.body)
create_schema = parsed_body['entity']['schemas']['service_binding']['create']
expect(create_schema).to eq(
{
'parameters' =>
{
'$schema' => 'http://json-schema.org/draft-04/schema#',
'type' => 'object'
}
}
)
end
end

context 'with an invalid create schema' do
before do
update_broker(default_catalog(plan_schemas: { 'service_binding' => { 'create' => true } }))
end

it 'returns an error' do
parsed_body = MultiJson.load(last_response.body)

expect(parsed_body['code']).to eq(270012)
expect(parsed_body['description']).to include('Schemas service_binding.create must be a hash, but has value true')
end
end
end

context 'when the broker catalog defines a plan without plan schemas' do
it 'responds with an empty schema' do
get("/v2/service_plans/#{@large_plan_guid}",
{}.to_json,
json_headers(admin_headers)
)

parsed_body = MultiJson.load(last_response.body)
expect(parsed_body['entity']['schemas']).
to eq(
{
'service_instance' => {
'create' => {
'parameters' => {}
},
'update' => {
'parameters' => {}
}
},
'service_binding' => {
'create' => {
'parameters' => {}
}
}
}
)
end
end
end
end
Loading

0 comments on commit c12ec74

Please sign in to comment.