Skip to content

Commit

Permalink
Refactored code, made it concurrent safe.
Browse files Browse the repository at this point in the history
  • Loading branch information
CJ-Jackson committed Feb 2, 2019
1 parent 2cb534c commit ac80a50
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 109 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ func main() {
"IPAddress": "8.8.8.8",
}

err = soap.Call("GetGeoIP", params)
res, err := soap.Call("GetGeoIP", params)
if err != nil {
fmt.Errorf("error in soap call: %s", err)
}

soap.Unmarshal(&r)
res.Unmarshal(&r)
if r.GetGeoIPResult.CountryCode != "USA" {
fmt.Errorf("error: %+v", r)
}
Expand Down
74 changes: 38 additions & 36 deletions encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,45 @@ import (
"reflect"
)

var tokens []xml.Token

// MarshalXML envelope the body and encode to xml
func (c Client) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
func (c process) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {

tokens = []xml.Token{}
tokens := &tokenData{}

//start envelope
if c.Definitions == nil {
if c.Client.Definitions == nil {
return fmt.Errorf("definitions is nil")
}

startEnvelope()
if len(c.HeaderParams) > 0 {
startHeader(c.HeaderName, c.Definitions.Types[0].XsdSchema[0].TargetNamespace)
for k, v := range c.HeaderParams {
tokens.startEnvelope()
if len(c.Client.HeaderParams) > 0 {
tokens.startHeader(c.Client.HeaderName, c.Client.Definitions.Types[0].XsdSchema[0].TargetNamespace)
for k, v := range c.Client.HeaderParams {
t := xml.StartElement{
Name: xml.Name{
Space: "",
Local: k,
},
}

tokens = append(tokens, t, xml.CharData(v), xml.EndElement{Name: t.Name})
tokens.data = append(tokens.data, t, xml.CharData(v), xml.EndElement{Name: t.Name})
}

endHeader(c.HeaderName)
tokens.endHeader(c.Client.HeaderName)
}

err := startBody(c.Method, c.Definitions.Types[0].XsdSchema[0].TargetNamespace)
err := tokens.startBody(c.Request.Method, c.Client.Definitions.Types[0].XsdSchema[0].TargetNamespace)
if err != nil {
return err
}

recursiveEncode(c.Params)
tokens.recursiveEncode(c.Request.Params)

//end envelope
endBody(c.Method)
endEnvelope()
tokens.endBody(c.Request.Method)
tokens.endEnvelope()

for _, t := range tokens {
for _, t := range tokens.data {
err := e.EncodeToken(t)
if err != nil {
return err
Expand All @@ -56,7 +54,11 @@ func (c Client) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
return e.Flush()
}

func recursiveEncode(hm interface{}) {
type tokenData struct {
data []xml.Token
}

func (tokens *tokenData) recursiveEncode(hm interface{}) {
v := reflect.ValueOf(hm)

switch v.Kind() {
Expand All @@ -69,21 +71,21 @@ func recursiveEncode(hm interface{}) {
},
}

tokens = append(tokens, t)
recursiveEncode(v.MapIndex(key).Interface())
tokens = append(tokens, xml.EndElement{Name: t.Name})
tokens.data = append(tokens.data, t)
tokens.recursiveEncode(v.MapIndex(key).Interface())
tokens.data = append(tokens.data, xml.EndElement{Name: t.Name})
}
case reflect.Slice:
for i := 0; i < v.Len(); i++ {
recursiveEncode(v.Index(i).Interface())
tokens.recursiveEncode(v.Index(i).Interface())
}
case reflect.String:
content := xml.CharData(v.String())
tokens = append(tokens, content)
tokens.data = append(tokens.data, content)
}
}

func startEnvelope() {
func (tokens *tokenData) startEnvelope() {
e := xml.StartElement{
Name: xml.Name{
Space: "",
Expand All @@ -96,21 +98,21 @@ func startEnvelope() {
},
}

tokens = append(tokens, e)
tokens.data = append(tokens.data, e)
}

func endEnvelope() {
func (tokens *tokenData) endEnvelope() {
e := xml.EndElement{
Name: xml.Name{
Space: "",
Local: "soap:Envelope",
},
}

tokens = append(tokens, e)
tokens.data = append(tokens.data, e)
}

func startHeader(m, n string) {
func (tokens *tokenData) startHeader(m, n string) {
h := xml.StartElement{
Name: xml.Name{
Space: "",
Expand All @@ -119,7 +121,7 @@ func startHeader(m, n string) {
}

if m == "" || n == "" {
tokens = append(tokens, h)
tokens.data = append(tokens.data, h)
return
}

Expand All @@ -133,12 +135,12 @@ func startHeader(m, n string) {
},
}

tokens = append(tokens, h, r)
tokens.data = append(tokens.data, h, r)

return
}

func endHeader(m string) {
func (tokens *tokenData) endHeader(m string) {
h := xml.EndElement{
Name: xml.Name{
Space: "",
Expand All @@ -147,7 +149,7 @@ func endHeader(m string) {
}

if m == "" {
tokens = append(tokens, h)
tokens.data = append(tokens.data, h)
return
}

Expand All @@ -158,11 +160,11 @@ func endHeader(m string) {
},
}

tokens = append(tokens, r, h)
tokens.data = append(tokens.data, r, h)
}

// startToken initiate body of the envelope
func startBody(m, n string) error {
func (tokens *tokenData) startBody(m, n string) error {
b := xml.StartElement{
Name: xml.Name{
Space: "",
Expand All @@ -184,13 +186,13 @@ func startBody(m, n string) error {
},
}

tokens = append(tokens, b, r)
tokens.data = append(tokens.data, b, r)

return nil
}

// endToken close body of the envelope
func endBody(m string) {
func (tokens *tokenData) endBody(m string) {
b := xml.EndElement{
Name: xml.Name{
Space: "",
Expand All @@ -205,5 +207,5 @@ func endBody(m string) {
},
}

tokens = append(tokens, r, b)
tokens.data = append(tokens.data, r, b)
}
2 changes: 1 addition & 1 deletion encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestClient_MarshalXML(t *testing.T) {
}

for _, test := range tests {
err = soap.Call("checkVat", test.Params)
_, err = soap.Call("checkVat", test.Params)
if err == nil {
t.Errorf(test.Err)
}
Expand Down
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
module github.com/tiaguinho/gosoap

require (
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3
golang.org/x/text v0.3.0 // indirect
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 h1:ulvT7fqt0yHWzpJwI57MezWnYDVpCAYBVuYst/L+fAY=
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
29 changes: 29 additions & 0 deletions request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package gosoap

import (
"fmt"
)

type Request struct {
Method string
Params Params
}

func NewRequest(m string, p Params) *Request {
return &Request{
Method: m,
Params: p,
}
}

type RequestStruct interface {
SoapBuildRequest() *Request
}

func NewRequestByStruct(s RequestStruct) (*Request, error) {
if s == nil {
return nil, fmt.Errorf("'s' cannot be 'nil'")
}

return s.SoapBuildRequest(), nil
}
27 changes: 27 additions & 0 deletions response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package gosoap

import (
"encoding/xml"
"fmt"
)

type Response struct {
Body []byte
Header []byte
Payload []byte
}

// Unmarshal get the body and unmarshal into the interface
func (r *Response) Unmarshal(v interface{}) error {
if len(r.Body) == 0 {
return fmt.Errorf("Body is empty")
}

var f Fault
xml.Unmarshal(r.Body, &f)
if f.Code != "" {
return fmt.Errorf("[%s]: %s", f.Code, f.Description)
}

return xml.Unmarshal(r.Body, v)
}
Loading

0 comments on commit ac80a50

Please sign in to comment.