使用 Aspera Transfer SDK发送软件包

使用 Faspex API 和传输 SDK 向收件人发送包裹。

您可以使用下面的 Ruby 脚本作为示例代码,用 Aspera Transfer SDK。

# frozen_string_literal: true
# Transfer Manager
# Ruby Client Example
# IBM Aspera

# Grpc generated classes are assumed to be in the load path
$LOAD_PATH << '.'
require 'transfer_services_pb'

require 'json'
require_relative 'utils'
require 'net/http'
require 'uri'
require 'securerandom'
require 'openssl'
require 'jwt'
require 'date'
require 'optparse'

include Transfersdk

def apiPostRequest(host, endpoint, body, auth = nil)
  uri = URI("https://#{host}/#{endpoint}")
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  headers = {"Content-Type" => "application/json"}
  headers["Authorization"] = auth if auth
  response, data = http.post(uri.request_uri, JSON(body), headers)
end

def main
  opts = {}
  OptionParser.new do |opt|
    opt.on('--host HOST') { |o| opts['host'] = o}
    opt.on('--email EMAIL') { |o| opts['email'] = o}
    opt.on('--client-id CLIENTID') { |o| opts['client_id'] = o}
    opt.on('--private-key-path PRIVATEKEY') { |o| opts['pkey_path'] = o}
    opt.on('--path PATH') { |o| opts['path'] = o}
  end.parse!
  # authorize against Faspex5
  host = opts["host"]
  email = opts["email"]
  client_id = opts["client_id"]
  private_key_path = opts["pkey_path"]
  path = opts["path"]
  payload = {
    "iss" => client_id,
    "sub" => "user:#{email}",
    "aud" => client_id,
    "jti" => SecureRandom.uuid,
    "exp" => Time.now.to_i + 103600,
    "iat" => Time.now.to_i
  }

  pk = OpenSSL::PKey::RSA.new(File.read(private_key_path))
  token = JWT.encode(payload, pk, "RS256", {typ:"JWT"})
  body = {"client_id" => client_id,
    "grant_type" => "urn:ietf:params:oauth:grant-type:jwt-bearer",
    "state" => SecureRandom.uuid,
    "assertion" => token
  }

  response = apiPostRequest(host, "aspera/faspex/auth/token", body)
  if response.code != "201"
    puts "failed to get response for faspex bearer token code #{response.code} body #{response.body}"
    exit(1)
  end
  # Get bearer token from the response
  bt = JSON.parse(response.body)["access_token"] 
  puts "Bearer Token #{bt}" 
  # create a package
  body = {"title" => "Package created at #{DateTime.now.to_s}",
    "recipients" => ["name" => email]
  }

  response = apiPostRequest(host, "aspera/faspex/api/v5/packages", body, bt)
  if response.code != "201"
    puts "failed to get response from package creation - code #{response.code} resp #{response.body}"
    exit(2)
  end
  j_rsp = JSON.parse(response.body) 
  puts j_rsp 
  pkg_id = j_rsp["id"]
  puts "package id #{pkg_id}"
 
  # get a transfer spec for the package
  body = {"paths" => [path]}
  response = apiPostRequest(host, "aspera/faspex/api/v5/packages/#{pkg_id}/transfer_spec/upload?transfer_type=remote_transfer", body, bt)
  if response.code != "201"
    puts "failed to get response from transfer_spec code #{response.code} body #{response.body}"
    exit(3)
  end
  transfer_spec = JSON.parse(response.body)
  transfer_spec["paths"] = path
  puts "transfer spec #{JSON.dump(transfer_spec)}"

  # create a connection to the transfer manager daemon
  client = TransferService::Stub.new('localhost:55002',
                                     :this_channel_is_insecure)

  # create a transfer request - transferSpec must be a string of json
  transfer_request = TransferRequest.new(
    transferType: TransferType::FILE_REGULAR, # transfer type (file/stream)
    config: TransferConfig.new, # transfer configuration
    transferSpec: JSON.dump(transfer_spec)) # transfer definition

  # send start transfer request to the transfer manager daemon
  start_transfer_response = client.start_transfer(transfer_request)
  transfer_id = start_transfer_response.transferId
  puts "transfer started with id #{transfer_id}"

  # monitor transfer status
  client.monitor_transfers(RegistrationRequest.new(
    transferId: [transfer_id],
    filters: [RegistrationFilter.new(
      operator: RegistrationFilterOperator::OR)])) do |response|
    puts "transfer info #{response}"

    # check transfer status in response, and exit if it's done
    status = response.status
    if [:FAILED, :COMPLETED].include?(status)
      puts "finished #{status}"
      break
    end
  end
end

main if __FILE__ == $PROGRAM_NAME