Ejemplo n.º 1
0
    def build_schema(self, types=None):
        schema_nodes = Application.build_schema(self, types)

        if types is None:
            pref_tns = soaplib.get_namespace_prefix(self.get_tns())
            logger.debug("generating schema for targetNamespace=%r, prefix: %r"
                                                   % (self.get_tns(), pref_tns))

            tmp_dir_name = tempfile.mkdtemp()

            # serialize nodes to files
            for k,v in schema_nodes.items():
                file_name = '%s/%s.xsd' % (tmp_dir_name, k)
                f = open(file_name, 'w')
                etree.ElementTree(v).write(f, pretty_print=True)
                f.close()
                logger.debug("writing %r for ns %s" % (file_name,
                                                            soaplib.nsmap[k]))

            f = open('%s/%s.xsd' % (tmp_dir_name, pref_tns), 'r')

            logger.debug("building schema...")
            self.schema = etree.XMLSchema(etree.parse(f))

            logger.debug("schema %r built, cleaning up..." % self.schema)
            f.close()
            shutil.rmtree(tmp_dir_name)
            logger.debug("removed %r" % tmp_dir_name)

        return self.schema
Ejemplo n.º 2
0
    def build_schema(self, types=None):
        """
        Build application schema specifically for xml validation purposes.
        """
        schema_nodes = Application.build_schema(self, types)

        if types is None:
            pref_tns = soaplib.get_namespace_prefix(self.get_tns())
            logger.debug("generating schema for targetNamespace=%r, prefix: %r"
                                                   % (self.get_tns(), pref_tns))

            tmp_dir_name = tempfile.mkdtemp()

            # serialize nodes to files
            for k,v in schema_nodes.items():
                file_name = '%s/%s.xsd' % (tmp_dir_name, k)
                f = open(file_name, 'w')
                etree.ElementTree(v).write(f, pretty_print=True)
                f.close()
                logger.debug("writing %r for ns %s" % (file_name,
                                                            soaplib.nsmap[k]))

            f = open('%s/%s.xsd' % (tmp_dir_name, pref_tns), 'r')

            logger.debug("building schema...")
            self.schema = etree.XMLSchema(etree.parse(f))

            logger.debug("schema %r built, cleaning up..." % self.schema)
            f.close()
            shutil.rmtree(tmp_dir_name)
            logger.debug("removed %r" % tmp_dir_name)

        return self.schema
Ejemplo n.º 3
0
    def __build_schema_nodes(self, schema_entries, types=None):
        """
        Fill individual <schema> nodes for every service that are part of this
        app.
        """

        schema_nodes = {}

        for pref in schema_entries.namespaces:
            schema = get_schema_node(pref, schema_nodes, types)

            # append import tags
            for namespace in schema_entries.imports[pref]:
                import_ = etree.SubElement(schema, "{%s}import"% soaplib.ns_xsd)
                import_.set("namespace", namespace)
                if types is None:
                    import_.set('schemaLocation', "%s.xsd" %
                                        soaplib.get_namespace_prefix(namespace))

            # append element tags
            for node in schema_entries.namespaces[pref].elements.values():
                schema.append(node)

            # append simpleType and complexType tags
            for node in schema_entries.namespaces[pref].types.values():
                schema.append(node)

        return schema_nodes
Ejemplo n.º 4
0
    def __add_callbacks(self, root, types, service_name, url):
        ns_xsd = soaplib.ns_xsd
        ns_wsa = soaplib.ns_wsa
        ns_wsdl = soaplib.ns_wsdl
        ns_soap = soaplib.ns_soap

        ns_tns = self.get_tns()
        pref_tns = soaplib.get_namespace_prefix(ns_tns)

        cb_port_type = None

        # add necessary async headers
        # WS-Addressing -> RelatesTo ReplyTo MessageID
        # callback porttype
        if self._has_callbacks():
            wsa_schema = etree.SubElement(types, "{%s}schema" % ns_xsd)
            wsa_schema.set("targetNamespace", '%sCallback'  % ns_tns)
            wsa_schema.set("elementFormDefault", "qualified")

            import_ = etree.SubElement(wsa_schema, "{%s}import" % ns_xsd)
            import_.set("namespace", ns_wsa)
            import_.set("schemaLocation", ns_wsa)

            relt_message = etree.SubElement(root, '{%s}message' % ns_wsdl)
            relt_message.set('name', 'RelatesToHeader')
            relt_part = etree.SubElement(relt_message, '{%s}part' % ns_wsdl)
            relt_part.set('name', 'RelatesTo')
            relt_part.set('element', '%s:RelatesTo' % _pref_wsa)

            reply_message = etree.SubElement(root, '{%s}message' % ns_wsdl)
            reply_message.set('name', 'ReplyToHeader')
            reply_part = etree.SubElement(reply_message, '{%s}part' % ns_wsdl)
            reply_part.set('name', 'ReplyTo')
            reply_part.set('element', '%s:ReplyTo' % _pref_wsa)

            id_header = etree.SubElement(root, '{%s}message' % ns_wsdl)
            id_header.set('name', 'MessageIDHeader')
            id_part = etree.SubElement(id_header, '{%s}part' % ns_wsdl)
            id_part.set('name', 'MessageID')
            id_part.set('element', '%s:MessageID' % _pref_wsa)

            # make portTypes
            cb_port_type = etree.SubElement(root, '{%s}portType' % ns_wsdl)
            cb_port_type.set('name', '%sCallback' % service_name)

            cb_service_name = '%sCallback' % service_name

            cb_service = etree.SubElement(root, '{%s}service' % ns_wsdl)
            cb_service.set('name', cb_service_name)

            cb_wsdl_port = etree.SubElement(cb_service, '{%s}port' % ns_wsdl)
            cb_wsdl_port.set('name', cb_service_name)
            cb_wsdl_port.set('binding', '%s:%s' % (pref_tns, cb_service_name))

            cb_address = etree.SubElement(cb_wsdl_port, '{%s}address'
                                                              % ns_soap)
            cb_address.set('location', url)

        return cb_port_type
Ejemplo n.º 5
0
    def add_service(self, root, service_name, types, url, service):
        ns_wsdl = soaplib.ns_wsdl
        ns_soap = soaplib.ns_soap
        ns_tns = self.get_tns()
        pref_tns = soaplib.get_namespace_prefix(ns_tns)

        wsdl_port = etree.SubElement(service, '{%s}port' % ns_wsdl)
        wsdl_port.set('name', service_name)
        wsdl_port.set('binding', '%s:%s' % (pref_tns, service_name))

        addr = etree.SubElement(wsdl_port, '{%s}address' % ns_soap)
        addr.set('location', url)
Ejemplo n.º 6
0
    def add_service(self, root, service_name, types, url, service):
        """
        Add service node to the wsdl.
        """
        pref_tns = soaplib.get_namespace_prefix(self.get_tns())

        wsdl_port = etree.SubElement(service, '{%s}port' % soaplib.ns_wsdl)
        wsdl_port.set('name', service_name)
        wsdl_port.set('binding', '%s:%s' % (pref_tns, service_name))

        addr = etree.SubElement(wsdl_port, '{%s}address' % soaplib.ns_soap)
        addr.set('location', url)
Ejemplo n.º 7
0
    def add_partner_link(self, root, service_name, types, url, plink):
        """
        Add the partnerLinkType node to the wsdl.
        """
        ns_plink = soaplib.ns_plink
        pref_tns = soaplib.get_namespace_prefix(self.get_tns())

        role = etree.SubElement(plink, '{%s}role' % ns_plink)
        role.set('name', service_name)

        plink_port_type = etree.SubElement(role, '{%s}portType' % ns_plink)
        plink_port_type.set('name', '%s:%s' % (pref_tns, service_name))
Ejemplo n.º 8
0
        def add_to_schema(cls, schema_entries):
            if not schema_entries.has_class(cls):
                simple_type = etree.Element('{%s}simpleType' % _ns_xs)
                simple_type.set('name', cls.get_type_name())

                restriction = etree.SubElement(simple_type,
                                                    '{%s}restriction' % _ns_xs)
                restriction.set('base', '%s:string' %
                                   soaplib.get_namespace_prefix(soaplib.ns_xsd))

                for v in values:
                    enumeration = etree.SubElement(restriction,
                                                    '{%s}enumeration' % _ns_xs)
                    enumeration.set('value', v)

                schema_entries.add_simple_type(cls, simple_type)
Ejemplo n.º 9
0
        def add_to_schema(cls, schema_entries):
            if not schema_entries.has_class(cls):
                simple_type = etree.Element('{%s}simpleType' % _ns_xs)
                simple_type.set('name', cls.get_type_name())

                restriction = etree.SubElement(simple_type,
                                                    '{%s}restriction' % _ns_xs)
                restriction.set('base', '%s:string' %
                                   soaplib.get_namespace_prefix(soaplib.ns_xsd))

                for v in values:
                    enumeration = etree.SubElement(restriction,
                                                    '{%s}enumeration' % _ns_xs)
                    enumeration.set('value', v)

                schema_entries.add_simple_type(cls, simple_type)
Ejemplo n.º 10
0
    def add_partner_link(self, root, service_name, types, url, plink):
        ns_plink = soaplib.ns_plink
        ns_tns = self.get_tns()
        pref_tns = soaplib.get_namespace_prefix(ns_tns)

        role = etree.SubElement(plink, '{%s}role' % ns_plink)
        role.set('name', service_name)

        plink_port_type = etree.SubElement(role, '{%s}portType' % ns_plink)
        plink_port_type.set('name', '%s:%s' % (pref_tns, service_name))

        if self._has_callbacks():
            role = etree.SubElement(plink, '{%s}role' % ns_plink)
            role.set('name', '%sCallback' % service_name)

            plink_port_type = etree.SubElement(role, '{%s}portType' % ns_plink)
            plink_port_type.set('name', '%s:%sCallback' %
                                                       (pref_tns, service_name))
Ejemplo n.º 11
0
    def get_namespace_prefix(cls):
        ns = cls.get_namespace()

        retval = soaplib.get_namespace_prefix(ns)

        return retval
Ejemplo n.º 12
0
    def get_namespace_prefix(cls):
        ns = cls.get_namespace()

        retval = soaplib.get_namespace_prefix(ns)

        return retval
Ejemplo n.º 13
0
    def __build_wsdl(self, url):
        ns_wsdl = soaplib.ns_wsdl
        ns_soap = soaplib.ns_soap
        ns_plink = soaplib.ns_plink

        ns_tns = self.get_tns()
        pref_tns = soaplib.get_namespace_prefix(ns_tns) #'tns'
        # FIXME: this can be enabled when soaplib.nsmap is no longer global
        #soaplib.set_namespace_prefix(ns_tns, pref_tns)

        # FIXME: doesn't look so robust
        url = url.replace('.wsdl', '')

        service_name = self.get_name()

        # create wsdl root node
        root = etree.Element("{%s}definitions" % ns_wsdl, nsmap=soaplib.nsmap)
        root.set('targetNamespace', ns_tns)
        root.set('name', service_name)

        # create types node
        types = etree.SubElement(root, "{%s}types" % ns_wsdl)

        self.build_schema(types)
        messages = set()

        for s in self.services:
            s=self.get_service(s,None)

            s.add_messages_for_methods(root, messages)

        if self._with_plink:
            # create plink node
            plink = etree.SubElement(root, '{%s}partnerLinkType' % ns_plink)
            plink.set('name', service_name)
            self.add_partner_link(root, service_name, types, url, plink)

        # create service node
        service = etree.SubElement(root, '{%s}service' % ns_wsdl)
        service.set('name', service_name)
        self.add_service(root, service_name, types, url, service)

        # create portType node
        port_type = etree.SubElement(root, '{%s}portType' % ns_wsdl)
        port_type.set('name', service_name)

        # create binding nodes
        binding = etree.SubElement(root, '{%s}binding' % ns_wsdl)
        binding.set('name', service_name)
        binding.set('type', '%s:%s'% (pref_tns, service_name))

        soap_binding = etree.SubElement(binding, '{%s}binding' % ns_soap)
        soap_binding.set('style', 'document')
        soap_binding.set('transport', 'http://schemas.xmlsoap.org/soap/http')

        cb_binding = None

        for s in self.services:
            s=self.get_service(s)
            s.add_port_type(root, service_name, types, url, port_type)
            cb_binding = s.add_bindings_for_methods(root, service_name, types,
                                                       url, binding, cb_binding)

        self.__wsdl = etree.tostring(root, xml_declaration=True,
                                                               encoding="UTF-8")

        return self.__wsdl
Ejemplo n.º 14
0
    def add_bindings_for_methods(self, root, service_name, types, url, binding, cb_binding=None):
        '''
        A private method for adding bindings to the wsdl

        @param the root element of the wsdl
        @param the name of this service
        '''

        ns_wsdl = soaplib.ns_wsdl
        ns_soap = soaplib.ns_soap
        pref_tns = soaplib.get_namespace_prefix(self.get_tns())

        if self._has_callbacks():
            if cb_binding is None:
                cb_binding = etree.SubElement(root, '{%s}binding' % ns_wsdl)
                cb_binding.set('name', '%sCallback' % service_name)
                cb_binding.set('type', 'typens:%sCallback' % service_name)

            soap_binding = etree.SubElement(cb_binding, '{%s}binding' % ns_soap)
            soap_binding.set('transport', 'http://schemas.xmlsoap.org/soap/http')

        for method in self.public_methods:
            operation = etree.Element('{%s}operation' % ns_wsdl)
            operation.set('name', method.name)

            soap_operation = etree.SubElement(operation, '{%s}operation' %
                                                                       ns_soap)
            soap_operation.set('soapAction', method.public_name)
            soap_operation.set('style', 'document')

            # get input
            input = etree.SubElement(operation, '{%s}input' % ns_wsdl)
            input.set('name', method.in_message.get_type_name())

            soap_body = etree.SubElement(input, '{%s}body' % ns_soap)
            soap_body.set('use', 'literal')

            # get input soap header
            in_header = method.in_header
            if in_header is None:
                in_header = self.__in_header__

            if not (in_header is None):
                soap_header = etree.SubElement(input, '{%s}header' % ns_soap)
                soap_header.set('use', 'literal')
                soap_header.set('message', in_header.get_type_name_ns())
                soap_header.set('part', in_header.get_type_name())

            if not (method.is_async or method.is_callback):
                output = etree.SubElement(operation, '{%s}output' % ns_wsdl)
                output.set('name', method.out_message.get_type_name())

                soap_body = etree.SubElement(output, '{%s}body' % ns_soap)
                soap_body.set('use', 'literal')

                # get input soap header
                out_header = method.in_header
                if out_header is None:
                    out_header = self.__in_header__

                if not (out_header is None):
                    soap_header = etree.SubElement(output, '{%s}header' % ns_soap)
                    soap_header.set('use', 'literal')
                    soap_header.set('message', out_header.get_type_name_ns())
                    soap_header.set('part', out_header.get_type_name())


            if method.is_callback:
                relates_to = etree.SubElement(input, '{%s}header' % ns_soap)

                relates_to.set('message', '%s:RelatesToHeader' % pref_tns)
                relates_to.set('part', 'RelatesTo')
                relates_to.set('use', 'literal')

                cb_binding.append(operation)

            else:
                if method.is_async:
                    rt_header = etree.SubElement(input,'{%s}header' % ns_soap)
                    rt_header.set('message', '%s:ReplyToHeader' % pref_tns)
                    rt_header.set('part', 'ReplyTo')
                    rt_header.set('use', 'literal')

                    mid_header = etree.SubElement(input, '{%s}header'% ns_soap)
                    mid_header.set('message', '%s:MessageIDHeader' % pref_tns)
                    mid_header.set('part', 'MessageID')
                    mid_header.set('use', 'literal')

                binding.append(operation)

        return cb_binding
Ejemplo n.º 15
0
    def __build_wsdl(self, url):
        """
        Build the wsdl for the application.
        """
        ns_wsdl = soaplib.ns_wsdl
        ns_soap = soaplib.ns_soap
        ns_plink = soaplib.ns_plink

        ns_tns = self.get_tns()
        pref_tns = soaplib.get_namespace_prefix(ns_tns) #'tns'
        # FIXME: this can be enabled when soaplib.nsmap is no longer global
        #soaplib.set_namespace_prefix(ns_tns, pref_tns)

        # FIXME: doesn't look so robust
        url = url.replace('.wsdl', '')

        service_name = self.get_name()

        # create wsdl root node
        root = etree.Element("{%s}definitions" % ns_wsdl, nsmap=soaplib.nsmap)
        root.set('targetNamespace', ns_tns)
        root.set('name', service_name)

        # create types node
        types = etree.SubElement(root, "{%s}types" % ns_wsdl)

        self.build_schema(types)
        messages = set()

        for s in self.services:
            s=self.get_service(s,None)

            s.add_messages_for_methods(root, messages)

        if self._with_plink:
            # create plink node
            plink = etree.SubElement(root, '{%s}partnerLinkType' % ns_plink)
            plink.set('name', service_name)
            self.add_partner_link(root, service_name, types, url, plink)

        # create service node
        service = etree.SubElement(root, '{%s}service' % ns_wsdl)
        service.set('name', service_name)
        self.add_service(root, service_name, types, url, service)

        # create portType node
        port_type = etree.SubElement(root, '{%s}portType' % ns_wsdl)
        port_type.set('name', service_name)

        # create binding nodes
        binding = etree.SubElement(root, '{%s}binding' % ns_wsdl)
        binding.set('name', service_name)
        binding.set('type', '%s:%s'% (pref_tns, service_name))

        soap_binding = etree.SubElement(binding, '{%s}binding' % ns_soap)
        soap_binding.set('style', 'document')
        soap_binding.set('transport', 'http://schemas.xmlsoap.org/soap/http')

        for s in self.services:
            s = self.get_service(s)
            s.add_port_type(root, service_name, types, url, port_type)
            s.add_bindings_for_methods(root, service_name, types, url, binding)

        self.__wsdl = etree.tostring(root, xml_declaration=True,
                                                               encoding="UTF-8")

        return self.__wsdl