Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add service broker create binding schema #866

Merged
merged 1 commit into from
Aug 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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