Fix Broken XML Namespace Handling
nodeName is set to ns2:metadata and not just metadata when namespaces are specified using first example in the defect. Explicitly check namespaces where necessary and use localName instead of nodeName. Ensure that scheduler_hints are picked up from the correct namespace fix lines too long from pep8 Fixes bug 887191 Change-Id: I5db2b575d24f6b1b358489e309af7e6ace2950fd
This commit is contained in:
		
				
					committed by
					
						
						Gerrit Code Review
					
				
			
			
				
	
			
			
			
						parent
						
							f1e5fbf92a
						
					
				
				
					commit
					10caf4b48f
				
			@@ -241,13 +241,9 @@ class CommonDeserializer(wsgi.MetadataXMLDeserializer):
 | 
			
		||||
 | 
			
		||||
    def _extract_scheduler_hints(self, server_node):
 | 
			
		||||
        """Marshal the scheduler hints attribute of a parsed request"""
 | 
			
		||||
        node = self.find_first_child_named(server_node,
 | 
			
		||||
                                           "OS-SCH-HNT:scheduler_hints")
 | 
			
		||||
        # NOTE(vish): Support the os: prefix because it is what we use
 | 
			
		||||
        #             for json, even though OS-SCH-HNT: is more correct
 | 
			
		||||
        if not node:
 | 
			
		||||
            node = self.find_first_child_named(server_node,
 | 
			
		||||
                                               "os:scheduler_hints")
 | 
			
		||||
        node = self.find_first_child_named_in_namespace(server_node,
 | 
			
		||||
            "http://docs.openstack.org/compute/ext/scheduler-hints/api/v2",
 | 
			
		||||
            "scheduler_hints")
 | 
			
		||||
        if node:
 | 
			
		||||
            scheduler_hints = {}
 | 
			
		||||
            for child in self.extract_elements(node):
 | 
			
		||||
 
 | 
			
		||||
@@ -244,17 +244,26 @@ class XMLDeserializer(TextDeserializer):
 | 
			
		||||
                                                                 listnames)
 | 
			
		||||
            return result
 | 
			
		||||
 | 
			
		||||
    def find_first_child_named_in_namespace(self, parent, namespace, name):
 | 
			
		||||
        """Search a nodes children for the first child with a given name"""
 | 
			
		||||
        for node in parent.childNodes:
 | 
			
		||||
            if (node.localName == name and
 | 
			
		||||
                node.namespaceURI and
 | 
			
		||||
                node.namespaceURI == namespace):
 | 
			
		||||
                return node
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def find_first_child_named(self, parent, name):
 | 
			
		||||
        """Search a nodes children for the first child with a given name"""
 | 
			
		||||
        for node in parent.childNodes:
 | 
			
		||||
            if node.nodeName == name:
 | 
			
		||||
            if node.localName == name:
 | 
			
		||||
                return node
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def find_children_named(self, parent, name):
 | 
			
		||||
        """Return all of a nodes children who have the given name"""
 | 
			
		||||
        for node in parent.childNodes:
 | 
			
		||||
            if node.nodeName == name:
 | 
			
		||||
            if node.localName == name:
 | 
			
		||||
                yield node
 | 
			
		||||
 | 
			
		||||
    def extract_text(self, node):
 | 
			
		||||
 
 | 
			
		||||
@@ -3030,6 +3030,57 @@ class TestServerCreateRequestXMLDeserializer(test.TestCase):
 | 
			
		||||
        }
 | 
			
		||||
        self.assertEquals(request['body'], expected)
 | 
			
		||||
 | 
			
		||||
    def test_request_with_alternate_namespace_prefix(self):
 | 
			
		||||
        serial_request = """
 | 
			
		||||
<ns2:server xmlns:ns2="http://docs.openstack.org/compute/api/v2"
 | 
			
		||||
        name="new-server-test"
 | 
			
		||||
        imageRef="1"
 | 
			
		||||
        flavorRef="2">
 | 
			
		||||
        <ns2:metadata><ns2:meta key="hello">world</ns2:meta></ns2:metadata>
 | 
			
		||||
        </ns2:server>
 | 
			
		||||
        """
 | 
			
		||||
        request = self.deserializer.deserialize(serial_request)
 | 
			
		||||
        expected = {
 | 
			
		||||
            "server": {
 | 
			
		||||
                "name": "new-server-test",
 | 
			
		||||
                "imageRef": "1",
 | 
			
		||||
                "flavorRef": "2",
 | 
			
		||||
                'metadata': {"hello": "world"},
 | 
			
		||||
                },
 | 
			
		||||
            }
 | 
			
		||||
        self.assertEquals(request['body'], expected)
 | 
			
		||||
 | 
			
		||||
    def test_request_with_scheduler_hints_and_alternate_namespace_prefix(self):
 | 
			
		||||
        serial_request = """
 | 
			
		||||
<ns2:server xmlns:ns2="http://docs.openstack.org/compute/api/v2"
 | 
			
		||||
     name="new-server-test"
 | 
			
		||||
     imageRef="1"
 | 
			
		||||
     flavorRef="2">
 | 
			
		||||
     <ns2:metadata><ns2:meta key="hello">world</ns2:meta></ns2:metadata>
 | 
			
		||||
     <os:scheduler_hints
 | 
			
		||||
     xmlns:os="http://docs.openstack.org/compute/ext/scheduler-hints/api/v2">
 | 
			
		||||
             <hypervisor>xen</hypervisor>
 | 
			
		||||
             <near>eb999657-dd6b-464e-8713-95c532ac3b18</near>
 | 
			
		||||
     </os:scheduler_hints>
 | 
			
		||||
     </ns2:server>
 | 
			
		||||
        """
 | 
			
		||||
        request = self.deserializer.deserialize(serial_request)
 | 
			
		||||
        expected = {
 | 
			
		||||
            "server": {
 | 
			
		||||
                'OS-SCH-HNT:scheduler_hints': {
 | 
			
		||||
                    'hypervisor': ['xen'],
 | 
			
		||||
                    'near': ['eb999657-dd6b-464e-8713-95c532ac3b18']
 | 
			
		||||
                },
 | 
			
		||||
                "name": "new-server-test",
 | 
			
		||||
                "imageRef": "1",
 | 
			
		||||
                "flavorRef": "2",
 | 
			
		||||
                "metadata": {
 | 
			
		||||
                    "hello": "world"
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        self.assertEquals(request['body'], expected)
 | 
			
		||||
 | 
			
		||||
    def test_access_ipv4(self):
 | 
			
		||||
        serial_request = """
 | 
			
		||||
<server xmlns="http://docs.openstack.org/compute/api/v2"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user