Ejemplo n.º 1
0
    def request(self, request_name, params=None, context=None, urn=None, opts={}):
        """ Send a single request to Zimbra; return the response as native python data. """
        if 'xml' in opts and opts['xml']:
            request, response = RequestXml(), ResponseXml()
        else:
            request, response = RequestJson(), ResponseJson()

        try:
            if urn == None:
                urn = urn_for_request(request_name)
            request.add_request(request_name, params or {}, "urn:"+urn)
            if context:
                request.set_context_params(context)
            request.set_auth_token(self.token)
        except:
            log.exception("failed to build request: request_name=%s, params=%s, context=%s",
                          request_name, params, context)
            return None
        if opts['debug']:
            if isinstance(request, RequestXml):
                print xml.dom.minidom.parseString(request.get_request()).toprettyxml(indent=".   ")
            else:
                pprint.pprint(yaml.load(request.get_request()))

        try:
            self.comm.send_request(request, response)
        except urllib2.HTTPError as e:
            requestbody = request.get_request()
            responsebody = e.read()
            log.error('''send_request HTTP Error %s: %s; request="%s" response="%s"''',
                          e.code, e.reason, requestbody, responsebody)
            if isinstance(request, RequestXml):
                requestdoc = xml.dom.minidom.parseString(requestbody)
                print "REQUEST=", requestdoc.toprettyxml(indent=".   ")
            else:
                print "REQUEST=\n", pprint.pformat(yaml.load(requestbody))
            if isinstance(response, ResponseXml):
                responsedoc = xml.dom.minidom.parseString(responsebody)
                print "RESPONSE=", responsedoc.toprettyxml(indent=".   ")
            else:
                print "RESPONSE=\n", pprint.pformat(yaml.load(responsebody))
            return None
        except Exception as e:
            log.exception("send_request failed (%s): request=%s", type(e), request.get_request())
            return None
        if response.is_fault():
            log.error("send_request returned fault: request=%s, response=%s",
                      request.get_request(), response.get_response())
            return None
        info = response.get_response()
        return info
Ejemplo n.º 2
0
class TestRequestXml(TestCase):
    """ Request tests
    """

    request = None
    """ The request to be tested against """
    def cleanUp(self):
        """ Clean up after one step to leave a dedicated result for the other
         test cases.
        """
        self.setUp()

    def setUp(self):
        self.request = RequestXml()

    def test_empty_request(self):
        """ Create an empty request and check the created xml
        """

        expected_result = '<?xml version="1.0" ?><soap:Envelope ' \
                          'xmlns:soap="http://www.w3' \
                          '.org/2003/05/soap-envelope"><soap:Header><context' \
                          ' xmlns="urn:zimbra"><format ' \
                          'type="xml"/></context></soap:Header><soap:Body' \
                          '/></soap:Envelope>'

        self.assertEqual(expected_result, self.request.get_request())

    def test_set_context_params_failtype(self):
        """ Add context parameters to the request and expect the method to
        send an exception
        """

        self.assertRaises(
            RequestHeaderContextException, self.request.set_context_params,
            {'invalidParam': {
                'invalidAttribute': 'invalidValue'
            }})

    def test_set_context_params(self):
        """ Add all currently accepted params and check the result
        """

        self.request.set_context_params({
            'authToken': {
                '_content': '1234567890abcdef'
            },
            'authTokenControl': {
                'voidOnExpired': '1'
            },
            'session': {
                'id': '1234567890abcdef',
                'seq': '1234567890',
                'type': 'admin'
            },
            'account': {
                'by': 'name',
                '_content': '*****@*****.**'
            },
            'change': {
                'token': '1234567890abcdef',
                'type': 'new'
            },
            'targetServer': {
                '_content': 'mailboxserver.zimbra.com'
            },
            'userAgent': {
                'name': 'Mozilla',
                'version': '1.0'
            },
            'via': {
                '_content': 'proxyserver.zimbra.com'
            }
        })

        expected_result = '<?xml version="1.0" ?><soap:Envelope ' \
                          'xmlns:soap="http://www.w3' \
                          '.org/2003/05/soap-envelope"><soap:Header><context ' \
                          'xmlns="urn:zimbra"><format ' \
                          'type="xml"/><authToken>1234567890abcdef</authToken' \
                          '><account by="name">user@zimbra' \
                          '.com</account><session id="1234567890abcdef" ' \
                          'seq="1234567890" type="admin"/><authTokenControl ' \
                          'voidOnExpired="1"/><targetServer>mailboxserver' \
                          '.zimbra.com</targetServer><via>proxyserver.zimbra' \
                          '.com</via><userAgent name="Mozilla" version="1' \
                          '.0"/><change token="1234567890abcdef" ' \
                          'type="new"/></context></soap:Header><soap:Body' \
                          '/></soap:Envelope>'

        self.assertEqual(expected_result, self.request.get_request())

        # Clean up after this test

        self.cleanUp()

    def test_enable_batch_default(self):
        """ Test enabling batch requests
        """

        # Check with default parameter

        self.request.enable_batch('urn:zimbra')

        expected_result = \
            '<?xml version="1.0" ?><soap:Envelope ' \
            'xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap' \
            ':Header><context xmlns="urn:zimbra"><format ' \
            'type="xml"/></context></soap:Header><soap:Body><BatchRequest ' \
            'onerror="urn:zimbra" ' \
            'xmlns="urn:zimbra"/></soap:Body></soap:Envelope>'

        self.assertEqual(expected_result, self.request.get_request())

        # Clean up

        self.cleanUp()

    def test_enable_batch_stop(self):
        """ Test enabling batch requests with additional parameter
        """

        self.request.enable_batch('stop')

        expected_result = '<?xml version="1.0" ?><soap:Envelope ' \
                          'xmlns:soap="http://www.w3' \
                          '.org/2003/05/soap-envelope"><soap:Header><context ' \
                          'xmlns="urn:zimbra"><format ' \
                          'type="xml"/></context></soap:Header><soap:Body' \
                          '><BatchRequest onerror="stop" ' \
                          'xmlns="urn:zimbra"/></soap:Body></soap:Envelope>'

        self.assertEqual(expected_result, self.request.get_request())

        # Clean up

        self.cleanUp()

    def test_batch_add_request(self):
        """ Test adding multiple request to a batch request
        """

        self.request.enable_batch()

        request_id = self.request.add_request('GetInfoRequest',
                                              {'sections': 'mbox,prefs'},
                                              'urn:zimbra')

        self.assertIsInstance(
            request_id,
            int,
            msg="Returned request_id for request 1 is not of type int, "
            "but of type %s" % (type(request_id)))

        self.assertEqual(
            1,
            request_id,
            msg="Returned request_id for request 1 is not 1, but %s" %
            (str(request_id)))

        expected_result = \
            '<?xml version="1.0" ?><soap:Envelope ' \
            'xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap' \
            ':Header><context xmlns="urn:zimbra"><format ' \
            'type="xml"/></context></soap:Header><soap:Body><BatchRequest ' \
            'onerror="continue" xmlns="urn:zimbra"><GetInfoRequest ' \
            'requestId="1" sections="mbox,prefs" ' \
            'xmlns="urn:zimbra"/></BatchRequest></soap:Body></soap:Envelope>'

        self.assertEqual(expected_result, self.request.get_request())

        request_id = self.request.add_request('GetInfoRequest',
                                              {'sections': 'zimlets'},
                                              'urn:zimbra')

        self.assertIsInstance(
            request_id,
            int,
            msg="Returned request_id for request 2 is not of type int, "
            "but of type %s" % (type(request_id)))

        self.assertEqual(
            2,
            request_id,
            msg="Returned request_id for request 2 is not 2, but %s" %
            (str(request_id)))

        expected_result = \
            '<?xml version="1.0" ?><soap:Envelope ' \
            'xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap' \
            ':Header><context xmlns="urn:zimbra"><format ' \
            'type="xml"/></context></soap:Header><soap:Body><BatchRequest ' \
            'onerror="continue" xmlns="urn:zimbra"><GetInfoRequest ' \
            'requestId="1" sections="mbox,prefs" ' \
            'xmlns="urn:zimbra"/><GetInfoRequest requestId="2" ' \
            'sections="zimlets" ' \
            'xmlns="urn:zimbra"/></BatchRequest></soap:Body></soap:Envelope>'

        self.assertEqual(expected_result, self.request.get_request())

        # Clean up

        self.setUp()

    def test_add_request(self):
        """ Test adding a request
        """

        request_id = self.request.add_request('GetInfoRequest',
                                              {'sections': 'mbox,prefs'},
                                              'urn:zimbra')

        self.assertIsNone(request_id,
                          msg="Returned request_id for request 1 is not none, "
                          "but %s" % (str(request_id)))

        expected_result = '<?xml version="1.0" ?><soap:Envelope ' \
                          'xmlns:soap="http://www.w3' \
                          '.org/2003/05/soap-envelope"><soap:Header><context ' \
                          'xmlns="urn:zimbra"><format ' \
                          'type="xml"/></context></soap:Header><soap:Body' \
                          '><GetInfoRequest sections="mbox,' \
                          'prefs" ' \
                          'xmlns="urn:zimbra"/></soap:Body></soap:Envelope>'

        self.assertEqual(expected_result, self.request.get_request())

        # Clean up

        self.setUp()

    def tearDown(self):
        self.request = None
class TestRequestXml(TestCase):
    """ Request tests
    """

    request = None

    """ The request to be tested against """

    def cleanUp(self):
        """ Clean up after one step to leave a dedicated result for the other
         test cases.
        """
        self.setUp()

    def setUp(self):
        self.request = RequestXml()

    def tool_assert_equal_xml(self, xml_a, xml_b, message=None):

        self.assertEqual(
            dom_to_dict(minidom.parseString(xml_a).firstChild),
            dom_to_dict(minidom.parseString(xml_b).firstChild),
            message
        )

    def test_empty_request(self):
        """ Create an empty request and check the created xml
        """

        expected_result = '<?xml version="1.0" ?><soap:Envelope ' \
                          'xmlns:soap="http://www.w3' \
                          '.org/2003/05/soap-envelope"><soap:Header><context' \
                          ' xmlns="urn:zimbra"><format ' \
                          'type="xml"/></context></soap:Header><soap:Body' \
                          '/></soap:Envelope>'

        self.tool_assert_equal_xml(
            expected_result,
            self.request.get_request()
        )

    def test_set_context_params_failtype(self):
        """ Add context parameters to the request and expect the method to
        send an exception
        """

        self.assertRaises(
            RequestHeaderContextException,
            self.request.set_context_params,
            {
                'invalidParam': {
                    'invalidAttribute': 'invalidValue'
                }
            }
        )

    def test_set_context_params(self):
        """ Add all currently accepted params and check the result
        """

        self.request.set_context_params(
            {
                'authToken': {
                    '_content': '1234567890abcdef'
                },
                'authTokenControl': {
                    'voidOnExpired': '1'
                },
                'session': {
                    'id': '1234567890abcdef',
                    'seq': '1234567890',
                    'type': 'admin'
                },
                'account': {
                    'by': 'name',
                    '_content': '*****@*****.**'
                },
                'change': {
                    'token': '1234567890abcdef',
                    'type': 'new'
                },
                'targetServer': {
                    '_content': 'mailboxserver.zimbra.com'
                },
                'userAgent': {
                    'name': 'Mozilla',
                    'version': '1.0'
                },
                'via': {
                    '_content': 'proxyserver.zimbra.com'
                }
            }
        )

        expected_result = '<?xml version="1.0" ?><soap:Envelope ' \
                          'xmlns:soap="http://www.w3' \
                          '.org/2003/05/soap-envelope"><soap:Header><context ' \
                          'xmlns="urn:zimbra"><format ' \
                          'type="xml"/><authToken>1234567890abcdef</authToken' \
                          '><account by="name">user@zimbra' \
                          '.com</account><session id="1234567890abcdef" ' \
                          'seq="1234567890" type="admin"/><authTokenControl ' \
                          'voidOnExpired="1"/><targetServer>mailboxserver' \
                          '.zimbra.com</targetServer><via>proxyserver.zimbra' \
                          '.com</via><userAgent name="Mozilla" version="1' \
                          '.0"/><change token="1234567890abcdef" ' \
                          'type="new"/></context></soap:Header><soap:Body' \
                          '/></soap:Envelope>'

        self.tool_assert_equal_xml(
            expected_result,
            self.request.get_request()
        )

        # Clean up after this test

        self.cleanUp()

    def test_enable_batch_default(self):

        """ Test enabling batch requests
        """

        # Check with default parameter

        self.request.enable_batch('urn:zimbra')

        expected_result = \
            '<?xml version="1.0" ?><soap:Envelope ' \
            'xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap' \
            ':Header><context xmlns="urn:zimbra"><format ' \
            'type="xml"/></context></soap:Header><soap:Body><BatchRequest ' \
            'onerror="urn:zimbra" ' \
            'xmlns="urn:zimbra"/></soap:Body></soap:Envelope>'

        self.tool_assert_equal_xml(
            expected_result,
            self.request.get_request()
        )

        # Clean up

        self.cleanUp()

    def test_enable_batch_stop(self):

        """ Test enabling batch requests with additional parameter
        """

        self.request.enable_batch('stop')

        expected_result = '<?xml version="1.0" ?><soap:Envelope ' \
                          'xmlns:soap="http://www.w3' \
                          '.org/2003/05/soap-envelope"><soap:Header><context ' \
                          'xmlns="urn:zimbra"><format ' \
                          'type="xml"/></context></soap:Header><soap:Body' \
                          '><BatchRequest onerror="stop" ' \
                          'xmlns="urn:zimbra"/></soap:Body></soap:Envelope>'

        self.tool_assert_equal_xml(
            expected_result,
            self.request.get_request()
        )

        # Clean up

        self.cleanUp()

    def test_batch_add_request(self):

        """ Test adding multiple request to a batch request
        """

        self.request.enable_batch()

        request_id = self.request.add_request(
            'GetInfoRequest',
            {
                'sections': 'mbox,prefs'
            },
            'urn:zimbra'
        )

        self.assertIsInstance(
            request_id,
            int,
            msg="Returned request_id for request 1 is not of type int, "
                "but of type %s" % (
                    type(request_id)
                )
        )

        self.assertEqual(
            1,
            request_id,
            msg="Returned request_id for request 1 is not 1, but %s" % (
                str(request_id)
            )
        )

        expected_result = \
            '<?xml version="1.0" ?><soap:Envelope ' \
            'xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap' \
            ':Header><context xmlns="urn:zimbra"><format ' \
            'type="xml"/></context></soap:Header><soap:Body><BatchRequest ' \
            'onerror="continue" xmlns="urn:zimbra"><GetInfoRequest ' \
            'requestId="1" sections="mbox,prefs" ' \
            'xmlns="urn:zimbra"/></BatchRequest></soap:Body></soap:Envelope>'

        self.tool_assert_equal_xml(
            expected_result,
            self.request.get_request()
        )

        request_id = self.request.add_request(
            'GetInfoRequest',
            {
                'sections': 'zimlets'
            },
            'urn:zimbra'
        )

        self.assertIsInstance(
            request_id,
            int,
            msg="Returned request_id for request 2 is not of type int, "
                "but of type %s" % (
                    type(request_id)
                )
        )

        self.assertEqual(
            2,
            request_id,
            msg="Returned request_id for request 2 is not 2, but %s" % (
                str(request_id)
            )
        )

        expected_result = \
            '<?xml version="1.0" ?><soap:Envelope ' \
            'xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap' \
            ':Header><context xmlns="urn:zimbra"><format ' \
            'type="xml"/></context></soap:Header><soap:Body><BatchRequest ' \
            'onerror="continue" xmlns="urn:zimbra"><GetInfoRequest ' \
            'requestId="1" sections="mbox,prefs" ' \
            'xmlns="urn:zimbra"/><GetInfoRequest requestId="2" ' \
            'sections="zimlets" ' \
            'xmlns="urn:zimbra"/></BatchRequest></soap:Body></soap:Envelope>'

        self.tool_assert_equal_xml(
            expected_result,
            self.request.get_request()
        )

        # Clean up

        self.setUp()

    def test_add_request(self):

        """ Test adding a request
        """

        request_id = self.request.add_request(
            'GetInfoRequest',
            {
                'sections': 'mbox,prefs'
            },
            'urn:zimbra'
        )

        self.assertIsNone(
            request_id,
            msg="Returned request_id for request 1 is not none, "
                "but %s" % (
                    str(request_id)
                )
        )

        expected_result = '<?xml version="1.0" ?><soap:Envelope ' \
                          'xmlns:soap="http://www.w3' \
                          '.org/2003/05/soap-envelope"><soap:Header><context ' \
                          'xmlns="urn:zimbra"><format ' \
                          'type="xml"/></context></soap:Header><soap:Body' \
                          '><GetInfoRequest sections="mbox,' \
                          'prefs" ' \
                          'xmlns="urn:zimbra"/></soap:Body></soap:Envelope>'

        self.tool_assert_equal_xml(
            expected_result,
            self.request.get_request()
        )

        # Clean up

        self.setUp()

    def tearDown(self):
        self.request = None