Skip to content

Commit 7cea001

Browse files
author
Ítalo Vietro
authored
Merge pull request #1 from vimeda/initial
Initial setup
2 parents 890178a + 9398831 commit 7cea001

14 files changed

Lines changed: 730 additions & 2 deletions

.travis.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
language: go
2+
3+
go:
4+
- stable
5+
6+
env:
7+
- GO111MODULE=on
8+
9+
install: true
10+
11+
script:
12+
- go test -v -cover -covermode=atomic -coverprofile=tests.out ./...
13+
14+
after_success:
15+
- go get github.com/mattn/goveralls
16+
- $GOPATH/bin/goveralls -coverprofile=tests.out -service travis-ci -repotoken $COVERALLS_TOKEN

CONTRIBUTING.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Contributing to Pletter
2+
3+
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
4+
5+
The following is a set of guidelines for contributing to Pletter and its packages,
6+
which are hosted on [Github](https://github.com/vimeda) on GitHub.
7+
These are just guidelines, not rules. Use your best judgment, and feel free to propose changes
8+
to this document in a pull request.
9+
10+
## Code of Conduct
11+
12+
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md).
13+
By participating, you are expected to uphold this code.
14+
Please report unacceptable behavior to [opensource@lykon.com](mailto:opensource@lykon.com).
15+
16+
We accept contributions via Pull Requests on [Github](https://github.com/vimeda/pletter).
17+
18+
## How Can I Contribute?
19+
20+
### Reporting Bugs
21+
22+
This section guides you through submitting a bug report for Pletter. Following these guidelines helps maintainers
23+
and the community understand your report :pencil:, reproduce the behavior :computer: :computer:, and find related
24+
reports :mag_right:.
25+
26+
Before creating bug reports, please check if the bug was already reported before as you might find out that you don't
27+
need to create one. When you are creating a bug report, please [include as many details as possible](#how-do-i-submit-a-good-bug-report).
28+
29+
#### How Do I Submit A (Good) Bug Report?
30+
31+
Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). Create an issue on provide the following information.
32+
33+
Explain the problem and include additional details to help maintainers reproduce the problem:
34+
35+
* **Use a clear and descriptive title** for the issue to identify the problem.
36+
* **Describe the exact steps which reproduce the problem** in as many details as possible. For example, start by explaining how you started Pletter,
37+
e.g. which command exactly you used in the terminal. When listing steps, **don't just say what you did, but explain how you did it**.
38+
* **Provide specific examples to demonstrate the steps**. Include links to files or GitHub projects, or copy/pasteable snippets, which you use in those examples.
39+
If you're providing snippets in the issue, use [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines).
40+
* **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior.
41+
* **Explain which behavior you expected to see instead and why.**
42+
43+
Include details about your configuration and environment:
44+
45+
* **Which version of Pletter are you using?**
46+
* **What's the name and version of the OS you're using**?
47+
48+
### Your First Code Contribution
49+
50+
Unsure where to begin contributing to Pletter? You can start by looking through these `beginner` and `help-wanted` issues:
51+
52+
* [Beginner issues][beginner] - issues which should only require a few lines of code, and a test or two.
53+
* [Help wanted issues][help-wanted] - issues which should be a bit more involved than `beginner` issues.
54+
55+
Both issue lists are sorted by total number of comments. While not perfect, number of comments is a reasonable proxy for impact a given change will have.
56+
57+
### Pull Requests
58+
59+
* Include screenshots and animated GIFs in your pull request whenever possible.
60+
* Follow the [Go](https://github.com/golang/go/wiki/CodeReviewComments) styleguides.
61+
* Include thoughtfully-worded, well-structured tests.
62+
* Document new code
63+
* End files with a newline.
64+
65+
66+
Happy Coding!

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 Lykon
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Makefile

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
OSFLAG:=
2+
UNAME_S := $(shell uname -s)
3+
OSFLAG = osx
4+
ifeq ($(UNAME_S),Linux)
5+
OSFLAG = linux
6+
endif
7+
8+
UNAME_P := $(shell uname -p)
9+
ifeq ($(UNAME_P),x86_64)
10+
OSFLAG := $(OSFLAG)-x86_64
11+
endif
12+
ifneq ($(filter %86,$(UNAME_P)),)
13+
OSFLAG := $(OSFLAG)-x86_32
14+
endif
15+
16+
PROTOC_ZIP="protoc-3.8.0-$(OSFLAG).zip"
17+
18+
.PHONY: compile
19+
20+
proto: tools
21+
@echo "Compile the pb.go files"
22+
@protoc --go_out=pb *.proto
23+
24+
#---------------
25+
#-- tools
26+
#---------------
27+
28+
.PHONY: tools tools.protoc-gen-go tools.protoc
29+
30+
tools: tools.protoc-gen-go tools.protoc
31+
32+
tools.protoc-gen-go:
33+
@command -v protoc-gen-go >/dev/null ; if [ $$? -ne 0 ]; then \
34+
echo "--> installing protoc-gen-go"; \
35+
go get github.com/golang/protobuf/protoc-gen-go; \
36+
fi
37+
38+
tools.protoc:
39+
@command -v protoc >/dev/null ; if [ $$? -ne 0 ]; then \
40+
echo "--> installing protoc"; \
41+
curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v3.8.0/$(PROTOC_ZIP); \
42+
unzip -o $(PROTOC_ZIP) -d /usr/local bin/protoc; \
43+
unzip -o $(PROTOC_ZIP) -d /usr/local include/*; \
44+
rm -f $(PROTOC_ZIP); \
45+
fi

README.md

Lines changed: 111 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,111 @@
1-
# pletter
2-
A standard way to wrap a proto message
1+
<h1 align="center">Welcome to Pletter 👋</h1>
2+
<p></p>
3+
4+
[![Build Status](https://travis-ci.com/vimeda/pletter.svg?branch=master)](https://travis-ci.com/vimeda/pletter)
5+
[![Coverage Status](https://coveralls.io/repos/github/vimeda/pletter/badge.svg)](https://coveralls.io/github/vimeda/pletter)
6+
[![Go Report Card](https://goreportcard.com/badge/github.com/vimeda/pletter)](https://goreportcard.com/report/github.com/vimeda/pletter)
7+
[![GoDoc](https://godoc.org/github.com/vimeda/pletter?status.svg)](https://godoc.org/github.com/vimeda/pletter)
8+
9+
> A standard way to wrap a proto message
10+
11+
Pletter was born with a single mission: `To standardize wrapping protocol buffer messages`. This is normally needed when you use protobuf as your messaging protocol.
12+
13+
## The Problem
14+
15+
Imagine that you have an event driven architecture. In this system you chose to use protocol buffers to ensure message contract and to transit information.
16+
Let's assume we use Kafka as our message broker. In this Kafka we have one topic called `accounts`, this means all account messages will go to the `accounts` topic.
17+
18+
On the consumer side, we will receive multiple messages in the same topic. If an application wants to read this messages it needs to identify the message type/name
19+
to either enrich, fan out or handle it. To solve that we have a few options:
20+
21+
1. If you use something like AMQP instead of a message broker you can set the name of the message in the header and deal with it in the consumer side
22+
2. If you use Kafka/Kinesis or any message broker that streams messages, you will need to envelop the message.
23+
24+
Option 2 is the option that Pletter tries to solve in Go.
25+
26+
An interesting article about streams architecture can be found [here](https://docs.confluent.io/current/streams/architecture.html)
27+
28+
## Install
29+
30+
```sh
31+
go get github.com:vimeda/pletter
32+
```
33+
34+
## Use
35+
36+
Pletter is simple to use, we provide you a few functions to deal with the message.
37+
38+
When producing messages:
39+
40+
```go
41+
// Create your proto message
42+
ac := pb.Example{
43+
ID: "1231231312",
44+
}
45+
46+
// call the PackAndMarshal function to wrap your message and already proto.Marshal it
47+
raw, err := any.PackAndMarshal(&ac)
48+
if err != nil {
49+
fmt.Errorf("an error ocurred while packing and marshalling the message: %s", err)
50+
}
51+
52+
// send the slice of byte to your message broker
53+
```
54+
55+
When consuming messages:
56+
57+
```go
58+
// declare your expected type
59+
var expectedExample pb.Example
60+
61+
// call the Unpack function that will unwrap your message from the envelop
62+
err = any.Unpack(raw, &expectedExample)
63+
if err != nil {
64+
fmt.Errorf("an error ocurred while unpacking the message: %s", err)
65+
}
66+
```
67+
68+
You can also filter out messages when consuming them:
69+
70+
```go
71+
// call the Unpack function that will unwrap your message from the envelop
72+
name, err := any.GetMessageName(raw)
73+
if err != nil {
74+
fmt.Errorf("an error ocurred while getting the message name: %s", err)
75+
}
76+
77+
switch name {
78+
case "pb.Example":
79+
// declare your expected type
80+
var expectedExample pb.Example
81+
82+
// call the Unpack function that will unwrap your message from the envelop
83+
err = any.Unpack(raw, &expectedExample)
84+
if err != nil {
85+
fmt.Errorf("an error ocurred while unpacking the message: %s", err)
86+
}
87+
// do somthing
88+
default;
89+
// ignore the other messages
90+
}
91+
```
92+
93+
## Run tests
94+
95+
```sh
96+
go test ./...
97+
```
98+
99+
## Author
100+
101+
👤 **Italo Vietro**
102+
103+
* Github: [@italolelis](https://github.com/italolelis)
104+
105+
👤 **Felipe Umpierre**
106+
107+
* Github: [@felipeumpierre](https://github.com/felipeumpierre)
108+
109+
## 🤝 Contributing
110+
111+
Contributions, issues and feature requests are welcome!<br />Feel free to check [issues page](https://github.com/vimeda/pletter/issues).

any/any.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package any
2+
3+
import (
4+
"strings"
5+
6+
"github.com/golang/protobuf/proto"
7+
"github.com/golang/protobuf/ptypes"
8+
"github.com/golang/protobuf/ptypes/any"
9+
"github.com/vimeda/pletter/pb"
10+
)
11+
12+
// PackAndMarshal packs a proto message into an envelope message and marshal it
13+
func PackAndMarshal(m proto.Message) ([]byte, error) {
14+
e, err := Pack(m)
15+
if err != nil {
16+
return []byte{}, err
17+
}
18+
19+
return proto.Marshal(&e)
20+
}
21+
22+
// Pack packs a proto message into an envelope message
23+
func Pack(m proto.Message) (pb.Envelope, error) {
24+
raw, err := proto.Marshal(m)
25+
if err != nil {
26+
return pb.Envelope{}, err
27+
}
28+
29+
return pb.Envelope{
30+
InnerMessage: &any.Any{
31+
TypeUrl: "github.com/lykon/pletter/" + proto.MessageName(m),
32+
Value: raw,
33+
},
34+
}, nil
35+
}
36+
37+
// Unpack unpacks a slice of bytes into a proto message.
38+
// The slice of bytes should represent an enveloped proto message
39+
func Unpack(m []byte, t proto.Message) error {
40+
e, err := getEnvelope(m)
41+
if err != nil {
42+
return err
43+
}
44+
45+
err = ptypes.UnmarshalAny(e.GetInnerMessage(), t)
46+
if err != nil {
47+
return err
48+
}
49+
50+
return nil
51+
}
52+
53+
// GetMessageName returns the message name from the wrapped proto message
54+
func GetMessageName(m []byte) (string, error) {
55+
e, err := getEnvelope(m)
56+
if err != nil {
57+
return "", err
58+
}
59+
60+
splits := strings.Split(e.GetInnerMessage().GetTypeUrl(), "/")
61+
return splits[len(splits)-1], nil
62+
}
63+
64+
func getEnvelope(m []byte) (pb.Envelope, error) {
65+
var receivingEnvelope pb.Envelope
66+
err := proto.Unmarshal(m, &receivingEnvelope)
67+
return receivingEnvelope, err
68+
}

0 commit comments

Comments
 (0)