-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Andre Hahn
committed
Jun 13, 2018
1 parent
e3a7d76
commit 41f83fc
Showing
7 changed files
with
613 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,3 +33,4 @@ khan-perf.dump | |
/dev/default.yaml | ||
*.coverprofile | ||
dev/khan-linux-x86_64 | ||
*.swp |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package lib | ||
|
||
import "context" | ||
|
||
// KhanInterface defines the interface for the khan client | ||
type KhanInterface interface { | ||
CreatePlayer(context.Context, string, string, interface{}) (string, error) | ||
UpdatePlayer(context.Context, string, string, interface{}) error | ||
RetrievePlayer(context.Context, string) (*Player, error) | ||
CreateClan(context.Context, *ClanPayload) (string, error) | ||
UpdateClan(context.Context, *ClanPayload) error | ||
RetrieveClanSummary(context.Context, string) (*ClanSummary, error) | ||
RetrieveClansSummary(context.Context, []string) ([]*ClanSummary, error) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
package lib | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
"strings" | ||
"sync" | ||
|
||
"github.com/spf13/viper" | ||
) | ||
|
||
// Khan is a struct that represents a khan API application | ||
type Khan struct { | ||
httpClient *http.Client | ||
Config *viper.Viper | ||
url string | ||
user string | ||
pass string | ||
gameID string | ||
} | ||
|
||
var ( | ||
client *http.Client | ||
once sync.Once | ||
) | ||
|
||
func getHTTPClient() *http.Client { | ||
once.Do(func() { | ||
client = &http.Client{} | ||
}) | ||
return client | ||
} | ||
|
||
// NewKhan returns a new khan API application | ||
func NewKhan(config *viper.Viper) KhanInterface { | ||
k := &Khan{ | ||
httpClient: getHTTPClient(), | ||
Config: config, | ||
url: config.GetString("khan.url"), | ||
user: config.GetString("khan.user"), | ||
pass: config.GetString("khan.pass"), | ||
gameID: config.GetString("khan.gameid"), | ||
} | ||
return k | ||
} | ||
|
||
func (k *Khan) sendTo(ctx context.Context, method, url string, payload interface{}) ([]byte, error) { | ||
payloadJSON, err := json.Marshal(payload) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var req *http.Request | ||
|
||
if payload != nil { | ||
req, err = http.NewRequest(method, url, bytes.NewBuffer(payloadJSON)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} else { | ||
req, err = http.NewRequest(method, url, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
req.Header.Set("Content-Type", "application/json") | ||
req.SetBasicAuth(k.user, k.pass) | ||
if ctx == nil { | ||
ctx = context.Background() | ||
} | ||
req = req.WithContext(ctx) | ||
|
||
resp, err := k.httpClient.Do(req) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer resp.Body.Close() | ||
|
||
body, respErr := ioutil.ReadAll(resp.Body) | ||
if respErr != nil { | ||
return nil, respErr | ||
} | ||
|
||
if resp.StatusCode > 399 { | ||
return nil, newRequestError(resp.StatusCode, string(body)) | ||
} | ||
|
||
return body, nil | ||
} | ||
|
||
func (k *Khan) buildURL(pathname string) string { | ||
return fmt.Sprintf("%s/games/%s/%s", k.url, k.gameID, pathname) | ||
} | ||
|
||
func (k *Khan) buildCreatePlayerURL() string { | ||
pathname := "players" | ||
return k.buildURL(pathname) | ||
} | ||
|
||
func (k *Khan) buildUpdatePlayerURL(playerID string) string { | ||
pathname := fmt.Sprintf("players/%s", playerID) | ||
return k.buildURL(pathname) | ||
} | ||
|
||
func (k *Khan) buildRetrievePlayerURL(playerID string) string { | ||
pathname := fmt.Sprintf("players/%s", playerID) | ||
return k.buildURL(pathname) | ||
} | ||
|
||
func (k *Khan) buildCreateClanURL() string { | ||
pathname := "clans" | ||
return k.buildURL(pathname) | ||
} | ||
|
||
func (k *Khan) buildUpdateClanURL(clanID string) string { | ||
pathname := fmt.Sprintf("clans/%s", clanID) | ||
return k.buildURL(pathname) | ||
} | ||
|
||
func (k *Khan) buildRetrieveClanSummaryURL(clanID string) string { | ||
pathname := fmt.Sprintf("clans/%s/summary", clanID) | ||
return k.buildURL(pathname) | ||
} | ||
|
||
func (k *Khan) buildRetrieveClansSummaryURL(clanIDs []string) string { | ||
pathname := fmt.Sprintf("clans-summary?clanPublicIds=%s", strings.Join(clanIDs, ",")) | ||
return k.buildURL(pathname) | ||
} | ||
|
||
// CreatePlayer calls Khan to create a new player | ||
func (k *Khan) CreatePlayer(ctx context.Context, publicID, name string, metadata interface{}) (string, error) { | ||
route := k.buildCreatePlayerURL() | ||
playerPayload := &Player{ | ||
PublicID: publicID, | ||
Name: name, | ||
Metadata: metadata, | ||
} | ||
body, err := k.sendTo(ctx, "POST", route, playerPayload) | ||
|
||
if err != nil { | ||
return "", err | ||
} | ||
|
||
var player Player | ||
err = json.Unmarshal(body, &player) | ||
|
||
return player.PublicID, err | ||
} | ||
|
||
// UpdatePlayer calls khan to update the player | ||
func (k *Khan) UpdatePlayer(ctx context.Context, publicID, name string, metadata interface{}) error { | ||
route := k.buildUpdatePlayerURL(publicID) | ||
playerPayload := &Player{ | ||
Name: name, | ||
Metadata: metadata, | ||
} | ||
_, err := k.sendTo(ctx, "PUT", route, playerPayload) | ||
return err | ||
} | ||
|
||
// RetrievePlayer calls the retrieve player route from khan | ||
func (k *Khan) RetrievePlayer(ctx context.Context, publicID string) (*Player, error) { | ||
route := k.buildRetrievePlayerURL(publicID) | ||
body, err := k.sendTo(ctx, "GET", route, nil) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var player Player | ||
err = json.Unmarshal(body, &player) | ||
return &player, err | ||
} | ||
|
||
// CreateClan calls the create clan route from khan | ||
func (k *Khan) CreateClan(ctx context.Context, clan *ClanPayload) (string, error) { | ||
route := k.buildCreateClanURL() | ||
body, err := k.sendTo(ctx, "POST", route, clan) | ||
|
||
if err != nil { | ||
return "", err | ||
} | ||
|
||
var player Player | ||
err = json.Unmarshal(body, &player) | ||
return player.PublicID, err | ||
} | ||
|
||
// UpdateClan calls the update clan route from khan | ||
func (k *Khan) UpdateClan(ctx context.Context, clan *ClanPayload) error { | ||
route := k.buildUpdateClanURL(clan.PublicID) | ||
_, err := k.sendTo(ctx, "PUT", route, clan) | ||
return err | ||
} | ||
|
||
// RetrieveClanSummary calls the route to retrieve clan summary from khan | ||
func (k *Khan) RetrieveClanSummary(ctx context.Context, clanID string) (*ClanSummary, error) { | ||
route := k.buildRetrieveClanSummaryURL(clanID) | ||
body, err := k.sendTo(ctx, "GET", route, nil) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var clanSummary ClanSummary | ||
err = json.Unmarshal(body, &clanSummary) | ||
return &clanSummary, err | ||
} | ||
|
||
// RetrieveClansSummary calls the route to retrieve clans summary from khan | ||
func (k *Khan) RetrieveClansSummary(ctx context.Context, clanIDs []string) ([]*ClanSummary, error) { | ||
route := k.buildRetrieveClansSummaryURL(clanIDs) | ||
body, err := k.sendTo(ctx, "GET", route, nil) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var clansSummary ClansSummary | ||
err = json.Unmarshal(body, &clansSummary) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return clansSummary.Clans, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package lib_test | ||
|
||
import ( | ||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
|
||
"testing" | ||
) | ||
|
||
func TestLib(t *testing.T) { | ||
RegisterFailHandler(Fail) | ||
RunSpecs(t, "Lib Suite") | ||
} |
Oops, something went wrong.