manageiq-messaging 0.1.0 → 0.1.1
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 +4 -4
 - data/CHANGES +5 -0
 - data/README.md +3 -3
 - data/examples/message.rb +1 -1
 - data/lib/manageiq/messaging/client.rb +28 -6
 - data/lib/manageiq/messaging/common.rb +4 -0
 - data/lib/manageiq/messaging/kafka/client.rb +7 -3
 - data/lib/manageiq/messaging/kafka/common.rb +6 -4
 - data/lib/manageiq/messaging/kafka/queue.rb +2 -2
 - data/lib/manageiq/messaging/kafka/topic.rb +3 -1
 - data/lib/manageiq/messaging/stomp/queue.rb +2 -0
 - data/lib/manageiq/messaging/stomp/topic.rb +2 -2
 - data/lib/manageiq/messaging/version.rb +1 -1
 - metadata +2 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 24d7b7196e5413465ff914e77ca504f91e96dc16
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 808545abce4d4629cdcd32a565ba63800005f331
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 05346bab1741de40e0a6d5fdf2abf6e87c0ad059b220671f5b62f91e917e984e8b97dc86281afa4a647818c08bea98ea59656b93f2062128a88c25fce255fb58
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 7ea84ea24c5199330a78bc6169637c94a1cae7e270aae06986aff43c12d20df24db35060288fcd0149591281ece366654342c7ec8cd8d78448c606802d4b312b
         
     | 
    
        data/CHANGES
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | 
         @@ -80,7 +80,7 @@ This is the one-to-one publish/subscribe pattern. Multiple subscribers can subsc 
     | 
|
| 
       80 
80 
     | 
    
         
             
                }
         
     | 
| 
       81 
81 
     | 
    
         
             
              )
         
     | 
| 
       82 
82 
     | 
    
         | 
| 
       83 
     | 
    
         
            -
              client.subscribe_messages(:service => 'ems_operation', :affinity => 'ems_amazon1') do |messages|
         
     | 
| 
      
 83 
     | 
    
         
            +
              client.subscribe_messages(:service => 'ems_operation', :affinity => 'ems_amazon1', :auto_ack => false) do |messages|
         
     | 
| 
       84 
84 
     | 
    
         
             
                messages.each do |msg|
         
     | 
| 
       85 
85 
     | 
    
         
             
                  # do stuff with msg.message and msg.payload
         
     | 
| 
       86 
86 
     | 
    
         
             
                  client.ack(msg.ack_ref)
         
     | 
| 
         @@ -149,8 +149,8 @@ This is the one-to-many publish/subscribe pattern. Multiple subscribers can subs 
     | 
|
| 
       149 
149 
     | 
    
         
             
                  :timestamp => '1501091391'
         
     | 
| 
       150 
150 
     | 
    
         
             
                })
         
     | 
| 
       151 
151 
     | 
    
         | 
| 
       152 
     | 
    
         
            -
              client.subscribe_topic(:service => 'provider_events', :persist_ref => 'automate_1') do | 
     | 
| 
       153 
     | 
    
         
            -
                # do stuff with  
     | 
| 
      
 152 
     | 
    
         
            +
              client.subscribe_topic(:service => 'provider_events', :persist_ref => 'automate_1') do |msg|
         
     | 
| 
      
 153 
     | 
    
         
            +
                # do stuff with msg.sender, msg.message, and msg.payload. sender may be nil if not set by the publisher
         
     | 
| 
       154 
154 
     | 
    
         
             
              end
         
     | 
| 
       155 
155 
     | 
    
         
             
            ```
         
     | 
| 
       156 
156 
     | 
    
         | 
    
        data/examples/message.rb
    CHANGED
    
    | 
         @@ -23,7 +23,7 @@ class ProducerConsumer < Common 
     | 
|
| 
       23 
23 
     | 
    
         
             
                  puts "produced 5 messages"
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
25 
     | 
    
         
             
                  puts "consumer"
         
     | 
| 
       26 
     | 
    
         
            -
                  client.subscribe_messages(:service => 'ems_operation', :affinity => 'ems_amazon1') do |messages|
         
     | 
| 
      
 26 
     | 
    
         
            +
                  client.subscribe_messages(:service => 'ems_operation', :affinity => 'ems_amazon1', :auto_ack => false) do |messages|
         
     | 
| 
       27 
27 
     | 
    
         
             
                    messages.each do |msg|
         
     | 
| 
       28 
28 
     | 
    
         
             
                      do_stuff(msg)
         
     | 
| 
       29 
29 
     | 
    
         
             
                      client.ack(msg.ack_ref)
         
     | 
| 
         @@ -94,6 +94,7 @@ module ManageIQ 
     | 
|
| 
       94 
94 
     | 
    
         
             
                  # Expected keys in +options+ are:
         
     | 
| 
       95 
95 
     | 
    
         
             
                  # * :service  (service and affinity are used to determine the queue)
         
     | 
| 
       96 
96 
     | 
    
         
             
                  # * :affinity (optional)
         
     | 
| 
      
 97 
     | 
    
         
            +
                  # * :auto_ack (default true, if it is false, client.ack method must be explicitly called)
         
     | 
| 
       97 
98 
     | 
    
         
             
                  # Other options are underlying messaging system specific.
         
     | 
| 
       98 
99 
     | 
    
         
             
                  #
         
     | 
| 
       99 
100 
     | 
    
         
             
                  # A callback block is needed to consume the messages:
         
     | 
| 
         @@ -107,16 +108,18 @@ module ManageIQ 
     | 
|
| 
       107 
108 
     | 
    
         
             
                  #       msg.payload
         
     | 
| 
       108 
109 
     | 
    
         
             
                  #       msg.ack_ref #used to ack the message
         
     | 
| 
       109 
110 
     | 
    
         
             
                  #
         
     | 
| 
       110 
     | 
    
         
            -
                  #       client.ack(msg.ack_ref)
         
     | 
| 
      
 111 
     | 
    
         
            +
                  #       client.ack(msg.ack_ref) # needed only when options[:auto_ack] is false
         
     | 
| 
       111 
112 
     | 
    
         
             
                  #       # process the message
         
     | 
| 
       112 
113 
     | 
    
         
             
                  #     end
         
     | 
| 
       113 
114 
     | 
    
         
             
                  #   end
         
     | 
| 
       114 
115 
     | 
    
         
             
                  #
         
     | 
| 
       115 
     | 
    
         
            -
                  #  
     | 
| 
      
 116 
     | 
    
         
            +
                  # With the auto_ack option default to true, the message will be automatically
         
     | 
| 
      
 117 
     | 
    
         
            +
                  # acked immediately after the delivery.
         
     | 
| 
      
 118 
     | 
    
         
            +
                  # Some messaging systems allow the subscriber to ack each message in the
         
     | 
| 
       116 
119 
     | 
    
         
             
                  # callback block. The code in the block can decide when to ack according
         
     | 
| 
       117 
120 
     | 
    
         
             
                  # to whether a message can be retried. Ack the message in the beginning of
         
     | 
| 
       118 
121 
     | 
    
         
             
                  # processing if the message is not re-triable; otherwise ack it after the
         
     | 
| 
       119 
     | 
    
         
            -
                  # message is  
     | 
| 
      
 122 
     | 
    
         
            +
                  # message is proccessed. Any un-acked message will be redelivered to next subscriber
         
     | 
| 
       120 
123 
     | 
    
         
             
                  # AFTER the current subscriber disconnects normally or abnormally (e.g. crashed).
         
     | 
| 
       121 
124 
     | 
    
         
             
                  #
         
     | 
| 
       122 
125 
     | 
    
         
             
                  # To ack a message call +ack+(+msg.ack_ref+)
         
     | 
| 
         @@ -131,6 +134,7 @@ module ManageIQ 
     | 
|
| 
       131 
134 
     | 
    
         
             
                  # Expected keys in +options+ are:
         
     | 
| 
       132 
135 
     | 
    
         
             
                  # * :service  (service and affinity are used to determine the queue)
         
     | 
| 
       133 
136 
     | 
    
         
             
                  # * :affinity (optional)
         
     | 
| 
      
 137 
     | 
    
         
            +
                  # * :auto_ack (default true, if it is false, client.ack method must be explicitly called)
         
     | 
| 
       134 
138 
     | 
    
         
             
                  # Other options are underlying messaging system specific.
         
     | 
| 
       135 
139 
     | 
    
         
             
                  #
         
     | 
| 
       136 
140 
     | 
    
         
             
                  # This subscriber consumes messages sent through +publish_message+ with required
         
     | 
| 
         @@ -146,7 +150,7 @@ module ManageIQ 
     | 
|
| 
       146 
150 
     | 
    
         
             
                  #       }
         
     | 
| 
       147 
151 
     | 
    
         
             
                  #     )
         
     | 
| 
       148 
152 
     | 
    
         
             
                  #
         
     | 
| 
       149 
     | 
    
         
            -
                  # Background job assumes each job is not re-triable. It  
     | 
| 
      
 153 
     | 
    
         
            +
                  # Background job assumes each job is not re-triable. It is auto-acked as soon as a request
         
     | 
| 
       150 
154 
     | 
    
         
             
                  # is received
         
     | 
| 
       151 
155 
     | 
    
         
             
                  def subscribe_background_job(options)
         
     | 
| 
       152 
156 
     | 
    
         
             
                    assert_options(options, [:service])
         
     | 
| 
         @@ -179,10 +183,28 @@ module ManageIQ 
     | 
|
| 
       179 
183 
     | 
    
         
             
                  #
         
     | 
| 
       180 
184 
     | 
    
         
             
                  # A callback block is needed to consume the topic:
         
     | 
| 
       181 
185 
     | 
    
         
             
                  #
         
     | 
| 
       182 
     | 
    
         
            -
                  #   client.subcribe_topic(:service => 'provider_events') do | 
     | 
| 
       183 
     | 
    
         
            -
                  #     #  
     | 
| 
      
 186 
     | 
    
         
            +
                  #   client.subcribe_topic(:service => 'provider_events', :auto_ack => false) do |msg|
         
     | 
| 
      
 187 
     | 
    
         
            +
                  #     # msg is a type of ManageIQ::Messaging::ReceivedMessage
         
     | 
| 
      
 188 
     | 
    
         
            +
                  #     # attributes in msg
         
     | 
| 
      
 189 
     | 
    
         
            +
                  #     msg.sender
         
     | 
| 
      
 190 
     | 
    
         
            +
                  #     msg.message
         
     | 
| 
      
 191 
     | 
    
         
            +
                  #     msg.payload
         
     | 
| 
      
 192 
     | 
    
         
            +
                  #     msg.ack_ref #used to ack the message
         
     | 
| 
      
 193 
     | 
    
         
            +
                  #
         
     | 
| 
      
 194 
     | 
    
         
            +
                  #     client.ack(msg.ack_ref) # needed only when options[:auto_ack] is false
         
     | 
| 
      
 195 
     | 
    
         
            +
                  #     # process the message
         
     | 
| 
       184 
196 
     | 
    
         
             
                  #   end
         
     | 
| 
       185 
197 
     | 
    
         
             
                  #
         
     | 
| 
      
 198 
     | 
    
         
            +
                  # With the auto_ack option default to true, the message will be automatically
         
     | 
| 
      
 199 
     | 
    
         
            +
                  # acked immediately after the delivery.
         
     | 
| 
      
 200 
     | 
    
         
            +
                  # Some messaging systems allow the subscriber to ack each message in the
         
     | 
| 
      
 201 
     | 
    
         
            +
                  # callback block. The code in the block can decide when to ack according
         
     | 
| 
      
 202 
     | 
    
         
            +
                  # to whether a message can be retried. Ack the message in the beginning of
         
     | 
| 
      
 203 
     | 
    
         
            +
                  # processing if the message is not re-triable; otherwise ack it after the
         
     | 
| 
      
 204 
     | 
    
         
            +
                  # message is proccessed. Any un-acked message will be redelivered to next subscriber
         
     | 
| 
      
 205 
     | 
    
         
            +
                  # AFTER the current subscriber disconnects normally or abnormally (e.g. crashed).
         
     | 
| 
      
 206 
     | 
    
         
            +
                  #
         
     | 
| 
      
 207 
     | 
    
         
            +
                  # To ack a message call +ack+(+msg.ack_ref+)
         
     | 
| 
       186 
208 
     | 
    
         
             
                  def subscribe_topic(options, &block)
         
     | 
| 
       187 
209 
     | 
    
         
             
                    raise "A block is required" unless block_given?
         
     | 
| 
       188 
210 
     | 
    
         
             
                    assert_options(options, [:service])
         
     | 
| 
         @@ -53,12 +53,16 @@ module ManageIQ 
     | 
|
| 
       53 
53 
     | 
    
         | 
| 
       54 
54 
     | 
    
         
             
                    attr_accessor :encoding
         
     | 
| 
       55 
55 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
                    def ack( 
     | 
| 
      
 56 
     | 
    
         
            +
                    def ack(ack_ref)
         
     | 
| 
      
 57 
     | 
    
         
            +
                      @queue_consumer.try(:mark_message_as_processed, ack_ref)
         
     | 
| 
      
 58 
     | 
    
         
            +
                      @topic_consumer.try(:mark_message_as_processed, ack_ref)
         
     | 
| 
       57 
59 
     | 
    
         
             
                    end
         
     | 
| 
       58 
60 
     | 
    
         | 
| 
       59 
61 
     | 
    
         
             
                    def close
         
     | 
| 
       60 
     | 
    
         
            -
                      @ 
     | 
| 
       61 
     | 
    
         
            -
                      @ 
     | 
| 
      
 62 
     | 
    
         
            +
                      @topic_consumer.try(:stop)
         
     | 
| 
      
 63 
     | 
    
         
            +
                      @topic_consumer = nil
         
     | 
| 
      
 64 
     | 
    
         
            +
                      @queue_consumer.try(:stop)
         
     | 
| 
      
 65 
     | 
    
         
            +
                      @queue_consumer = nil
         
     | 
| 
       62 
66 
     | 
    
         | 
| 
       63 
67 
     | 
    
         
             
                      @producer.try(:shutdown)
         
     | 
| 
       64 
68 
     | 
    
         
             
                      @producer = nil
         
     | 
| 
         @@ -16,7 +16,7 @@ module ManageIQ 
     | 
|
| 
       16 
16 
     | 
    
         
             
                    def topic_consumer(persist_ref)
         
     | 
| 
       17 
17 
     | 
    
         
             
                      # persist_ref enables consumer to receive messages sent when consumer is temporarily offline
         
     | 
| 
       18 
18 
     | 
    
         
             
                      # it also enables consumers to do load balancing when multiple consumers join the with the same ref.
         
     | 
| 
       19 
     | 
    
         
            -
                      @ 
     | 
| 
      
 19 
     | 
    
         
            +
                      @topic_consumer.try(:stop) unless @persist_ref == persist_ref
         
     | 
| 
       20 
20 
     | 
    
         
             
                      @persist_ref = persist_ref
         
     | 
| 
       21 
21 
     | 
    
         
             
                      @topic_consumer ||= kafka_client.consumer(:group_id => persist_ref)
         
     | 
| 
       22 
22 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -27,8 +27,10 @@ module ManageIQ 
     | 
|
| 
       27 
27 
     | 
    
         
             
                    end
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
       29 
29 
     | 
    
         
             
                    trap("TERM") do
         
     | 
| 
       30 
     | 
    
         
            -
                      @ 
     | 
| 
       31 
     | 
    
         
            -
                      @ 
     | 
| 
      
 30 
     | 
    
         
            +
                      @topic_consumer.try(:stop)
         
     | 
| 
      
 31 
     | 
    
         
            +
                      @topic_consumer = nil
         
     | 
| 
      
 32 
     | 
    
         
            +
                      @queue_consumer.try(:stop)
         
     | 
| 
      
 33 
     | 
    
         
            +
                      @queue_consumer = nil
         
     | 
| 
       32 
34 
     | 
    
         
             
                    end
         
     | 
| 
       33 
35 
     | 
    
         | 
| 
       34 
36 
     | 
    
         
             
                    def raw_publish(commit, body, options)
         
     | 
| 
         @@ -82,7 +84,7 @@ module ManageIQ 
     | 
|
| 
       82 
84 
     | 
    
         
             
                        payload = decode_body(message.headers, message.value)
         
     | 
| 
       83 
85 
     | 
    
         
             
                        sender, event_type = parse_event_headers(message.headers)
         
     | 
| 
       84 
86 
     | 
    
         
             
                        logger.info("Event received: topic(#{topic}), event(#{payload_log(payload)}), sender(#{sender}), type(#{event_type})")
         
     | 
| 
       85 
     | 
    
         
            -
                        yield sender, event_type, payload
         
     | 
| 
      
 87 
     | 
    
         
            +
                        yield ManageIQ::Messaging::ReceivedMessage.new(sender, event_type, payload, message)
         
     | 
| 
       86 
88 
     | 
    
         
             
                        logger.info("Event processed")
         
     | 
| 
       87 
89 
     | 
    
         
             
                      rescue StandardError => e
         
     | 
| 
       88 
90 
     | 
    
         
             
                        logger.error("Event processing error: #{e.message}")
         
     | 
| 
         @@ -19,12 +19,12 @@ module ManageIQ 
     | 
|
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
                      consumer = queue_consumer
         
     | 
| 
       21 
21 
     | 
    
         
             
                      consumer.subscribe(topic)
         
     | 
| 
       22 
     | 
    
         
            -
                      consumer.each_batch do |batch|
         
     | 
| 
      
 22 
     | 
    
         
            +
                      consumer.each_batch(:automatically_mark_as_processed => auto_ack?(options)) do |batch|
         
     | 
| 
       23 
23 
     | 
    
         
             
                        logger.info("Batch message received: queue(#{topic})")
         
     | 
| 
       24 
24 
     | 
    
         
             
                        begin
         
     | 
| 
       25 
25 
     | 
    
         
             
                          messages = batch.messages.collect do |message|
         
     | 
| 
       26 
26 
     | 
    
         
             
                            sender, message_type, _class_name, payload = process_queue_message(topic, message)
         
     | 
| 
       27 
     | 
    
         
            -
                            ManageIQ::Messaging::ReceivedMessage.new(sender, message_type, payload,  
     | 
| 
      
 27 
     | 
    
         
            +
                            ManageIQ::Messaging::ReceivedMessage.new(sender, message_type, payload, message)
         
     | 
| 
       28 
28 
     | 
    
         
             
                          end
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
       30 
30 
     | 
    
         
             
                          yield messages
         
     | 
| 
         @@ -15,7 +15,9 @@ module ManageIQ 
     | 
|
| 
       15 
15 
     | 
    
         
             
                      if persist_ref
         
     | 
| 
       16 
16 
     | 
    
         
             
                        consumer = topic_consumer(persist_ref)
         
     | 
| 
       17 
17 
     | 
    
         
             
                        consumer.subscribe(topic, :start_from_beginning => false)
         
     | 
| 
       18 
     | 
    
         
            -
                        consumer.each_message  
     | 
| 
      
 18 
     | 
    
         
            +
                        consumer.each_message(:automatically_mark_as_processed => auto_ack?(options)) do |message|
         
     | 
| 
      
 19 
     | 
    
         
            +
                          process_topic_message(topic, message, &block)
         
     | 
| 
      
 20 
     | 
    
         
            +
                        end
         
     | 
| 
       19 
21 
     | 
    
         
             
                      else
         
     | 
| 
       20 
22 
     | 
    
         
             
                        kafka_client.each_message(:topic => topic, :start_from_beginning => false) do |message|
         
     | 
| 
       21 
23 
     | 
    
         
             
                          process_topic_message(topic, message, &block)
         
     | 
| 
         @@ -28,6 +28,8 @@ module ManageIQ 
     | 
|
| 
       28 
28 
     | 
    
         
             
                      # for STOMP we can get message one at a time
         
     | 
| 
       29 
29 
     | 
    
         
             
                      subscribe(queue_name, headers) do |msg|
         
     | 
| 
       30 
30 
     | 
    
         
             
                        begin
         
     | 
| 
      
 31 
     | 
    
         
            +
                          ack(msg) if auto_ack?(options)
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
       31 
33 
     | 
    
         
             
                          sender = msg.headers['sender']
         
     | 
| 
       32 
34 
     | 
    
         
             
                          message_type = msg.headers['message_type']
         
     | 
| 
       33 
35 
     | 
    
         
             
                          message_body = decode_body(msg.headers, msg.body)
         
     | 
| 
         @@ -17,13 +17,13 @@ module ManageIQ 
     | 
|
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
                      subscribe(queue_name, headers) do |event|
         
     | 
| 
       19 
19 
     | 
    
         
             
                        begin
         
     | 
| 
       20 
     | 
    
         
            -
                          ack(event)
         
     | 
| 
      
 20 
     | 
    
         
            +
                          ack(event) if auto_ack?(options)
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
                          sender = event.headers['sender']
         
     | 
| 
       23 
23 
     | 
    
         
             
                          event_type = event.headers['event_type']
         
     | 
| 
       24 
24 
     | 
    
         
             
                          event_body = decode_body(event.headers, event.body)
         
     | 
| 
       25 
25 
     | 
    
         
             
                          logger.info("Event received: queue(#{queue_name}), event(#{event_body}), headers(#{event.headers})")
         
     | 
| 
       26 
     | 
    
         
            -
                          yield sender, event_type, event_body
         
     | 
| 
      
 26 
     | 
    
         
            +
                          yield ManageIQ::Messaging::ReceivedMessage.new(sender, event_type, event_body, event)
         
     | 
| 
       27 
27 
     | 
    
         
             
                          logger.info("Event processed")
         
     | 
| 
       28 
28 
     | 
    
         
             
                        rescue => e
         
     | 
| 
       29 
29 
     | 
    
         
             
                          logger.error("Event processing error: #{e.message}")
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: manageiq-messaging
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.1. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.1.1
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - ManageIQ Authors
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: exe
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2018- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2018-11-20 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: activesupport
         
     |