Skip to content

Commit

Permalink
Add openexchangerates api
Browse files Browse the repository at this point in the history
  • Loading branch information
meabed committed Sep 29, 2018
1 parent eebda8a commit db246fe
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 2 deletions.
3 changes: 3 additions & 0 deletions cmd/server/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ var Convert = func(w http.ResponseWriter, r *http.Request) {
case `themoneyconverter`:
e = ex.NewTheMoneyConverterApi(opt)
break
case `openexchangerates`:
e = ex.NewOpenExchangeRatesApi(opt)
break
}
Swap.AddExchanger(e)
}
Expand Down
127 changes: 126 additions & 1 deletion pkg/exchanger/openexchangerates.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,128 @@
package exchanger

//todo
import (
"fmt"
"github.com/bitly/go-simplejson"
"io/ioutil"
"log"
"net"
"net/http"
"time"
)

type openExchangeRatesApi struct {
attributes
}

var (
openExchangeRatesApiUrl = `https://openexchangerates.org/api/convert/1/%s/%s?app_id=%s`
openExchangeRatesApiHeaders = map[string][]string{
`Accept`: {`text/html,application/xhtml+xml,application/xml,application/json`},
`Accept-Encoding`: {`text`},
}
)

func (c *openExchangeRatesApi) requestRate(from string, to string, opt ...interface{}) (*openExchangeRatesApi, error) {

// todo add option opt to add more headers or client configurations
// free mem-leak
// optimize for memory leak
// todo optimize curl connection

url := fmt.Sprintf(openExchangeRatesApiUrl, c.apiKey, from, to)
req, _ := http.NewRequest("GET", url, nil)

openExchangeRatesApiHeaders[`User-Agent`] = []string{c.userAgent}
req.Header = openExchangeRatesApiHeaders

res, err := c.Client.Do(req)

if err != nil {
return nil, err
}
defer res.Body.Close()

body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}

// free mem-leak
// todo discard data
c.responseBody = string(body)
return c, nil
}

func (c *openExchangeRatesApi) GetValue() float64 {
return c.rateValue
}

func (c *openExchangeRatesApi) GetDateTime() string {
return c.rateDate.Format(time.RFC3339)
}

func (c *openExchangeRatesApi) GetExchangerName() string {
return c.name
}

func (c *openExchangeRatesApi) Latest(from string, to string, opt ...interface{}) error {

_, err := c.requestRate(from, to, opt)
if err != nil {
log.Print(err)
return err
}

// if from currency is same as converted currency return value of 1
if from == to {
c.rateValue = 1
return nil
}

json, err := simplejson.NewJson([]byte(c.responseBody))

if err != nil {
log.Print(err)
return err
}

// opening price
value := json.GetPath(`response`).
MustFloat64()
// todo handle error
c.rateValue = value
c.rateDate = time.Now()
return nil
}

func NewOpenExchangeRatesApi(opt map[string]string) *openExchangeRatesApi {
keepAliveTimeout := 600 * time.Second
timeout := 5 * time.Second
defaultTransport := &http.Transport{
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: keepAliveTimeout,
DualStack: true,
}).DialContext,
MaxIdleConns: 100,
MaxIdleConnsPerHost: 100,
}

client := &http.Client{
Transport: defaultTransport,
Timeout: timeout,
}

attr := attributes{
name: `openexchangerates`,
Client: client,
apiKey: opt[`apiKey`],
userAgent: `Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:21.0) Gecko/20100101 Firefox/21.0`,
}
if opt[`userAgent`] != "" {
attr.userAgent = opt[`userAgent`]
}

r := &openExchangeRatesApi{attr}
return r
}
19 changes: 18 additions & 1 deletion pkg/exchanger/openexchangerates_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
package exchanger

//todo
import (
"github.com/me-io/go-swap/test/staticMock"
"github.com/stretchr/testify/assert"
"testing"
)

func TestOpenExchangeRatesApi_Latest(t *testing.T) {
rate := NewOpenExchangeRatesApi(nil)
assert.Equal(t, rate.name, `openexchangerates`)

rate.Client.Transport = staticMock.NewTestMT()

rate.Latest(`EUR`, `EUR`)
assert.Equal(t, float64(1), rate.GetValue())

rate.Latest(`USD`, `AED`)
assert.Equal(t, float64(3.6571), rate.GetValue())
}
15 changes: 15 additions & 0 deletions test/staticMock/openexchangerates_json_aed_usd.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"disclaimer": "https://openexchangerates.org/terms/",
"license": "https://openexchangerates.org/license/",
"request": {
"query": "/convert/1/USD/AED",
"amount": 1,
"from": "USD",
"to": "AED"
},
"meta": {
"timestamp": 1449885661,
"rate": 3.6571
},
"response": 3.6571
}
5 changes: 5 additions & 0 deletions test/staticMock/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ func (t *mT) RoundTrip(req *http.Request) (*http.Response, error) {
fc, _ := ioutil.ReadFile(fp)
responseBody = string(fc)
break
case host == `openexchangerates.org`:
fp, _ := filepath.Abs(tPath + `/openexchangerates_json_aed_usd.json`)
fc, _ := ioutil.ReadFile(fp)
responseBody = string(fc)
break
default:

}
Expand Down

0 comments on commit db246fe

Please sign in to comment.