killbill 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/Jarfile +3 -2
  2. data/README.md +21 -0
  3. data/VERSION +1 -1
  4. data/killbill.gemspec +4 -2
  5. data/lib/killbill.rb +3 -4
  6. data/lib/killbill/http_servlet.rb +99 -0
  7. data/lib/killbill/jpayment.rb +152 -0
  8. data/lib/killbill/jresponse/jconverter.rb +100 -0
  9. data/lib/killbill/jresponse/jpayment_method_response.rb +89 -0
  10. data/lib/killbill/jresponse/jpayment_method_response_internal.rb +54 -0
  11. data/lib/killbill/jresponse/jpayment_response.rb +59 -0
  12. data/lib/killbill/jresponse/jrefund_response.rb +60 -0
  13. data/lib/killbill/logger.rb +44 -0
  14. data/lib/killbill/payment.rb +16 -8
  15. data/lib/killbill/plugin.rb +59 -26
  16. data/lib/killbill/rake_task.rb +27 -8
  17. data/lib/killbill/response/payment_method_response.rb +31 -0
  18. data/lib/killbill/response/payment_method_response_internal.rb +20 -0
  19. data/lib/killbill/response/payment_response.rb +22 -0
  20. data/lib/killbill/response/payment_status.rb +10 -0
  21. data/lib/killbill/response/refund_response.rb +23 -0
  22. data/spec/killbill/base_plugin_spec.rb +7 -0
  23. data/spec/killbill/config_test.ru +7 -0
  24. data/spec/killbill/jpayment_spec.rb +121 -0
  25. data/spec/killbill/jresponse/jconverter_spec.rb +208 -0
  26. data/spec/killbill/jresponse/jpayment_method_response_internal_spec.rb +34 -0
  27. data/spec/killbill/jresponse/jpayment_method_response_spec.rb +53 -0
  28. data/spec/killbill/jresponse/jpayment_response_spec.rb +41 -0
  29. data/spec/killbill/jresponse/jrefund_response_spec.rb +41 -0
  30. data/spec/killbill/killbill_integration_spec.rb +4 -5
  31. data/spec/killbill/payment_plugin_spec.rb +7 -3
  32. data/spec/killbill/payment_test.rb +88 -0
  33. data/spec/killbill/rack_handler_spec.rb +16 -0
  34. data/spec/spec_helper.rb +5 -0
  35. metadata +79 -16
@@ -0,0 +1,54 @@
1
+ require 'killbill/response/payment_method_response_internal'
2
+ require 'killbill/jresponse/jconverter'
3
+
4
+ module Killbill
5
+ module Plugin
6
+
7
+ java_package 'com.ning.billing.payment.plugin.api'
8
+ class JPaymentMethodResponseInternal
9
+
10
+ include Java::com.ning.billing.payment.plugin.api.PaymentMethodInfoPlugin
11
+ attr_reader :kb_account_id,
12
+ :kb_payment_method_id,
13
+ :is_default
14
+ :external_payment_method_id
15
+
16
+ class << self
17
+ def to_payment_method_response_internal(jinfo)
18
+ account_id = JConverter.from_uuid(jinfo.get_account_id)
19
+ payment_method_id = JConverter.from_uuid(jinfo.get_payment_method_id)
20
+ is_default = JConverter.from_boolean(jinfo.is_default)
21
+ external_payment_method_id = JConverter.from_string(jinfo.get_external_payment_method_id)
22
+ PaymentMethodResponseInternal.new(account_id, payment_method_id, is_default, external_payment_method_id)
23
+ end
24
+ end
25
+
26
+ def initialize(payment_method_response_internal)
27
+ @kb_account_id = JConverter.to_uuid(payment_method_response_internal.kb_account_id)
28
+ @kb_payment_method_id = JConverter.to_uuid(payment_method_response_internal.kb_payment_method_id)
29
+ @is_default = JConverter.to_boolean(payment_method_response_internal.is_default)
30
+ @external_payment_method_id = JConverter.to_string(payment_method_response_internal.external_payment_method_id)
31
+ end
32
+
33
+ java_signature 'java.lang.UUID getAccountId()'
34
+ def get_account_id
35
+ @kb_account_id
36
+ end
37
+
38
+ java_signature 'java.lang.UUID getPaymentMethodId()'
39
+ def get_payment_method_id
40
+ @kb_payment_method_id
41
+ end
42
+
43
+ java_signature 'java.lang.Boolean isDefault()'
44
+ def is_default
45
+ @is_default
46
+ end
47
+
48
+ java_signature 'java.lang.String getExternalPaymentMethodId()'
49
+ def get_external_payment_method_id
50
+ @external_payment_method_id
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,59 @@
1
+ require 'killbill/response/payment_response'
2
+ require 'killbill/jresponse/jconverter'
3
+
4
+ module Killbill
5
+ module Plugin
6
+
7
+ java_package 'com.ning.billing.payment.plugin.api'
8
+ class JPaymentResponse
9
+
10
+ include Java::com.ning.billing.payment.plugin.api.PaymentInfoPlugin
11
+
12
+ attr_reader :amount,
13
+ :created_date,
14
+ :effective_date,
15
+ :status,
16
+ :gateway_error,
17
+ :gateway_error_code
18
+
19
+ def initialize(payment_response)
20
+ @amount = JConverter.to_big_decimal(payment_response.amount_in_cents)
21
+ @created_date = JConverter.to_joda_date_time(payment_response.created_date)
22
+ @effective_date = JConverter.to_joda_date_time(payment_response.effective_date)
23
+ @status = JConverter.to_payment_plugin_status(payment_response.status)
24
+ @gateway_error = JConverter.to_string(payment_response.gateway_error)
25
+ @gateway_error_code = JConverter.to_string(payment_response.gateway_error_code)
26
+ end
27
+
28
+ java_signature 'java.math.BigDecimal getAmount()'
29
+ def get_amount
30
+ @amount
31
+ end
32
+
33
+ java_signature 'org.joda.time.DateTime getCreatedDate()'
34
+ def get_created_date
35
+ @created_date
36
+ end
37
+
38
+ java_signature 'org.joda.time.DateTime getEffectiveDate()'
39
+ def get_effective_date
40
+ @effective_date
41
+ end
42
+
43
+ java_signature 'Java::com.ning.billing.payment.plugin.api.PaymentInfoPlugin::PaymentPluginStatus getStatus()'
44
+ def get_status
45
+ @status
46
+ end
47
+
48
+ java_signature 'java.lang.String getGatewayError()'
49
+ def get_gateway_error
50
+ @gateway_error
51
+ end
52
+
53
+ java_signature 'java.lang.String getGatewayErrorCode()'
54
+ def get_gateway_error_code
55
+ @gateway_error_code
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,60 @@
1
+ require 'killbill/response/refund_response'
2
+ require 'killbill/jresponse/jconverter'
3
+
4
+ module Killbill
5
+ module Plugin
6
+
7
+ java_package 'com.ning.billing.payment.plugin.api'
8
+ class JRefundResponse
9
+
10
+ include Java::com.ning.billing.payment.plugin.api.RefundInfoPlugin
11
+
12
+ attr_reader :amount,
13
+ :created_date,
14
+ :effective_date,
15
+ :status,
16
+ :gateway_error,
17
+ :gateway_error_code
18
+
19
+ def initialize(refund_response)
20
+ @amount = JConverter.to_big_decimal(refund_response.amount_in_cents)
21
+ @created_date = JConverter.to_joda_date_time(refund_response.created_date)
22
+ @effective_date = JConverter.to_joda_date_time(refund_response.effective_date)
23
+ @status = JConverter.to_payment_plugin_status(refund_response.status)
24
+ @gateway_error = JConverter.to_string(refund_response.gateway_error)
25
+ @gateway_error_code = JConverter.to_string(refund_response.gateway_error_code)
26
+ end
27
+
28
+
29
+ java_signature 'java.math.BigDecimal getAmount()'
30
+ def get_amount
31
+ @amount
32
+ end
33
+
34
+ java_signature 'org.joda.time.DateTime getCreatedDate()'
35
+ def get_created_date
36
+ @created_date
37
+ end
38
+
39
+ java_signature 'org.joda.time.DateTime getEffectiveDate()'
40
+ def get_effective_date
41
+ @effective_date
42
+ end
43
+
44
+ java_signature 'Java::com.ning.billing.payment.plugin.api.PaymentInfoPlugin::PaymentPluginStatus getStatus()'
45
+ def get_status
46
+ @status
47
+ end
48
+
49
+ java_signature 'java.lang.String getGatewayError()'
50
+ def get_gateway_error
51
+ @gateway_error
52
+ end
53
+
54
+ java_signature 'java.lang.String getGatewayErrorCode()'
55
+ def get_gateway_error_code
56
+ @gateway_error_code
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,44 @@
1
+ # Plugin logger that will delegate to the OSGI LogService
2
+ module Killbill
3
+ module Plugin
4
+ class Logger
5
+ def initialize(delegate)
6
+ @logger = delegate
7
+ end
8
+
9
+ def debug(msg)
10
+ @logger.log(4, msg)
11
+ end
12
+
13
+ def info(msg)
14
+ @logger.log(3, msg)
15
+ end
16
+
17
+ def warn(msg)
18
+ @logger.log(2, msg)
19
+ end
20
+
21
+ def error(msg)
22
+ @logger.log(1, msg)
23
+ end
24
+
25
+ alias_method :fatal, :error
26
+
27
+ # XXX TODO
28
+ def debug?
29
+ false
30
+ end
31
+
32
+ def info?
33
+ true
34
+ end
35
+
36
+ def warn?
37
+ true
38
+ end
39
+
40
+ alias_method :error?, :warn?
41
+ alias_method :fatal?, :error?
42
+ end
43
+ end
44
+ end
@@ -1,4 +1,5 @@
1
1
  require 'killbill/plugin'
2
+ require 'killbill/response/payment_response'
2
3
 
3
4
  module Killbill
4
5
  module Plugin
@@ -7,38 +8,45 @@ module Killbill
7
8
  class OperationUnsupportedByGatewayError < NotImplementedError
8
9
  end
9
10
 
10
- def charge(external_account_key, killbill_payment_id, amount_in_cents, options = {})
11
+ def get_name
11
12
  raise OperationUnsupportedByGatewayError
12
13
  end
13
14
 
14
- def refund(external_account_key, killbill_payment_id, amount_in_cents, options = {})
15
+ def charge(kb_payment_id, kb_payment_method_id, amount_in_cents, options = {})
15
16
  raise OperationUnsupportedByGatewayError
16
17
  end
17
18
 
18
- def get_payment_info(killbill_payment_id, options = {})
19
+ def get_payment_info(kb_payment_id, options = {})
19
20
  raise OperationUnsupportedByGatewayError
20
21
  end
21
22
 
22
- def add_payment_method(external_account_key, payment_method, options = {})
23
+ def refund(kb_payment_id, amount_in_cents, options = {})
23
24
  raise OperationUnsupportedByGatewayError
24
25
  end
25
26
 
26
- def delete_payment_method(external_account_key, external_payment_method_id, options = {})
27
+ def add_payment_method(kb_account_id, kb_payment_method_id, payment_method_props, set_default, options = {})
27
28
  raise OperationUnsupportedByGatewayError
28
29
  end
29
30
 
30
- def update_payment_method(external_account_key, payment_method, options = {})
31
+ def delete_payment_method(kb_payment_method_id, options = {})
31
32
  raise OperationUnsupportedByGatewayError
32
33
  end
33
34
 
34
- def set_default_payment_method(external_account_key, payment_method, options = {})
35
+ def get_payment_method_detail(kb_account_id, kb_payment_method_id, options = {})
35
36
  raise OperationUnsupportedByGatewayError
36
37
  end
37
38
 
38
- def create_account(killbill_account, options = {})
39
+ def set_default_payment_method(kb_payment_method_id, options = {})
39
40
  raise OperationUnsupportedByGatewayError
40
41
  end
41
42
 
43
+ def get_payment_methods(kb_account_id, options = {})
44
+ raise OperationUnsupportedByGatewayError
45
+ end
46
+
47
+ def reset_payment_methods(payment_methods)
48
+ raise OperationUnsupportedByGatewayError
49
+ end
42
50
  end
43
51
  end
44
52
  end
@@ -1,3 +1,6 @@
1
+ require 'killbill/http_servlet'
2
+ require 'killbill/logger'
3
+
1
4
  module Killbill
2
5
  # There are various types of plugins one can write for Killbill:
3
6
  #
@@ -18,47 +21,77 @@ module Killbill
18
21
  @active = false
19
22
  end
20
23
 
21
- attr_accessor :account_user_api,
22
- :analytics_sanity_api,
23
- :analytics_user_api,
24
- :catalog_user_api,
25
- :entitlement_migration_api,
26
- :entitlement_timeline_api,
27
- :entitlement_transfer_api,
28
- :entitlement_user_api,
29
- :invoice_migration_api,
30
- :invoice_payment_api,
31
- :invoice_user_api,
32
- :meter_user_api,
33
- :overdue_user_api,
34
- :payment_api,
35
- :tenant_user_api,
36
- :usage_user_api,
37
- :audit_user_api,
38
- :custom_field_user_api,
39
- :export_user_api,
40
- :tag_user_api
24
+ attr_writer :account_user_api,
25
+ :analytics_sanity_api,
26
+ :analytics_user_api,
27
+ :catalog_user_api,
28
+ :entitlement_migration_api,
29
+ :entitlement_timeline_api,
30
+ :entitlement_transfer_api,
31
+ :entitlement_user_api,
32
+ :invoice_migration_api,
33
+ :invoice_payment_api,
34
+ :invoice_user_api,
35
+ :meter_user_api,
36
+ :overdue_user_api,
37
+ :payment_api,
38
+ :tenant_user_api,
39
+ :usage_user_api,
40
+ :audit_user_api,
41
+ :custom_field_user_api,
42
+ :export_user_api,
43
+ :tag_user_api
44
+ # Extra services
45
+ attr_accessor :root,
46
+ :logger
41
47
 
42
48
  # Called by the Killbill lifecycle when instantiating the plugin
43
- def initialize(apis_map = {})
49
+ def initialize(services = {})
44
50
  @active = false
45
51
 
46
- apis_map.each do |api_name, api_instance|
52
+ services.each do |service_name, service_instance|
47
53
  begin
48
- self.send("#{api_name}=", api_instance)
54
+ self.send("#{service_name}=", service_instance)
49
55
  rescue NoMethodError
50
- warn "Ignoring unsupported API: #{api_name}"
56
+ warn "Ignoring unsupported service: #{service_name}"
51
57
  end
52
58
  end
53
59
  end
54
60
 
61
+ def logger=(logger)
62
+ @logger = Killbill::Plugin::Logger.new(logger)
63
+ end
64
+
65
+ # Called by the Killbill lifecycle to register the servlet
66
+ def rack_handler
67
+ config_ru = Pathname.new("#{@root}/config.ru").expand_path
68
+ if config_ru.file?
69
+ @logger.info "Found Rack configuration file at #{config_ru.to_s}"
70
+ instance = Killbill::Plugin::RackHandler.instance
71
+ instance.configure(@logger, config_ru.to_s) unless instance.configured?
72
+ instance
73
+ else
74
+ @logger.info "No Rack configuration file found at #{config_ru.to_s}"
75
+ nil
76
+ end
77
+ end
78
+
55
79
  class APINotAvailableError < NotImplementedError
56
80
  end
57
81
 
58
82
  def method_missing(m, *args, &block)
59
- raise APINotAvailableError.new("API #{m} is not available") if m =~ /_api$/
83
+ # m being a symbol, to_s is required for Ruby 1.8
84
+ if m.to_s =~ /_api$/
85
+ api = self.instance_variable_get("@#{m.to_s}")
86
+ if api.nil?
87
+ raise APINotAvailableError.new("API #{m} is not available")
88
+ else
89
+ api
90
+ end
91
+ else
92
+ raise NoMethodError.new("undefined method `#{m}' for #{self}")
93
+ end
60
94
  end
61
-
62
95
  end
63
96
  end
64
97
  end
@@ -44,8 +44,8 @@ module Killbill
44
44
  # Note the Killbill friendly structure (which we will keep in the tarball)
45
45
  @target_dir = @package_dir.join("#{version}/gems").expand_path
46
46
 
47
- # Staging area to install the killbill.properties file
48
- @killbill_properties_target_dir = @package_dir.join("#{version}").expand_path
47
+ # Staging area to install the killbill.properties and config.ru files
48
+ @plugin_root_target_dir = @package_dir.join("#{version}").expand_path
49
49
  end
50
50
 
51
51
  def specs
@@ -58,6 +58,7 @@ module Killbill
58
58
  def install
59
59
  namespace :killbill do
60
60
  desc "Validate plugin tree"
61
+ # The killbill.properties file is required, but not the config.ru one
61
62
  task :validate => killbill_properties_file do
62
63
  validate
63
64
  end
@@ -72,7 +73,7 @@ module Killbill
72
73
  desc "Stage all dependencies"
73
74
  task :stage => :validate do
74
75
  stage_dependencies
75
- stage_killbill_properties_file
76
+ stage_extra_files
76
77
 
77
78
  # Small hack! Update the list of files to package (Rake::FileList is evaluated too early above)
78
79
  package_task.package_files = Rake::FileList.new("#{@package_dir.basename}/**/*")
@@ -166,20 +167,38 @@ module Killbill
166
167
  # For the plugin itself, install it manually (the cache path is likely to be wrong)
167
168
  next if spec.name == name and spec.version == version
168
169
  @logger.debug "Staging #{spec.name} (#{spec.version}) from #{spec.cache_file}"
169
- Gem::Installer.new(spec.cache_file, {:force => true, :install_dir => @target_dir}).install
170
+ begin
171
+ Gem::Installer.new(spec.cache_file, {:force => true, :install_dir => @target_dir}).install
172
+ rescue => e
173
+ @logger.warn "Unable to stage #{spec.name} (#{spec.version}) from #{spec.cache_file}: #{e}"
174
+ end
170
175
  end
171
176
 
172
177
  @logger.debug "Staging #{name} (#{version}) from #{@plugin_gem_file}"
173
178
  Gem::Installer.new(@plugin_gem_file, {:force => true, :install_dir => @target_dir}).install
174
179
  end
175
180
 
176
- def stage_killbill_properties_file
177
- @logger.debug "Staging #{killbill_properties_file} to #{@killbill_properties_target_dir}"
178
- cp killbill_properties_file, @killbill_properties_target_dir
181
+ def stage_extra_files
182
+ unless killbill_properties_file.nil?
183
+ @logger.debug "Staging #{killbill_properties_file} to #{@plugin_root_target_dir}"
184
+ cp killbill_properties_file, @plugin_root_target_dir
185
+ end
186
+ unless config_ru_file.nil?
187
+ @logger.debug "Staging #{config_ru_file} to #{@plugin_root_target_dir}"
188
+ cp config_ru_file, @plugin_root_target_dir
189
+ end
179
190
  end
180
191
 
181
192
  def killbill_properties_file
182
- @base.join("killbill.properties").expand_path.to_s
193
+ path_to_string @base.join("killbill.properties").expand_path
194
+ end
195
+
196
+ def config_ru_file
197
+ path_to_string @base.join("config.ru").expand_path
198
+ end
199
+
200
+ def path_to_string(path)
201
+ path.file? ? path.to_s : nil
183
202
  end
184
203
  end
185
204
  end