@@ -75,8 +75,8 @@ public class AppSecConfigServiceImpl implements AppSecConfigService {
75
75
private final ConfigurationPoller configurationPoller ;
76
76
private WafBuilder wafBuilder ;
77
77
78
- private MergedAsmFeatures mergedAsmFeatures ;
79
- private volatile boolean initialized ;
78
+ private final MergedAsmFeatures mergedAsmFeatures = new MergedAsmFeatures () ;
79
+ private volatile State state = State . UNINITIALIZED ;
80
80
81
81
private final ConcurrentHashMap <String , SubconfigListener > subconfigListeners =
82
82
new ConcurrentHashMap <>();
@@ -95,8 +95,6 @@ public class AppSecConfigServiceImpl implements AppSecConfigService {
95
95
.build ()
96
96
.adapter (Types .newParameterizedType (Map .class , String .class , Object .class ));
97
97
98
- private boolean hasUserWafConfig ;
99
- private boolean defaultConfigActivated ;
100
98
private final Set <String > usedDDWafConfigKeys = new HashSet <>();
101
99
private final String DEFAULT_WAF_CONFIG_RULE = "DEFAULT_WAF_CONFIG" ;
102
100
private String currentRuleVersion ;
@@ -119,7 +117,7 @@ private void subscribeConfigurationPoller() {
119
117
// see also close() method
120
118
subscribeAsmFeatures ();
121
119
122
- if (! hasUserWafConfig ) {
120
+ if (state != State . USER_CONFIG ) {
123
121
subscribeRulesAndData ();
124
122
} else {
125
123
log .debug ("Will not subscribe to ASM, ASM_DD and ASM_DATA (AppSec custom rules in use)" );
@@ -173,10 +171,7 @@ private class AppSecConfigChangesListener implements ProductListener {
173
171
@ Override
174
172
public void accept (ConfigKey configKey , byte [] content , PollingRateHinter pollingRateHinter )
175
173
throws IOException {
176
- if (!initialized ) {
177
- throw new IllegalStateException ();
178
- }
179
-
174
+ maybeInit ();
180
175
if (content == null ) {
181
176
try {
182
177
wafBuilder .removeConfig (configKey .toString ());
@@ -210,15 +205,15 @@ private class AppSecConfigChangesDDListener extends AppSecConfigChangesListener
210
205
@ Override
211
206
public void accept (ConfigKey configKey , byte [] content , PollingRateHinter pollingRateHinter )
212
207
throws IOException {
213
- if (defaultConfigActivated ) { // if we get any config, remove the default one
208
+ if (state == State . DEFAULT_CONFIG ) { // if we get any config, remove the default one
214
209
log .debug ("Removing default config" );
215
210
try {
216
211
wafBuilder .removeConfig (DEFAULT_WAF_CONFIG_RULE );
217
212
} catch (UnclassifiedWafException e ) {
218
213
throw new RuntimeException (e );
219
214
}
220
- defaultConfigActivated = false ;
221
215
}
216
+ state = State .REMOTE_CONFIG ;
222
217
super .accept (configKey , content , pollingRateHinter );
223
218
usedDDWafConfigKeys .add (configKey .toString ());
224
219
}
@@ -228,6 +223,9 @@ public void remove(ConfigKey configKey, PollingRateHinter pollingRateHinter)
228
223
throws IOException {
229
224
super .remove (configKey , pollingRateHinter );
230
225
usedDDWafConfigKeys .remove (configKey .toString ());
226
+ if (usedDDWafConfigKeys .isEmpty ()) {
227
+ init (); // initialize again the default config
228
+ }
231
229
}
232
230
}
233
231
@@ -252,7 +250,7 @@ private void handleWafUpdateResultReport(String configKey, Map<String, Object> r
252
250
if (wafDiagnostics .rulesetVersion != null
253
251
&& !wafDiagnostics .rulesetVersion .isEmpty ()
254
252
&& !wafDiagnostics .rules .getLoaded ().isEmpty ()
255
- && (! defaultConfigActivated || currentRuleVersion == null )) {
253
+ && (state != State . DEFAULT_CONFIG || currentRuleVersion == null )) {
256
254
currentRuleVersion = wafDiagnostics .rulesetVersion ;
257
255
statsReporter .setRulesVersion (currentRuleVersion );
258
256
if (modulesToUpdateVersionIn != null ) {
@@ -282,13 +280,7 @@ private void subscribeAsmFeatures() {
282
280
Product .ASM_FEATURES ,
283
281
AppSecFeaturesDeserializer .INSTANCE ,
284
282
(configKey , newConfig , hinter ) -> {
285
- if (!hasUserWafConfig && !defaultConfigActivated ) {
286
- // features activated in runtime
287
- init ();
288
- }
289
- if (!initialized ) {
290
- throw new IllegalStateException ();
291
- }
283
+ maybeInit ();
292
284
if (newConfig == null ) {
293
285
mergedAsmFeatures .removeConfig (configKey );
294
286
} else {
@@ -305,10 +297,6 @@ private void subscribeAsmFeatures() {
305
297
306
298
private void distributeSubConfigurations (
307
299
String key , AppSecModuleConfigurer .Reconfiguration reconfiguration ) {
308
- if (usedDDWafConfigKeys .isEmpty () && !defaultConfigActivated && !hasUserWafConfig ) {
309
- // no config left in the WAF builder, add the default config
310
- init ();
311
- }
312
300
for (Map .Entry <String , SubconfigListener > entry : subconfigListeners .entrySet ()) {
313
301
SubconfigListener listener = entry .getValue ();
314
302
try {
@@ -320,29 +308,33 @@ private void distributeSubConfigurations(
320
308
}
321
309
}
322
310
311
+ private void maybeInit () {
312
+ if (state == State .UNINITIALIZED ) {
313
+ init ();
314
+ }
315
+ }
316
+
323
317
@ Override
324
318
public void init () {
325
319
Map <String , Object > wafConfig ;
326
- hasUserWafConfig = false ;
327
320
try {
328
321
wafConfig = loadUserWafConfig (tracerConfig );
322
+ state = State .USER_CONFIG ;
329
323
} catch (Exception e ) {
330
324
log .error ("Error loading user-provided config" , e );
331
325
throw new AbortStartupException ("Error loading user-provided config" , e );
332
326
}
333
327
if (wafConfig == null ) {
334
328
try {
335
329
wafConfig = loadDefaultWafConfig ();
336
- defaultConfigActivated = true ;
330
+ state = State . DEFAULT_CONFIG ;
337
331
} catch (IOException e ) {
338
332
log .error ("Error loading default config" , e );
339
333
throw new AbortStartupException ("Error loading default config" , e );
340
334
}
341
- } else {
342
- hasUserWafConfig = true ;
343
335
}
344
- this . mergedAsmFeatures = new MergedAsmFeatures ();
345
- this . initialized = true ;
336
+ mergedAsmFeatures . clear ();
337
+ usedDDWafConfigKeys . clear () ;
346
338
347
339
if (wafConfig .isEmpty ()) {
348
340
throw new IllegalStateException ("Expected default waf config to be available" );
@@ -356,7 +348,7 @@ public void init() {
356
348
357
349
public void maybeSubscribeConfigPolling () {
358
350
if (this .configurationPoller != null ) {
359
- if (hasUserWafConfig
351
+ if (state == State . USER_CONFIG
360
352
&& tracerConfig .getAppSecActivation () == ProductActivation .FULLY_ENABLED ) {
361
353
log .info (
362
354
"AppSec will not use remote config because "
@@ -467,6 +459,7 @@ private static int countRules(Map<String, Object> config) {
467
459
468
460
@ Override
469
461
public void close () {
462
+ state = State .UNINITIALIZED ;
470
463
if (this .configurationPoller == null ) {
471
464
return ;
472
465
}
@@ -558,4 +551,11 @@ private static WafConfig createWafConfig(Config config) {
558
551
}
559
552
return wafConfig ;
560
553
}
554
+
555
+ private enum State {
556
+ UNINITIALIZED ,
557
+ DEFAULT_CONFIG ,
558
+ USER_CONFIG ,
559
+ REMOTE_CONFIG
560
+ }
561
561
}
0 commit comments