@@ -28,37 +28,30 @@ class Factory < Support::MemoizableData.define(
2828 def build ( event )
2929 event = prepare_event ( event )
3030
31- selected_json_schema_version = select_json_schema_version ( event ) { |failure | return failure }
31+ requested_schema_version = schema_version_from ( event )
32+ selected_schema_version = select_schema_version ( event , requested_schema_version ) { |failure | return failure }
33+ event = event . merge ( SCHEMA_VERSION_KEY => requested_schema_version )
3234
33- # Because the `select_json_schema_version` picks the closest-matching json schema version, the incoming
34- # event might not match the expected json_schema_version value in the json schema (which is a `const` field).
35- # This is by design, since we're picking a schema based on best-effort, so to avoid that by-design validation error,
36- # performing the envelope validation on a "patched" version of the event.
37- event_with_patched_envelope = event . merge ( { JSON_SCHEMA_VERSION_KEY => selected_json_schema_version } )
35+ event_for_validation = schema_artifacts . event_for_schema_version_validation ( event , selected_schema_version )
3836
39- if ( error_message = validator ( EVENT_ENVELOPE_JSON_SCHEMA_NAME , selected_json_schema_version ) . validate_with_error_message ( event_with_patched_envelope ) )
37+ if ( error_message = validator ( EVENT_ENVELOPE_JSON_SCHEMA_NAME , selected_schema_version ) . validate_with_error_message ( event_for_validation ) )
4038 return build_failed_result ( event , "event payload" , error_message )
4139 end
4240
43- failed_result = validate_record_returning_failure ( event , selected_json_schema_version )
41+ failed_result = validate_record_returning_failure ( event , selected_schema_version )
4442 failed_result || BuildResult . success ( build_all_operations_for (
4543 event ,
46- record_preparer_factory . for_json_schema_version ( selected_json_schema_version )
44+ record_preparer_factory . for_schema_version ( selected_schema_version )
4745 ) )
4846 end
4947
5048 private
5149
52- def select_json_schema_version ( event )
53- available_json_schema_versions = schema_artifacts . available_json_schema_versions
50+ def select_schema_version ( event , requested_schema_version )
51+ available_schema_versions = schema_artifacts . available_schema_versions
5452
55- requested_json_schema_version = event [ JSON_SCHEMA_VERSION_KEY ]
56-
57- # First check that a valid value has been requested (a positive integer)
58- if !event . key? ( JSON_SCHEMA_VERSION_KEY )
59- yield build_failed_result ( event , JSON_SCHEMA_VERSION_KEY , "Event lacks a `#{ JSON_SCHEMA_VERSION_KEY } `" )
60- elsif !requested_json_schema_version . is_a? ( Integer ) || requested_json_schema_version < 1
61- yield build_failed_result ( event , JSON_SCHEMA_VERSION_KEY , "#{ JSON_SCHEMA_VERSION_KEY } (#{ requested_json_schema_version } ) must be a positive integer." )
53+ unless requested_schema_version . is_a? ( Integer ) && requested_schema_version >= 1
54+ yield build_failed_result ( event , SCHEMA_VERSION_KEY , "#{ SCHEMA_VERSION_KEY } (#{ requested_schema_version } ) must be a positive integer." )
6255 end
6356
6457 # The requested version might not necessarily be available (if the publisher is deployed ahead of the indexer, or an old schema
@@ -67,46 +60,46 @@ def select_json_schema_version(event)
6760 # the event can still be indexed.
6861 #
6962 # This min_by block will take the closest version in the list. If a tie occurs, the first value in the list wins. The desired
70- # behavior is in the event of a tie (highly unlikely, there shouldn't be a gap in available json schema versions), the higher version
63+ # behavior is in the event of a tie (highly unlikely, there shouldn't be a gap in available schema versions), the higher version
7164 # should be selected. So to get that behavior, the list is sorted in descending order.
7265 #
73- selected_json_schema_version = available_json_schema_versions . sort . reverse . min_by { |version | ( requested_json_schema_version - version ) . abs }
66+ selected_schema_version = available_schema_versions . sort . reverse . min_by { |version | ( requested_schema_version - version ) . abs }
7467
75- if selected_json_schema_version != requested_json_schema_version
68+ if selected_schema_version != requested_schema_version
7669 logger . info ( {
77- "message_type" => "ElasticGraphMissingJSONSchemaVersion " ,
70+ "message_type" => "ElasticGraphMissingSchemaVersion " ,
7871 "message_id" => event [ "message_id" ] ,
7972 "event_id" => EventID . from_event ( event ) ,
8073 "event_type" => event [ "type" ] ,
81- "requested_json_schema_version " => requested_json_schema_version ,
82- "selected_json_schema_version " => selected_json_schema_version
74+ "requested_schema_version " => requested_schema_version ,
75+ "selected_schema_version " => selected_schema_version
8376 } )
8477 end
8578
86- if selected_json_schema_version . nil?
79+ if selected_schema_version . nil?
8780 yield build_failed_result (
88- event , JSON_SCHEMA_VERSION_KEY ,
89- "Failed to select json schema version. Requested version: #{ event [ JSON_SCHEMA_VERSION_KEY ] } . \
90- Available json schema versions: #{ available_json_schema_versions . sort . join ( ", " ) } "
81+ event , SCHEMA_VERSION_KEY ,
82+ "Failed to select schema version. Requested version: #{ requested_schema_version } . \
83+ Available schema versions: #{ available_schema_versions . sort . join ( ", " ) } "
9184 )
9285 end
9386
94- selected_json_schema_version
87+ selected_schema_version
9588 end
9689
97- def validator ( type , selected_json_schema_version )
98- factory = validator_factories_by_version [ selected_json_schema_version ] # : Support::JSONSchema::ValidatorFactory
90+ def validator ( type , selected_schema_version )
91+ factory = validator_factories_by_version [ selected_schema_version ] # : Support::JSONSchema::ValidatorFactory
9992 factory . validator_for ( type )
10093 end
10194
10295 def validator_factories_by_version
103- @validator_factories_by_version ||= ::Hash . new do |hash , json_schema_version |
96+ @validator_factories_by_version ||= ::Hash . new do |hash , schema_version |
10497 factory = Support ::JSONSchema ::ValidatorFactory . new (
105- schema : schema_artifacts . json_schemas_for ( json_schema_version ) ,
98+ schema : schema_artifacts . json_schemas_for ( schema_version ) ,
10699 sanitize_pii : true
107100 )
108101 factory = configure_record_validator . call ( factory ) if configure_record_validator
109- hash [ json_schema_version ] = factory
102+ hash [ schema_version ] = factory
110103 end
111104 end
112105
@@ -117,10 +110,14 @@ def prepare_event(event)
117110 event . merge ( "record" => event [ "record" ] . merge ( "id" => event . fetch ( "id" ) ) )
118111 end
119112
120- def validate_record_returning_failure ( event , selected_json_schema_version )
113+ def schema_version_from ( event )
114+ event . fetch ( SCHEMA_VERSION_KEY ) { schema_artifacts . available_schema_versions . max }
115+ end
116+
117+ def validate_record_returning_failure ( event , selected_schema_version )
121118 record = event . fetch ( "record" )
122119 graphql_type_name = event . fetch ( "type" )
123- validator = validator ( graphql_type_name , selected_json_schema_version )
120+ validator = validator ( graphql_type_name , selected_schema_version )
124121
125122 if ( error_message = validator . validate_with_error_message ( record ) )
126123 build_failed_result ( event , "#{ graphql_type_name } record" , error_message )
@@ -130,7 +127,7 @@ def validate_record_returning_failure(event, selected_json_schema_version)
130127 def build_failed_result ( event , payload_description , validation_message )
131128 message = "Malformed #{ payload_description } . #{ validation_message } "
132129
133- # Here we use the `RecordPreparer::Identity` record preparer because we may not have a valid JSON schema
130+ # Here we use the `RecordPreparer::Identity` record preparer because we may not have a valid schema
134131 # version number in this case (which is usually required to get a `RecordPreparer` from the factory), and
135132 # we won't wind up using the record preparer for real on these operations, anyway.
136133 operations = build_all_operations_for ( event , RecordPreparer ::Identity )
0 commit comments