AMBARI-3770. Need better error log message when agent unable to reach server (Dmytro Shkvyra via dlysnichenko)
diff --git a/ambari-agent/src/main/python/ambari_agent/Controller.py b/ambari-agent/src/main/python/ambari_agent/Controller.py
index 7c51b5f..30f9a4d 100644
--- a/ambari-agent/src/main/python/ambari_agent/Controller.py
+++ b/ambari-agent/src/main/python/ambari_agent/Controller.py
@@ -60,6 +60,7 @@
self.netutil = NetUtil()
self.responseId = -1
self.repeatRegistration = False
+ self.isRegistered = False
self.cachedconnect = None
self.range = range
self.hasMappedComponents = True
@@ -74,21 +75,34 @@
def registerWithServer(self):
retry=False
firstTime=True
- registered=False
id = -1
ret = {}
- while not registered:
+ while not self.isRegistered:
try:
data = json.dumps(self.register.build(id))
logger.info("Registering with the server " + pprint.pformat(data))
response = self.sendRequest(self.registerUrl, data)
ret = json.loads(response)
-
+ exitstatus = 0
+ # exitstatus is a code of error which was rised on server side.
+ # exitstatus = 0 (OK - Default)
+ # exitstatus = 1 (Registration failed because
+ # different version of agent and server)
+ if 'exitstatus' in ret.keys():
+ exitstatus = int(ret['exitstatus'])
+ # log - message, which will be printed to agents log
+ if 'log' in ret.keys():
+ log = ret['log']
+ if exitstatus == 1:
+ logger.error(log)
+ self.isRegistered = False
+ self.repeatRegistration=False
+ return ret
logger.info("Registered with the server with " + pprint.pformat(ret))
print("Registered with the server")
self.responseId= int(ret['responseId'])
- registered = True
+ self.isRegistered = True
if 'statusCommands' in ret.keys():
logger.info("Got status commands on registration " + pprint.pformat(ret['statusCommands']) )
self.addToQueue(ret['statusCommands'])
@@ -98,6 +112,7 @@
pass
except ssl.SSLError:
self.repeatRegistration=False
+ self.isRegistered = False
return
except Exception, err:
# try a reconnect only after a certain amount of random time
@@ -160,6 +175,7 @@
# check if the registration command is None. If none skip
if response['registrationCommand'] is not None:
logger.info("RegistrationCommand received - repeat agent registration")
+ self.isRegistered = False
self.repeatRegistration = True
return
@@ -192,6 +208,7 @@
self.heartbeat_wait_event.clear()
except ssl.SSLError:
self.repeatRegistration=False
+ self.isRegistered = False
return
except Exception, err:
#randomize the heartbeat
@@ -239,8 +256,9 @@
registerResponse = self.registerWithServer()
message = registerResponse['response']
logger.info("Response from server = " + message)
- time.sleep(self.netutil.HEARTBEAT_IDDLE_INTERVAL_SEC)
- self.heartbeatWithServer()
+ if self.isRegistered:
+ time.sleep(self.netutil.HEARTBEAT_IDDLE_INTERVAL_SEC)
+ self.heartbeatWithServer()
def restartAgent(self):
os._exit(AGENT_AUTO_RESTART_EXIT_CODE)
diff --git a/ambari-agent/src/test/python/TestController.py b/ambari-agent/src/test/python/TestController.py
index 2b0e614..87e00fe 100644
--- a/ambari-agent/src/test/python/TestController.py
+++ b/ambari-agent/src/test/python/TestController.py
@@ -55,12 +55,11 @@
@patch("json.dumps")
- @patch("json.loads")
@patch("time.sleep")
@patch("pprint.pformat")
@patch.object(Controller, "randint")
def test_registerWithServer(self, randintMock, pformatMock, sleepMock,
- loadsMock, dumpsMock):
+ dumpsMock):
out = StringIO.StringIO()
sys.stdout = out
@@ -68,19 +67,20 @@
register = MagicMock()
self.controller.register = register
- sendRequest = MagicMock()
- self.controller.sendRequest = sendRequest
+ self.controller.sendRequest = MagicMock()
dumpsMock.return_value = "request"
- response = {"responseId":1,}
- loadsMock.return_value = response
+ self.controller.sendRequest.return_value = '{"log":"Error text", "exitstatus":"1"}'
- self.assertEqual(response, self.controller.registerWithServer())
+ self.assertEqual({u'exitstatus': u'1', u'log': u'Error text'}, self.controller.registerWithServer())
- response["statusCommands"] = "commands"
+ self.controller.sendRequest.return_value = '{"responseId":1}'
+ self.assertEqual({"responseId":1}, self.controller.registerWithServer())
+
+ self.controller.sendRequest.return_value = '{"responseId":1, "statusCommands": "commands", "log":"", "exitstatus":"0"}'
self.controller.addToQueue = MagicMock(name="addToQueue")
-
- self.assertEqual(response, self.controller.registerWithServer())
+ self.controller.isRegistered = False
+ self.assertEqual({'exitstatus': '0', 'responseId': 1, 'log': '', 'statusCommands': 'commands'}, self.controller.registerWithServer())
self.controller.addToQueue.assert_called_with("commands")
calls = []
@@ -91,10 +91,11 @@
raise Exception("test")
return "request"
- del response["statusCommands"]
+ self.controller.sendRequest.return_value = '{"responseId":1}'
dumpsMock.side_effect = side_effect
- self.assertEqual(response, self.controller.registerWithServer())
+ self.controller.isRegistered = False
+ self.assertEqual({"responseId":1}, self.controller.registerWithServer())
self.assertTrue(randintMock.called)
self.assertTrue(sleepMock.called)
@@ -189,6 +190,7 @@
Controller.Controller.__sendRequest__ = MagicMock(side_effect=Exception())
+ self.controller.isRegistered = True
self.controller.registerAndHeartbeat()
registerWithServer.assert_called_once_with()
heartbeatWithServer.assert_called_once_with()
@@ -207,6 +209,7 @@
heartbeatWithServer = MagicMock(name="heartbeatWithServer")
self.controller.heartbeatWithServer = heartbeatWithServer
+ self.controller.isRegistered = True;
self.controller.registerAndHeartbeat()
registerWithServer.assert_called_once_with()
heartbeatWithServer.assert_called_once_with()
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/RegistrationResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/RegistrationResponse.java
index 5e466aa..dae80bb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/RegistrationResponse.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/RegistrationResponse.java
@@ -30,6 +30,21 @@
public class RegistrationResponse {
@JsonProperty("response")
private RegistrationStatus response;
+
+ /**
+ * exitstatus is a code of error which was rised on server side.
+ * exitstatus = 0 (OK - Default)
+ * exitstatus = 1 (Registration failed because
+ * different version of agent and server)
+ */
+ @JsonProperty("exitstatus")
+ private int exitstatus;
+
+ /**
+ * log - message, which will be printed to agents log
+ */
+ @JsonProperty("log")
+ private String log;
//Response id to start with, usually zero.
@JsonProperty("responseId")
@@ -62,6 +77,14 @@
this.responseId = responseId;
}
+ public void setExitstatus(int exitstatus) {
+ this.exitstatus = exitstatus;
+ }
+
+ public void setLog(String log) {
+ this.log = log;
+ }
+
@Override
public String toString() {
return "RegistrationResponse{" +
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/rest/AgentResource.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/rest/AgentResource.java
index 1aac28e..9037162 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/rest/AgentResource.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/rest/AgentResource.java
@@ -38,6 +38,7 @@
import org.apache.commons.logging.LogFactory;
import com.google.inject.Inject;
+import org.apache.ambari.server.agent.RegistrationStatus;
/**
* Agent Resource represents Ambari agent controller.
@@ -75,11 +76,21 @@
@Produces({MediaType.APPLICATION_JSON})
public RegistrationResponse register(Register message,
@Context HttpServletRequest req)
- throws WebApplicationException, AmbariException, InvalidStateTransitionException {
+ throws WebApplicationException, InvalidStateTransitionException {
/* Call into the heartbeat handler */
- RegistrationResponse response = hh.handleRegistration(message);
- LOG.debug("Sending registration response " + response);
+ RegistrationResponse response = null;
+ try {
+ response = hh.handleRegistration(message);
+ LOG.debug("Sending registration response " + response);
+ } catch (AmbariException ex) {
+ response = new RegistrationResponse();
+ response.setResponseId(-1);
+ response.setResponseStatus(RegistrationStatus.FAILED);
+ response.setExitstatus(1);
+ response.setLog(ex.getMessage());
+ return response;
+ }
return response;
}