Module: Maitredee

Defined in:
lib/maitredee.rb,
lib/maitredee/railtie.rb,
lib/maitredee/version.rb,
lib/maitredee/publisher.rb,
lib/maitredee/active_job.rb,
lib/maitredee/cli/runner.rb,
lib/maitredee/subscriber.rb,
lib/maitredee/adapters/base_adapter.rb,
lib/maitredee/adapters/test_adapter.rb,
lib/maitredee/adapters/sns_sqs_adapter.rb

Defined Under Namespace

Modules: ActiveJob, Adapters, CLI Classes: Publisher, PublisherMessage, Subscriber, SubscriberMessage

Constant Summary collapse

Error =
Class.new(StandardError)
ValidationError =
Class.new(Error)
NoRoutesError =
Class.new(Error)
VERSION =
"0.10.1"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.app_nameString

fetch configured app name or automatically fetch from Rails or from ENV["MAITREDEE_APP_NAME"] used for generating queue_resource_name

Returns:

  • (String)


143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/maitredee.rb', line 143

def app_name
  @app_name ||=
    begin
      rails_app_name =
        if defined?(Rails)
          Rails.application.class.parent_name.underscore.dasherize
        end
      ENV["MAITREDEE_APP_NAME"] ||
        rails_app_name ||
        raise("must set app_name for maitredee")
    end
end

.clientMaitredee::Adapters::AbstractAdapter

the client we use for publishing and setting up workers

Returns:

  • (Maitredee::Adapters::AbstractAdapter)


28
29
30
# File 'lib/maitredee.rb', line 28

def client
  @client
end

.namespaceString

fetch configured namespace or automatically fetch from ENV["MAITREDEE_NAMESPACE"]

Returns:

  • (String)


163
164
165
166
# File 'lib/maitredee.rb', line 163

def namespace
  @namespace ||=
    ENV["MAITREDEE_NAMESPACE"] || raise("must set namespace for maitredee")
end

.resource_name_suffixString

allows you to add a suffix to all your resource names, mostly used for testing but could be useful in other occassions.

Returns:

  • (String)

    string appended to all resource names



20
21
22
# File 'lib/maitredee.rb', line 20

def resource_name_suffix
  @resource_name_suffix
end

.schema_pathString

this is the path of the folder in which validation_schema will try to do a lookup. This folder should contain json schemas.

Returns:

  • (String)

    path to folder



24
25
26
# File 'lib/maitredee.rb', line 24

def schema_path
  @schema_path
end

Class Method Details

.configure_brokerObject

idempotently configures broker to create topics, queues and subscribe queues to topics nothing will eveer be deleted or cleaned up



174
175
176
177
178
179
180
181
182
# File 'lib/maitredee.rb', line 174

def configure_broker
  hash_array = Hash.new { |hash, key| hash[key] = [] }
  topics_and_queues =
    subscriber_registry.each_with_object(hash_array) do |subscriber, hash|
      topic_arn = topic_resource_name(subscriber.topic_name)
      hash[topic_arn] << queue_resource_name(subscriber.topic_name, subscriber.queue_name)
    end
  client.configure_broker(topics_and_queues)
end

.publish(topic_name:, body:, schema_name:, event_name: nil, primary_key: nil) ⇒ PublisherMessage

publishes messages using configured adapter

Parameters:

  • topic (String)

    topic name

  • body (Hash, Array, String)

    Any valid json data that can be validated by json-schema

  • schema_name (String)

    A valid schema name for publishing data

  • event_name (String, nil) (defaults to: nil)

    Event name for subscriber routing

  • primary_key (#to_s, nil) (defaults to: nil)

    Key to be used for resource identification

Returns:

Raises:

  • (ArgumentError)


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/maitredee.rb', line 39

def publish(
  topic_name:,
  body:,
  schema_name:,
  event_name: nil,
  primary_key: nil
)
  raise ArgumentError, "topic_name, body or schema_name is nil" if topic_name.nil? || body.nil? || schema_name.nil?
  validate!(body, schema_name)

  message = PublisherMessage.new(
    message_id: SecureRandom.uuid,
    topic_resource_name: topic_resource_name(topic_name),
    topic_name: topic_name.to_s,
    body: body,
    schema_name: schema_name&.to_s,
    event_name: event_name&.to_s,
    primary_key: primary_key&.to_s
  )

  client.publish(message)

  message
end

.queue_resource_name(topic_name, queue_name) ⇒ String

build queue resource name from queue name and topic name

Parameters:

  • topic_name (#to_s)

    topic name

  • queue_name (#to_s)

    queue name

Returns:

  • (String)


97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/maitredee.rb', line 97

def queue_resource_name(topic_name, queue_name)
  [
    namespace,
    topic_name,
    app_name,
    queue_name,
    resource_name_suffix
  ].compact.join("--").tap do |val|
    if val.length > 80
      raise "Cannot have a queue name longer than 80 characters: #{name}"
    end
  end
end

.schemasObject

hash to look up schema based of schema_path



132
133
134
135
136
137
# File 'lib/maitredee.rb', line 132

def schemas
  @schemas ||= Hash.new do |hash, key|
    path = Pathname.new(schema_path).join("#{key}.json")
    hash[key] = JSONSchemer.schema(path)
  end
end

.set_client(slug, *args) ⇒ Object

configure the adapter, must be executed before loading subscribers

Parameters:

  • slug (#to_s)

    name of adapter

  • args

    [] options to send to the adapter



68
69
70
71
# File 'lib/maitredee.rb', line 68

def set_client(slug, *args)
  raise "No client set for Maitredee" if slug.nil?
  @client = "::Maitredee::Adapters::#{slug.to_s.camelize}Adapter".constantize.new(*args)
end

.topic_resource_name(topic_name) ⇒ String

build topic resource name from topic name

Parameters:

  • topic_name (#to_s)

    topic name

Returns:

  • (String)


84
85
86
87
88
89
90
# File 'lib/maitredee.rb', line 84

def topic_resource_name(topic_name)
  [
    namespace,
    topic_name,
    resource_name_suffix
  ].compact.join("--")
end

.validate!(body, schema) ⇒ nil

validate a body given a schema name

Parameters:

  • body (Array, Hash, String)

    data to send with message

  • schema (String)

    string key to look up schema to validate against

Returns:

  • (nil)

Raises:



118
119
120
121
122
123
124
125
126
127
# File 'lib/maitredee.rb', line 118

def validate!(body, schema)
  errors = schemas[schema].validate(deep_stringify_keys(body))
  properties = errors.map do |error|
    error["data_pointer"]
  end.join(", ")

  if errors.any?
    raise ValidationError, "Invalid properties: #{properties}"
  end
end