pio 0.8.1 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -1
  3. data/README.md +24 -11
  4. data/Rakefile +0 -2
  5. data/examples/features_new.rb +17 -6
  6. data/features/packet_data/aggregate_stats_reply.raw +0 -0
  7. data/features/packet_data/aggregate_stats_request.raw +0 -0
  8. data/features/packet_data/barrier_reply.raw +0 -0
  9. data/features/packet_data/barrier_request.raw +0 -0
  10. data/features/packet_data/desc_stats_reply.raw +0 -0
  11. data/features/packet_data/desc_stats_request.raw +0 -0
  12. data/features/packet_data/echo_reply.raw +0 -0
  13. data/features/packet_data/echo_request.raw +0 -0
  14. data/features/packet_data/error.raw +0 -0
  15. data/features/packet_data/features_reply.raw +0 -0
  16. data/features/packet_data/flow_mod_add.raw +0 -0
  17. data/features/packet_data/flow_mod_delete.raw +0 -0
  18. data/features/packet_data/flow_removed.raw +0 -0
  19. data/features/packet_data/flow_stats_reply.raw +0 -0
  20. data/features/packet_data/flow_stats_request.raw +0 -0
  21. data/features/packet_data/get_config_reply.raw +0 -0
  22. data/features/packet_data/get_config_request.raw +0 -0
  23. data/features/packet_data/hello.raw +0 -0
  24. data/features/packet_data/packet_in.raw +0 -0
  25. data/features/packet_data/packet_out.raw +0 -0
  26. data/features/packet_data/port_mod.raw +0 -0
  27. data/features/packet_data/port_stats_reply.raw +0 -0
  28. data/features/packet_data/port_stats_request.raw +0 -0
  29. data/features/packet_data/port_status.raw +0 -0
  30. data/features/packet_data/queue_get_config_reply.raw +0 -0
  31. data/features/packet_data/queue_get_config_request.raw +0 -0
  32. data/features/packet_data/set_config.raw +0 -0
  33. data/features/packet_data/table_stats_reply.raw +0 -0
  34. data/features/packet_data/table_stats_request.raw +0 -0
  35. data/features/packet_data/vendor.raw +0 -0
  36. data/features/packet_data/vendor_stats_request.raw +0 -0
  37. data/features/step_definitions/packet_data_steps.rb +0 -2
  38. data/features/step_definitions/pending_steps.rb +0 -2
  39. data/features/support/env.rb +0 -2
  40. data/lib/pio.rb +0 -2
  41. data/lib/pio/arp.rb +0 -2
  42. data/lib/pio/arp/format.rb +0 -2
  43. data/lib/pio/arp/message.rb +14 -22
  44. data/lib/pio/arp/reply.rb +0 -2
  45. data/lib/pio/arp/request.rb +0 -2
  46. data/lib/pio/dhcp.rb +0 -2
  47. data/lib/pio/dhcp/ack.rb +0 -2
  48. data/lib/pio/dhcp/boot_reply.rb +0 -2
  49. data/lib/pio/dhcp/boot_reply_options.rb +0 -2
  50. data/lib/pio/dhcp/boot_request.rb +0 -2
  51. data/lib/pio/dhcp/boot_request_options.rb +0 -2
  52. data/lib/pio/dhcp/client_id.rb +0 -2
  53. data/lib/pio/dhcp/common_options.rb +0 -2
  54. data/lib/pio/dhcp/csum_util.rb +0 -2
  55. data/lib/pio/dhcp/dhcp_field.rb +0 -2
  56. data/lib/pio/dhcp/dhcp_tlv_options.rb +0 -2
  57. data/lib/pio/dhcp/discover.rb +0 -2
  58. data/lib/pio/dhcp/field_util.rb +0 -2
  59. data/lib/pio/dhcp/frame.rb +0 -2
  60. data/lib/pio/dhcp/message.rb +0 -2
  61. data/lib/pio/dhcp/offer.rb +0 -2
  62. data/lib/pio/dhcp/optional_tlv.rb +0 -2
  63. data/lib/pio/dhcp/parameter_list.rb +0 -2
  64. data/lib/pio/dhcp/request.rb +0 -2
  65. data/lib/pio/echo.rb +3 -6
  66. data/lib/pio/echo/format.rb +10 -6
  67. data/lib/pio/echo/message.rb +16 -41
  68. data/lib/pio/echo/reply.rb +8 -7
  69. data/lib/pio/echo/request.rb +6 -6
  70. data/lib/pio/features.rb +15 -9
  71. data/lib/pio/features/reply.rb +79 -44
  72. data/lib/pio/features/request.rb +30 -28
  73. data/lib/pio/hello.rb +17 -29
  74. data/lib/pio/hello/format.rb +8 -8
  75. data/lib/pio/icmp.rb +0 -2
  76. data/lib/pio/icmp/format.rb +0 -2
  77. data/lib/pio/icmp/message.rb +23 -31
  78. data/lib/pio/icmp/options.rb +0 -2
  79. data/lib/pio/icmp/reply.rb +2 -4
  80. data/lib/pio/icmp/request.rb +0 -2
  81. data/lib/pio/ipv4_address.rb +1 -5
  82. data/lib/pio/lldp.rb +0 -2
  83. data/lib/pio/lldp/chassis_id_tlv.rb +0 -2
  84. data/lib/pio/lldp/end_of_lldpdu_value.rb +0 -2
  85. data/lib/pio/lldp/frame.rb +0 -2
  86. data/lib/pio/lldp/management_address_value.rb +0 -2
  87. data/lib/pio/lldp/optional_tlv.rb +0 -2
  88. data/lib/pio/lldp/options.rb +0 -2
  89. data/lib/pio/lldp/organizationally_specific_value.rb +0 -2
  90. data/lib/pio/lldp/port_description_value.rb +0 -2
  91. data/lib/pio/lldp/port_id_tlv.rb +0 -2
  92. data/lib/pio/lldp/system_capabilities_value.rb +0 -2
  93. data/lib/pio/lldp/system_description_value.rb +0 -2
  94. data/lib/pio/lldp/system_name_value.rb +0 -2
  95. data/lib/pio/lldp/ttl_tlv.rb +0 -2
  96. data/lib/pio/mac.rb +2 -6
  97. data/lib/pio/message_type_selector.rb +5 -4
  98. data/lib/pio/open_flow.rb +5 -0
  99. data/lib/pio/open_flow/flags.rb +38 -0
  100. data/lib/pio/open_flow/message.rb +20 -0
  101. data/lib/pio/open_flow/open_flow_header.rb +18 -0
  102. data/lib/pio/open_flow/phy_port.rb +74 -0
  103. data/lib/pio/open_flow/type.rb +12 -0
  104. data/lib/pio/options.rb +0 -2
  105. data/lib/pio/parse_error.rb +0 -2
  106. data/lib/pio/pcap.rb +0 -2
  107. data/lib/pio/type/ethernet_header.rb +0 -2
  108. data/lib/pio/type/ip_address.rb +0 -2
  109. data/lib/pio/type/ipv4_header.rb +2 -2
  110. data/lib/pio/type/mac_address.rb +6 -3
  111. data/lib/pio/type/udp_header.rb +0 -2
  112. data/lib/pio/version.rb +1 -3
  113. data/pio.gemspec +18 -20
  114. data/spec/pio/arp/reply/options_spec.rb +0 -2
  115. data/spec/pio/arp/reply_spec.rb +0 -2
  116. data/spec/pio/arp/request/options_spec.rb +0 -2
  117. data/spec/pio/arp/request_spec.rb +0 -2
  118. data/spec/pio/arp_spec.rb +0 -2
  119. data/spec/pio/dhcp/ack_spec.rb +0 -2
  120. data/spec/pio/dhcp/discover_spec.rb +0 -2
  121. data/spec/pio/dhcp/offer_spec.rb +0 -2
  122. data/spec/pio/dhcp/request_spec.rb +0 -2
  123. data/spec/pio/dhcp_spec.rb +0 -2
  124. data/spec/pio/echo/reply_spec.rb +13 -15
  125. data/spec/pio/echo/request_spec.rb +15 -15
  126. data/spec/pio/echo_spec.rb +5 -7
  127. data/spec/pio/features/reply_spec.rb +47 -17
  128. data/spec/pio/features/request_spec.rb +6 -11
  129. data/spec/pio/features_spec.rb +70 -51
  130. data/spec/pio/hello_spec.rb +1 -3
  131. data/spec/pio/icmp/reply_spec.rb +0 -2
  132. data/spec/pio/icmp/request_spec.rb +0 -2
  133. data/spec/pio/icmp_spec.rb +0 -2
  134. data/spec/pio/ipv4_address_spec.rb +0 -2
  135. data/spec/pio/lldp/options_spec.rb +0 -2
  136. data/spec/pio/lldp_spec.rb +0 -2
  137. data/spec/pio/mac_spec.rb +0 -1
  138. data/spec/pio/open_flow/phy_port_spec.rb +25 -0
  139. data/spec/pio/open_flow/type_spec.rb +5 -0
  140. data/spec/spec_helper.rb +9 -24
  141. metadata +105 -40
  142. data/lib/pio/features/format.rb +0 -18
  143. data/lib/pio/features/message.rb +0 -14
  144. data/lib/pio/type/open_flow.rb +0 -34
@@ -1,48 +1,23 @@
1
- # encoding: utf-8
2
-
3
- require 'forwardable'
4
- require 'bindata'
5
-
6
1
  module Pio
7
2
  class Echo
8
3
  # Base class of Echo request and reply.
9
- class Message
10
- extend Forwardable
11
-
12
- def_delegators :@echo, :ofp_version
13
- def_delegators :@echo, :message_type
14
- def_delegators :@echo, :message_length
15
- def_delegators :@echo, :transaction_id
16
- def_delegator :@echo, :transaction_id, :xid
17
- def_delegator :@echo, :body, :data
18
- def_delegator :@echo, :to_binary_s, :to_binary
19
-
20
- def self.create_from(echo)
21
- message = allocate
22
- message.instance_variable_set :@echo, echo
23
- message
24
- end
25
-
26
- def initialize(message_type, user_options = {})
27
- if user_options.respond_to?(:to_i)
28
- @options = { transaction_id: user_options.to_i,
29
- message_type: message_type }
30
- elsif user_options.respond_to?(:[])
31
- @options = user_options.dup.merge(message_type: message_type)
32
- handle_user_hash_options
33
- else
34
- fail TypeError
35
- end
36
- @echo = Format.new(@options)
37
- end
38
-
39
- private
40
-
41
- def handle_user_hash_options
42
- @options[:body] = @options[:data]
43
- @options[:transaction_id] ||= @options[:xid]
44
- @options[:transaction_id] = 0 unless @options[:transaction_id]
4
+ class Message < Pio::OpenFlow::Message
5
+ # @reek This method smells of :reek:FeatureEnvy
6
+ # rubocop:disable Metrics/MethodLength
7
+ def initialize(user_options = {})
8
+ options = if user_options.respond_to?(:to_i)
9
+ { open_flow_header: { transaction_id: user_options.to_i } }
10
+ elsif user_options.respond_to?(:fetch)
11
+ transaction_id =
12
+ user_options[:transaction_id] || user_options[:xid] || 0
13
+ { open_flow_header: { transaction_id: transaction_id },
14
+ body: user_options[:user_data] }
15
+ else
16
+ fail TypeError
17
+ end
18
+ @format = self.class.const_get(:Format).new(options)
45
19
  end
20
+ # rubocop:enable Metrics/MethodLength
46
21
  end
47
22
  end
48
23
  end
@@ -1,13 +1,17 @@
1
- # encoding: utf-8
2
-
1
+ require 'forwardable'
3
2
  require 'pio/echo/format'
4
3
  require 'pio/echo/message'
4
+ require 'pio/open_flow'
5
5
 
6
6
  module Pio
7
- # OpenFlow Echo Request and Reply message parser.
8
7
  class Echo
9
- # OpenFlow 1.0 Echo Reply message.
8
+ # OpenFlow 1.0 Echo Reply message generator.
10
9
  class Reply < Message
10
+ # OpenFlow 1.0 Echo reply message generator.
11
+ class Format < Pio::Echo::Format
12
+ default_parameters message_type_value: Pio::OpenFlow::Type::ECHO_REPLY
13
+ end
14
+
11
15
  # Creates an EchoReply OpenFlow message. This message can be
12
16
  # used to measure the bandwidth of a controller/switch
13
17
  # connection as well as to verify its liveness.
@@ -37,9 +41,6 @@ module Pio
37
41
  # timestamp to check latency, various lengths to measure
38
42
  # bandwidth or zero-size(nil) to verify liveness between the
39
43
  # switch and controller.
40
- def initialize(user_options = {})
41
- super REPLY, user_options
42
- end
43
44
  end
44
45
  end
45
46
  end
@@ -1,13 +1,16 @@
1
- # encoding: utf-8
2
-
3
1
  require 'pio/echo/format'
4
2
  require 'pio/echo/message'
3
+ require 'pio/open_flow'
5
4
 
6
5
  module Pio
7
- # OpenFlow Echo Request and Reply message parser.
8
6
  class Echo
9
7
  # OpenFlow 1.0 Echo Request message.
10
8
  class Request < Message
9
+ # OpenFlow 1.0 Echo request message generator.
10
+ class Format < Pio::Echo::Format
11
+ default_parameters message_type_value: Pio::OpenFlow::Type::ECHO_REQUEST
12
+ end
13
+
11
14
  # Creates an EchoRequest OpenFlow message. This message can be
12
15
  # used to measure the bandwidth of a controller/switch
13
16
  # connection as well as to verify its liveness.
@@ -37,9 +40,6 @@ module Pio
37
40
  # timestamp to check latency, various lengths to measure
38
41
  # bandwidth or zero-size(nil) to verify liveness between the
39
42
  # switch and controller.
40
- def initialize(user_options = {})
41
- super REQUEST, user_options
42
- end
43
43
  end
44
44
  end
45
45
  end
@@ -1,18 +1,24 @@
1
- # encoding: utf-8
2
-
3
- require 'pio/features/format'
4
1
  require 'pio/features/reply'
5
2
  require 'pio/features/request'
6
- require 'pio/message_type_selector'
3
+ require 'pio/open_flow'
4
+ require 'pio/parse_error'
7
5
 
8
6
  module Pio
9
7
  # OpenFlow 1.0 Features messages
10
8
  class Features
11
- extend MessageTypeSelector
12
-
13
- REQUEST = 5
14
- REPLY = 6
9
+ include Pio::OpenFlow::Type
15
10
 
16
- message_type REQUEST => Request, REPLY => Reply
11
+ # @reek This method smells of :reek:TooManyStatements
12
+ def self.read(raw_data)
13
+ header = Pio::Type::OpenFlow::OpenFlowHeader.read(raw_data)
14
+ klass = { FEATURES_REQUEST => Request,
15
+ FEATURES_REPLY => Reply }.fetch(header.message_type)
16
+ format = klass.const_get(:Format).read(raw_data)
17
+ message = klass.allocate
18
+ message.instance_variable_set :@format, format
19
+ message
20
+ rescue KeyError
21
+ raise Pio::ParseError, 'Invalid features request/reply message.'
22
+ end
17
23
  end
18
24
  end
@@ -1,15 +1,50 @@
1
- # encoding: utf-8
2
-
3
1
  require 'bindata'
4
- require 'forwardable'
5
- require 'pio/features/message'
2
+ require 'pio/open_flow'
6
3
 
7
4
  module Pio
8
5
  # OpenFlow 1.0 Features messages
9
6
  class Features
10
7
  # OpenFlow 1.0 Features Reply message
11
- class Reply < Message
12
- # Message body of Features Reply
8
+ class Reply < Pio::OpenFlow::Message
9
+ # enum ofp_capabilities
10
+ class Capabilities < BinData::Primitive
11
+ extend Flags
12
+
13
+ endian :big
14
+
15
+ flags :capabilities,
16
+ flow_stats: 1 << 0,
17
+ table_stats: 1 << 1,
18
+ port_stats: 1 << 2,
19
+ stp: 1 << 3,
20
+ reserved: 1 << 4,
21
+ ip_reasm: 1 << 5,
22
+ queue_stats: 1 << 6,
23
+ arp_match_ip: 1 << 7
24
+ end
25
+
26
+ # enum ofp_action_type
27
+ class Actions < BinData::Primitive
28
+ extend Flags
29
+
30
+ endian :big
31
+
32
+ flags :actions,
33
+ output: 1 << 0,
34
+ set_vlan_vid: 1 << 1,
35
+ set_vlan_pcp: 1 << 2,
36
+ strip_vlan: 1 << 3,
37
+ set_dl_src: 1 << 4,
38
+ set_dl_dst: 1 << 5,
39
+ set_nw_src: 1 << 6,
40
+ set_nw_dst: 1 << 7,
41
+ set_nw_tos: 1 << 8,
42
+ set_tp_src: 1 << 9,
43
+ set_tp_dst: 1 << 10,
44
+ enqueue: 1 << 11
45
+ end
46
+
47
+ # Message body of features reply.
13
48
  class Body < BinData::Record
14
49
  endian :big
15
50
 
@@ -17,56 +52,56 @@ module Pio
17
52
  uint32 :n_buffers
18
53
  uint8 :n_tables
19
54
  uint24 :padding
20
- uint32 :capabilities
21
- uint32 :actions
55
+ hide :padding
56
+ capabilities :capabilities
57
+ actions :actions
22
58
  array :ports, type: :phy_port, read_until: :eof
23
- end
24
-
25
- extend Forwardable
26
59
 
27
- def_delegators :@features, :ofp_version
28
- def_delegators :@features, :message_type
29
- def_delegators :@features, :message_length
30
- def_delegators :@features, :transaction_id
31
- def_delegator :@features, :transaction_id, :xid
32
- def_delegators :@features, :body
60
+ def empty?
61
+ false
62
+ end
33
63
 
34
- def initialize(user_options = {})
35
- @options = user_options.dup.merge(datapath_id: user_options[:dpid])
36
- body = Body.new(@options)
37
- @features = Format.new(@options.merge(message_type: 6,
38
- body: body.to_binary_s))
64
+ def length
65
+ 24 + ports.to_binary_s.length
66
+ end
39
67
  end
40
68
 
41
- def datapath_id
42
- @body ||= Body.read(@features.body)
43
- @body.datapath_id
44
- end
45
- alias_method :dpid, :datapath_id
69
+ # OpenFlow 1.0 Features request message.
70
+ class Format < BinData::Record
71
+ include Pio::OpenFlow::Type
46
72
 
47
- def n_buffers
48
- @body ||= Body.read(@features.body)
49
- @body.n_buffers
50
- end
73
+ endian :big
51
74
 
52
- def n_tables
53
- @body ||= Body.read(@features.body)
54
- @body.n_tables
55
- end
75
+ open_flow_header :open_flow_header, message_type_value: FEATURES_REPLY
76
+ virtual assert: -> { open_flow_header.message_type == FEATURES_REPLY }
56
77
 
57
- def capabilities
58
- @body ||= Body.read(@features.body)
59
- @body.capabilities
78
+ body :body
60
79
  end
61
80
 
62
- def actions
63
- @body ||= Body.read(@features.body)
64
- @body.actions
81
+ def datapath_id
82
+ @format.body.datapath_id
65
83
  end
66
84
 
67
- def ports
68
- @body ||= Body.read(@features.body)
69
- @body.ports
85
+ def_delegators :body, :datapath_id
86
+ def_delegator :body, :datapath_id, :dpid
87
+ def_delegators :body, :n_buffers
88
+ def_delegators :body, :n_tables
89
+ def_delegators :body, :capabilities
90
+ def_delegators :body, :actions
91
+ def_delegators :body, :ports
92
+
93
+ # @reek This method smells of :reek:FeatureEnvy
94
+ def initialize(user_options)
95
+ body_options =
96
+ {
97
+ datapath_id: user_options[:dpid],
98
+ n_buffers: user_options[:n_buffers],
99
+ n_tables: user_options[:n_tables],
100
+ capabilities: user_options[:capabilities],
101
+ actions: user_options[:actions],
102
+ ports: user_options[:ports]
103
+ }
104
+ @format = Format.new(user_options.merge(body: body_options))
70
105
  end
71
106
  end
72
107
  end
@@ -1,22 +1,24 @@
1
- # encoding: utf-8
2
-
3
1
  require 'forwardable'
4
- require 'pio/features/message'
2
+ require 'pio/open_flow'
5
3
 
6
4
  module Pio
7
5
  # OpenFlow 1.0 Features messages
8
6
  class Features
9
7
  # OpenFlow 1.0 Features Request message
10
- class Request < Message
11
- extend Forwardable
8
+ class Request < Pio::OpenFlow::Message
9
+ # OpenFlow 1.0 Features Request format
10
+ class Format < BinData::Record
11
+ include Pio::OpenFlow::Type
12
+
13
+ endian :big
14
+
15
+ open_flow_header :open_flow_header, message_type_value: FEATURES_REQUEST
16
+ virtual assert: -> { open_flow_header.message_type == FEATURES_REQUEST }
12
17
 
13
- def_delegators :@features, :ofp_version
14
- def_delegators :@features, :message_type
15
- def_delegators :@features, :message_length
16
- def_delegators :@features, :transaction_id
17
- def_delegator :@features, :transaction_id, :xid
18
- def_delegators :@features, :body
19
- def_delegator :@features, :to_binary_s, :to_binary
18
+ def body
19
+ ''
20
+ end
21
+ end
20
22
 
21
23
  # Creates a Features Request OpenFlow message.
22
24
  #
@@ -39,25 +41,25 @@ module Pio
39
41
  # The options to create a message with.
40
42
  # @option user_options [Number] :transaction_id
41
43
  # @option user_options [Number] :xid An alias to transaction_id.
44
+ #
45
+ # @reek This method smells of :reek:FeatureEnvy
46
+ # rubocop:disable MethodLength
42
47
  def initialize(user_options = {})
43
- if user_options.respond_to?(:to_i)
44
- @options = { transaction_id: user_options.to_i,
45
- message_type: 5 }
46
- elsif user_options.respond_to?(:[])
47
- @options = user_options.dup.merge(message_type: 5)
48
- handle_user_hash_options
49
- else
50
- fail TypeError
48
+ options = if user_options.respond_to?(:to_i)
49
+ { open_flow_header: { transaction_id: user_options.to_i } }
50
+ elsif user_options.respond_to?(:fetch)
51
+ transaction_id =
52
+ user_options[:transaction_id] || user_options[:xid] || 0
53
+ { open_flow_header: { transaction_id: transaction_id } }
54
+ else
55
+ fail TypeError
56
+ end
57
+ if options[:open_flow_header][:transaction_id] >= 2**32
58
+ fail ArgumentError, 'Transaction ID >= 2**32'
51
59
  end
52
- @features = Format.new(@options)
53
- end
54
-
55
- private
56
-
57
- def handle_user_hash_options
58
- @options[:transaction_id] ||= @options[:xid]
59
- @options[:transaction_id] = 0 unless @options[:transaction_id]
60
+ @format = Format.new(options)
60
61
  end
62
+ # rubocop:enable MethodLength
61
63
  end
62
64
  end
63
65
  end
@@ -1,22 +1,11 @@
1
- # encoding: utf-8
2
-
3
1
  require 'English'
4
- require 'forwardable'
5
2
  require 'pio/hello/format'
3
+ require 'pio/parse_error'
4
+ require 'pio/open_flow'
6
5
 
7
6
  module Pio
8
7
  # OpenFlow 1.0 Hello message
9
- class Hello
10
- extend Forwardable
11
-
12
- def_delegators :@data, :ofp_version
13
- def_delegators :@data, :message_type
14
- def_delegators :@data, :message_length
15
- def_delegators :@data, :transaction_id
16
- def_delegator :@data, :transaction_id, :xid
17
- def_delegators :@data, :body
18
- def_delegator :@data, :to_binary_s, :to_binary
19
-
8
+ class Hello < Pio::OpenFlow::Message
20
9
  # Parses +raw_data+ binary string into a Hello message object.
21
10
  #
22
11
  # @example
@@ -24,12 +13,10 @@ module Pio
24
13
  # @return [Pio::Hello]
25
14
  def self.read(raw_data)
26
15
  hello = allocate
27
- begin
28
- hello.instance_variable_set :@data, Format.read(raw_data)
29
- rescue BinData::ValidityError
30
- raise ParseError, $ERROR_INFO.message
31
- end
16
+ hello.instance_variable_set :@format, Format.read(raw_data)
32
17
  hello
18
+ rescue BinData::ValidityError
19
+ raise Pio::ParseError, $ERROR_INFO.message
33
20
  end
34
21
 
35
22
  # Creates a Hello OpenFlow message.
@@ -52,17 +39,18 @@ module Pio
52
39
  # @param [Hash] user_options The options to create a message with.
53
40
  # @option user_options [Number] :transaction_id
54
41
  # @option user_options [Number] :xid An alias to transaction_id.
42
+ #
43
+ # @reek This method smells of :reek:FeatureEnvy
55
44
  def initialize(user_options = {})
56
- if user_options.respond_to?(:to_i)
57
- @options = { transaction_id: user_options.to_i }
58
- elsif user_options.respond_to?(:[])
59
- @options = user_options.dup
60
- @options[:transaction_id] ||= @options[:xid]
61
- @options[:transaction_id] = 0 unless @options[:transaction_id]
62
- else
63
- fail TypeError
64
- end
65
- @data = Format.new(@options)
45
+ options = if user_options.respond_to?(:to_i)
46
+ { transaction_id: user_options.to_i }
47
+ elsif user_options.respond_to?(:fetch)
48
+ { transaction_id: user_options[:transaction_id] ||
49
+ user_options[:xid] || 0 }
50
+ else
51
+ fail TypeError
52
+ end
53
+ @format = Format.new(open_flow_header: options)
66
54
  end
67
55
  end
68
56
  end