rimless 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb723bcb062c5d9a9266ef38998fe17ab11975cbf943333235cc5fd878201399
4
- data.tar.gz: a827fa49f7d2ab7e486ec7d26bdeb312fa9c6027a156292508d212e5e8c30d89
3
+ metadata.gz: a7bb2e99346e0f71cdd800b802a9d405e3188303a7017b375442c50a66872cfb
4
+ data.tar.gz: 73f37b16200f0ac00cec1756ffd085a8fcd1a3265fc8af8b652aca130161bf95
5
5
  SHA512:
6
- metadata.gz: 22366b62a462bbe2ffbce01c3382a53e7773d125442f6e4f516aab2a225abe5fbb3920c3c22323df43094daaf07bcdc5307e7ed9b80e2f6d428c4485d3779781
7
- data.tar.gz: 4f53842c9b8f721a42ba275abbcad699d0349d2db11aa8f9492b62d8405621ccd3d1a2e2d7b168a55a758e46fdf8dce5b0a692c7943de5aa954d2526f8c13693
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
@@ -0,0 +1,6 @@
1
+ LANG=en_US.UTF-8
2
+ LANGUAGE=en_US.UTF-8
3
+ LC_ALL=en_US.UTF-8
4
+
5
+ # Just fix this, so Appraisals with Rails 4 are working fine
6
+ BUNDLER_VERSION=1.17.3
data/Makefile CHANGED
@@ -116,7 +116,7 @@ endif
116
116
  clean-images:
117
117
  # Clean build images
118
118
  ifeq ($(MAKE_ENV),docker)
119
- @-$(DOCKER) images | $(GREP) hausgold-sdk \
119
+ @-$(DOCKER) images | $(GREP) rimless \
120
120
  | $(AWK) '{ print $$3 }' \
121
121
  | $(XARGS) -rn1 $(DOCKER) rmi -f
122
122
  endif
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 via the AvroTurf gem
258
- encoded = Rimless.avro.encode(user, schema_name: 'user_v1')
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
@@ -2,6 +2,7 @@ version: "3"
2
2
  services:
3
3
  test:
4
4
  build: .
5
+ env_file: Envfile
5
6
  network_mode: bridge
6
7
  working_dir: /app
7
8
  volumes:
@@ -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
@@ -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
- FileUtils.rm_rf(output_path)
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
 
@@ -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.avro.encode(data, schema_name: schema.to_s)
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.avro.encode(data, schema_name: schema.to_s)
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.avro.decode(data)
13
+ def avro_parse(data, **opts)
14
+ Rimless.avro_decode(data, **opts)
14
15
  end
15
16
  end
16
17
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Rimless
4
4
  # The version of the +rimless+ gem
5
- VERSION = '0.1.4'
5
+ VERSION = '0.2.0'
6
6
  end
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.1.4
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-04-17 00:00:00.000000000 Z
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