Updated Branches: refs/heads/trunk c7503231e -> 7948bc4b4
AMBARI-3770. Need better error log message when agent unable to reach server (Dmytro Shkvyra via dlysnichenko) Project: http://git-wip-us.apache.org/repos/asf/incubator-ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ambari/commit/7948bc4b Tree: http://git-wip-us.apache.org/repos/asf/incubator-ambari/tree/7948bc4b Diff: http://git-wip-us.apache.org/repos/asf/incubator-ambari/diff/7948bc4b Branch: refs/heads/trunk Commit: 7948bc4b42fc6b786849dd62b202cd886458af2a Parents: c750323 Author: Lisnichenko Dmitro <dlysniche...@hortonworks.com> Authored: Tue Nov 19 17:34:14 2013 +0200 Committer: Lisnichenko Dmitro <dlysniche...@hortonworks.com> Committed: Tue Nov 19 17:34:14 2013 +0200 ---------------------------------------------------------------------- .../src/main/python/ambari_agent/Controller.py | 30 ++++++++++++++++---- ambari-agent/src/test/python/TestController.py | 27 ++++++++++-------- .../server/agent/RegistrationResponse.java | 23 +++++++++++++++ .../ambari/server/agent/rest/AgentResource.java | 17 +++++++++-- 4 files changed, 76 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/7948bc4b/ambari-agent/src/main/python/ambari_agent/Controller.py ---------------------------------------------------------------------- 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 @@ class Controller(threading.Thread): 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 @@ class Controller(threading.Thread): 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 @@ class Controller(threading.Thread): 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 @@ class Controller(threading.Thread): # 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 @@ class Controller(threading.Thread): 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 @@ class Controller(threading.Thread): 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) http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/7948bc4b/ambari-agent/src/test/python/TestController.py ---------------------------------------------------------------------- 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 @@ class TestController(unittest.TestCase): @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 @@ class TestController(unittest.TestCase): 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.addToQueue = MagicMock(name="addToQueue") + self.controller.sendRequest.return_value = '{"responseId":1}' + self.assertEqual({"responseId":1}, self.controller.registerWithServer()) - self.assertEqual(response, self.controller.registerWithServer()) + self.controller.sendRequest.return_value = '{"responseId":1, "statusCommands": "commands", "log":"", "exitstatus":"0"}' + self.controller.addToQueue = MagicMock(name="addToQueue") + 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 @@ class TestController(unittest.TestCase): 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 @@ class TestController(unittest.TestCase): 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 @@ class TestController(unittest.TestCase): 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() http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/7948bc4b/ambari-server/src/main/java/org/apache/ambari/server/agent/RegistrationResponse.java ---------------------------------------------------------------------- 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 @@ import org.codehaus.jackson.annotate.JsonProperty; 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 @@ public class RegistrationResponse { 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{" + http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/7948bc4b/ambari-server/src/main/java/org/apache/ambari/server/agent/rest/AgentResource.java ---------------------------------------------------------------------- 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.Log; 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 @@ public class AgentResource { @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; }