hoodoo 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. checksums.yaml +7 -0
  2. data/bin/hoodoo +5 -0
  3. data/lib/hoodoo.rb +27 -0
  4. data/lib/hoodoo/active.rb +32 -0
  5. data/lib/hoodoo/active/active_model/uuid_validator.rb +45 -0
  6. data/lib/hoodoo/active/active_record/base.rb +81 -0
  7. data/lib/hoodoo/active/active_record/creator.rb +134 -0
  8. data/lib/hoodoo/active/active_record/dated.rb +343 -0
  9. data/lib/hoodoo/active/active_record/error_mapping.rb +351 -0
  10. data/lib/hoodoo/active/active_record/finder.rb +606 -0
  11. data/lib/hoodoo/active/active_record/search_helper.rb +189 -0
  12. data/lib/hoodoo/active/active_record/secure.rb +431 -0
  13. data/lib/hoodoo/active/active_record/support.rb +106 -0
  14. data/lib/hoodoo/active/active_record/translated.rb +87 -0
  15. data/lib/hoodoo/active/active_record/uuid.rb +80 -0
  16. data/lib/hoodoo/active/active_record/writer.rb +321 -0
  17. data/lib/hoodoo/client.rb +23 -0
  18. data/lib/hoodoo/client/augmented_array.rb +29 -0
  19. data/lib/hoodoo/client/augmented_base.rb +168 -0
  20. data/lib/hoodoo/client/augmented_hash.rb +23 -0
  21. data/lib/hoodoo/client/client.rb +354 -0
  22. data/lib/hoodoo/client/endpoint/endpoint.rb +427 -0
  23. data/lib/hoodoo/client/endpoint/endpoints/amqp.rb +180 -0
  24. data/lib/hoodoo/client/endpoint/endpoints/auto_session.rb +194 -0
  25. data/lib/hoodoo/client/endpoint/endpoints/http.rb +203 -0
  26. data/lib/hoodoo/client/endpoint/endpoints/http_based.rb +367 -0
  27. data/lib/hoodoo/client/endpoint/endpoints/not_found.rb +59 -0
  28. data/lib/hoodoo/client/headers.rb +269 -0
  29. data/lib/hoodoo/communicators.rb +23 -0
  30. data/lib/hoodoo/communicators/fast.rb +44 -0
  31. data/lib/hoodoo/communicators/pool.rb +601 -0
  32. data/lib/hoodoo/communicators/slow.rb +84 -0
  33. data/lib/hoodoo/data.rb +51 -0
  34. data/lib/hoodoo/data/resources/caller.rb +39 -0
  35. data/lib/hoodoo/data/resources/errors.rb +28 -0
  36. data/lib/hoodoo/data/resources/log.rb +31 -0
  37. data/lib/hoodoo/data/resources/session.rb +26 -0
  38. data/lib/hoodoo/data/types/error_primitive.rb +27 -0
  39. data/lib/hoodoo/data/types/permissions.rb +40 -0
  40. data/lib/hoodoo/data/types/permissions_defaults.rb +32 -0
  41. data/lib/hoodoo/data/types/permissions_full.rb +28 -0
  42. data/lib/hoodoo/data/types/permissions_resources.rb +31 -0
  43. data/lib/hoodoo/discovery.rb +20 -0
  44. data/lib/hoodoo/errors.rb +19 -0
  45. data/lib/hoodoo/errors/error_descriptions.rb +229 -0
  46. data/lib/hoodoo/errors/errors.rb +322 -0
  47. data/lib/hoodoo/generator.rb +139 -0
  48. data/lib/hoodoo/logger.rb +23 -0
  49. data/lib/hoodoo/logger/fast_writer.rb +27 -0
  50. data/lib/hoodoo/logger/flattener_mixin.rb +36 -0
  51. data/lib/hoodoo/logger/logger.rb +387 -0
  52. data/lib/hoodoo/logger/slow_writer.rb +49 -0
  53. data/lib/hoodoo/logger/writer_mixin.rb +52 -0
  54. data/lib/hoodoo/logger/writers/file_writer.rb +45 -0
  55. data/lib/hoodoo/logger/writers/log_entries_dot_com_writer.rb +64 -0
  56. data/lib/hoodoo/logger/writers/stream_writer.rb +43 -0
  57. data/lib/hoodoo/middleware.rb +33 -0
  58. data/lib/hoodoo/presenters.rb +45 -0
  59. data/lib/hoodoo/presenters/base.rb +281 -0
  60. data/lib/hoodoo/presenters/base_dsl.rb +519 -0
  61. data/lib/hoodoo/presenters/common_resource_fields.rb +31 -0
  62. data/lib/hoodoo/presenters/embedding.rb +232 -0
  63. data/lib/hoodoo/presenters/types/array.rb +118 -0
  64. data/lib/hoodoo/presenters/types/boolean.rb +26 -0
  65. data/lib/hoodoo/presenters/types/date.rb +26 -0
  66. data/lib/hoodoo/presenters/types/date_time.rb +26 -0
  67. data/lib/hoodoo/presenters/types/decimal.rb +47 -0
  68. data/lib/hoodoo/presenters/types/enum.rb +55 -0
  69. data/lib/hoodoo/presenters/types/field.rb +158 -0
  70. data/lib/hoodoo/presenters/types/float.rb +26 -0
  71. data/lib/hoodoo/presenters/types/hash.rb +361 -0
  72. data/lib/hoodoo/presenters/types/integer.rb +26 -0
  73. data/lib/hoodoo/presenters/types/object.rb +117 -0
  74. data/lib/hoodoo/presenters/types/string.rb +53 -0
  75. data/lib/hoodoo/presenters/types/tags.rb +24 -0
  76. data/lib/hoodoo/presenters/types/text.rb +26 -0
  77. data/lib/hoodoo/presenters/types/uuid.rb +54 -0
  78. data/lib/hoodoo/services.rb +34 -0
  79. data/lib/hoodoo/services/discovery/discoverers/by_consul.rb +66 -0
  80. data/lib/hoodoo/services/discovery/discoverers/by_convention.rb +173 -0
  81. data/lib/hoodoo/services/discovery/discoverers/by_drb/by_drb.rb +195 -0
  82. data/lib/hoodoo/services/discovery/discoverers/by_drb/drb_server.rb +166 -0
  83. data/lib/hoodoo/services/discovery/discoverers/by_drb/drb_server_start.rb +37 -0
  84. data/lib/hoodoo/services/discovery/discovery.rb +186 -0
  85. data/lib/hoodoo/services/discovery/results/for_amqp.rb +58 -0
  86. data/lib/hoodoo/services/discovery/results/for_http.rb +85 -0
  87. data/lib/hoodoo/services/discovery/results/for_local.rb +85 -0
  88. data/lib/hoodoo/services/discovery/results/for_remote.rb +57 -0
  89. data/lib/hoodoo/services/middleware/amqp_log_message.rb +186 -0
  90. data/lib/hoodoo/services/middleware/amqp_log_writer.rb +119 -0
  91. data/lib/hoodoo/services/middleware/endpoints/inter_resource_local.rb +130 -0
  92. data/lib/hoodoo/services/middleware/endpoints/inter_resource_remote.rb +202 -0
  93. data/lib/hoodoo/services/middleware/exception_reporting/base_reporter.rb +105 -0
  94. data/lib/hoodoo/services/middleware/exception_reporting/exception_reporting.rb +115 -0
  95. data/lib/hoodoo/services/middleware/exception_reporting/reporters/airbrake_reporter.rb +64 -0
  96. data/lib/hoodoo/services/middleware/exception_reporting/reporters/raygun_reporter.rb +63 -0
  97. data/lib/hoodoo/services/middleware/interaction.rb +127 -0
  98. data/lib/hoodoo/services/middleware/middleware.rb +2705 -0
  99. data/lib/hoodoo/services/middleware/rack_monkey_patch.rb +73 -0
  100. data/lib/hoodoo/services/services/context.rb +153 -0
  101. data/lib/hoodoo/services/services/implementation.rb +132 -0
  102. data/lib/hoodoo/services/services/interface.rb +934 -0
  103. data/lib/hoodoo/services/services/permissions.rb +250 -0
  104. data/lib/hoodoo/services/services/request.rb +189 -0
  105. data/lib/hoodoo/services/services/response.rb +316 -0
  106. data/lib/hoodoo/services/services/service.rb +141 -0
  107. data/lib/hoodoo/services/services/session.rb +729 -0
  108. data/lib/hoodoo/utilities.rb +12 -0
  109. data/lib/hoodoo/utilities/string_inquirer.rb +54 -0
  110. data/lib/hoodoo/utilities/utilities.rb +380 -0
  111. data/lib/hoodoo/utilities/uuid.rb +44 -0
  112. data/lib/hoodoo/version.rb +17 -0
  113. data/spec/active/active_record/base_spec.rb +57 -0
  114. data/spec/active/active_record/creator_spec.rb +88 -0
  115. data/spec/active/active_record/dated_spec.rb +248 -0
  116. data/spec/active/active_record/error_mapping_spec.rb +360 -0
  117. data/spec/active/active_record/finder_spec.rb +744 -0
  118. data/spec/active/active_record/search_helper_spec.rb +384 -0
  119. data/spec/active/active_record/secure_spec.rb +435 -0
  120. data/spec/active/active_record/support_spec.rb +225 -0
  121. data/spec/active/active_record/translated_spec.rb +19 -0
  122. data/spec/active/active_record/uuid_spec.rb +72 -0
  123. data/spec/active/active_record/writer_spec.rb +272 -0
  124. data/spec/alchemy/alchemy-amq.rb +33 -0
  125. data/spec/client/augmented_array_spec.rb +15 -0
  126. data/spec/client/augmented_base_spec.rb +50 -0
  127. data/spec/client/augmented_hash_spec.rb +15 -0
  128. data/spec/client/client_spec.rb +955 -0
  129. data/spec/client/endpoint/endpoint_spec.rb +70 -0
  130. data/spec/client/endpoint/endpoints/amqp_spec.rb +16 -0
  131. data/spec/client/endpoint/endpoints/auto_session_spec.rb +9 -0
  132. data/spec/client/endpoint/endpoints/http_based_spec.rb +9 -0
  133. data/spec/client/endpoint/endpoints/http_spec.rb +103 -0
  134. data/spec/client/endpoint/endpoints/not_found_spec.rb +35 -0
  135. data/spec/client/headers_spec.rb +172 -0
  136. data/spec/communicators/fast_spec.rb +9 -0
  137. data/spec/communicators/pool_spec.rb +339 -0
  138. data/spec/communicators/slow_spec.rb +15 -0
  139. data/spec/data/resources/caller_spec.rb +156 -0
  140. data/spec/data/resources/errors_spec.rb +22 -0
  141. data/spec/data/resources/log_spec.rb +20 -0
  142. data/spec/data/resources/session_spec.rb +15 -0
  143. data/spec/data/types/error_primitive_spec.rb +15 -0
  144. data/spec/data/types/permissions_defaults_spec.rb +25 -0
  145. data/spec/data/types/permissions_full_spec.rb +44 -0
  146. data/spec/data/types/permissions_resources_spec.rb +34 -0
  147. data/spec/data/types/permissions_spec.rb +37 -0
  148. data/spec/errors/error_descriptions_spec.rb +98 -0
  149. data/spec/errors/errors_spec.rb +346 -0
  150. data/spec/integration/service_actions_spec.rb +112 -0
  151. data/spec/logger/fast_writer_spec.rb +18 -0
  152. data/spec/logger/logger_spec.rb +259 -0
  153. data/spec/logger/slow_writer_spec.rb +144 -0
  154. data/spec/logger/writers/file_writer_spec.rb +37 -0
  155. data/spec/logger/writers/log_entries_dot_com_writer_spec.rb +29 -0
  156. data/spec/logger/writers/stream_writer_spec.rb +38 -0
  157. data/spec/presenters/base_dsl_spec.rb +111 -0
  158. data/spec/presenters/base_spec.rb +871 -0
  159. data/spec/presenters/common_resource_fields_spec.rb +30 -0
  160. data/spec/presenters/embedding_spec.rb +87 -0
  161. data/spec/presenters/types/array_spec.rb +249 -0
  162. data/spec/presenters/types/boolean_spec.rb +51 -0
  163. data/spec/presenters/types/date_spec.rb +57 -0
  164. data/spec/presenters/types/date_time_spec.rb +59 -0
  165. data/spec/presenters/types/decimal_spec.rb +58 -0
  166. data/spec/presenters/types/enum_spec.rb +71 -0
  167. data/spec/presenters/types/field_spec.rb +77 -0
  168. data/spec/presenters/types/float_spec.rb +50 -0
  169. data/spec/presenters/types/hash_spec.rb +1069 -0
  170. data/spec/presenters/types/integer_spec.rb +50 -0
  171. data/spec/presenters/types/object_spec.rb +177 -0
  172. data/spec/presenters/types/string_spec.rb +65 -0
  173. data/spec/presenters/types/tags_spec.rb +56 -0
  174. data/spec/presenters/types/text_spec.rb +50 -0
  175. data/spec/presenters/types/uuid_spec.rb +46 -0
  176. data/spec/presenters/walk_spec.rb +198 -0
  177. data/spec/services/discovery/discoverers/by_consul_spec.rb +29 -0
  178. data/spec/services/discovery/discoverers/by_convention_spec.rb +67 -0
  179. data/spec/services/discovery/discoverers/by_drb/by_drb_spec.rb +80 -0
  180. data/spec/services/discovery/discoverers/by_drb/drb_server_spec.rb +205 -0
  181. data/spec/services/discovery/discovery_spec.rb +73 -0
  182. data/spec/services/discovery/results/for_amqp_spec.rb +17 -0
  183. data/spec/services/discovery/results/for_http_spec.rb +37 -0
  184. data/spec/services/discovery/results/for_local_spec.rb +21 -0
  185. data/spec/services/discovery/results/for_remote_spec.rb +15 -0
  186. data/spec/services/middleware/amqp_log_message_spec.rb +60 -0
  187. data/spec/services/middleware/amqp_log_writer_spec.rb +95 -0
  188. data/spec/services/middleware/endpoints/inter_resource_local_spec.rb +9 -0
  189. data/spec/services/middleware/endpoints/inter_resource_remote_spec.rb +9 -0
  190. data/spec/services/middleware/exception_reporting/base_reporter_spec.rb +16 -0
  191. data/spec/services/middleware/exception_reporting/exception_reporting_spec.rb +92 -0
  192. data/spec/services/middleware/exception_reporting/reporters/airbrake_reporter_spec.rb +24 -0
  193. data/spec/services/middleware/exception_reporting/reporters/raygun_reporter_spec.rb +23 -0
  194. data/spec/services/middleware/middleware_cors_spec.rb +93 -0
  195. data/spec/services/middleware/middleware_create_update_spec.rb +489 -0
  196. data/spec/services/middleware/middleware_dated_at_spec.rb +186 -0
  197. data/spec/services/middleware/middleware_exotic_communication_spec.rb +560 -0
  198. data/spec/services/middleware/middleware_logging_spec.rb +356 -0
  199. data/spec/services/middleware/middleware_multi_local_spec.rb +1094 -0
  200. data/spec/services/middleware/middleware_multi_remote_spec.rb +1440 -0
  201. data/spec/services/middleware/middleware_permissions_spec.rb +1014 -0
  202. data/spec/services/middleware/middleware_public_spec.rb +238 -0
  203. data/spec/services/middleware/middleware_spec.rb +1569 -0
  204. data/spec/services/middleware/string_inquirer_spec.rb +30 -0
  205. data/spec/services/services/application_spec.rb +74 -0
  206. data/spec/services/services/context_spec.rb +48 -0
  207. data/spec/services/services/implementation_spec.rb +45 -0
  208. data/spec/services/services/interface_spec.rb +262 -0
  209. data/spec/services/services/permissions_spec.rb +249 -0
  210. data/spec/services/services/request_spec.rb +95 -0
  211. data/spec/services/services/response_spec.rb +250 -0
  212. data/spec/services/services/session_spec.rb +432 -0
  213. data/spec/spec_helper.rb +298 -0
  214. data/spec/utilities/utilities_spec.rb +537 -0
  215. data/spec/utilities/uuid_spec.rb +20 -0
  216. metadata +615 -0
@@ -0,0 +1,26 @@
1
+ module Hoodoo
2
+ module Presenters
3
+
4
+ # A JSON Integer schema member.
5
+ #
6
+ class Integer < Hoodoo::Presenters::Field
7
+
8
+ # Check if data is a valid Integer and return a Hoodoo::Errors instance.
9
+ #
10
+ def validate( data, path = '' )
11
+ errors = super( data, path )
12
+ return errors if errors.has_errors? || ( ! @required && data.nil? )
13
+
14
+ unless data.is_a?( ::Integer )
15
+ errors.add_error(
16
+ 'generic.invalid_integer',
17
+ :message => "Field `#{ full_path( path ) }` is an invalid integer",
18
+ :reference => { :field_name => full_path( path ) }
19
+ )
20
+ end
21
+
22
+ errors
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,117 @@
1
+ module Hoodoo
2
+ module Presenters
3
+
4
+ # A JSON Object schema member.
5
+ #
6
+ class Object < Hoodoo::Presenters::Field
7
+
8
+ include Hoodoo::Presenters::BaseDSL
9
+
10
+ # The properties of this object; a Hash of +Field+ instances keyed by
11
+ # field name.
12
+ #
13
+ attr_accessor :properties
14
+
15
+ # Initialize an Object instance with the appropriate name and options.
16
+ #
17
+ # +name+:: The JSON key.
18
+ # +options+:: A +Hash+ of options, e.g. :required => true.
19
+ #
20
+ def initialize( name = nil, options = {} )
21
+ super( name, options )
22
+
23
+ @properties = {}
24
+ @internationalised = false
25
+ end
26
+
27
+ # Check if data is a valid Object and return a Hoodoo::Errors instance
28
+ # with zero (valid) or more (has validation problems) errors inside.
29
+ #
30
+ # +data+:: Data to check (and check nested properties therein). Expected
31
+ # to be nil (unless field is required) or a Hash.
32
+ #
33
+ # +path+:: For internal callers only in theory - the human-readable
34
+ # nesting path to this "level", as an array. Omitted at the top
35
+ # level. In :errors => { :foo => { ... } }, validation of ":foo"
36
+ # would be at path "[ :errors ]". Validation of the contents of
37
+ # the object at ":foo" would be under "[ :errors, :foo ]".
38
+ #
39
+ def validate( data, path = '' )
40
+ errors = super( data, path )
41
+ return errors if !@required and data.nil? # If there are existing errors, we carry on and validate internally too
42
+
43
+ if ! data.nil? && ! data.is_a?( ::Hash )
44
+ errors.add_error(
45
+ 'generic.invalid_object',
46
+ :message => "Field `#{ full_path( path ) }` is an invalid object",
47
+ :reference => { :field_name => full_path( path ) }
48
+ )
49
+ end
50
+
51
+ @properties.each do | name, property |
52
+ rdata = ( data.is_a?( ::Hash ) && data.has_key?( name ) ) ? data[ name ] : nil
53
+ errors.merge!( property.validate( rdata, full_path( path ) ) )
54
+ end
55
+
56
+ errors
57
+ end
58
+
59
+ # Render inbound data into a target hash according to the schema,
60
+ # applying defaults where defined for fields with no value supplied
61
+ # in the inbound data.
62
+ #
63
+ # +data+:: Inbound data to render.
64
+ #
65
+ # +target+:: For internal callers only in theory. The target hash into
66
+ # which rendering should occur. This may then be merged into
67
+ # outer level hashes as part of nested items defined in the
68
+ # schema.
69
+ #
70
+ def render( data, target )
71
+
72
+ # In an simple field, e.g. a text field, then whether or not it has
73
+ # a default, should someone give a value of "nil" we expect that field
74
+ # to be rendered in output with the explicitly provided "nil" value.
75
+ # We thus apply the same to objects. A field with an associated object,
76
+ # if rendered with an explicit "nil", renders as just that.
77
+ #
78
+ return super( nil, target ) unless data.is_a?( ::Hash ) # nil or invalid
79
+
80
+ have_rendered_something = false
81
+
82
+ @properties.each do | name, property |
83
+ name = name.to_s
84
+ has_key = data.has_key?( name )
85
+
86
+ next unless has_key || property.has_default?()
87
+
88
+ have_rendered_something = true
89
+ property.render( has_key ? data[ name ] : property.default, target )
90
+ end
91
+
92
+ # If someone passes an empty object for a field and the object schema
93
+ # includes no default values, then the above code would render nothing
94
+ # as no properties have associated keys in the input data, and none of
95
+ # them have default values either. Make sure we render the field for
96
+ # this object with the associated empty object given by the input data
97
+ # in such cases.
98
+ #
99
+ super( {}, target ) unless have_rendered_something
100
+
101
+ end
102
+
103
+ # Invoke a given block, passing this item; call recursively for any
104
+ # defined sub-fields too. See Hoodoo::Presenters::Base#walk for why.
105
+ #
106
+ # &block:: Mandatory block, which is passed 'self' when called.
107
+ #
108
+ def walk( &block )
109
+ block.call( self )
110
+
111
+ @properties.each do | name, property |
112
+ property.walk( &block )
113
+ end unless @properties.nil?
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,53 @@
1
+ module Hoodoo
2
+ module Presenters
3
+
4
+ # A JSON String schema member.
5
+ #
6
+ class String < Hoodoo::Presenters::Field
7
+
8
+ # The maximum length of the String.
9
+ #
10
+ attr_accessor :length
11
+
12
+ # Initialize a String instance with the appropriate name and options.
13
+ #
14
+ # +name+:: The JSON key.
15
+ # +options+:: A +Hash+ of options, e.g. :required => true, :length => 10.
16
+ #
17
+ def initialize( name, options = {} )
18
+ super( name, options )
19
+
20
+ unless options.has_key?( :length )
21
+ raise ArgumentError.new( 'Hoodoo::Presenters::String must have a :length' )
22
+ end
23
+
24
+ @length = options[ :length ]
25
+ end
26
+
27
+ # Check if data is a valid String and return a Hoodoo::Errors instance.
28
+ #
29
+ def validate( data, path = '' )
30
+ errors = super( data, path )
31
+ return errors if errors.has_errors? || ( ! @required && data.nil? )
32
+
33
+ if data.is_a?( ::String )
34
+ if data.size > @length
35
+ errors.add_error(
36
+ 'generic.invalid_string',
37
+ :message => "Field `#{ full_path( path ) }` is longer than maximum length `#{ @length }`",
38
+ :reference => { :field_name => full_path( path ) }
39
+ )
40
+ end
41
+ else
42
+ errors.add_error(
43
+ 'generic.invalid_string',
44
+ :message => "Field `#{ full_path( path ) }` is an invalid string",
45
+ :reference => { :field_name => full_path( path ) }
46
+ )
47
+ end
48
+
49
+ errors
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,24 @@
1
+ ########################################################################
2
+ # File:: tags.rb
3
+ # (C):: Loyalty New Zealand 2014
4
+ #
5
+ # Purpose:: Hoodoo::Presenters::BaseDSL field implementation
6
+ # which supports a field defined to contain a string of
7
+ # comma separated tags.
8
+ # ----------------------------------------------------------------------
9
+ # 30-Sep-2014 (ADH): Created.
10
+ # 31-Oct-2014 (ADH): Moved to generic presenter layer from
11
+ # documented data layer.
12
+ ########################################################################
13
+
14
+ module Hoodoo
15
+ module Presenters
16
+
17
+ # A JSON string-like schema member intended to hold tag data.
18
+ #
19
+ class Tags < Hoodoo::Presenters::Text
20
+ # TODO: Note inheritance from "...::Text" not "...::Field"
21
+ # TODO: Future validations to ensure string looks tag-like?
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ module Hoodoo
2
+ module Presenters
3
+
4
+ # A JSON String schema member - unlimited length String.
5
+ #
6
+ class Text < Hoodoo::Presenters::Field
7
+
8
+ # Check if data is a valid String and return a Hoodoo::Errors instance.
9
+ #
10
+ def validate( data, path = '' )
11
+ errors = super( data, path )
12
+ return errors if errors.has_errors? || ( ! @required && data.nil? )
13
+
14
+ unless data.is_a?( ::String )
15
+ errors.add_error(
16
+ 'generic.invalid_string',
17
+ :message => "Field `#{ full_path( path ) }` is an invalid string",
18
+ :reference => { :field_name => full_path( path ) }
19
+ )
20
+ end
21
+
22
+ errors
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,54 @@
1
+ ########################################################################
2
+ # File:: documented_uuid.rb
3
+ # (C):: Loyalty New Zealand 2014
4
+ #
5
+ # Purpose:: Hoodoo::Presenters::BaseDSL field implementation
6
+ # which supports a field defined to contain a UUID that
7
+ # (optionally) can be verified as referring to a specific
8
+ # other Resource.
9
+ # ----------------------------------------------------------------------
10
+ # 22-Sep-2014 (ADH): Created.
11
+ # 31-Oct-2014 (ADH): Moved to generic presenter layer from
12
+ # documented data layer.
13
+ ########################################################################
14
+
15
+ module Hoodoo
16
+ module Presenters
17
+
18
+ # A JSON UUID schema member.
19
+ #
20
+ class UUID < Hoodoo::Presenters::Field
21
+
22
+ # The optional associated resource kind, as a symbol (e.g. ':Product').
23
+ #
24
+ attr_accessor :resource
25
+
26
+ # Initialize a UUID instance with the appropriate name and options.
27
+ #
28
+ # +name+:: The JSON key.
29
+ # +options+:: A +Hash+ of options, e.g. :resource => :Product, :required => true.
30
+ #
31
+ def initialize( name, options = {} )
32
+ @resource = options.delete( :resource )
33
+ super name, options
34
+ end
35
+
36
+ # Check if data is a valid UUID and return a Hoodoo::Errors instance.
37
+ #
38
+ def validate( data, path = '' )
39
+ errors = super( data, path )
40
+ return errors if errors.has_errors? || ( ! @required && data.nil? )
41
+
42
+ unless Hoodoo::UUID.valid?( data )
43
+ errors.add_error(
44
+ 'generic.invalid_uuid',
45
+ :message => "Field `#{ full_path( path ) }` is an invalid UUID",
46
+ :reference => { :field_name => full_path( path ) }
47
+ )
48
+ end
49
+
50
+ errors
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,34 @@
1
+ ########################################################################
2
+ # File:: services.rb
3
+ # (C):: Loyalty New Zealand 2014
4
+ #
5
+ # Purpose:: Include code useful to client service applications.
6
+ # ----------------------------------------------------------------------
7
+ # 26-Jan-2015 (ADH): Split from top-level inclusion file.
8
+ ########################################################################
9
+
10
+ module Hoodoo
11
+
12
+ # Module providing a namespace for code useful to client service
13
+ # applications and the supporting middleware.
14
+ #
15
+ module Services
16
+ end
17
+ end
18
+
19
+ # Dependencies
20
+
21
+ require 'hoodoo/utilities'
22
+ require 'hoodoo/logger'
23
+
24
+ # Services
25
+
26
+ require 'hoodoo/services/services/permissions'
27
+ require 'hoodoo/services/services/session'
28
+ require 'hoodoo/services/services/session'
29
+ require 'hoodoo/services/services/request'
30
+ require 'hoodoo/services/services/response'
31
+ require 'hoodoo/services/services/context'
32
+ require 'hoodoo/services/services/interface'
33
+ require 'hoodoo/services/services/implementation'
34
+ require 'hoodoo/services/services/service'
@@ -0,0 +1,66 @@
1
+ ########################################################################
2
+ # File:: by_consul.rb
3
+ # (C):: Loyalty New Zealand 2015
4
+ #
5
+ # Purpose:: Discover resource endpoint locations via a registry held in
6
+ # Consul. For AMQP-based endpoints; maps paths to queue names.
7
+ # PLACEHOLDER: NOT YET IMPLEMENTED.
8
+ # ----------------------------------------------------------------------
9
+ # 03-Mar-2015 (ADH): Created.
10
+ ########################################################################
11
+
12
+ module Hoodoo
13
+ module Services
14
+ class Discovery # Just used as a namespace here
15
+
16
+ # Discover resource endpoint locations via a registry held in
17
+ # Consul. For AMQP-based endpoints; maps paths to queue names.
18
+ #
19
+ class ByConsul < Hoodoo::Services::Discovery
20
+
21
+ protected
22
+
23
+ # Announce the location of an instance to Consul.
24
+ #
25
+ # Call via Hoodoo::Services::Discovery::Base#announce.
26
+ #
27
+ # TODO: NOT YET IMPLEMENTED. Placeholder only.
28
+ #
29
+ # +resource+:: Passed to #discover_remote.
30
+ # +version+:: Passed to #discover_remote.
31
+ # +options+:: Ignored. TODO: Queue name, equivalent path.
32
+ #
33
+ def announce_remote( resource, version, options = {} )
34
+ return discover_remote( resource, version ) # TODO: Replace
35
+ end
36
+
37
+ # Discover the location of an instance using Consul.
38
+ #
39
+ # TODO: This currently doesn't use Consul at all! It has a
40
+ # TODO: hard-coded mapping.
41
+ #
42
+ # Returns a Hoodoo::Services::Discovery::ForAMQP instance if
43
+ # the endpoint is found, else +nil+.
44
+ #
45
+ # Call via Hoodoo::Services::Discovery::Base#announce.
46
+ #
47
+ # +resource+:: Passed to #discover_remote.
48
+ # +version+:: Passed to #discover_remote.
49
+ #
50
+ def discover_remote( resource, version )
51
+
52
+ queue = "service.#{ resource.to_s.downcase }"
53
+ path = "/v#{ version }/#{ resource.to_s.downcase.pluralize }"
54
+
55
+ return Hoodoo::Services::Discovery::ForAMQP.new(
56
+ resource: resource,
57
+ version: version,
58
+ queue_name: queue,
59
+ equivalent_path: path
60
+ )
61
+ end
62
+
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,173 @@
1
+ ########################################################################
2
+ # File:: by_convention.rb
3
+ # (C):: Loyalty New Zealand 2015
4
+ #
5
+ # Purpose:: Discover - after a fashion - resource endpoint locations
6
+ # by convention, based on Rails-like pluralisation rules. For
7
+ # HTTP-based endpoints. Requires ActiveSupport.
8
+ # ----------------------------------------------------------------------
9
+ # 03-Mar-2015 (ADH): Created.
10
+ ########################################################################
11
+
12
+ module Hoodoo
13
+ module Services
14
+ class Discovery # Just used as a namespace here
15
+
16
+ begin
17
+ require 'active_support/inflector'
18
+
19
+ # Discover - after a fashion - resource endpoint locations
20
+ # by convention, based on Rails-like pluralisation rules. For
21
+ # HTTP-based endpoints. Requires ActiveSupport.
22
+ #
23
+ # https://rubygems.org/gems/activesupport
24
+ #
25
+ # See #configure_with for details of required instantiation
26
+ # options. See #discover_remote for the returned data type.
27
+ #
28
+ class ByConvention < Hoodoo::Services::Discovery
29
+
30
+ protected
31
+
32
+ # Configure an instance. Call via
33
+ # Hoodoo::Services::Discovery::Base#new. Parameters:
34
+ #
35
+ # +options+:: Options hash as described below.
36
+ #
37
+ # Options are:
38
+ #
39
+ # +base_uri+:: A String giving the base URI at which resource
40
+ # endpoint implementations can be found. The
41
+ # protocol (HTTP or HTTPS), host and port are of
42
+ # interest. The path will be overwritten with
43
+ # by-convention values for individual resources.
44
+ #
45
+ # +proxy_uri+:: An optional full URI of an HTTP proxy to use if
46
+ # the base URI commands use of HTTP or HTTPS. Ruby
47
+ # will itself read <tt>ENV['HTTP_PROXY']</tt> if
48
+ # set; this option will _override_ that variable.
49
+ # Set as a String, as with +base_uri+.
50
+ #
51
+ # +ca_file+:: An optional String indicating a relative or
52
+ # absolute file path to the location of a +.pem+
53
+ # format Certificate Authority file (trust store),
54
+ # which may include multliple certificates. The
55
+ # certificates in the file will be used by
56
+ # Net::HTTP to validate the SSL ceritificate
57
+ # chain presented by remote servers, when calling
58
+ # endpoints over HTTPS with Hoodoo::Client.
59
+ #
60
+ # Default +nil+ value should be used in nearly all
61
+ # cases and uses Ruby OpenSSL defaults which are
62
+ # generally Operating System provided.
63
+ #
64
+ # +http_timeout+:: Optional Float indicating the Net::HTTP read
65
+ # timeout value. This operates at the HTTP
66
+ # transport level and is independent of any
67
+ # timeouts set within the API providing server.
68
+ #
69
+ # +routing+:: An optional parameter which gives custom routing
70
+ # for exception cases where the by-convention map
71
+ # doesn't work. This is usually because there is a
72
+ # resource singleton which lives logically at a
73
+ # singular named route rather than plural route,
74
+ # e.g. "/v1/health" rather than "/v1/healths".
75
+ #
76
+ # The +routing+ parameter is a Hash of Resource names _as_
77
+ # _Symbols_, then values which are Hash of API Version _as_
78
+ # _Integers_ with values that are the Strings giving the
79
+ # full alternative routing path.
80
+ #
81
+ # For example, by convention API version 2 of a Health resource
82
+ # would be routed to "/v2/healths". You would override this to a
83
+ # singular route with this +routing+ parameter Hash:
84
+ #
85
+ # {
86
+ # :Health => {
87
+ # 2 => '/v2/health'
88
+ # }
89
+ # }
90
+ #
91
+ # This would leave version 1 of the endpoint (or any other version
92
+ # for that matter) still at the by-convention "v<x>/healths" path.
93
+ #
94
+ # Changing the "v<x>" convention for the version part of the path
95
+ # will break Hoodoo compatibility, but this is still allowed in
96
+ # the override in case you have unusual configurations or HTTP
97
+ # layer rewrites that redirect requests to paths that do map down
98
+ # to Hoodoo, or perhaps map to a Hoodoo-like system that's not
99
+ # actually Hoodoo itself but implemented in a compatible fashion.
100
+ #
101
+ def configure_with( options )
102
+ @base_uri = URI.parse( options[ :base_uri ] )
103
+ @proxy_uri = URI.parse( options[ :proxy_uri ] ) unless options[ :proxy_uri ].nil?
104
+ @ca_file = options[ :ca_file ]
105
+ @http_timeout = options[ :http_timeout ]
106
+ @routing = options[ :routing ] || {}
107
+ end
108
+
109
+ # Announce the location of an instance. This is really a no-op
110
+ # that runs through and returns the result of #discover_remote.
111
+ #
112
+ # Call via Hoodoo::Services::Discovery::Base#announce.
113
+ #
114
+ # +resource+:: Passed to #discover_remote.
115
+ # +version+:: Passed to #discover_remote.
116
+ # +options+:: Ignored.
117
+ #
118
+ def announce_remote( resource, version, options = {} )
119
+ return discover_remote( resource, version )
120
+ end
121
+
122
+ # Using the base URI string from the options in configure_with,
123
+ # underscore and pluralize the resource name with ActiveSupport
124
+ # to produce a path. For example:
125
+ #
126
+ # * Version 3 of resource Member results in
127
+ # <tt>/v3/members</tt>
128
+ #
129
+ # * Version 2 of resource FarmAnimal results in
130
+ # <tt>/v2/farm_animals</tt>
131
+ #
132
+ # Returns a Hoodoo::Services::Discovery::ForHTTP instance.
133
+ #
134
+ # The use of ActiveSupport means that pluralisation is subject to
135
+ # the well known Rails limitations and quirks. The behaviour can
136
+ # be overridden using the optional +routing+ parameter in the
137
+ # constructor.
138
+ #
139
+ # Call via Hoodoo::Services::Discovery::Base#discover.
140
+ #
141
+ # +resource+:: Resource name as a _String_.
142
+ # +version+:: Endpoint version as an Integer.
143
+ #
144
+ def discover_remote( resource, version )
145
+ custom_routes = @routing[ resource.to_sym ]
146
+
147
+ path = unless custom_routes.nil?
148
+ custom_routes[ version ]
149
+ end
150
+
151
+ path ||= "/v#{ version }/#{ resource.to_s.underscore.pluralize }"
152
+
153
+ endpoint_uri = @base_uri.dup
154
+ endpoint_uri.path = path
155
+
156
+ return Hoodoo::Services::Discovery::ForHTTP.new(
157
+ resource: resource,
158
+ version: version,
159
+ endpoint_uri: endpoint_uri,
160
+ proxy_uri: @proxy_uri,
161
+ ca_file: @ca_file,
162
+ http_timeout: @http_timeout
163
+ )
164
+ end
165
+
166
+ end
167
+
168
+ rescue LoadError
169
+ end
170
+
171
+ end
172
+ end
173
+ end