Skip to content

Commit

Permalink
Implement NewHTTPRequestFromEvents
Browse files Browse the repository at this point in the history
Now you can send batch events with your very own http.Client.

Signed-off-by: Mark Mandel <markmandel@google.com>
  • Loading branch information
markmandel committed Jan 7, 2023
1 parent e9cfad8 commit 5361386
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 2 deletions.
1 change: 1 addition & 0 deletions v2/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ var (
NewEventFromHTTPResponse = http.NewEventFromHTTPResponse
NewEventsFromHTTPRequest = http.NewEventsFromHTTPRequest
NewEventsFromHTTPResponse = http.NewEventsFromHTTPResponse
NewHTTPRequestFromEvents = http.NewHTTPRequestFromEvents

// HTTP Messages

Expand Down
26 changes: 26 additions & 0 deletions v2/protocol/http/utility.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
package http

import (
"bytes"
"context"
"encoding/json"
nethttp "net/http"

"github.com/cloudevents/sdk-go/v2/binding"
Expand Down Expand Up @@ -36,3 +38,27 @@ func NewEventsFromHTTPResponse(resp *nethttp.Response) ([]event.Event, error) {
msg := NewMessageFromHttpResponse(resp)
return binding.ToEvents(context.Background(), msg, msg.BodyReader)
}

// NewHTTPRequestFromEvents creates a http.Request object that can be used with any http.Client.
func NewHTTPRequestFromEvents(ctx context.Context, url string, events []event.Event) (*nethttp.Request, error) {
// Sending batch events is quite straightforward, as there is only JSON format, so a simple implementation.
for _, e := range events {
if err := e.Validate(); err != nil {
return nil, err
}
}
var buffer bytes.Buffer
err := json.NewEncoder(&buffer).Encode(events)
if err != nil {
return nil, err
}

request, err := nethttp.NewRequestWithContext(ctx, nethttp.MethodPost, url, &buffer)
if err != nil {
return nil, err
}

request.Header.Set(ContentType, event.ApplicationCloudEventsBatchJSON)

return request, nil
}
43 changes: 41 additions & 2 deletions v2/protocol/http/utility_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import (
"net/http/httptest"
"testing"

"github.com/stretchr/testify/require"

"github.com/cloudevents/sdk-go/v2/binding"
"github.com/cloudevents/sdk-go/v2/event"
"github.com/cloudevents/sdk-go/v2/test"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
)

func TestNewEventFromHttpRequest(t *testing.T) {
Expand Down Expand Up @@ -115,3 +115,42 @@ func TestNewEventsFromHTTPResponse(t *testing.T) {
require.Len(t, events, 1)
test.AssertEvent(t, events[0], test.IsValid())
}

func TestNewHTTPRequestFromEvents(t *testing.T) {
var events []event.Event
e := event.New()
e.SetID(uuid.New().String())
e.SetSource("example/uri")
e.SetType("example.type")
require.NoError(t, e.SetData(event.ApplicationJSON, map[string]string{"hello": "world"}))
events = append(events, e.Clone())

e.SetID(uuid.New().String())
require.NoError(t, e.SetData(event.ApplicationJSON, map[string]string{"goodbye": "world"}))
events = append(events, e)

require.Len(t, events, 2)
require.NotEqual(t, events[0], events[1])

// echo back what we get, so we can compare events at either side.
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set(ContentType, r.Header.Get(ContentType))
b, err := io.ReadAll(r.Body)
require.NoError(t, err)
require.NoError(t, r.Body.Close())
_, err = w.Write(b)
require.NoError(t, err)
}))
defer ts.Close()

req, err := NewHTTPRequestFromEvents(context.Background(), ts.URL, events)
require.NoError(t, err)

resp, err := ts.Client().Do(req)
require.NoError(t, err)

result, err := NewEventsFromHTTPResponse(resp)
require.NoError(t, err)

require.Equal(t, events, result)
}

0 comments on commit 5361386

Please sign in to comment.