killbill 3.2.4 → 4.0.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 (117) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -2
  3. data/.travis.yml +26 -5
  4. data/Gemfile +1 -1
  5. data/Gemfile.head +5 -0
  6. data/Gemfile.lock +125 -0
  7. data/Jarfile +9 -9
  8. data/Jarfile.lock +54 -0
  9. data/NEWS +3 -0
  10. data/README.md +13 -0
  11. data/VERSION +1 -1
  12. data/generators/active_merchant/templates/.gitignore.rb +2 -3
  13. data/generators/active_merchant/templates/.travis.yml.rb +22 -3
  14. data/generators/active_merchant/templates/Gemfile.head.rb +5 -0
  15. data/generators/active_merchant/templates/Gemfile.rb +1 -1
  16. data/generators/active_merchant/templates/Jarfile.rb +9 -8
  17. data/generators/active_merchant/templates/LICENSE.rb +2 -2
  18. data/generators/active_merchant/templates/config.yml.rb +16 -6
  19. data/generators/active_merchant/templates/lib/plugin.rb +0 -1
  20. data/generators/active_merchant/templates/plugin.gemspec.rb +17 -15
  21. data/generators/active_merchant/templates/pom.xml.rb +1 -1
  22. data/generators/active_merchant/templates/release.sh.rb +34 -14
  23. data/generators/active_merchant/templates/spec/base_plugin_spec.rb +5 -7
  24. data/generators/active_merchant/templates/spec/integration_spec.rb +7 -18
  25. data/killbill.gemspec +21 -15
  26. data/lib/killbill/ext/active_merchant/typhoeus_connection.rb +3 -4
  27. data/lib/killbill/gen/api/account.rb +1 -1
  28. data/lib/killbill/gen/api/account_data.rb +1 -1
  29. data/lib/killbill/gen/api/audit_log.rb +2 -2
  30. data/lib/killbill/gen/api/audit_user_api.rb +3 -3
  31. data/lib/killbill/gen/api/block.rb +1 -1
  32. data/lib/killbill/gen/api/blocking_state.rb +1 -1
  33. data/lib/killbill/gen/api/call_context.rb +2 -2
  34. data/lib/killbill/gen/api/control_tag.rb +2 -2
  35. data/lib/killbill/gen/api/currency_conversion.rb +1 -1
  36. data/lib/killbill/gen/api/currency_conversion_api.rb +2 -2
  37. data/lib/killbill/gen/api/custom_field.rb +1 -1
  38. data/lib/killbill/gen/api/custom_field_user_api.rb +2 -2
  39. data/lib/killbill/gen/api/dry_run_arguments.rb +22 -3
  40. data/lib/killbill/gen/api/duration.rb +1 -1
  41. data/lib/killbill/gen/api/entitlement.rb +3 -3
  42. data/lib/killbill/gen/api/entitlement_ao_status_dry_run.rb +3 -3
  43. data/lib/killbill/gen/api/entitlement_api.rb +25 -7
  44. data/lib/killbill/gen/api/fixed.rb +1 -1
  45. data/lib/killbill/gen/api/invoice.rb +1 -1
  46. data/lib/killbill/gen/api/invoice_formatter.rb +2 -2
  47. data/lib/killbill/gen/api/invoice_item.rb +2 -2
  48. data/lib/killbill/gen/api/invoice_item_formatter.rb +2 -2
  49. data/lib/killbill/gen/api/invoice_payment.rb +3 -3
  50. data/lib/killbill/gen/api/invoice_user_api.rb +2 -2
  51. data/lib/killbill/gen/api/migration_plan.rb +1 -1
  52. data/lib/killbill/gen/api/mutable_account_data.rb +1 -1
  53. data/lib/killbill/gen/api/payment.rb +1 -1
  54. data/lib/killbill/gen/api/payment_api.rb +11 -11
  55. data/lib/killbill/gen/api/payment_transaction.rb +4 -4
  56. data/lib/killbill/gen/api/plan.rb +1 -1
  57. data/lib/killbill/gen/api/plan_change_result.rb +2 -2
  58. data/lib/killbill/gen/api/plan_phase.rb +1 -1
  59. data/lib/killbill/gen/api/plan_phase_price_override.rb +93 -0
  60. data/lib/killbill/gen/api/plan_phase_price_overrides_with_call_context.rb +77 -0
  61. data/lib/killbill/gen/api/plan_phase_specifier.rb +3 -3
  62. data/lib/killbill/gen/api/plan_specifier.rb +2 -2
  63. data/lib/killbill/gen/api/price.rb +1 -1
  64. data/lib/killbill/gen/api/product.rb +1 -1
  65. data/lib/killbill/gen/api/rate.rb +2 -2
  66. data/lib/killbill/gen/api/record_id_api.rb +1 -1
  67. data/lib/killbill/gen/api/recurring.rb +1 -1
  68. data/lib/killbill/gen/api/refund.rb +2 -2
  69. data/lib/killbill/gen/api/require_gen.rb +2 -0
  70. data/lib/killbill/gen/api/static_catalog.rb +2 -2
  71. data/lib/killbill/gen/api/subscription.rb +3 -3
  72. data/lib/killbill/gen/api/subscription_event.rb +3 -3
  73. data/lib/killbill/gen/api/tag.rb +1 -1
  74. data/lib/killbill/gen/api/tag_definition.rb +1 -1
  75. data/lib/killbill/gen/api/tag_user_api.rb +6 -6
  76. data/lib/killbill/gen/api/tiered_block.rb +1 -1
  77. data/lib/killbill/gen/api/usage.rb +3 -3
  78. data/lib/killbill/gen/plugin-api/currency_plugin_api.rb +1 -1
  79. data/lib/killbill/gen/plugin-api/ext_bus_event.rb +2 -2
  80. data/lib/killbill/gen/plugin-api/payment_transaction_info_plugin.rb +3 -3
  81. data/lib/killbill/helpers/active_merchant.rb +2 -2
  82. data/lib/killbill/helpers/active_merchant/active_record.rb +1 -1
  83. data/lib/killbill/helpers/active_merchant/active_record/active_record_helper.rb +14 -0
  84. data/lib/killbill/helpers/active_merchant/active_record/models/helpers.rb +8 -0
  85. data/lib/killbill/helpers/active_merchant/active_record/models/payment_method.rb +10 -8
  86. data/lib/killbill/helpers/active_merchant/active_record/models/response.rb +16 -3
  87. data/lib/killbill/helpers/active_merchant/active_record/models/streamy_result_set.rb +1 -3
  88. data/lib/killbill/helpers/active_merchant/active_record/models/transaction.rb +2 -0
  89. data/lib/killbill/helpers/active_merchant/configuration.rb +119 -27
  90. data/lib/killbill/helpers/active_merchant/gateway.rb +40 -27
  91. data/lib/killbill/helpers/active_merchant/killbill_spec_helper.rb +63 -45
  92. data/lib/killbill/helpers/active_merchant/payment_plugin.rb +121 -95
  93. data/lib/killbill/helpers/active_merchant/private_payment_plugin.rb +1 -1
  94. data/lib/killbill/helpers/active_merchant/properties.rb +9 -2
  95. data/lib/killbill/helpers/active_merchant/sinatra.rb +4 -8
  96. data/lib/killbill/helpers/active_merchant/utils.rb +44 -0
  97. data/lib/killbill/helpers/properties_helper.rb +41 -0
  98. data/lib/killbill/http_servlet.rb +11 -4
  99. data/lib/killbill/killbill_api.rb +6 -4
  100. data/lib/killbill/rake_task.rb +542 -102
  101. data/spec/killbill/helpers/configuration_spec.rb +117 -33
  102. data/spec/killbill/helpers/payment_method_spec.rb +20 -17
  103. data/spec/killbill/helpers/payment_plugin_spec.rb +401 -201
  104. data/spec/killbill/helpers/private_payment_plugin_spec.rb +3 -16
  105. data/spec/killbill/helpers/response_spec.rb +92 -22
  106. data/spec/killbill/helpers/streamy_result_set_spec.rb +3 -2
  107. data/spec/killbill/helpers/test_payment_method.rb +9 -0
  108. data/spec/killbill/helpers/test_response.rb +11 -0
  109. data/spec/killbill/helpers/test_schema.rb +6 -6
  110. data/spec/killbill/helpers/test_transaction.rb +11 -0
  111. data/spec/killbill/helpers/transaction_spec.rb +3 -13
  112. data/spec/killbill/helpers/utils_spec.rb +127 -69
  113. data/spec/spec_helper.rb +69 -18
  114. metadata +77 -71
  115. data/lib/killbill/ext/active_merchant/jdbc_connection.rb +0 -92
  116. data/lib/killbill/ext/active_merchant/proxy_support.rb +0 -58
  117. data/spec/killbill/helpers/gateway_spec.rb +0 -36
@@ -41,7 +41,7 @@ module Killbill
41
41
 
42
42
  def to_java()
43
43
  # conversion for type [type = org.killbill.billing.catalog.api.BlockType]
44
- @type = Java::org.killbill.billing.catalog.api.BlockType.value_of("#{@type.to_s}") unless @type.nil?
44
+ @type = Java::org.killbill.billing.catalog.api.BlockType.value_of( @type.to_s ) unless @type.nil?
45
45
 
46
46
  # conversion for unit [type = org.killbill.billing.catalog.api.Unit]
47
47
  @unit = @unit.to_java unless @unit.nil?
@@ -44,13 +44,13 @@ module Killbill
44
44
  @name = @name.to_s unless @name.nil?
45
45
 
46
46
  # conversion for billing_mode [type = org.killbill.billing.catalog.api.BillingMode]
47
- @billing_mode = Java::org.killbill.billing.catalog.api.BillingMode.value_of("#{@billing_mode.to_s}") unless @billing_mode.nil?
47
+ @billing_mode = Java::org.killbill.billing.catalog.api.BillingMode.value_of( @billing_mode.to_s ) unless @billing_mode.nil?
48
48
 
49
49
  # conversion for usage_type [type = org.killbill.billing.catalog.api.UsageType]
50
- @usage_type = Java::org.killbill.billing.catalog.api.UsageType.value_of("#{@usage_type.to_s}") unless @usage_type.nil?
50
+ @usage_type = Java::org.killbill.billing.catalog.api.UsageType.value_of( @usage_type.to_s ) unless @usage_type.nil?
51
51
 
52
52
  # conversion for billing_period [type = org.killbill.billing.catalog.api.BillingPeriod]
53
- @billing_period = Java::org.killbill.billing.catalog.api.BillingPeriod.value_of("#{@billing_period.to_s}") unless @billing_period.nil?
53
+ @billing_period = Java::org.killbill.billing.catalog.api.BillingPeriod.value_of( @billing_period.to_s ) unless @billing_period.nil?
54
54
 
55
55
  # conversion for limits [type = org.killbill.billing.catalog.api.Limit[]]
56
56
  tmp = java.util.ArrayList.new
@@ -48,7 +48,7 @@ module Killbill
48
48
  tmp = java.util.TreeSet.new
49
49
  (res || []).each do |m|
50
50
  # conversion for m [type = org.killbill.billing.catalog.api.Currency]
51
- m = Java::org.killbill.billing.catalog.api.Currency.value_of("#{m.to_s}") unless m.nil?
51
+ m = Java::org.killbill.billing.catalog.api.Currency.value_of( m.to_s ) unless m.nil?
52
52
  tmp.add(m)
53
53
  end
54
54
  res = tmp
@@ -41,10 +41,10 @@ module Killbill
41
41
 
42
42
  def to_java()
43
43
  # conversion for event_type [type = org.killbill.billing.notification.plugin.api.ExtBusEventType]
44
- @event_type = Java::org.killbill.billing.notification.plugin.api.ExtBusEventType.value_of("#{@event_type.to_s}") unless @event_type.nil?
44
+ @event_type = Java::org.killbill.billing.notification.plugin.api.ExtBusEventType.value_of( @event_type.to_s ) unless @event_type.nil?
45
45
 
46
46
  # conversion for object_type [type = org.killbill.billing.ObjectType]
47
- @object_type = Java::org.killbill.billing.ObjectType.value_of("#{@object_type.to_s}") unless @object_type.nil?
47
+ @object_type = Java::org.killbill.billing.ObjectType.value_of( @object_type.to_s ) unless @object_type.nil?
48
48
 
49
49
  # conversion for object_id [type = java.util.UUID]
50
50
  @object_id = java.util.UUID.fromString(@object_id.to_s) unless @object_id.nil?
@@ -47,7 +47,7 @@ module Killbill
47
47
  @kb_transaction_payment_id = java.util.UUID.fromString(@kb_transaction_payment_id.to_s) unless @kb_transaction_payment_id.nil?
48
48
 
49
49
  # conversion for transaction_type [type = org.killbill.billing.payment.api.TransactionType]
50
- @transaction_type = Java::org.killbill.billing.payment.api.TransactionType.value_of("#{@transaction_type.to_s}") unless @transaction_type.nil?
50
+ @transaction_type = Java::org.killbill.billing.payment.api.TransactionType.value_of( @transaction_type.to_s ) unless @transaction_type.nil?
51
51
 
52
52
  # conversion for amount [type = java.math.BigDecimal]
53
53
  if @amount.nil?
@@ -57,7 +57,7 @@ module Killbill
57
57
  end
58
58
 
59
59
  # conversion for currency [type = org.killbill.billing.catalog.api.Currency]
60
- @currency = Java::org.killbill.billing.catalog.api.Currency.value_of("#{@currency.to_s}") unless @currency.nil?
60
+ @currency = Java::org.killbill.billing.catalog.api.Currency.value_of( @currency.to_s ) unless @currency.nil?
61
61
 
62
62
  # conversion for created_date [type = org.joda.time.DateTime]
63
63
  if !@created_date.nil?
@@ -72,7 +72,7 @@ module Killbill
72
72
  end
73
73
 
74
74
  # conversion for status [type = org.killbill.billing.payment.plugin.api.PaymentPluginStatus]
75
- @status = Java::org.killbill.billing.payment.plugin.api.PaymentPluginStatus.value_of("#{@status.to_s}") unless @status.nil?
75
+ @status = Java::org.killbill.billing.payment.plugin.api.PaymentPluginStatus.value_of( @status.to_s ) unless @status.nil?
76
76
 
77
77
  # conversion for gateway_error [type = java.lang.String]
78
78
  @gateway_error = @gateway_error.to_s unless @gateway_error.nil?
@@ -3,8 +3,8 @@ module Killbill
3
3
  module ActiveMerchant
4
4
  require 'killbill'
5
5
 
6
- require 'killbill/ext/active_merchant/jdbc_connection'
7
- require 'killbill/ext/active_merchant/proxy_support'
6
+ require File.dirname(__FILE__) + '/properties_helper.rb'
7
+ require File.dirname(__FILE__) + '/active_merchant/active_record/active_record_helper.rb'
8
8
 
9
9
  require 'active_support/core_ext'
10
10
  require File.dirname(__FILE__) + '/active_merchant/core_ext.rb'
@@ -14,4 +14,4 @@ module Killbill
14
14
  end
15
15
  end
16
16
  end
17
- end
17
+ end
@@ -0,0 +1,14 @@
1
+ module Killbill
2
+ module Plugin
3
+ module ActiveMerchant
4
+ module ActiveRecordHelper
5
+
6
+ def close_connection(logger = nil)
7
+ pool = ::ActiveRecord::Base.connection_pool
8
+ logger.debug { "after_request: pool.active_connection? = #{pool.active_connection?}, pool.connections.size = #{pool.connections.size}, connections = #{pool.connections.inspect}" } if logger
9
+ ::ActiveRecord::Base.connection.close if pool.active_connection? # check-in to pool
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -34,6 +34,14 @@ module Killbill
34
34
  }
35
35
  end
36
36
 
37
+ def with_connection(&block)
38
+ self.connection_pool.with_connection(&block)
39
+ end
40
+
41
+ def with_connection_and_transaction(&block)
42
+ with_connection { self.transaction(&block) }
43
+ end
44
+
37
45
  # Useful helper to extract params from AM response objects, e.g. extract(response, 'card', 'address_country')
38
46
  def extract(response, key1, key2=nil, key3=nil)
39
47
  return nil if response.nil? || response.params.nil?
@@ -12,6 +12,8 @@ module Killbill
12
12
  extend ::Killbill::Plugin::ActiveMerchant::Helpers
13
13
 
14
14
  self.abstract_class = true
15
+ # See Response#from_response
16
+ self.record_timestamps = false
15
17
 
16
18
  @@quotes_cache = build_quotes_cache
17
19
 
@@ -23,12 +25,12 @@ module Killbill
23
25
  :kb_payment_method_id => kb_payment_method_id,
24
26
  :kb_tenant_id => kb_tenant_id,
25
27
  :token => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? response.authorization : (cc_or_token || response.authorization),
26
- :cc_first_name => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.first_name : nil,
27
- :cc_last_name => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.last_name : nil,
28
- :cc_type => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.brand : nil,
29
- :cc_exp_month => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.month : nil,
30
- :cc_exp_year => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.year : nil,
31
- :cc_last_4 => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.last_digits : nil,
28
+ :cc_first_name => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.first_name : extra_params[:cc_first_name],
29
+ :cc_last_name => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.last_name : extra_params[:cc_last_name],
30
+ :cc_type => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.brand : extra_params[:cc_type],
31
+ :cc_exp_month => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.month : extra_params[:cc_exp_month],
32
+ :cc_exp_year => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.year : extra_params[:cc_exp_year],
33
+ :cc_last_4 => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.last_digits : extra_params[:cc_last_4],
32
34
  :cc_number => cc_or_token.kind_of?(::ActiveMerchant::Billing::CreditCard) ? cc_or_token.number : nil,
33
35
  :address1 => (options[:billing_address] || {})[:address1],
34
36
  :address2 => (options[:billing_address] || {})[:address2],
@@ -38,7 +40,7 @@ module Killbill
38
40
  :country => (options[:billing_address] || {})[:country],
39
41
  :created_at => current_time,
40
42
  :updated_at => current_time
41
- }.merge!(extra_params))
43
+ }.merge!(extra_params.compact)) # Don't override with nil values
42
44
  end
43
45
 
44
46
  def self.from_kb_account_id(kb_account_id, kb_tenant_id)
@@ -59,7 +61,7 @@ module Killbill
59
61
  else
60
62
  payment_methods = where("kb_payment_method_id = #{@@quotes_cache[kb_payment_method_id]} AND kb_tenant_id = #{@@quotes_cache[kb_tenant_id]} AND is_deleted = #{@@quotes_cache[false]}")
61
63
  end
62
- raise "No payment method found for payment method #{kb_payment_method_id}" if payment_methods.empty?
64
+ raise "No payment method found for payment method #{kb_payment_method_id} and tenant #{kb_tenant_id}" if payment_methods.empty?
63
65
  raise "Kill Bill payment method #{kb_payment_method_id} mapping to multiple active plugin payment methods" if payment_methods.size > 1
64
66
  payment_methods[0]
65
67
  end
@@ -13,11 +13,14 @@ module Killbill
13
13
  extend ::Killbill::Plugin::ActiveMerchant::Helpers
14
14
 
15
15
  self.abstract_class = true
16
+ self.record_timestamps = false
16
17
 
17
18
  @@quotes_cache = build_quotes_cache
18
19
 
19
20
  def self.from_response(api_call, kb_account_id, kb_payment_id, kb_payment_transaction_id, transaction_type, payment_processor_account_id, kb_tenant_id, response, extra_params = {}, model = Response)
20
21
  # Under high load, Rails sometimes fails to set timestamps. Unclear why...
22
+ # But regardless, for performance reasons, we want to set these timestamps ourselves
23
+ # See ActiveRecord::Timestamp
21
24
  current_time = Time.now.utc
22
25
  model.new({
23
26
  :api_call => api_call,
@@ -40,7 +43,7 @@ module Killbill
40
43
  :success => response.success?,
41
44
  :created_at => current_time,
42
45
  :updated_at => current_time
43
- }.merge!(extra_params))
46
+ }.merge!(extra_params.compact)) # Don't override with nil values
44
47
  end
45
48
 
46
49
  def self.create_response_and_transaction(identifier, transaction_model, api_call, kb_account_id, kb_payment_id, kb_payment_transaction_id, transaction_type, payment_processor_account_id, kb_tenant_id, gw_response, amount_in_cents, currency, extra_params = {}, model = Response)
@@ -48,7 +51,7 @@ module Killbill
48
51
 
49
52
  # Rails wraps all create/save calls in a transaction. To speed things up, create a single transaction for both rows.
50
53
  # This has a small gotcha in the unhappy path though (see below).
51
- transaction do
54
+ with_connection_and_transaction do
52
55
  # Save the response to our logs
53
56
  response = from_response(api_call, kb_account_id, kb_payment_id, kb_payment_transaction_id, transaction_type, payment_processor_account_id, kb_tenant_id, gw_response, extra_params, model)
54
57
  response.save!(shared_activerecord_options)
@@ -87,15 +90,25 @@ module Killbill
87
90
  return response, transaction
88
91
  end
89
92
 
93
+ def self.from_kb_payment_id(transaction_model, kb_payment_id, kb_tenant_id)
94
+ association = transaction_model.table_name.singularize.to_sym
95
+ # Use eager_load to force Rails to issue a single query (see https://github.com/killbill/killbill-plugin-framework-ruby/issues/32)
96
+ eager_load(association)
97
+ .where(:kb_payment_id => kb_payment_id, :kb_tenant_id => kb_tenant_id)
98
+ .order(:created_at)
99
+ end
100
+
90
101
  def to_transaction_info_plugin(transaction=nil)
91
102
  if transaction.nil?
92
103
  amount_in_cents = nil
93
104
  currency = nil
94
105
  created_date = created_at
106
+ status = :UNDEFINED # Likely pending
95
107
  else
96
108
  amount_in_cents = transaction.amount_in_cents
97
109
  currency = transaction.currency
98
110
  created_date = transaction.created_at
111
+ status = success ? :PROCESSED : :ERROR
99
112
  end
100
113
 
101
114
  t_info_plugin = Killbill::Plugin::Model::PaymentTransactionInfoPlugin.new
@@ -106,7 +119,7 @@ module Killbill
106
119
  t_info_plugin.currency = currency
107
120
  t_info_plugin.created_date = created_date
108
121
  t_info_plugin.effective_date = effective_date
109
- t_info_plugin.status = (success ? :PROCESSED : :ERROR)
122
+ t_info_plugin.status = status
110
123
  t_info_plugin.gateway_error = gateway_error
111
124
  t_info_plugin.gateway_error_code = gateway_error_code
112
125
  t_info_plugin.first_payment_reference_id = first_reference_id
@@ -36,9 +36,7 @@ module Killbill
36
36
  pool = ::ActiveRecord::Base.connection_pool
37
37
  return unless pool.active_connection?
38
38
 
39
- connection = ::ActiveRecord::Base.connection
40
- pool.remove(connection)
41
- connection.disconnect!
39
+ ::ActiveRecord::Base.connection.close # check-in to pool
42
40
  end
43
41
  end
44
42
  end
@@ -9,6 +9,8 @@ module Killbill
9
9
  extend ::Killbill::Plugin::ActiveMerchant::Helpers
10
10
 
11
11
  self.abstract_class = true
12
+ # See Response#from_response
13
+ self.record_timestamps = false
12
14
 
13
15
  @@quotes_cache = build_quotes_cache
14
16
 
@@ -1,4 +1,5 @@
1
1
  require 'logger'
2
+ require 'pathname'
2
3
  require 'thread_safe'
3
4
 
4
5
  module Killbill
@@ -12,39 +13,31 @@ module Killbill
12
13
  mattr_reader :kb_apis
13
14
  mattr_reader :gateway_name
14
15
  mattr_reader :gateway_builder
16
+ # To be kept in sync with sinatra.rb
15
17
  mattr_reader :logger
16
18
  mattr_reader :config_key_name
17
19
  mattr_reader :per_tenant_config_cache
18
20
 
19
-
20
21
  class << self
21
22
 
22
23
  def initialize!(gateway_builder, gateway_name, logger, config_key_name, config_file, kb_apis)
23
-
24
24
  @@logger = logger
25
25
  @@kb_apis = kb_apis
26
26
  @@gateway_name = gateway_name
27
27
  @@gateway_builder = gateway_builder
28
28
  @@config_key_name = config_key_name
29
29
  @@per_tenant_config_cache = ThreadSafe::Cache.new
30
+ @@per_tenant_gateways_cache = ThreadSafe::Cache.new
30
31
 
31
- if defined?(JRUBY_VERSION)
32
- begin
33
- # See https://github.com/jruby/activerecord-jdbc-adapter/issues/302
34
- require 'jdbc/mysql'
35
- ::Jdbc::MySQL.load_driver(:require) if ::Jdbc::MySQL.respond_to?(:load_driver)
36
- rescue => e
37
- @@logger.warn "Unable to load the JDBC driver: #{e}"
38
- end
39
- end
40
-
41
- initialize_from_global_config!(gateway_builder, gateway_name, logger, config_file)
32
+ initialize_from_global_config!(config_file)
42
33
  end
43
34
 
44
-
45
35
  def gateways(kb_tenant_id=nil)
46
- tenant_config = get_tenant_config(kb_tenant_id)
47
- extract_gateway_config(tenant_config)
36
+ if @@per_tenant_gateways_cache[kb_tenant_id].nil?
37
+ tenant_config = get_tenant_config(kb_tenant_id)
38
+ @@per_tenant_gateways_cache[kb_tenant_id] = extract_gateway_config(tenant_config)
39
+ end
40
+ @@per_tenant_gateways_cache[kb_tenant_id]
48
41
  end
49
42
 
50
43
  def currency_conversions(kb_tenant_id=nil)
@@ -56,8 +49,9 @@ module Killbill
56
49
  end
57
50
  end
58
51
 
52
+ # To be kept in sync with sinatra.rb
59
53
  def config(kb_tenant_id=nil)
60
- get_tenant_config(kb_tenant_id)
54
+ @@glob_config.merge(get_tenant_config(kb_tenant_id) || {})
61
55
  end
62
56
 
63
57
  def converted_currency(currency, kb_tenant_id=nil)
@@ -69,6 +63,7 @@ module Killbill
69
63
  def invalidate_tenant_config!(kb_tenant_id)
70
64
  @@logger.info("Invalidate plugin key #{@@config_key_name}, tenant = #{kb_tenant_id}")
71
65
  @@per_tenant_config_cache[kb_tenant_id] = nil
66
+ @@per_tenant_gateways_cache[kb_tenant_id] = nil
72
67
  end
73
68
 
74
69
  private
@@ -83,19 +78,18 @@ module Killbill
83
78
  if gateway_account_id.nil?
84
79
  @@logger.warn "Skipping config #{gateway_config} -- missing :account_id"
85
80
  else
86
- gateways_config[gateway_account_id.to_sym] = Gateway.wrap(gateway_builder, logger, gateway_config)
81
+ gateways_config[gateway_account_id.to_sym] = Gateway.wrap(gateway_builder, gateway_config)
87
82
  default_gateway = gateways_config[gateway_account_id.to_sym] if idx == 0
88
83
  end
89
84
  end
90
85
  gateways_config[:default] = default_gateway if gateways_config[:default].nil?
91
86
  else
92
- gateways_config[:default] = Gateway.wrap(@@gateway_builder, logger, gateway_configs)
87
+ gateways_config[:default] = Gateway.wrap(@@gateway_builder, gateway_configs)
93
88
  end
94
89
  gateways_config
95
90
  end
96
91
 
97
92
  def get_tenant_config(kb_tenant_id)
98
-
99
93
  if @@per_tenant_config_cache[kb_tenant_id].nil?
100
94
  # Make the api api to verify if there is a per tenant value
101
95
  context = @@kb_apis.create_context(kb_tenant_id) if kb_tenant_id
@@ -113,30 +107,128 @@ module Killbill
113
107
  @@per_tenant_config_cache[kb_tenant_id]
114
108
  end
115
109
 
116
- def initialize_from_global_config!(gateway_builder, gateway_name, logger, config_file)
110
+ def initialize_from_global_config!(config_file)
117
111
  # Look for global config
118
- @@glob_config = Properties.new(config_file)
119
- @@glob_config.parse!
112
+ if !config_file.blank? && Pathname.new(config_file).file?
113
+ @@glob_config = Properties.new(config_file)
114
+ @@glob_config.parse!
115
+ @@glob_config = @@glob_config.to_hash
116
+ else
117
+ @@glob_config = {}
118
+ end
120
119
 
121
120
  @@logger.log_level = Logger::DEBUG if (@@glob_config[:logger] || {})[:debug]
122
121
 
123
122
  @@glob_currency_conversions = @@glob_config[:currency_conversions]
124
123
 
124
+ initialize_active_record
125
+
126
+ initialize_active_merchant
127
+
128
+ @@initialized = true
129
+ end
130
+
131
+ def initialize_active_record
125
132
  begin
126
133
  require 'active_record'
127
- ::ActiveRecord::Base.establish_connection(@@glob_config[:database])
134
+ require 'arjdbc' if defined?(JRUBY_VERSION)
135
+ db_config = @@glob_config[:database]
136
+
137
+ if db_config.nil?
138
+ # Sane defaults for running as a Kill Bill plugin
139
+ db_config = {
140
+ :adapter => :mysql,
141
+ # See KillbillActivator#KILLBILL_OSGI_JDBC_JNDI_NAME
142
+ :jndi => 'killbill/osgi/jdbc',
143
+ # See https://github.com/kares/activerecord-bogacs
144
+ :pool => false,
145
+ # Since AR-JDBC 1.4, to disable session configuration
146
+ :configure_connection => false
147
+ }
148
+ end
149
+
150
+ if defined?(JRUBY_VERSION) && db_config.is_a?(Hash)
151
+ if db_config[:jndi]
152
+ # Lookup the DataSource object once, for performance reasons
153
+ begin
154
+ db_config[:data_source] = Java::JavaxNaming::InitialContext.new.lookup(db_config[:jndi].to_s)
155
+ db_config.delete(:jndi)
156
+ rescue Java::javax.naming.NamingException => e
157
+ # See https://github.com/killbill/killbill-plugin-framework-ruby/issues/39
158
+ @@logger.warn "Unable to lookup JNDI DataSource (yet?): #{e}" unless defined?(JBUNDLER_CLASSPATH)
159
+ end
160
+ end
161
+
162
+ # we accept a **pool: false** configuration in which case we
163
+ # the built-in pool is replaced with a false one (under JNDI) :
164
+ if db_config[:pool] == false && ( db_config[:jndi] || db_config[:data_source] )
165
+ begin; require 'active_record/bogacs'
166
+ pool_class = ::ActiveRecord::Bogacs::FalsePool
167
+ ::ActiveRecord::ConnectionAdapters::ConnectionHandler.connection_pool_class = pool_class
168
+ rescue LoadError
169
+ db_config.delete(:pool) # do not confuse AR's built-in pool
170
+ @@logger.warn "ActiveRecord-Bogacs missing, will use default (built-in) AR pool."
171
+ end
172
+ end
173
+ end
174
+ ::ActiveRecord::Base.establish_connection(db_config)
128
175
  ::ActiveRecord::Base.logger = @@logger
129
176
  rescue => e
130
177
  @@logger.warn "Unable to establish a database connection: #{e}"
131
178
  end
179
+ end
180
+
181
+ # Configure global properties
182
+ # It would be nice to fix ActiveMerchant to make these configurable on a per instance basis
183
+ def initialize_active_merchant
184
+ require 'active_merchant'
185
+
186
+ ::ActiveMerchant::Billing::Gateway.logger = @@logger
187
+
188
+ am_config = @@glob_config[@@gateway_name.to_sym]
189
+ if am_config.is_a?(Array)
190
+ default_gateway_config = {}
191
+ am_config.each_with_index do |gateway_config, idx|
192
+ gateway_account_id = gateway_config[:account_id]
193
+ if gateway_account_id.nil?
194
+ @@logger.warn "Skipping config #{gateway_config} -- missing :account_id"
195
+ else
196
+ default_gateway_config = gateway_config if idx == 0 || gateway_account_id == :default
197
+ end
198
+ end
199
+ am_config = default_gateway_config
200
+ end
201
+ am_config ||= {
202
+ # Sane defaults
203
+ :test => true
204
+ }
205
+
206
+ if am_config[:test]
207
+ ::ActiveMerchant::Billing::Base.mode = :test
208
+ end
209
+
210
+ if am_config[:log_file]
211
+ ::ActiveMerchant::Billing::Gateway.wiredump_device = File.open(am_config[:log_file], 'w')
212
+ else
213
+ log_method = am_config[:quiet] ? :debug : :info
214
+ ::ActiveMerchant::Billing::Gateway.wiredump_device = ::Killbill::Plugin::ActiveMerchant::Utils::KBWiredumpDevice.new(@@logger, log_method)
215
+ end
216
+ ::ActiveMerchant::Billing::Gateway.wiredump_device.sync = true
217
+
218
+ ::ActiveMerchant::Billing::Gateway.open_timeout = am_config[:open_timeout] unless am_config[:open_timeout].nil?
219
+ ::ActiveMerchant::Billing::Gateway.read_timeout = am_config[:read_timeout] unless am_config[:read_timeout].nil?
220
+ ::ActiveMerchant::Billing::Gateway.retry_safe = am_config[:retry_safe] unless am_config[:retry_safe].nil?
221
+ ::ActiveMerchant::Billing::Gateway.ssl_strict = am_config[:ssl_strict] unless am_config[:ssl_strict].nil?
222
+ ::ActiveMerchant::Billing::Gateway.ssl_version = am_config[:ssl_version] unless am_config[:ssl_version].nil?
223
+ ::ActiveMerchant::Billing::Gateway.max_retries = am_config[:max_retries] unless am_config[:max_retries].nil?
224
+ ::ActiveMerchant::Billing::Gateway.proxy_address = am_config[:proxy_address] unless am_config[:proxy_address].nil?
225
+ ::ActiveMerchant::Billing::Gateway.proxy_port = am_config[:proxy_port] unless am_config[:proxy_port].nil?
132
226
 
133
227
  # Configure the ActiveMerchant HTTP backend
134
- connection_type = (@@glob_config[:active_merchant] || {})[:connection_type]
228
+ connection_type = (@@glob_config[:active_merchant] || am_config)[:connection_type]
135
229
  if connection_type == :typhoeus
136
230
  require 'killbill/ext/active_merchant/typhoeus_connection'
137
231
  end
138
-
139
- @@initialized = true
140
232
  end
141
233
  end
142
234
  end