rimless 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/Dockerfile +2 -1
- data/Envfile +6 -0
- data/Makefile +1 -1
- data/README.md +30 -2
- data/docker-compose.yml +1 -0
- data/lib/rimless/avro_helpers.rb +35 -0
- data/lib/rimless/avro_utils.rb +6 -1
- data/lib/rimless/dependencies.rb +7 -4
- data/lib/rimless/kafka_helpers.rb +2 -2
- data/lib/rimless/rspec/helpers.rb +3 -2
- data/lib/rimless/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a7bb2e99346e0f71cdd800b802a9d405e3188303a7017b375442c50a66872cfb
|
4
|
+
data.tar.gz: 73f37b16200f0ac00cec1756ffd085a8fcd1a3265fc8af8b652aca130161bf95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42541dacf4cd9c0ce8c7dc837e0f0d289d4be93c0b940f3b2fd724ec08ed70f4d4a69e92b0726a81951e509c83c2c4e69a48b92884862404225754fbce4ef109
|
7
|
+
data.tar.gz: 84986a34d1f651dcb1f215d25762f1e1b6c9f18aa8068ed34090fa15f0185284be3ab1b77e8b29c2dddb9b74b3a6f655728b42d196af9650ed7b7253710ad4c9
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
### 0.2.0
|
2
|
+
|
3
|
+
* Added the `Rimless.encode` (`.avro_encode`) and `Rimless.decode`
|
4
|
+
(`.avro_decode`) helpers/shortcuts to simplify the interaction with the
|
5
|
+
Apache Avro library
|
6
|
+
* The `.encode` method automatically performs input data sanitation and
|
7
|
+
supports deep relative (to the local namespace) schema resolution. This
|
8
|
+
allows you to access deeply located schemes relative by just providing a
|
9
|
+
leading period (eg. `.deep.a.b.c` becomes
|
10
|
+
`development.your_app.deep.a.b.c`)
|
11
|
+
* The `.message`, '.sync_message', '.async_message' helpers now make use of the
|
12
|
+
new `.encode` functionality which adds transparent data sanitation and schema
|
13
|
+
name features
|
14
|
+
* At the `test` environment the compiled Avro schemas output path is not
|
15
|
+
deleted anymore, instead the compiled schemas are overwritten. This may keep
|
16
|
+
dead schemas, but it allows parallel test execution without flaws. The removal
|
17
|
+
of the compiled schema directory caused previously file read errors when a
|
18
|
+
parallel process started a recompilation.
|
19
|
+
|
1
20
|
### 0.1.4
|
2
21
|
|
3
22
|
* Reconfigure (reset) the AvroTurf instance on tests to avoid caching issues
|
data/Dockerfile
CHANGED
@@ -11,7 +11,8 @@ RUN apt-get update -yqqq && \
|
|
11
11
|
ca-certificates \
|
12
12
|
bash-completion inotify-tools && \
|
13
13
|
echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen && /usr/sbin/locale-gen && \
|
14
|
-
gem install bundler --no-document --no-prerelease
|
14
|
+
gem install bundler -v '~> 2.0' --no-document --no-prerelease && \
|
15
|
+
gem install bundler -v '~> 1.0' --no-document --no-prerelease
|
15
16
|
|
16
17
|
# Add new web user
|
17
18
|
RUN mkdir /app && \
|
data/Envfile
ADDED
data/Makefile
CHANGED
data/README.md
CHANGED
@@ -23,6 +23,7 @@ opinionated framework which sets up solid conventions for producing messages.
|
|
23
23
|
- [Confluent Schema Registry Subject](#confluent-schema-registry-subject)
|
24
24
|
- [Organize and write schema definitions](#organize-and-write-schema-definitions)
|
25
25
|
- [Producing messages](#producing-messages)
|
26
|
+
- [Encoding/Decoding messages](#encodingdecoding-messages)
|
26
27
|
- [Handling of schemaless deep blobs](#handling-of-schemaless-deep-blobs)
|
27
28
|
- [Writing tests for your messages](#writing-tests-for-your-messages)
|
28
29
|
- [Development](#development)
|
@@ -254,8 +255,11 @@ Rimless.message(data: user, schema: :user_v1, topic: :users)
|
|
254
255
|
Rimless.async_message(data: user, schema: :user_v1, topic: :users)
|
255
256
|
|
256
257
|
# In cases you just want the encoded Apache Avro binary blob, you can encode it
|
257
|
-
# directly
|
258
|
-
encoded = Rimless.
|
258
|
+
# directly with our simple helper like this:
|
259
|
+
encoded = Rimless.encode(user, schema: 'user_v1')
|
260
|
+
# Next to this wrapped shortcut (see Encoding/Decoding messages section for
|
261
|
+
# details), we provide access to our configured AvroTurf gem instance via
|
262
|
+
# +Rimless.avro+, so you can also use +Rimless.avro.encode(user, ..)+
|
259
263
|
|
260
264
|
# You can also send raw messages with the rimless gem, so encoding of your
|
261
265
|
# message must be done before
|
@@ -275,6 +279,30 @@ Rimless.message(data: user, schema: :user_v1,
|
|
275
279
|
Rimless.async_raw_message(data: encoded, topic: :users)
|
276
280
|
```
|
277
281
|
|
282
|
+
### Encoding/Decoding messages
|
283
|
+
|
284
|
+
By convention we focus on the [Apache Avro](https://avro.apache.org/) data
|
285
|
+
format. This is provided by the [AvroTurf](https://rubygems.org/gems/avro_turf)
|
286
|
+
gem and the rimless gem adds some neat helpers on top of it. Here are a few
|
287
|
+
examples to show how rimless can be used to encode/decode Apache Avro data:
|
288
|
+
|
289
|
+
```ruby
|
290
|
+
# Encode a data structure (no matter of symbolized, or stringified keys, or
|
291
|
+
# non-simple types) to Apache Avro format
|
292
|
+
encoded = Rimless.encode(user, schema: 'user_v1')
|
293
|
+
|
294
|
+
# Works the same for symbolized schema names
|
295
|
+
encoded = Rimless.encode(user, schema: :user_v1)
|
296
|
+
|
297
|
+
# Also supports the resolution of deep relative schemes
|
298
|
+
# (+.user.address+ becomes +<ENV>.<APP>.user.address+)
|
299
|
+
encoded = Rimless.encode(user.address, schema: '.user.address')
|
300
|
+
|
301
|
+
# Decoding Apache Avro data is even more simple. The resulting data structure
|
302
|
+
# is deeply key-symbolized.
|
303
|
+
decoded = Rimless.decode('your-avro-binary-data-here')
|
304
|
+
```
|
305
|
+
|
278
306
|
#### Handling of schemaless deep blobs
|
279
307
|
|
280
308
|
Apache Avro is by design a strict, type casted format which does not allow
|
data/docker-compose.yml
CHANGED
data/lib/rimless/avro_helpers.rb
CHANGED
@@ -8,6 +8,41 @@ module Rimless
|
|
8
8
|
class_methods do
|
9
9
|
# A top-level avro instance
|
10
10
|
mattr_accessor :avro
|
11
|
+
# A shared AvroUtils instance
|
12
|
+
mattr_accessor :avro_utils
|
13
|
+
|
14
|
+
# A shortcut to encode data using the specified schema to the Apache Avro
|
15
|
+
# format. This also applies data sanitation to avoid issues with the low
|
16
|
+
# level Apache Avro library (symbolized keys, etc) and it allows
|
17
|
+
# deep-relative schema names. When you pass +.deep.deep+ for example
|
18
|
+
# (leading period) it will prefix the schema name with the local
|
19
|
+
# namespace (so it becomes absolute).
|
20
|
+
#
|
21
|
+
# @param data [Mixed] the data structure to encode
|
22
|
+
# @param schema [String, Symbol] name of the schema that should be used
|
23
|
+
# @param opts [Hash{Symbol => Mixed}] additional options
|
24
|
+
# @return [String] the Apache Avro blob
|
25
|
+
def avro_encode(data, schema:, **opts)
|
26
|
+
data = avro_sanitize(data)
|
27
|
+
|
28
|
+
# When the deep-relative form (+.deep.deep[..]+) is present, we add our
|
29
|
+
# local namespace, so Avro can resolve it
|
30
|
+
schema = avro_utils.namespace + schema.to_s \
|
31
|
+
if schema.to_s.start_with? '.'
|
32
|
+
|
33
|
+
avro.encode(data, schema_name: schema.to_s, **opts)
|
34
|
+
end
|
35
|
+
alias_method :encode, :avro_encode
|
36
|
+
|
37
|
+
# A shortcut to parse a blob of Apache Avro data.
|
38
|
+
#
|
39
|
+
# @param data [String] the Apache Avro blob
|
40
|
+
# @param opts [Hash{Symbol => Mixed}] additional options
|
41
|
+
# @return [Mixed] the decoded data structure
|
42
|
+
def avro_decode(data, **opts)
|
43
|
+
avro.decode(data, **opts).deep_symbolize_keys!
|
44
|
+
end
|
45
|
+
alias_method :decode, :avro_decode
|
11
46
|
|
12
47
|
# The Apache Avro Ruby gem requires simple typed hashes for encoding.
|
13
48
|
# This forces us to convert eg. Grape entity representations into simple
|
data/lib/rimless/avro_utils.rb
CHANGED
@@ -61,7 +61,12 @@ module Rimless
|
|
61
61
|
|
62
62
|
# Clear previous compiled Avro schema files to provide a clean rebuild.
|
63
63
|
def clear
|
64
|
-
|
64
|
+
# In a test environment, especially with parallel test execution the
|
65
|
+
# recompiling of Avro schemas is error prone due to the deletion of the
|
66
|
+
# configuration (output) directory. This leads to random failures due to
|
67
|
+
# file read calls to temporary not existing files. So we just keep the
|
68
|
+
# files and just overwrite them in place while testing.
|
69
|
+
FileUtils.rm_rf(output_path) unless Rimless.env.test?
|
65
70
|
FileUtils.mkdir_p(output_path)
|
66
71
|
end
|
67
72
|
|
data/lib/rimless/dependencies.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
module Rimless
|
4
4
|
# The top-level dependencies helpers.
|
5
|
+
#
|
6
|
+
# rubocop:disable Metrics/BlockLength because its an Active Support concern
|
5
7
|
module Dependencies
|
6
8
|
extend ActiveSupport::Concern
|
7
9
|
|
@@ -53,17 +55,18 @@ module Rimless
|
|
53
55
|
|
54
56
|
# Setup a global available Apache Avro decoder/encoder with support for
|
55
57
|
# the Confluent Schema Registry, but first create a helper instance
|
56
|
-
avro_utils = Rimless::AvroUtils.new
|
58
|
+
Rimless.avro_utils = Rimless::AvroUtils.new
|
57
59
|
# Compile our Avro schema templates to ready-to-consume Avro schemas
|
58
|
-
avro_utils.recompile_schemas
|
60
|
+
Rimless.avro_utils.recompile_schemas
|
59
61
|
# Register a global Avro messaging instance
|
60
62
|
Rimless.avro = AvroTurf::Messaging.new(
|
61
63
|
logger: Rimless.logger,
|
62
|
-
namespace: avro_utils.namespace,
|
63
|
-
schemas_path: avro_utils.output_path,
|
64
|
+
namespace: Rimless.avro_utils.namespace,
|
65
|
+
schemas_path: Rimless.avro_utils.output_path,
|
64
66
|
registry_url: Rimless.configuration.schema_registry_url
|
65
67
|
)
|
66
68
|
end
|
67
69
|
end
|
68
70
|
end
|
71
|
+
# rubocop:enable Metrics/BlockLength
|
69
72
|
end
|
@@ -50,7 +50,7 @@ module Rimless
|
|
50
50
|
# @param topic [String, Symbol, Hash{Symbol => Mixed}] the destination
|
51
51
|
# Apache Kafka topic
|
52
52
|
def sync_message(data:, schema:, topic:, **args)
|
53
|
-
encoded = Rimless.
|
53
|
+
encoded = Rimless.encode(data, schema: schema)
|
54
54
|
sync_raw_message(data: encoded, topic: topic, **args)
|
55
55
|
end
|
56
56
|
alias_method :message, :sync_message
|
@@ -66,7 +66,7 @@ module Rimless
|
|
66
66
|
# @param topic [String, Symbol, Hash{Symbol => Mixed}] the destination
|
67
67
|
# Apache Kafka topic
|
68
68
|
def async_message(data:, schema:, topic:, **args)
|
69
|
-
encoded = Rimless.
|
69
|
+
encoded = Rimless.encode(data, schema: schema)
|
70
70
|
async_raw_message(data: encoded, topic: topic, **args)
|
71
71
|
end
|
72
72
|
|
@@ -8,9 +8,10 @@ module Rimless
|
|
8
8
|
# A simple helper to parse a blob of Apache Avro data.
|
9
9
|
#
|
10
10
|
# @param data [String] the Apache Avro blob
|
11
|
+
# @param opts [Hash{Symbol => Mixed}] additional options
|
11
12
|
# @return [Hash{String => Mixed}] the parsed payload
|
12
|
-
def avro_parse(data)
|
13
|
-
Rimless.
|
13
|
+
def avro_parse(data, **opts)
|
14
|
+
Rimless.avro_decode(data, **opts)
|
14
15
|
end
|
15
16
|
end
|
16
17
|
end
|
data/lib/rimless/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rimless
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hermann Mayer
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-06-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -327,6 +327,7 @@ files:
|
|
327
327
|
- Appraisals
|
328
328
|
- CHANGELOG.md
|
329
329
|
- Dockerfile
|
330
|
+
- Envfile
|
330
331
|
- Gemfile
|
331
332
|
- LICENSE
|
332
333
|
- Makefile
|