Skip to content

Commit fd91f9f

Browse files
jbertrambrusdev
authored andcommitted
ARTEMIS-4197 mitigate races w/various config changes
This commit mitigates a number of different potential race conditions involving configuration changes. Consider the storeAddressSetting method in o.a.a.a.c.p.i.j.AbstractJournalStorageManager. It mutates mapPersistedAddressSettings twice - once to delete an entry and once to put an entry. If another thread executes the recoverAddressSettings method in between these two operations it will not contain the record that is being stored. This same race condition exists for a number of different maps. This commit mitigates the race condition by ensuring that the relevant map is mutated only once (i.e. via put). This commit also refactors a number of methods to avoid duplicated code. There are no tests associated with this change since there's no deterministic way to induce the race condition. It relies on static analysis and existing tests to validate the fix and detect regressions.
1 parent 044de42 commit fd91f9f

13 files changed

+242
-300
lines changed

artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/config/AbstractPersistedAddressSetting.java

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@
1818
package org.apache.activemq.artemis.core.persistence.config;
1919

2020
import org.apache.activemq.artemis.api.core.SimpleString;
21-
import org.apache.activemq.artemis.core.journal.EncodingSupport;
2221
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
2322

24-
public abstract class AbstractPersistedAddressSetting implements EncodingSupport {
23+
public abstract class AbstractPersistedAddressSetting extends PersistedConfiguration {
2524

2625
protected long storeId;
2726

@@ -38,15 +37,6 @@ public AbstractPersistedAddressSetting(SimpleString addressMatch, AddressSetting
3837
this.setting = setting;
3938
}
4039

41-
public long getStoreId() {
42-
return storeId;
43-
}
44-
45-
public AbstractPersistedAddressSetting setStoreId(long storeId) {
46-
this.storeId = storeId;
47-
return this;
48-
}
49-
5040
public SimpleString getAddressMatch() {
5141
return addressMatch;
5242
}
@@ -64,4 +54,9 @@ public AbstractPersistedAddressSetting setSetting(AddressSettings setting) {
6454
this.setting = setting;
6555
return this;
6656
}
57+
58+
@Override
59+
public String getName() {
60+
return addressMatch.toString();
61+
}
6762
}

artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/config/PersistedAddressSetting.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
2020
import org.apache.activemq.artemis.core.journal.EncodingSupport;
21+
import org.apache.activemq.artemis.core.persistence.impl.journal.JournalRecordIds;
2122
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
2223

2324
/**
@@ -63,4 +64,8 @@ public int getEncodeSize() {
6364
return addressMatch.sizeof() + setting.getEncodeSize();
6465
}
6566

67+
@Override
68+
public byte getRecordType() {
69+
return JournalRecordIds.ADDRESS_SETTING_RECORD;
70+
}
6671
}

artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/config/PersistedAddressSettingJSON.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818

1919
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
2020
import org.apache.activemq.artemis.api.core.SimpleString;
21-
import org.apache.activemq.artemis.core.journal.EncodingSupport;
21+
import org.apache.activemq.artemis.core.persistence.impl.journal.JournalRecordIds;
2222
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
2323

24-
public class PersistedAddressSettingJSON extends AbstractPersistedAddressSetting implements EncodingSupport {
24+
public class PersistedAddressSettingJSON extends AbstractPersistedAddressSetting {
2525

2626
SimpleString jsonSetting;
2727

@@ -68,4 +68,9 @@ public int getEncodeSize() {
6868
public String toString() {
6969
return "PersistedAddressSettingJSON{" + "jsonSetting=" + jsonSetting + ", storeId=" + storeId + ", addressMatch=" + addressMatch + ", setting=" + setting + '}';
7070
}
71+
72+
@Override
73+
public byte getRecordType() {
74+
return JournalRecordIds.ADDRESS_SETTING_RECORD_JSON;
75+
}
7176
}

artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/config/PersistedBridgeConfiguration.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,10 @@
1818

1919
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
2020
import org.apache.activemq.artemis.core.config.BridgeConfiguration;
21-
import org.apache.activemq.artemis.core.journal.EncodingSupport;
21+
import org.apache.activemq.artemis.core.persistence.impl.journal.JournalRecordIds;
2222

23-
public class PersistedBridgeConfiguration implements EncodingSupport {
23+
public class PersistedBridgeConfiguration extends PersistedConfiguration {
2424

25-
private long storeId;
2625
private BridgeConfiguration bridgeConfiguration;
2726

2827
@Override
@@ -38,14 +37,6 @@ public PersistedBridgeConfiguration() {
3837
bridgeConfiguration = new BridgeConfiguration();
3938
}
4039

41-
public void setStoreId(long id) {
42-
this.storeId = id;
43-
}
44-
45-
public long getStoreId() {
46-
return storeId;
47-
}
48-
4940
@Override
5041
public int getEncodeSize() {
5142
return bridgeConfiguration.getEncodeSize();
@@ -61,10 +52,16 @@ public void decode(ActiveMQBuffer buffer) {
6152
bridgeConfiguration.decode(buffer);
6253
}
6354

55+
@Override
6456
public String getName() {
6557
return bridgeConfiguration.getParentName();
6658
}
6759

60+
@Override
61+
public byte getRecordType() {
62+
return JournalRecordIds.BRIDGE_RECORD;
63+
}
64+
6865
public BridgeConfiguration getBridgeConfiguration() {
6966
return bridgeConfiguration;
7067
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.activemq.artemis.core.persistence.config;
18+
19+
import org.apache.activemq.artemis.core.journal.EncodingSupport;
20+
21+
public abstract class PersistedConfiguration implements EncodingSupport {
22+
23+
protected long storeId;
24+
25+
public void setStoreId(long id) {
26+
this.storeId = id;
27+
}
28+
29+
public long getStoreId() {
30+
return storeId;
31+
}
32+
33+
/**
34+
* Returns the name to be used as the key for the map used by the broker to track this configuration implementation.
35+
*
36+
* @return the name as a String
37+
*/
38+
public abstract String getName();
39+
40+
public abstract byte getRecordType();
41+
}

artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/config/PersistedConnector.java

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,10 @@
1717
package org.apache.activemq.artemis.core.persistence.config;
1818

1919
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
20-
import org.apache.activemq.artemis.core.journal.EncodingSupport;
20+
import org.apache.activemq.artemis.core.persistence.impl.journal.JournalRecordIds;
2121
import org.apache.activemq.artemis.utils.BufferHelper;
2222

23-
public class PersistedConnector implements EncodingSupport {
24-
25-
private long storeId;
23+
public class PersistedConnector extends PersistedConfiguration {
2624

2725
private String url;
2826

@@ -36,14 +34,6 @@ public PersistedConnector(String name, String url) {
3634
this.url = url;
3735
}
3836

39-
public void setStoreId(long id) {
40-
this.storeId = id;
41-
}
42-
43-
public long getStoreId() {
44-
return storeId;
45-
}
46-
4737
public void setUrl(String url) {
4838
this.url = url;
4939
}
@@ -56,10 +46,16 @@ public void setName(String name) {
5646
this.name = name;
5747
}
5848

49+
@Override
5950
public String getName() {
6051
return name;
6152
}
6253

54+
@Override
55+
public byte getRecordType() {
56+
return JournalRecordIds.CONNECTOR_RECORD;
57+
}
58+
6359
@Override
6460
public int getEncodeSize() {
6561
int size = 0;

artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/config/PersistedDivertConfiguration.java

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@
1818

1919
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
2020
import org.apache.activemq.artemis.core.config.DivertConfiguration;
21-
import org.apache.activemq.artemis.core.journal.EncodingSupport;
21+
import org.apache.activemq.artemis.core.persistence.impl.journal.JournalRecordIds;
2222

23-
public class PersistedDivertConfiguration implements EncodingSupport {
24-
25-
private long storeId;
23+
public class PersistedDivertConfiguration extends PersistedConfiguration {
2624

2725
private DivertConfiguration divertConfiguration;
2826

@@ -39,14 +37,6 @@ public PersistedDivertConfiguration() {
3937
divertConfiguration = new DivertConfiguration();
4038
}
4139

42-
public void setStoreId(long id) {
43-
this.storeId = id;
44-
}
45-
46-
public long getStoreId() {
47-
return storeId;
48-
}
49-
5040
@Override
5141
public int getEncodeSize() {
5242
return divertConfiguration.getEncodeSize();
@@ -62,10 +52,16 @@ public void decode(ActiveMQBuffer buffer) {
6252
divertConfiguration.decode(buffer);
6353
}
6454

55+
@Override
6556
public String getName() {
6657
return divertConfiguration.getName();
6758
}
6859

60+
@Override
61+
public byte getRecordType() {
62+
return JournalRecordIds.DIVERT_RECORD;
63+
}
64+
6965
public DivertConfiguration getDivertConfiguration() {
7066
return divertConfiguration;
7167
}

artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/config/PersistedKeyValuePair.java

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,10 @@
1717
package org.apache.activemq.artemis.core.persistence.config;
1818

1919
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
20-
import org.apache.activemq.artemis.core.journal.EncodingSupport;
20+
import org.apache.activemq.artemis.core.persistence.impl.journal.JournalRecordIds;
2121
import org.apache.activemq.artemis.utils.BufferHelper;
2222

23-
public class PersistedKeyValuePair implements EncodingSupport {
24-
25-
private long storeId;
23+
public class PersistedKeyValuePair extends PersistedConfiguration {
2624

2725
private String mapId;
2826

@@ -39,14 +37,6 @@ public PersistedKeyValuePair(String mapId, String key, String value) {
3937
this.value = value;
4038
}
4139

42-
public void setStoreId(long id) {
43-
this.storeId = id;
44-
}
45-
46-
public long getStoreId() {
47-
return storeId;
48-
}
49-
5040
public String getMapId() {
5141
return mapId;
5242
}
@@ -59,6 +49,16 @@ public String getValue() {
5949
return value;
6050
}
6151

52+
@Override
53+
public String getName() {
54+
return mapId;
55+
}
56+
57+
@Override
58+
public byte getRecordType() {
59+
return JournalRecordIds.KEY_VALUE_PAIR_RECORD;
60+
}
61+
6262
@Override
6363
public int getEncodeSize() {
6464
int size = 0;
@@ -85,12 +85,9 @@ public void decode(ActiveMQBuffer buffer) {
8585
@Override
8686
public String toString() {
8787
return "PersistedKeyValuePair [storeId=" + storeId +
88-
", mapId=" +
89-
mapId +
90-
", key=" +
91-
key +
92-
", value=" +
93-
value +
88+
", mapId=" + mapId +
89+
", key=" + key +
90+
", value=" + value +
9491
"]";
9592
}
9693
}

artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/config/PersistedRole.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,11 @@
2121
import java.util.Objects;
2222

2323
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
24-
import org.apache.activemq.artemis.core.journal.EncodingSupport;
24+
import org.apache.activemq.artemis.core.persistence.impl.journal.JournalRecordIds;
2525
import org.apache.activemq.artemis.utils.BufferHelper;
2626
import org.apache.activemq.artemis.utils.DataConstants;
2727

28-
public class PersistedRole implements EncodingSupport {
29-
30-
private long storeId;
28+
public class PersistedRole extends PersistedConfiguration {
3129

3230
private String username;
3331

@@ -41,14 +39,6 @@ public PersistedRole(String username, List<String> roles) {
4139
this.roles = Objects.requireNonNull(roles);
4240
}
4341

44-
public void setStoreId(long id) {
45-
this.storeId = id;
46-
}
47-
48-
public long getStoreId() {
49-
return storeId;
50-
}
51-
5242
public String getUsername() {
5343
return username;
5444
}
@@ -105,4 +95,14 @@ public String toString() {
10595

10696
return result.toString();
10797
}
98+
99+
@Override
100+
public byte getRecordType() {
101+
return JournalRecordIds.ROLE_RECORD;
102+
}
103+
104+
@Override
105+
public String getName() {
106+
return username;
107+
}
108108
}

0 commit comments

Comments
 (0)