octocore-cassandra 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES.md +12 -0
  3. data/CONTRIBUTING +0 -0
  4. data/Gemfile +10 -0
  5. data/LICENSE +202 -0
  6. data/MAINTAINERS +0 -0
  7. data/NOTICE +8 -0
  8. data/README.md +69 -0
  9. data/Rakefile +142 -0
  10. data/bin/fakestream-cassandra +258 -0
  11. data/bin/octocore-admin-cassandra +54 -0
  12. data/lib/octocore-cassandra.rb +152 -0
  13. data/lib/octocore-cassandra/baseline.rb +131 -0
  14. data/lib/octocore-cassandra/callbacks.rb +117 -0
  15. data/lib/octocore-cassandra/config.rb +39 -0
  16. data/lib/octocore-cassandra/config/config.yml +1 -0
  17. data/lib/octocore-cassandra/config/search/index/user.yml +42 -0
  18. data/lib/octocore-cassandra/counter.rb +265 -0
  19. data/lib/octocore-cassandra/counter/helpers.rb +168 -0
  20. data/lib/octocore-cassandra/email.rb +63 -0
  21. data/lib/octocore-cassandra/featureflag.rb +79 -0
  22. data/lib/octocore-cassandra/helpers.rb +6 -0
  23. data/lib/octocore-cassandra/helpers/api_consumer_helper.rb +51 -0
  24. data/lib/octocore-cassandra/helpers/api_helper.rb +65 -0
  25. data/lib/octocore-cassandra/helpers/api_logger.rb +14 -0
  26. data/lib/octocore-cassandra/helpers/client_helper.rb +104 -0
  27. data/lib/octocore-cassandra/helpers/kong_helper.rb +164 -0
  28. data/lib/octocore-cassandra/helpers/sinatra_helper.rb +22 -0
  29. data/lib/octocore-cassandra/kafka_bridge.rb +60 -0
  30. data/lib/octocore-cassandra/kldivergence.rb +14 -0
  31. data/lib/octocore-cassandra/mailer.rb +1 -0
  32. data/lib/octocore-cassandra/mailer/subscriber_mailer.rb +30 -0
  33. data/lib/octocore-cassandra/message_parser.rb +114 -0
  34. data/lib/octocore-cassandra/models.rb +274 -0
  35. data/lib/octocore-cassandra/models/contactus.rb +42 -0
  36. data/lib/octocore-cassandra/models/enterprise.rb +76 -0
  37. data/lib/octocore-cassandra/models/enterprise/adapter_details.rb +18 -0
  38. data/lib/octocore-cassandra/models/enterprise/api_event.rb +14 -0
  39. data/lib/octocore-cassandra/models/enterprise/api_hit.rb +20 -0
  40. data/lib/octocore-cassandra/models/enterprise/api_key.rb +11 -0
  41. data/lib/octocore-cassandra/models/enterprise/api_track.rb +13 -0
  42. data/lib/octocore-cassandra/models/enterprise/app_init.rb +13 -0
  43. data/lib/octocore-cassandra/models/enterprise/app_login.rb +12 -0
  44. data/lib/octocore-cassandra/models/enterprise/app_logout.rb +12 -0
  45. data/lib/octocore-cassandra/models/enterprise/authorization.rb +67 -0
  46. data/lib/octocore-cassandra/models/enterprise/category.rb +14 -0
  47. data/lib/octocore-cassandra/models/enterprise/category_baseline.rb +19 -0
  48. data/lib/octocore-cassandra/models/enterprise/category_hit.rb +26 -0
  49. data/lib/octocore-cassandra/models/enterprise/category_trend.rb +19 -0
  50. data/lib/octocore-cassandra/models/enterprise/conversions.rb +69 -0
  51. data/lib/octocore-cassandra/models/enterprise/ctr.rb +54 -0
  52. data/lib/octocore-cassandra/models/enterprise/dimension_choice.rb +21 -0
  53. data/lib/octocore-cassandra/models/enterprise/engagement_time.rb +43 -0
  54. data/lib/octocore-cassandra/models/enterprise/funnel_data.rb +20 -0
  55. data/lib/octocore-cassandra/models/enterprise/funnel_tracker.rb +19 -0
  56. data/lib/octocore-cassandra/models/enterprise/funnels.rb +129 -0
  57. data/lib/octocore-cassandra/models/enterprise/gcm.rb +21 -0
  58. data/lib/octocore-cassandra/models/enterprise/newsfeed_hit.rb +52 -0
  59. data/lib/octocore-cassandra/models/enterprise/notification_hit.rb +42 -0
  60. data/lib/octocore-cassandra/models/enterprise/page.rb +15 -0
  61. data/lib/octocore-cassandra/models/enterprise/page_view.rb +14 -0
  62. data/lib/octocore-cassandra/models/enterprise/pageload_time.rb +43 -0
  63. data/lib/octocore-cassandra/models/enterprise/product.rb +22 -0
  64. data/lib/octocore-cassandra/models/enterprise/product_baseline.rb +20 -0
  65. data/lib/octocore-cassandra/models/enterprise/product_hit.rb +26 -0
  66. data/lib/octocore-cassandra/models/enterprise/product_page_view.rb +13 -0
  67. data/lib/octocore-cassandra/models/enterprise/product_trend.rb +18 -0
  68. data/lib/octocore-cassandra/models/enterprise/push_key.rb +15 -0
  69. data/lib/octocore-cassandra/models/enterprise/rules.rb +45 -0
  70. data/lib/octocore-cassandra/models/enterprise/segment.rb +65 -0
  71. data/lib/octocore-cassandra/models/enterprise/segment_data.rb +22 -0
  72. data/lib/octocore-cassandra/models/enterprise/tag.rb +14 -0
  73. data/lib/octocore-cassandra/models/enterprise/tag_baseline.rb +19 -0
  74. data/lib/octocore-cassandra/models/enterprise/tag_hit.rb +26 -0
  75. data/lib/octocore-cassandra/models/enterprise/tag_trend.rb +19 -0
  76. data/lib/octocore-cassandra/models/enterprise/template.rb +18 -0
  77. data/lib/octocore-cassandra/models/plans.rb +17 -0
  78. data/lib/octocore-cassandra/models/subscribe.rb +13 -0
  79. data/lib/octocore-cassandra/models/user.rb +15 -0
  80. data/lib/octocore-cassandra/models/user/push_token.rb +15 -0
  81. data/lib/octocore-cassandra/models/user/user_browser_details.rb +16 -0
  82. data/lib/octocore-cassandra/models/user/user_location_history.rb +15 -0
  83. data/lib/octocore-cassandra/models/user/user_persona.rb +101 -0
  84. data/lib/octocore-cassandra/models/user/user_phone_details.rb +17 -0
  85. data/lib/octocore-cassandra/models/user/user_profile.rb +20 -0
  86. data/lib/octocore-cassandra/models/user/user_timeline.rb +111 -0
  87. data/lib/octocore-cassandra/record.rb +20 -0
  88. data/lib/octocore-cassandra/schedeuleable.rb +20 -0
  89. data/lib/octocore-cassandra/scheduler.rb +72 -0
  90. data/lib/octocore-cassandra/search.rb +5 -0
  91. data/lib/octocore-cassandra/search/client.rb +33 -0
  92. data/lib/octocore-cassandra/search/indexer.rb +0 -0
  93. data/lib/octocore-cassandra/search/searchable.rb +18 -0
  94. data/lib/octocore-cassandra/search/setup.rb +71 -0
  95. data/lib/octocore-cassandra/segment.rb +287 -0
  96. data/lib/octocore-cassandra/stats.rb +33 -0
  97. data/lib/octocore-cassandra/trendable.rb +88 -0
  98. data/lib/octocore-cassandra/trends.rb +158 -0
  99. data/lib/octocore-cassandra/utils.rb +90 -0
  100. data/lib/octocore-cassandra/version.rb +4 -0
  101. data/spec/lib/stats_spec.rb +20 -0
  102. data/spec/spec_helper.rb +103 -0
  103. metadata +490 -0
@@ -0,0 +1,274 @@
1
+ require 'cequel'
2
+ require 'redis'
3
+
4
+
5
+ module Cequel
6
+ module Record
7
+
8
+ include ActiveModel::Serializers::JSON
9
+
10
+ DUMP_ATTRS = [:@attributes] #, :@collection_proxies, :@loaded, :@persisted, :@record_collection]
11
+
12
+ # Updates caching config
13
+ # @param [String] host The host to connect to
14
+ # @param [Fixnum] port The port to connect to
15
+ def self.update_cache_config(host, port)
16
+ @redis = Redis.new(host: host,
17
+ port: port,
18
+ driver: :hiredis)
19
+ end
20
+
21
+ # Getter for redis object
22
+ # @return [Redis] redis cache instance
23
+ def self.redis
24
+ @redis
25
+ end
26
+
27
+ def marshal_dump
28
+ DUMP_ATTRS.inject({}) do |val, attr|
29
+ val[attr] = self.instance_variable_get(attr)
30
+ val
31
+ end
32
+ end
33
+
34
+ def marshal_load(data)
35
+ DUMP_ATTRS.each do |attr|
36
+ instance_variable_set(attr, data[attr])
37
+ end
38
+ instance_variable_set(:@collection_proxies, {})
39
+ instance_variable_set(:@record_collection, nil)
40
+ end
41
+
42
+ # Override Cequel::Record here
43
+ module ClassMethods
44
+
45
+ # fakes up data
46
+ def fake_data_with(args, values, opts={})
47
+ res = []
48
+ ts = args.fetch(:ts, 7.days.ago..Time.now.floor)
49
+ if ts.class == Range
50
+ bod = opts.fetch(:bod, false)
51
+ ts_begin = ts.begin
52
+ ts_end = ts.end
53
+ if bod
54
+ ts_begin = ts_begin.beginning_of_day
55
+ ts_end = ts_end.end_of_day
56
+ end
57
+ step = opts.fetch(:step, 1.minute)
58
+ ts_begin.to(ts_end, step).each do |_ts|
59
+ _args = args.merge({ ts: _ts })
60
+ r = self.where(_args)
61
+ if r.count == 0
62
+ res << self.new(_args.merge(values)).save!
63
+ else
64
+ res << r
65
+ end
66
+ end
67
+ elsif ts.class == Time
68
+ _args = args.merge({ ts: ts }).merge(values)
69
+ res << self.new(_args).save!
70
+ end
71
+ res.flatten
72
+ end
73
+
74
+ # Recreates this object from other object
75
+ def recreate_from(obj)
76
+ keys = self.key_column_names
77
+ args = {}
78
+ if obj.respond_to?(:enterprise_id) and obj.respond_to?(:uid)
79
+ args[keys.delete(:enterprise_id)] = obj.enterprise_id
80
+ if keys.length == 1
81
+ args[keys.first] = obj.uid
82
+ self.get_cached(args)
83
+ else
84
+ puts keys.to_a.to_s
85
+ raise NotImplementedError, 'See octocore/models.rb'
86
+ end
87
+ end
88
+ end
89
+
90
+ # If a record exists, will find it and update it's value with the
91
+ # provided options. Else, will just create the record.
92
+ def findOrCreateOrUpdate(args, options = {})
93
+ cache_key = gen_cache_key(args)
94
+ res = get_cached(args)
95
+ if res
96
+ dirty = false
97
+
98
+ # handle price separately because of float issues
99
+ if options.has_key?(:price)
100
+ _v = options.delete(:price)
101
+ dirty = _v.round(2) != res.price.round(2)
102
+ end
103
+
104
+ # remaining opts
105
+ options.each do |k, v|
106
+ if res.respond_to?(k)
107
+ unless res.public_send(k) == v
108
+ dirty = true
109
+ res.public_send("#{ k }=", v)
110
+ end
111
+ end
112
+ end
113
+
114
+ if dirty
115
+ res.save!
116
+ Cequel::Record.redis.setex(cache_key, get_ttl,
117
+ Octo::Utils.serialize(res))
118
+ end
119
+ else
120
+ _args = args.merge(options)
121
+ res = self.new(_args).save!
122
+ Cequel::Record.redis.setex(cache_key, get_ttl,
123
+ Octo::Utils.serialize(res))
124
+ end
125
+ res
126
+ end
127
+
128
+ # Finds the record/recordset satisfying a `where` condition
129
+ # or create a new record from the params passed
130
+ # @param [Hash] args The args used to build `where` condition
131
+ # @param [Hash] options The options used to construct record
132
+ def findOrCreate(args, options = {})
133
+ # attempt to find the record
134
+ res = get_cached(args)
135
+
136
+ # on failure, do
137
+ unless res
138
+ args.merge!(options)
139
+ res = self.new(args).save!
140
+
141
+ # Update cache
142
+ cache_key = gen_cache_key(args)
143
+ Cequel::Record.redis.setex(cache_key, get_ttl, Octo::Utils.serialize(res))
144
+ end
145
+ res
146
+ end
147
+
148
+
149
+ # If a record exists in a COUNTER TABLE, it will find
150
+ # it and increment or decrement it's value with the
151
+ # provided options. Else, will just create the
152
+ # record with default value.
153
+ def findOrCreateOrAdjust(args, options)
154
+ self.where(args).data_set.increment(options)
155
+ end
156
+
157
+
158
+ # Perform a cache backed get
159
+ # @param [Hash] args The arguments hash for the record
160
+ # to be found
161
+ # @return [Cequel::Record::RecordSet] The record matching
162
+ def get_cached(args)
163
+ cache_key = gen_cache_key(args)
164
+
165
+ begin
166
+ cached_val = Cequel::Record.redis.get(cache_key)
167
+ rescue Exception
168
+ cached_val = nil
169
+ end
170
+
171
+ unless cached_val
172
+ res = where(args)
173
+ result_count = res.count
174
+ if result_count == 0
175
+ return nil
176
+ elsif result_count == 1
177
+ cached_val = Octo::Utils.serialize(res.first)
178
+ Cequel::Record.redis.setex(cache_key, get_ttl, cached_val)
179
+ elsif result_count > 1
180
+ cached_val = Octo::Utils.serialize(res)
181
+ Cequel::Record.redis.setex(cache_key, get_ttl, cached_val)
182
+ end
183
+ end
184
+ begin
185
+ Octo::Utils.deserialize(cached_val)
186
+ rescue Exception => e
187
+ Octo.logger.error e
188
+ nil
189
+ end
190
+ end
191
+
192
+ private
193
+
194
+ # Generate cache key
195
+ # @param [Hash] args The arguments for fetching hash
196
+ # @return [String] Cache key generated
197
+ def gen_cache_key(args)
198
+ args = args.flatten
199
+ args.unshift(self.name.to_s)
200
+ args.join('::')
201
+ end
202
+
203
+ def get_ttl
204
+ # default ttl of 1 hour
205
+ ttl = 60
206
+ if self.constants.include?(:TTL)
207
+ ttl = self.const_get(:TTL)
208
+ end
209
+
210
+ # convert ttl into seconds
211
+ ttl *= 60
212
+ end
213
+
214
+ end
215
+ end
216
+ end
217
+
218
+
219
+ require 'octocore-cassandra/models/enterprise'
220
+ require 'octocore-cassandra/models/enterprise/adapter_details'
221
+ require 'octocore-cassandra/models/enterprise/api_event'
222
+ require 'octocore-cassandra/models/enterprise/api_hit'
223
+ require 'octocore-cassandra/models/enterprise/api_key'
224
+ require 'octocore-cassandra/models/enterprise/api_track'
225
+ require 'octocore-cassandra/models/enterprise/app_init'
226
+ require 'octocore-cassandra/models/enterprise/app_login'
227
+ require 'octocore-cassandra/models/enterprise/app_logout'
228
+ require 'octocore-cassandra/models/enterprise/authorization'
229
+ require 'octocore-cassandra/models/enterprise/category'
230
+ require 'octocore-cassandra/models/enterprise/category_baseline'
231
+ require 'octocore-cassandra/models/enterprise/category_hit'
232
+ require 'octocore-cassandra/models/enterprise/category_trend'
233
+ require 'octocore-cassandra/models/enterprise/conversions'
234
+ require 'octocore-cassandra/models/enterprise/ctr'
235
+ require 'octocore-cassandra/models/enterprise/dimension_choice'
236
+ require 'octocore-cassandra/models/enterprise/engagement_time'
237
+ require 'octocore-cassandra/models/enterprise/funnels'
238
+ require 'octocore-cassandra/models/enterprise/funnel_data'
239
+ require 'octocore-cassandra/models/enterprise/funnel_tracker'
240
+
241
+ require 'octocore-cassandra/models/enterprise/gcm'
242
+ require 'octocore-cassandra/models/enterprise/newsfeed_hit'
243
+ require 'octocore-cassandra/models/enterprise/notification_hit'
244
+ require 'octocore-cassandra/models/enterprise/page'
245
+ require 'octocore-cassandra/models/enterprise/pageload_time'
246
+ require 'octocore-cassandra/models/enterprise/page_view'
247
+ require 'octocore-cassandra/models/enterprise/product'
248
+ require 'octocore-cassandra/models/enterprise/product_baseline'
249
+ require 'octocore-cassandra/models/enterprise/product_hit'
250
+ require 'octocore-cassandra/models/enterprise/product_page_view'
251
+ require 'octocore-cassandra/models/enterprise/product_trend'
252
+ require 'octocore-cassandra/models/enterprise/push_key'
253
+ require 'octocore-cassandra/models/enterprise/rules'
254
+ require 'octocore-cassandra/models/enterprise/segment.rb'
255
+ require 'octocore-cassandra/models/enterprise/segment_data.rb'
256
+ require 'octocore-cassandra/models/enterprise/tag'
257
+ require 'octocore-cassandra/models/enterprise/tag_hit'
258
+ require 'octocore-cassandra/models/enterprise/tag_baseline'
259
+ require 'octocore-cassandra/models/enterprise/tag_trend'
260
+ require 'octocore-cassandra/models/enterprise/template'
261
+
262
+ require 'octocore-cassandra/models/user'
263
+ require 'octocore-cassandra/models/user/push_token'
264
+ require 'octocore-cassandra/models/user/user_browser_details'
265
+ require 'octocore-cassandra/models/user/user_location_history'
266
+ require 'octocore-cassandra/models/user/user_persona'
267
+ require 'octocore-cassandra/models/user/user_phone_details'
268
+ require 'octocore-cassandra/models/user/user_profile'
269
+ require 'octocore-cassandra/models/user/user_timeline'
270
+
271
+ require 'octocore-cassandra/models/subscribe'
272
+ require 'octocore-cassandra/models/contactus'
273
+
274
+ require 'octocore-cassandra/utils'
@@ -0,0 +1,42 @@
1
+ require 'cequel'
2
+
3
+ # Model for contact us page on the microsite
4
+ module Octo
5
+ class ContactUs
6
+ include Cequel::Record
7
+
8
+ key :email, :text
9
+ key :created_at, :timestamp
10
+
11
+ column :typeofrequest, :text
12
+ column :firstname, :text
13
+ column :lastname, :text
14
+ column :message, :text
15
+
16
+ after_create :send_email
17
+
18
+ # Send Email after model save
19
+ def send_email
20
+
21
+ # Send thankyou mail
22
+ subject = 'Thanks for contacting us - Octo.ai'
23
+ opts = {
24
+ text: 'Hey we will get in touch with you shortly. Thanks :)',
25
+ name: self.firstname + ' ' + self.lastname
26
+ }
27
+ Octo::Email.send(self.email, subject, opts)
28
+
29
+ # Send mail to aron and param
30
+ Octo.get_config(:email_to).each { |x|
31
+ opts1 = {
32
+ text: self.email + ' \n\r ' + self.typeofrequest + '\n\r' + self.message,
33
+ name: x.fetch('name')
34
+ }
35
+ Octo::Email.send(x.fetch('email'), subject, opts1)
36
+ }
37
+
38
+
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,76 @@
1
+ require 'cequel'
2
+
3
+ module Octo
4
+ class Enterprise
5
+ include Cequel::Record
6
+
7
+ # Set ttl of 120 minutes for the caches
8
+ TTL = 120
9
+
10
+ key :id, :uuid, auto: true
11
+ column :name, :varchar
12
+
13
+ has_many :users, class_name: 'Octo::User'
14
+ has_many :segments, class_name: 'Octo::Segment'
15
+ has_many :templates, class_name: 'Octo::Template'
16
+ has_many :funnels, class_name: 'Octo::Funnel'
17
+ has_many :conversions, class_name: 'Octo::Conversions'
18
+
19
+ after_save :_setup
20
+
21
+ # Setup the new enterprise
22
+ def _setup
23
+ setup_notification_categories
24
+ setup_intelligent_segments
25
+ end
26
+
27
+ # Method to check if it is okay to create fakedata for this
28
+ # client
29
+ # @return [Boolean]
30
+ def fakedata?
31
+ self.name.start_with?('Octo')
32
+ end
33
+
34
+ private
35
+
36
+ # Setup the notification categories for the enterprise
37
+ def setup_notification_categories
38
+ templates = Octo.get_config(:push_templates)
39
+ if templates
40
+ templates.each do |t|
41
+ args = {
42
+ enterprise_id: self.id,
43
+ category_type: t[:name],
44
+ template_text: t[:text],
45
+ active: true
46
+ }
47
+ Octo::Template.new(args).save!
48
+ end
49
+ Octo.logger.info("Created templates for Enterprise: #{ self.name }")
50
+ end
51
+ end
52
+
53
+ # Setup the intelligent segments for the enterprise
54
+ def setup_intelligent_segments
55
+ segments = Octo.get_config(:intelligent_segments)
56
+ if segments
57
+ segments.each do |seg|
58
+ args = {
59
+ enterprise_id: self.id,
60
+ name: seg[:name],
61
+ type: seg[:type].constantize,
62
+ dimensions: seg[:dimensions].collect(&:constantize),
63
+ operators: seg[:operators].collect(&:constantize),
64
+ values: seg[:values].collect(&:constantize),
65
+ active: true,
66
+ intelligence: true,
67
+ }
68
+ Octo::Segment.new(args).save!
69
+ end
70
+ Octo.logger.info "Created segents for Enterprise: #{ self.name }"
71
+ end
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,18 @@
1
+ require 'cequel'
2
+ require 'octocore-cassandra/record'
3
+
4
+ module Octo
5
+ # Store adapter details of Enterprise
6
+ class AdapterDetails
7
+ include Cequel::Record
8
+ include Octo::Record
9
+
10
+ belongs_to :enterprise, class_name: 'Octo::Enterprise'
11
+
12
+ key :adapter_id, :int
13
+ key :enable, :boolean
14
+
15
+ column :settings, :text
16
+
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ require 'cequel'
2
+ require 'octocore-cassandra/record'
3
+
4
+ module Octo
5
+ class ApiEvent
6
+ include Cequel::Record
7
+ include Octo::Record
8
+
9
+ belongs_to :enterprise, class_name: 'Octo::Enterprise'
10
+
11
+ key :eventname, :text
12
+ end
13
+ end
14
+
@@ -0,0 +1,20 @@
1
+ require 'cequel'
2
+
3
+ require 'octocore-cassandra/counter'
4
+ require 'octocore-cassandra/trendable'
5
+ require 'octocore-cassandra/schedeuleable'
6
+
7
+ module Octo
8
+ class ApiHit
9
+ include Cequel::Record
10
+ extend Octo::Counter
11
+ extend Octo::Scheduleable
12
+
13
+ COUNTERS = 30
14
+
15
+ belongs_to :enterprise, class_name: 'Octo::Enterprise'
16
+
17
+ countables
18
+
19
+ end
20
+ end