hrr_rb_netconf 0.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 (66) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +28 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +32 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE +201 -0
  8. data/README.md +220 -0
  9. data/Rakefile +6 -0
  10. data/demo/server.rb +54 -0
  11. data/demo/server_over_ssh.rb +97 -0
  12. data/demo/server_with_session-oriented-database.rb +134 -0
  13. data/demo/server_with_sessionless-database.rb +81 -0
  14. data/hrr_rb_netconf.gemspec +28 -0
  15. data/lib/hrr_rb_netconf.rb +10 -0
  16. data/lib/hrr_rb_netconf/logger.rb +56 -0
  17. data/lib/hrr_rb_netconf/server.rb +109 -0
  18. data/lib/hrr_rb_netconf/server/capabilities.rb +75 -0
  19. data/lib/hrr_rb_netconf/server/capability.rb +206 -0
  20. data/lib/hrr_rb_netconf/server/capability/base_1_0.rb +183 -0
  21. data/lib/hrr_rb_netconf/server/capability/base_1_1.rb +247 -0
  22. data/lib/hrr_rb_netconf/server/capability/candidate_1_0.rb +34 -0
  23. data/lib/hrr_rb_netconf/server/capability/confirmed_commit_1_0.rb +24 -0
  24. data/lib/hrr_rb_netconf/server/capability/confirmed_commit_1_1.rb +24 -0
  25. data/lib/hrr_rb_netconf/server/capability/rollback_on_error_1_0.rb +16 -0
  26. data/lib/hrr_rb_netconf/server/capability/startup_1_0.rb +22 -0
  27. data/lib/hrr_rb_netconf/server/capability/url_1_0.rb +23 -0
  28. data/lib/hrr_rb_netconf/server/capability/validate_1_0.rb +25 -0
  29. data/lib/hrr_rb_netconf/server/capability/validate_1_1.rb +25 -0
  30. data/lib/hrr_rb_netconf/server/capability/writable_running_1_0.rb +17 -0
  31. data/lib/hrr_rb_netconf/server/capability/xpath_1_0.rb +14 -0
  32. data/lib/hrr_rb_netconf/server/datastore.rb +30 -0
  33. data/lib/hrr_rb_netconf/server/datastore/oper_handler.rb +29 -0
  34. data/lib/hrr_rb_netconf/server/datastore/session.rb +52 -0
  35. data/lib/hrr_rb_netconf/server/error.rb +52 -0
  36. data/lib/hrr_rb_netconf/server/error/access_denied.rb +19 -0
  37. data/lib/hrr_rb_netconf/server/error/bad_attribute.rb +20 -0
  38. data/lib/hrr_rb_netconf/server/error/bad_element.rb +20 -0
  39. data/lib/hrr_rb_netconf/server/error/data_exists.rb +19 -0
  40. data/lib/hrr_rb_netconf/server/error/data_missing.rb +19 -0
  41. data/lib/hrr_rb_netconf/server/error/in_use.rb +19 -0
  42. data/lib/hrr_rb_netconf/server/error/invalid_value.rb +19 -0
  43. data/lib/hrr_rb_netconf/server/error/lock_denied.rb +19 -0
  44. data/lib/hrr_rb_netconf/server/error/malformed_message.rb +19 -0
  45. data/lib/hrr_rb_netconf/server/error/missing_attribute.rb +19 -0
  46. data/lib/hrr_rb_netconf/server/error/missing_element.rb +19 -0
  47. data/lib/hrr_rb_netconf/server/error/operation_failed.rb +19 -0
  48. data/lib/hrr_rb_netconf/server/error/operation_not_supported.rb +19 -0
  49. data/lib/hrr_rb_netconf/server/error/partial_operation.rb +19 -0
  50. data/lib/hrr_rb_netconf/server/error/resource_denied.rb +19 -0
  51. data/lib/hrr_rb_netconf/server/error/rollback_failed.rb +19 -0
  52. data/lib/hrr_rb_netconf/server/error/rpc_errorable.rb +138 -0
  53. data/lib/hrr_rb_netconf/server/error/too_big.rb +19 -0
  54. data/lib/hrr_rb_netconf/server/error/unknown_attribute.rb +19 -0
  55. data/lib/hrr_rb_netconf/server/error/unknown_element.rb +19 -0
  56. data/lib/hrr_rb_netconf/server/error/unknown_namespace.rb +19 -0
  57. data/lib/hrr_rb_netconf/server/errors.rb +28 -0
  58. data/lib/hrr_rb_netconf/server/filter.rb +48 -0
  59. data/lib/hrr_rb_netconf/server/filter/subtree.rb +135 -0
  60. data/lib/hrr_rb_netconf/server/filter/xpath.rb +59 -0
  61. data/lib/hrr_rb_netconf/server/model.rb +123 -0
  62. data/lib/hrr_rb_netconf/server/model/node.rb +19 -0
  63. data/lib/hrr_rb_netconf/server/operation.rb +92 -0
  64. data/lib/hrr_rb_netconf/server/session.rb +177 -0
  65. data/lib/hrr_rb_netconf/version.rb +6 -0
  66. metadata +149 -0
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_netconf/server/error/rpc_errorable'
5
+
6
+ module HrrRbNetconf
7
+ class Server
8
+ class Error
9
+ class OperationNotSupported < Error
10
+ include RpcErrorable
11
+
12
+ TAG = 'operation-not-supported'
13
+ TYPE = ['protocol', 'application']
14
+ SEVERITY = ['error']
15
+ INFO = []
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_netconf/server/error/rpc_errorable'
5
+
6
+ module HrrRbNetconf
7
+ class Server
8
+ class Error
9
+ class PartialOperation < Error
10
+ include RpcErrorable
11
+
12
+ TAG = 'partial-operation'
13
+ TYPE = ['application']
14
+ SEVERITY = ['error']
15
+ INFO = ['ok-element', 'err-element', 'noop-element']
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_netconf/server/error/rpc_errorable'
5
+
6
+ module HrrRbNetconf
7
+ class Server
8
+ class Error
9
+ class ResourceDenied < Error
10
+ include RpcErrorable
11
+
12
+ TAG = 'resource-denied'
13
+ TYPE = ['transport', 'rpc', 'protocol', 'application']
14
+ SEVERITY = ['error']
15
+ INFO = []
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_netconf/server/error/rpc_errorable'
5
+
6
+ module HrrRbNetconf
7
+ class Server
8
+ class Error
9
+ class RollbackFailed < Error
10
+ include RpcErrorable
11
+
12
+ TAG = 'rollback-failed'
13
+ TYPE = ['protocol', 'application']
14
+ SEVERITY = ['error']
15
+ INFO = []
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,138 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'rexml/document'
5
+
6
+ module HrrRbNetconf
7
+ class Server
8
+ class Error < StandardError
9
+ module RpcErrorable
10
+ def initialize type, severity, info: nil, app_tag: nil, path: nil, message: nil
11
+ @logger = Logger.new self.class.name
12
+
13
+ @tag = self.class::TAG
14
+ @type = type
15
+ @severity = severity
16
+ @info = info
17
+ @app_tag = app_tag
18
+ @path = path
19
+ @message = message
20
+
21
+ validate
22
+ end
23
+
24
+ def validate
25
+ validate_type
26
+ validate_severity
27
+ validate_info
28
+ validate_app_tag
29
+ validate_path
30
+ validate_message
31
+ end
32
+
33
+ def validate_type
34
+ unless self.class::TYPE.include? @type
35
+ raise ArgumentError.new "error-type arg must be one of #{self.class::TYPE}, but given #{@type}"
36
+ end
37
+ end
38
+
39
+ def validate_severity
40
+ unless self.class::SEVERITY.include? @severity
41
+ raise ArgumentError.new "error-severity arg must be one of #{self.class::SEVERITY}, but given #{@severity}"
42
+ end
43
+ end
44
+
45
+ def validate_info
46
+ unless self.class::INFO.empty?
47
+ unless @info.kind_of? Hash
48
+ raise ArgumentError.new "error-info arg must be a kind of Hash, but given #{@info.class}"
49
+ end
50
+ unless self.class::INFO.all?{ |e| @info[e] }
51
+ raise ArgumentError.new "error-info arg must contain #{self.class::INFO} as keys, but given #{@info}"
52
+ end
53
+ end
54
+ end
55
+
56
+ def validate_app_tag
57
+ # Pass
58
+ end
59
+
60
+ def validate_path
61
+ if @path
62
+ case @path
63
+ when Hash
64
+ unless @path['value']
65
+ raise ArgumentError.new "error-path arg must contain 'value' key if Hash"
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ def validate_message
72
+ if @message
73
+ case @message
74
+ when Hash
75
+ unless @message['value']
76
+ raise ArgumentError.new "error-message arg must contain \"value\" key if Hash"
77
+ end
78
+ unless @message.fetch('attributes', {}).keys.include?('xml:lang')
79
+ @logger.warn { "error-message arg does not contain \"xml:lang\" attribute, so assuming \"en\"" }
80
+ end
81
+ else
82
+ @logger.warn { "error-message arg does not contain \"xml:lang\" attribute, so assuming \"en\"" }
83
+ end
84
+ end
85
+ end
86
+
87
+ def to_rpc_error
88
+ xml_doc = REXML::Document.new
89
+ rpc_error_e = xml_doc.add_element 'rpc-error'
90
+ tag_e = rpc_error_e.add_element 'error-tag'
91
+ tag_e.text = @tag
92
+ type_e = rpc_error_e.add_element 'error-type'
93
+ type_e.text = @type
94
+ severity_e = rpc_error_e.add_element 'error-severity'
95
+ severity_e.text = @severity
96
+ if @info
97
+ info_e = rpc_error_e.add_element 'error-info'
98
+ case @info
99
+ when Hash
100
+ @info.each{ |k, v|
101
+ child_e = info_e.add_element k
102
+ child_e.text = v
103
+ }
104
+ else
105
+ info_e.text = @info
106
+ end
107
+ end
108
+ if @app_tag
109
+ app_tag_e = rpc_error_e.add_element 'error-app-tag'
110
+ app_tag_e.text = @app_tag
111
+ end
112
+ if @path
113
+ path_e = rpc_error_e.add_element 'error-path'
114
+ case @path
115
+ when Hash
116
+ path_e.add_attributes @path['attributes']
117
+ path_e.text = @path['value']
118
+ else
119
+ path_e.text = @path
120
+ end
121
+ end
122
+ if @message
123
+ message_e = rpc_error_e.add_element 'error-message'
124
+ message_e.add_attribute 'xml:lang', 'en'
125
+ case @message
126
+ when Hash
127
+ message_e.add_attributes @message['attributes']
128
+ message_e.text = @message['value']
129
+ else
130
+ message_e.text = @message
131
+ end
132
+ end
133
+ xml_doc.root
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_netconf/server/error/rpc_errorable'
5
+
6
+ module HrrRbNetconf
7
+ class Server
8
+ class Error
9
+ class TooBig < Error
10
+ include RpcErrorable
11
+
12
+ TAG = 'too-big'
13
+ TYPE = ['transport', 'rpc', 'protocol', 'application']
14
+ SEVERITY = ['error']
15
+ INFO = []
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_netconf/server/error/rpc_errorable'
5
+
6
+ module HrrRbNetconf
7
+ class Server
8
+ class Error
9
+ class UnknownAttribute < Error
10
+ include RpcErrorable
11
+
12
+ TAG = 'unknown-attribute'
13
+ TYPE = ['rpc', 'protocol', 'application']
14
+ SEVERITY = ['error']
15
+ INFO = ['bad-attribute', 'bad-element']
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_netconf/server/error/rpc_errorable'
5
+
6
+ module HrrRbNetconf
7
+ class Server
8
+ class Error
9
+ class UnknownElement < Error
10
+ include RpcErrorable
11
+
12
+ TAG = 'unknown-element'
13
+ TYPE = ['protocol', 'application']
14
+ SEVERITY = ['error']
15
+ INFO = ['bad-element']
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_netconf/server/error/rpc_errorable'
5
+
6
+ module HrrRbNetconf
7
+ class Server
8
+ class Error
9
+ class UnknownNamespace < Error
10
+ include RpcErrorable
11
+
12
+ TAG = 'unknown-namespace'
13
+ TYPE = ['protocol', 'application']
14
+ SEVERITY = ['error']
15
+ INFO = ['bad-element', 'bad-namespace']
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_netconf/server/error'
5
+
6
+ module HrrRbNetconf
7
+ class Server
8
+ class Errors < StandardError
9
+ include Enumerable
10
+
11
+ def initialize *errors
12
+ @errors = errors.flatten
13
+ validate_errors
14
+ end
15
+
16
+ def validate_errors
17
+ unless @errors.all?{ |e| e.kind_of? HrrRbNetconf::Server::Error }
18
+ given = @errors.reject{ |e| e.kind_of? HrrRbNetconf::Server::Error }.map{ |e| e.class }
19
+ raise ArgumentError.new "Wrong argument type: given #{given}, expected HrrRbNetconf::Server::Error"
20
+ end
21
+ end
22
+
23
+ def each &blk
24
+ @errors.each &blk
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,48 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ module HrrRbNetconf
5
+ class Server
6
+ class Filter
7
+ @subclass_list = Array.new
8
+
9
+ class << self
10
+ def inherited klass
11
+ @subclass_list.push klass if @subclass_list
12
+ end
13
+
14
+ def [] key
15
+ __subclass_list__(__method__).find{ |klass| klass::TYPE == key }
16
+ end
17
+
18
+ def list
19
+ __subclass_list__(__method__).map{ |klass| klass::TYPE }
20
+ end
21
+
22
+ def __subclass_list__ method_name
23
+ send(:method_missing, method_name) unless @subclass_list
24
+ @subclass_list
25
+ end
26
+
27
+ def filter raw_output_e, input_e
28
+ filter_e = input_e.elements['filter']
29
+ if filter_e
30
+ filter_type = filter_e.attributes['type']
31
+ if self[filter_type]
32
+ self[filter_type].filter raw_output_e, filter_e
33
+ else
34
+ raise Error['bad-attribute'].new('protocol', 'error', info: {'bad-attribute' => filter_type, 'bad-element' => 'filter'})
35
+ end
36
+ else
37
+ raw_output_e
38
+ end
39
+ end
40
+
41
+ private :__subclass_list__
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ require 'hrr_rb_netconf/server/filter/subtree'
48
+ require 'hrr_rb_netconf/server/filter/xpath'
@@ -0,0 +1,135 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'rexml/document'
5
+
6
+ module HrrRbNetconf
7
+ class Server
8
+ class Filter
9
+ class Subtree < Filter
10
+ TYPE = 'subtree'
11
+
12
+ class << self
13
+ def filter raw_output_e, filter_e
14
+ selected_element_xpaths = []
15
+ output_xml_doc = REXML::Document.new
16
+ subtree_e = filter_e.elements[1]
17
+ filter_recursively(selected_element_xpaths, output_xml_doc, raw_output_e, subtree_e)
18
+ output_xml_doc.root
19
+ end
20
+
21
+ def content_match_nodes_match_all? content_match_nodes, raw_output_e
22
+ content_match_nodes.all?{ |child_filter_e|
23
+ child_filter_attributes = child_filter_e.attributes.to_a.reject{ |attr| (attr.prefix =='' && attr.name == 'xmlns') || attr.prefix == 'xmlns' }
24
+ raw_output_e.elements.to_a.any?{ |child_raw_output_e|
25
+ (child_filter_e.namespace == "" || child_filter_e.namespace == child_raw_output_e.namespace) && child_filter_e.name == child_raw_output_e.name && child_filter_e.text == child_raw_output_e.text && (
26
+ child_filter_attributes.empty? || child_filter_attributes.reject{ |child_filter_attr|
27
+ child_raw_output_e.attributes.to_a.reject{ |attr| (attr.prefix =='' && attr.name == 'xmlns') || attr.prefix == 'xmlns' }.any?{ |child_raw_output_attr|
28
+ (child_filter_attr.namespace == "" || child_filter_attr.namespace == child_raw_output_attr.namespace) && child_filter_attr.name == child_raw_output_attr.name && child_filter_attr.value == child_raw_output_attr.value
29
+ }
30
+ }
31
+ )
32
+ }
33
+ }
34
+ end
35
+
36
+ def add_elem selected_element_xpaths, output_e, raw_output_e, output_e_duplicated
37
+ if output_e_duplicated
38
+ xpath, elem = selected_element_xpaths.find{ |xpath, elem| xpath == raw_output_e.xpath }
39
+ unless xpath
40
+ child_output_e = output_e.add raw_output_e.clone
41
+ selected_element_xpaths.push [raw_output_e.xpath, child_output_e]
42
+ [child_output_e, false]
43
+ else
44
+ [elem, true]
45
+ end
46
+ else
47
+ child_output_e = output_e.add raw_output_e.clone
48
+ selected_element_xpaths.push [raw_output_e.xpath, child_output_e]
49
+ [child_output_e, false]
50
+ end
51
+ end
52
+
53
+ def filter_recursively selected_element_xpaths, output_e, raw_output_e, filter_e, options={}
54
+ if filter_e
55
+ if raw_output_e.name == filter_e.name
56
+ # Namespace Selection
57
+ filter_namespace = options['namespace'] || filter_e.namespace
58
+ if filter_namespace == nil || filter_namespace == "" || raw_output_e.namespace == filter_namespace
59
+ # Attribute Match Expressions
60
+ filter_attributes = filter_e.attributes.to_a.reject{ |attr| (attr.prefix =='' && attr.name == 'xmlns') || attr.prefix == 'xmlns' }
61
+ if filter_attributes.empty? || filter_attributes.reject{ |filter_attr|
62
+ raw_output_e.attributes.to_a.reject{ |attr| (attr.prefix =='' && attr.name == 'xmlns') || attr.prefix == 'xmlns' }.any?{ |raw_output_attr|
63
+ filter_attr.namespace == raw_output_attr.namespace && filter_attr.name == raw_output_attr.name && filter_attr.value == raw_output_attr.value
64
+ }
65
+ }.empty?
66
+ if filter_e.has_elements?
67
+ # Containment Nodes
68
+ if filter_e.elements.to_a.select{ |c| c.has_text? }.empty?
69
+ child_output_e, child_output_e_duplicated = add_elem selected_element_xpaths, output_e, raw_output_e, options['output_e_duplicated']
70
+ raw_output_e.each_element{ |child_raw_output_e|
71
+ filter_e.elements.to_a.select{ |c| c.name == child_raw_output_e.name && (c.namespace == "" || c.namespace == child_raw_output_e.namespace) }.each{ |child_filter_e|
72
+ unless child_output_e_duplicated
73
+ if selected_element_xpaths.any?{ |xpath, elem| xpath == child_raw_output_e.xpath }
74
+ child_output_e_duplicated = true
75
+ end
76
+ end
77
+ filter_recursively selected_element_xpaths, child_output_e, child_raw_output_e, child_filter_e, {'namespace' => filter_namespace, 'output_e_duplicated' => child_output_e_duplicated}
78
+ }
79
+ }
80
+ # Content Match Nodes
81
+ else
82
+ content_match_nodes = filter_e.elements.to_a.select{ |c| c.has_text? }
83
+ not_content_match_nodes = filter_e.elements.to_a.reject{ |c| c.has_text? }
84
+ if content_match_nodes_match_all? content_match_nodes, raw_output_e
85
+ child_output_e, child_output_e_duplicated = add_elem selected_element_xpaths, output_e, raw_output_e, options['output_e_duplicated']
86
+ if not_content_match_nodes.empty?
87
+ raw_output_e.each_element{ |child_raw_output_e|
88
+ child_filter_e = filter_e.elements.to_a.find{ |c| (c.namespace == "" || child_raw_output_e.namespace == c.namespace) && child_raw_output_e.name == c.name }
89
+ if child_filter_e
90
+ filter_recursively selected_element_xpaths, child_output_e, child_raw_output_e, child_filter_e, {'namespace' => filter_namespace, 'output_e_duplicated' => child_output_e_duplicated}
91
+ else
92
+ filter_recursively selected_element_xpaths, child_output_e, child_raw_output_e, child_filter_e, {'namespace' => filter_namespace, 'in_filter' => true, 'output_e_duplicated' => child_output_e_duplicated}
93
+ end
94
+ }
95
+ else
96
+ raw_output_e.each_element{ |child_raw_output_e|
97
+ child_filter_e = filter_e.elements.to_a.find{ |c| (c.namespace == "" || child_raw_output_e.namespace == c.namespace) && child_raw_output_e.name == c.name }
98
+ filter_recursively selected_element_xpaths, child_output_e, child_raw_output_e, child_filter_e, {'namespace' => filter_namespace, 'output_e_duplicated' => child_output_e_duplicated}
99
+ }
100
+ end
101
+ else
102
+ end
103
+ end
104
+ else
105
+ child_output_e, child_output_e_duplicated = add_elem selected_element_xpaths, output_e, raw_output_e, options['output_e_duplicated']
106
+ if raw_output_e.has_text?
107
+ child_output_e.text = raw_output_e.text
108
+ else
109
+ raw_output_e.each_element{ |child_raw_output_e|
110
+ filter_recursively selected_element_xpaths, child_output_e, child_raw_output_e, nil, {'namespace' => filter_namespace, 'in_filter' => true, 'output_e_duplicated' => child_output_e_duplicated}
111
+ }
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+ elsif options['in_filter']
118
+ # Namespace Selection
119
+ filter_namespace = options['namespace']
120
+ if filter_namespace == nil || filter_namespace == "" || raw_output_e.namespace == filter_namespace
121
+ child_output_e, child_output_e_duplicated = add_elem selected_element_xpaths, output_e, raw_output_e, options['output_e_duplicated']
122
+ if raw_output_e.has_text?
123
+ child_output_e.text = raw_output_e.text
124
+ end
125
+ raw_output_e.each_element{ |child_raw_output_e|
126
+ filter_recursively selected_element_xpaths, child_output_e, child_raw_output_e, filter_e, {'namespace' => filter_namespace, 'in_filter' => true, 'outout_e_duplicated' => child_output_e_duplicated}
127
+ }
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end