singleton-client-test 0.7.0.33 → 0.7.0.36
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
- 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
|