-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract Flume client to a separate package
refs #35 This is the first step to split the single client to independent Avro and Flume clients.
- Loading branch information
Showing
8 changed files
with
249 additions
and
149 deletions.
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
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
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,59 @@ | ||
package flume | ||
|
||
import ( | ||
"github.com/myzhan/avroipc" | ||
) | ||
|
||
// An avro client implementation | ||
type Client interface { | ||
Close() error | ||
Append(event *Event) (string, error) | ||
AppendBatch(events []*Event) (string, error) | ||
} | ||
|
||
type client struct { | ||
client avroipc.Client | ||
} | ||
|
||
// NewClient creates an avro client with default option values and | ||
// connects to the specified remote Flume endpoint immediately. | ||
// | ||
// Very useful for the testing purposes and to build simple examples. | ||
func NewClient(addr string) (Client, error) { | ||
return NewClientWithConfig(addr, avroipc.NewConfig()) | ||
} | ||
|
||
// NewClient creates an avro client with considering values of options from | ||
// the passed configuration object and connects to the specified remote Flume | ||
// endpoint immediately. | ||
// | ||
// This constructor supposed to be used in production environments. | ||
func NewClientWithConfig(addr string, config *avroipc.Config) (Client, error) { | ||
c, err := avroipc.NewClientWithConfig(addr, config) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &client{c}, nil | ||
} | ||
|
||
// Append sends event to flume | ||
func (c *client) Append(event *Event) (string, error) { | ||
datum := event.toMap() | ||
|
||
return c.client.SendMessage("append", datum) | ||
} | ||
|
||
// Append sends events to flume | ||
func (c *client) AppendBatch(events []*Event) (string, error) { | ||
datum := make([]map[string]interface{}, 0) | ||
for _, event := range events { | ||
datum = append(datum, event.toMap()) | ||
} | ||
|
||
return c.client.SendMessage("appendBatch", datum) | ||
} | ||
|
||
func (c *client) Close() error { | ||
return c.client.Close() | ||
} |
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,86 @@ | ||
package flume | ||
|
||
import ( | ||
"errors" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/myzhan/avroipc/flume/mocks" | ||
) | ||
|
||
func prepare() (*client, *mocks.MockClient) { | ||
x := &mocks.MockClient{} | ||
|
||
c := &client{ | ||
client: x, | ||
} | ||
|
||
return c, x | ||
} | ||
|
||
func TestClient_Close(t *testing.T) { | ||
testErr := errors.New("test error") | ||
|
||
t.Run("succeed", func(t *testing.T) { | ||
c, x := prepare() | ||
|
||
x.On("Close").Return(nil).Once() | ||
|
||
err := c.Close() | ||
require.NoError(t, err) | ||
x.AssertExpectations(t) | ||
}) | ||
|
||
t.Run("client error", func(t *testing.T) { | ||
c, x := prepare() | ||
|
||
x.On("Close").Return(testErr).Once() | ||
|
||
err := c.Close() | ||
require.EqualError(t, err, "test error") | ||
x.AssertExpectations(t) | ||
}) | ||
} | ||
|
||
func TestClient_Append(t *testing.T) { | ||
method := "append" | ||
|
||
origEvent := &Event{Headers: map[string]string{}, Body: []byte("test body")} | ||
prepEvent := origEvent.toMap() | ||
|
||
t.Run("succeed", func(t *testing.T) { | ||
c, x := prepare() | ||
|
||
x.On("SendMessage", method, prepEvent).Return("SOME", nil).Once() | ||
|
||
status, err := c.Append(origEvent) | ||
require.NoError(t, err) | ||
require.Equal(t, "SOME", status) | ||
x.AssertExpectations(t) | ||
}) | ||
} | ||
|
||
func TestClient_AppendBatch(t *testing.T) { | ||
method := "appendBatch" | ||
|
||
origEvents := []*Event{ | ||
{Headers: map[string]string{}, Body: []byte("test body 1")}, | ||
{Headers: map[string]string{}, Body: []byte("test body 2")}, | ||
} | ||
prepEvents := []map[string]interface{}{ | ||
origEvents[0].toMap(), | ||
origEvents[1].toMap(), | ||
} | ||
|
||
t.Run("succeed", func(t *testing.T) { | ||
c, x := prepare() | ||
|
||
x.On("SendMessage", method, prepEvents).Return("SOME", nil).Once() | ||
|
||
status, err := c.AppendBatch(origEvents) | ||
require.NoError(t, err) | ||
require.Equal(t, "SOME", status) | ||
x.AssertExpectations(t) | ||
}) | ||
} |
Oops, something went wrong.