singleton-client-test 0.7.0.33 → 0.7.0.36
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +27 -28
- data/lib/sgtn-client/api/source.rb +1 -10
- data/lib/sgtn-client/api/translation.rb +84 -81
- data/lib/sgtn-client/cldr/localized_str.rb +1 -0
- data/lib/sgtn-client/common/data.rb +30 -0
- data/lib/sgtn-client/common/single_operation.rb +1 -0
- data/lib/sgtn-client/core/config.rb +35 -2
- data/lib/sgtn-client/exceptions.rb +6 -0
- data/lib/sgtn-client/loader/cache.rb +58 -34
- data/lib/sgtn-client/loader/chain_loader.rb +49 -0
- data/lib/sgtn-client/loader/consts.rb +15 -0
- data/lib/sgtn-client/loader/loader_factory.rb +33 -0
- data/lib/sgtn-client/loader/local_translation.rb +51 -0
- data/lib/sgtn-client/loader/server.rb +94 -0
- data/lib/sgtn-client/loader/single_loader.rb +46 -0
- data/lib/sgtn-client/loader/source.rb +55 -0
- data/lib/sgtn-client/loader/source_comparer.rb +48 -28
- data/lib/sgtn-client/sgtn-client.rb +1 -0
- data/lib/sgtn-client/util/cache-util.rb +0 -3
- data/lib/sgtn-client/util/locale-util.rb +22 -18
- data/lib/sgtn-client/util/validate-util.rb +1 -6
- data/lib/singleton-client.rb +15 -0
- data/lib/singleton-ruby.rb +2 -0
- metadata +36 -119
- data/lib/sgtn-client/core/request.rb +0 -24
- data/lib/sgtn-client/loader/local_bundle.rb +0 -13
- data/lib/sgtn-client/loader/local_source_bundle.rb +0 -29
- data/lib/sgtn-client/loader/server_bundle.rb +0 -22
- data/lib/sgtn-client/util/file-util.rb +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf77c54658953532871e1efcaeefdd2eeafe82d79d45de57341bc1f36faef8c7
|
4
|
+
data.tar.gz: '031790359ed9af74295e1679aae41a486da96104ae3a02421494c1a6a3593fd4'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48113ab44d513f63789e7821340fc2de03e8f0c2a73063354ea7fc35b378b8d1f48b22ac3fc4d444c95a810e95a80cee02d8a44866153c82fa39300c1cf142ca
|
7
|
+
data.tar.gz: 05ba491346a1079a8d4b793d3d7d727aaec7ced066d7410df3b11e8a602700ba46a2fee5504649877db567ee5adaa492ab0bc0702925bad230bd6771b4aeb002
|
data/README.md
CHANGED
@@ -1,54 +1,53 @@
|
|
1
|
-
#
|
1
|
+
# Singleton Client for Ruby
|
2
2
|
|
3
3
|
## Prerequisites
|
4
4
|
- Ruby version: 3.0.0 or above
|
5
5
|
- Bundler version: 2.2.3 or above
|
6
6
|
|
7
7
|
## Run Unit Test
|
8
|
-
rake spec
|
8
|
+
`rake spec`
|
9
9
|
|
10
10
|
## Usage
|
11
11
|
|
12
12
|
Basic Usage:
|
13
13
|
|
14
14
|
```ruby
|
15
|
-
require 'singleton-
|
16
|
-
|
17
|
-
include SgtnClient
|
18
|
-
|
19
|
-
SgtnClient.load(file, mode)
|
20
|
-
|
21
|
-
SgtnClient::Source.loadBundles(locale)
|
22
|
-
|
23
|
-
@Result = SgtnClient::Translation.getString(component, key, locale)
|
15
|
+
require 'singleton-client'
|
24
16
|
|
17
|
+
Sgtn.load_config(file, env)
|
18
|
+
result = Sgtn.translate(key, component, locale)
|
25
19
|
```
|
26
20
|
## API Usage
|
27
21
|
|
28
22
|
### Get a string's translation
|
29
|
-
|
30
|
-
|
31
|
-
### Get a string's translation and format it with placeholders
|
32
|
-
SgtnClient::Translation.getString_f(component, key, args, locale)
|
33
|
-
|
34
|
-
### Get a component's translations
|
35
|
-
SgtnClient::Translation.getStrings(component, locale)
|
36
|
-
|
23
|
+
`result = Sgtn.translate(key, component, locale)`
|
37
24
|
|
38
|
-
|
39
|
-
|
40
|
-
Before call below APIs(without locale and component arguments), it requires to set the locale and component in the initial codes.
|
41
|
-
|
42
|
-
### Get a string's translation
|
43
|
-
SgtnClient::T.s(key)
|
25
|
+
### Get a string's translation with default value when no translation
|
26
|
+
`result = Sgtn.translate(key, component, locale) { 'default value' }`
|
44
27
|
|
45
28
|
### Get a string's translation and format it with placeholders
|
46
|
-
|
29
|
+
`result = Sgtn.translate(key, component, locale, **args)`
|
47
30
|
|
48
|
-
### Get
|
49
|
-
|
31
|
+
### Get pluralized translation
|
32
|
+
`result = Sgtn.translate(key, component, locale, **args)`
|
50
33
|
|
34
|
+
### Get translations of a bundle
|
35
|
+
`result = Sgtn.get_translations(component, locale)`
|
51
36
|
|
37
|
+
### Set locale for a request
|
38
|
+
`Sgtn.locale = 'en'`
|
52
39
|
|
40
|
+
### Get locale of the request
|
41
|
+
`result = Sgtn.locale`
|
53
42
|
|
43
|
+
### Get a string's translation with locale set
|
44
|
+
```ruby
|
45
|
+
Sgtn.locale = 'en'
|
46
|
+
result = Sgtn.translate(key, component)
|
47
|
+
```
|
54
48
|
|
49
|
+
### Get translations of a bundle with locale set
|
50
|
+
```ruby
|
51
|
+
Sgtn.locale = 'en'
|
52
|
+
result = Sgtn.get_translations(component)
|
53
|
+
```
|
@@ -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/
|
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
|
-
|
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
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
8
|
+
module Implementation
|
9
|
+
# <b>DEPRECATED:</b> Please use <tt>Sgtn: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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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>Sgtn: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
|
-
|
45
|
-
|
46
|
-
|
21
|
+
# <b>DEPRECATED:</b> Please use <tt>Sgtn: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
|
-
|
49
|
-
s = s % args
|
34
|
+
s
|
50
35
|
end
|
51
|
-
s
|
52
|
-
end
|
53
36
|
|
54
|
-
|
55
|
-
|
56
|
-
|
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>Sgtn:get_translations</tt> instead.
|
38
|
+
def getStrings(component, locale)
|
39
|
+
get_translations(component, locale)
|
60
40
|
end
|
61
41
|
|
62
|
-
|
63
|
-
|
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
|
-
|
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
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
54
|
+
if result.nil?
|
55
|
+
return key unless block_given?
|
56
|
+
|
57
|
+
result = yield
|
58
|
+
return if result.nil?
|
59
|
+
end
|
80
60
|
|
81
|
-
|
82
|
-
|
83
|
-
|
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
|
87
|
-
#
|
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
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
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
|
-
|
99
|
-
|
80
|
+
{ 'component' => component, 'locale' => locale, 'messages' => items || {} } if items
|
81
|
+
end
|
100
82
|
|
101
|
-
|
102
|
-
|
83
|
+
def locale
|
84
|
+
RequestStore.store[:locale] ||= SgtnClient::LocaleUtil.get_fallback_locale
|
103
85
|
end
|
104
86
|
|
105
|
-
def
|
106
|
-
|
87
|
+
def locale=(value)
|
88
|
+
RequestStore.store[:locale] = SgtnClient::LocaleUtil.get_best_locale(value)
|
89
|
+
end
|
107
90
|
|
108
|
-
|
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
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# SPDX-License-Identifier: EPL-2.0
|
3
3
|
|
4
4
|
String.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
5
|
+
# <b>DEPRECATED:</b> Please use <tt>Sgtn:translate</tt> instead.
|
5
6
|
def to_plural_s(locale, arg)
|
6
7
|
num_str = SgtnClient::Formatters::PluralFormatter.new(locale).num_s(self, arg)
|
7
8
|
if num_str.nil? || num_str.empty?
|
@@ -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
|
@@ -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,
|
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
|
@@ -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
|
-
|
9
|
+
module TranslationLoader
|
10
|
+
autoload :CONSTS, 'sgtn-client/loader/consts'
|
26
11
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
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
|