singleton-client-test 0.7.0.33 → 0.7.0.34

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2a32a268d9bc9b395baeb2d296049cbbb29a40c081968d6e8a5ae364c39444c
4
- data.tar.gz: fdf427aaf792fbff1bf6afa404d6e0aeeea030b9fa90b7eab578cbe46659656e
3
+ metadata.gz: 6722a7f77f8f9ee4fbf2f481d0c66e30b818c61746a9c7e8471fc1b225079f72
4
+ data.tar.gz: ba0e6acade9bc655f97a731cf760e15097b713e99000cf8f2612e4975a357d2d
5
5
  SHA512:
6
- metadata.gz: 1ecfa3b8fbc1ef494e41a517a102856f4717d408845eeac43cd751c24df2a590404082cd00670b280fd8c404b3dd95ecd2ae5c06f7b0c0b23172b9eb7ab2fff7
7
- data.tar.gz: 0a8aee2dd03eaa02c981cdfaa097ffbddebc2118c7c7a63625ad19ca332ecf582fac19a812339ef9920dac37765a03b30d9800d69cfe9dd2b854762ee0796170
6
+ metadata.gz: 27e3c13e20185a08049c2d634bc11e3a6d4e05095802e3c76026b74c34acd3a327b2e49c79020b9143479747e9d25fbfe5eaf4c859621afdc23f512859efd0fc
7
+ data.tar.gz: bed85d6578397cd90e0823574f552d7f7e98e19a0f49e35e12963eecc32d5f87d85b8c0a8ab2c50c5c66b3ea81e630334194f8d4600fdc4a0eec2bf391b2decb
@@ -1,7 +1,7 @@
1
1
  # Copyright 2022 VMware, Inc.
2
2
  # SPDX-License-Identifier: EPL-2.0
3
3
 
4
- require 'sgtn-client/loader/local_source_bundle'
4
+ require 'sgtn-client/loader/source'
5
5
 
6
6
  module SgtnClient
7
7
  autoload :CacheUtil, 'sgtn-client/util/cache-util'
@@ -9,16 +9,7 @@ module SgtnClient
9
9
  class Source
10
10
  def self.loadBundles(locale)
11
11
  SgtnClient.logger.debug "[Source][loadBundles]locale=#{locale}"
12
- env = SgtnClient::Config.default_environment
13
12
  SgtnClient::Config.configurations.default = locale
14
- source_bundle = SgtnClient::Config.configurations[env]['source_bundle']
15
- Dir.foreach(source_bundle) do |component|
16
- next if %w[. ..].include? component
17
-
18
- bundle = load_bundle(component)
19
- cachekey = SgtnClient::CacheUtil.get_cachekey(component, LocaleUtil.get_source_locale)
20
- SgtnClient::CacheUtil.write_cache(cachekey, bundle)
21
- end
22
13
  end
23
14
  end
24
15
  end
@@ -1,110 +1,113 @@
1
1
  # Copyright 2022 VMware, Inc.
2
2
  # SPDX-License-Identifier: EPL-2.0
3
3
 
4
- module SgtnClient
5
- autoload :StringUtil, 'sgtn-client/util/string-util'
6
-
7
- module TranslationLoader
8
- autoload :LocalBundle, 'sgtn-client/loader/local_bundle'
9
- autoload :ServerBundle, 'sgtn-client/loader/server_bundle'
10
- autoload :SourceComparer, 'sgtn-client/loader/source_comparer'
11
- autoload :SingleLoader, 'sgtn-client/loader/single_loader'
12
- autoload :Cache, 'sgtn-client/loader/cache'
13
- end
4
+ require 'request_store'
14
5
 
6
+ module SgtnClient
15
7
  module Translation
16
- def self.getString(component, key, locale)
17
- SgtnClient.logger.debug "[Translation.getString]component: #{component}, key: #{key}, locale: #{locale}"
18
- str = getTranslation(component, key, locale)
19
- if str.nil? && !LocaleUtil.is_source_locale(locale)
20
- str = getTranslation(component, key, LocaleUtil.get_source_locale)
8
+ module Implementation
9
+ # <b>DEPRECATED:</b> Please use <tt>Singleton:translate</tt> instead.
10
+ def getString(component, key, locale)
11
+ SgtnClient.logger.debug "[Translation.getString]component: #{component}, key: #{key}, locale: #{locale}"
12
+ translate(key, component, locale) { nil }
21
13
  end
22
- str
23
- end
24
14
 
25
- def self.getString_p(component, key, plural_args, locale)
26
- SgtnClient.logger.debug "[Translation][getString_p]component=#{component}, key=#{key}, locale=#{locale}"
27
- str = getTranslation(component, key, locale)
28
- if str.nil?
29
- unless LocaleUtil.is_source_locale(locale)
30
- str = getTranslation(component, key, LocaleUtil.get_source_locale)
31
- str.to_plural_s(LocaleUtil.get_source_locale, plural_args) if str
32
- end
33
- else
34
- locale = str.locale if str.is_a?(SgtnClient::StringUtil)
35
- str.to_plural_s(locale, plural_args)
15
+ # <b>DEPRECATED:</b> Please use <tt>Singleton:translate</tt> instead.
16
+ def getString_p(component, key, plural_args, locale)
17
+ SgtnClient.logger.debug "[Translation][getString_p]component=#{component}, key=#{key}, locale=#{locale}"
18
+ translate(key, component, locale, **plural_args) { nil }
36
19
  end
37
- end
38
-
39
- def self.getString_f(component, key, args, locale, *optionals)
40
- SgtnClient.logger.debug "[Translation][getString_f]component=#{component}, key=#{key}, locale=#{locale}"
41
- s = getString(component, key, locale, *optionals)
42
- return nil if s.nil?
43
20
 
44
- if args.is_a?(Hash)
45
- args.each do |source, arg|
46
- s.gsub! "{#{source}}", arg
21
+ # <b>DEPRECATED:</b> Please use <tt>Singleton:translate</tt> instead.
22
+ def getString_f(component, key, args, locale, *_optionals)
23
+ SgtnClient.logger.debug "[Translation][getString_f]component=#{component}, key=#{key}, locale=#{locale}"
24
+ s = translate(key, component, locale) { nil }
25
+ return nil if s.nil?
26
+
27
+ if args.is_a?(Hash)
28
+ args.each do |source, arg|
29
+ s.gsub! "{#{source}}", arg
30
+ end
31
+ elsif args.is_a?(Array)
32
+ s = s % args
47
33
  end
48
- elsif args.is_a?(Array)
49
- s = s % args
34
+ s
50
35
  end
51
- s
52
- end
53
36
 
54
- def self.getStrings(component, locale)
55
- SgtnClient.logger.debug "[Translation][getStrings]component=#{component}, locale=#{locale}"
56
- locale = SgtnClient::LocaleUtil.get_best_locale(locale)
57
- items = get_cs(component, locale)
58
- if (items.nil? || items['messages'].nil?) && !LocaleUtil.is_source_locale(locale)
59
- items = get_cs(component, LocaleUtil.get_source_locale)
37
+ # <b>DEPRECATED:</b> Please use <tt>Singleton:get_translations</tt> instead.
38
+ def getStrings(component, locale)
39
+ get_translations(component, locale)
60
40
  end
61
41
 
62
- items
63
- end
42
+ # raise error when translation is not found
43
+ def translate(key, component, locale = nil, **kwargs)
44
+ SgtnClient.logger.debug "[#{method(__callee__).owner}.#{__callee__}] key: #{key}, component: #{component}, locale: #{locale}, args: #{kwargs}"
64
45
 
65
- def self.getTranslation(component, key, locale)
66
- locale = SgtnClient::LocaleUtil.get_best_locale(locale)
67
- items = get_cs(component, locale)
68
- items&.dig('messages', key)
69
- end
46
+ locale = locale.nil? ? self.locale : SgtnClient::LocaleUtil.get_best_locale(locale)
70
47
 
71
- def self.get_cs(component, locale)
72
- cache_item = load_bundle(component, locale)
73
- cache_item&.dig(:items)
74
- end
48
+ result = get_bundle(component, locale)&.fetch(key, nil)
49
+ if result.nil? && !LocaleUtil.is_source_locale(locale)
50
+ locale = LocaleUtil.get_source_locale
51
+ result = get_bundle(component, locale)&.fetch(key, nil)
52
+ end
75
53
 
76
- def self.load_bundle(component, locale)
77
- init_translations unless initialized?
78
- super
79
- end
54
+ if result.nil?
55
+ return key unless block_given?
56
+
57
+ result = yield
58
+ return if result.nil?
59
+ end
80
60
 
81
- class << self
82
- def initialized?
83
- @initialized ||= false
61
+ if kwargs.empty?
62
+ result
63
+ else
64
+ locale = result.locale if result.is_a?(SgtnClient::StringUtil)
65
+ result.localize(locale) % kwargs
66
+ end
84
67
  end
68
+ alias t translate
85
69
 
86
- def init_translations
87
- # TODO: Lock to initialize?
88
- env = SgtnClient::Config.default_environment
89
- mode = SgtnClient::Config.configurations[env]['bundle_mode']
90
- SgtnClient.logger.debug "[Translation][init_translations]mode=#{mode}"
70
+ def get_translations(component, locale = nil)
71
+ SgtnClient.logger.debug "[#{method(__callee__).owner}.#{__callee__}] component: #{component}, locale: #{locale}"
91
72
 
92
- if mode == 'offline'
93
- extend SgtnClient::TranslationLoader::LocalBundle
94
- else
95
- extend SgtnClient::TranslationLoader::ServerBundle
73
+ locale = locale.nil? ? self.locale : SgtnClient::LocaleUtil.get_best_locale(locale)
74
+ items = get_bundle(component, locale)
75
+ if items.nil? && !LocaleUtil.is_source_locale(locale)
76
+ items = get_bundle(component, LocaleUtil.get_source_locale)
77
+ locale = LocaleUtil.get_source_locale
96
78
  end
97
79
 
98
- extend SgtnClient::TranslationLoader::SourceComparer
99
- extend SgtnClient::TranslationLoader::Cache
80
+ { 'component' => component, 'locale' => locale, 'messages' => items || {} } if items
81
+ end
100
82
 
101
- load_translations
102
- @initialized = true
83
+ def locale
84
+ RequestStore.store[:locale] ||= SgtnClient::LocaleUtil.get_fallback_locale
103
85
  end
104
86
 
105
- def load_translations; end
106
- end
87
+ def locale=(value)
88
+ RequestStore.store[:locale] = SgtnClient::LocaleUtil.get_best_locale(value)
89
+ end
107
90
 
108
- private_class_method :getTranslation, :get_cs, :load_bundle, :initialized?, :load_translations
91
+ private
92
+
93
+ def get_bundle(component, locale)
94
+ get_bundle!(component, locale)
95
+ rescue StandardError => e
96
+ SgtnClient.logger.error "[#{method(__callee__).owner}.#{__callee__}] failed to get a bundle. component: #{component}, locale: #{locale}"
97
+ SgtnClient.logger.error e
98
+ nil
99
+ end
100
+
101
+ def get_bundle!(component, locale)
102
+ id = SgtnClient::Common::BundleID.new(component, locale)
103
+ bundles = SgtnClient::Config.available_bundles
104
+ unless bundles.nil? || bundles.empty? || bundles.include?(id)
105
+ raise SgtnClient::SingletonError, 'bundle is unavailable.'
106
+ end
107
+
108
+ SgtnClient::Config.loader.get_bundle(component, locale)
109
+ end
110
+ end
111
+ extend Implementation
109
112
  end
110
113
  end
@@ -0,0 +1,30 @@
1
+ # Copyright 2022 VMware, Inc.
2
+ # SPDX-License-Identifier: EPL-2.0
3
+
4
+ module SgtnClient
5
+ module Common
6
+ class BundleID
7
+ attr_reader :locale, :component
8
+
9
+ def initialize(component, locale)
10
+ @locale = locale
11
+ @component = component
12
+ @key = [@component, @locale].hash
13
+ end
14
+
15
+ def hash
16
+ @key
17
+ end
18
+
19
+ def ==(other)
20
+ (other.is_a? self.class) && @locale == other.locale && @component == other.component
21
+ end
22
+
23
+ alias eql? ==
24
+
25
+ def to_s
26
+ "locale=#{@locale}, component=#{@component}}"
27
+ end
28
+ end
29
+ end
30
+ end
@@ -20,6 +20,7 @@ module SgtnClient
20
20
  @conditions.each do |con|
21
21
  return obj unless con.call(id, obj, *args)
22
22
  end
23
+ # TODO: whatif returning nil
23
24
  @hash[id] = @creator.call(id, obj, *args)
24
25
  end
25
26
  end
@@ -4,8 +4,14 @@
4
4
  require 'erb'
5
5
  require 'yaml'
6
6
 
7
+
7
8
  module SgtnClient
8
9
  #include Exceptions
10
+
11
+ module TranslationLoader
12
+ autoload :LoaderFactory, 'sgtn-client/loader/loader_factory'
13
+ end
14
+
9
15
  module Configuration
10
16
 
11
17
  def config
@@ -42,7 +48,7 @@ module SgtnClient
42
48
  :mode, :endpoint, :merchant_endpoint, :platform_endpoint, :ipn_endpoint,
43
49
  :rest_endpoint, :rest_token_endpoint, :client_id, :client_secret,
44
50
  :openid_endpoint, :openid_redirect_uri, :openid_client_id, :openid_client_secret,
45
- :verbose_logging, :product_name, :version, :vip_server, :bundle_mode,
51
+ :verbose_logging, :product_name, :version, :vip_server,
46
52
  :translation_bundle, :source_bundle, :cache_expiry_period, :disable_cache, :default_language
47
53
 
48
54
 
@@ -152,6 +158,34 @@ module SgtnClient
152
158
  Logging.logger
153
159
  end
154
160
 
161
+
162
+ def loader
163
+ @loader ||= begin
164
+ config = SgtnClient::Config.configurations[SgtnClient::Config.default_environment]
165
+ SgtnClient::TranslationLoader::LoaderFactory.create(config)
166
+ end
167
+ end
168
+
169
+ def available_bundles
170
+ loader.available_bundles
171
+ rescue StandardError => e
172
+ SgtnClient.logger.error 'failed to get available bundles'
173
+ SgtnClient.logger.error e
174
+ Set.new
175
+ end
176
+
177
+ def available_locales
178
+ bundles = available_bundles
179
+ return Set.new if bundles.nil? || bundles.empty?
180
+
181
+ unless bundles.respond_to?(:locales)
182
+ def bundles.locales
183
+ @locales ||= reduce(Set.new) { |locales, id| locales << id.locale }
184
+ end
185
+ end
186
+ bundles.locales
187
+ end
188
+
155
189
  private
156
190
  # Read configurations from the given file name
157
191
  # === Arguments
@@ -161,7 +195,6 @@ module SgtnClient
161
195
  erb.filename = file_name
162
196
  YAML.load(erb.result)
163
197
  end
164
-
165
198
 
166
199
  end
167
200
  end
@@ -0,0 +1,6 @@
1
+ # Copyright 2022 VMware, Inc.
2
+ # SPDX-License-Identifier: EPL-2.0
3
+
4
+ module SgtnClient
5
+ class SingletonError < StandardError; end
6
+ end
@@ -1,47 +1,71 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2022 VMware, Inc.
2
4
  # SPDX-License-Identifier: EPL-2.0
3
5
 
4
6
  module SgtnClient
5
7
  autoload :CacheUtil, 'sgtn-client/util/cache-util'
6
- autoload :SingleOperation, 'sgtn-client/common/single_operation'
7
- end
8
- module SgtnClient::TranslationLoader::Cache
9
- def load_bundle(component, locale)
10
- cache_key = SgtnClient::CacheUtil.get_cachekey(component, locale)
11
- SgtnClient.logger.debug "[#{self.to_s}][#{__FILE__}][#{__method__}] cache_key=#{cache_key}"
12
- cache_item = SgtnClient::CacheUtil.get_cache(cache_key)
13
- if cache_item.nil?
14
- # refresh synchronously if not in cache
15
- SgtnClient.logger.debug "[#{self.to_s}][#{__FILE__}][#{__method__}] Cache miss. cache_key=#{cache_key}"
16
- cache_item = (single_loader { |c, l| super(c, l) }).operate(cache_key, component, locale).value
17
- # TODO: if an error occurs when requesting a bundle, need to avoid more requests
18
- elsif SgtnClient::CacheUtil.is_expired(cache_item) && locale != SgtnClient::LocaleUtil.get_source_locale # local source never expires.
19
- SgtnClient.logger.debug "[#{self.to_s}][#{__FILE__}][#{__method__}] Bundle cache is expired. cache_key=#{cache_key}"
20
- @single_loader.operate(cache_key, component, locale) # refresh in background
21
- end
22
- cache_item
23
- end
24
8
 
25
- private
9
+ module TranslationLoader
10
+ autoload :CONSTS, 'sgtn-client/loader/consts'
26
11
 
27
- def single_loader
28
- @single_loader ||= begin
29
- none_alive = proc { |_, thread| thread.nil? || thread.alive? == false }
30
- to_run = proc do |id|
31
- cache_item = SgtnClient::CacheUtil.get_cache(id)
32
- cache_item&.dig(:items).nil? || SgtnClient::CacheUtil.is_expired(cache_item)
33
- end
34
- creator = proc do |id, _, c, l|
35
- Thread.new do
36
- SgtnClient.logger.debug "Refreshing cache for #{c}/#{l}"
37
- cache_item = SgtnClient::CacheUtil.write_cache(id, yield(c, l))
38
- # delete thread from hash after finish
39
- Thread.new { @single_loader.remove_object(id) }
40
- cache_item
12
+ module Cache # :nodoc:
13
+ # get from cache, return expired data immediately
14
+ def get_bundle(component, locale)
15
+ SgtnClient.logger.debug "[#{__FILE__}][#{__callee__}] component=#{component}, locale=#{locale}"
16
+
17
+ key = SgtnClient::CacheUtil.get_cachekey(component, locale)
18
+ cache_item = SgtnClient::CacheUtil.get_cache(key)
19
+ if cache_item
20
+ if SgtnClient::CacheUtil.is_expired(cache_item)
21
+ Thread.new do # TODO: Use one thread # refresh in background
22
+ begin
23
+ load_bundle(component, locale)
24
+ rescue StandardError => e
25
+ SgtnClient.logger.error "an error occured while loading bundle: component=#{component}, locale=#{locale}"
26
+ SgtnClient.logger.error e
27
+ end
28
+ end
29
+ end
30
+ return cache_item.dig(:items)
41
31
  end
32
+
33
+ load_bundle(component, locale) # refresh synchronously if not in cache
42
34
  end
43
35
 
44
- SgtnClient::SingleOperation.new(none_alive, to_run, &creator)
36
+ # load and save to cache
37
+ def load_bundle(component, locale)
38
+ SgtnClient.logger.debug "[#{__FILE__}][#{__callee__}] component=#{component}, locale=#{locale}"
39
+
40
+ key = SgtnClient::CacheUtil.get_cachekey(component, locale)
41
+ item = super
42
+ SgtnClient::CacheUtil.write_cache(key, item) if item
43
+ item
44
+ end
45
+
46
+ def available_bundles
47
+ SgtnClient.logger.debug "[#{__FILE__}][#{__callee__}]"
48
+
49
+ cache_item = SgtnClient::CacheUtil.get_cache(CONSTS::AVAILABLE_BUNDLES_KEY)
50
+ if cache_item
51
+ if SgtnClient::CacheUtil.is_expired(cache_item)
52
+ Thread.new do # TODO: Use one thread
53
+ begin
54
+ item = super
55
+ SgtnClient::CacheUtil.write_cache(CONSTS::AVAILABLE_BUNDLES_KEY, item) if item
56
+ rescue StandardError => e
57
+ SgtnClient.logger.error 'an error occured while loading available bundles.'
58
+ SgtnClient.logger.error e
59
+ end
60
+ end
61
+ end
62
+ return cache_item.dig(:items)
63
+ end
64
+
65
+ item = super
66
+ SgtnClient::CacheUtil.write_cache(CONSTS::AVAILABLE_BUNDLES_KEY, item) if item
67
+ item
68
+ end
45
69
  end
46
70
  end
47
71
  end
@@ -0,0 +1,49 @@
1
+ # Copyright 2022 VMware, Inc.
2
+ # SPDX-License-Identifier: EPL-2.0
3
+
4
+ module SgtnClient
5
+ module TranslationLoader
6
+ class Chain
7
+ attr_accessor :loaders
8
+
9
+ def initialize(*loaders)
10
+ self.loaders = loaders
11
+ end
12
+
13
+ def load_bundle(component, locale)
14
+ exception = nil
15
+
16
+ loaders.each do |loader|
17
+ begin
18
+ bundle = loader.load_bundle(component, locale)
19
+ return bundle if bundle
20
+ rescue StandardError => e
21
+ exception = e
22
+ SgtnClient.logger.error "[#{__FILE__}][#{__callee__}] {component: #{component},locale: #{locale}}, failed on #{loader.class}: #{e}"
23
+ end
24
+ end
25
+
26
+ raise exception || SgtnClient::SingletonError.new("can't load component: #{component}, locale: #{locale}")
27
+ end
28
+
29
+ def available_bundles
30
+ exception = nil
31
+ total_data = Set.new
32
+
33
+ loaders.each do |loader|
34
+ begin
35
+ item = loader.available_bundles
36
+ total_data += item
37
+ rescue StandardError => e
38
+ exception = e
39
+ SgtnClient.logger.error "[#{__FILE__}][#{__callee__}] failed on #{loader.class}: #{e}"
40
+ end
41
+ end
42
+
43
+ raise exception if total_data.empty? && exception
44
+
45
+ total_data
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2022 VMware, Inc.
4
+ # SPDX-License-Identifier: EPL-2.0
5
+
6
+ module SgtnClient
7
+ module TranslationLoader
8
+ module CONSTS
9
+ OLD_SOURCE_LOCALE = 'old_source'
10
+ REAL_SOURCE_LOCALE = 'latest'
11
+
12
+ AVAILABLE_BUNDLES_KEY = 'available_bundles'
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,33 @@
1
+ # Copyright 2022 VMware, Inc.
2
+ # SPDX-License-Identifier: EPL-2.0
3
+
4
+ module SgtnClient
5
+ module TranslationLoader
6
+ autoload :Source, 'sgtn-client/loader/source'
7
+ autoload :SgtnServer, 'sgtn-client/loader/server'
8
+ autoload :LocalTranslation, 'sgtn-client/loader/local_translation'
9
+ autoload :Chain, 'sgtn-client/loader/chain_loader'
10
+ autoload :SourceComparer, 'sgtn-client/loader/source_comparer'
11
+ autoload :SingleLoader, 'sgtn-client/loader/single_loader'
12
+ autoload :Cache, 'sgtn-client/loader/cache'
13
+
14
+ module LoaderFactory
15
+ def self.create(config)
16
+ SgtnClient.logger.info "[#{method(__callee__).owner}.#{__callee__}] config=#{config}"
17
+
18
+ loaders = []
19
+ loaders << Source.new(config) if config['source_bundle']
20
+ loaders << SgtnServer.new(config) if config['vip_server']
21
+ loaders << LocalTranslation.new(config) if config['translation_bundle']
22
+ raise SgtnClient::SingletonError, 'no translation is available!' if loaders.empty?
23
+
24
+ chain_loader = Class.new(Chain)
25
+ chain_loader.include SourceComparer if config['source_bundle'] || config['vip_server']
26
+ chain_loader.include SingleLoader
27
+ chain_loader.include Cache
28
+
29
+ chain_loader.new(*loaders)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,50 @@
1
+ # Copyright 2022 VMware, Inc.
2
+ # SPDX-License-Identifier: EPL-2.0
3
+
4
+ require 'multi_json'
5
+
6
+ module SgtnClient
7
+ module Common
8
+ autoload :BundleID, 'sgtn-client/common/data'
9
+ end
10
+
11
+ module TranslationLoader
12
+ autoload :CONSTS, 'sgtn-client/loader/consts'
13
+
14
+ class LocalTranslation
15
+ BUNDLE_PREFIX = 'messages_'.freeze
16
+ BUNDLE_SUFFIX = '.json'.freeze
17
+
18
+ def initialize(config)
19
+ @base_path = Pathname.new(config['translation_bundle']) + config['product_name'] + config['version'].to_s
20
+ end
21
+
22
+ def load_bundle(component, locale)
23
+ return if locale == CONSTS::REAL_SOURCE_LOCALE # return when querying source
24
+
25
+ SgtnClient.logger.debug "[#{method(__callee__).owner}.#{__callee__}] component=#{component}, locale=#{locale}"
26
+
27
+ file_name = BUNDLE_PREFIX + locale + BUNDLE_SUFFIX
28
+ file_path = @base_path + component + file_name
29
+
30
+ bundle_data = JSON.parse(File.read(file_path))
31
+ messages = bundle_data['messages']
32
+
33
+ raise SgtnClient::SingletonError, "no messages in local bundle file: #{file_path}." unless messages
34
+
35
+ messages
36
+ end
37
+
38
+ def available_bundles
39
+ SgtnClient.logger.debug "[#{method(__callee__).owner}.#{__callee__}]"
40
+
41
+ @available_bundles ||= begin
42
+ @base_path.glob('*/*.json').reduce(Set.new) do |bundles, f|
43
+ locale = f.basename.to_s.sub(/\A#{BUNDLE_PREFIX}/i, '').sub(/#{BUNDLE_SUFFIX}\z/i, '')
44
+ bundles.add Common::BundleID.new(f.parent.basename.to_s, locale)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end