octocore-mongo 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGES.md +12 -0
- data/CONTRIBUTING +0 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +150 -0
- data/LICENSE +202 -0
- data/MAINTAINERS +0 -0
- data/NOTICE +8 -0
- data/README.md +69 -0
- data/Rakefile +51 -0
- data/bin/fakestream-mongo +258 -0
- data/bin/octocore-admin-mongo +54 -0
- data/lib/octocore-mongo.rb +157 -0
- data/lib/octocore-mongo/baseline.rb +131 -0
- data/lib/octocore-mongo/callbacks.rb +117 -0
- data/lib/octocore-mongo/config.rb +39 -0
- data/lib/octocore-mongo/config/config.yml +1 -0
- data/lib/octocore-mongo/config/search/index/user.yml +42 -0
- data/lib/octocore-mongo/counter.rb +265 -0
- data/lib/octocore-mongo/counter/helpers.rb +168 -0
- data/lib/octocore-mongo/email.rb +63 -0
- data/lib/octocore-mongo/featureflag.rb +79 -0
- data/lib/octocore-mongo/helpers.rb +6 -0
- data/lib/octocore-mongo/helpers/api_consumer_helper.rb +51 -0
- data/lib/octocore-mongo/helpers/api_helper.rb +65 -0
- data/lib/octocore-mongo/helpers/api_logger.rb +14 -0
- data/lib/octocore-mongo/helpers/client_helper.rb +104 -0
- data/lib/octocore-mongo/helpers/kong_helper.rb +164 -0
- data/lib/octocore-mongo/helpers/sinatra_helper.rb +22 -0
- data/lib/octocore-mongo/kafka_bridge.rb +60 -0
- data/lib/octocore-mongo/kldivergence.rb +14 -0
- data/lib/octocore-mongo/mailer.rb +1 -0
- data/lib/octocore-mongo/mailer/subscriber_mailer.rb +32 -0
- data/lib/octocore-mongo/message_parser.rb +114 -0
- data/lib/octocore-mongo/models.rb +275 -0
- data/lib/octocore-mongo/models/contactus.rb +42 -0
- data/lib/octocore-mongo/models/enterprise.rb +75 -0
- data/lib/octocore-mongo/models/enterprise/adapter_details.rb +18 -0
- data/lib/octocore-mongo/models/enterprise/api_event.rb +14 -0
- data/lib/octocore-mongo/models/enterprise/api_hit.rb +20 -0
- data/lib/octocore-mongo/models/enterprise/api_key.rb +11 -0
- data/lib/octocore-mongo/models/enterprise/api_track.rb +13 -0
- data/lib/octocore-mongo/models/enterprise/app_init.rb +13 -0
- data/lib/octocore-mongo/models/enterprise/app_login.rb +12 -0
- data/lib/octocore-mongo/models/enterprise/app_logout.rb +12 -0
- data/lib/octocore-mongo/models/enterprise/authorization.rb +67 -0
- data/lib/octocore-mongo/models/enterprise/category.rb +14 -0
- data/lib/octocore-mongo/models/enterprise/category_baseline.rb +19 -0
- data/lib/octocore-mongo/models/enterprise/category_hit.rb +26 -0
- data/lib/octocore-mongo/models/enterprise/category_trend.rb +19 -0
- data/lib/octocore-mongo/models/enterprise/conversions.rb +69 -0
- data/lib/octocore-mongo/models/enterprise/ctr.rb +54 -0
- data/lib/octocore-mongo/models/enterprise/dimension_choice.rb +21 -0
- data/lib/octocore-mongo/models/enterprise/engagement_time.rb +43 -0
- data/lib/octocore-mongo/models/enterprise/funnel_data.rb +20 -0
- data/lib/octocore-mongo/models/enterprise/funnel_tracker.rb +19 -0
- data/lib/octocore-mongo/models/enterprise/funnels.rb +129 -0
- data/lib/octocore-mongo/models/enterprise/gcm.rb +21 -0
- data/lib/octocore-mongo/models/enterprise/newsfeed_hit.rb +52 -0
- data/lib/octocore-mongo/models/enterprise/notification_hit.rb +42 -0
- data/lib/octocore-mongo/models/enterprise/page.rb +15 -0
- data/lib/octocore-mongo/models/enterprise/page_view.rb +14 -0
- data/lib/octocore-mongo/models/enterprise/pageload_time.rb +43 -0
- data/lib/octocore-mongo/models/enterprise/product.rb +22 -0
- data/lib/octocore-mongo/models/enterprise/product_baseline.rb +20 -0
- data/lib/octocore-mongo/models/enterprise/product_hit.rb +26 -0
- data/lib/octocore-mongo/models/enterprise/product_page_view.rb +13 -0
- data/lib/octocore-mongo/models/enterprise/product_trend.rb +18 -0
- data/lib/octocore-mongo/models/enterprise/push_key.rb +15 -0
- data/lib/octocore-mongo/models/enterprise/rules.rb +45 -0
- data/lib/octocore-mongo/models/enterprise/segment.rb +65 -0
- data/lib/octocore-mongo/models/enterprise/segment_data.rb +22 -0
- data/lib/octocore-mongo/models/enterprise/tag.rb +14 -0
- data/lib/octocore-mongo/models/enterprise/tag_baseline.rb +19 -0
- data/lib/octocore-mongo/models/enterprise/tag_hit.rb +26 -0
- data/lib/octocore-mongo/models/enterprise/tag_trend.rb +19 -0
- data/lib/octocore-mongo/models/enterprise/template.rb +18 -0
- data/lib/octocore-mongo/models/plans.rb +17 -0
- data/lib/octocore-mongo/models/subscribe.rb +13 -0
- data/lib/octocore-mongo/models/user.rb +13 -0
- data/lib/octocore-mongo/models/user/push_token.rb +15 -0
- data/lib/octocore-mongo/models/user/user_browser_details.rb +16 -0
- data/lib/octocore-mongo/models/user/user_location_history.rb +15 -0
- data/lib/octocore-mongo/models/user/user_persona.rb +101 -0
- data/lib/octocore-mongo/models/user/user_phone_details.rb +17 -0
- data/lib/octocore-mongo/models/user/user_profile.rb +20 -0
- data/lib/octocore-mongo/models/user/user_timeline.rb +111 -0
- data/lib/octocore-mongo/record.rb +20 -0
- data/lib/octocore-mongo/schedeuleable.rb +20 -0
- data/lib/octocore-mongo/scheduler.rb +72 -0
- data/lib/octocore-mongo/search.rb +5 -0
- data/lib/octocore-mongo/search/client.rb +33 -0
- data/lib/octocore-mongo/search/indexer.rb +0 -0
- data/lib/octocore-mongo/search/searchable.rb +18 -0
- data/lib/octocore-mongo/search/setup.rb +71 -0
- data/lib/octocore-mongo/segment.rb +287 -0
- data/lib/octocore-mongo/stats.rb +33 -0
- data/lib/octocore-mongo/trendable.rb +88 -0
- data/lib/octocore-mongo/trends.rb +158 -0
- data/lib/octocore-mongo/utils.rb +90 -0
- data/lib/octocore-mongo/version.rb +4 -0
- data/octocore-mongo.gemspec +50 -0
- data/spec/lib/stats_spec.rb +20 -0
- data/spec/spec_helper.rb +103 -0
- metadata +545 -0
data/Rakefile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'redis'
|
3
|
+
require 'mongo_mapper'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
require 'octocore/config'
|
7
|
+
|
8
|
+
RSpec::Core::RakeTask.new('spec')
|
9
|
+
|
10
|
+
task :environment do
|
11
|
+
config_dir = ENV['CONFIG_DIR'] || 'lib/octocore/config/'
|
12
|
+
config = {}
|
13
|
+
Dir[config_dir + '**{,/*/**}/*.yml'].each do |file|
|
14
|
+
_config = YAML.load_file(file)
|
15
|
+
if _config
|
16
|
+
puts "loading from file: #{ file }"
|
17
|
+
config = config.merge(_config.deep_symbolize_keys)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
Octo.load_config config
|
21
|
+
mongo_uri = Octo.get_config(:mongo_uri)
|
22
|
+
MongoMapper.setup({'production' => {'uri' => mongo_uri}}, 'production')
|
23
|
+
end
|
24
|
+
|
25
|
+
# Load default tasks from Cequel
|
26
|
+
spec = Gem::Specification.find_by_name 'mongo_mapper'
|
27
|
+
load "#{spec.gem_dir}/lib/mongo_mapper/railtie/database.rake"
|
28
|
+
|
29
|
+
# Overriding rake actions
|
30
|
+
namespace :octo do
|
31
|
+
|
32
|
+
desc 'Create keyspace and tables for all defined models'
|
33
|
+
task :init => %w(environment db:setup)
|
34
|
+
|
35
|
+
desc 'Drop keyspace if exists, then create and migrate'
|
36
|
+
task :reset => :environment do
|
37
|
+
clear_cache
|
38
|
+
task('db:drop').invoke
|
39
|
+
task('db:create').invoke
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Clear Cache
|
44
|
+
def clear_cache
|
45
|
+
default_cache = {
|
46
|
+
host: '127.0.0.1', port: 6379
|
47
|
+
}
|
48
|
+
redis = Redis.new(default_cache.merge(driver: :hiredis))
|
49
|
+
redis.flushall
|
50
|
+
puts 'Cache Cleaned'
|
51
|
+
end
|
@@ -0,0 +1,258 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# A simple utility to generate fake stream of data
|
4
|
+
#
|
5
|
+
# Usage:
|
6
|
+
# ./fakestream
|
7
|
+
|
8
|
+
require 'net/http'
|
9
|
+
require 'json'
|
10
|
+
require 'octocore-mongo'
|
11
|
+
|
12
|
+
module Octo
|
13
|
+
class FakeStream
|
14
|
+
|
15
|
+
MAX_USERS = 100
|
16
|
+
|
17
|
+
MAX_PAGES = 30
|
18
|
+
MAX_PRODUCTS = 200
|
19
|
+
|
20
|
+
MAX_CATEGORIES = 10
|
21
|
+
|
22
|
+
MAX_TAGS = 15
|
23
|
+
|
24
|
+
|
25
|
+
#How many no. of pages to view before going to product page
|
26
|
+
MAX_PAGES_TO_VISIT = 3
|
27
|
+
|
28
|
+
# Initialize with the URL
|
29
|
+
def initialize
|
30
|
+
@_apikeys = {}
|
31
|
+
end
|
32
|
+
|
33
|
+
def base_url
|
34
|
+
Octo.get_config(:base_url)
|
35
|
+
end
|
36
|
+
|
37
|
+
def stream
|
38
|
+
user = fakeuser
|
39
|
+
|
40
|
+
# simulate an app login
|
41
|
+
app_init user
|
42
|
+
# simulate a random number of page views before going to product
|
43
|
+
for i in 1..(1+rand(MAX_PAGES_TO_VISIT))
|
44
|
+
pv user, fakepage(user.enterprise)
|
45
|
+
end
|
46
|
+
|
47
|
+
# simulate a product page view
|
48
|
+
ppv user, fakeproduct(user.enterprise)
|
49
|
+
|
50
|
+
|
51
|
+
#visit a page or not after going to the product page
|
52
|
+
for i in 0..rand(2)
|
53
|
+
pv user, fakepage(user.enterprise)
|
54
|
+
end
|
55
|
+
|
56
|
+
puts "---- Next User ----"
|
57
|
+
end
|
58
|
+
|
59
|
+
def stream_forever
|
60
|
+
while 1
|
61
|
+
stream
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# Create an APP INIT request
|
68
|
+
def app_init(user)
|
69
|
+
payload = {
|
70
|
+
userId: user.id,
|
71
|
+
phoneDetails: phonedetails
|
72
|
+
}
|
73
|
+
key = apikey(user.enterprise)
|
74
|
+
url = '/events/app.init/'
|
75
|
+
post(url, key, payload)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Create a page view request
|
79
|
+
def pv(user, page)
|
80
|
+
payload = {
|
81
|
+
userId: user.id,
|
82
|
+
phoneDetails: phonedetails,
|
83
|
+
routeUrl: page.routeurl,
|
84
|
+
categories: fakecategories,
|
85
|
+
tags: faketags,
|
86
|
+
}
|
87
|
+
key = apikey user.enterprise
|
88
|
+
url = '/events/page.view/'
|
89
|
+
post(url, key, payload)
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
# Create a product page view request
|
94
|
+
def ppv(user, product)
|
95
|
+
payload = {
|
96
|
+
userId: user.id,
|
97
|
+
phoneDetails: phonedetails,
|
98
|
+
routeUrl: product.routeurl,
|
99
|
+
categories: fakecategories,
|
100
|
+
tags: faketags,
|
101
|
+
productId: product.id,
|
102
|
+
productName: product.name,
|
103
|
+
price: product.price
|
104
|
+
}
|
105
|
+
key = apikey user.enterprise
|
106
|
+
url = '/events/productpage.view/'
|
107
|
+
post(url, key, payload)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Hash containing phone details
|
111
|
+
# @return [Hash]
|
112
|
+
def phonedetails
|
113
|
+
{
|
114
|
+
deviceId: 'FCDBD8EF-62FC-4ECB-B2F5-92C9E79AC7F9',
|
115
|
+
manufacturer: 'Apple',
|
116
|
+
model: 'iPhone 6',
|
117
|
+
latitude: 28.6139,
|
118
|
+
longitude: 77.209
|
119
|
+
}
|
120
|
+
end
|
121
|
+
|
122
|
+
# Creates a fake user for the enterprise on the fly
|
123
|
+
# @param [Octo::Enterprise] enterprise
|
124
|
+
# @return [Octo::User]
|
125
|
+
def fakeuser(enterprise = enterprises.to_a.sample)
|
126
|
+
Octo::User.new(enterprise_id: enterprise.id,
|
127
|
+
id: rand(MAX_USERS))
|
128
|
+
end
|
129
|
+
|
130
|
+
# Generates a fake page for the enterprise
|
131
|
+
# @param [Octo::Enterprise] enterprise
|
132
|
+
# @return [Octo::Product]
|
133
|
+
def fakepage(enterprise)
|
134
|
+
id = rand(MAX_PAGES)
|
135
|
+
Octo::Page.new(
|
136
|
+
enterprise_id: enterprise.id,
|
137
|
+
routeurl: "/PageUrl/#{ id }",
|
138
|
+
categories: fakecategories,
|
139
|
+
tags: faketags
|
140
|
+
)
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
# Generates a fake product for the enterprise
|
145
|
+
# @param [Octo::Enterprise] enterprise
|
146
|
+
# @return [Octo::Product]
|
147
|
+
def fakeproduct(enterprise)
|
148
|
+
id = rand(MAX_PRODUCTS)
|
149
|
+
Octo::Product.new(
|
150
|
+
enterprise_id: enterprise.id,
|
151
|
+
id: id,
|
152
|
+
price: rand(10000).to_f,
|
153
|
+
name: "Fake Product #{ id }",
|
154
|
+
routeurl: "/Some/Url/#{ id }",
|
155
|
+
categories: fakecategories,
|
156
|
+
tags: faketags
|
157
|
+
)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Generates fake categories
|
161
|
+
# @return [Array<String>] Array of fake categories
|
162
|
+
def fakecategories(count = 2)
|
163
|
+
(0..MAX_CATEGORIES).to_a.sample(count).collect { |x| "Fake Category #{ x }"}
|
164
|
+
end
|
165
|
+
|
166
|
+
# Generates fake tags
|
167
|
+
# @return [Array<String>] Array of fake tags
|
168
|
+
def faketags(count = 2)
|
169
|
+
(0..MAX_TAGS).to_a.sample(count).collect { |x| "Fake Tag #{ x }"}
|
170
|
+
end
|
171
|
+
|
172
|
+
# Fetches the APIKey for the enterprise
|
173
|
+
def apikey(enterprise)
|
174
|
+
unless @_apikeys.has_key?(enterprise.id)
|
175
|
+
@_apikeys[enterprise.id] = Octo::Authorization.find_by_username(enterprise.name).apikey
|
176
|
+
end
|
177
|
+
@_apikeys[enterprise.id]
|
178
|
+
end
|
179
|
+
|
180
|
+
# Creates the URI
|
181
|
+
def uri(url = base_url)
|
182
|
+
URI(url)
|
183
|
+
end
|
184
|
+
|
185
|
+
# Find all enterprises
|
186
|
+
# @return [Cequel::RecordSet]
|
187
|
+
def enterprises
|
188
|
+
Octo::Enterprise.all.select { |x| !x.name.nil? and x.fakedata? }
|
189
|
+
end
|
190
|
+
|
191
|
+
# Make the POST call
|
192
|
+
# @param [String] url The endpoint url
|
193
|
+
# @param [String] apikey The API Key
|
194
|
+
# @param [Hash] payload The payload
|
195
|
+
def post(url, apikey, payload)
|
196
|
+
headers = {
|
197
|
+
'Content-Type' => 'application/json',
|
198
|
+
'Accept' => 'application/json',
|
199
|
+
'apikey' => apikey
|
200
|
+
}
|
201
|
+
|
202
|
+
_uri = uri(base_url + url)
|
203
|
+
req = Net::HTTP::Post.new(_uri, headers)
|
204
|
+
req.content_type = 'application/json'
|
205
|
+
req.body = payload.to_json
|
206
|
+
|
207
|
+
res = Net::HTTP.start(_uri.hostname, _uri.port) do |http|
|
208
|
+
http.request(req)
|
209
|
+
end
|
210
|
+
|
211
|
+
case res
|
212
|
+
when Net::HTTPSuccess, Net::HTTPRedirection
|
213
|
+
puts res.body
|
214
|
+
else
|
215
|
+
puts res.value
|
216
|
+
end
|
217
|
+
|
218
|
+
end
|
219
|
+
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
# All the main Job
|
224
|
+
def _main(config_file)
|
225
|
+
|
226
|
+
# setup signal trap
|
227
|
+
Signal.trap('INT') {
|
228
|
+
puts 'Halting on user request'
|
229
|
+
exit
|
230
|
+
}
|
231
|
+
|
232
|
+
# connect Octo and start the show
|
233
|
+
Octo.connect_with config_file
|
234
|
+
streamer = Octo::FakeStream.new
|
235
|
+
streamer.stream_forever
|
236
|
+
end
|
237
|
+
|
238
|
+
def main
|
239
|
+
config_file = if ARGV[0]
|
240
|
+
ARGV[0]
|
241
|
+
else
|
242
|
+
spec = Gem::Specification.find_by_name('octocore')
|
243
|
+
gem_root = spec.gem_dir
|
244
|
+
File.join(gem_root, 'lib', 'octocore' ,'config')
|
245
|
+
end
|
246
|
+
puts config_file
|
247
|
+
if File.exist?config_file
|
248
|
+
_main(config_file)
|
249
|
+
else
|
250
|
+
puts "Config file '#{ config_file }' does not exist. Exiting..."
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
main
|
255
|
+
|
256
|
+
if __FILE__ == $0
|
257
|
+
main
|
258
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# A simple utility to provide easy migrations, reset
|
4
|
+
# and all the rake tasks that you may need to do
|
5
|
+
|
6
|
+
# ./octocore-admin --tasks
|
7
|
+
|
8
|
+
require 'open3'
|
9
|
+
|
10
|
+
module Octo
|
11
|
+
module CliAdmin
|
12
|
+
|
13
|
+
VALID_ACTIONS = %w(init migrate reset)
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
def perform(action, config_dir)
|
17
|
+
if VALID_ACTIONS.include?(action)
|
18
|
+
cmd = ['rake', '-f', spec.gem_dir + '/Rakefile',
|
19
|
+
'--verbose', "octo:#{ action }",
|
20
|
+
"CONFIG_DIR=#{ config_dir }"]
|
21
|
+
#STDOUT.puts "** Executing: #{ cmd }"
|
22
|
+
Open3.popen3(*cmd) do |stdout, stderr, status, thread|
|
23
|
+
stderr.sync = true
|
24
|
+
while line=stderr.gets do
|
25
|
+
puts(line)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
else
|
29
|
+
STDOUT.puts "Invalid action: #{ action }"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def spec
|
34
|
+
@spec ||= Gem::Specification.find_by_name 'octocore'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Cli
|
39
|
+
extend ClassMethods
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.main
|
43
|
+
STDOUT.sync = true
|
44
|
+
action = ARGV[0]
|
45
|
+
config_dir = ARGV[1]
|
46
|
+
Octo::CliAdmin::Cli.perform(action, config_dir)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
Octo::CliAdmin.main
|
54
|
+
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'mongo_mapper'
|
2
|
+
require 'yaml'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
require 'octocore-mongo/version'
|
6
|
+
require 'octocore-mongo/config'
|
7
|
+
|
8
|
+
|
9
|
+
require 'octocore-mongo/models'
|
10
|
+
require 'octocore-mongo/counter'
|
11
|
+
require 'octocore-mongo/email'
|
12
|
+
require 'octocore-mongo/utils'
|
13
|
+
|
14
|
+
require 'octocore-mongo/trendable'
|
15
|
+
require 'octocore-mongo/baseline'
|
16
|
+
require 'octocore-mongo/trends'
|
17
|
+
require 'octocore-mongo/kldivergence'
|
18
|
+
require 'octocore-mongo/segment'
|
19
|
+
|
20
|
+
# Mailer and scheduler should always be required in the following order
|
21
|
+
require 'octocore-mongo/mailer'
|
22
|
+
require 'octocore-mongo/scheduler'
|
23
|
+
|
24
|
+
require 'octocore-mongo/message_parser'
|
25
|
+
|
26
|
+
require 'octocore-mongo/schedeuleable'
|
27
|
+
require 'octocore-mongo/helpers'
|
28
|
+
require 'octocore-mongo/kafka_bridge'
|
29
|
+
require 'octocore-mongo/stats'
|
30
|
+
|
31
|
+
# The main Octo module
|
32
|
+
module Octo
|
33
|
+
|
34
|
+
# Connect using the provided configuration. If you want to extend Octo's connect
|
35
|
+
# method you can override this method with your own. Just make sure to make
|
36
|
+
# a call to self._connect(configuration) so that Octo also connects
|
37
|
+
# @param [Hash] configuration The configuration hash
|
38
|
+
def self.connect(configuration)
|
39
|
+
self._connect(configuration)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Connect by reading configuration from the provided file
|
43
|
+
# @param [String] config_file Location of the YAML config file
|
44
|
+
def self.connect_with_config_file(config_file)
|
45
|
+
config = YAML.load_file(config_file).deep_symbolize_keys
|
46
|
+
self.connect(config)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Connect by reading configuration files from the given directory.
|
50
|
+
# In this case, all *.y*ml files would be read in
|
51
|
+
# Dir.glob order and merged into one unified config
|
52
|
+
def self.connect_with_config_dir(config_dir)
|
53
|
+
config = {}
|
54
|
+
accepted_formats = Set.new(['.yaml', '.yml'])
|
55
|
+
Dir[config_dir + '/*'].each do |file_obj|
|
56
|
+
if File.file?(file_obj) and accepted_formats.include?File.extname(file_obj)
|
57
|
+
config = self.true_load(config, file_obj, config_dir)
|
58
|
+
elsif File.directory?(file_obj)
|
59
|
+
Dir[file_obj + '/**/*.y*ml'].each do |file|
|
60
|
+
config = self.true_load(config, file, config_dir)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
# As a cleanup step, merge the values of key named "config"
|
65
|
+
# with the global config hash
|
66
|
+
configConfig = config.delete(:config)
|
67
|
+
config = config.deep_merge(configConfig)
|
68
|
+
# Now, good to merge the two
|
69
|
+
self.connect config
|
70
|
+
end
|
71
|
+
|
72
|
+
# Loads the true config. The true config is the hierarchial config
|
73
|
+
# @param [Hash] config The base config. Loaded config will be deep merged
|
74
|
+
# with this
|
75
|
+
# @param [String] file The file from which config should be loaded
|
76
|
+
# @param [String] config_fir The config dir in which the file is located
|
77
|
+
# @return [Hash] The merged config hash
|
78
|
+
def self.true_load(config, file, config_dir)
|
79
|
+
_config = YAML.load_file file
|
80
|
+
if _config
|
81
|
+
$stdout.puts "Loading from Config file: #{ file }"
|
82
|
+
# A little bit of hack here.
|
83
|
+
# This hack makes sure that if we load config files from nestes
|
84
|
+
# directories, the corresponding config is loaded in
|
85
|
+
# hierarchy.
|
86
|
+
# So, if the file is like /config/search/index.yml, the
|
87
|
+
# key would be like [config[search[index]]]
|
88
|
+
a = file.gsub(/(\/?#{config_dir}(\/)*(config\/)*|.yml)/, '').split('/')
|
89
|
+
_true_config = a.reverse.inject(_config) { |r,e| { e => r } }
|
90
|
+
config = config.deep_merge(_true_config.deep_symbolize_keys)
|
91
|
+
end
|
92
|
+
config
|
93
|
+
end
|
94
|
+
|
95
|
+
# Provides a unified interface to #connect_with_config_dir
|
96
|
+
# and #connect_with_config_file for convenience
|
97
|
+
def self.connect_with(location)
|
98
|
+
if File.directory?(location)
|
99
|
+
self.connect_with_config_dir location
|
100
|
+
elsif File.file?(location)
|
101
|
+
self.connect_with_config_file location
|
102
|
+
else
|
103
|
+
puts "Invalid location #{ location }"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
# A low level method to connect using a configuration
|
109
|
+
# @param [Hash] configuration The configuration hash
|
110
|
+
def self._connect(configuration)
|
111
|
+
|
112
|
+
load_config configuration
|
113
|
+
|
114
|
+
self.logger.info('Octo booting up.')
|
115
|
+
|
116
|
+
# Establish Cequel Connection
|
117
|
+
# cassandra_config = Octo.get_config(:cassandra)
|
118
|
+
# connection = Cequel.connect(cassandra_config)
|
119
|
+
# Cequel::Record.connection = connection
|
120
|
+
|
121
|
+
# Establish Mongo Connection
|
122
|
+
mongo_uri = Octo.get_config(:mongo_uri)
|
123
|
+
connection = MongoMapper.setup({'production' => {'uri' => mongo_uri}}, 'production')
|
124
|
+
# MongoMapper::Connection.connection= connection
|
125
|
+
|
126
|
+
# Establish connection to cache server
|
127
|
+
default_cache = {
|
128
|
+
host: '127.0.0.1', port: 6379
|
129
|
+
}
|
130
|
+
cache_config = Octo.get_config(:redis, default_cache)
|
131
|
+
MongoMapper::Document.update_cache_config(*cache_config.values_at(:host, :port))
|
132
|
+
|
133
|
+
# Establish connection to statsd server if required
|
134
|
+
if configuration.has_key?(:statsd)
|
135
|
+
statsd_config = configuration[:statsd]
|
136
|
+
set_config :stats, Statsd.new(*statsd_config.values)
|
137
|
+
end
|
138
|
+
|
139
|
+
self.logger.info('I\'m connected now.')
|
140
|
+
require 'octocore-mongo/callbacks'
|
141
|
+
|
142
|
+
self.logger.info('Setting callbacks.')
|
143
|
+
|
144
|
+
Octo::Callbacks.run_hook(:after_connect)
|
145
|
+
end
|
146
|
+
|
147
|
+
# Creates a logger for Octo
|
148
|
+
def self.logger
|
149
|
+
unless @logger
|
150
|
+
@logger = Logger.new(Octo.get_config(:logfile, $stdout)).tap do |log|
|
151
|
+
log.progname = name
|
152
|
+
end
|
153
|
+
end
|
154
|
+
@logger
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|