Skip to content

Commit

Permalink
ARTEMIS-4545 Allow node ID to be configured
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonRoskvist committed May 31, 2024
1 parent b05d45c commit 6a36082
Show file tree
Hide file tree
Showing 14 changed files with 122 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ public interface Configuration {
*/
Configuration setName(String name);

/**
* Returns the ID of the node.
*/
String getNodeID();

/**
* Sets the ID of the node. If not set, a UUID generated on first startup will be used instead.
*/
Configuration setNodeID(String nodeID);

/**
* We use Bean-utils to pass in System.properties that start with {@link #setSystemPropertyPrefix(String)}.
* The default should be 'brokerconfig.' (Including the ".").
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ public class ConfigurationImpl implements Configuration, Serializable {

private String name = "localhost";

private String nodeID = null;

private boolean persistenceEnabled = ActiveMQDefaultConfiguration.isDefaultPersistenceEnabled();

private int maxRedeliveryRecords = ActiveMQDefaultConfiguration.getDefaultMaxRedeliveryRecords();
Expand Down Expand Up @@ -2559,6 +2561,17 @@ public ConfigurationImpl setName(String name) {
return this;
}

@Override
public String getNodeID() {
return nodeID;
}

@Override
public ConfigurationImpl setNodeID(String nodeID) {
this.nodeID = toCompatibleNodeID(nodeID);
return this;
}

@Override
public ConfigurationImpl setResolveProtocols(boolean resolveProtocols) {
this.resolveProtocols = resolveProtocols;
Expand Down Expand Up @@ -3665,6 +3678,28 @@ public String getProperty(final String expression) {
}
}

private String toCompatibleNodeID(String nodeID) {
if (nodeID == null) {
return null;
}

final int len = nodeID.length();

if (!(len > 0)) {
return null;
}

if (len >= 16) {
nodeID = nodeID.substring(0, 16);
} else if (len % 2 != 0) {
// must be even for conversion to uuid, extend to next even
nodeID = nodeID + "+";
}

return nodeID.replace('-', '.');

}

public static class InsertionOrderedProperties extends Properties {

final LinkedHashMap<Object, Object> orderedMap = new LinkedHashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,8 @@ public void parseMainConfig(final Element e, final Configuration config) throws

config.setName(getString(e, "name", config.getName(), NO_CHECK));

config.setNodeID(getString(e, "node-id", config.getNodeID(), NO_CHECK));

config.setSystemPropertyPrefix(getString(e, "system-property-prefix", config.getSystemPropertyPrefix(), NOT_NULL_OR_EMPTY));

NodeList haPolicyNodes = e.getElementsByTagName("ha-policy");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ public SimpleString getNodeId() {
}
}

/**
* Returns the converted form of a given nodeID
*
* @param nodeID
*/
public String getConvertedNodeId(String nodeID) {
return new UUID(UUID.TYPE_TIME_BASED, UUID.stringToBytes(nodeID)).toString();
}

public long readNodeActivationSequence() throws NodeManagerException {
// TODO make it abstract
throw new UnsupportedOperationException("TODO");
Expand Down Expand Up @@ -117,16 +126,14 @@ public UUID getUUID() {
}

/**
* Sets the nodeID.
* <p>
* Only used by replicating backups.
* Sets the nodeID
*
* @param nodeID
*/
public void setNodeID(String nodeID) {
synchronized (nodeIDGuard) {
this.nodeID = new SimpleString(nodeID);
this.uuid = new UUID(UUID.TYPE_TIME_BASED, UUID.stringToBytes(nodeID));
this.nodeID = new SimpleString(uuid.toString());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,11 @@ protected NodeManager createNodeManager(final File directory, boolean replicatin
} else {
manager = new FileLockNodeManager(directory, replicatingBackup, configuration.getJournalLockAcquisitionTimeout(), scheduledPool);
}

if (!replicatingBackup && configuration.getNodeID() != null) {
manager.setNodeID(configuration.getNodeID());
}

return manager;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,9 @@ protected final synchronized void createNodeId() throws IOException {
channel.write(id, 3);
channel.force(true);
} else if (read != 16) {
setUUID(UUIDGenerator.getInstance().generateUUID());
if (getUUID() == null) {
setUUID(UUIDGenerator.getInstance().generateUUID());
}
id.put(getUUID().asBytes(), 0, 16);
id.position(0);
channel.write(id, 3);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public ReplicationBackupActivation(final ActiveMQServerImpl activeMQServer,
// patch expectedNodeID
final String coordinationId = policy.getPrimaryPolicy().getCoordinationId();
if (coordinationId != null) {
expectedNodeID = coordinationId;
expectedNodeID = activeMQServer.getNodeManager().getConvertedNodeId(coordinationId);
} else {
final SimpleString serverNodeID = activeMQServer.getNodeID();
if (serverNodeID == null || serverNodeID.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@
</xsd:annotation>
</xsd:element>

<xsd:element name="node-id" type="xsd:string" maxOccurs="1" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Node ID. If set, it will be used as an identifier when running in a cluster.
Has to be unique within the cluster
</xsd:documentation>
</xsd:annotation>
</xsd:element>

<xsd:element name="system-property-prefix" type="xsd:string" maxOccurs="1" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
xsi:schemaLocation="urn:activemq ../../../../activemq-server/src/main/resources/schema/artemis-server.xsd">
<core xmlns="urn:activemq:core">
<name>SomeNameForUseOnTheApplicationServer</name>
<node-id>AUniqueIDForThisBroker</node-id>
<resolve-protocols>false</resolve-protocols>
<persistence-enabled>false</persistence-enabled>
<scheduled-thread-pool-max-size>12345</scheduled-thread-pool-max-size>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
xsi:schemaLocation="urn:activemq ../../../../activemq-server/src/main/resources/schema/artemis-server.xsd">
<core xmlns="urn:activemq:core">
<name>SomeNameForUseOnTheApplicationServer</name>
<node-id>AUniqueIDForThisBroker</node-id>
<resolve-protocols>false</resolve-protocols>
<persistence-enabled>false</persistence-enabled>
<scheduled-thread-pool-max-size>12345</scheduled-thread-pool-max-size>
Expand Down
1 change: 1 addition & 0 deletions docs/user-manual/_book.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ include::metrics.adoc[leveloffset=1]

//== Broker-to-Broker Connectivity

include::node-id.adoc[leveloffset=1]
include::core-bridges.adoc[leveloffset=1]
include::clusters.adoc[leveloffset=1]
include::federation.adoc[leveloffset=1]
Expand Down
40 changes: 40 additions & 0 deletions docs/user-manual/node-id.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
= Node ID
:idprefix:
:idseparator: -

When connecting multiple Artemis brokers together they can cooperate to solve a common task
like xref:clusters.adoc[clustering] or xref:ha.adoc[high availability] for example.

Implementation of coordination and control over which broker does what will vary between the different "Broker-to-broker Connectivity"
variants, but one important aspect is the use of a unique identifier called `node-id`.

By default, the brokers `node-id` will get generated the first time it starts up. The value is then
persisted into the `journal`, on a file called `server.lock`

This id _must_ be unique among all brokers to ensure proper functionality.


== Manually setting the brokers ID

In certain cases, being able to manually set a `node-id` rather than generating one can be preferable. Brokers running in
an environment where their storage is ephemeral would be one such case. This is because any time a broker is restarted, moved
or upgraded it could end up with a new disk and therefore also a new journal. Starting this broker up, while being configured
identiaclly, would still give it a new `node-id`. In some configurations, this means the broker won't be able to resume
whatever role it orinially had because the other broker it was connected to prior will look for the original `node-id`.

To handle these scenarios `node-id` can be set in the `broker.xml` configuration file.
[,xml]
----
<node-id>myUniqueID</node-id>
----

The selected nodeID will get converted internally into a 16-byte UUID. Therefore it might not be recognizeable to
someone looking for it in logs or the console.

The `node-id` has to be set before first starting the broker as this value will get persisted in the brokers `journal`.
Once persisted, this is the value that the broker will use regardless of configuration.

[WARNING]
====
If you choose to set `node-id` manually, it's uniqueness among other brokers are _UTMOST_ important.
====
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ protected ConfigurationImpl createBasicConfig() throws Exception {

protected ConfigurationImpl createBasicConfig(final int serverID) {
ConfigurationImpl configuration = new ConfigurationImpl().setSecurityEnabled(false).setJournalMinFiles(2).setJournalFileSize(100 * 1024).setJournalType(getDefaultJournalType()).setJournalDirectory(getJournalDir(serverID, false)).setBindingsDirectory(getBindingsDir(serverID, false)).setPagingDirectory(getPageDir(serverID, false)).setLargeMessagesDirectory(getLargeMessagesDir(serverID, false)).setJournalCompactMinFiles(0).setJournalCompactPercentage(0).setClusterPassword(CLUSTER_PASSWORD).setJournalDatasync(false);
configuration.setNodeID("node-" + serverID);

// When it comes to the testsuite, we don't need any batching, I will leave some minimal batching to exercise the codebase
configuration.setJournalBufferTimeout_AIO(100).setJournalBufferTimeout_NIO(100);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ protected Configuration createPrimaryConfiguration() throws Exception {
conf.addClusterConfiguration(ccconf);

conf.setSecurityEnabled(false).setJMXManagementEnabled(false).setJournalType(JournalType.MAPPED).setJournalFileSize(1024 * 512).setConnectionTTLOverride(60_000L);
conf.setNodeID("localhost::primary");

return conf;
}
Expand Down Expand Up @@ -300,6 +301,7 @@ protected Configuration createBackupConfiguration() throws Exception {
conf.addClusterConfiguration(ccconf);

conf.setSecurityEnabled(false).setJMXManagementEnabled(false).setJournalType(JournalType.MAPPED).setJournalFileSize(1024 * 512).setConnectionTTLOverride(60_000L);
conf.setNodeID("localhost::backup");

return conf;
}
Expand Down

0 comments on commit 6a36082

Please sign in to comment.