cmor_transports 0.0.56.pre

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.
Files changed (83) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +28 -0
  4. data/Rakefile +19 -0
  5. data/app/assets/config/cmor/transports_manifest.js +1 -0
  6. data/app/assets/javascripts/cmor/transports/application.js +2 -0
  7. data/app/assets/javascripts/cmor/transports/application/keep.js +0 -0
  8. data/app/assets/javascripts/cmor_transports.js +2 -0
  9. data/app/assets/stylesheets/cmor/transports/application.css +3 -0
  10. data/app/assets/stylesheets/cmor/transports/application/keep.css +0 -0
  11. data/app/assets/stylesheets/cmor_transports.css +3 -0
  12. data/app/concerns/cmor/transports/models/uuid_concern.rb +20 -0
  13. data/app/concerns/cmor/transports/resources_controller/export_concern.rb +63 -0
  14. data/app/concerns/cmor/transports/routing/export_resources_concern.rb +30 -0
  15. data/app/controllers/cmor/transports/api/incoming/create_services_controller.rb +22 -0
  16. data/app/controllers/cmor/transports/api/incoming/show_services_controller.rb +22 -0
  17. data/app/controllers/cmor/transports/export_sidebars_controller.rb +11 -0
  18. data/app/controllers/cmor/transports/exports_controller.rb +24 -0
  19. data/app/controllers/cmor/transports/home_controller.rb +6 -0
  20. data/app/controllers/cmor/transports/incomings_controller.rb +16 -0
  21. data/app/controllers/cmor/transports/outgoings_controller.rb +16 -0
  22. data/app/controllers/cmor/transports/systems_controller.rb +14 -0
  23. data/app/models/cmor/transports/export.rb +61 -0
  24. data/app/models/cmor/transports/import.rb +37 -0
  25. data/app/models/cmor/transports/incoming.rb +40 -0
  26. data/app/models/cmor/transports/outgoing.rb +98 -0
  27. data/app/models/cmor/transports/outgoing_export.rb +8 -0
  28. data/app/models/cmor/transports/outgoing_target.rb +20 -0
  29. data/app/models/cmor/transports/system.rb +15 -0
  30. data/app/services/cmor/transports/api/incoming/create_service.rb +45 -0
  31. data/app/services/cmor/transports/api/incoming/show_service.rb +22 -0
  32. data/app/services/cmor/transports/exports/base.rb +74 -0
  33. data/app/services/cmor/transports/exports/csv_service.rb +32 -0
  34. data/app/services/cmor/transports/exports/json_service.rb +25 -0
  35. data/app/services/cmor/transports/exports/yaml_service.rb +25 -0
  36. data/app/services/cmor/transports/packs/base.rb +19 -0
  37. data/app/services/cmor/transports/packs/zip_service.rb +28 -0
  38. data/app/services/cmor/transports/transfers/api/incoming_state_service.rb +39 -0
  39. data/app/services/cmor/transports/transfers/api/push_service.rb +47 -0
  40. data/app/view_helpers/cmor/transports/application_view_helper.rb +6 -0
  41. data/app/view_helpers/cmor/transports/export_view_helper.rb +63 -0
  42. data/app/views/cmor/core/backend/resources_controller/base/_export_form.html.haml +3 -0
  43. data/app/views/cmor/core/backend/resources_controller/base/export.html.haml +6 -0
  44. data/app/views/cmor/transports/export_sidebars/show.html.haml +1 -0
  45. data/app/views/cmor/transports/exports/_after_show_table.html.haml +9 -0
  46. data/app/views/cmor/transports/exports/_form.html.haml +6 -0
  47. data/app/views/cmor/transports/exports/_index_table.html.haml +14 -0
  48. data/app/views/cmor/transports/exports/_show_table.html.haml +17 -0
  49. data/app/views/cmor/transports/incomings/_index_table.html.haml +12 -0
  50. data/app/views/cmor/transports/outgoings/_after_show_table.html.haml +26 -0
  51. data/app/views/cmor/transports/outgoings/_form.html.haml +2 -0
  52. data/app/views/cmor/transports/outgoings/_index_table.html.haml +8 -0
  53. data/app/views/cmor/transports/outgoings/_show_table.html.haml +11 -0
  54. data/config/initializers/assets.rb +2 -0
  55. data/config/initializers/cmor.rb +3 -0
  56. data/config/initializers/include_routing_concerns.rb +1 -0
  57. data/config/locales/de.yml +43 -0
  58. data/config/locales/en.yml +41 -0
  59. data/config/routes.rb +31 -0
  60. data/db/migrate/20200525095216_create_cmor_transports_exports.rb +20 -0
  61. data/db/migrate/20200607101713_create_cmor_transports_outgoings.rb +15 -0
  62. data/db/migrate/20200607102346_create_cmor_transports_outgoing_exports.rb +10 -0
  63. data/db/migrate/20200607105529_create_cmor_transports_systems.rb +11 -0
  64. data/db/migrate/20200607105839_create_cmor_transports_outgoing_targets.rb +10 -0
  65. data/db/migrate/20200607110930_create_cmor_transports_incomings.rb +16 -0
  66. data/db/migrate/20200607111046_create_cmor_transports_imports.rb +17 -0
  67. data/lib/cmor/transports/configuration.rb +41 -0
  68. data/lib/cmor/transports/engine.rb +19 -0
  69. data/lib/cmor/transports/version.rb +7 -0
  70. data/lib/cmor_transports.rb +18 -0
  71. data/lib/generators/cmor/transports/install/install_generator.rb +26 -0
  72. data/lib/generators/cmor/transports/install/templates/initializer.rb +45 -0
  73. data/lib/generators/cmor/transports/install/templates/routes.source +4 -0
  74. data/lib/tasks/cmor/transports_tasks.rake +5 -0
  75. data/spec/factories/cmor_transports_exports.rb +11 -0
  76. data/spec/factories/cmor_transports_imports.rb +7 -0
  77. data/spec/factories/cmor_transports_incomings.rb +7 -0
  78. data/spec/factories/cmor_transports_outgoing_exports.rb +8 -0
  79. data/spec/factories/cmor_transports_outgoing_targets.rb +8 -0
  80. data/spec/factories/cmor_transports_outgoings.rb +6 -0
  81. data/spec/factories/cmor_transports_systems.rb +9 -0
  82. data/spec/files/cmor/transports/outgoing/output/example.zip +0 -0
  83. metadata +601 -0
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor::Transports
4
+ class Incoming < ApplicationRecord
5
+ include Cmor::Transports::Models::UuidConcern
6
+ include AASM
7
+
8
+ belongs_to :creator, optional: true, polymorphic: true
9
+ # belongs_to :job, optional: true
10
+
11
+ has_one_attached :input
12
+ has_one_attached :payload
13
+
14
+ validates :outgoing_uuid, presence: true, uniqueness: true
15
+
16
+ aasm(:default, column: "state") do
17
+ state :created, initial: true
18
+ state :enqueued
19
+ state :processing
20
+ state :failed
21
+ state :succeeded
22
+
23
+ event :enqueue, after: :enqueue_service_call do
24
+ transitions from: :created, to: :enqueued
25
+ end
26
+
27
+ event :process do
28
+ transitions from: [:created, :enqueued], to: :processing
29
+ end
30
+
31
+ event :fail do
32
+ transitions from: :processing, to: :failed
33
+ end
34
+
35
+ event :succeed do
36
+ transitions from: :processing, to: :succeeded
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor::Transports
4
+ class Outgoing < ApplicationRecord
5
+ include Cmor::Transports::Models::UuidConcern
6
+ include AASM
7
+
8
+ belongs_to :creator, optional: true, polymorphic: true
9
+
10
+ has_many :outgoing_exports, dependent: :destroy
11
+ has_many :exports, through: :outgoing_exports
12
+
13
+ has_many :outgoing_targets, dependent: :destroy
14
+ has_many :systems, through: :outgoing_targets
15
+
16
+ has_one_attached :output
17
+
18
+ validates :state, presence: true
19
+
20
+ aasm(:default, column: "state") do
21
+ state :created, initial: true
22
+ state :enqueued_for_pack
23
+ state :packing
24
+ state :failed_packing
25
+ state :succeeded_packing
26
+ state :enqueued_for_transfer
27
+ state :transferring
28
+ state :failed_transferring
29
+ state :succeeded_transferring
30
+
31
+ event :enqueue_packing, after: :enqueue_packing_service_call do
32
+ transitions from: :created, to: :enqueued_for_pack
33
+ end
34
+
35
+ event :start_packing do
36
+ transitions from: :enqueued_for_pack, to: :packing
37
+ end
38
+
39
+ event :failed_packing do
40
+ transitions from: :packing, to: :failed_packing
41
+ end
42
+
43
+ event :succeed_packing do
44
+ transitions from: :packing, to: :succeeded_packing
45
+ end
46
+
47
+ event :reset_packing do
48
+ transitions from: [:enqueued_for_packing, :failed_packing], to: :created
49
+ end
50
+
51
+ event :enqueue_for_transfer, after: :enqueue_transferring_service_call do
52
+ transitions from: :succeeded_packing, to: :enqueued_for_transfer
53
+ end
54
+
55
+ event :start_transferring do
56
+ transitions from: :enqueued_for_transfer, to: :transferring
57
+ end
58
+
59
+ event :failed_transferring do
60
+ transitions from: :transferring, to: :failed_transferring
61
+ end
62
+
63
+ event :reset_transferring do
64
+ transitions from: [:enqueued_for_transfer, :failed_transferring], to: :succeeded_packing
65
+ end
66
+
67
+ event :succeed_transferring do
68
+ transitions from: :transferring, to: :succeeded_transferring
69
+ end
70
+ end
71
+
72
+ def enqueue_packing_service_call
73
+ result = pack_service_class_name.constantize.call_later!(outgoing: self)
74
+ self.job_id = result.job_id
75
+ end
76
+
77
+ def enqueue_transferring_service_call
78
+ result = transfer_service_class_name.constantize.call_later!(outgoing: self)
79
+ self.job_id = result.job_id
80
+ end
81
+
82
+ def pack_service_class_name
83
+ "Cmor::Transports::Packs::ZipService"
84
+ end
85
+
86
+ def transfer_service_class_name
87
+ "Cmor::Transports::Transfers::Api::PushService"
88
+ end
89
+
90
+ def output_base64
91
+ if output.attached?
92
+ Base64.encode64(output.attachment.blob.download)
93
+ else
94
+ nil
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor::Transports
4
+ class OutgoingExport < ApplicationRecord
5
+ belongs_to :outgoing
6
+ belongs_to :export
7
+ end
8
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor::Transports
4
+ class OutgoingTarget < ApplicationRecord
5
+ belongs_to :outgoing
6
+ belongs_to :system
7
+
8
+ delegate :identifier, :endpoint, :api_key, to: :system, prefix: true, allow_nil: true
9
+ delegate :uuid, to: :outgoing, prefix: true, allow_nil: true
10
+
11
+ def incoming_status
12
+ result = Cmor::Transports::Transfers::Api::IncomingStateService.call(system_identifier: system_identifier, endpoint: system_endpoint, api_key: system_api_key, outgoing_uuid: outgoing_uuid)
13
+ if result.ok?
14
+ result.incoming
15
+ else
16
+ nil
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor::Transports
4
+ class System < ApplicationRecord
5
+ has_many :outgoing_targets
6
+
7
+ validates :identifier, presence: true, uniqueness: true
8
+ validates :endpoint, presence: true, uniqueness: true
9
+ validates :api_key, presence: true
10
+
11
+ def human
12
+ "#{identifier} | #{endpoint}"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Transports
5
+ module Api
6
+ module Incoming
7
+ class CreateService < Rao::Service::Base
8
+ class Result < Rao::Service::Result::Base
9
+ end
10
+
11
+ attr_accessor :outgoing, :incoming
12
+
13
+ validates :outgoing_output_base64, presence: true
14
+
15
+
16
+ def save
17
+ if @incoming.save
18
+ say "Saved incoming with id #{@incoming.id}"
19
+ else
20
+ add_error_and_say "Could not save incoming. Errors: #{@incoming.errors.full_messages.to_sentence}"
21
+ end
22
+ end
23
+
24
+ def outgoing_output_base64
25
+ outgoing["output_base64"] if outgoing.respond_to?(:[])
26
+ end
27
+
28
+ private
29
+ def _perform
30
+ build_incoming!
31
+ end
32
+
33
+ def build_incoming!
34
+ @incoming = Cmor::Transports::Incoming.new.tap do |i|
35
+ i.outgoing_uuid = outgoing["uuid"]
36
+ i.payload.attach(io: StringIO.new(Base64.decode64(outgoing["output_base64"])), filename: "payload.zip", content_type: "application/zip")
37
+ i.input.attach(io: StringIO.new(outgoing.to_json), filename: "outgoing.json", content_type: "application/json")
38
+ i
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Transports
5
+ module Api
6
+ module Incoming
7
+ class ShowService < Rao::Service::Base
8
+ class Result < Rao::Service::Result::Base
9
+ attr_accessor :incoming
10
+ end
11
+
12
+ attr_accessor :outgoing_uuid
13
+
14
+ private
15
+ def _perform
16
+ @result.incoming = @incoming = Cmor::Transports::Incoming.where(outgoing_uuid: outgoing_uuid).first
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Transports
5
+ module Exports
6
+ class Base < Rao::Service::Base
7
+ class Result < Rao::Service::Result::Base
8
+ attr_accessor :export
9
+ end
10
+
11
+ attr_accessor :export
12
+
13
+ private
14
+ def _perform
15
+ export.aasm.fire(:process)
16
+ generate_output!
17
+ if @errors.any?
18
+ export.aasm.fire(:fail)
19
+ return @result
20
+ end
21
+
22
+ attach_output_to_export!
23
+ if @errors.any?
24
+ export.aasm.fire(:fail)
25
+ return @result
26
+ end
27
+
28
+ export.aasm.fire(:succeed)
29
+ end
30
+
31
+ def after_perform
32
+ @export.service_errors = @errors.full_messages.to_sentence
33
+ @export.service_messages = @messages.map(&:to_s)
34
+ @result.export = @export
35
+ end
36
+
37
+ def save
38
+ export.save!
39
+ end
40
+
41
+ def generate_output!
42
+ raise "Child class responsibility"
43
+ end
44
+
45
+ def attach_output_to_export!
46
+ export.output.attach(attributes_for_attachment)
47
+ end
48
+
49
+ def attributes_for_attachment
50
+ raise "Child class responsibility"
51
+ end
52
+
53
+
54
+ def load_collection
55
+ resource_class.find_by_sql(export.query)
56
+ end
57
+
58
+ def resource_class
59
+ export.root_model.constantize
60
+ end
61
+
62
+ def resource_attributes
63
+ export.output_attributes || resource_class.attribute_names
64
+ end
65
+
66
+ def build_resource_hash(resource)
67
+ resource_attributes.each_with_object({}) do |attr, memo|
68
+ memo[attr] = resource.send(attr)
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "csv"
4
+
5
+ module Cmor
6
+ module Transports
7
+ module Exports
8
+ class CsvService < Base
9
+ class Result < Base::Result
10
+ end
11
+
12
+ private
13
+ def generate_output!
14
+ @output = CSV.generate(headers: true) do |csv|
15
+ csv << resource_attributes
16
+ load_collection.each do |resource|
17
+ csv << build_resource_hash(resource).values
18
+ end
19
+ end
20
+ end
21
+
22
+ def attributes_for_attachment
23
+ {
24
+ io: StringIO.new(@output),
25
+ filename: "export_#{export.id}.csv",
26
+ content_type: "text/csv"
27
+ }
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Transports
5
+ module Exports
6
+ class JsonService < Base
7
+ class Result < Base::Result
8
+ end
9
+
10
+ private
11
+ def generate_output!
12
+ @output = load_collection.collect { |r| build_resource_hash(r) }.to_json
13
+ end
14
+
15
+ def attributes_for_attachment
16
+ {
17
+ io: StringIO.new(@output),
18
+ filename: "export_#{export.id}.json",
19
+ content_type: "application/json"
20
+ }
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Transports
5
+ module Exports
6
+ class YamlService < Base
7
+ class Result < Base::Result
8
+ end
9
+
10
+ private
11
+ def generate_output!
12
+ @output = load_collection.collect { |r| build_resource_hash(r) }.to_yaml
13
+ end
14
+
15
+ def attributes_for_attachment
16
+ {
17
+ io: StringIO.new(@output),
18
+ filename: "export_#{export.id}.yaml",
19
+ content_type: "application/x-yaml"
20
+ }
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Transports
5
+ module Packs
6
+ class Base < Rao::Service::Base
7
+ class Result < Rao::Service::Result::Base
8
+ end
9
+
10
+ attr_accessor :outgoing
11
+
12
+ private
13
+ def _perform
14
+ pack_and_attach!
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Transports
5
+ module Packs
6
+ class ZipService < Base
7
+ private
8
+ def pack_and_attach!
9
+ outgoing.start_packing!
10
+ stringio = Zip::OutputStream.write_buffer do |zio|
11
+ outgoing.exports.map(&:output).each do |attachment|
12
+ zio.put_next_entry(attachment.filename)
13
+ zio.write attachment.blob.download
14
+ end
15
+ end
16
+
17
+ stringio.rewind
18
+
19
+ @outgoing.output.attach(io: stringio, filename: "output.zip", content_type: "application/zip")
20
+ outgoing.succeed_packing!
21
+ rescue => e
22
+ outgoing.failed_packing!
23
+ raise e
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end