unageanu-jiji 1.0.3 → 1.1.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 (68) hide show
  1. data/ChangeLog +3 -0
  2. data/bin/jiji +1 -1
  3. data/html/swf/chart.swf +0 -0
  4. data/lib/jiji/agent/agent.rb +0 -1
  5. data/lib/jiji/agent/agent_manager.rb +0 -1
  6. data/lib/jiji/collector.rb +14 -17
  7. data/lib/jiji/command.rb +40 -12
  8. data/lib/jiji/configuration.rb +8 -2
  9. data/lib/jiji/dao/trade_result_dao.rb +1 -1
  10. data/lib/jiji/migration/migrator1_1_0.rb +46 -0
  11. data/lib/jiji/models.rb +1 -5
  12. data/lib/jiji/operator.rb +12 -30
  13. data/lib/jiji/plugin/embedded/click_securities_demo_plugin.rb +140 -0
  14. data/lib/jiji/plugin/embedded/single_click_client.rb +107 -0
  15. data/lib/jiji/plugin/plugin_loader.rb +53 -0
  16. data/lib/jiji/plugin/securities_plugin.rb +135 -0
  17. data/lib/jiji/registry.rb +24 -19
  18. data/lib/jiji/server.rb +3 -1
  19. data/lib/jiji/service/rate_service.rb +7 -2
  20. data/lib/jiji/util/block_to_session.rb +4 -4
  21. data/lib/jiji/util/util.rb +0 -67
  22. data/lib/jiji_plugin.rb +6 -0
  23. data/swf/build.xml +1 -1
  24. data/swf/chart/fx/chart/Chart.as +6 -4
  25. data/swf/chart/fx/chart/ctrl/Controller.as +12 -0
  26. data/swf/chart/fx/chart/model/Model.as +3 -1
  27. data/swf/chart/fx/chart/ui/RangeInfoWindow.as +1 -1
  28. data/swf/chart/fx/chart/ui/ScaleSelector.as +6 -17
  29. data/test/OutputregistryTest/conf/configuration.yaml +3 -0
  30. data/test/ProcessManagerTest/conf/configuration.yaml +4 -17
  31. data/test/{test_AgentManager.rb → agent/test_AgentManager.rb} +37 -39
  32. data/test/{test_AgentRegistry.rb → agent/test_AgentRegistry.rb} +3 -2
  33. data/test/{test_PeriodicallyAgent.rb → agent/test_PeriodicallyAgent.rb} +7 -6
  34. data/test/{test_Permitter.rb → agent/test_Permitter.rb} +10 -9
  35. data/test/all_tests.rb +31 -24
  36. data/test/{test_RateDao.rb → dao/test_RateDao.rb} +5 -5
  37. data/test/{test_TradeResultDao.rb → dao/test_TradeResultDao.rb} +12 -11
  38. data/test/jiji_plugin.rb +7 -0
  39. data/test/migration/migrator1_1_0test_data/configuration.yaml +11 -0
  40. data/test/migration/test_Migrator1_1_0.rb +56 -0
  41. data/test/{test_SingleClickClient.rb → plugin/embedded/test_SingleClickClient.rb} +44 -14
  42. data/test/plugin/error_test/jiji_plugin.rb +2 -0
  43. data/test/plugin/test/foo_plugin.rb +1 -0
  44. data/test/plugin/test/jiji_plugin.rb +2 -0
  45. data/test/plugin/test_Loader.rb +33 -0
  46. data/test/plugin/test_gem/a/jiji_plugin_test_gem_a-1.0.0.gem +0 -0
  47. data/test/plugin/test_gem/a/jiji_plugin_test_gem_a.gemspec +10 -0
  48. data/test/plugin/test_gem/a/lib/jiji_plugin.rb +2 -0
  49. data/test/plugin/test_gem/a/lib/jiji_plugin_test.rb +6 -0
  50. data/test/plugin/test_gem/b/jiji_plugin_test_gem_b-1.0.0.gem +0 -0
  51. data/test/plugin/test_gem/b/jiji_plugin_test_gem_b.gemspec +9 -0
  52. data/test/plugin/test_gem/b/lib/jiji_plugin.rb +2 -0
  53. data/test/test_BackTestCollector.rb +12 -20
  54. data/test/test_Collector.rb +16 -32
  55. data/test/test_Configuration.rb +3 -3
  56. data/test/test_Operator.rb +9 -9
  57. data/test/test_Output.rb +2 -3
  58. data/test/test_Output_registry.rb +9 -9
  59. data/test/test_Process.rb +6 -6
  60. data/test/test_ProcessManager.rb +11 -9
  61. data/test/test_utils.rb +49 -0
  62. data/test/{test_BlockToSession.rb → util/test_BlockToSession.rb} +57 -9
  63. data/test/{test_CSV.rb → util/test_CSV.rb} +5 -5
  64. data/test/{test_SynchronizeInterceptor.rb → util/test_SynchronizeInterceptor.rb} +5 -3
  65. metadata +59 -26
  66. data/lib/jiji/single_click_client.rb +0 -95
  67. data/test/test_configuration.yaml +0 -16
  68. data/test/testutils.rb +0 -37
data/ChangeLog CHANGED
@@ -1,4 +1,7 @@
1
1
 
2
+ 2009-5-6 1.1.0
3
+ * 証券会社へのアクセスロジックを、プラグインで後から追加できるように修正。
4
+
2
5
  2009-4-19 1.0.3
3
6
  * グラフの色を変更してもリロードすると元に戻る不具合を修正。
4
7
 
data/bin/jiji CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'rubygems'
3
+ require 'rubygems'
4
4
  require 'jiji/command'
5
5
  JIJI::Command.new.run( ARGV )
data/html/swf/chart.swf CHANGED
Binary file
@@ -3,7 +3,6 @@ require 'jiji/util/file_lock'
3
3
  require "jiji/models"
4
4
  require 'jiji/util/util'
5
5
  require 'jiji/operator'
6
- require 'jiji/single_click_client'
7
6
  require 'jiji/output'
8
7
 
9
8
  module JIJI
@@ -123,7 +123,6 @@ module JIJI
123
123
  end
124
124
 
125
125
  attr :agent_registry, true
126
- attr :client, true
127
126
  attr :trade_result_dao, true
128
127
  attr :operator, true
129
128
  attr :conf, true
@@ -76,7 +76,7 @@ module JIJI
76
76
  attr :observer_manager, true
77
77
  #ロガー
78
78
  attr :logger, true
79
- #JIJI::SingleClickClient
79
+ #証券会社アクセスクライアント
80
80
  attr :client, true
81
81
  #情報取得中に発生したエラー
82
82
  attr_reader :error
@@ -90,8 +90,9 @@ module JIJI
90
90
  @logger.info( "collector start" )
91
91
  JIJI::Util.log_if_error_and_throw( @logger ) {
92
92
  # 通貨ペア情報を取得
93
- @pair_infos = @client.request{|fx|
94
- fx.list_currency_pairs
93
+ @pair_infos = @client.list_pairs.inject({}){|r,i|
94
+ r[i.name.to_sym] = i
95
+ r
95
96
  }
96
97
  }
97
98
  collect
@@ -122,20 +123,16 @@ module JIJI
122
123
  def collect
123
124
  while( @end_mutex.synchronize { @alive } ) #停止されるまでループ
124
125
  JIJI::Util.log_if_error( @logger ) {
125
- #通貨ペアコードを変換
126
- list = @client.request{|fx|
127
- fx.list_rates.inject({}) {|r,p|
128
- code = JIJI::Util.convert_currency_pair_code(p[0])
129
- r[code] = p[1]
130
- r
131
- }
132
- }
133
- #オブザーバーに通知
134
- @observer_manager.next_rates Rates.new( @pair_infos, list )
135
- @now = Time.now # 現在時刻を更新
136
-
137
- # 一定期間待つ
138
- sleep @conf.get([:collector, :wait_time], 10 )
126
+ begin
127
+ #レート
128
+ list = @client.list_rates
129
+ #オブザーバーに通知
130
+ @observer_manager.next_rates Rates.new( @pair_infos, list )
131
+ @now = Time.now # 現在時刻を更新
132
+ ensure
133
+ # 一定期間待つ
134
+ sleep @conf.get([:collector, :wait_time], 10 )
135
+ end
139
136
  }
140
137
  end
141
138
  end
data/lib/jiji/command.rb CHANGED
@@ -1,8 +1,11 @@
1
1
 
2
2
  require 'rubygems'
3
3
  require "highline"
4
+ require 'logger'
4
5
  require 'jiji/server'
5
6
  require 'jiji/util/json_rpc_requestor'
7
+ require 'jiji/plugin/plugin_loader'
8
+ require 'jiji/plugin/securities_plugin'
6
9
 
7
10
  module JIJI
8
11
 
@@ -45,8 +48,39 @@ module JIJI
45
48
  # 初期化
46
49
  def setting
47
50
  h = HighLine.new
48
- user = h.ask("> Please input a user name of CLICK Securities DEMO Trade.")
49
- pass = h.ask("> Please input a password of CLICK Securities DEMO Trade."){|q| q.echo = '*' }
51
+
52
+ # アクセス先証券会社
53
+ JIJI::Plugin::Loader.new.load
54
+ mng = JIJI::Plugin::SecuritiesPluginManager.new
55
+ plugins = mng.all
56
+ index = 0
57
+ str = plugins.map {|p| "#{index+=1} : #{p.display_name.to_s}" }.join( "\n " )
58
+ value = h.ask("> Please select a securities.\n " + str)
59
+ unless value =~ /\d+/
60
+ puts "[ERROR] setting failed.( Illegal value. vlaue=#{value} )"
61
+ return
62
+ end
63
+ begin
64
+ type = plugins[value.to_i-1]
65
+ unless type
66
+ puts "[ERROR] setting failed.( Illegal value. vlaue=#{value} )"
67
+ return
68
+ end
69
+ rescue Exception
70
+ puts "[ERROR] setting failed.( Illegal value. vlaue=#{value} )"
71
+ return
72
+ end
73
+
74
+ # 入力
75
+ values = {:type=>type.plugin_id}
76
+ type.input_infos.each {|i|
77
+ value = i.secure ? h.ask("> #{i.description}") {|q| q.echo = '*' } : h.ask("> #{i.description}")
78
+ if i.validator && error = i.validator.call( value )
79
+ puts "[ERROR] setting failed.( #{error}. value=#{value} )"
80
+ return
81
+ end
82
+ values[i.key.to_sym] = value
83
+ }
50
84
  dir = h.ask("> Please input a data directory of jiji. (default: #{JIJI_DIR_NAME} )")
51
85
  dir = !dir || dir.empty? ? JIJI_DIR_NAME : dir
52
86
 
@@ -74,16 +108,10 @@ module JIJI
74
108
 
75
109
  # 設定ファイル
76
110
  open( "#{dir}/conf/configuration.yaml", "w" ) {|f|
77
- f << <<-DATA
78
- ---
79
- server:
80
- port: #{port}
81
-
82
- securities:
83
- account:
84
- user: "#{user}"
85
- password: "#{pass}"
86
- DATA
111
+ f << YAML.dump( {
112
+ :server => { :port=>port.to_i },
113
+ :securities => values
114
+ } )
87
115
  }
88
116
  FileUtils.chmod(0600, "#{dir}/conf/configuration.yaml")
89
117
 
@@ -12,8 +12,14 @@ module JIJI
12
12
  #コンストラクタ
13
13
  #configuration_file:: 設定ファイルのパス
14
14
  def initialize( configuration_file=nil )
15
- if configuration_file && File.exist?( configuration_file )
16
- FileLock.new( configuration_file ).readlock {|f|
15
+ @configuration_file=configuration_file
16
+ load
17
+ end
18
+
19
+ # データをロードする
20
+ def load
21
+ if @configuration_file && File.exist?( @configuration_file )
22
+ FileLock.new( @configuration_file ).readlock {|f|
17
23
  tmp = YAML.load f
18
24
  @conf = key_to_sym( tmp )
19
25
  }
@@ -61,7 +61,7 @@ module JIJI
61
61
  end
62
62
  ids.inject({}) {|r,id|
63
63
  v = load(id)
64
- if ( !( start_date && v[:fix_date] != 0 && v[:fix_date] < start_date.to_i ) \
64
+ if ( v && !( start_date && v[:fix_date] != 0 && v[:fix_date] < start_date.to_i ) \
65
65
  && !( end_date && v[:date] > end_date.to_i ))
66
66
  r[id] = v
67
67
  end
@@ -0,0 +1,46 @@
1
+
2
+ require 'fileutils'
3
+ require 'yaml'
4
+ require 'jiji/util/fix_yaml_bug'
5
+ require 'jiji/util/file_lock'
6
+
7
+ module JIJI
8
+ module Migration
9
+
10
+ #===1.0.3 → 1.1.0
11
+ class Migrator1_1_0
12
+ def migrate( registry )
13
+ #設定ファイルを更新
14
+ conf_file = registry.base_dir + "/conf/configuration.yaml"
15
+ return unless File.exist? conf_file
16
+ tmp = key_to_sym(YAML.load_file(conf_file))
17
+
18
+ # 証券会社アクセス関連の設定値を置換
19
+ if( tmp[:securities] )
20
+ old = tmp[:securities]
21
+ tmp[:securities] = {
22
+ :type=>:click_securities_demo,
23
+ :user=>old[:account] &&old[:account][:user] ? old[:account][:user] : "",
24
+ :password=>old[:account] &&old[:account][:password] ? old[:account][:password] : ""
25
+ }
26
+ open( conf_file, "w" ) {|f|
27
+ f << YAML.dump( tmp )
28
+ }
29
+ # 設定値を再読み込み
30
+ registry.conf.load
31
+ end
32
+ end
33
+
34
+ # ハッシュのキーをシンボルに置換する
35
+ def key_to_sym( map )
36
+ map.inject({}) {|r,e|
37
+ v = e[1].kind_of?(Hash) ? key_to_sym( e[1] ) : e[1]
38
+ r.store(e[0].to_sym, v)
39
+ r
40
+ }
41
+ end
42
+ end
43
+
44
+ end
45
+ end
46
+
data/lib/jiji/models.rb CHANGED
@@ -11,11 +11,7 @@ module JIJI
11
11
 
12
12
  def initialize( pair_infos, list, time=Time.now )
13
13
  super()
14
- @pair_infos = pair_infos.inject({}){ |r,pair|
15
- code = JIJI::Util.convert_currency_pair_code(pair[0])
16
- r[code] = pair[1]
17
- r
18
- }
14
+ @pair_infos = pair_infos
19
15
  @time = time
20
16
  list.each_pair { |k,info|
21
17
  self[k] = Rate.new( info.bid.to_f, info.ask.to_f,
data/lib/jiji/operator.rb CHANGED
@@ -2,7 +2,6 @@
2
2
  require 'fileutils'
3
3
  require 'delegate'
4
4
  require 'jiji/util/util'
5
- require 'jiji/single_click_client'
6
5
  require 'jiji/util/util'
7
6
  require 'jiji/dao/timed_data_dao'
8
7
  require 'uuidtools'
@@ -228,7 +227,7 @@ module JIJI
228
227
  def values
229
228
  {
230
229
  :position_id => position_id,
231
- :open_interest_no=> open_interest_no,
230
+ :raw_position_id => raw_position_id,
232
231
  :sell_or_buy => sell_or_buy == JIJI::Position::SELL ? :sell : :buy,
233
232
  :state => state,
234
233
  :date => date.to_i,
@@ -246,13 +245,12 @@ module JIJI
246
245
 
247
246
  # クライアント
248
247
  attr :operator
249
- # 建玉番号
250
- attr :open_interest_no, true
251
- # 注文番号
252
- attr :order_no, true
253
248
 
254
249
  # 一意な識別子
255
250
  attr_reader :position_id
251
+ # プラグインが返す識別子
252
+ attr :raw_position_id, true
253
+
256
254
  # 売りか買いか?
257
255
  attr_reader :sell_or_buy
258
256
  # 状態
@@ -300,23 +298,16 @@ module JIJI
300
298
  #*count*:: 購入する数量
301
299
  #*return*:: Position
302
300
  def buy(count, pair=:EURJPY, trader="")
303
- open_interest_no = nil
304
- order_no = nil
301
+ id = nil
305
302
  if @trade_enable
306
303
  JIJI::Util.log_if_error_and_throw( @logger ) {
307
304
  rate = @rate[pair]
308
305
  # 成り行きで買い
309
- result = @client.request{ |fx|
310
- fx.order( JIJI::Util.convert_currency_pair_code_r(pair),
311
- ClickClient::FX::BUY, count, options={:slippage_base_rate=>rate.bid} )
312
- }
313
- open_interest_no = result.open_interest_no
314
- order_no = result.order_no
306
+ id = @client.order( pair, :buy, count ).position_id
315
307
  }
316
308
  end
317
309
  p = super(count, pair, trader)
318
- p.open_interest_no = open_interest_no
319
- p.order_no = order_no
310
+ p.raw_position_id = id if id
320
311
  p
321
312
  end
322
313
 
@@ -324,33 +315,24 @@ module JIJI
324
315
  #*count*:: 売却する数量
325
316
  #*return*:: Position
326
317
  def sell(count, pair=:EURJPY, trader="")
327
- open_interest_no = nil
328
- order_no = nil
318
+ id = nil
329
319
  if @trade_enable
330
320
  JIJI::Util.log_if_error_and_throw( @logger ) {
331
321
  rate = @rate[pair]
332
322
  # 成り行きで売り
333
- result = @client.request {|fx|
334
- fx.order( JIJI::Util.convert_currency_pair_code_r(pair),
335
- ClickClient::FX::SELL, count, options={:slippage_base_rate=>rate.ask} )
336
- }
337
- open_interest_no = result.open_interest_no
338
- order_no = result.order_no
323
+ id = @client.order( pair, :sell, count ).position_id
339
324
  }
340
325
  end
341
326
  p = super(count, pair, trader)
342
- p.open_interest_no = open_interest_no
343
- p.order_no = order_no
327
+ p.raw_position_id = id if id
344
328
  p
345
329
  end
346
330
 
347
331
  # 取引を確定する
348
332
  def commit(position)
349
- if @trade_enable
333
+ if @trade_enable && position.raw_position_id
350
334
  JIJI::Util.log_if_error_and_throw( @logger ) {
351
- @client.request {|fx|
352
- fx.settle( position.open_interest_no, position.count )
353
- }
335
+ @client.commit( position.raw_position_id, position.count )
354
336
  }
355
337
  end
356
338
  super(position)
@@ -0,0 +1,140 @@
1
+
2
+ require 'jiji/plugin/securities_plugin'
3
+ require 'jiji/plugin/embedded/single_click_client'
4
+
5
+ module JIJI
6
+ module Plugin
7
+
8
+ # クリック証券デモトレードアクセスプラグイン
9
+ class ClickSecuritiesDemoPlugin
10
+ include JIJI::Plugin::SecuritiesPlugin
11
+
12
+ #プラグインの識別子を返します。
13
+ def plugin_id
14
+ :click_securities_demo
15
+ end
16
+ #プラグインの表示名を返します。
17
+ def display_name
18
+ "CLICK Securities DEMO Trade"
19
+ end
20
+ #「jiji setting」でユーザーに入力を要求するデータの情報を返します。
21
+ def input_infos
22
+ [ Input.new( :user, "Please input a user name of CLICK Securities DEMO Trade.", false, nil ),
23
+ Input.new( :password, "Please input a password of CLICK Securities DEMO Trade.", true, nil )]
24
+ end
25
+
26
+ #プラグインを初期化します。
27
+ def init_plugin( props, logger )
28
+ @client = JIJI::Plugin::SingleClickClient.new( props, logger )
29
+ end
30
+ #プラグインを破棄します。
31
+ def destroy_plugin
32
+ @client.close if @client
33
+ end
34
+
35
+ #利用可能な通貨ペア一覧を取得します。
36
+ def list_pairs
37
+ pairs = @client.request {|fx| fx.list_currency_pairs }
38
+ return pairs.map {|i|
39
+ name = convert_currency_pair_code(i[0])
40
+ Pair.new( name, i[1].trade_unit )
41
+ }
42
+ end
43
+
44
+ #現在のレートを取得します。
45
+ def list_rates
46
+ @client.request {|fx|
47
+ fx.list_rates.inject({}) {|r,p|
48
+ code = convert_currency_pair_code(p[0])
49
+ r[code] = Rate.new( p[1].bid, p[1].ask, p[1].sell_swap, p[1].buy_swap )
50
+ r
51
+ }
52
+ }
53
+ end
54
+
55
+ #成り行きで発注を行います。
56
+ def order( pair, sell_or_buy, count )
57
+ result = @client.request{ |fx|
58
+ fx.order( convert_currency_pair_code_r(pair),
59
+ sell_or_buy == :buy ? ClickClient::FX::BUY : ClickClient::FX::SELL, count )
60
+ }
61
+ return JIJI::Plugin::SecuritiesPlugin::Position.new( result.open_interest_no )
62
+ end
63
+
64
+ #建玉を決済します。
65
+ def commit( position_id, count )
66
+ @client.request {|fx| fx.settle( position_id, count ) }
67
+ end
68
+
69
+ # 通貨ペアコードをシンボルに変換する
70
+ def convert_currency_pair_code(code)
71
+ case code
72
+ when ClickClient::FX::USDJPY
73
+ return :USDJPY
74
+ when ClickClient::FX::EURJPY
75
+ return :EURJPY
76
+ when ClickClient::FX::GBPJPY
77
+ return :GBPJPY
78
+ when ClickClient::FX::AUDJPY
79
+ return :AUDJPY
80
+ when ClickClient::FX::NZDJPY
81
+ return :NZDJPY
82
+ when ClickClient::FX::CADJPY
83
+ return :CADJPY
84
+ when ClickClient::FX::CHFJPY
85
+ return :CHFJPY
86
+ when ClickClient::FX::ZARJPY
87
+ return :ZARJPY
88
+ when ClickClient::FX::EURUSD
89
+ return :EURUSD
90
+ when ClickClient::FX::GBPUSD
91
+ return :GBPUSD
92
+ when ClickClient::FX::AUDUSD
93
+ return :AUDUSD
94
+ when ClickClient::FX::EURCHF
95
+ return :EURCHF
96
+ when ClickClient::FX::GBPCHF
97
+ return :GBPCHF
98
+ when ClickClient::FX::USDCHF
99
+ return :USDCHF
100
+ end
101
+ end
102
+
103
+ # シンボルを通貨ペアコードに変換する
104
+ def convert_currency_pair_code_r(code)
105
+ case code
106
+ when :USDJPY
107
+ return ClickClient::FX::USDJPY
108
+ when :EURJPY
109
+ return ClickClient::FX::EURJPY
110
+ when :GBPJPY
111
+ return ClickClient::FX::GBPJPY
112
+ when :AUDJPY
113
+ return ClickClient::FX::AUDJPY
114
+ when :NZDJPY
115
+ return ClickClient::FX::NZDJPY
116
+ when :CADJPY
117
+ return ClickClient::FX::CADJPY
118
+ when :CHFJPY
119
+ return ClickClient::FX::CHFJPY
120
+ when :ZARJPY
121
+ return ClickClient::FX::ZARJPY
122
+ when :EURUSD
123
+ return ClickClient::FX::EURUSD
124
+ when :GBPUSD
125
+ return ClickClient::FX::GBPUSD
126
+ when :AUDUSD
127
+ return ClickClient::FX::AUDUSD
128
+ when :EURCHF
129
+ return ClickClient::FX::EURCHF
130
+ when :GBPCHF
131
+ return ClickClient::FX::GBPCHF
132
+ when :USDCHF
133
+ return ClickClient::FX::USDCHF
134
+ end
135
+ end
136
+
137
+ end
138
+
139
+ end
140
+ end
@@ -0,0 +1,107 @@
1
+
2
+ require "rubygems"
3
+ require "clickclient"
4
+ require 'jiji/util/block_to_session'
5
+ require 'jiji/util/util'
6
+ require 'jiji/error'
7
+
8
+ # エラー発生時に実行時例外になる場合があるので修正。
9
+ module ClickClient
10
+ def self.parse( content )
11
+ doc = REXML::Document.new( content )
12
+ unless ( doc.text( "./*/responseStatus" ) =~ /OK/ )
13
+ error = doc.text( "./*/message" )
14
+ raise "fail. #{error ? error : content }"
15
+ end
16
+ return doc
17
+ end
18
+ end
19
+
20
+
21
+ module JIJI
22
+ module Plugin
23
+
24
+ #
25
+ #==クリック証券へのアクセスを集約するためのサービス
26
+ #
27
+ class SingleClickClient
28
+
29
+ def initialize( conf, logger )
30
+ @conf = conf
31
+ @logger = logger
32
+ @mutex = Mutex.new
33
+ end
34
+
35
+ #リクエストを送付する。
36
+ #ブロックの第1引数としてセッションが渡される。
37
+ def request( &block )
38
+ @mutex.synchronize {
39
+ begin
40
+ @session = create_session unless @session
41
+ @session.request( &block )
42
+ rescue Exception
43
+ begin
44
+ # セッション切れの場合、再作成して再実行してみる。
45
+ # それでもエラーになったらあきらめてエラーを返す。
46
+ if $!.to_s =~ /Out Of Session\./
47
+ @logger.info "restart single click client."
48
+ @session.close
49
+ @session = create_session
50
+ @session.request( &block )
51
+ else
52
+ raise $!
53
+ end
54
+ rescue Exception
55
+ # エラーの場合、次回のリクエストもセッションを再作成する
56
+ @session.close if @session
57
+ @session = nil
58
+ raise $!
59
+ end
60
+ end
61
+ }
62
+ end
63
+
64
+ #サービスを破棄する。
65
+ #不要になった場合、必ず実行すること。
66
+ def close
67
+ @session.close if @session
68
+ @logger.info "close single click client."
69
+ end
70
+ attr :conf, true
71
+ attr :logger, true
72
+
73
+ private
74
+ def create_session
75
+ return Session.new { |wait|
76
+ logger.info "start single click client."
77
+ begin
78
+ JIJI::Util.log_if_error_and_throw( @logger ) {
79
+ client = ClickClient::Client.new
80
+ client.host_name = conf[:host] ? conf[:host] : "https://fx-demo.click-sec.com"
81
+ @logger.info "connect host=#{client.host_name}, user=#{conf[:user]}"
82
+ client.fx_session(conf[:user], conf[:password]){|fx|
83
+ wait.call( fx )
84
+ }
85
+ }
86
+ rescue Exception
87
+ @logger.info "connect failed."
88
+ e = JIJI::FatalError.new( JIJI::ERROR_NOT_CONNECTED, $!.to_s )
89
+ wait.call( ErrorSession.new( e ) )
90
+ end
91
+ }
92
+ end
93
+ end
94
+
95
+ #接続エラー時に使用するセッション
96
+ #常にエラーをスローする。
97
+ class ErrorSession
98
+ def initialize(error)
99
+ @error = error
100
+ end
101
+ def method_missing(name, *args, &block)
102
+ raise @error
103
+ end
104
+ end
105
+
106
+ end
107
+ end
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'set'
3
+
4
+ module JIJI
5
+ module Plugin
6
+
7
+ @@registry = {}
8
+
9
+ #プラグインを登録する。
10
+ #future:: 機能の識別子
11
+ #instance:: 機能を提供するプラグインインスタンス
12
+ def self.register( future, instance )
13
+ if @@registry.key? future
14
+ @@registry[future] << instance
15
+ else
16
+ @@registry[future] = [instance]
17
+ end
18
+ end
19
+
20
+ #プラグインを取得する。
21
+ #future:: 機能の識別子
22
+ #return:: 機能を提供するプラグインの配列
23
+ def self.get( future )
24
+ @@registry.key?(future) ? @@registry[future] : []
25
+ end
26
+
27
+ # プラグインローダー
28
+ class Loader
29
+ def initialize
30
+ @loaded = Set.new
31
+ end
32
+ # プラグインをロードする。
33
+ def load
34
+ ($: + Gem.latest_load_paths).each {|dir|
35
+ plugin = File.expand_path "#{dir}/jiji_plugin.rb"
36
+ next unless File.exist? plugin
37
+ next if @loaded.include?( plugin )
38
+ begin
39
+ Kernel.load plugin
40
+ server_logger.info( "plugin loaded. plugin_path=#{plugin}" ) if server_logger
41
+ @loaded << plugin
42
+ rescue Exception
43
+ server_logger.error( "plugin load failed. plugin_path=#{plugin}" ) if server_logger
44
+ server_logger.error($!) if server_logger
45
+ end
46
+ }
47
+ end
48
+ attr :server_logger, true
49
+ end
50
+
51
+ end
52
+ end
53
+