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.
- checksums.yaml +7 -0
- data/bin/hoodoo +5 -0
- data/lib/hoodoo.rb +27 -0
- data/lib/hoodoo/active.rb +32 -0
- data/lib/hoodoo/active/active_model/uuid_validator.rb +45 -0
- data/lib/hoodoo/active/active_record/base.rb +81 -0
- data/lib/hoodoo/active/active_record/creator.rb +134 -0
- data/lib/hoodoo/active/active_record/dated.rb +343 -0
- data/lib/hoodoo/active/active_record/error_mapping.rb +351 -0
- data/lib/hoodoo/active/active_record/finder.rb +606 -0
- data/lib/hoodoo/active/active_record/search_helper.rb +189 -0
- data/lib/hoodoo/active/active_record/secure.rb +431 -0
- data/lib/hoodoo/active/active_record/support.rb +106 -0
- data/lib/hoodoo/active/active_record/translated.rb +87 -0
- data/lib/hoodoo/active/active_record/uuid.rb +80 -0
- data/lib/hoodoo/active/active_record/writer.rb +321 -0
- data/lib/hoodoo/client.rb +23 -0
- data/lib/hoodoo/client/augmented_array.rb +29 -0
- data/lib/hoodoo/client/augmented_base.rb +168 -0
- data/lib/hoodoo/client/augmented_hash.rb +23 -0
- data/lib/hoodoo/client/client.rb +354 -0
- data/lib/hoodoo/client/endpoint/endpoint.rb +427 -0
- data/lib/hoodoo/client/endpoint/endpoints/amqp.rb +180 -0
- data/lib/hoodoo/client/endpoint/endpoints/auto_session.rb +194 -0
- data/lib/hoodoo/client/endpoint/endpoints/http.rb +203 -0
- data/lib/hoodoo/client/endpoint/endpoints/http_based.rb +367 -0
- data/lib/hoodoo/client/endpoint/endpoints/not_found.rb +59 -0
- data/lib/hoodoo/client/headers.rb +269 -0
- data/lib/hoodoo/communicators.rb +23 -0
- data/lib/hoodoo/communicators/fast.rb +44 -0
- data/lib/hoodoo/communicators/pool.rb +601 -0
- data/lib/hoodoo/communicators/slow.rb +84 -0
- data/lib/hoodoo/data.rb +51 -0
- data/lib/hoodoo/data/resources/caller.rb +39 -0
- data/lib/hoodoo/data/resources/errors.rb +28 -0
- data/lib/hoodoo/data/resources/log.rb +31 -0
- data/lib/hoodoo/data/resources/session.rb +26 -0
- data/lib/hoodoo/data/types/error_primitive.rb +27 -0
- data/lib/hoodoo/data/types/permissions.rb +40 -0
- data/lib/hoodoo/data/types/permissions_defaults.rb +32 -0
- data/lib/hoodoo/data/types/permissions_full.rb +28 -0
- data/lib/hoodoo/data/types/permissions_resources.rb +31 -0
- data/lib/hoodoo/discovery.rb +20 -0
- data/lib/hoodoo/errors.rb +19 -0
- data/lib/hoodoo/errors/error_descriptions.rb +229 -0
- data/lib/hoodoo/errors/errors.rb +322 -0
- data/lib/hoodoo/generator.rb +139 -0
- data/lib/hoodoo/logger.rb +23 -0
- data/lib/hoodoo/logger/fast_writer.rb +27 -0
- data/lib/hoodoo/logger/flattener_mixin.rb +36 -0
- data/lib/hoodoo/logger/logger.rb +387 -0
- data/lib/hoodoo/logger/slow_writer.rb +49 -0
- data/lib/hoodoo/logger/writer_mixin.rb +52 -0
- data/lib/hoodoo/logger/writers/file_writer.rb +45 -0
- data/lib/hoodoo/logger/writers/log_entries_dot_com_writer.rb +64 -0
- data/lib/hoodoo/logger/writers/stream_writer.rb +43 -0
- data/lib/hoodoo/middleware.rb +33 -0
- data/lib/hoodoo/presenters.rb +45 -0
- data/lib/hoodoo/presenters/base.rb +281 -0
- data/lib/hoodoo/presenters/base_dsl.rb +519 -0
- data/lib/hoodoo/presenters/common_resource_fields.rb +31 -0
- data/lib/hoodoo/presenters/embedding.rb +232 -0
- data/lib/hoodoo/presenters/types/array.rb +118 -0
- data/lib/hoodoo/presenters/types/boolean.rb +26 -0
- data/lib/hoodoo/presenters/types/date.rb +26 -0
- data/lib/hoodoo/presenters/types/date_time.rb +26 -0
- data/lib/hoodoo/presenters/types/decimal.rb +47 -0
- data/lib/hoodoo/presenters/types/enum.rb +55 -0
- data/lib/hoodoo/presenters/types/field.rb +158 -0
- data/lib/hoodoo/presenters/types/float.rb +26 -0
- data/lib/hoodoo/presenters/types/hash.rb +361 -0
- data/lib/hoodoo/presenters/types/integer.rb +26 -0
- data/lib/hoodoo/presenters/types/object.rb +117 -0
- data/lib/hoodoo/presenters/types/string.rb +53 -0
- data/lib/hoodoo/presenters/types/tags.rb +24 -0
- data/lib/hoodoo/presenters/types/text.rb +26 -0
- data/lib/hoodoo/presenters/types/uuid.rb +54 -0
- data/lib/hoodoo/services.rb +34 -0
- data/lib/hoodoo/services/discovery/discoverers/by_consul.rb +66 -0
- data/lib/hoodoo/services/discovery/discoverers/by_convention.rb +173 -0
- data/lib/hoodoo/services/discovery/discoverers/by_drb/by_drb.rb +195 -0
- data/lib/hoodoo/services/discovery/discoverers/by_drb/drb_server.rb +166 -0
- data/lib/hoodoo/services/discovery/discoverers/by_drb/drb_server_start.rb +37 -0
- data/lib/hoodoo/services/discovery/discovery.rb +186 -0
- data/lib/hoodoo/services/discovery/results/for_amqp.rb +58 -0
- data/lib/hoodoo/services/discovery/results/for_http.rb +85 -0
- data/lib/hoodoo/services/discovery/results/for_local.rb +85 -0
- data/lib/hoodoo/services/discovery/results/for_remote.rb +57 -0
- data/lib/hoodoo/services/middleware/amqp_log_message.rb +186 -0
- data/lib/hoodoo/services/middleware/amqp_log_writer.rb +119 -0
- data/lib/hoodoo/services/middleware/endpoints/inter_resource_local.rb +130 -0
- data/lib/hoodoo/services/middleware/endpoints/inter_resource_remote.rb +202 -0
- data/lib/hoodoo/services/middleware/exception_reporting/base_reporter.rb +105 -0
- data/lib/hoodoo/services/middleware/exception_reporting/exception_reporting.rb +115 -0
- data/lib/hoodoo/services/middleware/exception_reporting/reporters/airbrake_reporter.rb +64 -0
- data/lib/hoodoo/services/middleware/exception_reporting/reporters/raygun_reporter.rb +63 -0
- data/lib/hoodoo/services/middleware/interaction.rb +127 -0
- data/lib/hoodoo/services/middleware/middleware.rb +2705 -0
- data/lib/hoodoo/services/middleware/rack_monkey_patch.rb +73 -0
- data/lib/hoodoo/services/services/context.rb +153 -0
- data/lib/hoodoo/services/services/implementation.rb +132 -0
- data/lib/hoodoo/services/services/interface.rb +934 -0
- data/lib/hoodoo/services/services/permissions.rb +250 -0
- data/lib/hoodoo/services/services/request.rb +189 -0
- data/lib/hoodoo/services/services/response.rb +316 -0
- data/lib/hoodoo/services/services/service.rb +141 -0
- data/lib/hoodoo/services/services/session.rb +729 -0
- data/lib/hoodoo/utilities.rb +12 -0
- data/lib/hoodoo/utilities/string_inquirer.rb +54 -0
- data/lib/hoodoo/utilities/utilities.rb +380 -0
- data/lib/hoodoo/utilities/uuid.rb +44 -0
- data/lib/hoodoo/version.rb +17 -0
- data/spec/active/active_record/base_spec.rb +57 -0
- data/spec/active/active_record/creator_spec.rb +88 -0
- data/spec/active/active_record/dated_spec.rb +248 -0
- data/spec/active/active_record/error_mapping_spec.rb +360 -0
- data/spec/active/active_record/finder_spec.rb +744 -0
- data/spec/active/active_record/search_helper_spec.rb +384 -0
- data/spec/active/active_record/secure_spec.rb +435 -0
- data/spec/active/active_record/support_spec.rb +225 -0
- data/spec/active/active_record/translated_spec.rb +19 -0
- data/spec/active/active_record/uuid_spec.rb +72 -0
- data/spec/active/active_record/writer_spec.rb +272 -0
- data/spec/alchemy/alchemy-amq.rb +33 -0
- data/spec/client/augmented_array_spec.rb +15 -0
- data/spec/client/augmented_base_spec.rb +50 -0
- data/spec/client/augmented_hash_spec.rb +15 -0
- data/spec/client/client_spec.rb +955 -0
- data/spec/client/endpoint/endpoint_spec.rb +70 -0
- data/spec/client/endpoint/endpoints/amqp_spec.rb +16 -0
- data/spec/client/endpoint/endpoints/auto_session_spec.rb +9 -0
- data/spec/client/endpoint/endpoints/http_based_spec.rb +9 -0
- data/spec/client/endpoint/endpoints/http_spec.rb +103 -0
- data/spec/client/endpoint/endpoints/not_found_spec.rb +35 -0
- data/spec/client/headers_spec.rb +172 -0
- data/spec/communicators/fast_spec.rb +9 -0
- data/spec/communicators/pool_spec.rb +339 -0
- data/spec/communicators/slow_spec.rb +15 -0
- data/spec/data/resources/caller_spec.rb +156 -0
- data/spec/data/resources/errors_spec.rb +22 -0
- data/spec/data/resources/log_spec.rb +20 -0
- data/spec/data/resources/session_spec.rb +15 -0
- data/spec/data/types/error_primitive_spec.rb +15 -0
- data/spec/data/types/permissions_defaults_spec.rb +25 -0
- data/spec/data/types/permissions_full_spec.rb +44 -0
- data/spec/data/types/permissions_resources_spec.rb +34 -0
- data/spec/data/types/permissions_spec.rb +37 -0
- data/spec/errors/error_descriptions_spec.rb +98 -0
- data/spec/errors/errors_spec.rb +346 -0
- data/spec/integration/service_actions_spec.rb +112 -0
- data/spec/logger/fast_writer_spec.rb +18 -0
- data/spec/logger/logger_spec.rb +259 -0
- data/spec/logger/slow_writer_spec.rb +144 -0
- data/spec/logger/writers/file_writer_spec.rb +37 -0
- data/spec/logger/writers/log_entries_dot_com_writer_spec.rb +29 -0
- data/spec/logger/writers/stream_writer_spec.rb +38 -0
- data/spec/presenters/base_dsl_spec.rb +111 -0
- data/spec/presenters/base_spec.rb +871 -0
- data/spec/presenters/common_resource_fields_spec.rb +30 -0
- data/spec/presenters/embedding_spec.rb +87 -0
- data/spec/presenters/types/array_spec.rb +249 -0
- data/spec/presenters/types/boolean_spec.rb +51 -0
- data/spec/presenters/types/date_spec.rb +57 -0
- data/spec/presenters/types/date_time_spec.rb +59 -0
- data/spec/presenters/types/decimal_spec.rb +58 -0
- data/spec/presenters/types/enum_spec.rb +71 -0
- data/spec/presenters/types/field_spec.rb +77 -0
- data/spec/presenters/types/float_spec.rb +50 -0
- data/spec/presenters/types/hash_spec.rb +1069 -0
- data/spec/presenters/types/integer_spec.rb +50 -0
- data/spec/presenters/types/object_spec.rb +177 -0
- data/spec/presenters/types/string_spec.rb +65 -0
- data/spec/presenters/types/tags_spec.rb +56 -0
- data/spec/presenters/types/text_spec.rb +50 -0
- data/spec/presenters/types/uuid_spec.rb +46 -0
- data/spec/presenters/walk_spec.rb +198 -0
- data/spec/services/discovery/discoverers/by_consul_spec.rb +29 -0
- data/spec/services/discovery/discoverers/by_convention_spec.rb +67 -0
- data/spec/services/discovery/discoverers/by_drb/by_drb_spec.rb +80 -0
- data/spec/services/discovery/discoverers/by_drb/drb_server_spec.rb +205 -0
- data/spec/services/discovery/discovery_spec.rb +73 -0
- data/spec/services/discovery/results/for_amqp_spec.rb +17 -0
- data/spec/services/discovery/results/for_http_spec.rb +37 -0
- data/spec/services/discovery/results/for_local_spec.rb +21 -0
- data/spec/services/discovery/results/for_remote_spec.rb +15 -0
- data/spec/services/middleware/amqp_log_message_spec.rb +60 -0
- data/spec/services/middleware/amqp_log_writer_spec.rb +95 -0
- data/spec/services/middleware/endpoints/inter_resource_local_spec.rb +9 -0
- data/spec/services/middleware/endpoints/inter_resource_remote_spec.rb +9 -0
- data/spec/services/middleware/exception_reporting/base_reporter_spec.rb +16 -0
- data/spec/services/middleware/exception_reporting/exception_reporting_spec.rb +92 -0
- data/spec/services/middleware/exception_reporting/reporters/airbrake_reporter_spec.rb +24 -0
- data/spec/services/middleware/exception_reporting/reporters/raygun_reporter_spec.rb +23 -0
- data/spec/services/middleware/middleware_cors_spec.rb +93 -0
- data/spec/services/middleware/middleware_create_update_spec.rb +489 -0
- data/spec/services/middleware/middleware_dated_at_spec.rb +186 -0
- data/spec/services/middleware/middleware_exotic_communication_spec.rb +560 -0
- data/spec/services/middleware/middleware_logging_spec.rb +356 -0
- data/spec/services/middleware/middleware_multi_local_spec.rb +1094 -0
- data/spec/services/middleware/middleware_multi_remote_spec.rb +1440 -0
- data/spec/services/middleware/middleware_permissions_spec.rb +1014 -0
- data/spec/services/middleware/middleware_public_spec.rb +238 -0
- data/spec/services/middleware/middleware_spec.rb +1569 -0
- data/spec/services/middleware/string_inquirer_spec.rb +30 -0
- data/spec/services/services/application_spec.rb +74 -0
- data/spec/services/services/context_spec.rb +48 -0
- data/spec/services/services/implementation_spec.rb +45 -0
- data/spec/services/services/interface_spec.rb +262 -0
- data/spec/services/services/permissions_spec.rb +249 -0
- data/spec/services/services/request_spec.rb +95 -0
- data/spec/services/services/response_spec.rb +250 -0
- data/spec/services/services/session_spec.rb +432 -0
- data/spec/spec_helper.rb +298 -0
- data/spec/utilities/utilities_spec.rb +537 -0
- data/spec/utilities/uuid_spec.rb +20 -0
- metadata +615 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
########################################################################
|
2
|
+
# File:: common_resource_fields.rb
|
3
|
+
# (C):: Loyalty New Zealand 2014
|
4
|
+
#
|
5
|
+
# Purpose:: Define a schema describing fields common to any schema that
|
6
|
+
# describes an API Resource.
|
7
|
+
# ----------------------------------------------------------------------
|
8
|
+
# 02-Dec-2014 (ADH): Split from DocumentedPresenter.
|
9
|
+
########################################################################
|
10
|
+
|
11
|
+
module Hoodoo
|
12
|
+
module Presenters
|
13
|
+
|
14
|
+
# Used internally for additional validation of common Resource fields.
|
15
|
+
# See Hoodoo::Presenters::Base::validate.
|
16
|
+
#
|
17
|
+
class CommonResourceFields < Hoodoo::Presenters::Base
|
18
|
+
schema do
|
19
|
+
uuid :id, :required => true
|
20
|
+
datetime :created_at, :required => true
|
21
|
+
text :kind, :required => true
|
22
|
+
text :language
|
23
|
+
|
24
|
+
hash :secured_with
|
25
|
+
|
26
|
+
hash :_embed
|
27
|
+
hash :_reference
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,232 @@
|
|
1
|
+
########################################################################
|
2
|
+
# File:: embedding.rb
|
3
|
+
# (C):: Loyalty New Zealand 2015
|
4
|
+
#
|
5
|
+
# Purpose:: Light weight, simple support for basic embed and reference
|
6
|
+
# operations that help reduce service reliance on "knowing"
|
7
|
+
# exactly how to structure such data / avoid inconsistency.
|
8
|
+
# ----------------------------------------------------------------------
|
9
|
+
# 29-Apr-2015 (ADH): Created.
|
10
|
+
########################################################################
|
11
|
+
|
12
|
+
module Hoodoo
|
13
|
+
module Presenters
|
14
|
+
|
15
|
+
# The Embedding namespace collects classes that assist with rendering
|
16
|
+
# embedded resource data.
|
17
|
+
#
|
18
|
+
module Embedding
|
19
|
+
|
20
|
+
# The Embeddable base class should not be instantiated directly.
|
21
|
+
# It provides common functionality for
|
22
|
+
# Hoodoo::Presenters::Embedding::Embeds and
|
23
|
+
# Hoodoo::Presenters::Embedding::References - use those instead.
|
24
|
+
#
|
25
|
+
class Embeddable
|
26
|
+
|
27
|
+
# Create an instance.
|
28
|
+
#
|
29
|
+
def initialize
|
30
|
+
@hash = {}
|
31
|
+
end
|
32
|
+
|
33
|
+
# Add a singlular resource (for embedding) or UUID (for referencing)
|
34
|
+
# to an embed or reference assembly.
|
35
|
+
#
|
36
|
+
# +key+:: The key to use in the resource representation leading to
|
37
|
+
# the embedded resource object or UUID string. Typically
|
38
|
+
# follows a singular name convention in your resource API
|
39
|
+
# field language of choice, e.g. "member" (an API where the
|
40
|
+
# resource names and fields are in English), "mitglied" (an
|
41
|
+
# API described in German).
|
42
|
+
#
|
43
|
+
# This key must match the value specified in the query string
|
44
|
+
# of a request in order to ask for the thing in question to
|
45
|
+
# be embedded / referenced.
|
46
|
+
#
|
47
|
+
# +rendered_resource_or_uuid+:: A rendered resource representation
|
48
|
+
# in full, or a resource UUID String.
|
49
|
+
#
|
50
|
+
def add_one( key, rendered_resource_or_uuid )
|
51
|
+
validate_one( rendered_resource_or_uuid )
|
52
|
+
@hash[ key ] = rendered_resource_or_uuid
|
53
|
+
end
|
54
|
+
|
55
|
+
# Add a collection of resources (for embedding) or UUIDs (for
|
56
|
+
# referencing) to an embed or reference assembly.
|
57
|
+
#
|
58
|
+
# +key+:: The key to use in the resource representation leading to
|
59
|
+
# the embedded resource object or UUID string array. Typically
|
60
|
+
# follows a plural name convention in your resource API field
|
61
|
+
# language of choice, e.g. "members" (an API where the
|
62
|
+
# resource names and fields are in English), "mitglieder" (an
|
63
|
+
# API described in German).
|
64
|
+
#
|
65
|
+
# This key must match the value specified in the query string
|
66
|
+
# of a request in order to ask for the things in question to
|
67
|
+
# be embedded / referenced.
|
68
|
+
#
|
69
|
+
# +array_of_rendered_resources_or_uuids+::
|
70
|
+
# An Array of rendered resource representations in full, or an
|
71
|
+
# Array of resource UUID Strings.
|
72
|
+
#
|
73
|
+
def add_many( key, array_of_rendered_resources_or_uuids )
|
74
|
+
validate_many( array_of_rendered_resources_or_uuids )
|
75
|
+
@hash[ key ] = array_of_rendered_resources_or_uuids
|
76
|
+
end
|
77
|
+
|
78
|
+
# Delete all data associated with the given key.
|
79
|
+
#
|
80
|
+
# +key+:: As provided to a prior call to #add_one or #add_many. Has no
|
81
|
+
# side effects if the key has not been previously used in such
|
82
|
+
# a call; no error is raised in this case either.
|
83
|
+
#
|
84
|
+
def remove( key )
|
85
|
+
@hash.delete( key )
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns a Hash where keys are the keys provided in calls to #add_one
|
89
|
+
# or #add_many and values are the values provided to those same
|
90
|
+
# corresponding calls. Returns an empty Hash if no such calls have
|
91
|
+
# been made or if all the keys were subsequently removed with #remove.
|
92
|
+
#
|
93
|
+
def retrieve
|
94
|
+
@hash
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Instantiate this class and add one, or an Array of fully rendered
|
99
|
+
# resource objects to it via the API described in the base class,
|
100
|
+
# Hoodoo::Presenters::Embedding::Embeddable. You can then pass it to
|
101
|
+
# the likes of Hoodoo::Presenters::Base.render_in via the +options+
|
102
|
+
# parameter to have the embed data included in the fully rendered end
|
103
|
+
# result.
|
104
|
+
#
|
105
|
+
# When a request arrives to embed data for a particular resource or
|
106
|
+
# list of resources (in which case, do the following for each item in
|
107
|
+
# that list):
|
108
|
+
#
|
109
|
+
# * Render the embedded resource(s)
|
110
|
+
# * Create an instance of this class
|
111
|
+
# * Add the rendered resource representations using this class's API
|
112
|
+
# * Use Hoodoo::Presenters::Base.render_in to render the final, target
|
113
|
+
# resource, passing in the embed collection via the +options+ Hash.
|
114
|
+
#
|
115
|
+
# Simple example:
|
116
|
+
#
|
117
|
+
# embeds = Hoodoo::Presenters::Embedding::Embeds.new
|
118
|
+
# embeds.add_one( 'balance', rendered_balance )
|
119
|
+
# embeds.add_many( 'vouchers', rendered_voucher_array )
|
120
|
+
#
|
121
|
+
class Embeds < Embeddable
|
122
|
+
|
123
|
+
public
|
124
|
+
|
125
|
+
# Returns the top-level resource key used for reference data, as per
|
126
|
+
# the API documentation - which is the String +_embed+.
|
127
|
+
#
|
128
|
+
def resource_key
|
129
|
+
'_embed'
|
130
|
+
end
|
131
|
+
|
132
|
+
protected
|
133
|
+
|
134
|
+
# Called from #add_one in the base class to make sure the right data
|
135
|
+
# is being supplied. Raises an exception if it gets worried.
|
136
|
+
#
|
137
|
+
# +thing+:: The value that'll be stored; should be a Hash.
|
138
|
+
#
|
139
|
+
def validate_one( thing )
|
140
|
+
unless thing.is_a?( ::Hash )
|
141
|
+
raise "Hoodoo::Presenters::Embedding::Embeds\#add_one requires a rendered resource Hash, but was given an instance of #{ thing.class }"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# Called from #add_many in the base class to make sure the right data
|
146
|
+
# is being supplied. Raises an exception if it gets worried.
|
147
|
+
#
|
148
|
+
# +thing+:: The value that'll be stored; should be an Array of Hashes
|
149
|
+
# but only the first array entry is checked, for speed.
|
150
|
+
#
|
151
|
+
def validate_many( thing )
|
152
|
+
unless thing.is_a?( ::Array )
|
153
|
+
raise "Hoodoo::Presenters::Embedding::Embeds\#add_many requires an Array, but was given an instance of #{ thing.class }"
|
154
|
+
end
|
155
|
+
|
156
|
+
unless thing[ 0 ].nil? || thing[ 0 ].is_a?( ::Hash )
|
157
|
+
raise "Hoodoo::Presenters::Embedding::Embeds\#add_many requires an Array of rendered resource Hashes, but the first Array entry is an instance of #{ thing[ 0 ].class }"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
# Instantiate this class and add one, or an Array of UUID strings via
|
164
|
+
# the API described in the base class,
|
165
|
+
# Hoodoo::Presenters::Embedding::Embeddable. You can then pass it to
|
166
|
+
# the likes of Hoodoo::Presenters::Base.render_in via the +options+
|
167
|
+
# parameter to have the reference data included in the fully rendered
|
168
|
+
# end result.
|
169
|
+
#
|
170
|
+
# When a request arrives to reference UUID data for a particular
|
171
|
+
# resource or list of resources (in which case, do the following for
|
172
|
+
# each item in that list):
|
173
|
+
#
|
174
|
+
# * Obtain the referenced resource UUID(s)
|
175
|
+
# * Create an instance of this class
|
176
|
+
# * Add the UUIDs using this class's API
|
177
|
+
# * Use Hoodoo::Presenters::Base.render_in to render the final, target
|
178
|
+
# resource, passing in the reference collection via the +options+
|
179
|
+
# Hash.
|
180
|
+
#
|
181
|
+
# Simple example:
|
182
|
+
#
|
183
|
+
# references = Hoodoo::Presenters::Embedding::References.new
|
184
|
+
# references.add_one( 'member', member_uuid )
|
185
|
+
# references.add_many( 'memberships', array_of_membership_uuids )
|
186
|
+
#
|
187
|
+
class References < Embeddable
|
188
|
+
|
189
|
+
public
|
190
|
+
|
191
|
+
# Returns the top-level resource key used for reference data, as per
|
192
|
+
# the API documentation - which is the String +_reference+.
|
193
|
+
#
|
194
|
+
def resource_key
|
195
|
+
'_reference'
|
196
|
+
end
|
197
|
+
|
198
|
+
protected
|
199
|
+
|
200
|
+
# Called from #add_one in the base class to make sure the right data
|
201
|
+
# is being supplied. Raises an exception if it gets worried.
|
202
|
+
#
|
203
|
+
# +thing+:: The value that'll be stored; should be a valid UUID.
|
204
|
+
#
|
205
|
+
def validate_one( thing )
|
206
|
+
unless Hoodoo::UUID.valid?( thing )
|
207
|
+
raise 'Hoodoo::Presenters::Embedding::References#add_one requires a valid UUID String, but the given value is invalid'
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# Called from #add_many in the base class to make sure the right data
|
212
|
+
# is being supplied. Raises an exception if it gets worried.
|
213
|
+
#
|
214
|
+
# +thing+:: The value that'll be stored; should be an Array of valid
|
215
|
+
# UUIDs, but only the first array entry is checked, for
|
216
|
+
# speed.
|
217
|
+
#
|
218
|
+
def validate_many( thing )
|
219
|
+
unless thing.is_a?( ::Array )
|
220
|
+
raise "Hoodoo::Presenters::Embedding::References\#add_many requires an Array, but was given an instance of #{ thing.class }"
|
221
|
+
end
|
222
|
+
|
223
|
+
unless thing[ 0 ].nil? || Hoodoo::UUID.valid?( thing[ 0 ] )
|
224
|
+
raise 'Hoodoo::Presenters::Embedding::References#add_many requires an Array of valid UUID strings, but the first Array entry is invalid'
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
end
|
229
|
+
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Hoodoo
|
2
|
+
module Presenters
|
3
|
+
|
4
|
+
# A JSON Array schema member.
|
5
|
+
#
|
6
|
+
class Array < Hoodoo::Presenters::Field
|
7
|
+
|
8
|
+
include Hoodoo::Presenters::BaseDSL
|
9
|
+
|
10
|
+
# The properties of this object, an +array+ of +Field+ instances.
|
11
|
+
#
|
12
|
+
attr_accessor :properties
|
13
|
+
|
14
|
+
# Check if data is a valid Array and return a Hoodoo::Errors instance.
|
15
|
+
#
|
16
|
+
def validate( data, path = '' )
|
17
|
+
errors = super( data, path )
|
18
|
+
return errors if errors.has_errors? || ( ! @required && data.nil? )
|
19
|
+
|
20
|
+
if data.is_a?( ::Array )
|
21
|
+
# No array entry schema? No array entry validation, then.
|
22
|
+
unless @properties.nil?
|
23
|
+
data.each_with_index do | item, index |
|
24
|
+
@properties.each do | name, property |
|
25
|
+
rdata = ( item.is_a?( ::Hash ) && item.has_key?( name ) ) ? item[ name ] : nil
|
26
|
+
indexed_path = "#{ full_path( path ) }[#{ index }]"
|
27
|
+
errors.merge!( property.validate( rdata, indexed_path ) )
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
else
|
32
|
+
errors.add_error(
|
33
|
+
'generic.invalid_array',
|
34
|
+
:message => "Field `#{ full_path( path ) }` is an invalid array",
|
35
|
+
:reference => { :field_name => full_path( path ) }
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
errors
|
40
|
+
end
|
41
|
+
|
42
|
+
# Render an array into the target hash based on the internal state that
|
43
|
+
# describes this instance's current path (position in the heirarchy of
|
44
|
+
# nested schema entities).
|
45
|
+
#
|
46
|
+
# +data+:: The Array to render.
|
47
|
+
# +target+:: The Hash that we render into. A "path" of keys leading to
|
48
|
+
# nested Hashes is built via +super()+, with the final
|
49
|
+
# key entry yielding the rendered array.
|
50
|
+
#
|
51
|
+
def render( data, target )
|
52
|
+
|
53
|
+
# Data provided is explicitly nil or not an array? Don't need to render
|
54
|
+
# anything beyond 'nil' at the field (the not-array case covers nil and
|
55
|
+
# covers invalid input, which is treated as nil).
|
56
|
+
|
57
|
+
return super( nil, target ) if ! data.is_a?( ::Array )
|
58
|
+
|
59
|
+
# Otherwise, start looking at rendering array contents (even if the
|
60
|
+
# input array is empty). This relies on pass-by-reference; we'll update
|
61
|
+
# this specific instance of 'array' later. Call 'super' to render the
|
62
|
+
# 'array' instance in place in 'target' straight away...
|
63
|
+
|
64
|
+
array = []
|
65
|
+
path = super( array, target )
|
66
|
+
|
67
|
+
# ...then look at rendering the input entries of 'data' into 'array'.
|
68
|
+
|
69
|
+
if @properties.nil?
|
70
|
+
# Must modify existing instance of 'array', so use 'push()'
|
71
|
+
array.push( *data )
|
72
|
+
|
73
|
+
else
|
74
|
+
data.each do | item |
|
75
|
+
|
76
|
+
# We have properties defined so array values (in "item") must be
|
77
|
+
# Hashes. If non-Hash, treat as if nil; explicit-nil-means-nil.
|
78
|
+
|
79
|
+
unless item.is_a?( ::Hash )
|
80
|
+
# Must modify existing instance of 'array', so use 'push()'
|
81
|
+
array.push( nil )
|
82
|
+
next
|
83
|
+
end
|
84
|
+
|
85
|
+
subtarget = {}
|
86
|
+
|
87
|
+
@properties.each do | name, property |
|
88
|
+
name = name.to_s
|
89
|
+
has_key = item.has_key?( name )
|
90
|
+
|
91
|
+
next unless has_key || property.has_default?()
|
92
|
+
|
93
|
+
property.render( has_key ? item[ name ] : property.default, subtarget )
|
94
|
+
end
|
95
|
+
|
96
|
+
rendered = subtarget.empty? ? {} : read_at_path( subtarget, path )
|
97
|
+
|
98
|
+
# Must modify existing instance of 'array', so use 'push()'
|
99
|
+
array.push( rendered )
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Invoke a given block, passing this item; call recursively for any
|
105
|
+
# defined sub-fields too. See Hoodoo::Presenters::Base#walk for why.
|
106
|
+
#
|
107
|
+
# &block:: Mandatory block, which is passed 'self' when called.
|
108
|
+
#
|
109
|
+
def walk( &block )
|
110
|
+
block.call( self )
|
111
|
+
|
112
|
+
@properties.each do | name, property |
|
113
|
+
property.walk( &block )
|
114
|
+
end unless @properties.nil?
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Hoodoo
|
2
|
+
module Presenters
|
3
|
+
|
4
|
+
# A JSON Boolean schema member.
|
5
|
+
#
|
6
|
+
class Boolean < Hoodoo::Presenters::Field
|
7
|
+
|
8
|
+
# Check if data is a valid Boolean 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 == data
|
15
|
+
errors.add_error(
|
16
|
+
'generic.invalid_boolean',
|
17
|
+
:message => "Field `#{ full_path( path ) }` is an invalid boolean",
|
18
|
+
:reference => { :field_name => full_path( path ) }
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
errors
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Hoodoo
|
2
|
+
module Presenters
|
3
|
+
|
4
|
+
# A JSON Date schema member.
|
5
|
+
#
|
6
|
+
class Date < Hoodoo::Presenters::Field
|
7
|
+
|
8
|
+
# Check if data is a valid Date 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 Hoodoo::Utilities.valid_iso8601_subset_date?( data )
|
15
|
+
errors.add_error(
|
16
|
+
'generic.invalid_date',
|
17
|
+
:message => "Field `#{ full_path( path ) }` is an invalid ISO8601 date",
|
18
|
+
:reference => { :field_name => full_path( path ) }
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
errors
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Hoodoo
|
2
|
+
module Presenters
|
3
|
+
|
4
|
+
# A JSON DateTime schema member.
|
5
|
+
#
|
6
|
+
class DateTime < Hoodoo::Presenters::Field
|
7
|
+
|
8
|
+
# Check if data is a valid DateTime 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 Hoodoo::Utilities.valid_iso8601_subset_datetime?( data )
|
15
|
+
errors.add_error(
|
16
|
+
'generic.invalid_datetime',
|
17
|
+
:message => "Field `#{ full_path( path ) }` is an invalid ISO8601 datetime",
|
18
|
+
:reference => { :field_name => full_path( path ) }
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
errors
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|