pio 0.27.1 → 0.27.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/Rakefile +1 -1
  4. data/bin/{terminal-notifier → code_metrics} +2 -2
  5. data/bin/code_metrics-profile +16 -0
  6. data/features/icmpv6.pcap +0 -0
  7. data/features/open_flow10/aggregate_stats_reply.feature +1 -1
  8. data/features/open_flow10/aggregate_stats_request.feature +2 -2
  9. data/features/open_flow10/bad_request.feature +2 -2
  10. data/features/open_flow10/barrier_reply.feature +3 -18
  11. data/features/open_flow10/barrier_request.feature +3 -18
  12. data/features/open_flow10/description_stats_reply.feature +1 -1
  13. data/features/open_flow10/description_stats_request.feature +3 -3
  14. data/features/open_flow10/echo_reply.feature +4 -47
  15. data/features/open_flow10/echo_request.feature +4 -36
  16. data/features/open_flow10/exact_match.feature +20 -2
  17. data/features/open_flow10/features_reply.feature +65 -72
  18. data/features/open_flow10/features_request.feature +3 -22
  19. data/features/open_flow10/flow_mod.feature +5 -5
  20. data/features/open_flow10/flow_stats_reply.feature +2 -2
  21. data/features/open_flow10/flow_stats_request.feature +3 -4
  22. data/features/open_flow10/hello.feature +4 -20
  23. data/features/open_flow10/hello_failed.feature +4 -4
  24. data/features/open_flow10/packet_in.feature +2 -2
  25. data/features/open_flow10/packet_in_arp_reply.raw +0 -0
  26. data/features/open_flow10/packet_out.feature +1 -1
  27. data/features/open_flow10/port_status.feature +1 -1
  28. data/features/open_flow13/bad_request.feature +2 -2
  29. data/features/open_flow13/echo_reply.feature +5 -37
  30. data/features/open_flow13/echo_request.feature +5 -37
  31. data/features/open_flow13/features_reply.feature +3 -7
  32. data/features/open_flow13/features_request.feature +3 -18
  33. data/features/open_flow13/flow_mod.feature +5 -5
  34. data/features/open_flow13/hello.feature +4 -19
  35. data/features/open_flow13/hello_failed.feature +4 -4
  36. data/features/open_flow13/match.feature +4 -4
  37. data/features/open_flow13/packet_in.feature +3 -3
  38. data/features/open_flow13/packet_out.feature +3 -3
  39. data/features/parser.feature +10 -0
  40. data/lib/pio/arp/format.rb +20 -0
  41. data/lib/pio/ipv4_header.rb +20 -0
  42. data/lib/pio/open_flow.rb +0 -1
  43. data/lib/pio/open_flow/message.rb +51 -57
  44. data/lib/pio/open_flow/open_flow_header.rb +6 -10
  45. data/lib/pio/open_flow10.rb +20 -15
  46. data/lib/pio/open_flow10/aggregate_stats/reply.rb +20 -0
  47. data/lib/pio/open_flow10/aggregate_stats/request.rb +25 -0
  48. data/lib/pio/open_flow10/barrier/reply.rb +14 -0
  49. data/lib/pio/open_flow10/barrier/request.rb +14 -0
  50. data/lib/pio/open_flow10/description_stats/reply.rb +21 -0
  51. data/lib/pio/open_flow10/description_stats/request.rb +19 -0
  52. data/lib/pio/open_flow10/echo/reply.rb +16 -0
  53. data/lib/pio/open_flow10/echo/request.rb +16 -0
  54. data/lib/pio/open_flow10/error/bad_request.rb +27 -49
  55. data/lib/pio/open_flow10/error/hello_failed.rb +6 -28
  56. data/lib/pio/open_flow10/exact_match.rb +4 -39
  57. data/lib/pio/open_flow10/features/reply.rb +48 -72
  58. data/lib/pio/open_flow10/features/request.rb +4 -11
  59. data/lib/pio/open_flow10/flow_mod.rb +21 -51
  60. data/lib/pio/open_flow10/{flow_stats_reply.rb → flow_stats/reply.rb} +7 -23
  61. data/lib/pio/open_flow10/flow_stats/request.rb +25 -0
  62. data/lib/pio/open_flow10/hello.rb +3 -13
  63. data/lib/pio/open_flow10/match.rb +0 -18
  64. data/lib/pio/open_flow10/match10.rb +22 -0
  65. data/lib/pio/open_flow10/packet_in.rb +18 -42
  66. data/lib/pio/open_flow10/packet_out.rb +8 -31
  67. data/lib/pio/open_flow10/port_status.rb +11 -39
  68. data/lib/pio/open_flow10/stats_reply.rb +11 -8
  69. data/lib/pio/open_flow10/stats_request.rb +8 -8
  70. data/lib/pio/open_flow13.rb +13 -6
  71. data/lib/pio/open_flow13/echo/reply.rb +15 -0
  72. data/lib/pio/open_flow13/echo/request.rb +15 -0
  73. data/lib/pio/open_flow13/error/bad_request.rb +32 -49
  74. data/lib/pio/open_flow13/error/hello_failed.rb +7 -30
  75. data/lib/pio/open_flow13/features/reply.rb +27 -51
  76. data/lib/pio/open_flow13/features/request.rb +3 -10
  77. data/lib/pio/open_flow13/flow_mod.rb +29 -52
  78. data/lib/pio/open_flow13/hello.rb +18 -22
  79. data/lib/pio/open_flow13/packet_in.rb +26 -44
  80. data/lib/pio/open_flow13/packet_out.rb +16 -35
  81. data/lib/pio/open_flow13/stats_request.rb +5 -21
  82. data/lib/pio/parser.rb +5 -4
  83. data/lib/pio/version.rb +1 -1
  84. data/pio.gemspec +6 -6
  85. data/spec/pio/open_flow10/{echo_reply_spec.rb → echo/reply_spec.rb} +1 -1
  86. data/spec/pio/open_flow10/{echo_request_spec.rb → echo/request_spec.rb} +1 -1
  87. data/spec/pio/open_flow10/error/hello_failed_spec.rb +2 -2
  88. data/spec/pio/open_flow10/features/request_spec.rb +0 -5
  89. data/spec/pio/open_flow10/flow_mod_spec.rb +2 -4
  90. data/spec/pio/open_flow10/flow_stats_reply_spec.rb +1 -1
  91. data/spec/pio/open_flow10/flow_stats_request_spec.rb +2 -2
  92. data/spec/pio/open_flow10/packet_out_spec.rb +15 -18
  93. data/spec/pio/open_flow13/echo_reply_spec.rb +1 -1
  94. data/spec/pio/open_flow13/echo_request_spec.rb +1 -1
  95. data/spec/pio/open_flow13/error/hello_failed_spec.rb +2 -2
  96. data/spec/pio/open_flow13/features/request_spec.rb +5 -3
  97. data/spec/pio/open_flow13/hello_spec.rb +3 -3
  98. data/spec/support/shared_examples_for_openflow_messages.rb +5 -12
  99. metadata +92 -85
  100. data/lib/pio/open_flow/echo.rb +0 -44
  101. data/lib/pio/open_flow/format.rb +0 -46
  102. data/lib/pio/open_flow10/aggregate_stats_reply.rb +0 -38
  103. data/lib/pio/open_flow10/aggregate_stats_request.rb +0 -42
  104. data/lib/pio/open_flow10/barrier_reply.rb +0 -21
  105. data/lib/pio/open_flow10/barrier_request.rb +0 -22
  106. data/lib/pio/open_flow10/description_stats_reply.rb +0 -35
  107. data/lib/pio/open_flow10/description_stats_request.rb +0 -36
  108. data/lib/pio/open_flow10/echo.rb +0 -20
  109. data/lib/pio/open_flow10/flow_stats_request.rb +0 -64
  110. data/lib/pio/open_flow13/echo.rb +0 -20
  111. data/lib/pio/open_flow13/features.rb +0 -2
@@ -10,7 +10,7 @@ Feature: Pio::Features::Request
10
10
  | field | value |
11
11
  | ofp_version | 4 |
12
12
  | message_type | 5 |
13
- | length | 8 |
13
+ | message_length | 8 |
14
14
  | transaction_id | 0 |
15
15
  | xid | 0 |
16
16
  | body | |
@@ -25,22 +25,7 @@ Feature: Pio::Features::Request
25
25
  | field | value |
26
26
  | ofp_version | 4 |
27
27
  | message_type | 5 |
28
- | length | 8 |
29
- | transaction_id | 123 |
30
- | xid | 123 |
31
- | body | |
32
-
33
- Scenario: new(xid: 123)
34
- When I try to create an OpenFlow message with:
35
- """
36
- Pio::Features::Request.new(xid: 123)
37
- """
38
- Then it should finish successfully
39
- And the message has the following fields and values:
40
- | field | value |
41
- | ofp_version | 4 |
42
- | message_type | 5 |
43
- | length | 8 |
28
+ | message_length | 8 |
44
29
  | transaction_id | 123 |
45
30
  | xid | 123 |
46
31
  | body | |
@@ -59,7 +44,7 @@ Feature: Pio::Features::Request
59
44
  | field | value |
60
45
  | ofp_version | 4 |
61
46
  | message_type | 5 |
62
- | length | 8 |
47
+ | message_length | 8 |
63
48
  | transaction_id | 0 |
64
49
  | xid | 0 |
65
50
  | body | |
@@ -10,7 +10,7 @@ Feature: Pio::FlowMod
10
10
  | field | value |
11
11
  | ofp_version | 4 |
12
12
  | message_type | 14 |
13
- | length | 56 |
13
+ | message_length | 56 |
14
14
  | to_binary.length | 56 |
15
15
  | transaction_id | 0 |
16
16
  | xid | 0 |
@@ -38,7 +38,7 @@ Feature: Pio::FlowMod
38
38
  | field | value |
39
39
  | ofp_version | 4 |
40
40
  | message_type | 14 |
41
- | length | 80 |
41
+ | message_length | 80 |
42
42
  | transaction_id | 0 |
43
43
  | xid | 0 |
44
44
  | cookie | 0 |
@@ -68,7 +68,7 @@ Feature: Pio::FlowMod
68
68
  | field | value |
69
69
  | ofp_version | 4 |
70
70
  | message_type | 14 |
71
- | length | 88 |
71
+ | message_length | 88 |
72
72
  | transaction_id | 0 |
73
73
  | xid | 0 |
74
74
  | cookie | 0 |
@@ -95,7 +95,7 @@ Feature: Pio::FlowMod
95
95
  | field | value |
96
96
  | ofp_version | 4 |
97
97
  | message_type | 14 |
98
- | length | 56 |
98
+ | message_length | 56 |
99
99
  | transaction_id | 0 |
100
100
  | xid | 0 |
101
101
  | cookie | 0 |
@@ -119,7 +119,7 @@ Feature: Pio::FlowMod
119
119
  | field | value |
120
120
  | ofp_version | 4 |
121
121
  | message_type | 14 |
122
- | length | 80 |
122
+ | message_length | 80 |
123
123
  | transaction_id | 0 |
124
124
  | xid | 0 |
125
125
  | cookie | 0 |
@@ -10,7 +10,7 @@ Feature: Pio::Hello
10
10
  | field | value |
11
11
  | ofp_version | 4 |
12
12
  | message_type | 0 |
13
- | length | 16 |
13
+ | message_length | 16 |
14
14
  | transaction_id | 0 |
15
15
  | xid | 0 |
16
16
  | supported_versions | [:open_flow13] |
@@ -25,22 +25,7 @@ Feature: Pio::Hello
25
25
  | field | value |
26
26
  | ofp_version | 4 |
27
27
  | message_type | 0 |
28
- | length | 16 |
29
- | transaction_id | 123 |
30
- | xid | 123 |
31
- | supported_versions | [:open_flow13] |
32
-
33
- Scenario: new(xid: 123)
34
- When I try to create an OpenFlow message with:
35
- """
36
- Pio::Hello.new(xid: 123)
37
- """
38
- Then it should finish successfully
39
- And the message has the following fields and values:
40
- | field | value |
41
- | ofp_version | 4 |
42
- | message_type | 0 |
43
- | length | 16 |
28
+ | message_length | 16 |
44
29
  | transaction_id | 123 |
45
30
  | xid | 123 |
46
31
  | supported_versions | [:open_flow13] |
@@ -52,7 +37,7 @@ Feature: Pio::Hello
52
37
  | field | value |
53
38
  | ofp_version | 4 |
54
39
  | message_type | 0 |
55
- | length | 8 |
40
+ | message_length | 8 |
56
41
  | transaction_id | 0 |
57
42
  | xid | 0 |
58
43
  | supported_versions | [] |
@@ -64,7 +49,7 @@ Feature: Pio::Hello
64
49
  | field | value |
65
50
  | ofp_version | 4 |
66
51
  | message_type | 0 |
67
- | length | 16 |
52
+ | message_length | 16 |
68
53
  | transaction_id | 0 |
69
54
  | xid | 0 |
70
55
  | supported_versions | [:open_flow10, :open_flow13] |
@@ -13,7 +13,7 @@ Feature: Pio::Error::HelloFailed
13
13
  | field | value |
14
14
  | ofp_version | 4 |
15
15
  | message_type | 1 |
16
- | length | 12 |
16
+ | message_length | 12 |
17
17
  | transaction_id | 0 |
18
18
  | xid | 0 |
19
19
  | error_type | :hello_failed |
@@ -30,7 +30,7 @@ Feature: Pio::Error::HelloFailed
30
30
  | field | value |
31
31
  | ofp_version | 4 |
32
32
  | message_type | 1 |
33
- | length | 29 |
33
+ | message_length | 29 |
34
34
  | transaction_id | 0 |
35
35
  | xid | 0 |
36
36
  | error_type | :hello_failed |
@@ -47,7 +47,7 @@ Feature: Pio::Error::HelloFailed
47
47
  | field | value |
48
48
  | ofp_version | 4 |
49
49
  | message_type | 1 |
50
- | length | 12 |
50
+ | message_length | 12 |
51
51
  | transaction_id | 0 |
52
52
  | xid | 0 |
53
53
  | error_type | :hello_failed |
@@ -61,7 +61,7 @@ Feature: Pio::Error::HelloFailed
61
61
  | field | value |
62
62
  | ofp_version | 4 |
63
63
  | message_type | 1 |
64
- | length | 29 |
64
+ | message_length | 29 |
65
65
  | transaction_id | 0 |
66
66
  | xid | 0 |
67
67
  | error_type | :hello_failed |
@@ -784,7 +784,7 @@ Feature: Pio::Match
784
784
  When I try to parse a file named "open_flow13/oxm_experimenter_stratos_basic_dot11.raw" with "Pio::Match" class
785
785
  Then it should finish successfully
786
786
  And the message has the following fields and values:
787
- | field | value |
788
- | match_fields.at(0).oxm_field | 0 |
789
- | match_fields.at(0).experimenter | 4278247501 |
790
- | match_fields.at(0).data.inspect | "\x00\x01\x01" |
787
+ | field | value |
788
+ | match_fields.at(0).oxm_field | 0 |
789
+ | match_fields.at(0).experimenter | 4278247501 |
790
+ | match_fields.at(0).data.unpack('C*') | [0, 1, 1] |
@@ -10,7 +10,7 @@ Feature: Pio::PacketIn
10
10
  | field | value |
11
11
  | ofp_version | 4 |
12
12
  | message_type | 10 |
13
- | length | 34 |
13
+ | message_length | 34 |
14
14
  | transaction_id | 0 |
15
15
  | xid | 0 |
16
16
  | buffer_id | 0 |
@@ -39,7 +39,7 @@ Feature: Pio::PacketIn
39
39
  And the message has the following fields and values:
40
40
  | field | value |
41
41
  | ofp_version | 4 |
42
- | length | 94 |
42
+ | message_length | 94 |
43
43
  | transaction_id | 0 |
44
44
  | xid | 0 |
45
45
  | buffer_id | 0 |
@@ -59,7 +59,7 @@ Feature: Pio::PacketIn
59
59
  | field | value |
60
60
  | ofp_version | 4 |
61
61
  | message_type | 10 |
62
- | length | 102 |
62
+ | message_length | 102 |
63
63
  | transaction_id | 123 |
64
64
  | xid | 123 |
65
65
  | buffer_id.to_hex | 0xcafebabe |
@@ -10,7 +10,7 @@ Feature: Pio::PacketOut
10
10
  | field | value |
11
11
  | ofp_version | 4 |
12
12
  | message_type | 13 |
13
- | length | 24 |
13
+ | message_length | 24 |
14
14
  | to_binary.length | 24 |
15
15
  | transaction_id | 0 |
16
16
  | xid | 0 |
@@ -38,7 +38,7 @@ Feature: Pio::PacketOut
38
38
  | field | value |
39
39
  | ofp_version | 4 |
40
40
  | message_type | 13 |
41
- | length | 100 |
41
+ | message_length | 100 |
42
42
  | to_binary.length | 100 |
43
43
  | transaction_id | 0 |
44
44
  | xid | 0 |
@@ -67,7 +67,7 @@ Feature: Pio::PacketOut
67
67
  | field | value |
68
68
  | ofp_version | 4 |
69
69
  | message_type | 13 |
70
- | length | 100 |
70
+ | message_length | 100 |
71
71
  | transaction_id | 123 |
72
72
  | xid | 123 |
73
73
  | buffer_id | :no_buffer |
@@ -0,0 +1,10 @@
1
+ Feature: Pio::Parser
2
+ Scenario: parse icmpv6.pcap
3
+ When I try to parse a file named "icmpv6.pcap" with "Pio::Parser" class
4
+ Then it should finish successfully
5
+ And the message #1 have the following fields and values:
6
+ | field | value |
7
+ | class | Pio::Parser::EthernetFrame |
8
+ | destination_mac | 00:60:97:07:69:ea |
9
+ | source_mac | 00:00:86:05:80:da |
10
+ | ether_type | 34525 |
@@ -27,6 +27,26 @@ module Pio
27
27
  operation
28
28
  end
29
29
 
30
+ # rubocop:disable MethodLength
31
+ def to_exact_match(in_port)
32
+ match_options = {
33
+ in_port: in_port,
34
+ ether_source_address: source_mac,
35
+ ether_destination_address: destination_mac,
36
+ vlan_vid: vlan_vid,
37
+ vlan_priority: vlan_pcp,
38
+ ether_type: ether_type,
39
+ ip_tos: 0,
40
+ ip_protocol: operation,
41
+ ip_source_address: sender_protocol_address,
42
+ ip_destination_address: target_protocol_address,
43
+ transport_source_port: 0,
44
+ transport_destination_port: 0
45
+ }
46
+ Pio::OpenFlow10::Match.new(match_options)
47
+ end
48
+ # rubocop:enable MethodLength
49
+
30
50
  def to_binary
31
51
  to_binary_s + "\000" * (64 - num_bytes)
32
52
  end
@@ -33,6 +33,26 @@ module Pio
33
33
  end
34
34
  # rubocop:enable MethodLength
35
35
 
36
+ # rubocop:disable MethodLength
37
+ def to_exact_match(in_port)
38
+ match_options = {
39
+ in_port: in_port,
40
+ ether_source_address: source_mac,
41
+ ether_destination_address: destination_mac,
42
+ vlan_vid: vlan_vid,
43
+ vlan_priority: vlan_pcp,
44
+ ether_type: ether_type,
45
+ ip_tos: ip_type_of_service,
46
+ ip_protocol: ip_protocol,
47
+ ip_source_address: ip_source_address,
48
+ ip_destination_address: ip_destination_address,
49
+ transport_source_port: transport_source_port,
50
+ transport_destination_port: transport_destination_port
51
+ }
52
+ Pio::OpenFlow10::Match.new match_options
53
+ end
54
+ # rubocop:enable MethodLength
55
+
36
56
  private
37
57
 
38
58
  def calculate_ip_length
data/lib/pio/open_flow.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  require 'pio/open_flow/datapath_id'
2
2
  require 'pio/open_flow/error'
3
3
  require 'pio/open_flow/flags'
4
- require 'pio/open_flow/format'
5
4
  require 'pio/open_flow/message'
6
5
  require 'pio/open_flow/open_flow_header'
7
6
  require 'pio/open_flow10'
@@ -1,40 +1,66 @@
1
1
  require 'bindata'
2
2
  require 'pio/parse_error'
3
+ require 'pio/open_flow/open_flow_header'
3
4
 
4
5
  module Pio
5
6
  module OpenFlow
6
7
  # OpenFlow messages.
7
8
  class Message
8
- # rubocop:disable MethodLength
9
- def self.inherited(child)
10
- child.class_eval <<-EOS
11
- def self.read(raw_data)
12
- allocate.tap do |message|
13
- format_klass = self.const_get(:Format)
14
- message.instance_variable_set(:@format,
15
- format_klass.read(raw_data))
16
- end
17
- rescue BinData::ValidityError
18
- message_name = name.split('::')[1..-1].join(' ')
19
- raise Pio::ParseError, "Invalid \#{message_name} message."
20
- end
21
- EOS
9
+ def self.inherited(child_klass)
10
+ child_klass.const_set :Format, Class.new(BinData::Record)
11
+ child_klass.class_variable_set(:@@valid_options, [])
22
12
  end
23
- # rubocop:enable MethodLength
24
13
 
25
- def self.body_option(name)
26
- unless class_variable_defined?(:@@valid_body_options)
27
- class_variable_set(:@@valid_body_options, [])
14
+ def self.read(raw_data)
15
+ allocate.tap do |message|
16
+ message.instance_variable_set(:@format,
17
+ const_get(:Format).read(raw_data))
28
18
  end
29
- class_variable_set(:@@valid_body_options,
30
- class_variable_get(:@@valid_body_options) + [name])
19
+ rescue BinData::ValidityError
20
+ message_name = name.split('::')[1..-1].join(' ')
21
+ raise Pio::ParseError, "Invalid #{message_name} message."
31
22
  end
32
23
 
24
+ def self.method_missing(method, *args, &block)
25
+ const_get(:Format).__send__ method, *args, &block
26
+
27
+ return if method == :endian || method == :virtual
28
+ define_method(args.first) do
29
+ @format.__send__ args.first
30
+ end
31
+ class_variable_set(:@@valid_options,
32
+ class_variable_get(:@@valid_options) + [args.first])
33
+ end
34
+
35
+ # rubocop:disable AbcSize
36
+ # rubocop:disable MethodLength
37
+ def self.open_flow_header(opts)
38
+ module_eval do
39
+ endian :big
40
+
41
+ uint8 :ofp_version, value: opts.fetch(:version)
42
+ virtual assert: -> { ofp_version == opts.fetch(:version) }
43
+ uint8 :message_type, value: opts.fetch(:message_type)
44
+ virtual assert: -> { message_type == opts.fetch(:message_type) }
45
+ uint16 :message_length,
46
+ initial_value: opts[:message_length] || -> { 8 + body.length }
47
+ transaction_id :transaction_id, initial_value: 0
48
+
49
+ alias_method :xid, :transaction_id
50
+ end
51
+ end
52
+ # rubocop:enable AbcSize
53
+ # rubocop:enable MethodLength
54
+
33
55
  def initialize(user_options = {})
34
56
  validate_user_options user_options
35
57
  @format = self.class.const_get(:Format).new(parse_options(user_options))
36
58
  end
37
59
 
60
+ def to_binary
61
+ @format.to_binary_s
62
+ end
63
+
38
64
  def method_missing(method, *args, &block)
39
65
  @format.__send__ method, *args, &block
40
66
  end
@@ -43,48 +69,16 @@ module Pio
43
69
 
44
70
  def validate_user_options(user_options)
45
71
  unknown_options =
46
- user_options.keys - valid_header_options - valid_body_options
72
+ user_options.keys - self.class.class_variable_get(:@@valid_options)
47
73
  return if unknown_options.empty?
48
74
  fail "Unknown option: #{unknown_options.first}"
49
75
  end
50
76
 
51
77
  def parse_options(user_options)
52
- if valid_body_options.empty?
53
- { header: parse_header_options(user_options) }
54
- else
55
- { header: parse_header_options(user_options),
56
- body: parse_body_options(user_options) }
57
- end
58
- end
59
-
60
- def parse_header_options(user_options)
61
- transaction_id =
62
- user_options[:transaction_id] || user_options[:xid] || 0
63
- { transaction_id: transaction_id }
64
- end
65
-
66
- def parse_body_options(user_options)
67
- if valid_body_options.include?(:body)
68
- return user_options[:body] || user_options[:user_data] || ''
69
- end
70
- options = user_options.dup
71
- options.delete :transaction_id
72
- options.delete :xid
73
- dpid = options[:dpid]
74
- options[:datapath_id] = dpid if dpid
75
- options.empty? ? {} : options
76
- end
77
-
78
- def valid_header_options
79
- [:transaction_id, :xid]
80
- end
81
-
82
- def valid_body_options
83
- if self.class.class_variable_defined?(:@@valid_body_options)
84
- self.class.class_variable_get(:@@valid_body_options)
85
- else
86
- []
87
- end
78
+ parsed_options = user_options.dup
79
+ parsed_options[:transaction_id] = user_options[:transaction_id] || 0
80
+ parsed_options[:body] = user_options[:body] || ''
81
+ parsed_options
88
82
  end
89
83
  end
90
84
  end