tla-sbuilder 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +328 -0
- data/VERSION +1 -0
- data/bin/sbuilder.rb +5 -0
- data/lib/cli/cli-customer.rb +420 -0
- data/lib/cli/cli-example.rb +92 -0
- data/lib/cli/cli-pet.rb +767 -0
- data/lib/cli/cli-text.rb +226 -0
- data/lib/cli/cli.rb +298 -0
- data/lib/sbuilder.rb +52 -0
- data/lib/sbuilder/constants.rb +72 -0
- data/lib/sbuilder/controller.rb +798 -0
- data/lib/sbuilder/default-sbuilder.yaml +372 -0
- data/lib/sbuilder/domain.rb +124 -0
- data/lib/sbuilder/domain_cardinality.rb +37 -0
- data/lib/sbuilder/domain_value.rb +81 -0
- data/lib/sbuilder/exception.rb +27 -0
- data/lib/sbuilder/extension_loader.rb +721 -0
- data/lib/sbuilder/factory.rb +234 -0
- data/lib/sbuilder/model.rb +356 -0
- data/lib/sbuilder/mustache/template.rb +125 -0
- data/lib/sbuilder/mustache/template_reader.rb +206 -0
- data/lib/sbuilder/mustache/template_reader_context.rb +371 -0
- data/lib/sbuilder/param_set.rb +132 -0
- data/lib/sbuilder/param_set_db.rb +20 -0
- data/lib/sbuilder/param_set_def.rb +57 -0
- data/lib/sbuilder/param_set_if.rb +68 -0
- data/lib/sbuilder/param_set_loader.rb +77 -0
- data/lib/sbuilder/param_set_loader_swagger.rb +424 -0
- data/lib/sbuilder/param_set_step.rb +62 -0
- data/lib/sbuilder/param_sets.rb +54 -0
- data/lib/sbuilder/parameter.rb +97 -0
- data/lib/sbuilder/parameter_container.rb +72 -0
- data/lib/sbuilder/parameter_dom.rb +70 -0
- data/lib/sbuilder/parameter_ref.rb +71 -0
- data/lib/sbuilder/resolver.rb +78 -0
- data/lib/sbuilder/resolver_loader.rb +79 -0
- data/lib/sbuilder/resolver_loader_yaml.rb +103 -0
- data/lib/sbuilder/resolver_rule.rb +36 -0
- data/lib/sbuilder/resolver_rule_match.rb +55 -0
- data/lib/sbuilder/resolver_rule_ref.rb +37 -0
- data/lib/utils/hash_inject.rb +12 -0
- data/lib/utils/logger.rb +80 -0
- data/lib/utils/netio.rb +58 -0
- data/lib/utils/string_inject.rb +10 -0
- data/lib/utils/version.rb +13 -0
- data/mustache/cfg/const_def.mustache +8 -0
- data/mustache/cfg/const_run.mustache +3 -0
- data/mustache/cfg/invariant-infrastructure-service.mustache +4 -0
- data/mustache/cfg/macro_run.mustache +6 -0
- data/mustache/cfg/module_footer.mustache +0 -0
- data/mustache/cfg/module_header.mustache +7 -0
- data/mustache/data-model-dump.mustache +19 -0
- data/mustache/data-model-footer.mustache +5 -0
- data/mustache/data-model-header.mustache +16 -0
- data/mustache/definition_types.mustache +40 -0
- data/mustache/domains.mustache +20 -0
- data/mustache/domains_assign.mustache +22 -0
- data/mustache/domains_run.mustache +21 -0
- data/mustache/extend/extend_assumptions.mustache +7 -0
- data/mustache/extend/extend_const.mustache +5 -0
- data/mustache/extend/extend_implementation.mustache +9 -0
- data/mustache/extend/extend_invariant.mustache +7 -0
- data/mustache/extend/extend_invariant_cfg.mustache +7 -0
- data/mustache/extend/extend_macros.mustache +19 -0
- data/mustache/extend/extend_operations.mustache +9 -0
- data/mustache/extend/extend_state.mustache +9 -0
- data/mustache/infrastructure-service-init.mustache +36 -0
- data/mustache/infrastructure-service-variables.mustache +10 -0
- data/mustache/interface_processes.mustache +38 -0
- data/mustache/interface_stubs_dummy.mustache +13 -0
- data/mustache/interface_types.mustache +52 -0
- data/mustache/markdown-header.mustache +24 -0
- data/mustache/markdown-toc.mustache +13 -0
- data/mustache/name_definition_type.mustache +5 -0
- data/mustache/name_domain.mustache +5 -0
- data/mustache/name_domain_value.mustache +5 -0
- data/mustache/name_domain_value_prefix.mustache +5 -0
- data/mustache/name_interface_response_type.mustache +6 -0
- data/mustache/name_interface_type.mustache +6 -0
- data/mustache/name_parameter_definition.mustache +5 -0
- data/mustache/name_parameter_type.mustache +6 -0
- data/mustache/name_process.mustache +6 -0
- data/mustache/name_type_invariant.mustache +5 -0
- data/mustache/name_variable.mustache +6 -0
- data/mustache/operator-infrastructure-service.mustache +13 -0
- data/mustache/possibility/module_extends.mustache +1 -0
- data/mustache/possibility/module_footer.mustache +1 -0
- data/mustache/possibility/module_header.mustache +8 -0
- data/mustache/possibility/possibility_definition.mustache +12 -0
- data/mustache/possibility/possibility_directive.mustache +1 -0
- data/mustache/possibility/possility_setup.mustache +28 -0
- data/mustache/setup/module_footer.mustache +1 -0
- data/mustache/setup/module_header.mustache +9 -0
- data/mustache/setup/operator_run.mustache +7 -0
- data/mustache/setup/operator_tick.mustache +2 -0
- data/mustache/setup/steps_run.mustache +22 -0
- data/mustache/setup/steps_run_bind_rule.mustache +51 -0
- data/mustache/setup/steps_run_bind_set.mustache +37 -0
- data/mustache/setup/steps_run_parameterBind.mustache +80 -0
- data/mustache/setup/steps_run_parameterExact.mustache +79 -0
- data/mustache/state_type_invariant-infrastructure-service.mustache +49 -0
- data/mustache/state_type_invariant.mustache +17 -0
- data/mustache/state_type_invariant_cfg.mustache +18 -0
- data/mustache/state_variables.mustache +20 -0
- data/mustache/tla/const_def.mustache +5 -0
- data/mustache/tla/const_run.mustache +3 -0
- data/mustache/tla/macro-infrastructure-service.mustache +14 -0
- data/mustache/tla/macro_run.mustache +40 -0
- data/mustache/tla/module_footer.mustache +2 -0
- data/mustache/tla/module_header.mustache +9 -0
- data/mustache/tla/operator_run.mustache +8 -0
- data/mustache/tla/operators-infrastructure-service.mustache +12 -0
- data/mustache/tla/plc_define_footer.mustache +1 -0
- data/mustache/tla/plc_define_header.mustache +1 -0
- data/mustache/tla/plc_define_run.mustache +59 -0
- data/mustache/tla/plc_footer.mustache +2 -0
- data/mustache/tla/plc_header.mustache +2 -0
- data/mustache/tla/plc_run_state.mustache +12 -0
- data/mustache/tla/plc_tail.mustache +8 -0
- data/mustache/tla/plc_translation.mustache +2 -0
- data/resources/schema/json_schema/draft-04.json +150 -0
- data/resources/schema/swagger/2.0/schema.json +1591 -0
- data/src-extend/README +2 -0
- data/src-extend/extend/extend_assumptions.mustache +7 -0
- data/src-extend/extend/extend_const.mustache +5 -0
- data/src-extend/extend/extend_implementation.mustache +9 -0
- data/src-extend/extend/extend_invariant.mustache +11 -0
- data/src-extend/extend/extend_invariant_cfg.mustache +7 -0
- data/src-extend/extend/extend_macros.mustache +19 -0
- data/src-extend/extend/extend_operations.mustache +9 -0
- data/src-extend/extend/extend_state.mustache +9 -0
- data/src-extend/extend_app/assumption +20 -0
- data/src-extend/extend_app/correctness +19 -0
- data/src-extend/extend_app/correctness.cfg +9 -0
- data/src-extend/extend_app/infrastructure +25 -0
- data/src-extend/extend_app/interface +11 -0
- data/src-extend/extend_app/operator +18 -0
- data/src-extend/extend_app/possibility +16 -0
- data/src-extend/extend_app/service +33 -0
- data/src-extend/extend_app/state +16 -0
- data/src-extend/extend_app/transaction +22 -0
- data/src/pet/assumption +29 -0
- data/src/pet/assumption_address_domains.tla +12 -0
- data/src/pet/assumption_domains.tla +16 -0
- data/src/pet/assumption_generic.tla +8 -0
- data/src/pet/assumption_id_domains.tla +2 -0
- data/src/pet/assumption_owner_domains.tla +14 -0
- data/src/pet/assumption_pet_domains.tla +16 -0
- data/src/pet/assumption_tag_domains.tla +13 -0
- data/src/pet/correctness +24 -0
- data/src/pet/correctness.cfg +9 -0
- data/src/pet/correctness_coherent_owner_address.tla +6 -0
- data/src/pet/correctness_pet_name.tla +4 -0
- data/src/pet/correctness_ref_tag.tla +13 -0
- data/src/pet/correctness_type_invariants.tla +12 -0
- data/src/pet/correctness_unique_pet.tla +3 -0
- data/src/pet/correctness_unique_tag.tla +3 -0
- data/src/pet/docs/Petstore.md +117 -0
- data/src/pet/extend/extend_assumptions.mustache +7 -0
- data/src/pet/extend/extend_implementation.mustache +9 -0
- data/src/pet/extend/extend_invariant.mustache +11 -0
- data/src/pet/extend/extend_invariant_cfg.mustache +7 -0
- data/src/pet/extend/extend_macros.mustache +19 -0
- data/src/pet/extend/extend_operations.mustache +9 -0
- data/src/pet/extend/extend_state.mustache +9 -0
- data/src/pet/infrastructure +25 -0
- data/src/pet/infrastructure_id_get.tla +24 -0
- data/src/pet/interface +12 -0
- data/src/pet/interface_delete_pet.tla +5 -0
- data/src/pet/interface_get_pet.tla +4 -0
- data/src/pet/interface_post_pet.tla +5 -0
- data/src/pet/interface_post_tag.tla +5 -0
- data/src/pet/interface_put_tag.tla +3 -0
- data/src/pet/operator +30 -0
- data/src/pet/operator_find_tag_by_owner_name.tla +1 -0
- data/src/pet/operator_get_pet.tla +4 -0
- data/src/pet/operator_get_pet_by_tag.tla +4 -0
- data/src/pet/operator_get_tag.tla +10 -0
- data/src/pet/operator_new_owner.tla +3 -0
- data/src/pet/operator_new_pet.tla +13 -0
- data/src/pet/operator_new_tag.tla +3 -0
- data/src/pet/operator_next_pet_id.tla +3 -0
- data/src/pet/operator_responses.tla +8 -0
- data/src/pet/operator_tag_exists.tla +2 -0
- data/src/pet/operator_tag_owner_validated.tla +2 -0
- data/src/pet/operator_tag_referenced.tla +4 -0
- data/src/pet/operator_valid_owner.tla +17 -0
- data/src/pet/operator_valid_pet.tla +6 -0
- data/src/pet/operator_valid_tag.tla +5 -0
- data/src/pet/possibility +18 -0
- data/src/pet/possibility_at_least_two_tags.tla +12 -0
- data/src/pet/possibility_invalid_tag_address.tla +8 -0
- data/src/pet/service +35 -0
- data/src/pet/service_pet_delete.tla +11 -0
- data/src/pet/service_pet_get.tla +27 -0
- data/src/pet/service_pet_post.tla +78 -0
- data/src/pet/service_tag_post.tla +53 -0
- data/src/pet/service_tag_put.tla +82 -0
- data/src/pet/state +16 -0
- data/src/pet/state_infra.tla +6 -0
- data/src/pet/state_pet.tla +5 -0
- data/src/pet/state_tag_id.tla +2 -0
- data/src/pet/transaction +23 -0
- data/src/pet/transaction_delete_pet.tla +13 -0
- data/src/pet/transaction_enter_pet.tla +13 -0
- data/src/pet/transaction_enter_tag.tla +56 -0
- data/src/pet/transaction_error.tla +23 -0
- data/tla-sbuilder.gemspec +43 -0
- metadata +353 -0
@@ -0,0 +1,132 @@
|
|
1
|
+
|
2
|
+
module Sbuilder
|
3
|
+
|
4
|
+
class ParamSet
|
5
|
+
|
6
|
+
attr_reader :parameters # array of parameters:Parameter
|
7
|
+
|
8
|
+
# ------------------------------------------------------------------
|
9
|
+
# mixer
|
10
|
+
PROGNAME = "ParamSet" # progname for logger
|
11
|
+
include Sbuilder::Utils::MyLogger # mix logger
|
12
|
+
|
13
|
+
|
14
|
+
# ------------------------------------------------------------------
|
15
|
+
# constrcutore
|
16
|
+
def initialize( options = {} )
|
17
|
+
@logger = getLogger( PROGNAME, options )
|
18
|
+
@logger.info( "#{__method__} initialized" )
|
19
|
+
@parameters = []
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
"#{getId}"
|
24
|
+
end
|
25
|
+
|
26
|
+
# normally resolve 'parameter' sub-classes may override
|
27
|
+
def parametersToResolve
|
28
|
+
parameters
|
29
|
+
end
|
30
|
+
|
31
|
+
# ------------------------------------------------------------------
|
32
|
+
# builder
|
33
|
+
def addParameter( param )
|
34
|
+
parameters << param
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
# ------------------------------------------------------------------
|
39
|
+
# identifier for finding domain matche
|
40
|
+
|
41
|
+
def matchesWithParamSet( matcher )
|
42
|
+
matcher.is_a?( String ) ? getId == matcher : (getId =~ matcher) != nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def getId
|
46
|
+
doGetId
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
def doGetId
|
51
|
+
msg = "Sub class should implement doGetId -method"
|
52
|
+
@logger.error( "#{__method__} #{msg}" )
|
53
|
+
raise NoMethodError.new( msg )
|
54
|
+
end
|
55
|
+
|
56
|
+
# ------------------------------------------------------------------
|
57
|
+
# generata phase
|
58
|
+
|
59
|
+
|
60
|
+
# return hash for generation phase, false if no paramteers
|
61
|
+
def parameter_definitions( model )
|
62
|
+
arra = parameters.map.with_index do |p,i|
|
63
|
+
# puts "p=#{p}"
|
64
|
+
parameter_def = p.parameter_definition( model )
|
65
|
+
# puts "parameter_def=#{parameter_def}"
|
66
|
+
parameter_def[:parameter_name] = ParamSet.cleanUpName( parameter_def[:parameter_name] )
|
67
|
+
|
68
|
+
parameter_def[:_comma] = (i < parameters.length-1 ? "," : "" ) # empty string for last element
|
69
|
+
parameter_def
|
70
|
+
# {
|
71
|
+
# :name => p.name,
|
72
|
+
# :parameter_name => ParamSet.cleanUpName( p.name ),
|
73
|
+
# :type => p.getType,
|
74
|
+
# :
|
75
|
+
# }
|
76
|
+
end
|
77
|
+
# return false if no parameter
|
78
|
+
return false if arra.length == 0
|
79
|
+
return arra
|
80
|
+
end
|
81
|
+
|
82
|
+
# make it valid identifier
|
83
|
+
def self.cleanUpName( name )
|
84
|
+
return name ?
|
85
|
+
name.gsub( /\./, "_" ) : # . --> _
|
86
|
+
name
|
87
|
+
end
|
88
|
+
|
89
|
+
# getId with invalid-caharacters as underscpce
|
90
|
+
def getName
|
91
|
+
return getId.
|
92
|
+
gsub( /\//, "_" ). # / --> _
|
93
|
+
gsub( /\(/, "_" ). # ( --> _
|
94
|
+
gsub( /\{/, "_" ). # { --> _
|
95
|
+
gsub( /\}/, "_" ). # } --> _
|
96
|
+
gsub( /\)/, "_" ) # ) --> _
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
# ------------------------------------------------------------------
|
101
|
+
# locateParameter
|
102
|
+
|
103
|
+
# Locate parameter 'key', raise on an error if not found
|
104
|
+
def locateParameter( key )
|
105
|
+
key = key.first if key.is_a?( Array )
|
106
|
+
@logger.debug( "#{__method__} key=#{key}" )
|
107
|
+
|
108
|
+
|
109
|
+
# locate key in this paramter set
|
110
|
+
# puts "parameters=#{parameters}"
|
111
|
+
found = parameters.select do |parameter|
|
112
|
+
# puts "parameter.name #{parameter.name} == key = #{key}"
|
113
|
+
parameter.name == key
|
114
|
+
end.first
|
115
|
+
@logger.debug( "#{__method__} key=#{key} --> found='#{found}' found.class=#{found.class}" )
|
116
|
+
raise <<-EOS if found.nil?
|
117
|
+
|
118
|
+
Could not locate parameter '#{key}' in parameter set '#{getId}'
|
119
|
+
|
120
|
+
Valid names in parameter set '#{getId}': #{parameters.map {|parameter| parameter.name}.join(',')}
|
121
|
+
|
122
|
+
EOS
|
123
|
+
|
124
|
+
return found
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
end # class
|
131
|
+
|
132
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
module Sbuilder
|
3
|
+
|
4
|
+
class ParamSet_Db < ParamSet
|
5
|
+
|
6
|
+
# ------------------------------------------------------------------
|
7
|
+
# mixer
|
8
|
+
PROGNAME = "ParamSet_Db" # progname for logger
|
9
|
+
include Sbuilder::Utils::MyLogger # mix logger
|
10
|
+
|
11
|
+
# ------------------------------------------------------------------
|
12
|
+
# constrcutore
|
13
|
+
def initialize( options = {} )
|
14
|
+
@logger = getLogger( PROGNAME, options )
|
15
|
+
@logger.info( "#{__method__} initialized" )
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
|
2
|
+
module Sbuilder
|
3
|
+
|
4
|
+
# interface paramter set (identified by path+operations)
|
5
|
+
class ParamSetDef < ParamSet
|
6
|
+
|
7
|
+
attr_reader :isArray # defaults 'false'
|
8
|
+
attr_reader :definition # REST path
|
9
|
+
|
10
|
+
|
11
|
+
# ------------------------------------------------------------------
|
12
|
+
# mixer
|
13
|
+
PROGNAME = "ParamSet_Def" # progname for logger
|
14
|
+
include Sbuilder::Utils::MyLogger # mix logger
|
15
|
+
|
16
|
+
# ------------------------------------------------------------------
|
17
|
+
# constrcutore
|
18
|
+
def initialize( options = {} )
|
19
|
+
super( options )
|
20
|
+
@logger = getLogger( PROGNAME, options )
|
21
|
+
@logger.info( "#{__method__} initialized" )
|
22
|
+
|
23
|
+
# default is not an arrays
|
24
|
+
@isArray = false
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
# ------------------------------------------------------------------
|
29
|
+
# setIdentity
|
30
|
+
|
31
|
+
# set configure
|
32
|
+
def setDefinition( definition )
|
33
|
+
@definition = definition
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
# ------------------------------------------------------------------
|
38
|
+
# implentation
|
39
|
+
|
40
|
+
# return identity
|
41
|
+
def doGetId
|
42
|
+
"#{definition}"
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
# ------------------------------------------------------------------
|
47
|
+
#
|
48
|
+
def setIsArray( isArray = true )
|
49
|
+
@isArray = isArray
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
module Sbuilder
|
3
|
+
|
4
|
+
# interface paramter set (identified by path+operations)
|
5
|
+
class ParamSet_If < ParamSet
|
6
|
+
|
7
|
+
attr_reader :path # REST path
|
8
|
+
attr_reader :operation # REST path
|
9
|
+
attr_reader :response # returned from interface
|
10
|
+
attr_reader :infrastructureService # default 'false'
|
11
|
+
|
12
|
+
# ------------------------------------------------------------------
|
13
|
+
# mixer
|
14
|
+
PROGNAME = "ParamSet_If" # progname for logger
|
15
|
+
include Sbuilder::Utils::MyLogger # mix logger
|
16
|
+
|
17
|
+
# ------------------------------------------------------------------
|
18
|
+
# constrcutore
|
19
|
+
def initialize( options = {} )
|
20
|
+
super( options )
|
21
|
+
@logger = getLogger( PROGNAME, options )
|
22
|
+
@logger.info( "#{__method__} initialized" )
|
23
|
+
@response = nil
|
24
|
+
@infrastructureService = false
|
25
|
+
end
|
26
|
+
|
27
|
+
# # normally resolve 'parameter', however in my case resolve also responses
|
28
|
+
# def parametersToResolve
|
29
|
+
# return parameters + ( @response ? @response.parameters : [])
|
30
|
+
# end
|
31
|
+
|
32
|
+
|
33
|
+
# ------------------------------------------------------------------
|
34
|
+
# configure
|
35
|
+
|
36
|
+
# def addResponse( response )
|
37
|
+
# @responses << response
|
38
|
+
# self
|
39
|
+
# end
|
40
|
+
|
41
|
+
def setResponse( response )
|
42
|
+
@response = response
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def setInfrastructureService( infrastructureService )
|
47
|
+
@infrastructureService = infrastructureService
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
# ------------------------------------------------------------------
|
52
|
+
# setIdentity
|
53
|
+
|
54
|
+
# set identity
|
55
|
+
def setIdentity( path, operation )
|
56
|
+
@path = path
|
57
|
+
@operation = operation
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
# return identity
|
62
|
+
def doGetId
|
63
|
+
"#{path}(#{operation})"
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
|
2
|
+
module Sbuilder
|
3
|
+
|
4
|
+
class ParamSetLoader
|
5
|
+
|
6
|
+
attr_reader :factory # to create stuff
|
7
|
+
attr_accessor :controller # get sets when load starts
|
8
|
+
|
9
|
+
# ------------------------------------------------------------------
|
10
|
+
# mixer
|
11
|
+
PROGNAME = "ParamSetLoader" # progname for logger
|
12
|
+
include Sbuilder::Utils::MyLogger # mix logger
|
13
|
+
|
14
|
+
|
15
|
+
# ------------------------------------------------------------------
|
16
|
+
# constructore
|
17
|
+
|
18
|
+
def initialize( factory, options = {} )
|
19
|
+
@logger = getLogger( PROGNAME, options )
|
20
|
+
@logger.info( "#{__method__} initialized" )
|
21
|
+
@factory = factory
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param loaderDef [Hash] adding configuration for loader (override)
|
25
|
+
def configure( loaderDef )
|
26
|
+
doConfigure( loaderDef )
|
27
|
+
end
|
28
|
+
|
29
|
+
def doConfigure( loaderDef )
|
30
|
+
msg = "Sub class should implement doConfigure -method"
|
31
|
+
@logger.error( "#{__method__} #{msg}" )
|
32
|
+
raise NoMethodError.new( msg )
|
33
|
+
end
|
34
|
+
|
35
|
+
# ------------------------------------------------------------------
|
36
|
+
# load paramset from 'fileUri'
|
37
|
+
def load( controller, fileUri, cacheFile=nil )
|
38
|
+
# controller which control loading
|
39
|
+
@controller = controller
|
40
|
+
|
41
|
+
begin
|
42
|
+
loaded = doLoad( fileUri, cacheFile )
|
43
|
+
rescue Exception => e
|
44
|
+
msg = "Exception '#{e}' when loading fileUri '#{fileUri}'"
|
45
|
+
@logger.error( "#{__method__} #{msg}" )
|
46
|
+
puts msg
|
47
|
+
raise e
|
48
|
+
end
|
49
|
+
|
50
|
+
# # iterate && report to controller
|
51
|
+
# loaded.each do |paramSet|
|
52
|
+
# controller.interfaceEncountered( paramSet )
|
53
|
+
# end
|
54
|
+
end
|
55
|
+
|
56
|
+
def createParamSet( type )
|
57
|
+
factory.createParamSet( type )
|
58
|
+
end
|
59
|
+
|
60
|
+
def createParameter( type )
|
61
|
+
factory.createParameter( type )
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
# ------------------------------------------------------------------
|
66
|
+
# sub-class should implement the doload method
|
67
|
+
def doLoad( fileUri, cacheFile=nil )
|
68
|
+
msg = "Sub class should implement doLoad -method"
|
69
|
+
@logger.error( "#{__method__} #{msg}" )
|
70
|
+
raise NoMethodError.new( msg )
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
end # class ParamSetLoader
|
75
|
+
|
76
|
+
|
77
|
+
end # module
|
@@ -0,0 +1,424 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'yaml'
|
3
|
+
require 'json'
|
4
|
+
require 'hashie'
|
5
|
+
|
6
|
+
require 'json-schema'
|
7
|
+
|
8
|
+
module Sbuilder
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
class ParamSetLoaderSwagger < ParamSetLoader
|
13
|
+
|
14
|
+
attr_reader :infrastructureServices # default 'false'
|
15
|
+
|
16
|
+
# ------------------------------------------------------------------
|
17
|
+
# mixer
|
18
|
+
PROGNAME = "LoadSwagger" # progname for logger
|
19
|
+
include Sbuilder::Utils::MyLogger # mix logger
|
20
|
+
|
21
|
+
# ------------------------------------------------------------------
|
22
|
+
# constrcutore
|
23
|
+
def initialize( factory, options = {} )
|
24
|
+
super( factory, options )
|
25
|
+
@logger = getLogger( PROGNAME, options )
|
26
|
+
@logger.info( "#{__method__} initialized" )
|
27
|
+
|
28
|
+
# properties
|
29
|
+
@infrastructureServices = false
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
# extract 'intfractureServices' property from 'paramsetLoaderDef'
|
34
|
+
#
|
35
|
+
# @param paramsetLoaderDef [Hash] configuration in 'sbuilder.yaml'
|
36
|
+
#
|
37
|
+
def doConfigure( paramsetLoaderDef )
|
38
|
+
@infrastructureServices = true if paramsetLoaderDef['infrastructureServices']
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# implements abstract super class method validates, loads
|
43
|
+
# interfaces and definitions in YAML parsed from 'yamlFileUri'
|
44
|
+
|
45
|
+
# @param yamlFileUri [String] path or url to YAML file to process
|
46
|
+
|
47
|
+
def doLoad( yamlFileUri, cacheFile=nil )
|
48
|
+
@logger.info( "#{__method__} yamlFileUri=#{yamlFileUri}" )
|
49
|
+
# swagger_hash = YAML.load_file( yamlFileUri )
|
50
|
+
yaml_lines = Sbuilder::Utils::NetIo.read_lines_cached( yamlFileUri, cacheFile )
|
51
|
+
# puts yaml_lines
|
52
|
+
# puts "yamlFileUri=#{yamlFileUri}"
|
53
|
+
swagger_hash = YAML.load( yaml_lines )
|
54
|
+
|
55
|
+
validate( swagger_hash )
|
56
|
+
doLoadInterfaces( swagger_hash )
|
57
|
+
doLoadDefinitions( swagger_hash )
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
# ==================================================================
|
62
|
+
# entry points
|
63
|
+
|
64
|
+
# calls '@controller.definitionEncountered' for each parameter set
|
65
|
+
# found in swagger configuration
|
66
|
+
# @param swagger_hash [swagger 2.0]
|
67
|
+
|
68
|
+
def doLoadDefinitions( swagger_hash )
|
69
|
+
paramsSets = swaggerDefinitionParamsets( swagger_hash )
|
70
|
+
paramsSets.each do |paramSet|
|
71
|
+
controller.definitionEncountered( paramSet )
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
# calls '@controller.interfaceEncountered' for each parameter set
|
77
|
+
# found in swagger configuration
|
78
|
+
#
|
79
|
+
# @param swagger_hash [swagger 2.0]
|
80
|
+
|
81
|
+
def doLoadInterfaces( swagger_hash )
|
82
|
+
|
83
|
+
interface_paramsSets = swaggerPathInterfaces( swagger_hash )
|
84
|
+
@logger.info( "#{__method__} loaded=#{interface_paramsSets.length} interface_paramsSets" )
|
85
|
+
|
86
|
+
interface_paramsSets.each do |interface|
|
87
|
+
controller.interfaceEncountered( interface )
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
# entry poinsts
|
93
|
+
# ==================================================================
|
94
|
+
|
95
|
+
# Validates this object against the Swagger specification and
|
96
|
+
# returns the first detected error. Faster than
|
97
|
+
# {#fully_validate}.
|
98
|
+
#
|
99
|
+
# @return [true] if the object fully complies with the Swagger specification.
|
100
|
+
# @raise [Swagger::InvalidDefinition] if an error is found.
|
101
|
+
def validate( json )
|
102
|
+
JSON::Validator.validate!(swagger_schema, json ) #
|
103
|
+
# JSON::Validator.fully_validate(swagger_schema, json ) #
|
104
|
+
rescue JSON::Schema::ValidationError => e
|
105
|
+
raise Sbuilder::LoaderException.new, e.message
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
private def swagger_schema
|
110
|
+
@swagger_schema ||= JSON.parse(File.read(Sbuilder::Constants::SWAGGER_SCHEMA))
|
111
|
+
# FIXME: Swagger should be able to parse offline. Blocked by json-schema.
|
112
|
+
# Offline workaround
|
113
|
+
# @swagger_schema = JSON.parse(File.read(SWAGGER_SCHEMA)
|
114
|
+
# .gsub('http://json-schema.org/draft-04/schema', "file://#{SWAGGER_SCHEMA}"))
|
115
|
+
# @swagger_schema['$schema'] = 'http://json-schema.org/draft-04/schema#'
|
116
|
+
# @swagger_schema
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
# ------------------------------------------------------------------
|
123
|
+
# iterate defitions
|
124
|
+
def swaggerDefinitionParamsets( swagger_hash )
|
125
|
+
paramSets = []
|
126
|
+
swagger_hash['definitions'] && swagger_hash['definitions'].each do |defineKey,definedDoc|
|
127
|
+
# puts "defineKey=#{defineKey} -> #{definedDoc}"
|
128
|
+
|
129
|
+
# create set && configure param set for a defintion
|
130
|
+
paramSet = createParamSet( Sbuilder::Constants::SWAGGER_DEFINITION )
|
131
|
+
paramSet.setDefinition( defineKey )
|
132
|
+
paramSet.setIsArray if definedDoc['type'] == 'array'
|
133
|
+
paramSets << paramSet
|
134
|
+
|
135
|
+
if hasRef( definedDoc ) then
|
136
|
+
# case paramter set is a wrapper - most likely an array
|
137
|
+
reference_parameter( paramSet, defineKey, getRefDocumentName( definedDoc ), definedDoc['type'] )
|
138
|
+
else
|
139
|
+
|
140
|
+
expandedDocs = expand_definedDocs( definedDoc, swagger_hash )
|
141
|
+
# puts " defineKey=#{defineKey} --> expandedDocs=#{expandedDocs}"
|
142
|
+
|
143
|
+
# iterate array of [ { <name> = { "type"=>.., <format> =>..}, <name> => ..}, ... ]
|
144
|
+
expandedDocs.each do |expandedDoc|
|
145
|
+
# puts "#----->{op}-expandedDoc->#{expandedDoc}"
|
146
|
+
expandedDoc.each do |parameterName,parameterProps|
|
147
|
+
@logger.debug( "#{__method__} {op}-parameterName->#{parameterName}, parameterProps=>#{parameterProps}" )
|
148
|
+
if hasRef( parameterProps ) then
|
149
|
+
reference_parameter( paramSet, parameterName, getRefDocumentName( parameterProps ), parameterProps['type'] )
|
150
|
+
else
|
151
|
+
simple_parameter( paramSet, parameterName, parameterProps['type'] )
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
end # each definitions
|
158
|
+
|
159
|
+
return paramSets
|
160
|
+
end
|
161
|
+
|
162
|
+
# ------------------------------------------------------------------
|
163
|
+
# iterate interface ['path'][<operation>]['paramters']
|
164
|
+
|
165
|
+
def swaggerPathInterfaces( swagger_hash )
|
166
|
+
|
167
|
+
@logger.info( "#{__method__} starting" )
|
168
|
+
|
169
|
+
# collect all interface paramsets together
|
170
|
+
paramSets = []
|
171
|
+
|
172
|
+
# interfaces are hashes under 'paths'/<path>/<op>
|
173
|
+
swagger_hash['paths'].each do |path,ops|
|
174
|
+
ops.each do |op,opdef|
|
175
|
+
|
176
|
+
# Create new paramSet, configugre its identity
|
177
|
+
interfaceParamSet = createParamSet( Sbuilder::Constants::SWAGGER )
|
178
|
+
interfaceParamSet.setIdentity( path, op )
|
179
|
+
interfaceParamSet.setInfrastructureService( infrastructureServices )
|
180
|
+
@logger.info( "#{__method__} created interfaceParamSet=#{interfaceParamSet.getId}" )
|
181
|
+
@logger.debug( "#{__method__} created interfaceParamSet.getId=#{interfaceParamSet.getId}, opdef=#{opdef}" )
|
182
|
+
|
183
|
+
# add to array we are going to return
|
184
|
+
paramSets << interfaceParamSet
|
185
|
+
|
186
|
+
# ---------------------------------
|
187
|
+
# input paramters: 'paths'/<path>/<op>/'parameters'
|
188
|
+
|
189
|
+
# collect paramters to an array
|
190
|
+
# parameters = []
|
191
|
+
opdef['parameters'] && opdef['parameters'].map do |parameter|
|
192
|
+
@logger.debug( "#{__method__} path/op #{path}/#{op} - parameter #{parameter}" )
|
193
|
+
if parameter['schema'] then
|
194
|
+
# in='body' => schema defined
|
195
|
+
defintionReferenceName = getReferencedDefinitionName( parameter['schema'], swagger_hash )
|
196
|
+
reference_parameter( interfaceParamSet, parameter['name'], defintionReferenceName )
|
197
|
+
# parameters = parameters +
|
198
|
+
# # expand_reference_object( parameter['schema'], swagger_hash ).map do |schema|
|
199
|
+
# [ parameter['name'], schema ]
|
200
|
+
#end
|
201
|
+
elsif parameter['name']
|
202
|
+
simple_parameter( interfaceParamSet, parameter['name'], parameter['type'] ) if parameter['name']
|
203
|
+
# parameter object normal i.e. not in='body' object
|
204
|
+
# parameters << parameter2ParamObject( parameter )
|
205
|
+
else
|
206
|
+
msg = "Empty parameter definition on #{path}/#{op} "
|
207
|
+
@logger.error( "#{__method__} #{msg}" )
|
208
|
+
warn msg
|
209
|
+
end
|
210
|
+
|
211
|
+
end # parameters
|
212
|
+
|
213
|
+
# ------------------------------
|
214
|
+
# responses: 'paths'/<path>/<op>/'responses'
|
215
|
+
|
216
|
+
paramSetResponse = createParamSet( Sbuilder::Constants::SWAGGER )
|
217
|
+
paramSetResponse.setIdentity( path, 'response' )
|
218
|
+
|
219
|
+
# response response to an interface
|
220
|
+
interfaceParamSet.setResponse( paramSetResponse )
|
221
|
+
|
222
|
+
|
223
|
+
opdef['responses'] && opdef['responses'].each_pair do |status_code,response|
|
224
|
+
# puts "op=#{op}, status_code=#{status_code}, response=#{response}"
|
225
|
+
|
226
|
+
if response['schema'] then
|
227
|
+
defintionReferenceName = getReferencedDefinitionName( response['schema'], swagger_hash )
|
228
|
+
@logger.debug( "#{__method__} defintionReferenceName=#{defintionReferenceName}, op=#{op}, status_code=#{status_code}, response=#{response}" )
|
229
|
+
reference_parameter( paramSetResponse, "status_#{status_code}", defintionReferenceName, response['schema']['type'] )
|
230
|
+
|
231
|
+
else
|
232
|
+
@logger.debug( "#{path}-#{op}-#{status_code}: no response data for response #{response}" )
|
233
|
+
# # response object
|
234
|
+
end
|
235
|
+
end # opdef['responses'].each
|
236
|
+
|
237
|
+
|
238
|
+
end # each 'paths'
|
239
|
+
end
|
240
|
+
|
241
|
+
return paramSets
|
242
|
+
end
|
243
|
+
|
244
|
+
|
245
|
+
|
246
|
+
# return the name of definition referenced in 'paramOrRespSchema'
|
247
|
+
def getReferencedDefinitionName( paramOrRespSchema, swagger_hash )
|
248
|
+
|
249
|
+
# e.g. '#/definitions/doc
|
250
|
+
ref = getRef( paramOrRespSchema )
|
251
|
+
|
252
|
+
# e.g ['defintions', 'doc']
|
253
|
+
pathElements = getPathElementFromReference( ref )
|
254
|
+
|
255
|
+
# e.g. doc
|
256
|
+
definitionDocumentName = pathElements.last
|
257
|
+
|
258
|
+
# return the name
|
259
|
+
definitionDocumentName
|
260
|
+
|
261
|
+
end
|
262
|
+
|
263
|
+
# concat 'collectedReferences' with expanded '$ref' properties in 'definedDoc' with values in 'swagger_hash'
|
264
|
+
def expand_definedDocs( definedDoc, swagger_hash )
|
265
|
+
|
266
|
+
if definedDoc['properties']
|
267
|
+
return [ definedDoc['properties'] ]
|
268
|
+
# collect documents in 'allOf'
|
269
|
+
elsif definedDoc['allOf'] then
|
270
|
+
allDocs = []
|
271
|
+
definedDoc['allOf'].each do |elemenDoc|
|
272
|
+
allDocs = allDocs + definedDocArr2ParamObject(expand_definedDocs( elemenDoc, swagger_hash ))
|
273
|
+
end
|
274
|
+
# puts "---> expand_definedDocs-1 = #{allDocs} for #{definedDoc}"
|
275
|
+
return allDocs
|
276
|
+
else
|
277
|
+
# check for references
|
278
|
+
definedDoc.extend Hashie::Extensions::DeepFind
|
279
|
+
refs = definedDoc.deep_find_all( "$ref" )
|
280
|
+
|
281
|
+
if refs.nil?
|
282
|
+
puts "---> expand_definedDocs-2 = #{[definedDoc]} for #{definedDoc}"
|
283
|
+
return definedDocArr2ParamObject([definedDoc])
|
284
|
+
end
|
285
|
+
# expand all referncnes
|
286
|
+
expandedDocs = []
|
287
|
+
refs.each do |ref|
|
288
|
+
referredDoc = getDefinitionDoc( ref, swagger_hash )
|
289
|
+
expandedDocs = expandedDocs + definedDocArr2ParamObject(expand_definedDocs( referredDoc, swagger_hash ))
|
290
|
+
end
|
291
|
+
|
292
|
+
# puts "---> expand_definedDocs-3 = #{expandedDocs} for #{definedDoc}"
|
293
|
+
return expandedDocs
|
294
|
+
end # else not allOf
|
295
|
+
|
296
|
+
end
|
297
|
+
|
298
|
+
# 'properties' holds paramObject { <name>=>{}, <name>=>{}, ...}
|
299
|
+
def definedDocArr2ParamObject( definedDocArr )
|
300
|
+
definedDocArr.map { |e| e['properties'] ? e['properties'] : e }
|
301
|
+
end
|
302
|
+
|
303
|
+
# parameter hash {name: <name>, type:...} paramObject { <name>=>{}, <name>=>{}, ...}
|
304
|
+
def parameter2ParamObject( parameter )
|
305
|
+
return { parameter['name'] =>
|
306
|
+
{
|
307
|
+
"type" => parameter['type'],
|
308
|
+
"format" => parameter['format'],
|
309
|
+
} }
|
310
|
+
end
|
311
|
+
|
312
|
+
|
313
|
+
# get $ref from '$ref' or 'item.$ref'
|
314
|
+
def getRef( paramOrRespSchema )
|
315
|
+
return paramOrRespSchema['$ref'] if paramOrRespSchema['$ref']
|
316
|
+
return paramOrRespSchema['items']['$ref'] if paramOrRespSchema['items'] && paramOrRespSchema['items']['$ref']
|
317
|
+
raise "No ref found in #{paramOrRespSchema}"
|
318
|
+
end
|
319
|
+
|
320
|
+
def getRefDocumentName( paramOrRespSchema )
|
321
|
+
|
322
|
+
|
323
|
+
# --> /definitions/doc
|
324
|
+
ref = getRef( paramOrRespSchema )
|
325
|
+
|
326
|
+
# --> ['definitions', 'doc']
|
327
|
+
arrOfElement = getPathElementFromReference( ref )
|
328
|
+
|
329
|
+
# doc
|
330
|
+
arrOfElement.last
|
331
|
+
|
332
|
+
end
|
333
|
+
|
334
|
+
def hasRef( paramOrRespSchema )
|
335
|
+
return true if paramOrRespSchema['$ref']
|
336
|
+
return true if paramOrRespSchema['items'] && paramOrRespSchema['items']['$ref']
|
337
|
+
return false
|
338
|
+
end
|
339
|
+
|
340
|
+
|
341
|
+
|
342
|
+
# get document pointed by 'ref' in 'swagger_hash'
|
343
|
+
def getDefinitionDoc( ref, swagger_hash )
|
344
|
+
@logger.info( "#{__method__} ref=#{ref}" )
|
345
|
+
|
346
|
+
|
347
|
+
# currently supports only local references
|
348
|
+
raise "Not valid local ref #{ref} in #{schemaObject}" unless valid_local_ref( ref )
|
349
|
+
|
350
|
+
# '#/definitions/doc --> ['definitions', 'doc']
|
351
|
+
pathElements = getPathElementFromReference( ref )
|
352
|
+
|
353
|
+
# puts "pathElements=#{pathElements} for ref=#{ref} in #{refs}"
|
354
|
+
defininedDoc = swagger_hash.traverse( *pathElements )
|
355
|
+
@logger.debug( "#{__method__} ref=#{ref} --> defininedDoc=#{defininedDoc}" )
|
356
|
+
raise "Could not resolve definition reference '#{ref}'" if defininedDoc.nil?
|
357
|
+
defininedDoc
|
358
|
+
end
|
359
|
+
|
360
|
+
# '#/definitions/doc --> ['definitions', 'doc']
|
361
|
+
def getPathElementFromReference( ref )
|
362
|
+
pathElements = ref[2..-1].split( '/' )
|
363
|
+
end
|
364
|
+
|
365
|
+
|
366
|
+
|
367
|
+
# # process one pameter in swagger inferface
|
368
|
+
# def set_paramter_swagger( swagger_hash, paramSet, paramDef )
|
369
|
+
# @logger.debug( "#{__method__} paramSet=#{paramSet}, paramDef=#{paramDef}" )
|
370
|
+
|
371
|
+
# name = getProp( 'name', paramDef )
|
372
|
+
# inType = getProp( 'in', paramDef )
|
373
|
+
|
374
|
+
# if inType == 'body' then
|
375
|
+
# schema_parameter( paramSet, paramDef, swagger_hash )
|
376
|
+
# else
|
377
|
+
# simple_parameter( paramSet, name )
|
378
|
+
# end
|
379
|
+
|
380
|
+
# end
|
381
|
+
|
382
|
+
# process simple (i.e. non body ) parameter
|
383
|
+
def simple_parameter( paramSet, name, parameterType )
|
384
|
+
|
385
|
+
# create parameter object && configure it
|
386
|
+
swagger_parameter = createParameter( Sbuilder::Constants::PARAMETER )
|
387
|
+
swagger_parameter.setName( name )
|
388
|
+
|
389
|
+
# default for parameter 'not array' - set exlicitely array
|
390
|
+
swagger_parameter.setIsArray if parameterType == 'array'
|
391
|
+
|
392
|
+
@logger.info( "#{__method__} param set =#{paramSet.getId}, parameter name=#{swagger_parameter.getName}" )
|
393
|
+
|
394
|
+
# add to parameter set
|
395
|
+
paramSet.addParameter( swagger_parameter )
|
396
|
+
|
397
|
+
end
|
398
|
+
|
399
|
+
# process simple (i.e. non body ) parameter
|
400
|
+
def reference_parameter( paramSet, name, defintionReferenceName, parameterType="string" )
|
401
|
+
|
402
|
+
# create parameter object && configure it
|
403
|
+
swagger_parameter = createParameter( Sbuilder::Constants::PARAMETER_REF )
|
404
|
+
swagger_parameter.setName( name )
|
405
|
+
swagger_parameter.setReference( defintionReferenceName )
|
406
|
+
swagger_parameter.setIsArray if parameterType == 'array'
|
407
|
+
|
408
|
+
@logger.info( "#{__method__} param set =#{paramSet.getId}, parameter=#{swagger_parameter.getName}, parameter=#{swagger_parameter.reference}" )
|
409
|
+
|
410
|
+
# add to parameter set
|
411
|
+
paramSet.addParameter( swagger_parameter )
|
412
|
+
|
413
|
+
end
|
414
|
+
|
415
|
+
|
416
|
+
def valid_local_ref(ref)
|
417
|
+
ref.match(%r{\A#\/})
|
418
|
+
end
|
419
|
+
|
420
|
+
|
421
|
+
|
422
|
+
end # class ResolverLoaderSwagger << ResolverLoader
|
423
|
+
|
424
|
+
end # module Sbuilder
|