Skip to content

Commit edfdac4

Browse files
authored
Merge pull request #56 from opencredo/xml_to_json_conversion
XML-to-JSON conversion
2 parents fa87c0b + 549a7e9 commit edfdac4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+26059
-1288
lines changed

.travis.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,8 @@ go:
1111
env:
1212
- CGO_ENABLED=0
1313

14-
script: travis_wait 20 ./scripts/build.sh
14+
script: |
15+
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
16+
export UPCLOUD_GO_SDK_TEST_NO_CREDENTIALS="yes"
17+
fi
18+
travis_wait 20 ./scripts/build.sh

upcloud/account.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,27 @@
11
package upcloud
22

3+
import "encoding/json"
4+
35
// Account represents an account
46
type Account struct {
5-
Credits float64 `xml:"credits"`
6-
UserName string `xml:"username"`
7+
Credits float64 `json:"credits"`
8+
UserName string `json:"username"`
9+
}
10+
11+
// UnmarshalJSON is a custom unmarshaller that deals with
12+
// deeply embedded values.
13+
func (s *Account) UnmarshalJSON(b []byte) error {
14+
type localAccount Account
15+
16+
v := struct {
17+
Account localAccount `json:"account"`
18+
}{}
19+
err := json.Unmarshal(b, &v)
20+
if err != nil {
21+
return err
22+
}
23+
24+
(*s) = Account(v.Account)
25+
26+
return nil
727
}

upcloud/account_test.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
package upcloud
22

33
import (
4-
"encoding/xml"
4+
"encoding/json"
55
"testing"
66

77
"github.com/stretchr/testify/assert"
88
)
99

1010
// TestUnmarshalAccount tests that Account objects unmarshal correctly
1111
func TestUnmarshalAccount(t *testing.T) {
12-
originalXML := `<?xml version="1.0" encoding="utf-8"?>
13-
<account>
14-
<credits>22465.536</credits>
15-
<username>foobar</username>
16-
</account>`
12+
originalJSON := `
13+
{
14+
"account": {
15+
"credits": 9972.2324,
16+
"username": "username"
17+
}
18+
}
19+
`
1720

1821
account := Account{}
19-
err := xml.Unmarshal([]byte(originalXML), &account)
20-
assert.Nil(t, err)
21-
assert.Equal(t, 22465.536, account.Credits)
22-
assert.Equal(t, "foobar", account.UserName)
22+
err := json.Unmarshal([]byte(originalJSON), &account)
23+
assert.NoError(t, err)
24+
assert.Equal(t, 9972.2324, account.Credits)
25+
assert.Equal(t, "username", account.UserName)
2326
}

upcloud/client/client.go

Lines changed: 4 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,6 @@ func (c *Client) CreateRequestURL(location string) string {
6868
return fmt.Sprintf("%s%s", c.getBaseURL(), location)
6969
}
7070

71-
// PerformGetRequest performs a GET request to the specified URL and returns the response body and eventual errors
72-
func (c *Client) PerformGetRequest(url string) ([]byte, error) {
73-
request, err := http.NewRequest(http.MethodGet, url, nil)
74-
75-
if err != nil {
76-
return nil, err
77-
}
78-
79-
return c.performRequest(request)
80-
}
81-
8271
// PerformJSONGetRequest performs a GET request to the specified URL and returns the response body and eventual errors
8372
func (c *Client) PerformJSONGetRequest(url string) ([]byte, error) {
8473
request, err := http.NewRequest(http.MethodGet, url, nil)
@@ -90,23 +79,6 @@ func (c *Client) PerformJSONGetRequest(url string) ([]byte, error) {
9079
return c.performJSONRequest(request)
9180
}
9281

93-
// PerformPostRequest performs a POST request to the specified URL and returns the response body and eventual errors
94-
func (c *Client) PerformPostRequest(url string, requestBody []byte) ([]byte, error) {
95-
var bodyReader io.Reader
96-
97-
if requestBody != nil {
98-
bodyReader = bytes.NewBuffer(requestBody)
99-
}
100-
101-
request, err := http.NewRequest(http.MethodPost, url, bodyReader)
102-
103-
if err != nil {
104-
return nil, err
105-
}
106-
107-
return c.performRequest(request)
108-
}
109-
11082
// PerformJSONPostRequest performs a POST request to the specified URL and returns the response body and eventual errors
11183
func (c *Client) PerformJSONPostRequest(url string, requestBody []byte) ([]byte, error) {
11284
var bodyReader io.Reader
@@ -124,33 +96,21 @@ func (c *Client) PerformJSONPostRequest(url string, requestBody []byte) ([]byte,
12496
return c.performJSONRequest(request)
12597
}
12698

127-
// PerformPutRequest performs a PUT request to the specified URL and returns the response body and eventual errors
128-
func (c *Client) PerformPutRequest(url string, requestBody []byte) ([]byte, error) {
99+
// PerformJSONPutRequest performs a PUT request to the specified URL and returns the response body and eventual errors
100+
func (c *Client) PerformJSONPutRequest(url string, requestBody []byte) ([]byte, error) {
129101
var bodyReader io.Reader
130102

131103
if requestBody != nil {
132104
bodyReader = bytes.NewBuffer(requestBody)
133105
}
134106

135-
request, err := http.NewRequest("PUT", url, bodyReader)
107+
request, err := http.NewRequest(http.MethodPut, url, bodyReader)
136108

137109
if err != nil {
138110
return nil, err
139111
}
140112

141-
return c.performRequest(request)
142-
}
143-
144-
// PerformDeleteRequest performs a DELETE request to the specified URL and returns the response body and eventual errors
145-
func (c *Client) PerformDeleteRequest(url string) error {
146-
request, err := http.NewRequest(http.MethodDelete, url, nil)
147-
148-
if err != nil {
149-
return err
150-
}
151-
152-
_, err = c.performRequest(request)
153-
return err
113+
return c.performJSONRequest(request)
154114
}
155115

156116
// PerformJSONDeleteRequest performs a DELETE request to the specified URL and returns the response body and eventual errors
@@ -165,15 +125,6 @@ func (c *Client) PerformJSONDeleteRequest(url string) error {
165125
return err
166126
}
167127

168-
// Adds common headers to the specified request
169-
func (c *Client) addRequestHeaders(request *http.Request) *http.Request {
170-
request.SetBasicAuth(c.userName, c.password)
171-
request.Header.Add("Accept", "application/xml")
172-
request.Header.Add("Content-Type", "application/xml")
173-
174-
return request
175-
}
176-
177128
// Adds common headers to the specified request
178129
func (c *Client) addJSONRequestHeaders(request *http.Request) *http.Request {
179130
request.SetBasicAuth(c.userName, c.password)
@@ -183,18 +134,6 @@ func (c *Client) addJSONRequestHeaders(request *http.Request) *http.Request {
183134
return request
184135
}
185136

186-
// Performs the specified HTTP request and returns the response through handleResponse()
187-
func (c *Client) performRequest(request *http.Request) ([]byte, error) {
188-
c.addRequestHeaders(request)
189-
response, err := c.httpClient.Do(request)
190-
191-
if err != nil {
192-
return nil, err
193-
}
194-
195-
return handleResponse(response)
196-
}
197-
198137
// Performs the specified HTTP request and returns the response through handleResponse()
199138
func (c *Client) performJSONRequest(request *http.Request) ([]byte, error) {
200139
c.addJSONRequestHeaders(request)

upcloud/error.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import (
77

88
// Error represents an error
99
type Error struct {
10-
ErrorCode string `xml:"error_code" json:"error_code"`
11-
ErrorMessage string `xml:"error_message" json:"error_message"`
10+
ErrorCode string `json:"error_code"`
11+
ErrorMessage string `json:"error_message"`
1212
}
1313

14+
// UnmarshalJSON is a custom unmarshaller that deals with
15+
// deeply embedded values.
1416
func (e *Error) UnmarshalJSON(b []byte) error {
1517
type localError Error
1618
v := struct {

upcloud/firewall.go

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package upcloud
22

3+
import "encoding/json"
4+
35
// Constants
46
const (
57
FirewallRuleActionAccept = "accept"
@@ -16,24 +18,65 @@ const (
1618

1719
// FirewallRules represents a list of firewall rules
1820
type FirewallRules struct {
19-
FirewallRules []FirewallRule `xml:"firewall_rule"`
21+
FirewallRules []FirewallRule `json:"firewall_rules"`
22+
}
23+
24+
// UnmarshalJSON is a custom unmarshaller that deals with
25+
// deeply embedded values.
26+
func (s *FirewallRules) UnmarshalJSON(b []byte) error {
27+
type localFirewallRule FirewallRule
28+
type firewallRuleWrapper struct {
29+
FirewallRules []localFirewallRule `json:"firewall_rule"`
30+
}
31+
32+
v := struct {
33+
FirewallRules firewallRuleWrapper `json:"firewall_rules"`
34+
}{}
35+
err := json.Unmarshal(b, &v)
36+
if err != nil {
37+
return err
38+
}
39+
40+
for _, f := range v.FirewallRules.FirewallRules {
41+
s.FirewallRules = append(s.FirewallRules, FirewallRule(f))
42+
}
43+
44+
return nil
2045
}
2146

2247
// FirewallRule represents a single firewall rule. Note that most integer values are represented as strings
2348
type FirewallRule struct {
24-
Action string `xml:"action"`
25-
Comment string `xml:"comment,omitempty"`
26-
DestinationAddressStart string `xml:"destination_address_start,omitempty"`
27-
DestinationAddressEnd string `xml:"destination_address_end,omitempty"`
28-
DestinationPortStart string `xml:"destination_port_start,omitempty"`
29-
DestinationPortEnd string `xml:"destination_port_end,omitempty"`
30-
Direction string `xml:"direction"`
31-
Family string `xml:"family"`
32-
ICMPType string `xml:"icmp_type,omitempty"`
33-
Position int `xml:"position"`
34-
Protocol string `xml:"protocol,omitempty"`
35-
SourceAddressStart string `xml:"source_address_start,omitempty"`
36-
SourceAddressEnd string `xml:"source_address_end,omitempty"`
37-
SourcePortStart string `xml:"source_port_start,omitempty"`
38-
SourcePortEnd string `xml:"source_port_end,omitempty"`
49+
Action string `json:"action"`
50+
Comment string `json:"comment,omitempty"`
51+
DestinationAddressStart string `json:"destination_address_start,omitempty"`
52+
DestinationAddressEnd string `json:"destination_address_end,omitempty"`
53+
DestinationPortStart string `json:"destination_port_start,omitempty"`
54+
DestinationPortEnd string `json:"destination_port_end,omitempty"`
55+
Direction string `json:"direction"`
56+
Family string `json:"family"`
57+
ICMPType string `json:"icmp_type,omitempty"`
58+
Position int `json:"position,string"`
59+
Protocol string `json:"protocol,omitempty"`
60+
SourceAddressStart string `json:"source_address_start,omitempty"`
61+
SourceAddressEnd string `json:"source_address_end,omitempty"`
62+
SourcePortStart string `json:"source_port_start,omitempty"`
63+
SourcePortEnd string `json:"source_port_end,omitempty"`
64+
}
65+
66+
// UnmarshalJSON is a custom unmarshaller that deals with
67+
// deeply embedded values.
68+
func (s *FirewallRule) UnmarshalJSON(b []byte) error {
69+
type localFirewallRule FirewallRule
70+
71+
v := struct {
72+
FirewallRule localFirewallRule `json:"firewall_rule"`
73+
}{}
74+
err := json.Unmarshal(b, &v)
75+
if err != nil {
76+
return err
77+
}
78+
79+
(*s) = FirewallRule(v.FirewallRule)
80+
81+
return nil
3982
}

0 commit comments

Comments
 (0)