17
17
*/
18
18
package com .tc .config ;
19
19
20
-
21
20
import com .tc .classloader .ServiceLocator ;
22
21
import com .tc .productinfo .ProductInfo ;
23
22
import com .tc .properties .TCPropertiesImpl ;
28
27
import java .io .ByteArrayInputStream ;
29
28
import java .io .InputStream ;
30
29
import java .nio .charset .StandardCharsets ;
31
- import java .util .Collection ;
32
30
import java .util .Collections ;
33
31
import java .util .HashMap ;
34
32
import java .util .Map ;
35
33
import java .util .Objects ;
36
34
import java .util .Properties ;
37
35
import org .terracotta .configuration .ConfigurationException ;
38
36
import com .tc .text .PrettyPrintable ;
37
+ import java .io .Closeable ;
38
+ import java .io .File ;
39
+ import java .net .InetSocketAddress ;
39
40
import java .util .List ;
41
+ import java .util .concurrent .locks .Lock ;
42
+ import java .util .concurrent .locks .ReentrantLock ;
43
+ import java .util .stream .Collectors ;
44
+ import org .slf4j .Logger ;
45
+ import org .slf4j .LoggerFactory ;
46
+ import org .terracotta .configuration .FailoverBehavior ;
47
+ import org .terracotta .entity .ServiceProviderConfiguration ;
40
48
41
49
public class ServerConfigurationManager implements PrettyPrintable {
42
50
43
- private final ConfigurationProvider configurationProvider ;
51
+ private final Logger LOGGER = LoggerFactory .getLogger (ServerConfigurationManager .class );
52
+ private final CachingConfigurationProvider configurationProvider ;
53
+ private ServerConfiguration thisServer ;
44
54
private final ServiceLocator serviceLocator ;
45
55
private final List <String > startUpArgs ;
46
56
private final ProductInfo productInfo ;
47
57
48
- private Configuration configuration ;
49
- private ServerConfiguration serverConfiguration ;
50
-
51
58
public ServerConfigurationManager (ConfigurationProvider configurationProvider ,
52
- ServiceLocator classLoader ,
53
- List <String > startUpArgs ) {
59
+ ServiceLocator classLoader ,
60
+ List <String > startUpArgs ) {
54
61
Objects .requireNonNull (configurationProvider );
55
62
Objects .requireNonNull (classLoader );
56
63
Objects .requireNonNull (startUpArgs );
57
64
58
- this .configurationProvider = configurationProvider ;
65
+ this .configurationProvider = new CachingConfigurationProvider ( configurationProvider ) ;
59
66
this .serviceLocator = classLoader ;
60
67
this .startUpArgs = startUpArgs ;
61
68
this .productInfo = generateProductInfo (serviceLocator );
@@ -70,18 +77,24 @@ public ProductInfo getProductInfo() {
70
77
}
71
78
72
79
public void initialize () throws ConfigurationException {
73
- this .configurationProvider .initialize (this .startUpArgs );
74
-
75
- this .configuration = configurationProvider .getConfiguration ();
76
- if (this .configuration == null ) {
77
- throw new ConfigurationException ("unable to determine server configuration" );
78
- }
80
+ Lock lock = this .configurationProvider .lockAndInitialize (this .startUpArgs );
79
81
80
- this .serverConfiguration = this .configuration .getServerConfiguration ();
81
- if (this .serverConfiguration == null ) {
82
- throw new ConfigurationException ("unable to determine server configuration" );
82
+ try {
83
+ Configuration configuration = configurationProvider .getConfiguration ();
84
+ if (configuration == null ) {
85
+ throw new ConfigurationException ("unable to determine server configuration" );
86
+ }
87
+
88
+ ServerConfiguration base = configuration .getServerConfiguration ();
89
+ if (base == null ) {
90
+ throw new ConfigurationException ("unable to determine server configuration" );
91
+ }
92
+ thisServer = new StableServerConfiguration (base );
93
+
94
+ processTcProperties (configuration .getTcProperties ());
95
+ } finally {
96
+ lock .unlock ();
83
97
}
84
- processTcProperties (configuration .getTcProperties ());
85
98
}
86
99
87
100
public void close () {
@@ -93,69 +106,265 @@ public String[] getProcessArguments() {
93
106
}
94
107
95
108
public ServerConfiguration getServerConfiguration () {
96
- return this . serverConfiguration ;
109
+ return thisServer ;
97
110
}
98
111
99
112
public GroupConfiguration getGroupConfiguration () {
100
- List <ServerConfiguration > serverConfigurationMap = configuration . getServerConfigurations ();
101
- return new GroupConfiguration (serverConfigurationMap , this . serverConfiguration .getName ());
113
+ List <ServerConfiguration > serverConfigurationMap = configurationProvider . getStableServerConfigurations ();
114
+ return new GroupConfiguration (serverConfigurationMap , getServerConfiguration () .getName ());
102
115
}
103
-
116
+
104
117
public InputStream rawConfigFile () {
105
- String text = configuration .getRawConfiguration ();
106
- return new ByteArrayInputStream (text .getBytes (StandardCharsets .UTF_8 ));
118
+ try (LockedConfiguration config = configurationProvider .getLockedConfiguration ()) {
119
+ String text = config .getRawConfiguration ();
120
+ return new ByteArrayInputStream (text .getBytes (StandardCharsets .UTF_8 ));
121
+ }
107
122
}
108
123
109
124
public String rawConfigString () {
110
- return configuration .getRawConfiguration ();
125
+ try (LockedConfiguration config = configurationProvider .getLockedConfiguration ()) {
126
+ return config .getRawConfiguration ();
127
+ }
111
128
}
112
129
113
130
public String [] allCurrentlyKnownServers () {
114
131
return getGroupConfiguration ().getMembers ();
115
132
}
116
-
133
+
134
+ public boolean isConsistentStartup () {
135
+ try (LockedConfiguration config = configurationProvider .getLockedConfiguration ()) {
136
+ return config .isConsistentStartup ();
137
+ }
138
+ }
139
+
117
140
public boolean isPartialConfiguration () {
118
- return this .configuration .isPartialConfiguration ();
141
+ try (LockedConfiguration config = configurationProvider .getLockedConfiguration ()) {
142
+ return config .isPartialConfiguration ();
143
+ }
144
+ }
145
+
146
+ public FailoverBehavior getFailoverPriority () {
147
+ try (LockedConfiguration config = configurationProvider .getLockedConfiguration ()) {
148
+ return config .getFailoverPriority ();
149
+ }
150
+ }
151
+
152
+ public <T > List <T > getExtendedConfiguration (Class <T > type ) {
153
+ try (LockedConfiguration config = configurationProvider .getLockedConfiguration ()) {
154
+ return config .getExtendedConfiguration (type );
155
+ }
119
156
}
120
157
158
+ public List <ServiceProviderConfiguration > getServiceConfigurations () {
159
+ try (LockedConfiguration config = configurationProvider .getLockedConfiguration ()) {
160
+ return config .getServiceConfigurations ();
161
+ }
162
+ }
163
+
121
164
public ServiceLocator getServiceLocator () {
122
165
return this .serviceLocator ;
123
166
}
124
167
125
- public Configuration getConfiguration () {
126
- return configuration ;
127
- }
128
-
129
168
public ConfigurationProvider getConfigurationProvider () {
130
- return configurationProvider ;
131
- }
132
-
133
- private Map <String , ServerConfiguration > getServerConfigurationMap (Collection <ServerConfiguration > servers ) {
134
- Map <String , ServerConfiguration > serverConfigurationMap = new HashMap <>();
135
- for (ServerConfiguration server : servers ) {
136
- if (server .getName () != null ) {
137
- serverConfigurationMap .put (server .getName (), server );
138
- }
139
- }
140
- return serverConfigurationMap ;
169
+ return configurationProvider .delegateProvider ;
141
170
}
142
171
143
172
private static void processTcProperties (Properties tcProperties ) {
144
173
Map <String , String > propMap = new HashMap <>();
145
174
146
175
if (tcProperties != null ) {
147
- tcProperties .forEach ((k , v )-> propMap .put (k .toString ().trim (), v .toString ().trim ()));
176
+ tcProperties .forEach ((k , v ) -> propMap .put (k .toString ().trim (), v .toString ().trim ()));
148
177
}
149
178
150
179
TCPropertiesImpl .getProperties ().overwriteTcPropertiesFromConfig (propMap );
151
180
}
152
181
153
182
@ Override
154
183
public Map <String , ?> getStateMap () {
155
- if (configuration instanceof PrettyPrintable ) {
156
- return ((PrettyPrintable )configuration ).getStateMap ();
157
- } else {
158
- return Collections .emptyMap ();
184
+ try (LockedConfiguration config = configurationProvider .getLockedConfiguration ()) {
185
+ if (config instanceof PrettyPrintable ) {
186
+ return ((PrettyPrintable ) config ).getStateMap ();
187
+ } else {
188
+ return Collections .emptyMap ();
189
+ }
190
+ }
191
+ }
192
+
193
+ private static class LockedConfiguration implements Configuration , Closeable {
194
+ private final Configuration delegate ;
195
+ private final Lock close ;
196
+
197
+ public LockedConfiguration (Configuration delegate , Lock close ) {
198
+ this .delegate = delegate ;
199
+ this .close = close ;
200
+ }
201
+
202
+ public void close () {
203
+ close .unlock ();
204
+ }
205
+
206
+ @ Override
207
+ public ServerConfiguration getServerConfiguration () throws ConfigurationException {
208
+ return delegate .getServerConfiguration ();
209
+ }
210
+
211
+ @ Override
212
+ public List <ServerConfiguration > getServerConfigurations () {
213
+ return delegate .getServerConfigurations ();
214
+ }
215
+
216
+ @ Override
217
+ public List <ServiceProviderConfiguration > getServiceConfigurations () {
218
+ return delegate .getServiceConfigurations ();
219
+ }
220
+
221
+ @ Override
222
+ public <T > List <T > getExtendedConfiguration (Class <T > type ) {
223
+ return delegate .getExtendedConfiguration (type );
224
+ }
225
+
226
+ @ Override
227
+ public String getRawConfiguration () {
228
+ return delegate .getRawConfiguration ();
229
+ }
230
+
231
+ @ Override
232
+ public Properties getTcProperties () {
233
+ return delegate .getTcProperties ();
234
+ }
235
+
236
+ @ Override
237
+ public FailoverBehavior getFailoverPriority () {
238
+ return delegate .getFailoverPriority ();
239
+ }
240
+
241
+ @ Override
242
+ public boolean isConsistentStartup () {
243
+ return delegate .isConsistentStartup ();
244
+ }
245
+
246
+ @ Override
247
+ public boolean isPartialConfiguration () {
248
+ return delegate .isPartialConfiguration ();
249
+ }
250
+ }
251
+
252
+ private static final class CachingConfigurationProvider implements ConfigurationProvider {
253
+
254
+ private final ConfigurationProvider delegateProvider ;
255
+ private final Lock lock = new ReentrantLock ();
256
+
257
+ public CachingConfigurationProvider (ConfigurationProvider delegateProvider ) {
258
+ this .delegateProvider = delegateProvider ;
259
+ }
260
+
261
+ List <ServerConfiguration > getStableServerConfigurations () {
262
+ lock .lock ();
263
+ try {
264
+ return delegateProvider .getConfiguration ().getServerConfigurations ().stream ().map (StableServerConfiguration ::new ).collect (Collectors .toList ());
265
+ } finally {
266
+ lock .unlock ();
267
+ }
268
+ }
269
+
270
+ Lock lockAndInitialize (List <String > configurationParams ) throws ConfigurationException {
271
+ lock .lock ();
272
+ initialize (configurationParams );
273
+ return lock ;
274
+ }
275
+
276
+ @ Override
277
+ public void initialize (List <String > configurationParams ) throws ConfigurationException {
278
+ delegateProvider .initialize (configurationParams );
279
+ }
280
+
281
+ public LockedConfiguration getLockedConfiguration () {
282
+ lock .lock ();
283
+ return new LockedConfiguration (delegateProvider .getConfiguration (), lock );
284
+ }
285
+
286
+ @ Override
287
+ public Configuration getConfiguration () {
288
+ lock .lock ();
289
+ try {
290
+ return delegateProvider .getConfiguration ();
291
+ } finally {
292
+ lock .unlock ();
293
+ }
294
+ }
295
+
296
+ @ Override
297
+ public String getConfigurationParamsDescription () {
298
+ return delegateProvider .getConfigurationParamsDescription ();
299
+ }
300
+
301
+ @ Override
302
+ public void close () {
303
+ delegateProvider .close ();
304
+ }
305
+
306
+ @ Override
307
+ public byte [] getSyncData () {
308
+ return delegateProvider .getSyncData ();
309
+ }
310
+
311
+ @ Override
312
+ public void sync (byte [] syncData ) {
313
+ lock .lock ();
314
+ try {
315
+ delegateProvider .sync (syncData );
316
+ } finally {
317
+ lock .unlock ();
318
+ }
319
+ }
320
+ }
321
+
322
+ private static class StableServerConfiguration implements ServerConfiguration {
323
+
324
+ private final InetSocketAddress tsaPort ;
325
+ private final InetSocketAddress groupPort ;
326
+ private final String host ;
327
+ private final String name ;
328
+ private final int reconnectWindow ;
329
+ private final File logDir ;
330
+
331
+ public StableServerConfiguration (ServerConfiguration base ) {
332
+ tsaPort = base .getTsaPort ();
333
+ groupPort = base .getGroupPort ();
334
+ host = base .getHost ();
335
+ name = base .getName ();
336
+ reconnectWindow = base .getClientReconnectWindow ();
337
+ logDir = base .getLogsLocation ();
338
+ }
339
+
340
+ @ Override
341
+ public InetSocketAddress getTsaPort () {
342
+ return tsaPort ;
343
+ }
344
+
345
+ @ Override
346
+ public InetSocketAddress getGroupPort () {
347
+ return groupPort ;
348
+ }
349
+
350
+ @ Override
351
+ public String getHost () {
352
+ return host ;
353
+ }
354
+
355
+ @ Override
356
+ public String getName () {
357
+ return name ;
358
+ }
359
+
360
+ @ Override
361
+ public int getClientReconnectWindow () {
362
+ return reconnectWindow ;
363
+ }
364
+
365
+ @ Override
366
+ public File getLogsLocation () {
367
+ return logDir ;
159
368
}
160
369
}
161
370
}
0 commit comments