Skip to content

Commit

Permalink
added client package
Browse files Browse the repository at this point in the history
  • Loading branch information
draganm committed Jan 30, 2023
1 parent 9750213 commit de977be
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 46 deletions.
62 changes: 26 additions & 36 deletions server/integration_sate_test.go → client/client.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package server_test
package client

import (
"bytes"
Expand All @@ -11,35 +11,29 @@ import (
"strconv"
)

type StateKeyType string
type Client struct {
eventsURL *url.URL
}

const stateKey = StateKeyType("")
func New(baseURL string) (*Client, error) {
u, err := url.Parse(baseURL)
if err != nil {
return nil, fmt.Errorf("could not parse base URL: %w", err)
}
eventsURL := u.JoinPath("events")

type eventsOrError struct {
events []string
err error
}
return &Client{eventsURL: eventsURL}, nil

type State struct {
serverBaseURL string
pollResult []string
secondPollResult []string
longPollResult chan eventsOrError
lastId string
}

func (s *State) sendEvents(ctx context.Context, events []any) error {
u, err := url.JoinPath(s.serverBaseURL, "events")
if err != nil {
return fmt.Errorf("could not join url path: %w", err)
}
func (c *Client) SendEvents(ctx context.Context, events []any) error {

d, err := json.Marshal(events)
if err != nil {
return fmt.Errorf("could not marshal events: %w", err)
}

req, err := http.NewRequestWithContext(ctx, "POST", u, bytes.NewReader(d))
req, err := http.NewRequestWithContext(ctx, "POST", c.eventsURL.String(), bytes.NewReader(d))
if err != nil {
return fmt.Errorf("could not create request: %w", err)
}
Expand Down Expand Up @@ -90,39 +84,35 @@ func (e *event) UnmarshalJSON(p []byte) error {
return nil
}

func (s *State) pollForEvents(ctx context.Context, evts any, lastID string, limit int) (string, error) {
func (c *Client) PollForEvents(ctx context.Context, lastID string, limit int, evts any) ([]string, error) {
uc := *c.eventsURL

u, err := url.Parse(s.serverBaseURL)
if err != nil {
return "", fmt.Errorf("could not parse url: %w", err)
}

u = u.JoinPath("events")
u := &uc
q := u.Query()
q.Set("limit", strconv.FormatInt(int64(limit), 10))
q.Set("after", lastID)
u.RawQuery = q.Encode()
req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil)
if err != nil {
return "", fmt.Errorf("could not create request: %w", err)
return nil, fmt.Errorf("could not create request: %w", err)
}

res, err := http.DefaultClient.Do(req)
if err != nil {
return "", fmt.Errorf("could not perform request: %w", err)
return nil, fmt.Errorf("could not perform request: %w", err)
}

defer res.Body.Close()

if res.StatusCode != http.StatusOK {
rd, _ := io.ReadAll(res.Body)
return "", fmt.Errorf("unexpected status %s: %s", res.Status, string(rd))
return nil, fmt.Errorf("unexpected status %s: %s", res.Status, string(rd))
}

resp := []event{}
err = json.NewDecoder(res.Body).Decode(&resp)
if err != nil {
return "", fmt.Errorf("could not decode response: %w", err)
return nil, fmt.Errorf("could not decode response: %w", err)
}

payloads := make([]json.RawMessage, len(resp))
Expand All @@ -133,19 +123,19 @@ func (s *State) pollForEvents(ctx context.Context, evts any, lastID string, limi

d, err := json.Marshal(payloads)
if err != nil {
return "", fmt.Errorf("could not marshal payloads: %w", err)
return nil, fmt.Errorf("could not marshal payloads: %w", err)
}

err = json.Unmarshal(d, evts)

if err != nil {
return "", fmt.Errorf("could not unmarshal events: %w", err)
return nil, fmt.Errorf("could not unmarshal events: %w", err)
}

if len(resp) > 0 {
return resp[len(resp)-1].ID, nil
ids := make([]string, len(resp))
for i, evt := range resp {
ids[i] = evt.ID
}

return "", nil

return ids, nil
}
23 changes: 23 additions & 0 deletions server/integration_state_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package server_test

import (
"github.com/draganm/event-buffer/client"
)

type StateKeyType string

const stateKey = StateKeyType("")

type eventsOrError struct {
events []string
err error
}

type State struct {
// serverBaseURL string
client *client.Client
pollResult []string
secondPollResult []string
longPollResult chan eventsOrError
lastId string
}
32 changes: 22 additions & 10 deletions server/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"testing"

"github.com/cucumber/godog"
"github.com/draganm/event-buffer/client"
"github.com/draganm/event-buffer/server/testrig"
"github.com/go-logr/logr"
"github.com/go-logr/zapr"
Expand Down Expand Up @@ -73,7 +74,13 @@ func InitializeScenario(ctx *godog.ScenarioContext) {
if err != nil {
return ctx, fmt.Errorf("could not start server: %w", err)
}
state.serverBaseURL = serverURL

cl, err := client.New(serverURL)
if err != nil {
return ctx, fmt.Errorf("could not create client: %w", err)
}

state.client = cl

ctx = context.WithValue(ctx, stateKey, state)

Expand Down Expand Up @@ -102,7 +109,7 @@ func getState(ctx context.Context) *State {

func iSendASingleEvent(ctx context.Context) error {
s := getState(ctx)
err := s.sendEvents(ctx, []any{"evt1"})
err := s.client.SendEvents(ctx, []any{"evt1"})
if err != nil {
return err
}
Expand All @@ -116,7 +123,7 @@ func iShouldGetAConfirmation() error {

func oneEventInTheBuffer(ctx context.Context) error {
s := getState(ctx)
err := s.sendEvents(ctx, []any{"evt1"})
err := s.client.SendEvents(ctx, []any{"evt1"})
if err != nil {
return err
}
Expand All @@ -126,7 +133,7 @@ func oneEventInTheBuffer(ctx context.Context) error {
func iPollForTheEvents(ctx context.Context) error {
s := getState(ctx)
evts := []string{}
_, err := s.pollForEvents(ctx, &evts, "", 100)
_, err := s.client.PollForEvents(ctx, "", 100, &evts)
if err != nil {
return fmt.Errorf("failed polling for events: %w", err)
}
Expand All @@ -153,7 +160,7 @@ func iStartPollingForTheEvents(ctx context.Context) error {
s.longPollResult = make(chan eventsOrError, 1)
go func() {
evts := []string{}
_, err := s.pollForEvents(ctx, &evts, "", 100)
_, err := s.client.PollForEvents(ctx, "", 100, &evts)
if err != nil {
s.longPollResult <- eventsOrError{err: fmt.Errorf("failed polling for events: %w", err)}
return
Expand All @@ -166,7 +173,7 @@ func iStartPollingForTheEvents(ctx context.Context) error {

func thereIsANewEventSentToTheBuffer(ctx context.Context) error {
s := getState(ctx)
err := s.sendEvents(ctx, []any{"evt1"})
err := s.client.SendEvents(ctx, []any{"evt1"})
if err != nil {
return err
}
Expand Down Expand Up @@ -194,7 +201,7 @@ func iShouldReceiveTheNewEvent(ctx context.Context) error {

func twoEventsInTheBuffer(ctx context.Context) error {
s := getState(ctx)
err := s.sendEvents(ctx, []any{"evt1", "evt2"})
err := s.client.SendEvents(ctx, []any{"evt1", "evt2"})
if err != nil {
return err
}
Expand All @@ -204,19 +211,24 @@ func twoEventsInTheBuffer(ctx context.Context) error {
func iPollForOneEvent(ctx context.Context) error {
s := getState(ctx)
evts := []string{}
lastId, err := s.pollForEvents(ctx, &evts, "", 1)
ids, err := s.client.PollForEvents(ctx, "", 1, &evts)
if err != nil {
return fmt.Errorf("failed polling for events: %w", err)
}

if len(ids) != 1 {
return fmt.Errorf("expected 1 event, got %d", len(ids))
}

s.pollResult = evts
s.lastId = lastId
s.lastId = ids[len(ids)-1]
return nil
}

func iPollForOtherEventAfterThePreviousEvent(ctx context.Context) error {
s := getState(ctx)
evts := []string{}
_, err := s.pollForEvents(ctx, &evts, s.lastId, 1)
_, err := s.client.PollForEvents(ctx, s.lastId, 1, &evts)
if err != nil {
return fmt.Errorf("failed polling for events: %w", err)
}
Expand Down

0 comments on commit de977be

Please sign in to comment.