aspera-cli 4.15.0 → 4.17.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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/BUGS.md +29 -3
  4. data/CHANGELOG.md +375 -280
  5. data/CONTRIBUTING.md +71 -18
  6. data/README.md +1978 -1656
  7. data/bin/ascli +13 -31
  8. data/bin/asession +32 -22
  9. data/examples/dascli +2 -2
  10. data/lib/aspera/agent/alpha.rb +117 -0
  11. data/lib/aspera/agent/base.rb +61 -0
  12. data/lib/aspera/{fasp/agent_connect.rb → agent/connect.rb} +13 -11
  13. data/lib/aspera/{fasp/agent_direct.rb → agent/direct.rb} +116 -116
  14. data/lib/aspera/{fasp/agent_httpgw.rb → agent/httpgw.rb} +21 -19
  15. data/lib/aspera/{fasp/agent_node.rb → agent/node.rb} +21 -33
  16. data/lib/aspera/agent/trsdk.rb +188 -0
  17. data/lib/aspera/api/aoc.rb +586 -0
  18. data/lib/aspera/api/ats.rb +46 -0
  19. data/lib/aspera/api/cos_node.rb +95 -0
  20. data/lib/aspera/api/node.rb +344 -0
  21. data/lib/aspera/ascmd.rb +47 -14
  22. data/lib/aspera/{fasp → ascp}/installation.rb +54 -15
  23. data/lib/aspera/{fasp → ascp}/management.rb +14 -14
  24. data/lib/aspera/{fasp → ascp}/products.rb +1 -1
  25. data/lib/aspera/assert.rb +45 -0
  26. data/lib/aspera/cli/basic_auth_plugin.rb +11 -10
  27. data/lib/aspera/cli/extended_value.rb +5 -5
  28. data/lib/aspera/cli/formatter.rb +27 -14
  29. data/lib/aspera/cli/hints.rb +7 -6
  30. data/lib/aspera/cli/main.rb +49 -29
  31. data/lib/aspera/cli/manager.rb +46 -36
  32. data/lib/aspera/cli/plugin.rb +34 -20
  33. data/lib/aspera/cli/plugin_factory.rb +61 -0
  34. data/lib/aspera/cli/plugins/alee.rb +7 -7
  35. data/lib/aspera/cli/plugins/aoc.rb +168 -132
  36. data/lib/aspera/cli/plugins/ats.rb +33 -33
  37. data/lib/aspera/cli/plugins/bss.rb +3 -4
  38. data/lib/aspera/cli/plugins/config.rb +250 -272
  39. data/lib/aspera/cli/plugins/console.rb +8 -6
  40. data/lib/aspera/cli/plugins/cos.rb +20 -19
  41. data/lib/aspera/cli/plugins/faspex.rb +71 -60
  42. data/lib/aspera/cli/plugins/faspex5.rb +212 -133
  43. data/lib/aspera/cli/plugins/node.rb +83 -75
  44. data/lib/aspera/cli/plugins/orchestrator.rb +36 -44
  45. data/lib/aspera/cli/plugins/preview.rb +33 -31
  46. data/lib/aspera/cli/plugins/server.rb +33 -32
  47. data/lib/aspera/cli/plugins/shares.rb +39 -33
  48. data/lib/aspera/cli/sync_actions.rb +9 -9
  49. data/lib/aspera/cli/transfer_agent.rb +45 -25
  50. data/lib/aspera/cli/transfer_progress.rb +2 -3
  51. data/lib/aspera/cli/version.rb +1 -1
  52. data/lib/aspera/colors.rb +5 -0
  53. data/lib/aspera/command_line_builder.rb +16 -14
  54. data/lib/aspera/coverage.rb +21 -0
  55. data/lib/aspera/data_repository.rb +33 -2
  56. data/lib/aspera/environment.rb +5 -4
  57. data/lib/aspera/faspex_gw.rb +13 -11
  58. data/lib/aspera/faspex_postproc.rb +6 -5
  59. data/lib/aspera/id_generator.rb +4 -2
  60. data/lib/aspera/json_rpc.rb +10 -8
  61. data/lib/aspera/keychain/encrypted_hash.rb +46 -11
  62. data/lib/aspera/keychain/macos_security.rb +29 -22
  63. data/lib/aspera/log.rb +5 -4
  64. data/lib/aspera/nagios.rb +7 -2
  65. data/lib/aspera/node_simulator.rb +213 -0
  66. data/lib/aspera/oauth/base.rb +143 -0
  67. data/lib/aspera/oauth/factory.rb +124 -0
  68. data/lib/aspera/oauth/generic.rb +34 -0
  69. data/lib/aspera/oauth/jwt.rb +51 -0
  70. data/lib/aspera/oauth/url_json.rb +31 -0
  71. data/lib/aspera/oauth/web.rb +50 -0
  72. data/lib/aspera/oauth.rb +5 -328
  73. data/lib/aspera/open_application.rb +7 -7
  74. data/lib/aspera/persistency_action_once.rb +13 -14
  75. data/lib/aspera/persistency_folder.rb +3 -2
  76. data/lib/aspera/preview/file_types.rb +53 -267
  77. data/lib/aspera/preview/generator.rb +7 -5
  78. data/lib/aspera/preview/terminal.rb +17 -7
  79. data/lib/aspera/preview/utils.rb +8 -7
  80. data/lib/aspera/proxy_auto_config.rb +6 -3
  81. data/lib/aspera/rest.rb +187 -140
  82. data/lib/aspera/rest_error_analyzer.rb +1 -0
  83. data/lib/aspera/rest_errors_aspera.rb +5 -3
  84. data/lib/aspera/resumer.rb +77 -0
  85. data/lib/aspera/secret_hider.rb +5 -2
  86. data/lib/aspera/ssh.rb +15 -8
  87. data/lib/aspera/temp_file_manager.rb +1 -1
  88. data/lib/aspera/{fasp → transfer}/error.rb +3 -3
  89. data/lib/aspera/{fasp → transfer}/error_info.rb +1 -1
  90. data/lib/aspera/{fasp → transfer}/faux_file.rb +1 -1
  91. data/lib/aspera/{fasp → transfer}/parameters.rb +95 -120
  92. data/lib/aspera/{fasp/transfer_spec.rb → transfer/spec.rb} +23 -19
  93. data/lib/aspera/{fasp/parameters.yaml → transfer/spec.yaml} +4 -99
  94. data/lib/aspera/transfer/sync.rb +273 -0
  95. data/lib/aspera/{fasp → transfer}/uri.rb +10 -9
  96. data/lib/aspera/web_server_simple.rb +12 -3
  97. data.tar.gz.sig +0 -0
  98. metadata +92 -68
  99. metadata.gz.sig +0 -0
  100. data/lib/aspera/aoc.rb +0 -606
  101. data/lib/aspera/ats_api.rb +0 -47
  102. data/lib/aspera/cos_node.rb +0 -93
  103. data/lib/aspera/fasp/agent_aspera.rb +0 -126
  104. data/lib/aspera/fasp/agent_base.rb +0 -48
  105. data/lib/aspera/fasp/agent_trsdk.rb +0 -146
  106. data/lib/aspera/fasp/resume_policy.rb +0 -77
  107. data/lib/aspera/node.rb +0 -338
  108. data/lib/aspera/sync.rb +0 -219
data/bin/ascli CHANGED
@@ -3,36 +3,18 @@
3
3
 
4
4
  Encoding.default_internal = Encoding::UTF_8
5
5
  Encoding.default_external = Encoding::UTF_8
6
- # coverage for tests
7
- if ENV.key?('ENABLE_COVERAGE')
8
- require 'simplecov'
9
- require 'securerandom'
10
- # compute gem source root based on this script location, assuming it is in bin/
11
- # use dirname instead of gsub, in case folder separator is not /
12
- development_root = File.dirname(File.dirname(File.realpath(__FILE__)))
13
- SimpleCov.root(development_root)
14
- SimpleCov.enable_for_subprocesses if SimpleCov.respond_to?(:enable_for_subprocesses)
15
- # keep cache data for 1 day (must be longer that time to run the whole test suite)
16
- SimpleCov.merge_timeout(86400)
17
- SimpleCov.command_name(SecureRandom.uuid)
18
- SimpleCov.at_exit do
19
- original_file_descriptor = $stdout
20
- $stdout.reopen(File.join(development_root, 'simplecov.log'))
21
- SimpleCov.result.format!
22
- $stdout.reopen(original_file_descriptor)
23
- end
24
- SimpleCov.start
25
- end
26
- # if in development, add path to gem
27
- #
6
+
28
7
  begin
29
- require 'aspera/cli/main'
30
- rescue LoadError
31
- # development environment
32
- development_root = File.dirname(File.dirname(File.realpath(__FILE__)))
33
- $LOAD_PATH.unshift(File.join(development_root, 'lib'))
34
- require 'aspera/cli/main'
8
+ gem_lib_folder = File.join(File.dirname(File.dirname(File.realpath(__FILE__))), 'lib')
9
+ Kernel.load(File.join(gem_lib_folder, 'aspera/coverage.rb'))
10
+ begin
11
+ require 'aspera/cli/main'
12
+ rescue LoadError
13
+ # if in development, add path toward gem
14
+ $LOAD_PATH.unshift(gem_lib_folder)
15
+ require 'aspera/cli/main'
16
+ end
17
+ require 'aspera/environment'
18
+ Aspera::Environment.fix_home
19
+ Aspera::Cli::Main.new(ARGV).process_command_line
35
20
  end
36
- require 'aspera/environment'
37
- Aspera::Environment.fix_home
38
- Aspera::Cli::Main.new(ARGV).process_command_line
data/bin/asession CHANGED
@@ -3,16 +3,18 @@
3
3
 
4
4
  # Laurent Martin/2017
5
5
  $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib")
6
- require 'aspera/fasp/agent_direct'
6
+ require 'aspera/agent/direct'
7
7
  require 'aspera/cli/extended_value'
8
+ require 'aspera/ascp/installation'
8
9
  require 'aspera/log'
9
10
  require 'json'
10
11
  # extended transfer spec parameter (only used in asession)
11
12
  # Change log level
12
- TS_LOG_LEVEL = 'EX_loglevel'
13
+ PARAM_LOG_LEVEL = 'loglevel'
13
14
  # by default go to /tmp/username.filelist
14
- TS_TMP_FILE_LIST_FOLDER = 'EX_file_list_folder'
15
-
15
+ PARAM_TMP_FILE_LIST_FOLDER = 'file_list_folder'
16
+ # place transfer spec in that
17
+ PARAM_SPEC = 'spec'
16
18
  SAMPLE_DEMO = '"remote_host":"demo.asperasoft.com","remote_user":"asperaweb","ssh_port":33001,"remote_password":"demoaspera"'
17
19
  SAMPLE_DEMO2 = '"direction":"receive","destination_root":"./test.dir"'
18
20
  def assert_usage(assertion, error_message)
@@ -21,25 +23,27 @@ def assert_usage(assertion, error_message)
21
23
  $stderr.puts('USAGE')
22
24
  $stderr.puts(' asession')
23
25
  $stderr.puts(' asession -h|--help')
24
- $stderr.puts(' asession <transfer spec extended value>')
26
+ $stderr.puts(' asession <session spec extended value>')
25
27
  $stderr.puts(' ')
26
28
  $stderr.puts(' If no argument is provided, default will be used: @json:@stdin')
27
29
  $stderr.puts(' -h, --help display this message')
28
- $stderr.puts(' <transfer spec extended value> a JSON value for transfer_spec, using the prefix: @json:')
30
+ $stderr.puts(' <session spec extended value> a dictionary value (Hash)')
29
31
  $stderr.puts(' The value can be either:')
30
32
  $stderr.puts(" the JSON description itself, e.g. @json:'{\"xx\":\"yy\",...}'")
31
33
  $stderr.puts(' @json:@stdin, if the JSON is provided from stdin')
32
34
  $stderr.puts(' @json:@file:<path>, if the JSON is provided from a file')
35
+ $stderr.puts(" Parameter #{PARAM_SPEC} is mandatory, it contains the transfer spec")
33
36
  $stderr.puts(' Asynchronous commands can be provided on STDIN, examples:')
34
37
  $stderr.puts(' {"type":"START","source":"/aspera-test-dir-tiny/200KB.2"}')
35
38
  $stderr.puts(' {"type":"START","source":"xx","destination":"yy"}')
36
39
  $stderr.puts(' {"type":"DONE"}')
37
- $stderr.puts(%Q(Note: debug information can be placed on STDERR, using the "#{TS_LOG_LEVEL}" parameter in transfer spec (debug=0)))
40
+ $stderr.puts(%Q(Note: debug information can be placed on STDERR, using the "#{PARAM_LOG_LEVEL}" parameter in session spec (debug=0)))
38
41
  $stderr.puts('EXAMPLES')
39
- $stderr.puts(%Q( asession @json:'{#{SAMPLE_DEMO},#{SAMPLE_DEMO2},"paths":[{"source":"/aspera-test-dir-tiny/200KB.1"}]}'))
40
- $stderr.puts(%q( echo '{"remote_host":...}'|asession @json:@stdin))
42
+ $stderr.puts(%Q( asession @json:'{"#{PARAM_SPEC}":{#{SAMPLE_DEMO},#{SAMPLE_DEMO2},"paths":[{"source":"/aspera-test-dir-tiny/200KB.1"}]}}'))
43
+ $stderr.puts(%Q( echo '{"#{PARAM_SPEC}":{"remote_host":...}}'|asession @json:@stdin))
41
44
  Process.exit(1)
42
45
  end
46
+ Aspera::Ascp::Installation.instance.sdk_folder = File.join(Dir.home, '.aspera', 'sdk')
43
47
 
44
48
  parameter_source_err_msg = ' (argument), did you specify: "@json:" ?'
45
49
  # by default assume JSON input on stdin if no argument
@@ -52,33 +56,39 @@ assert_usage(ARGV.length.eql?(1), 'exactly one argument is expected')
52
56
  assert_usage(!['-h', '--help'].include?(ARGV.first), nil)
53
57
  # parse transfer spec
54
58
  begin
55
- transfer_spec_arg = ARGV.pop
56
- transfer_spec = Aspera::Cli::ExtendedValue.instance.evaluate(transfer_spec_arg)
59
+ session_argument = ARGV.pop
60
+ session_spec = Aspera::Cli::ExtendedValue.instance.evaluate(session_argument)
57
61
  rescue
58
- assert_usage(false, "Cannot extract transfer spec from: #{transfer_spec_arg}")
62
+ assert_usage(false, "Cannot parse argument: #{session_argument}")
59
63
  end
60
64
  # ensure right type
61
- assert_usage(transfer_spec.is_a?(Hash), "the value must be a hash table#{parameter_source_err_msg}")
65
+ assert_usage(session_spec.is_a?(Hash), "The value must be a hash table#{parameter_source_err_msg}")
66
+ assert_usage(session_spec[PARAM_SPEC].is_a?(Hash), "the value must contain key #{PARAM_SPEC}")
62
67
  # additional debug capability
63
- if transfer_spec.key?(TS_LOG_LEVEL)
64
- Aspera::Log.instance.level = transfer_spec[TS_LOG_LEVEL]
65
- transfer_spec.delete(TS_LOG_LEVEL)
68
+ if session_spec.key?(PARAM_LOG_LEVEL)
69
+ Aspera::Log.instance.level = session_spec[PARAM_LOG_LEVEL]
66
70
  end
67
71
  # possibly override temp folder
68
- if transfer_spec.key?(TS_TMP_FILE_LIST_FOLDER)
69
- Aspera::Fasp::Parameters.file_list_folder = transfer_spec[TS_TMP_FILE_LIST_FOLDER]
70
- transfer_spec.delete(TS_TMP_FILE_LIST_FOLDER)
72
+ if session_spec.key?(PARAM_TMP_FILE_LIST_FOLDER)
73
+ Aspera::Transfer::Parameters.file_list_folder = session_spec[PARAM_TMP_FILE_LIST_FOLDER]
74
+ end
75
+ session_spec['agent'] = {} unless session_spec.key?('agent')
76
+ session_spec['agent']['quiet'] = true
77
+ session_spec['agent']['management_cb'] = ->(event) do
78
+ puts JSON.generate(Aspera::Ascp::Management.enhanced_event_format(event))
71
79
  end
72
80
  # get local agent (ascp), disable ascp output on stdout to not mix with JSON events
73
- client = Aspera::Fasp::AgentDirect.new({quiet: true})
81
+ client = Aspera::Agent::Direct.new(session_spec['agent'])
74
82
  # start transfer (asynchronous)
75
- job_id = client.start_transfer(transfer_spec)
83
+ job_id = client.start_transfer(session_spec[PARAM_SPEC])
76
84
  # async commands
77
85
  Thread.new do
86
+ # we assume here a single session
87
+ session_id = client.sessions_by_job(job_id).first
78
88
  begin # rubocop:disable Style/RedundantBegin
79
89
  loop do
80
90
  data = JSON.parse($stdin.gets)
81
- client.send_command(job_id, 0, data)
91
+ client.send_command(session_id, data)
82
92
  end
83
93
  rescue
84
94
  Process.exit(1)
data/examples/dascli CHANGED
@@ -7,7 +7,7 @@
7
7
  : "${imgtag=$image:$version}"
8
8
  # set env var `docker` to podman, to use podman
9
9
  : "${docker:=docker}"
10
- # set env var docker_args to add options to docker run (transform var into array) # spellcheck disable=SC2086
10
+ # set env var `docker_args` to add options to docker run (then, transform this var into array) # spellcheck disable=SC2086
11
11
  read -a add_dock_args <<< $docker_args
12
12
  # set env var ASCLI_HOME to set the config folder on host
13
13
  : "${ASCLI_HOME:=$HOME/.aspera/ascli}"
@@ -24,7 +24,7 @@ exec $docker run \
24
24
  --interactive \
25
25
  --user root \
26
26
  --env ASCLI_HOME="$ascli_home_container" \
27
- --volume "$ASCLI_HOME:$ascli_home_container" \
27
+ --volume "$ASCLI_HOME:$ascli_home_container:z" \
28
28
  "${add_dock_args[@]}" \
29
29
  "$imgtag" \
30
30
  "$@"
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aspera/agent/base'
4
+ require 'aspera/rest'
5
+ require 'aspera/log'
6
+ require 'aspera/json_rpc'
7
+ require 'aspera/open_application'
8
+ require 'securerandom'
9
+
10
+ module Aspera
11
+ module Agent
12
+ class Alpha < Base
13
+ # try twice the main init url in sequence
14
+ START_URIS = ['aspera://', 'aspera://', 'aspera://']
15
+ # delay between each try to start the app
16
+ SLEEP_SEC_BETWEEN_RETRY = 5
17
+ APP_IDENTIFIER = 'com.ibm.software.aspera.desktop'
18
+ APP_NAME = 'Aspera Desktop Alpha Client'
19
+ private_constant :START_URIS, :SLEEP_SEC_BETWEEN_RETRY
20
+ def initialize(options)
21
+ @application_id = SecureRandom.uuid
22
+ super(options)
23
+ raise 'Using client requires a graphical environment' if !OpenApplication.default_gui_mode.eql?(:graphical)
24
+ method_index = 0
25
+ begin
26
+ # curl 'http://127.0.0.1:33024/' -X POST -H 'content-type: application/json' --data-raw '{"jsonrpc":"2.0","params":[],"id":999999,"method":"rpc.discover"}'
27
+ # https://playground.open-rpc.org/?schemaUrl=http://127.0.0.1:33024
28
+ @client_app_api = Aspera::JsonRpcClient.new(Aspera::Rest.new(base_url: aspera_client_api_url))
29
+ client_info = @client_app_api.get_info
30
+ Log.log.debug{Log.dump(:client_version, client_info)}
31
+ Log.log.info('Client was reached') if method_index > 0
32
+ rescue Errno::ECONNREFUSED => e
33
+ start_url = START_URIS[method_index]
34
+ method_index += 1
35
+ raise StandardError, "Unable to start #{APP_NAME} #{method_index} times" if start_url.nil?
36
+ Log.log.warn{"#{APP_NAME} is not started (#{e}). Trying to start it ##{method_index}..."}
37
+ if !OpenApplication.uri_graphical(start_url)
38
+ OpenApplication.uri_graphical('https://www.ibm.com/aspera/connect/')
39
+ raise StandardError, "#{APP_NAME} is not installed"
40
+ end
41
+ sleep(SLEEP_SEC_BETWEEN_RETRY)
42
+ retry
43
+ end
44
+ end
45
+
46
+ def sdk_log_file
47
+ File.join(Dir.home, 'Library', 'Logs', APP_IDENTIFIER, 'ibm-aspera-desktop.log')
48
+ end
49
+
50
+ def aspera_client_api_url
51
+ log_file = sdk_log_file
52
+ url = nil
53
+ File.open(log_file, 'r') do |file|
54
+ file.each_line do |line|
55
+ line = line.chomp
56
+ if (m = line.match(/JSON-RPC server listening on (.*)/))
57
+ url = "http://#{m[1]}"
58
+ end
59
+ end
60
+ end
61
+ url = 'http://127.0.0.1:33024' if url.nil?
62
+ raise StandardError, "Unable to find the JSON-RPC server URL in #{log_file}" if url.nil?
63
+ return url
64
+ end
65
+
66
+ def start_transfer(transfer_spec, token_regenerator: nil)
67
+ @request_id = SecureRandom.uuid
68
+ # if there is a token, we ask the client app to use well known ssh private keys
69
+ # instead of asking password
70
+ transfer_spec['authentication'] = 'token' if transfer_spec.key?('token')
71
+ result = @client_app_api.start_transfer(app_id: @application_id, desktop_spec: {}, transfer_spec: transfer_spec)
72
+ @xfer_id = result['uuid']
73
+ end
74
+
75
+ def wait_for_transfers_completion
76
+ started = false
77
+ pre_calc = false
78
+ begin
79
+ loop do
80
+ transfer = @client_app_api.get_transfer(app_id: @application_id, transfer_id: @xfer_id)
81
+ case transfer['status']
82
+ when 'initiating', 'queued'
83
+ notify_progress(session_id: nil, type: :pre_start, info: transfer['status'])
84
+ when 'running'
85
+ if !started
86
+ notify_progress(session_id: @xfer_id, type: :session_start)
87
+ started = true
88
+ end
89
+ if !pre_calc && (transfer['bytes_expected'] != 0)
90
+ notify_progress(type: :session_size, session_id: @xfer_id, info: transfer['bytes_expected'])
91
+ pre_calc = true
92
+ else
93
+ notify_progress(type: :transfer, session_id: @xfer_id, info: transfer['bytes_written'])
94
+ end
95
+ when 'completed'
96
+ notify_progress(type: :end, session_id: @xfer_id)
97
+ break
98
+ when 'failed'
99
+ notify_progress(type: :end, session_id: @xfer_id)
100
+ raise Transfer::Error, transfer['error_desc']
101
+ when 'cancelled'
102
+ notify_progress(type: :end, session_id: @xfer_id)
103
+ raise Transfer::Error, 'Transfer cancelled by user'
104
+ else
105
+ notify_progress(type: :end, session_id: @xfer_id)
106
+ raise Transfer::Error, "unknown status: #{transfer['status']}: #{transfer['error_desc']}"
107
+ end
108
+ sleep(1)
109
+ end
110
+ rescue StandardError => e
111
+ return [e]
112
+ end
113
+ return [:success]
114
+ end # wait
115
+ end # AgentAlpha
116
+ end
117
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aspera/log'
4
+ require 'aspera/assert'
5
+ module Aspera
6
+ module Agent
7
+ # Base class for transfer agents
8
+ class Base
9
+ RUBY_EXT = '.rb'
10
+ class << self
11
+ # compute options from user provided and default options
12
+ def options(default:, options:)
13
+ result = options.symbolize_keys
14
+ available = default.map{|k, v|"#{k}(#{v})"}.join(', ')
15
+ result.each_key do |k|
16
+ Aspera.assert_values(k, default.keys){"transfer agent parameter: #{k}"}
17
+ # check it is the expected type: too limiting, as we can have an Integer or Float, or symbol and string
18
+ # raise "Invalid value for transfer agent parameter: #{k}, expect #{default[k].class.name}" unless default[k].nil? || v.is_a?(default[k].class)
19
+ end
20
+ default.each do |k, v|
21
+ raise "Missing required agent parameter: #{k}. Parameters: #{available}" if v.eql?(:required) && !result.key?(k)
22
+ result[k] = v unless result.key?(k)
23
+ end
24
+ return result
25
+ end
26
+
27
+ # discover available agents
28
+ def agent_list
29
+ base_class = File.basename(__FILE__)
30
+ Dir.entries(File.dirname(File.expand_path(__FILE__))).select do |file|
31
+ file.end_with?(RUBY_EXT) && !file.eql?(base_class)
32
+ end.map{|file|file[0..(-1 - RUBY_EXT.length)].to_sym}
33
+ end
34
+ end
35
+ def wait_for_completion
36
+ # list of: :success or "error message string"
37
+ statuses = wait_for_transfers_completion
38
+ @progress&.reset
39
+ Aspera.assert_type(statuses, Array)
40
+ Aspera.assert(statuses.none?{|i|!i.eql?(:success) && !i.is_a?(StandardError)}){"bad statuses content: #{statuses}"}
41
+ return statuses
42
+ end
43
+
44
+ private
45
+
46
+ def initialize(options)
47
+ # method `shutdown` is optional
48
+ Aspera.assert(respond_to?(:start_transfer))
49
+ Aspera.assert(respond_to?(:wait_for_transfers_completion))
50
+ Aspera.assert_type(options, Hash){'transfer agent options'}
51
+ Log.log.debug{Log.dump(:agent_options, options)}
52
+ @progress = options[:progress]
53
+ options.delete(:progress)
54
+ end
55
+
56
+ def notify_progress(**parameters)
57
+ @progress&.event(**parameters)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -1,17 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'aspera/fasp/agent_base'
3
+ require 'aspera/agent/base'
4
4
  require 'aspera/rest'
5
5
  require 'aspera/open_application'
6
6
  require 'securerandom'
7
7
 
8
8
  module Aspera
9
- module Fasp
10
- class AgentConnect < Aspera::Fasp::AgentBase
9
+ module Agent
10
+ class Connect < Base
11
11
  # try twice the main init url in sequence
12
12
  CONNECT_START_URIS = ['fasp://initialize', 'fasp://initialize', 'aspera-drive://initialize', 'https://test-connect.ibmaspera.com/']
13
13
  # delay between each try to start connect
14
- SLEEP_SEC_BETWEEN_RETRY = 3
14
+ SLEEP_SEC_BETWEEN_RETRY = 5
15
15
  private_constant :CONNECT_START_URIS, :SLEEP_SEC_BETWEEN_RETRY
16
16
  def initialize(options)
17
17
  super(options)
@@ -21,9 +21,11 @@ module Aspera
21
21
  raise 'Using connect requires a graphical environment' if !OpenApplication.default_gui_mode.eql?(:graphical)
22
22
  method_index = 0
23
23
  begin
24
- connect_url = Products.connect_uri
24
+ connect_url = Ascp::Products.connect_uri
25
25
  Log.log.debug{"found: #{connect_url}"}
26
- @connect_api = Rest.new({base_url: "#{connect_url}/v5/connect", headers: {'Origin' => Rest.user_agent}}) # could use v6 also now
26
+ @connect_api = Rest.new(
27
+ base_url: "#{connect_url}/v5/connect", # could use v6 also now
28
+ headers: {'Origin' => Rest.user_agent})
27
29
  connect_info = @connect_api.read('info/version')[:data]
28
30
  Log.log.info('Connect was reached') if method_index > 0
29
31
  Log.log.debug{Log.dump(:connect_version, connect_info)}
@@ -33,7 +35,7 @@ module Aspera
33
35
  raise StandardError, "Unable to start connect #{method_index} times" if start_url.nil?
34
36
  Log.log.warn{"Aspera Connect is not started (#{e}). Trying to start it ##{method_index}..."}
35
37
  if !OpenApplication.uri_graphical(start_url)
36
- OpenApplication.uri_graphical('https://downloads.asperasoft.com/connect2/')
38
+ OpenApplication.uri_graphical('https://www.ibm.com/aspera/connect/')
37
39
  raise StandardError, 'Connect is not installed'
38
40
  end
39
41
  sleep(SLEEP_SEC_BETWEEN_RETRY)
@@ -67,7 +69,7 @@ module Aspera
67
69
  }]}
68
70
  # asynchronous anyway
69
71
  res = @connect_api.create('transfers/start', connect_transfer_args)[:data]
70
- @xfer_id = res['transfer_specs'].first['transfer_spec']['tags'][Fasp::TransferSpec::TAG_RESERVED]['xfer_id']
72
+ @xfer_id = res['transfer_specs'].first['transfer_spec']['tags'][Transfer::Spec::TAG_RESERVED]['xfer_id']
71
73
  end
72
74
 
73
75
  def wait_for_transfers_completion
@@ -105,13 +107,13 @@ module Aspera
105
107
  break
106
108
  when 'failed'
107
109
  notify_progress(type: :end, session_id: session_id)
108
- raise Fasp::Error, transfer['error_desc']
110
+ raise Transfer::Error, transfer['error_desc']
109
111
  when 'cancelled'
110
112
  notify_progress(type: :end, session_id: session_id)
111
- raise Fasp::Error, 'Transfer cancelled by user'
113
+ raise Transfer::Error, 'Transfer cancelled by user'
112
114
  else
113
115
  notify_progress(type: :end, session_id: session_id)
114
- raise Fasp::Error, "unknown status: #{transfer['status']}: #{transfer['error_desc']}"
116
+ raise Transfer::Error, "unknown status: #{transfer['status']}: #{transfer['error_desc']}"
115
117
  end
116
118
  end
117
119
  sleep(1)