class Hawkular::Operations::Client

Client class to interact with the agent via websockets

Attributes

logger[RW]
ws[RW]

Public Class Methods

new(args) click to toggle source

Initialize new Client

@param [Hash] args Arguments for client. There are two ways of passing in the target host/port: via :host and via :entrypoint. If both are given, then :entrypoint will be used.

@option args [String] :entrypoint Base URL of the hawkular server e.g. localhost:8080. @option args [String] :host base host:port pair of Hawkular - e.g localhost:8080 @option args [Boolean] :use_secure_connection if no entrypoint is provided, determines if use a secure connection

defaults to false

@option args [Hash{String=>String}] :credentials Hash of (username password) or token @option args [Hash{String=>String}] :options Additional rest client options @option args [Fixnum] :wait_time Time in seconds describing how long the constructor should block - handshake

@example

Hawkular::Operations::Client.new(credentials: {username: 'jdoe', password: 'password'})
Calls superclass method Hawkular::BaseClient::new
    # File lib/hawkular/operations/operations_api.rb
 86 def initialize(args)
 87   args = {
 88     credentials: {},
 89     options: {},
 90     wait_time: 0.5,
 91     use_secure_connection: false,
 92     entrypoint: nil
 93   }.merge(args)
 94 
 95   if args[:entrypoint]
 96     uri = URI.parse(args[:entrypoint].to_s)
 97     args[:host] = "#{uri.host}:#{uri.port}"
 98     args[:use_secure_connection] = %w[https wss].include?(uri.scheme) ? true : false
 99   end
100 
101   fail Hawkular::ArgumentError, 'no parameter ":host" or ":entrypoint" given' if args[:host].nil?
102 
103   super(args[:host], args[:credentials], args[:options])
104 
105   @logger = Hawkular::Logger.new
106 
107   @url = "ws#{args[:use_secure_connection] ? 's' : ''}://#{args[:host]}/hawkular/command-gateway/ui/ws"
108   @credentials = args[:credentials]
109   @tenant = args[:options][:tenant]
110   @wait_time = args[:wait_time]
111 end

Private Class Methods

handle_error(parsed_message, &callback) click to toggle source
    # File lib/hawkular/operations/operations_api.rb
424 def self.handle_error(parsed_message, &callback)
425   callback.perform(:failure, parsed_message == {} ? 'error' : parsed_message[:data]['errorMessage'])
426 end

Public Instance Methods

add_datasource(hash, &callback) click to toggle source

Adds a new datasource

@param [Hash] hash Arguments for the datasource @option hash [String] :resourceId ID of the WildFly server into which we add datasource @option hash [String] :feedId ID of the feed containing the WildFly server @option hash [String] :xaDatasource XA DS or normal @option hash [String] :datasourceName name of the datasource @option hash [String] :jndiName JNDI name @option hash [String] :driverName this is internal name of the driver in Hawkular @option hash [String] :driverClass class of driver @option hash [String] :connectionUrl jdbc connection string @option hash [String] :datasourceProperties optional properties @option hash [String] :username username to DB @option hash [String] :password password to DB

@param callback [Block] callback that is run after the operation is done

    # File lib/hawkular/operations/operations_api.rb
294 def add_datasource(hash, &callback)
295   required = %i[resourceId feedId xaDatasource datasourceName jndiName
296                 driverName driverClass connectionUrl]
297   check_pre_conditions hash, required, &callback
298 
299   invoke_specific_operation(hash, 'AddDatasource', &callback)
300 end
add_deployment(hash, &callback) click to toggle source

Deploys an archive file into WildFly

@param [Hash] hash Arguments for deployment @option hash [String] :resource_id ID of the WildFly server into which we deploy

or of the domain controller if we deploy into a server group (in case of domain mode)

@option hash [String] :feed_id feed containing this resource @option hash [String] :destination_file_name resulting file name @option hash [String] :binary_content binary content representing the war file @option hash [String] :enabled whether the deployment should be enabled immediately, or not (default = true) @option hash [String] :force_deploy whether to replace existing content or not (default = false) @option hash [String] :server_groups comma-separated list of server groups for the operation (default = ignored)

@param callback [Block] callback that is run after the operation is done

    # File lib/hawkular/operations/operations_api.rb
190 def add_deployment(hash, &callback)
191   hash[:enabled] = hash.key?(:enabled) ? hash[:enabled] : true
192   hash[:force_deploy] = hash.key?(:force_deploy) ? hash[:force_deploy] : false
193   required = %i[resource_id feed_id destination_file_name binary_content]
194   check_pre_conditions hash, required, &callback
195 
196   operation_payload = prepare_payload_hash([:binary_content], hash)
197   invoke_operation_helper(operation_payload, 'DeployApplication', hash[:binary_content], &callback)
198 end
add_jdbc_driver(hash, &callback) click to toggle source

Adds a new datasource

@param [Hash] hash Arguments for the datasource @option hash [String] :resource_id ID of the WildFly server into which we add driver @option hash [String] :feed_id ID of the feed containing the WildFly server @option hash [String] :driver_jar_name name of the jar file @option hash [String] :driver_name name of the jdbc driver (when adding datasource, this is the driverName) @option hash [String] :module_name name of the JBoss module into which the driver will be installed - 'foo.bar' @option hash [String] :driver_class fully specified java class of the driver - e.q. 'com.mysql.jdbc.Driver' @option hash [String] :binary_content driver jar file bits

@param callback [Block] callback that is run after the operation is done

    # File lib/hawkular/operations/operations_api.rb
314 def add_jdbc_driver(hash, &callback)
315   required = %i[resource_id feed_id driver_jar_name driver_name module_name
316                 driver_class binary_content]
317   check_pre_conditions hash, required, &callback
318 
319   operation_payload = prepare_payload_hash([:binary_content], hash)
320   invoke_operation_helper(operation_payload, 'AddJdbcDriver', hash[:binary_content], &callback)
321 end
base64_credentials() click to toggle source
    # File lib/hawkular/operations/operations_api.rb
113 def base64_credentials
114   ["#{@credentials[:username]}:#{@credentials[:password]}"].pack('m').delete("\r\n")
115 end
close_connection!() click to toggle source

Closes the WebSocket connection

    # File lib/hawkular/operations/operations_api.rb
145 def close_connection!
146   @ws && @ws.close
147 end
connect() click to toggle source
    # File lib/hawkular/operations/operations_api.rb
117 def connect
118   return if @connecting || (@ws && @ws.open?)
119 
120   @connecting = true
121 
122   ws_options = {
123     headers:  {
124       'Authorization' => 'Basic ' + base64_credentials,
125       'Hawkular-Tenant' => @tenant,
126       'Accept' => 'application/json'
127     }
128   }
129 
130   @ws = Simple.connect @url, ws_options do |client|
131     client.on(:message, once: true) do |msg|
132       parsed_message = msg.data.to_msg_hash
133 
134       logger = Hawkular::Logger.new
135       logger.log("Sent WebSocket message: #{parsed_message}")
136     end
137   end
138 
139   Timeout.timeout(@wait_time) { sleep 0.1 until @ws.open? }
140 ensure
141   @connecting = false
142 end
disable_deployment(hash, &callback) click to toggle source

Disable a WildFly deployment

@param [Hash] hash Arguments for disable deployment @option hash [String] :resource_id ID of the WildFly server from which to disable the deployment @option hash [String] :feed_id feed containing this resource @option hash [String] :deployment_name name of deployment to disable @option hash [String] :server_groups comma-separated list of server groups for the operation (default = ignored)

@param callback [Block] callback that is run after the operation is done

    # File lib/hawkular/operations/operations_api.rb
249 def disable_deployment(hash, &callback)
250   required = %i[resource_id feed_id deployment_name]
251   check_pre_conditions hash, required, &callback
252 
253   hash[:destination_file_name] = hash[:deployment_name]
254 
255   operation_payload = prepare_payload_hash([:deployment_name], hash)
256   invoke_operation_helper(operation_payload, 'DisableApplication', &callback)
257 end
enable_deployment(hash, &callback) click to toggle source

Enable a WildFly deployment

@param [Hash] hash Arguments for enable deployment @option hash [String] :resource_id ID of the WildFly server from which to enable the deployment @option hash [String] :feed_id feed containing this resource @option hash [String] :deployment_name name of deployment to enable @option hash [String] :server_groups comma-separated list of server groups for the operation (default = ignored)

@param callback [Block] callback that is run after the operation is done

    # File lib/hawkular/operations/operations_api.rb
230 def enable_deployment(hash, &callback)
231   required = %i[resource_id feed_id deployment_name]
232   check_pre_conditions hash, required, &callback
233 
234   hash[:destination_file_name] = hash[:deployment_name]
235 
236   operation_payload = prepare_payload_hash([:deployment_name], hash)
237   invoke_operation_helper(operation_payload, 'EnableApplication', &callback)
238 end
export_jdr(resource_id, feed_id, delete_immediately = false, sender_request_id = nil, &callback) click to toggle source

Exports the JDR report

@param [String] resource_id ID of the WildFly server @param [String] feed_id ID of the feed containing the WildFly server @param [Boolean] delete_immediately specifies whether the temporary file at the remote server should be deleted. False, by default. @param callback [Block] callback that is run after the operation is done

    # File lib/hawkular/operations/operations_api.rb
330 def export_jdr(resource_id, feed_id, delete_immediately = false, sender_request_id = nil, &callback)
331   fail Hawkular::ArgumentError, 'resource_id must be specified' if resource_id.nil?
332   fail Hawkular::ArgumentError, 'feed_id must be specified' if feed_id.nil?
333   check_pre_conditions(&callback)
334 
335   invoke_specific_operation({ resourceId: resource_id,
336                               feedId: feed_id,
337                               deleteImmediately: delete_immediately,
338                               senderRequestId: sender_request_id },
339                             'ExportJdr', &callback)
340 end
invoke_generic_operation(hash, &callback) click to toggle source

Invokes a generic operation on the WildFly agent (the operation name must be specified in the hash) Note: if success and failure callbacks are omitted, the client will not wait for the Response message @param hash [Hash{String=>Object}] a hash containing: resourceId [String] denoting the resource on which the operation is about to run, feedId [String], operationName [String] @param callback [Block] callback that is run after the operation is done

    # File lib/hawkular/operations/operations_api.rb
155 def invoke_generic_operation(hash, &callback)
156   required = %i[resourceId feedId operationName]
157   check_pre_conditions hash, required, &callback
158 
159   invoke_operation_helper(hash, &callback)
160 end
invoke_specific_operation(operation_payload, operation_name, &callback) click to toggle source

Invokes operation on the WildFly agent that has it's own message type @param operation_payload [Hash{String=>Object}] a hash containing: resourceId [String] denoting the resource on which the operation is about to run, feedId [String] @param operation_name [String] the name of the operation. This must correspond with the message type, they can be found here git.io/v2h1a (Use only the first part of the name without the Request/Response suffix), e.g. RemoveDatasource (and not RemoveDatasourceRequest) @param callback [Block] callback that is run after the operation is done

    # File lib/hawkular/operations/operations_api.rb
169 def invoke_specific_operation(operation_payload, operation_name, &callback)
170   fail Hawkular::ArgumentError, 'Operation must be specified' if operation_name.nil?
171   required = %i[resourceId feedId]
172   check_pre_conditions operation_payload, required, &callback
173 
174   invoke_operation_helper(operation_payload, operation_name, &callback)
175 end
restart_deployment(hash, &callback) click to toggle source

Restart a WildFly deployment

@param [Hash] hash Arguments for restart deployment @option hash [String] :resource_id ID of the WildFly server from which to restart the deployment @option hash [String] :feed_id feed containing this resource @option hash [String] :deployment_name name of deployment to restart @option hash [String] :server_groups comma-separated list of server groups for the operation (default = ignored)

@param callback [Block] callback that is run after the operation is done

    # File lib/hawkular/operations/operations_api.rb
268 def restart_deployment(hash, &callback)
269   required = %i[resource_id feed_id deployment_name]
270   check_pre_conditions hash, required, &callback
271 
272   hash[:destination_file_name] = hash[:deployment_name]
273 
274   operation_payload = prepare_payload_hash([:deployment_name], hash)
275   invoke_operation_helper(operation_payload, 'RestartApplication', &callback)
276 end
undeploy(hash, &callback) click to toggle source

Undeploy a WildFly deployment

@param [Hash] hash Arguments for deployment removal @option hash [String] :resource_id ID of the WildFly server from which to undeploy the deployment @option hash [String] :feed_id feed containing this resource @option hash [String] :deployment_name name of deployment to undeploy @option hash [String] :remove_content whether to remove the deployment content or not (default = true) @option hash [String] :server_groups comma-separated list of server groups for the operation (default = ignored)

@param callback [Block] callback that is run after the operation is done

    # File lib/hawkular/operations/operations_api.rb
210 def undeploy(hash, &callback)
211   hash[:remove_content] = hash.key?(:remove_content) ? hash[:remove_content] : true
212   required = %i[resource_id feed_id deployment_name]
213   check_pre_conditions hash, required, &callback
214 
215   hash[:destination_file_name] = hash[:deployment_name]
216 
217   operation_payload = prepare_payload_hash([:deployment_name], hash)
218   invoke_operation_helper(operation_payload, 'UndeployApplication', &callback)
219 end
update_collection_intervals(hash, &callback) click to toggle source

Updates the collection intervals.

@param [Hash] hash Arguments for update collection intervals @option hash {resourceId} a resource managed by the target agent @option hash {feedId} the related feed ID @option hash {metricTypes} A map with key=MetricTypeId, value=interval (seconds). MetricTypeId must be of form MetricTypeSet~MetricTypeName @option hash {availTypes} A map with key=AvailTypeId, value=interval (seconds). AvailTypeId must be of form AvailTypeSet~AvailTypeName

@param callback [Block] callback that is run after the operation is done

    # File lib/hawkular/operations/operations_api.rb
353 def update_collection_intervals(hash, &callback)
354   required = %i[resourceId feedId metricTypes availTypes]
355   check_pre_conditions hash, required, &callback
356   invoke_specific_operation(hash, 'UpdateCollectionIntervals', &callback)
357 end

Private Instance Methods

add_credentials!(hash) click to toggle source
    # File lib/hawkular/operations/operations_api.rb
397 def add_credentials!(hash)
398   hash[:authentication] = @credentials.delete_if { |_, v| v.nil? }
399 end
check_pre_conditions(hash = {}, params = [], &callback) click to toggle source
    # File lib/hawkular/operations/operations_api.rb
381 def check_pre_conditions(hash = {}, params = [], &callback)
382   fail Hawkular::ArgumentError, 'Hash cannot be nil.' if hash.nil?
383   fail Hawkular::ArgumentError, 'callback must have the perform method defined. include Hawkular::Operations' unless
384       callback.nil? || callback.respond_to?('perform')
385 
386   params.each do |property|
387     next unless hash[property].nil?
388     err_callback = 'You need to specify error callback'
389     err_message = "Hash property #{property} must be specified"
390 
391     if !callback || callback.perform(:failure, err_message) == Proc::PerformMethodMissing
392       fail(Hawkular::ArgumentError, err_callback)
393     end
394   end
395 end
handle_message(operation_name, operation_payload, &callback) click to toggle source
    # File lib/hawkular/operations/operations_api.rb
401 def handle_message(operation_name, operation_payload, &callback)
402   client = @ws
403   # register a callback handler
404   @ws.on :message do |msg|
405     parsed = msg.data.to_msg_hash
406 
407     logger = Hawkular::Logger.new
408     logger.log("Received WebSocket msg: #{parsed}")
409 
410     case parsed[:operationName]
411     when "#{operation_name}Response"
412       if parsed[:data]['senderRequestId'] == operation_payload[:senderRequestId]
413         success = parsed[:data]['status'] == 'OK'
414         success ? callback.perform(:success, parsed[:data]) : callback.perform(:failure, parsed[:data]['message'])
415         client.remove_listener :message
416       end
417     when 'GenericErrorResponse'
418       Client.handle_error parsed, &callback
419       client.remove_listener :message
420     end
421   end
422 end
invoke_operation_helper(operation_payload, operation_name = nil, binary_content = nil, &callback) click to toggle source
    # File lib/hawkular/operations/operations_api.rb
361 def invoke_operation_helper(operation_payload, operation_name = nil, binary_content = nil, &callback)
362   synchronize { connect }
363 
364   # fallback to generic 'ExecuteOperation' if nothing is specified
365   operation_name ||= 'ExecuteOperation'
366   add_credentials! operation_payload
367 
368   # if unset, set the :senderRequestId
369   operation_payload[:senderRequestId] = SecureRandom.uuid unless operation_payload[:senderRequestId]
370 
371   handle_message(operation_name, operation_payload, &callback) unless callback.nil?
372 
373   # sends a message that will actually run the operation
374   payload = "#{operation_name}Request=#{operation_payload.to_json}"
375   payload += binary_content unless binary_content.nil?
376   @ws.send payload, type: binary_content.nil? ? :text : :binary
377 rescue => e
378   callback.perform(:failure, "#{e.class} - #{e.message}")
379 end
prepare_payload_hash(ignored_params, hash) click to toggle source
    # File lib/hawkular/operations/operations_api.rb
429 def prepare_payload_hash(ignored_params, hash)
430   # it filters out ignored params and convert keys from snake_case to camelCase
431   Hash[hash.reject { |k, _| ignored_params.include? k }.map { |k, v| [to_camel_case(k.to_s).to_sym, v] }]
432 end
to_camel_case(str) click to toggle source
    # File lib/hawkular/operations/operations_api.rb
434 def to_camel_case(str)
435   subs = str.split('_')
436   ret = subs.length > 1 ? subs.collect(&:capitalize).join : subs[0]
437   ret[0] = ret[0].downcase
438   ret
439 end