Skip to content

Commit

Permalink
feat: adds Makefile for build, using cmd directory and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
klassmann committed Aug 15, 2019
1 parent b6b787e commit c8d04d0
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 75 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@

# Output of the go coverage tool, specifically when used with LiteIDE
*.out
dist
36 changes: 36 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

all: clean win_64 win_32 linux_64 linux_32 darwin_64 darwin_32 freebsd_64 freebsd_32

win_64:
env GOOS=windows GOARCH=amd64 go build -o "dist/pubsub-push.exe" ./cmd/pubsub-push
zip -T -j -9 "dist/pubsub-push_$(shell cat VERSION)_$@.zip" dist/pubsub-push.exe
rm -f dist/pubsub-push.exe

win_32:
env GOOS=windows GOARCH=386 go build -o "dist/pubsub-push.exe" ./cmd/pubsub-push
zip -T -j -9 "dist/pubsub-push_$(shell cat VERSION)_$@.zip" dist/pubsub-push.exe
rm -f dist/pubsub-push.exe

linux_64:
env GOOS=linux GOARCH=amd64 go build -o dist/pubsub-push ./cmd/pubsub-push
gzip dist/pubsub-push -c > "dist/pubsub-push_$(shell cat VERSION)_$@.gz"
rm -f dist/pubsub-push

linux_32:
env GOOS=linux GOARCH=386 go build -o dist/pubsub-push ./cmd/pubsub-push
gzip dist/pubsub-push -c > "dist/pubsub-push_$(shell cat VERSION)_$@.gz"
rm -f dist/pubsub-push

darwin_64:
env GOOS=darwin GOARCH=amd64 go build -o dist/pubsub-push ./cmd/pubsub-push
gzip dist/pubsub-push -c > "dist/pubsub-push_$(shell cat VERSION)_$@.gz"
rm -f dist/pubsub-push

darwin_32:
env GOOS=darwin GOARCH=386 go build -o dist/pubsub-push ./cmd/pubsub-push
gzip dist/pubsub-push -c > "dist/pubsub-push_$(shell cat VERSION)_$@.gz"
rm -f dist/pubsub-push

clean:
rm -rf dist/*

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ $ pubsub-push -project proj-id -sub name -endpoint localhost -header "Content-ty
-endpoint The complete URL, including schema, domain, port and the path.
Eg: -endpoint http://localhost:5000/services/sync
-header An string like "key=value" for request headers. It can be used
-header A string like "key=value" for request headers. It can be used
multiplem times.
Eg: -header "Content-type=application/json"
```
Expand Down
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.1
78 changes: 4 additions & 74 deletions main.go → cmd/pubsub-push/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,84 +3,25 @@ package main
import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"flag"
"fmt"
"io"
"log"
"net/http"
"os"
"strings"

"cloud.google.com/go/pubsub"
push "github.com/klassmann/pubsub-push"
)

const (
credentialsVarName string = "GOOGLE_APPLICATION_CREDENTIALS"
messageMimetype string = "application/json"
)

type headers []string

func (h *headers) String() string {
b := strings.Builder{}

for _, v := range *h {
b.WriteString(v)
}

return b.String()
}

func (h *headers) Set(value string) error {
*h = append(*h, value)
return nil
}

func (h *headers) applyHeaders(ht *http.Request) {
for _, v := range *h {
parts := strings.Split(v, "=")

if len(parts) == 2 {
ht.Header.Set(parts[0], parts[1])
} else if len(parts) == 1 {
ht.Header.Set(parts[0], "")
}
}
}

type settings struct {
ProjectID string
Subscription string
Endpoint string
Headers headers
}

type message struct {
MessageID string `json:"messageId"`
Data string `json:"data"`
Attributes map[string]string `json:"attributes"`
}

type request struct {
Message message `json:"message"`
}

func encodeMessage(m *pubsub.Message) ([]byte, int) {
data := m.Data
req := request{}
req.Message.Data = base64.StdEncoding.EncodeToString(data)
req.Message.Attributes = m.Attributes
req.Message.MessageID = m.ID
b, err := json.Marshal(req)

if err != nil {
log.Fatal(err)
return []byte{}, 0
}

return b, len(b)
Headers push.Headers
}

func getArguments() *settings {
Expand All @@ -100,17 +41,6 @@ func getArguments() *settings {
return &s
}

func post(url string, contentType string, body io.Reader, h *headers) (*http.Response, error) {
req, err := http.NewRequest("POST", url, body)
if err != nil {
log.Fatalf("I was not possible to create a new request: %v\n", err)
return nil, err
}
req.Header.Set("Content-type", contentType)
h.applyHeaders(req)
return http.DefaultClient.Do(req)
}

func main() {
settings := getArguments()

Expand All @@ -131,10 +61,10 @@ func main() {
fmt.Printf("Listening subscription %s:\n", settings.Subscription)
sub := client.Subscription(settings.Subscription)
err = sub.Receive(ctx, func(ctx context.Context, m *pubsub.Message) {
b, size := encodeMessage(m)
b, size := push.EncodeMessage(m)
buff := bytes.NewBuffer(b)

resp, err := post(settings.Endpoint, messageMimetype, buff, &settings.Headers) //http.Post(settings.Endpoint, messageMimetype, buff)
resp, err := push.PostMessage(settings.Endpoint, messageMimetype, buff, &settings.Headers)

if err != nil {
log.Fatalf("Error on send message to endpoint: %v\n", err)
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ go 1.12
require (
cloud.google.com/go v0.43.0
github.com/hashicorp/golang-lru v0.5.3 // indirect
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 // indirect
golang.org/x/arch v0.0.0-20190312162104-788fe5ffcd8c // indirect
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 // indirect
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 // indirect
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f h1:Jnx61latede7zDD3DiiP4gmNz33uK0U5HDUaF0a/HVQ=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
Expand All @@ -31,11 +32,16 @@ github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
golang.org/x/arch v0.0.0-20190312162104-788fe5ffcd8c h1:Rx/HTKi09myZ25t1SOlDHmHOy/mKxNAcu0hP1oPX9qM=
golang.org/x/arch v0.0.0-20190312162104-788fe5ffcd8c/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
Expand Down Expand Up @@ -96,6 +102,7 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0 h1:9sdfJOzWlkqPltHAuzT2Cp+yrBeY1KRVYgms8soxMwM=
Expand Down Expand Up @@ -125,3 +132,4 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
83 changes: 83 additions & 0 deletions pubsubpush.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package pubsubpush

import (
"encoding/base64"
"encoding/json"
"io"
"log"
"net/http"
"strings"

"cloud.google.com/go/pubsub"
)

type message struct {
MessageID string `json:"messageId"`
Data string `json:"data"`
Attributes map[string]string `json:"attributes"`
}

type request struct {
Message message `json:"message"`
}

// Headers is the list of HTTP Header to be applied on Request
type Headers []string

func (h *Headers) String() string {
b := strings.Builder{}

for _, v := range *h {
b.WriteString(v)
}

return b.String()
}

// Set appends a new Header
func (h *Headers) Set(value string) error {
*h = append(*h, value)
return nil
}

func (h *Headers) applyHeaders(ht *http.Request) {
for _, v := range *h {
parts := strings.Split(v, "=")

if len(parts) == 2 {
ht.Header.Set(parts[0], parts[1])
} else if len(parts) == 1 {
ht.Header.Set(parts[0], "")
}
}
}

// EncodeMessage prepares the message to be like the HTTP Push from PubSub
// It is an JSON with a data field containing a base64 value
func EncodeMessage(m *pubsub.Message) ([]byte, int) {
data := m.Data
req := request{}
req.Message.Data = base64.StdEncoding.EncodeToString(data)
req.Message.Attributes = m.Attributes
req.Message.MessageID = m.ID
b, err := json.Marshal(req)

if err != nil {
log.Fatal(err)
return []byte{}, 0
}

return b, len(b)
}

// PostMessage sends the the message to endpoint
func PostMessage(url string, contentType string, body io.Reader, h *Headers) (*http.Response, error) {
req, err := http.NewRequest("POST", url, body)
if err != nil {
log.Fatalf("I was not possible to create a new request: %v\n", err)
return nil, err
}
req.Header.Set("Content-type", contentType)
h.applyHeaders(req)
return http.DefaultClient.Do(req)
}
35 changes: 35 additions & 0 deletions pubsubpush_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package pubsubpush

import "testing"

func TestHeadersSet(t *testing.T) {
h := Headers{}
h.Set("Content-type=application/json")
h.Set("Auth=api-key")

if len(h) != 2 {
t.Errorf("Len expected 2 and got %d", len(h))
}

if h[0] != "Content-type=application/json" {
t.Errorf("Expected value %s and got %s", "Content-type=application/json", h[0])
}

if h[1] != "Auth=api-key" {
t.Errorf("Expected value %s and got %s", "Auth=api-key", h[1])
}
}

func TestHeadersString(t *testing.T) {
h := Headers{}
h.Set("Content-type=application/json")

if len(h) != 1 {
t.Errorf("Len expected 2 and got %d", len(h))
}

if h.String() != "Content-type=application/json" {
t.Errorf("Expected value %s and got %s", "Content-type=application/json", h.String())
}

}

0 comments on commit c8d04d0

Please sign in to comment.