-
Notifications
You must be signed in to change notification settings - Fork 18
Persistence #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Persistence #19
Changes from all commits
b973e3a
f476b32
3f1cddb
2c42d0f
c828280
c99c877
3a2189d
bdf1215
15cbac0
e4512ed
41f0c5c
343b0eb
dc0e381
cb71eb3
9592cf1
a6b8d1e
4a12f34
2aaf737
78f34c7
d90eb38
51ecc12
afd68ba
2d97f1d
a0d32de
c6810ae
690cdd3
b1a97be
3386d1b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,6 @@ | ||
| source 'https://rubygems.org' | ||
|
|
||
| gemspec | ||
|
|
||
| gem 'pry' | ||
| gem 'pry-nav' | ||
| gem 'pry-stack_explorer' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| class Cangaroo::Attempt < ActiveRecord::Base | ||
| belongs_to :translation | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| module Cangaroo | ||
| class Translation < ActiveRecord::Base | ||
| include Cangaroo::Log | ||
|
|
||
| belongs_to :destination_connection, class_name: 'Cangaroo::Connection' | ||
| belongs_to :source_connection, class_name: 'Cangaroo::Connection' | ||
|
|
||
| has_many :attempts | ||
|
|
||
| def request=(payload) | ||
| super | ||
|
|
||
| self.object_id = nil | ||
| self.object_key = nil | ||
|
|
||
| determine_payload_identifier | ||
|
|
||
| self.request | ||
| end | ||
|
|
||
| def successful? | ||
| !!self.response | ||
| end | ||
|
|
||
| def related_translations | ||
| Cangaroo::Translation.where( | ||
| object_type: self.object_type, | ||
| object_key: self.object_key, | ||
| object_id: self.object_id, | ||
| ) | ||
| .where.not(job_id: self.job_id) | ||
| end | ||
|
|
||
| def determine_object_key_from_payload | ||
| Rails.configuration.cangaroo.payload_keys.each do |payload_key| | ||
| if self.request[payload_key].present? | ||
| return payload_key | ||
| end | ||
| end | ||
|
|
||
| nil | ||
| end | ||
|
|
||
| def determine_payload_identifier | ||
| self.object_key = determine_object_key_from_payload | ||
|
|
||
| if self.object_key | ||
| self.object_id = self.request[self.object_key] | ||
| else | ||
| log.info 'unable to find primary key', translation: self | ||
| end | ||
| end | ||
|
|
||
| def retry | ||
| Cangaroo::PerformJobs.call( | ||
| # TODO this should be abstracted away into a interator that accepts json payloads | ||
| json_body: { self.object_type => [ self.request ] }.to_json, | ||
| source_connection: self.source_connection, | ||
| jobs: Rails.configuration.cangaroo.jobs | ||
| ) | ||
| end | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| class CreateTranslations < ActiveRecord::Migration | ||
| def change | ||
| create_table :cangaroo_translations do |t| | ||
| t.references :source_connection, index: true | ||
| t.references :destination_connection, index: true | ||
|
|
||
| t.string :job_id | ||
|
|
||
| t.string :object_type | ||
| t.string :object_id | ||
| t.string :object_key | ||
|
|
||
| t.jsonb :request | ||
| t.jsonb :response | ||
|
|
||
| t.timestamps null: false | ||
| end | ||
|
|
||
| add_foreign_key :cangaroo_translations, :cangaroo_connections, column: :source_connection_id | ||
| add_foreign_key :cangaroo_translations, :cangaroo_connections, column: :destination_connection_id | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| class CreateCangarooAttempts < ActiveRecord::Migration | ||
| def change | ||
| create_table :cangaroo_attempts do |t| | ||
| t.references :translation, index: true | ||
| t.integer :response_code | ||
| t.jsonb :response | ||
|
|
||
| t.timestamps null: false | ||
| end | ||
|
|
||
| add_foreign_key :cangaroo_attempts, :cangaroo_translations, column: :translation_id | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| FactoryGirl.define do | ||
| factory :translation, class: 'Cangaroo::Translation' do | ||
| source_connection { FactoryGirl.create(:cangaroo_connection, name: Faker::Company.name, url: Faker::Internet.domain_name) } | ||
| destination_connection { FactoryGirl.create(:cangaroo_connection, name: Faker::Company.name, url: Faker::Internet.domain_name) } | ||
|
|
||
| job_id { SecureRandom.uuid } | ||
| object_type 'customers' | ||
|
|
||
| request { | ||
| { | ||
| "id" => SecureRandom.random_number(1000), | ||
| "updated_at" => DateTime.now.iso8601, | ||
| "created_at" => DateTime.now.iso8601 | ||
| } | ||
| } | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,7 +11,7 @@ class FakeJob < Cangaroo::Job | |
| let(:job_class) { FakeJob } | ||
| let(:destination_connection) { create(:cangaroo_connection) } | ||
| let(:type) { 'orders' } | ||
| let(:payload) { { id: 'O123' } } | ||
| let(:payload) { { "id" => 'O123' } } | ||
| let(:connection_response) { parse_fixture('json_payload_connection_response.json') } | ||
|
|
||
| let(:options) do | ||
|
|
@@ -43,11 +43,12 @@ class FakeJob < Cangaroo::Job | |
| it 'calls post on client' do | ||
| job.perform | ||
| expect(client).to have_received(:post) | ||
| .with(job.transform, job.job_id, email: 'info@nebulab.it') | ||
| .with(job.transform, job.job_id, { email: 'info@nebulab.it' }, an_instance_of(Cangaroo::Translation)) | ||
| end | ||
|
|
||
| it 'restart the flow' do | ||
| job.perform | ||
|
|
||
| expect(Cangaroo::PerformFlow).to have_received(:call) | ||
| .once | ||
| .with(source_connection: destination_connection, | ||
|
|
@@ -63,6 +64,31 @@ class FakeJob < Cangaroo::Job | |
| expect(Cangaroo::PerformFlow).to_not have_received(:call) | ||
| end | ||
|
|
||
| it 'creates a translation record and stores the response' do | ||
| job.perform | ||
|
|
||
| translation = Cangaroo::Translation.find_by(job_id: job.job_id) | ||
|
|
||
| expect(translation).to_not be_nil | ||
| expect(translation.successful?).to eq(true) | ||
| expect(translation.destination_connection).to eq(destination_connection) | ||
| expect(translation.object_type).to eq('orders') | ||
| expect(translation.object_key).to eq('id') | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping. |
||
| expect(translation.object_id).to eq('O123') | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping. |
||
| end | ||
|
|
||
| context 'endpoint communication fails' do | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping. |
||
| it 'creates a unsuccessful translation model' do | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping. |
||
| client.stub(:post).and_raise('an error') | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping. |
||
|
|
||
| expect { job.perform }.to raise_error | ||
|
|
||
| translation = Cangaroo::Translation.find_by(job_id: job.job_id) | ||
| expect(translation).to_not be_nil | ||
| expect(translation.successful?).to eq(false) | ||
| end | ||
| end | ||
|
|
||
| context 'endpoint provides a empty response' do | ||
| it 'should not restart the flow' do | ||
| allow(client).to receive(:post).and_return('') | ||
|
|
@@ -81,5 +107,17 @@ class FakeJob < Cangaroo::Job | |
| describe '#transform' do | ||
| it { expect(job_class.new(options).transform).to eq('order' => payload) } | ||
| end | ||
|
|
||
| describe '#payload_state' do | ||
| let(:job) { job_class.new(options) } | ||
|
|
||
| it { expect(job.payload_state).to eq(:new) } | ||
|
|
||
| it 'returns updated when a previous matching payload exists' do | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping. |
||
| allow_any_instance_of(Cangaroo::Translation).to receive(:related_translations).and_return([OpenStruct.new()]) | ||
|
|
||
| expect(job.payload_state).to eq(:updated) | ||
| end | ||
| end | ||
| end | ||
| end | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.