Giter Site home page Giter Site logo

wsdl2go's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wsdl2go's Issues

wsdl's SoapAction not respected for Soap1.1

In Soap1.1, the soapAction header is set to the object's name even if the wsdl specifies the soapAction name.

For example, the following wsdl snippet

<soap:operation soapAction="http://soap.example.com"/>

<soap:body use="literal"/>


<soap:body use="literal"/>


<soap:fault name="WsValidationException" use="literal"/>

will generate
if err = p.cli.RoundTripWithAction("ModifyObj", α, &γ); err != nil {
return nil, err
}
return &γ.Body.M, nil

instead, I should expect
if err = p.cli.RoundTripWithAction("http://soap.example.com", α, &γ); err != nil {
return nil, err
}
return &γ.Body.M, nil

Support "this namespace" aka "tns"

Related to #65 which uses "tns"
The request which was send used "xmlns:ns":

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="urn:HandleSearch" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

but needed "xmlns:tns":

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="urn:HandleSearch" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

e2e tests

Ultimate goal of this is to have wsdl2go running on a catalog of public and authorized soap providers and compare their output against some golden files that we pre-generate.

Question. Local dependencies.

Some WSDL files have link on local dependencies(the same directory), like:
<xsd:import namespace="http://test.net/AdminAPI_Admin" schemaLocation="test.net.AdminAPI_Admin.xsd" />

In this case we have the error:
wsdl import: Get test.net.AdminAPI_Admin.wsdl: unsupported protocol scheme ""
If I'm right - this is a error from net/http

Do we need to bug fix something or I can just fast-fix something in my WSDL file?

SOAP call returns empty string

I am trying to use a web service which I have generated some code for, based on the WSDL. The service returns GetResult of the query as a string, which is a string containing XML. This service is query-based so the XML returned in the GetResult is variable depending on which query is used.

My problem is that when I try using this service, GetResult is allways an empty string. The output below is what the result looks like when I run the request in SOAPUI.

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <soap:Body>
      <GetResponse xmlns="http://www.example.com/webservices">
         <GetResult>
            <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
               <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
                  <xs:complexType>
                     <xs:choice minOccurs="0" maxOccurs="unbounded">
                        <xs:element name="Table">
                           <xs:complexType>
                              <xs:sequence>
                                 <xs:element name="ID" type="xs:decimal" minOccurs="0"/>
                              </xs:sequence>
                           </xs:complexType>
                        </xs:element>
                     </xs:choice>
                  </xs:complexType>
               </xs:element>
            </xs:schema>
            <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
               <NewDataSet xmlns="">
                  <Table diffgr:id="Table1" msdata:rowOrder="0">
                     <ID>12345</ID>
                  </Table>
               </NewDataSet>
            </diffgr:diffgram>
         </GetResult>
      </GetResponse>
   </soap:Body>
</soap:Envelope>

Handle enumeration better

A small annoyance that I found today. It revolves around enumeration, and how to work with them.

Take the following wsdl snippet:

<xs:simpleType name="country">
  <xs:restriction base="xs:string">
    <xs:enumeration value="DE"/>
    <xs:enumeration value="AT"/>
    <xs:enumeration value="CH"/>
    <xs:enumeration value="GB"/>
    <xs:enumeration value="ES"/>
    <xs:enumeration value="FR"/>
    <xs:enumeration value="SK"/>
    <xs:enumeration value="LU"/>
    <xs:enumeration value="PL"/>
    <xs:enumeration value="DK"/>
    <xs:enumeration value="IT"/>
    <xs:enumeration value="CZ"/>
    <xs:enumeration value="US"/>
    <xs:enumeration value="BE"/>
    <xs:enumeration value="NL"/>
    <xs:enumeration value="SE"/>
  </xs:restriction>
</xs:simpleType>

This gets translated to:

// Country was auto-generated from WSDL.
type country string

// Validate validates country.
func (v country) Validate() bool {
	for _, vv := range []string{
		"DE",
		"AT",
		"CH",
		"GB",
		"ES",
		"FR",
		"SK",
		"LU",
		"PL",
		"DK",
		"IT",
		"CZ",
		"US",
		"BE",
		"NL",
		"SE",
	} {
		if reflect.DeepEqual(v, vv) {
			return true
		}
	}
	return false
}

The problem is type country string - as the type starts with lowercase, you effectively cannot access that type outside the package the bindings are generated in (which is especially sour if you need that enumeration for requests).

Now, one could of course simple make it start with uppercase just like all the other types. However, that seems unsafe, as we already have a validate method. What I have in mind instead is something like NewCountry(input string), which would take a string (or the equivalent type of the enumeration), instantiate a new instance, run validate, and then return the instance or an error.

Edit: I just realize that this a bad idea, since this method would still return an unexported type - which is deemed bad style. So instead - how about title casing them like the other types, but also providing constants of sorts, so they could be used directly without instantiating?

Thoughts?

generate panic error nil pointer

Hi, i'm try genearet code form documental wsdl (https://api.reformagkh.ru/api_document_literal/wsdl)

But i'm get error:

> panic: runtime error: invalid memory address or nil pointer dereference
> [signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x6eba3b]
> 
> goroutine 1 [running]:
> github.com/fiorix/wsdl2go/wsdlgo.(*goEncoder).genGoOpStruct(0xc420168bb0, 0x94db80, 0xc4201579d0, 0xc42015e000, 0xc4202d4a00, 0x0, 0x0)
> 	/home/neroot/go/src/github.com/fiorix/wsdl2go/wsdlgo/encoder.go:1358 +0x11b
> github.com/fiorix/wsdl2go/wsdlgo.(*goEncoder).writeGoTypes(0xc420168bb0, 0x94db80, 0xc420156d90, 0xc42015e000, 0x0, 0x0)
> 	/home/neroot/go/src/github.com/fiorix/wsdl2go/wsdlgo/encoder.go:1110 +0x82f
> github.com/fiorix/wsdl2go/wsdlgo.(*goEncoder).(github.com/fiorix/wsdl2go/wsdlgo.writeGoTypes)-fm(0x94db80, 0xc420156d90, 0xc42015e000, 0x0, 0x0)
> 	/home/neroot/go/src/github.com/fiorix/wsdl2go/wsdlgo/encoder.go:208 +0x48
> github.com/fiorix/wsdl2go/wsdlgo.(*goEncoder).encode(0xc420168bb0, 0x94db80, 0xc420156d20, 0xc42015e000, 0x80, 0xc420128e40)
> 	/home/neroot/go/src/github.com/fiorix/wsdl2go/wsdlgo/encoder.go:220 +0x370
> github.com/fiorix/wsdl2go/wsdlgo.(*goEncoder).Encode(0xc420168bb0, 0xc42015e000, 0xc42027f1d0, 0x0)
> 	/home/neroot/go/src/github.com/fiorix/wsdl2go/wsdlgo/encoder.go:145 +0xa4
> main.codegen(0x94e680, 0xc42000e018, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
> 	/home/neroot/go/src/github.com/fiorix/wsdl2go/main.go:86 +0x468
> main.main()
> 	/home/neroot/go/src/github.com/fiorix/wsdl2go/main.go:57 +0x3ce
> 

No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.2 LTS
Release: 16.04
Codename: xenial

Generated code cannot unmarshal the response

I ran into the problem, that the response couldn't be unmarshaled, because you apparently assume, that the OutputType token generated in line https://github.com/fiorix/wsdl2go/blob/master/wsdlgo/encoder.go#L490 as xml:\"{{.OutputType}}\" is equal for the struct name and in the annotation, which is not the case for my wsdl endpoint. In my case the name of the XML node is not capitalised.

After I changed the xml annotation token to lower-case, the response could be successfully parsed.

I could try to come up with a patch if you'd help me to understand the problem.

Thank you for your work!

Namespaced operations.

Some endpoints require namespaced messages, for example...

<SOAP-ENV:Envelope 
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:ns="http://example.com/WatWebServiceAPI?wsdl">
    <SOAP-ENV:Body>
        <mns1:watsay xmlns:mns1="http://WatWebServiceAPI/">
            <somevalue>WAT</somevalue>
        </mns1:watsay>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

instead of (note the watsay entity)

<SOAP-ENV:Envelope 
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:ns="http://example.com/WatWebServiceAPI?wsdl">
    <SOAP-ENV:Body>
        <watsay xmlns="http://WatWebServiceAPI/">
            <somevalue>WAT</somevalue>
        </watsay>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

This seems to be the case when the WSDL specifies the targetNamespace and xmlns:tns in the wsdl:definitions entity. I may be wrong on the actual reason for this.

Example snippet from WSDL.

    <?xml version="1.0" encoding="utf-8"?>
    <wsdl:definitions 
            xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
            xmlns:tns="WatWebServiceAPI/" 
            xmlns:xs="http://www.w3.org/2001/XMLSchema" 
            xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
            targetNamespace="WatWebServiceAPI/" 
            name="WatService">
        <wsdl:types>
        ...

Missing Types

I noticed a few missing types in the generated code after running my WSDL through your library.

WSDL seems like it makes a distinction distinguish between xs:int (int32) and xs:integer (arbitrarily large integer), but you don't support the latter. I think we could just use math/big.Int for these, though we'd have to keep track before outputting the imports.

Additionally, you don't generate any structs for abstract types (https://github.com/fiorix/wsdl2go/blob/master/wsdlgo/encoder.go#L897), which seems odd to me - if any types depend on these, we end up with compile failures, because it doesn't exist. Was there a reason not to emit types that are abstract?

The same thing goes for AnySimpleType,
http://search.cpan.org/dist/SOAP-WSDL/lib/SOAP/WSDL/XSD/Typelib/Builtin.pm#SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType, but I admit that I don't fully understand the SOAP spec, so I'm not clear what it should convert to.

I'm happy to submit PRs for these small changes, but I wasn't sure if there was a reason behind doing them this way, so I didn't want to jump the gun. Suggestions/fixes would be appreciated. Thanks!

How to set SOAP Headers?

Thanks for wsdl2go!
So, I used wsdl2go and generated awesome set of types for my huge wsdl (which I cannot post here.) However, the service I am trying to hit expects certain custom headers to be present. I can set them in any of my SOAP clients that I use and it goes fine. But, I did not find how to set those headers. I wrote a simple go test like so:


func TestMakeClient(t *testing.T) {
        request := new(MyDoSomethingRequest)
        client := soap.Client{
                URL:         "<valid-url-here>",
                Namespace:   Namespace,
                ContentType: "text/xml",
        }
        svcPort := NewMyServicePort(&client)
        resp, err := svcPort.MyDoSomething(request)
        if err != nil {
                t.Fatalf("nil response received. %s", err.Error())
        } 
}

I get back errors from my service saying certain headers missing. How do I get a hook to set headers in soap.Client.Config http client? Thanks!

wsdl2go panicking

Hello,
executing wsdl2go with a valid wsdl shows me the following error:

./wsdl2go < perfilamiento.wsdl > perf1.go                                                                                                                                                                                                                               
panic: interface conversion: http.RoundTripper is nil, not *http.Transport

goroutine 1 [running]:
panic(0x7ff9a0, 0xc820118480)
        /usr/lib/go-1.6/src/runtime/panic.go:481 +0x3e6
main.main()
        /home/lalanne/go/src/github.com/fiorix/wsdl2go/main.go:53 +0x5bd

any ideas?
Thanks

Case mismatch in generated `xml:` for responses

From my wsdl, I have one of the operations in types.go generated like so for one myOperation:

type MyServicePort interface {
  // MyOperation was auto-generated from WSDL.
  func (p *myServicePort) MyOperation(α *MyOperationRequest) (β *MyOperationResponse, err error) {
    γ := struct {
        XMLName xml.Name `xml:"Envelope"`
        Body    struct {
            M MyOperationResponse `xml:"MyOperationResponse"`
        }
    }{}
    if err = p.cli.RoundTrip(α, &γ); err != nil {
        return nil, err
    }
    return &γ.Body.M, nil
  }
}

The response type is like so:

type MyOperationResponse struct {
  Ack string `xml:"ack,omitempty" json:"ack,omitempty" yaml:"ack,omitempty"`
  ... // more omitted
}

Server returns XML response for myOperation like so:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">   
  <soapenv:Header />
   <soapenv:Body>
    <myOperation xmlns="http://www.my.com/somenamespace">
      <ack>Failure</ack>
      <!-- omitted -->
    </myOperation>
  </soapenv:Body>
</soapenv:Envelope>

Please note, that the case for myOperation is different from what is defined in the γ struct in func MyOperation(...) Now, upon calling MyOperation always an empty response object is returned. No errors too. Turns out, if I change the case of xml:"MyOperation" to xml:"myOperation" in generated types go file - parsing works fine and I get back a response object with all fields set properly. My question is: is this case mismatch while generating code ? or Is something wrong with my wsdl ?

thanks!

Panic while processing wsdl

I'm trying to process the wsdl from https://testing.maventa.com/apis/v1.1/wsdl. Unfortunately I'm seeing a panic:

panic: runtime error: index out of range

goroutine 1 [running]:
panic(0x6b6a40, 0xc42000c1b0)
        /home/vagrant/.local/share/umake/go/go-lang/src/runtime/panic.go:500 +0x1a1
maventa/vendor/github.com/fiorix/wsdl2go/wsdlgo.(*goEncoder).writeInterfaceFuncs(0xc4201f0720, 0x842940, 0xc4201773b0, 0xc4200ee000, 0xc42022ad01, 0xc420222aa0)
        /home/vagrant/dev/grpc-demo/src/maventa/vendor/github.com/fiorix/wsdl2go/wsdlgo/encoder.go:296 +0x900
maventa/vendor/github.com/fiorix/wsdl2go/wsdlgo.(*goEncoder).(maventa/vendor/github.com/fiorix/wsdl2go/wsdlgo.writeInterfaceFuncs)-fm(0x842940, 0xc4201773b0, 0xc4200ee000, 0x0, 0x4)
        /home/vagrant/dev/grpc-demo/src/maventa/vendor/github.com/fiorix/wsdl2go/wsdlgo/encoder.go:137 +0x48
maventa/vendor/github.com/fiorix/wsdl2go/wsdlgo.(*goEncoder).encode(0xc4201f0720, 0x842940, 0xc420177340, 0xc4200ee000, 0xc420072a14, 0x1)
        /home/vagrant/dev/grpc-demo/src/maventa/vendor/github.com/fiorix/wsdl2go/wsdlgo/encoder.go:150 +0x3bc
maventa/vendor/github.com/fiorix/wsdl2go/wsdlgo.(*goEncoder).Encode(0xc4201f0720, 0xc4200ee000, 0xc4202076e0, 0x0)
        /home/vagrant/dev/grpc-demo/src/maventa/vendor/github.com/fiorix/wsdl2go/wsdlgo/encoder.go:91 +0xbe
main.decode(0x843480, 0xc42002c010, 0x0, 0x0, 0x863600, 0x15, 0x1e)
        /home/vagrant/dev/grpc-demo/src/maventa/vendor/github.com/fiorix/wsdl2go/main.go:74 +0x3fc
main.main()
        /home/vagrant/dev/grpc-demo/src/maventa/vendor/github.com/fiorix/wsdl2go/main.go:53 +0x210

Should not depend on $GOROOT to be defined

According to https://golang.org/doc/install, GOROOT should be set only in the case where go binary distribution is installed to a custom location. Otherwise, "The Go binary distributions assume they will be installed in /usr/local/go (or c:\Go under Windows)"

However, in wsdlgo/encoder.go, it requires GOROOT to be set. A better solution is to assume /usr/local/go (or C:\Go in the case of windows) if GOROOT is not set.

SetXMLType on interface

The encoder should not encode the SetXMLType object if the complexType itself is abstract. Otherwise, the generated go file cannot compile because you cannot assign TypeAttrXSI and TypeNamespace to it.

Currently, the following is generated:

// BulkOperationRequest was auto-generated from WSDL.
type BulkOperationRequest interface{}

// SetXMLType was auto-generated from WSDL.
func (t *BulkOperationRequest) SetXMLType() {
t.TypeAttrXSI = "objtype:BulkOperationRequest"
t.TypeNamespace = "http://www.example.com"
}

Output file not written if it is not present

I try to invoke wsdl2go -i -o ~/dummy.go

If ~/dummy.go is not present, the program will output
016/09/01 17:50:21 open /home/atam/dummy.go: no such file or directory

Simple fix is to create the file if it not present.

Decimal type not found error

When wsdl2go produce the file, it added the Decimal type but it doesnt exists in library.
if you have a problem like me, only add below type definition line on top of the produced file and it works.

type Decimal float32

or on encoder.go change wsdl2goType function like this

// Converts types from wsdl type to Go type.
func (ge *goEncoder) wsdl2goType(t string) string {
	// TODO: support other types.
	v := ge.trimns(t)
	if _, exists := ge.stypes[v]; exists {
		return v
	}
	switch strings.ToLower(v) {
	case "int":
		return "int"
	case "long":
		return "int64"
	case "float", "double":
		return "float64"
	case "decimal":
		return "float32"
	case "boolean":
		return "bool"
	case "hexbinary", "base64binary":
		return "[]byte"
	case "string", "anyuri", "token", "qname":
		return "string"
	case "date":
		ge.needsDateType = true
		return "Date"
	case "time":
		ge.needsTimeType = true
		return "Time"
	case "nonnegativeinteger":
		return "uint"
	case "datetime":
		ge.needsDateTimeType = true
		return "DateTime"
	case "duration":
		ge.needsDurationType = true
		return "Duration"
	case "anysequence":
		return "interface{}"
	default:
		return "*" + strings.Title(strings.Replace(v, ".", "", -1))
	}
}

generated bad code: 104:11: expected expression (and 1 more errors)

@kernle32dll the last changes you did in #75 causes:

2017/12/29 10:24:37 generated bad code: 104:11: expected expression (and 1 more errors)
    1	package brokerbin
    2	
    3	import (
    4	"github.com/fiorix/wsdl2go/soap"
    5	)
    6	
    7	// Namespace was auto-generated from WSDL.
    8	var Namespace = "urn:HandleSearch"
    9	
   10	
   11	// NewHandleSearchPort creates an initializes a HandleSearchPort.
   12	func NewHandleSearchPort(cli *soap.Client) HandleSearchPort {
   13		return &handleSearchPort{cli}
   14	}
   15	
   16	// HandleSearchPort was auto-generated from WSDL
   17	// and defines interface for the remote service. Useful for testing.
   18	type HandleSearchPort interface {
   19	// Authenticate was auto-generated from WSDL.
   20	Authenticate(reqUsername string,reqPassword string,reqOptions interface{}) (string,error)
   21	
   22	// Search was auto-generated from WSDL.
   23	Search(reqPart interface{},reqOptions interface{}) (interface{},error)
   24	
   25	}
   26	// Operation wrapper for Authenticate.
   27	// OperationAuthenticateRequest was auto-generated from WSDL.
   28	type OperationAuthenticateRequest struct {
   29	ReqUsername *string `xml:"reqUsername,omitempty" json:"reqUsername,omitempty" yaml:"reqUsername,omitempty"`
   30	ReqPassword *string `xml:"reqPassword,omitempty" json:"reqPassword,omitempty" yaml:"reqPassword,omitempty"`
   31	ReqOptions *interface{} `xml:"reqOptions,omitempty" json:"reqOptions,omitempty" yaml:"reqOptions,omitempty"`
   32	}
   33	
   34	// Operation wrapper for Authenticate.
   35	// OperationAuthenticateResponse was auto-generated from WSDL.
   36	type OperationAuthenticateResponse struct {
   37	ResSession *string `xml:"resSession,omitempty" json:"resSession,omitempty" yaml:"resSession,omitempty"`
   38	}
   39	
   40	// Operation wrapper for Search.
   41	// OperationSearchRequest was auto-generated from WSDL.
   42	type OperationSearchRequest struct {
   43	ReqPart *interface{} `xml:"reqPart,omitempty" json:"reqPart,omitempty" yaml:"reqPart,omitempty"`
   44	ReqOptions *interface{} `xml:"reqOptions,omitempty" json:"reqOptions,omitempty" yaml:"reqOptions,omitempty"`
   45	}
   46	
   47	// Operation wrapper for Search.
   48	// OperationSearchResponse was auto-generated from WSDL.
   49	type OperationSearchResponse struct {
   50	ResParam *interface{} `xml:"resParam,omitempty" json:"resParam,omitempty" yaml:"resParam,omitempty"`
   51	}
   52	
   53	
   54	// handleSearchPort implements the HandleSearchPort interface.
   55	type handleSearchPort struct {
   56		cli *soap.Client
   57	}
   58	
   59	// Authenticate was auto-generated from WSDL.
   60	func (p *handleSearchPort) Authenticate(reqUsername string,reqPassword string,reqOptions interface{}) (string,error) {
   61		α := struct {
   62			
   63				M OperationAuthenticateRequest `xml:"tns:Authenticate"`
   64			
   65		}{
   66			OperationAuthenticateRequest {
   67				&reqUsername,
   68				&reqPassword,
   69				&reqOptions,
   70				
   71			},
   72		}
   73	
   74		γ := struct {
   75			
   76				M OperationAuthenticateResponse `xml:"AuthenticateResponse"`
   77			
   78		}{}
   79		if err := p.cli.RoundTripWithAction("urn:brokerbin#HandleSearch#Authenticate", α, &γ); err != nil {
   80			return "",err
   81		}
   82		return *γ.M.ResSession, nil
   83	}
   84	// Search was auto-generated from WSDL.
   85	func (p *handleSearchPort) Search(reqPart interface{},reqOptions interface{}) (interface{},error) {
   86		α := struct {
   87			
   88				M OperationSearchRequest `xml:"tns:Search"`
   89			
   90		}{
   91			OperationSearchRequest {
   92				&reqPart,
   93				&reqOptions,
   94				
   95			},
   96		}
   97	
   98		γ := struct {
   99			
  100				M OperationSearchResponse `xml:"SearchResponse"`
  101			
  102		}{}
  103		if err := p.cli.RoundTripWithAction("urn:brokerbin#HandleSearch#Search", α, &γ); err != nil {
  104			return &interface{}{},err
  105		}
  106		return *γ.M.ResParam, nil
  107	}

It worked until here: #75 (comment)
wsdl file in #65

Unreachable code when encoder should generate nested ComplexType

In wsdl2go/wsdlgo/encoder.go at line 1040 there is a code:

	if el.Type == "" {
		el.Type = "string"
	}
	var slicetype string
	if el.Type == "" && el.ComplexType != nil {
         ...
        }

Second "if" will never evaluate to true because when el.Type is empty it'll be set to "string" in the first "if". That will generated all nested complex types as "string" instead of proper types.

Possibly the proper logic should be:

	if el.Type == "" {
		if el.ComplexType != nil {
		...
		} else {
			el.Type = "string"
		}
	}

Broken SOAP body

According to this commit you have removed the body from the soap messages:

0e4e8dc

It has basically broken the whole functionality over old SOAP servers

I think it should be fixed somehow

Enhancement to allow overriding of SetXMLType values

Currently, the SetXMLType function will set the TypeAttrXSI and TypeNamespace for complex content. However, it does not allow the caller to overwrite the above values. In some cases, it will be useful to allow the caller to overwrite these values.

wsdl2go issues

wsdl: http://soap.brokerbin.com/brokerbin_search/search.wsdl

Cut from generated go file:

// NewHandleSearchPort creates an initializes a HandleSearchPort.
func NewHandleSearchPort(cli *soap.Client) HandleSearchPort {
	return &handleSearchPort{cli}
}

// HandleSearchPort was auto-generated from WSDL
// and defines interface for the remote service. Useful for testing.
type HandleSearchPort interface {
}

// handleSearchPort implements the HandleSearchPort interface.
type handleSearchPort struct {
	cli *soap.Client
}

// Authenticate was auto-generated from WSDL.
func (p *handleSearchPort) Authenticate(α string, reqPassword string, reqOptions interface{}) (β string, err error) {
	γ := struct {
		XMLName xml.Name `xml:"Envelope"`
		Body    struct {
			M string `xml:"string"`
		}
	}{}
	if err = p.cli.RoundTripWithAction("Authenticate", α, &γ); err != nil {
		return "", err
	}
	return γ.Body.M, nil
}

// Search was auto-generated from WSDL.
func (p *handleSearchPort) Search(α interface{}, reqOptions interface{}) (β interface{}, err error) {
	γ := struct {
		XMLName xml.Name `xml:"Envelope"`
		Body    struct {
			M interface{} `xml:"interface{}"`
		}
	}{}
	if err = p.cli.RoundTripWithAction("Search", α, &γ); err != nil {
		return nil, err
	}
	return γ.Body.M, nil
}

HandleSearchPort is empty which causes:
image

Authenticate and Search will only transport first parameter e.g. for Authenticate:

POST / HTTP/1.1
Host: localhost
Content-Type: text/xml
Soapaction: urn:HandleSearch/Authenticate

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="urn:HandleSearch" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Body><Message>foo</Message></SOAP-ENV:Body></SOAP-ENV:Envelope>

Expected or needed request for linked wsdl above:

POST / HTTP/1.1
Host: localhost
Content-Type: text/xml
Soapaction: urn:HandleSearch/Authenticate

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:tns="urn:HandleSearch">
	<soap:Body>
		<tns:Authenticate>
			<reqUsername>foo</reqUsername>
			<reqPassword>:)</reqPassword>
		</tns:Authenticate>
	</soap:Body>
</soap:Envelope>

The main difference is that Message (in first) is replaced by a "message" tns:Authenticate (in second) which also contains reqUsername (aka α) and reqPassword (aka reqPassword).

Got same issues for other wsdl files, but this is the easiest example, to explain.

Support Relative URLs for remote wsdl's

Running the tool over the ONVIF specification produces the following error:

2017/12/02 17:44:05 wsdl import: could not open file raw:  path: ../../../ver10/schema/onvif.xsd escaped: ../../../ver10/schema/onvif.xsd : open ../../../ver10/schema/onvif.xsd: no such file or directory

Upon closer inspection of the WSDL, it appears it does some relative importing:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../../../ver20/util/onvif-wsdl-viewer.xsl"?>
<!--
Copyright (c) 2008-2017 by ONVIF: Open Network Video Interface Forum. All rights reserved.

Recipients of this document may copy, distribute, publish, or display this document so long as this copyright notice, license and disclaimer are retained with all copies of the document. No license is granted to modify this document.

THIS DOCUMENT IS PROVIDED "AS IS," AND THE CORPORATION AND ITS MEMBERS AND THEIR AFFILIATES, MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THIS DOCUMENT ARE SUITABLE FOR ANY PURPOSE; OR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
IN NO EVENT WILL THE CORPORATION OR ITS MEMBERS OR THEIR AFFILIATES BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR RELATING TO ANY USE OR DISTRIBUTION OF THIS DOCUMENT, WHETHER OR NOT (1) THE CORPORATION, MEMBERS OR THEIR AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR (2) SUCH DAMAGES WERE REASONABLY FORESEEABLE, AND ARISING OUT OF OR RELATING TO ANY USE OR DISTRIBUTION OF THIS DOCUMENT.  THE FOREGOING DISCLAIMER AND LIMITATION ON LIABILITY DO NOT APPLY TO, INVALIDATE, OR LIMIT REPRESENTATIONS AND WARRANTIES MADE BY THE MEMBERS AND THEIR RESPECTIVE AFFILIATES TO THE CORPORATION AND OTHER MEMBERS IN CERTAIN WRITTEN POLICIES OF THE CORPORATION.
-->
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" targetNamespace="http://www.onvif.org/ver10/device/wsdl">
	<wsdl:types>
		<xs:schema targetNamespace="http://www.onvif.org/ver10/device/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" elementFormDefault="qualified" version="17.06">
			<xs:import namespace="http://www.onvif.org/ver10/schema" schemaLocation="../../../ver10/schema/onvif.xsd"/>
			<!--===============================-->

Unable to process wsdl file

I try to process this WSDL file (the one from UPS delivery)
https://gist.github.com/vodolaz095/732a0822902b1cb06dd592adbf359e32

I receive this error:

panic: template: interfaceType:10: illegal number syntax: "-"

goroutine 1 [running]:
text/template.Must(0x0, 0x7f15fa332000, 0xc820076e00, 0x0)
    /usr/lib/golang/src/text/template/helper.go:23 +0x4b
github.com/fiorix/wsdl2go/wsdlgo.init()
    /home/vodolaz095/go/src/github.com/fiorix/wsdl2go/wsdlgo/encoder.go:269 +0xe6
main.init()
    /home/vodolaz095/go/src/github.com/fiorix/wsdl2go/main.go:87 +0x68

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /usr/lib/golang/src/runtime/asm_amd64.s:1721 +0x1

I use Linux and Go of version go version go1.5.4 linux/amd64

Incorrect paramStruct xml names

I have an XML file that has a bunch of types/functions that look like this:

<wsdl:definitions targetNamespace="Namespace">
  <wsdl:types>
    <xs:schema targetNamespace="Namespace">
      <xs:complexType name="ArrayOfString">
        <xs:sequence>
          <xs:element name="stringItem" type="xs:string" minOccurs="0" maxOccurs="unbounded" nillable="false"/>
        </xs:sequence>
      </xs:complexType>

      <xs:complexType name="Tag">
        <xs:sequence>
          <xs:element name="type" type="xs:string" minOccurs="0" maxOccurs="1" nillable="false"/>
          <xs:element name="values" type="tns:ArrayOfString" minOccurs="0" maxOccurs="1" nillable="false"/>
        </xs:sequence>
      </xs:complexType>
      <xs:complexType name="ArrayOfTag">
        <xs:sequence>
          <xs:element name="tag" type="tns:Tag" minOccurs="0" maxOccurs="unbounded" nillable="false"/>
        </xs:sequence>
      </xs:complexType>

      <xs:complexType name="ParamsGetTags">
        <xs:sequence>
          <xs:element name="tagList" type="tns:ArrayOfTag" minOccurs="0" maxOccurs="1" nillable="false"/>
        </xs:sequence>
      </xs:complexType>
      <xs:complexType name="ResultGetTags">
        <xs:sequence>
          <xs:element name="tagList" type="tns:ArrayOfTag" minOccurs="1" maxOccurs="1" nillable="false"/>
        </xs:sequence>
      </xs:complexType>
      <xs:complexType name="SuccessGetTags">
        <xs:sequence>
          <xs:element name="result" type="tns:ResultGetTags" minOccurs="1" maxOccurs="1"/>
        </xs:sequence>
      </xs:complexType>

      <xs:element name="paramsGetTags" type="tns:ParamsGetTags"/>
      <xs:element name="successGetTags" type="tns:SuccessGetTags"/>
    </xs:schema>
  </wsdl:types>

  <wsdl:message name="GetTagsRequest">
    <wsdl:part name="paramsGetTags" element="tns:paramsGetTags"/>
  </wsdl:message>
  <wsdl:message name="GetTagsResponse">
    <wsdl:part name="successGetTags" element="tns:successGetTags"/>
  </wsdl:message>

  <wsdl:portType name="NPort">
    <wsdl:operation name="getTags">
      <wsdl:documentation>Get Tags
      </wsdl:documentation>
      <wsdl:input message="tns:GetTagsRequest"/>
      <wsdl:output message="tns:GetTagsResponse"/>
    </wsdl:operation>
  </wsdl:portType>

  <wsdl:binding name="NApiSoapBinding" type="tns:NPort">
      <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
      <wsdl:operation name="getTags">
          <soap:operation soapAction="example.com/N/getTags" />
          <wsdl:input>
              <soap:header use="literal" part="authentication" message="tns:AuthenticationHeader" />
              <soap:body use="literal" />
          </wsdl:input>
          <wsdl:output>
              <soap:body use="literal" />
          </wsdl:output>
      </wsdl:operation>
  </wsdl:binding>

</wsdl:definitions>

I've included all the definitions (e.g. of ArrayOfTags) for completeness, and since it allows the example above to be complete/testable.

It wasn't working for me, and when I looked more closely, I was able to uncovere the problem. I believe that the line <xs:element name="paramsGetTags" type="tns:ParamsGetTags"/> should override the "name" on the complex type <xs:complexType name="ParamsGetTags">. The generated struct is

// ParamsGetTags was auto-generated from WSDL.
type ParamsGetTags struct {
        XMLName xml.Name    `xml:"Namespace ParamsGetTags" json:"-" yaml:"-"`
        TagList *ArrayOfTag `xml:"tagList,omitempty" json:"tagList,omitempty" yaml:"tagList,omitempty"`
}

but it fails when the element name is ParamsGetTags. If I change it to paramsGetTags, it works perfectly.

Is there an easy fix you recommend for this? I can dig into some of the code generation, but nothing jumped at me as an easy way to look up if there's another element with that type, and I didn't want to build out a hacky solution if there was something you felt was more appropriate.

Let me know what you think.
Thanks! This library has made my dealing with SOAP in Go much more bearable.

Type collission (Invalid recursive type)

File http://service.businessmall.hp.live.greenova.de/API/1/BusinessmallService.svc?wsdl

// Char was auto-generated from WSDL.
type Char int

// Duration was auto-generated from WSDL.
type Duration Duration // <-- HERE

// Guid was auto-generated from WSDL.
type Guid string

Type defined in http://service.businessmall.hp.live.greenova.de/API/1/BusinessmallService.svc?xsd=xsd1

It compiles, but should be changed.
And maybe a good file for testing, generates about 2000 lines.

Enhancement: Automatic generation of mock object to satisfy interface

Probably a good idea to have some way to automatically generate a mock object that satisfy the interface. This allow easy testing of data that uses the interface.

For example, for the interface Foo
type Foo interface {
CreateMoo(a *CreateMooRequest) (B *CreateMooResponse, err error)
}

We can generate abc_test.go
type MockFoo struct {
Err error
MockCreateMooResponse *CreateMooResponse
}

func (m * MockFoo) CreateMoo(a *CreateMooRequest) (B *CreateMooResponse, err error) {
return m.MockCreateMooResponse, m.Err
}

Message is not unmarshalled into response struct correctly

I have created a working version (using a specific struct, rather than the Message interface used by the generated Client)...

https://play.golang.org/p/9S0Jzk9_C-

and a version that uses the Message interface. Again, this is isolated code from a generated Client.

https://play.golang.org/p/czWZqKEUgG

Has anyone seen the structs being populated correctly when using the Message interface in Body?

Using a []byte instead of a Message interface seems to work.

https://play.golang.org/p/qFY2hj5Lnv

If you are happy with this option I would supply a fix. Thoughts?

SoapAction error

client.go doesnt send soap action, i change roudtrip function like this (and it works perfectly):
`

// RoundTrip implements the RoundTripper interface.
func (c *Client) RoundTrip(in, out Message) error {
req := &Envelope{
EnvelopeAttr: c.Envelope,
NSAttr: c.Namespace,
Header: c.Header,
Body: Body{Message: in},
}

if req.EnvelopeAttr == "" {
	req.EnvelopeAttr = "http://schemas.xmlsoap.org/soap/envelope/"
}
if req.NSAttr == "" {
	req.NSAttr = c.URL
}
var b bytes.Buffer
err := xml.NewEncoder(&b).Encode(req)
if err != nil {
	return err
}
ct := c.ContentType
if ct == "" {
	ct = "text/xml"
}
cli := c.Config
if cli == nil {
	cli = http.DefaultClient
}
r, err := http.NewRequest("POST", c.URL, &b)
if err != nil {
	return err
}
r.Header.Set("Content-Type", ct)
r.Header.Add("SOAPAction", fmt.Sprintf("%s/%s", c.Namespace, reflect.TypeOf(in).Elem().Name()))
if c.Pre != nil {
	c.Pre(r)
}
resp, err := cli.Do(r)
if err != nil {
	return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
	// read only the first Mb of the body in error case
	limReader := io.LimitReader(resp.Body, 1024*1024)
	body, _ := ioutil.ReadAll(limReader)
	return fmt.Errorf("%q: %q", resp.Status, body)
}
return xml.NewDecoder(resp.Body).Decode(out)

}

`

I hope this will be helpfull

Fix complex types

Found several annoyances while trying to parse this wsdl with @flavioayra:

http://webservices.sabre.com/wsdl/sabreXML1.0.00/usg/SessionCreateRQ.wsdl

Problems include:

  • Couldn't parse the tag in schemas, which apparently is the same as
  • Template that generates functions with multiple return values missing "," between returned args
  • Missing string types: nmtoken, language, id
  • Complex types sequence elements but also "any" generates empty interface types
  • Complex types and attributes without name and type, only containing ref

possible typo in encoder.go

Hello,

I am trying to use wsdl2go with the WSDL files provided by UK NationalRail as part of OpenLDBWS. When I try this, wsdl2go fails with a stack overflow. Here is what I tried:

    curl -o ldbws.wsdl https://lite.realtime.nationalrail.co.uk/OpenLDBWS/wsdl.aspx?ver=2017-10-01
    wget https://lite.realtime.nationalrail.co.uk/OpenLDBWS/rtti_2017-10-01_ldb.wsdl
    wget https://lite.realtime.nationalrail.co.uk/OpenLDBWS/rtti_2007-10-10_ldb_common_types.xsd
    wget https://lite.realtime.nationalrail.co.uk/OpenLDBWS/rtti_2015-11-27_ldb_common_types.xsd
    wget https://lite.realtime.nationalrail.co.uk/OpenLDBWS/rtti_2017-10-01_ldb_types.xsd
    wget https://lite.realtime.nationalrail.co.uk/OpenLDBWS/rtti_2016-02-16_ldb_common_types.xsd
    wget https://lite.realtime.nationalrail.co.uk/OpenLDBWS/rtti_2017-02-02_ldb_common_types.xsd
    wget https://lite.realtime.nationalrail.co.uk/OpenLDBWS/rtti_2017-10-01_ldb_common_types.xsd
    wget https://lite.realtime.nationalrail.co.uk/OpenLDBWS/rtti_2012-01-13_ldb_types.xsd
    wget https://lite.realtime.nationalrail.co.uk/OpenLDBWS/rtti_2015-11-27_ldb_types.xsd
    wget https://lite.realtime.nationalrail.co.uk/OpenLDBWS/rtti_2016-02-16_ldb_types.xsd
    wsdl2go <ldbws.wsdl >ldbws.go

The result is a very long error message, indicating a stack overflow, which involves the following recursion:

...
github.com/fiorix/wsdl2go/wsdlgo.trimns(0xc42027c560, 0x18, 0x10afc32, 0xc42027c560)
	/Users/voss/go/src/github.com/fiorix/wsdl2go/wsdlgo/encoder.go:1276 +0x57 fp=0xc440300538 sp=0xc4403004e8 pc=0x12e0f07
github.com/fiorix/wsdl2go/wsdlgo.(*goEncoder).genComplexContent(0xc42016c2c0, 0x13e32e0, 0xc420145c70, 0xc420162000, 0xc420205b80, 0x2, 0xc4201ee970)
	/Users/voss/go/src/github.com/fiorix/wsdl2go/wsdlgo/encoder.go:1397 +0x668 fp=0xc440300610 sp=0xc440300538 pc=0x12e2688
github.com/fiorix/wsdl2go/wsdlgo.(*goEncoder).genStructFields(0xc42016c2c0, 0x13e32e0, 0xc420145c70, 0xc420162000, 0xc420205b80, 0x13a2501, 0x1)
	/Users/voss/go/src/github.com/fiorix/wsdl2go/wsdlgo/encoder.go:1354 +0x57 fp=0xc440300658 sp=0xc440300610 pc=0x12e1ac7
github.com/fiorix/wsdl2go/wsdlgo.(*goEncoder).genComplexContent(0xc42016c2c0, 0x13e32e0, 0xc420145c70, 0xc420162000, 0xc420205b80, 0x2, 0xc4201ee970)
	/Users/voss/go/src/github.com/fiorix/wsdl2go/wsdlgo/encoder.go:1399 +0x6e4 fp=0xc440300730 sp=0xc440300658 pc=0x12e2704
github.com/fiorix/wsdl2go/wsdlgo.(*goEncoder).genStructFields(0xc42016c2c0, 0x13e32e0, 0xc420145c70, 0xc420162000, 0xc420205b80, 0x13a2501, 0x1)
	/Users/voss/go/src/github.com/fiorix/wsdl2go/wsdlgo/encoder.go:1354 +0x57 fp=0xc440300778 sp=0xc440300730 pc=0x12e1ac7
github.com/fiorix/wsdl2go/wsdlgo.(*goEncoder).genComplexContent(0xc42016c2c0, 0x13e32e0, 0xc420145c70, 0xc420162000, 0xc420205b80, 0x2, 0xc4201ee970)
	/Users/voss/go/src/github.com/fiorix/wsdl2go/wsdlgo/encoder.go:1399 +0x6e4 fp=0xc440300850 sp=0xc440300778 pc=0x12e2704
...

I wonder whether the test if exists {...} really should be if !exists {...}?

if exists {

Enhancement to allow overriding of namespace in XMLName

Currently, the name for complex object is generated from the target namespace as specified in WSDL file.

However, in some legacy SOAP system, it is required that the SOAP message body object's namespace be different than the one specified in the wsdl file. Thus, it would be advantageous to allow override of the default (correct) behaviour.

Soap funcs with != 1 parameter not working

I realized today, that this lib shows odd behavior when using soap funcs which either don't take any parameters, or more than one.

The first one of course is explained by this TODO in-code. However, the if clause at this position also has an oversight which causes wrong method templating on soap funcs with more than one parameter. In this case the parameters end up in the go func definition, but are not passed to p.cli.RoundTripWithAction.

If welcome, I can cook up at least some test cases, and maybe some potential enhancements to fix the issues.

Edit: I see the "more than 1 parameter" issue is tracked by #65

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.