Class: Arborist::Node::Service

Inherits:
Arborist::Node show all
Includes:
HashUtilities, Arborist::NetworkUtilities
Defined in:
lib/arborist/node/service.rb

Overview

A node type for Arborist trees that represent services running on hosts.

Constant Summary collapse

DEFAULT_PROTOCOL =

The default transport layer protocol to use for services that don’t specify one

'tcp'

Constants included from Arborist::NetworkUtilities

Arborist::NetworkUtilities::IPADDR_RE

Constants inherited from Arborist::Node

LOADED_INSTANCE_KEY, OPERATIONAL_ATTRIBUTES, UNREACHABLE_STATES, VALID_IDENTIFIER

Instance Attribute Summary

Attributes inherited from Arborist::Node

#ack, #children, #dependencies, #errors, #identifier, #last_contacted, #pending_change_events, #previous_ack, #properties, #quieted_reasons, #source, #status_changed, #status_history, #status_last_changed, #subscriptions, #update_delta, #warnings

Instance Method Summary collapse

Methods included from HashUtilities

compact_hash, hash_matches, merge_recursively, stringify_keys, symbolify_keys

Methods included from Arborist::NetworkUtilities

#normalize_address

Methods inherited from Arborist::Node

#<<, #acked_description, #acknowledge, #add_child, add_loaded_instance, add_subnode_factory_method, #add_subscription, #all_of, #any_of, #broadcast_events, #clear_transition_temp_vars, #config, curried_create, #dependencies_down?, #dependencies_up?, #depends_on, #description, #each, each_in, #fetch_values, #find_matching_subscriptions, #flap_threshold, #flapping, from_hash, #handle_event, #handle_node_disabled_event, #handle_node_down_event, #handle_node_quieted_event, #handle_node_up_event, #has_children?, #has_dependencies?, #has_quieted_reason?, inherited, #inspect, load, #make_delta_event, #make_update_event, #marshal_dump, #marshal_load, #matches?, #merge_and_record_delta, #merge_new_properties, new, #node_subscribers, #operational?, parent_types, #publish_events, #reachable?, #register_secondary_dependencies, #remove_child, #remove_subscription, #reparent, #restore, #state_has_changed?, #status, #status_description, #status_history_size, subnode_type?, #tags, #type, #unacknowledge, #unreachable?, #update, #update_errors, #update_properties, #update_warnings

Methods included from MethodUtilities

#attr_predicate, #attr_predicate_accessor, #dsl_accessor, #singleton_attr_accessor, #singleton_attr_reader, #singleton_attr_writer, #singleton_method_alias, #singleton_predicate_accessor, #singleton_predicate_reader

Constructor Details

#initialize(identifier, host, attributes = {}, &block) ⇒ Service

Create a new Service node.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/arborist/node/service.rb', line 29

def initialize( identifier, host, attributes={}, &block )
	raise Arborist::NodeError, "no host given" unless host.is_a?( Arborist::Node::Host )
	qualified_identifier = "%s-%s" % [ host.identifier, identifier ]

	@host         = host
	@addresses    = nil
	@app_protocol = nil
	@protocol     = nil
	@port         = nil

	attributes[ :app_protocol ] ||= identifier
	attributes[ :protocol ] ||= DEFAULT_PROTOCOL

	super( qualified_identifier, host, attributes, &block )

	unless @port
		service_port = default_port_for( @app_protocol, @protocol ) or
			raise ArgumentError, "can't determine the port for %s/%s" %
				[ @app_protocol, @protocol ]
		@port = Integer( service_port )
	end
end

Instance Method Details

#==(other_host) ⇒ Object

Equality operator – returns true if other_node is equal to the receiver. Overridden to also compare addresses.



186
187
188
189
190
191
192
# File 'lib/arborist/node/service.rb', line 186

def ==( other_host )
	return super &&
		other_host.addresses == self.addresses &&
		other_host.protocol == self.protocol &&
		other_host.app_protocol == self.app_protocol &&
		other_host.port == self.port
end

#address(new_address) ⇒ Object

Set an IP address of the service. This must be one of the addresses of its containing host.



91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/arborist/node/service.rb', line 91

def address( new_address )
	self.log.debug "Adding address %p to %p" % [ new_address, self ]
	normalized_addresses = normalize_address( new_address )

	unless normalized_addresses.all? {|addr| @host.addresses.include?(addr) }
		raise Arborist::ConfigError, "%s is not one of %s's addresses" %
			[ new_address, @host.identifier ]
	end

	@addresses ||= []
	@addresses += normalized_addresses
end

#addressesObject

Delegate the service’s address to its host.



106
107
108
# File 'lib/arborist/node/service.rb', line 106

def addresses
	return @addresses || @host.addresses
end

#app_protocolObject

Get/set the application protocol the service uses



63
# File 'lib/arborist/node/service.rb', line 63

dsl_accessor :app_protocol

#familyObject

Return the node family, so observers can know ancestry after serialization for custom node types that inherit from this class.



72
73
74
# File 'lib/arborist/node/service.rb', line 72

def family
	return :service
end

#hostnameObject

Delegate the service’s hostname to it’s parent host.



112
113
114
# File 'lib/arborist/node/service.rb', line 112

def hostname
	return @host.hostname
end

#match_criteria?(key, val) ⇒ Boolean

Returns true if the node matches the specified key and val criteria.

Returns:

  • (Boolean)


118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/arborist/node/service.rb', line 118

def match_criteria?( key, val )
	self.log.debug "Matching %p: %p against %p" % [ key, val, self ]
	array_val = Array( val )
	return case key
		when 'port'
			vals = array_val.collect do |port|
				port = default_port_for( port, @protocol ) unless port.is_a?( Integer )
				port.to_i
			end
			vals.include?( self.port )
		when 'address'
			search_addr = IPAddr.new( val )
			self.addresses.any? {|a| search_addr.include?(a) }
		when 'protocol' then array_val.include?( self.protocol )
		when 'app', 'app_protocol' then array_val.include?( self.app_protocol )
		else
			super
		end
end

#modify(attributes) ⇒ Object

Set service attributes.



78
79
80
81
82
83
84
85
86
# File 'lib/arborist/node/service.rb', line 78

def modify( attributes )
	attributes = stringify_keys( attributes )

	super

	self.port( attributes['port'] )
	self.app_protocol( attributes['app_protocol'] )
	self.protocol( attributes['protocol'] )
end

#node_descriptionObject

Return service-node-specific information for #inspect.



153
154
155
156
157
158
# File 'lib/arborist/node/service.rb', line 153

def node_description
	return "{listening on %s port %d}" % [
		self.protocol,
		self.port,
	]
end

#operational_valuesObject

Return a Hash of the operational values that are included with the node’s monitor state.



141
142
143
144
145
146
147
148
149
# File 'lib/arborist/node/service.rb', line 141

def operational_values
	return super.merge(
		addresses: self.addresses.map( &:to_s ),
		hostname: self.hostname,
		port: self.port,
		protocol: self.protocol,
		app_protocol: self.app_protocol,
	)
end

#parent(new_parent = nil) ⇒ Object

Overridden to disallow modification of a Service’s parent, as it needs a reference to the Host node for delegation.



163
164
165
166
# File 'lib/arborist/node/service.rb', line 163

def parent( new_parent=nil )
	return super unless new_parent
	raise "Can't reparent a service; replace the node instead"
end

#portObject

Get/set the port the service binds to



59
# File 'lib/arborist/node/service.rb', line 59

dsl_accessor :port

#protocolObject

Get/set the network protocol the service uses



67
# File 'lib/arborist/node/service.rb', line 67

dsl_accessor :protocol

#to_hObject

Return a Hash of the host node’s state.



174
175
176
177
178
179
180
181
# File 'lib/arborist/node/service.rb', line 174

def to_h( ** )
	return super.merge(
		addresses: self.addresses.map(&:to_s),
		protocol: self.protocol,
		app_protocol: self.app_protocol,
		port: self.port
	)
end