karafka 2.4.18 → 2.5.0.beta1
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.github/CODEOWNERS +3 -0
- data/.github/workflows/ci.yml +58 -14
- data/.github/workflows/verify-action-pins.yml +16 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +53 -0
- data/Gemfile +3 -3
- data/Gemfile.lock +55 -58
- data/LICENSE-COMM +2 -2
- data/bin/clean_kafka +43 -0
- data/bin/integrations +17 -5
- data/bin/rspecs +15 -3
- data/bin/verify_kafka_warnings +35 -0
- data/bin/verify_topics_naming +27 -0
- data/config/locales/errors.yml +3 -0
- data/config/locales/pro_errors.yml +13 -2
- data/docker-compose.yml +1 -1
- data/examples/payloads/json/enrollment_event.json +579 -0
- data/examples/payloads/json/ingestion_event.json +30 -0
- data/examples/payloads/json/transaction_event.json +17 -0
- data/examples/payloads/json/user_event.json +11 -0
- data/karafka.gemspec +3 -3
- data/lib/karafka/active_job/current_attributes.rb +1 -1
- data/lib/karafka/admin/acl.rb +5 -1
- data/lib/karafka/admin.rb +51 -19
- data/lib/karafka/base_consumer.rb +17 -8
- data/lib/karafka/cli/base.rb +8 -2
- data/lib/karafka/connection/client.rb +20 -7
- data/lib/karafka/connection/listener.rb +24 -12
- data/lib/karafka/connection/messages_buffer.rb +1 -1
- data/lib/karafka/connection/proxy.rb +3 -0
- data/lib/karafka/contracts/config.rb +3 -0
- data/lib/karafka/contracts/topic.rb +1 -1
- data/lib/karafka/errors.rb +11 -0
- data/lib/karafka/helpers/async.rb +3 -1
- data/lib/karafka/instrumentation/callbacks/rebalance.rb +5 -1
- data/lib/karafka/instrumentation/logger_listener.rb +86 -23
- data/lib/karafka/instrumentation/proctitle_listener.rb +5 -1
- data/lib/karafka/instrumentation/vendors/datadog/metrics_listener.rb +2 -2
- data/lib/karafka/messages/builders/batch_metadata.rb +1 -1
- data/lib/karafka/pro/cleaner.rb +8 -0
- data/lib/karafka/pro/cli/parallel_segments/base.rb +89 -0
- data/lib/karafka/pro/cli/parallel_segments/collapse.rb +164 -0
- data/lib/karafka/pro/cli/parallel_segments/distribute.rb +164 -0
- data/lib/karafka/pro/cli/parallel_segments.rb +60 -0
- data/lib/karafka/pro/connection/manager.rb +5 -8
- data/lib/karafka/pro/encryption.rb +8 -0
- data/lib/karafka/pro/instrumentation/performance_tracker.rb +1 -1
- data/lib/karafka/pro/iterator/expander.rb +5 -3
- data/lib/karafka/pro/iterator/tpl_builder.rb +23 -0
- data/lib/karafka/pro/loader.rb +10 -0
- data/lib/karafka/pro/processing/coordinator.rb +4 -1
- data/lib/karafka/pro/processing/coordinators/errors_tracker.rb +27 -3
- data/lib/karafka/pro/processing/coordinators/filters_applier.rb +11 -0
- data/lib/karafka/pro/processing/filters/base.rb +10 -2
- data/lib/karafka/pro/processing/filters/expirer.rb +5 -0
- data/lib/karafka/pro/processing/filters/inline_insights_delayer.rb +2 -2
- data/lib/karafka/pro/processing/filters/virtual_limiter.rb +5 -0
- data/lib/karafka/pro/processing/parallel_segments/filters/base.rb +73 -0
- data/lib/karafka/pro/processing/parallel_segments/filters/default.rb +85 -0
- data/lib/karafka/pro/processing/parallel_segments/filters/mom.rb +66 -0
- data/lib/karafka/pro/processing/partitioner.rb +1 -13
- data/lib/karafka/pro/processing/piping/consumer.rb +13 -13
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom.rb +1 -1
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom_vp.rb +1 -1
- data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom.rb +1 -1
- data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom_vp.rb +1 -1
- data/lib/karafka/pro/processing/strategies/aj/ftr_lrj_mom_vp.rb +1 -1
- data/lib/karafka/pro/processing/strategies/aj/lrj_mom_vp.rb +1 -1
- data/lib/karafka/pro/processing/strategies/default.rb +36 -8
- data/lib/karafka/pro/processing/strategies/dlq/default.rb +14 -10
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj.rb +1 -1
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom.rb +1 -1
- data/lib/karafka/pro/processing/strategies/dlq/lrj.rb +3 -1
- data/lib/karafka/pro/processing/strategies/dlq/lrj_mom.rb +1 -1
- data/lib/karafka/pro/processing/strategies/ftr/default.rb +1 -1
- data/lib/karafka/pro/processing/strategies/lrj/default.rb +4 -1
- data/lib/karafka/pro/processing/strategies/lrj/ftr.rb +1 -1
- data/lib/karafka/pro/processing/strategies/lrj/ftr_mom.rb +1 -1
- data/lib/karafka/pro/processing/strategies/lrj/mom.rb +1 -1
- data/lib/karafka/pro/processing/virtual_partitions/distributors/balanced.rb +50 -0
- data/lib/karafka/pro/processing/virtual_partitions/distributors/base.rb +29 -0
- data/lib/karafka/pro/processing/virtual_partitions/distributors/consistent.rb +27 -0
- data/lib/karafka/pro/recurring_tasks/contracts/config.rb +8 -4
- data/lib/karafka/pro/recurring_tasks/dispatcher.rb +3 -3
- data/lib/karafka/pro/recurring_tasks/setup/config.rb +7 -2
- data/lib/karafka/pro/recurring_tasks.rb +13 -0
- data/lib/karafka/pro/routing/features/dead_letter_queue/topic.rb +1 -1
- data/lib/karafka/pro/routing/features/multiplexing/config.rb +1 -0
- data/lib/karafka/pro/routing/features/multiplexing/contracts/topic.rb +17 -0
- data/lib/karafka/pro/routing/features/multiplexing/proxy.rb +5 -2
- data/lib/karafka/pro/routing/features/multiplexing/subscription_group.rb +8 -1
- data/lib/karafka/pro/routing/features/parallel_segments/builder.rb +47 -0
- data/lib/karafka/pro/routing/features/parallel_segments/config.rb +27 -0
- data/lib/karafka/pro/routing/features/parallel_segments/consumer_group.rb +83 -0
- data/lib/karafka/pro/routing/features/parallel_segments/contracts/consumer_group.rb +49 -0
- data/lib/karafka/pro/routing/features/parallel_segments/topic.rb +43 -0
- data/lib/karafka/pro/routing/features/parallel_segments.rb +24 -0
- data/lib/karafka/pro/routing/features/patterns/pattern.rb +1 -1
- data/lib/karafka/pro/routing/features/recurring_tasks/builder.rb +2 -2
- data/lib/karafka/pro/routing/features/scheduled_messages/builder.rb +10 -6
- data/lib/karafka/pro/routing/features/virtual_partitions/config.rb +20 -2
- data/lib/karafka/pro/routing/features/virtual_partitions/contracts/topic.rb +1 -0
- data/lib/karafka/pro/routing/features/virtual_partitions/topic.rb +8 -2
- data/lib/karafka/pro/scheduled_messages/consumer.rb +14 -15
- data/lib/karafka/pro/scheduled_messages/daily_buffer.rb +9 -6
- data/lib/karafka/pro/scheduled_messages/deserializers/headers.rb +7 -1
- data/lib/karafka/pro/scheduled_messages/max_epoch.rb +15 -6
- data/lib/karafka/pro/scheduled_messages.rb +13 -0
- data/lib/karafka/processing/coordinators_buffer.rb +1 -0
- data/lib/karafka/processing/strategies/default.rb +4 -4
- data/lib/karafka/routing/features/dead_letter_queue/contracts/topic.rb +1 -0
- data/lib/karafka/routing/subscription_group.rb +1 -1
- data/lib/karafka/runner.rb +7 -1
- data/lib/karafka/server.rb +5 -0
- data/lib/karafka/setup/attributes_map.rb +2 -0
- data/lib/karafka/setup/config.rb +22 -1
- data/lib/karafka/setup/defaults_injector.rb +26 -1
- data/lib/karafka/status.rb +6 -1
- data/lib/karafka/swarm/node.rb +31 -0
- data/lib/karafka/swarm/supervisor.rb +4 -0
- data/lib/karafka/templates/karafka.rb.erb +14 -1
- data/lib/karafka/version.rb +1 -1
- data/lib/karafka.rb +17 -9
- data/renovate.json +14 -2
- data.tar.gz.sig +0 -0
- metadata +36 -11
- metadata.gz.sig +0 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# This script verifies that we do not create (except few needed exceptions) test topics that do
|
4
|
+
# not start with the "it-" prefix which is our standard.
|
5
|
+
#
|
6
|
+
# This ensures that we can clearly identify all test topics for removal in case of doing dev work
|
7
|
+
# on a long-lived Kafka cluster without option to fully reset it.
|
8
|
+
#
|
9
|
+
# It also ensures we have one convention that we can follow.
|
10
|
+
|
11
|
+
require_relative '../spec/integrations_helper.rb'
|
12
|
+
|
13
|
+
setup_karafka
|
14
|
+
|
15
|
+
# Please note that "__" starting topics are not here by default. It is expected.
|
16
|
+
invalid = Karafka::Admin
|
17
|
+
.cluster_info
|
18
|
+
.topics
|
19
|
+
.map { |topic| topic[:topic_name] }
|
20
|
+
.select { |topic| !topic.start_with?('it-') }
|
21
|
+
.select { |topic| topic.length <= 6 }
|
22
|
+
|
23
|
+
invalid.each do |invalid_name|
|
24
|
+
puts "#{invalid_name} does not start with the \"it-\" prefix"
|
25
|
+
end
|
26
|
+
|
27
|
+
exit invalid.empty? ? 0 : 1
|
data/config/locales/errors.yml
CHANGED
@@ -24,6 +24,7 @@ en:
|
|
24
24
|
key_must_be_a_symbol: All keys under the kafka settings scope need to be symbols
|
25
25
|
max_timeout_vs_pause_max_timeout: pause_timeout must be less or equal to pause_max_timeout
|
26
26
|
shutdown_timeout_vs_max_wait_time: shutdown_timeout must be more than max_wait_time
|
27
|
+
worker_thread_priority_format: must be between -3 and 3
|
27
28
|
|
28
29
|
oauth.token_provider_listener_format: 'must be false or respond to #on_oauthbearer_token_refresh'
|
29
30
|
|
@@ -36,6 +37,7 @@ en:
|
|
36
37
|
internal.processing.expansions_selector_format: cannot be nil
|
37
38
|
internal.processing.executor_class_format: cannot be nil
|
38
39
|
internal.processing.worker_job_call_wrapper_format: 'needs to be false or respond to #wrap'
|
40
|
+
internal.processing.errors_tracker_class_format: 'needs to be nil or a class'
|
39
41
|
|
40
42
|
internal.active_job.dispatcher_format: cannot be nil
|
41
43
|
internal.active_job.job_options_contract_format: cannot be nil
|
@@ -67,6 +69,7 @@ en:
|
|
67
69
|
internal.connection.proxy.metadata.timeout_format: needs to be an integer bigger than 0
|
68
70
|
internal.connection.proxy.metadata.max_attempts_format: needs to be an integer bigger than 0
|
69
71
|
internal.connection.proxy.metadata.wait_time_format: needs to be an integer bigger than 0
|
72
|
+
internal.connection.listener_thread_priority_format: must be between -3 and 3
|
70
73
|
|
71
74
|
internal.swarm.manager_format: cannot be nil
|
72
75
|
internal.swarm.orphaned_exit_code_format: needs to be an integer bigger or equal to 0
|
@@ -5,6 +5,7 @@ en:
|
|
5
5
|
virtual_partitions.max_partitions_format: needs to be equal or more than 1
|
6
6
|
virtual_partitions.offset_metadata_strategy_format: needs to be either :exact or :current
|
7
7
|
virtual_partitions.reducer_format: "needs to respond to `#call`"
|
8
|
+
virtual_partitions.distribution_format: "needs to be either :consistent or :balanced"
|
8
9
|
|
9
10
|
long_running_job.active_format: needs to be either true or false
|
10
11
|
|
@@ -58,6 +59,8 @@ en:
|
|
58
59
|
subscription_group_details_multiplexing_boot_mismatch: 'boot needs to be between min and max'
|
59
60
|
subscription_group_details.multiplexing_boot_format: 'needs to be an integer equal or more than 1'
|
60
61
|
subscription_group_details.multiplexing_boot_not_dynamic: 'needs to be equal to max when not in dynamic mode'
|
62
|
+
subscription_group_details_multiplexing_one_not_enough: 'min and max cannot equal 1'
|
63
|
+
subscription_group_details.multiplexing_scale_delay_format: 'needs to be an integer equal or more than 1000'
|
61
64
|
|
62
65
|
swarm.active_format: needs to be true
|
63
66
|
swarm.nodes_format: needs to be a range, array of nodes ids or a hash with direct assignments
|
@@ -88,8 +91,16 @@ en:
|
|
88
91
|
patterns_format: must be an array with hashes
|
89
92
|
patterns_missing: needs to be present
|
90
93
|
patterns_regexps_not_unique: 'must be unique within consumer group'
|
94
|
+
|
91
95
|
direct_assignments_homogenous: 'single consumer group cannot mix regular and direct assignments'
|
92
96
|
|
97
|
+
parallel_segments.partitioner_format: needs to be defined and needs to respond to `#call`
|
98
|
+
parallel_segments.partitioner_respond_to_call: needs to be defined and needs to respond to `#call`
|
99
|
+
parallel_segments.count_format: needs to be equal or more than 1
|
100
|
+
parallel_segments.active_format: needs to be boolean
|
101
|
+
parallel_segments.reducer_format: "needs to respond to `#call`"
|
102
|
+
parallel_segments.merge_key_format: "needs to be a non-empty string"
|
103
|
+
|
93
104
|
pattern:
|
94
105
|
regexp_format: must be a regular expression
|
95
106
|
name_format: 'needs to be a string with a Kafka accepted format'
|
@@ -113,8 +124,8 @@ en:
|
|
113
124
|
|
114
125
|
recurring_tasks.consumer_class_format: 'needs to inherit from Karafka::BaseConsumer'
|
115
126
|
recurring_tasks.group_id_format: 'needs to be a string with a Kafka accepted format'
|
116
|
-
recurring_tasks.topics.
|
117
|
-
recurring_tasks.topics.
|
127
|
+
recurring_tasks.topics.schedules.name_format: 'needs to be a string with a Kafka accepted format'
|
128
|
+
recurring_tasks.topics.logs.name_format: 'needs to be a string with a Kafka accepted format'
|
118
129
|
recurring_tasks.interval_format: 'needs to be equal or more than 1000 and an integer'
|
119
130
|
recurring_tasks.deserializer_format: 'needs to be configured'
|
120
131
|
recurring_tasks.logging_format: needs to be a boolean
|
data/docker-compose.yml
CHANGED
@@ -0,0 +1,579 @@
|
|
1
|
+
{
|
2
|
+
"event_type": "enrollment",
|
3
|
+
"data": {
|
4
|
+
"tenant_id": "tenant_5",
|
5
|
+
"tenant_dashed_id": "tenant_5",
|
6
|
+
"tenant_name": "Tenant 5",
|
7
|
+
"rc_base_url": "https://tenant-5.example.com",
|
8
|
+
"domain": "tenant-5.example.com",
|
9
|
+
"admin_domain": "tenant-5.admin.example.com",
|
10
|
+
"admin_email": "email@example.com",
|
11
|
+
"country_codes": [
|
12
|
+
"US"
|
13
|
+
],
|
14
|
+
"cash_currency": "USD",
|
15
|
+
"locales": [
|
16
|
+
"en-US"
|
17
|
+
],
|
18
|
+
"tenant_locales": [
|
19
|
+
{
|
20
|
+
"locale": "en-US",
|
21
|
+
"enabled": true,
|
22
|
+
"default_for_tenant": true
|
23
|
+
}
|
24
|
+
],
|
25
|
+
"time_zone": "America/New_York",
|
26
|
+
"provider_config": {
|
27
|
+
"request_phase_url": "https://random.tenant-5.com/example"
|
28
|
+
},
|
29
|
+
"partner_name_for_te": "tenant_InternalId partner",
|
30
|
+
"tenant_code_for_tc": "CODE_FOR_TC",
|
31
|
+
"webhook_resource_app_name_for_tc": "service_4",
|
32
|
+
"tenant_status_for_tc": "live",
|
33
|
+
"nn_internal_domain": "service-4.internal.com",
|
34
|
+
"mc_internal_domain": "service-5.internal.com",
|
35
|
+
"nn_internal_webhook_url": "https://service-4.internal.com/int/webhooks",
|
36
|
+
"loyalty_programs_for_nn": [
|
37
|
+
{
|
38
|
+
"loyalty_program": {
|
39
|
+
"transfer_connect_identifier": "tenant_InternalId",
|
40
|
+
"active": true,
|
41
|
+
"tenant": true,
|
42
|
+
"manual_verification_required": false,
|
43
|
+
"tenant_id": "tenant_InternalId",
|
44
|
+
"name_required": false,
|
45
|
+
"category": "airline",
|
46
|
+
"name": "tenant_InternalId Rewards",
|
47
|
+
"short_name": "tenant_InternalId Rewards",
|
48
|
+
"description": "tenant_InternalId",
|
49
|
+
"translations": {
|
50
|
+
"en-US": {
|
51
|
+
"name": "tenant_InternalId Rewards",
|
52
|
+
"short_name": "tenant_InternalId Rewards"
|
53
|
+
}
|
54
|
+
}
|
55
|
+
},
|
56
|
+
"capability": {},
|
57
|
+
"loyalty_currency": {
|
58
|
+
"name": "Rewards Points",
|
59
|
+
"short_name": "Rewards Points",
|
60
|
+
"translations": {
|
61
|
+
"en-US": {
|
62
|
+
"name": "Rewards Points",
|
63
|
+
"short_name": "Rewards Points"
|
64
|
+
}
|
65
|
+
}
|
66
|
+
}
|
67
|
+
}
|
68
|
+
],
|
69
|
+
"payment_tier_id": "paid_at_redemption",
|
70
|
+
"demo": true,
|
71
|
+
"feature_settings": {
|
72
|
+
"accrual_campaign": {
|
73
|
+
"enabled": true
|
74
|
+
},
|
75
|
+
"gift_card_campaign": {
|
76
|
+
"enabled": true
|
77
|
+
},
|
78
|
+
"comms_campaign": {
|
79
|
+
"enabled": true
|
80
|
+
}
|
81
|
+
},
|
82
|
+
"ui_settings": {
|
83
|
+
"application": {
|
84
|
+
"components": {
|
85
|
+
"buttons": {
|
86
|
+
"primary": {
|
87
|
+
"borderRadius": "4px",
|
88
|
+
"borderWidth": "1px",
|
89
|
+
"textColor": "#FFFFFF"
|
90
|
+
},
|
91
|
+
"secondary": {
|
92
|
+
"borderRadius": "4px",
|
93
|
+
"borderWidth": "1px",
|
94
|
+
"textColor": "#22285A"
|
95
|
+
}
|
96
|
+
},
|
97
|
+
"breadcrumbs": {
|
98
|
+
"enabled": true
|
99
|
+
},
|
100
|
+
"footer": {
|
101
|
+
"enabled": true,
|
102
|
+
"backgroundColor": "#22285A",
|
103
|
+
"color": "#E3E4EB",
|
104
|
+
"logo": "inverted",
|
105
|
+
"footerLogo": "https://some.random.url.com/logo.png",
|
106
|
+
"hideBranding": false,
|
107
|
+
"textAlign": "text-left",
|
108
|
+
"textDecoration": "no-underline",
|
109
|
+
"textTransform": "none",
|
110
|
+
"variant": "footer-2"
|
111
|
+
},
|
112
|
+
"header": {
|
113
|
+
"enabled": true,
|
114
|
+
"avatar": "primary",
|
115
|
+
"backgroundColor": "#22285A",
|
116
|
+
"color": "#FFFFFF",
|
117
|
+
"logo": "primary",
|
118
|
+
"showLogo": true,
|
119
|
+
"twoLayer": true
|
120
|
+
},
|
121
|
+
"heroBannerAndQuickLinks": {
|
122
|
+
"backgroundColor": "#22285A",
|
123
|
+
"textColor": "#FFFFFF"
|
124
|
+
},
|
125
|
+
"navigation": {
|
126
|
+
"descriptionColor": "#818181",
|
127
|
+
"hoverBackgroundColor": "#00000000"
|
128
|
+
},
|
129
|
+
"spinner": {}
|
130
|
+
},
|
131
|
+
"features": {
|
132
|
+
"cashback": {
|
133
|
+
"description": {
|
134
|
+
"color": "#FFFFFF",
|
135
|
+
"text": " Maximize Your Rewards: Cash in on Incredible Cashback Offers",
|
136
|
+
"transform": "none"
|
137
|
+
},
|
138
|
+
"enabled": false,
|
139
|
+
"listingImageUrl": "https://some-random-url.com/assets/image.jpg",
|
140
|
+
"productImageUrl": "https://some-random-url.com/assets/image.jpg",
|
141
|
+
"title": {
|
142
|
+
"color": "#FFFFFF",
|
143
|
+
"text": "Cashback",
|
144
|
+
"transform": "capitalize"
|
145
|
+
}
|
146
|
+
},
|
147
|
+
"crypto": {
|
148
|
+
"description": {
|
149
|
+
"color": "#FFFFFF",
|
150
|
+
"text": "Unlock the Future: Convert Your Events into Stream",
|
151
|
+
"transform": "none"
|
152
|
+
},
|
153
|
+
"enabled": false,
|
154
|
+
"listingImageUrl": "https://some-random-url.com/assets/crypto.jpg",
|
155
|
+
"productImageUrl": "https://some-random-url.com/assets/crypto.jpg",
|
156
|
+
"title": {
|
157
|
+
"color": "#FFFFFF",
|
158
|
+
"text": "Crypto",
|
159
|
+
"transform": "capitalize"
|
160
|
+
}
|
161
|
+
},
|
162
|
+
"giftCard": {
|
163
|
+
"description": {
|
164
|
+
"color": "#FFFFFF",
|
165
|
+
"text": "Unlock Endless Possibilities: Redeem Gift Cards for Your Favorite Events",
|
166
|
+
"transform": "none"
|
167
|
+
},
|
168
|
+
"enabled": false,
|
169
|
+
"listingImageUrl": "https://some-random-url.com/assets/gift_card.jpg",
|
170
|
+
"productImageUrl": "https://some-random-url.com/assets/gift_card.jpg",
|
171
|
+
"title": {
|
172
|
+
"color": "#FFFFFF",
|
173
|
+
"text": "Gift Card",
|
174
|
+
"transform": "capitalize"
|
175
|
+
}
|
176
|
+
},
|
177
|
+
"offer": {
|
178
|
+
"title": {
|
179
|
+
"text": "Offers",
|
180
|
+
"color": "#FFFFFF",
|
181
|
+
"transform": "capitalize"
|
182
|
+
},
|
183
|
+
"enabled": false,
|
184
|
+
"description": {
|
185
|
+
"text": "Save with free hand-picked coupons, promo codes, discounts & deals.",
|
186
|
+
"color": "#FFFFFF",
|
187
|
+
"transform": "uppercase"
|
188
|
+
},
|
189
|
+
"listingImageUrl": "https://some-random-url.com/assets/offers_banner.jpeg",
|
190
|
+
"productImageUrl": "https://some-random-url.com/assets/offers_banner.jpeg"
|
191
|
+
},
|
192
|
+
"dining": {
|
193
|
+
"enabled": false,
|
194
|
+
"title": {
|
195
|
+
"text": "Premium dining",
|
196
|
+
"color": "#FFFFFF",
|
197
|
+
"transform": "capitalize"
|
198
|
+
},
|
199
|
+
"description": {
|
200
|
+
"text": "Earn points on your purchases when you make payment using an eligible card.",
|
201
|
+
"color": "#FFFFFF",
|
202
|
+
"transform": "uppercase"
|
203
|
+
},
|
204
|
+
"listingImageUrl": "https://some-random-url.com/assets/dining-background.jpeg",
|
205
|
+
"productImageUrl": "https://some-random-url.com/assets/dining-background.jpeg"
|
206
|
+
},
|
207
|
+
"extraCredit": {
|
208
|
+
"title": {
|
209
|
+
"text": "Karafka Credit",
|
210
|
+
"color": "#FFFFFF",
|
211
|
+
"transform": "capitalize"
|
212
|
+
},
|
213
|
+
"enabled": false,
|
214
|
+
"description": {
|
215
|
+
"text": "Turn points into Karafka credit for convenient rides and food delivery",
|
216
|
+
"color": "#FFFFFF",
|
217
|
+
"transform": "uppercase"
|
218
|
+
},
|
219
|
+
"listingImageUrl": "https://some-random-url.com/assets/extra.png",
|
220
|
+
"productImageUrl": "https://some-random-url.com/assets/extra.png"
|
221
|
+
},
|
222
|
+
"pointsTransfer": {
|
223
|
+
"description": {
|
224
|
+
"color": "#FFFFFF",
|
225
|
+
"text": "Extend your Reach: Transfer Points to Unlock New Rewards",
|
226
|
+
"transform": "none"
|
227
|
+
},
|
228
|
+
"enabled": false,
|
229
|
+
"listingImageUrl": "https://some-random-url.com/assets/frequent_traveller_programs.jpg",
|
230
|
+
"productImageUrl": "https://some-random-url.com/assets/frequent_traveller_programs.jpg",
|
231
|
+
"title": {
|
232
|
+
"color": "#FFFFFF",
|
233
|
+
"text": "Transfer",
|
234
|
+
"transform": "capitalize"
|
235
|
+
}
|
236
|
+
},
|
237
|
+
"rewardsSummary": {
|
238
|
+
"listingImageUrl": "https://some-random-url.com/assets/reward_summary.jpg",
|
239
|
+
"title": {
|
240
|
+
"color": "#FFFFFF",
|
241
|
+
"text": "My Rewards Summary",
|
242
|
+
"transform": "capitalize"
|
243
|
+
},
|
244
|
+
"includeHeadlessRedemptions": true
|
245
|
+
},
|
246
|
+
"sustainability": {
|
247
|
+
"description": {
|
248
|
+
"color": "#FFFFFF",
|
249
|
+
"text": "Rewarding Sustainability: Make Every Point Count for a Better Planet",
|
250
|
+
"transform": "none"
|
251
|
+
},
|
252
|
+
"enabled": false,
|
253
|
+
"listingImageUrl": "https://some-random-url.com/assets/sustainability.jpg",
|
254
|
+
"productImageUrl": "https://some-random-url.com/assets/sustainability.jpg",
|
255
|
+
"title": {
|
256
|
+
"color": "#FFFFFF",
|
257
|
+
"text": "Carbon offset",
|
258
|
+
"transform": "capitalize"
|
259
|
+
}
|
260
|
+
},
|
261
|
+
"termsAndConditions": {
|
262
|
+
"enabled": true
|
263
|
+
},
|
264
|
+
"travel": {
|
265
|
+
"enabled": false,
|
266
|
+
"features": {
|
267
|
+
"cars": {
|
268
|
+
"title": {
|
269
|
+
"text": "Travel",
|
270
|
+
"color": "#FFFFFF",
|
271
|
+
"transform": "none"
|
272
|
+
},
|
273
|
+
"enabled": false,
|
274
|
+
"listingImageUrl": "https://some-random-url.com/assets/banner.jpeg"
|
275
|
+
},
|
276
|
+
"experiences": {
|
277
|
+
"title": {
|
278
|
+
"text": "Travel",
|
279
|
+
"color": "#FFFFFF",
|
280
|
+
"transform": "none"
|
281
|
+
},
|
282
|
+
"enabled": false,
|
283
|
+
"listingImageUrl": "https://some-random-url.com/assets/banner.jpeg"
|
284
|
+
},
|
285
|
+
"hotels": {
|
286
|
+
"title": {
|
287
|
+
"text": "Travel",
|
288
|
+
"color": "#FFFFFF",
|
289
|
+
"transform": "none"
|
290
|
+
},
|
291
|
+
"enabled": false,
|
292
|
+
"listingImageUrl": "https://some-random-url.com/assets/banner.jpeg"
|
293
|
+
},
|
294
|
+
"flights": {
|
295
|
+
"title": {
|
296
|
+
"text": "Travel",
|
297
|
+
"color": "#FFFFFF",
|
298
|
+
"transform": "none"
|
299
|
+
},
|
300
|
+
"enabled": false,
|
301
|
+
"listingImageUrl": "https://some-random-url.com/assets/banner.jpeg"
|
302
|
+
}
|
303
|
+
},
|
304
|
+
"description": {
|
305
|
+
"color": "#FFFFFF",
|
306
|
+
"text": "Book with points and choose from 200 events & 900,000 streams globally",
|
307
|
+
"transform": "none"
|
308
|
+
}
|
309
|
+
},
|
310
|
+
"travelEarn": {
|
311
|
+
"enabled": false
|
312
|
+
},
|
313
|
+
"pointsEarn": {
|
314
|
+
"enabled": false
|
315
|
+
},
|
316
|
+
"helpCenter": {
|
317
|
+
"contactUs": {
|
318
|
+
"externalContactUsEnabled": false,
|
319
|
+
"imageUrl": "https://some-random-url.com/assets/help_center.jpg",
|
320
|
+
"title": {
|
321
|
+
"color": "#FFFFFF",
|
322
|
+
"text": "Contact Us",
|
323
|
+
"transform": "none"
|
324
|
+
}
|
325
|
+
},
|
326
|
+
"customerService": {
|
327
|
+
"imageUrl": "https://some-random-url.com/assets/customer_service.jpg"
|
328
|
+
},
|
329
|
+
"email": {
|
330
|
+
"emailAddress": "cs@example.com",
|
331
|
+
"enabled": true
|
332
|
+
},
|
333
|
+
"listing": {
|
334
|
+
"imageUrl": "https://some-random-url.com/assets/help_center.jpg",
|
335
|
+
"title": {
|
336
|
+
"color": "#FFFFFF",
|
337
|
+
"text": "Help Centre",
|
338
|
+
"transform": "none"
|
339
|
+
}
|
340
|
+
},
|
341
|
+
"phone": {
|
342
|
+
"contactNumber": "0000 999 9999",
|
343
|
+
"enabled": true,
|
344
|
+
"hours": "Mon - Fri (9am-6pm)"
|
345
|
+
},
|
346
|
+
"privacyPolicy": {
|
347
|
+
"imageUrl": "https://some-random-url.com/assets/privacy_policy.jpg"
|
348
|
+
},
|
349
|
+
"termsAndConditions": {
|
350
|
+
"imageUrl": "https://some-random-url.com/assets/terms_of_use.jpg"
|
351
|
+
}
|
352
|
+
},
|
353
|
+
"personalization": {
|
354
|
+
"similarItems": {
|
355
|
+
"giftCardDetails": {
|
356
|
+
"enabled": false
|
357
|
+
},
|
358
|
+
"giftCardCheckout": {
|
359
|
+
"enabled": false
|
360
|
+
},
|
361
|
+
"pointsTransferDetails": {
|
362
|
+
"enabled": false
|
363
|
+
},
|
364
|
+
"pointsTransferCheckout": {
|
365
|
+
"enabled": false
|
366
|
+
},
|
367
|
+
"cashbackDetails": {
|
368
|
+
"enabled": false
|
369
|
+
},
|
370
|
+
"cashbackCheckout": {
|
371
|
+
"enabled": false
|
372
|
+
},
|
373
|
+
"sustainabilityDetails": {
|
374
|
+
"enabled": false
|
375
|
+
},
|
376
|
+
"sustainabilityCheckout": {
|
377
|
+
"enabled": false
|
378
|
+
},
|
379
|
+
"cryptoDetails": {
|
380
|
+
"enabled": false
|
381
|
+
},
|
382
|
+
"cryptoCheckout": {
|
383
|
+
"enabled": false
|
384
|
+
},
|
385
|
+
"voucherDetails": {
|
386
|
+
"enabled": false
|
387
|
+
},
|
388
|
+
"voucherCheckout": {
|
389
|
+
"enabled": false
|
390
|
+
}
|
391
|
+
},
|
392
|
+
"giftCardListing": {
|
393
|
+
"enabled": false
|
394
|
+
},
|
395
|
+
"pointsTransferListing": {
|
396
|
+
"enabled": false
|
397
|
+
}
|
398
|
+
},
|
399
|
+
"appleMerchandise": {
|
400
|
+
"enabled": false
|
401
|
+
},
|
402
|
+
"freeformPointsInput": {
|
403
|
+
"travel": {
|
404
|
+
"enabled": false,
|
405
|
+
"defaultMaxPoints": false
|
406
|
+
}
|
407
|
+
}
|
408
|
+
},
|
409
|
+
"homepage": [
|
410
|
+
{
|
411
|
+
"data": [
|
412
|
+
{
|
413
|
+
"body": {
|
414
|
+
"content": "Earning loyalty points has never been more rewarding. Redeem them for exclusive events packages and stream the world in style. Start planning your dream cluster now.",
|
415
|
+
"textTransform": "none"
|
416
|
+
},
|
417
|
+
"image": {
|
418
|
+
"alt": "third carou image",
|
419
|
+
"url": "https://some-random-url.com/assets/hero_banner.png"
|
420
|
+
},
|
421
|
+
"title": {
|
422
|
+
"content": "A world of rewards awaits",
|
423
|
+
"textTransform": "none"
|
424
|
+
},
|
425
|
+
"config": {
|
426
|
+
"variant": "marketing-banner-1",
|
427
|
+
"textAlign": "text-left"
|
428
|
+
}
|
429
|
+
}
|
430
|
+
],
|
431
|
+
"type": "marketing-banner"
|
432
|
+
},
|
433
|
+
{
|
434
|
+
"type": "redeem-again"
|
435
|
+
},
|
436
|
+
{
|
437
|
+
"type": "spend-x-points"
|
438
|
+
},
|
439
|
+
{
|
440
|
+
"type": "save-up-to-your-points"
|
441
|
+
},
|
442
|
+
{
|
443
|
+
"data": [
|
444
|
+
{
|
445
|
+
"body": {
|
446
|
+
"content": "Earning loyalty points has never been more rewarding. Redeem them for exclusive events packages and stream the world in style. Start streaming your dreams now.",
|
447
|
+
"textTransform": "none"
|
448
|
+
},
|
449
|
+
"image": {
|
450
|
+
"alt": "Earning loyalty points has never been more rewarding.",
|
451
|
+
"url": "https://some-random-url.com/assets/carousel.png"
|
452
|
+
},
|
453
|
+
"title": {
|
454
|
+
"content": "Escape to your next adventure with a click of a button.",
|
455
|
+
"textTransform": "none"
|
456
|
+
},
|
457
|
+
"variant": "carousel-1"
|
458
|
+
}
|
459
|
+
],
|
460
|
+
"type": "carousel"
|
461
|
+
},
|
462
|
+
{
|
463
|
+
"fallbackData": [],
|
464
|
+
"config": {
|
465
|
+
"title": "Recommended for you"
|
466
|
+
},
|
467
|
+
"type": "personalization"
|
468
|
+
},
|
469
|
+
{
|
470
|
+
"config": {
|
471
|
+
"title": "You'll love these ways to earn points faster",
|
472
|
+
"backgroundColor": "#f6f6f6",
|
473
|
+
"tileBackgroundColor": "#FFFFFF"
|
474
|
+
},
|
475
|
+
"data": [
|
476
|
+
{
|
477
|
+
"icon": null,
|
478
|
+
"id": "pt_0",
|
479
|
+
"image": {
|
480
|
+
"url": "https://some-random-url.com/assets/frequent_traveller_programs_icon.jpg",
|
481
|
+
"alt": "Frequent Streamer Program icon"
|
482
|
+
},
|
483
|
+
"productType": "points-transfer",
|
484
|
+
"title": "Frequent Streamer Program",
|
485
|
+
"type": "listing"
|
486
|
+
},
|
487
|
+
{
|
488
|
+
"icon": null,
|
489
|
+
"id": "gc_0",
|
490
|
+
"image": {
|
491
|
+
"url": "https://some-random-url.com/assets/gift_card_icon.png",
|
492
|
+
"alt": "Gift Card Icon"
|
493
|
+
},
|
494
|
+
"productType": "gift-card",
|
495
|
+
"title": "Gift Card",
|
496
|
+
"type": "listing"
|
497
|
+
},
|
498
|
+
{
|
499
|
+
"icon": null,
|
500
|
+
"id": "crypto_0",
|
501
|
+
"image": {
|
502
|
+
"url": "https://some-random-url.com/assets/crypto_icon.jpg",
|
503
|
+
"alt": "Crypto Icon"
|
504
|
+
},
|
505
|
+
"productType": "crypto",
|
506
|
+
"title": "Crypto",
|
507
|
+
"type": "listing"
|
508
|
+
},
|
509
|
+
{
|
510
|
+
"icon": null,
|
511
|
+
"id": "substain_0",
|
512
|
+
"image": {
|
513
|
+
"url": "https://some-random-url.com/assets/sustainability_icon.jpg",
|
514
|
+
"alt": "Sustainability Icon"
|
515
|
+
},
|
516
|
+
"productType": "carbon",
|
517
|
+
"title": "Sustainability",
|
518
|
+
"type": "listing"
|
519
|
+
},
|
520
|
+
{
|
521
|
+
"icon": null,
|
522
|
+
"id": "cashback_0",
|
523
|
+
"image": {
|
524
|
+
"url": "https://some-random-url.com/assets/cashback_icon.png",
|
525
|
+
"alt": "Cashback icon"
|
526
|
+
},
|
527
|
+
"productType": "cashback",
|
528
|
+
"title": "Cashback",
|
529
|
+
"type": "listing"
|
530
|
+
}
|
531
|
+
],
|
532
|
+
"type": "quick-links"
|
533
|
+
},
|
534
|
+
{
|
535
|
+
"config": {
|
536
|
+
"title": "Campaigns for you"
|
537
|
+
},
|
538
|
+
"type": "campaign-banner"
|
539
|
+
}
|
540
|
+
],
|
541
|
+
"theme": {
|
542
|
+
"bodyFont": "Poppins",
|
543
|
+
"brandLogo": "https://some-random-url.com/assets/alternative_logo.png",
|
544
|
+
"colors": {
|
545
|
+
"accent": "#05A0D1",
|
546
|
+
"primary": "#22285A",
|
547
|
+
"secondary": "#05A0D1"
|
548
|
+
},
|
549
|
+
"favicon": "https://some-random-url.com/assets/favicon.png",
|
550
|
+
"headingFont": "Poppins",
|
551
|
+
"iconStyle": "solid",
|
552
|
+
"invertedLogo": "https://some-random-url.com/assets/alternative_logo.png",
|
553
|
+
"overlayStyle": "#22285A"
|
554
|
+
},
|
555
|
+
"tenantLocales": [
|
556
|
+
{
|
557
|
+
"locale": "en-US",
|
558
|
+
"enabled": true,
|
559
|
+
"defaultForTenant": true
|
560
|
+
}
|
561
|
+
]
|
562
|
+
},
|
563
|
+
"platform": {
|
564
|
+
"auth": {
|
565
|
+
"appId": "bf9f91ab-ccbd-4a45-a7c8-63893298b71e",
|
566
|
+
"connection": "magic_link",
|
567
|
+
"idleCheckConfig": {
|
568
|
+
"promptTimeout": 120,
|
569
|
+
"timeout": 36000
|
570
|
+
},
|
571
|
+
"scope": "openid,address,email,phone,profile,custom",
|
572
|
+
"sessionCheckPollInterval": 60
|
573
|
+
}
|
574
|
+
}
|
575
|
+
},
|
576
|
+
"is_corporate": false,
|
577
|
+
"configuration_change_id": "0727c699-212a-4c1f-b0d4-e975d44aecab"
|
578
|
+
}
|
579
|
+
}
|