Skip to content

Commit a4d05c2

Browse files
mprokopchukPearl1594
authored andcommitted
Store last successful MS host for agent reconnection fallback
* Store last successful MS host for agent reconnection fallback * Add newline at end of CapacityManagerImplTest.java
1 parent 6136ac9 commit a4d05c2

5 files changed

Lines changed: 67 additions & 6 deletions

File tree

‎agent/src/main/java/com/cloud/agent/Agent.java‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public int value() {
131131
CopyOnWriteArrayList<IAgentControlListener> controlListeners = new CopyOnWriteArrayList<>();
132132

133133
IAgentShell shell;
134-
NioConnection connection;
134+
NioClient connection;
135135
ServerResource serverResource;
136136
Link link;
137137
Long id;
@@ -919,6 +919,20 @@ private void processManagementServerList(final List<String> msList, final String
919919
}
920920
}
921921

922+
/**
923+
* Saves the currently connected management server host after successful setup completion.
924+
* This host is persisted and later added to the reconnection list as a fallback option.
925+
* Called after receiving a Ready command from the management server, indicating that
926+
* the agent has successfully completed its initialization and is ready to work.
927+
*
928+
* @param connectedHost the hostname or IP address of the successfully connected management server
929+
*/
930+
private void updateLastSetupCompletedHost(String connectedHost) {
931+
if (StringUtils.isNotBlank(connectedHost)) {
932+
shell.setLastSetupCompletedHost(connectedHost);
933+
}
934+
}
935+
922936
private Answer setupManagementServerList(final SetupMSListCommand cmd) {
923937
processManagementServerList(cmd.getMsList(), cmd.getLbAlgorithm(), cmd.getLbCheckInterval());
924938
return new SetupMSListAnswer(true);
@@ -959,6 +973,8 @@ public void processReadyCommand(final Command cmd) {
959973

960974
verifyAgentArch(ready.getArch());
961975
processManagementServerList(ready.getMsHostList(), ready.getLbAlgorithm(), ready.getLbCheckInterval());
976+
String connectedHost = shell.getConnectedHost();
977+
updateLastSetupCompletedHost(connectedHost);
962978

963979
logger.info("Ready command is processed for agent [id: {}, uuid: {}, name: {}]", getId(), getUuid(), getName());
964980
}

‎agent/src/main/java/com/cloud/agent/AgentShell.java‎

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,20 @@ public void resetHostCounter() {
154154

155155
@Override
156156
public String[] getHosts() {
157-
return _host.split(",");
157+
String lastSetupCompletedHost = getLastSetupCompletedHost();
158+
String host;
159+
// Add the last successful setup host as a fallback option at the end of the host list.
160+
// This host is tried only after all configured hosts have failed, providing a
161+
// last-resort connection option since this host previously completed setup successfully.
162+
if (StringUtils.isNotBlank(lastSetupCompletedHost)
163+
&& StringUtils.isNotBlank(_host)
164+
&& !_host.contains(lastSetupCompletedHost)) {
165+
host = _host + "," + lastSetupCompletedHost;
166+
} else {
167+
host = _host;
168+
}
169+
170+
return host.split(",");
158171
}
159172

160173
@Override
@@ -464,6 +477,21 @@ public Integer getSslHandshakeTimeout() {
464477
return AgentPropertiesFileHandler.getPropertyValue(AgentProperties.SSL_HANDSHAKE_TIMEOUT);
465478
}
466479

480+
@Override
481+
public void setLastSetupCompletedHost(String host) {
482+
setPersistentProperty(null, AgentProperties.LAST_SETUP_COMPLETED_HOST.getName(), host);
483+
}
484+
485+
/**
486+
* Gets the last host where the agent successfully completed its setup process
487+
* and received a Ready command.
488+
*
489+
* @return the hostname or IP address of the last successfully setup host, or null if none exists
490+
*/
491+
private String getLastSetupCompletedHost() {
492+
return AgentPropertiesFileHandler.getPropertyValue(AgentProperties.LAST_SETUP_COMPLETED_HOST);
493+
}
494+
467495
public synchronized int getNextAgentId() {
468496
return _nextAgentId++;
469497
}

‎agent/src/main/java/com/cloud/agent/IAgentShell.java‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,13 @@ public interface IAgentShell {
7272
void launchNewAgent(ServerResource resource) throws ConfigurationException;
7373

7474
Integer getSslHandshakeTimeout();
75+
76+
/**
77+
* Sets the last host where the agent successfully completed its setup process
78+
* and received a Ready command. This value is persisted across agent restarts
79+
* and used to prioritize reconnection attempts to previously working hosts.
80+
*
81+
* @param host the hostname or IP address where the agent setup completed successfully
82+
*/
83+
void setLastSetupCompletedHost(String host);
7584
}

‎agent/src/main/java/com/cloud/agent/properties/AgentProperties.java‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ public class AgentProperties{
5757
*/
5858
public static final Property<String> HOST = new Property<>("host", "localhost");
5959

60+
/**
61+
* The name of the last host where the agent successfully completed its setup process
62+
* and received a Ready command
63+
* Data type: String.<br>
64+
* Default value: <code>null</code>
65+
*/
66+
public static final Property<String> LAST_SETUP_COMPLETED_HOST = new Property<>("last.setup.completed.host", null, String.class);
67+
6068
/**
6169
* The time interval (in seconds) after which the agent will check if the connected host is the preferred host.<br>
6270
* After that interval, if the agent is connected to one of the secondary/backup hosts, it will attempt to reconnect to the preferred host.<br>

‎agent/src/test/java/com/cloud/agent/AgentTest.java‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import javax.naming.ConfigurationException;
3737

3838
import org.apache.logging.log4j.Logger;
39+
import com.cloud.utils.nio.NioClient;
3940
import org.junit.Before;
4041
import org.junit.Test;
4142
import org.junit.runner.RunWith;
@@ -45,7 +46,6 @@
4546
import com.cloud.resource.ServerResource;
4647
import com.cloud.utils.backoff.impl.ConstantTimeBackoff;
4748
import com.cloud.utils.nio.Link;
48-
import com.cloud.utils.nio.NioConnection;
4949

5050
@RunWith(MockitoJUnitRunner.class)
5151
public class AgentTest {
@@ -224,7 +224,7 @@ public void testStopAndCleanupConnectionConnectionIsNullDoesNothing() {
224224

225225
@Test
226226
public void testStopAndCleanupConnectionValidConnectionNoWaitStopsAndCleansUp() throws IOException {
227-
NioConnection mockConnection = mock(NioConnection.class);
227+
NioClient mockConnection = mock(NioClient.class);
228228
agent.connection = mockConnection;
229229
agent.stopAndCleanupConnection(false);
230230
verify(mockConnection).stop();
@@ -233,7 +233,7 @@ public void testStopAndCleanupConnectionValidConnectionNoWaitStopsAndCleansUp()
233233

234234
@Test
235235
public void testStopAndCleanupConnectionCleanupThrowsIOExceptionLogsWarning() throws IOException {
236-
NioConnection mockConnection = mock(NioConnection.class);
236+
NioClient mockConnection = mock(NioClient.class);
237237
agent.connection = mockConnection;
238238
doThrow(new IOException("Cleanup failed")).when(mockConnection).cleanUp();
239239
agent.stopAndCleanupConnection(false);
@@ -243,7 +243,7 @@ public void testStopAndCleanupConnectionCleanupThrowsIOExceptionLogsWarning() th
243243

244244
@Test
245245
public void testStopAndCleanupConnectionValidConnectionWaitForStopWaitsForStartupToStop() throws IOException {
246-
NioConnection mockConnection = mock(NioConnection.class);
246+
NioClient mockConnection = mock(NioClient.class);
247247
ConstantTimeBackoff mockBackoff = mock(ConstantTimeBackoff.class);
248248
mockBackoff.setTimeToWait(0);
249249
agent.connection = mockConnection;

0 commit comments

Comments
 (0)