Module: OmfCommon

Defined in:
omf_common/lib/omf_common/version.rb,
omf_common/lib/omf_common.rb,
omf_common/lib/omf_common/key.rb,
omf_common/lib/omf_common/auth.rb,
omf_common/lib/omf_common/comm.rb,
omf_common/lib/omf_common/measure.rb,
omf_common/lib/omf_common/message.rb,
omf_common/lib/omf_common/eventloop.rb,
omf_common/lib/omf_common/comm/topic.rb,
omf_common/lib/omf_common/eventloop/em.rb,
omf_common/lib/omf_common/comm/xmpp/topic.rb,
omf_common/lib/omf_common/default_logging.rb,
omf_common/lib/omf_common/comm/xmpp/xmpp_mp.rb,
omf_common/lib/omf_common/comm/amqp/amqp_mp.rb,
omf_common/lib/omf_common/eventloop/local_evl.rb,
omf_common/lib/omf_common/message/xml/message.rb,
omf_common/lib/omf_common/comm/amqp/amqp_topic.rb,
omf_common/lib/omf_common/comm/local/local_topic.rb,
omf_common/lib/omf_common/comm/xmpp/communicator.rb,
omf_common/lib/omf_common/message/json/json_message.rb,
omf_common/lib/omf_common/message/xml/relaxng_schema.rb,
omf_common/lib/omf_common/comm/amqp/amqp_communicator.rb,
omf_common/lib/omf_common/comm/amqp/amqp_file_transfer.rb,
omf_common/lib/omf_common/comm/local/local_communicator.rb

Overview

Copyright © 2012 National ICT Australia Limited (NICTA). This software may be used and distributed solely under the terms of the MIT license (License). You should find a copy of the License in LICENSE.TXT or at opensource.org/licenses/MIT. By downloading or using this software you accept the terms and the liability disclaimer in the License.

Defined Under Namespace

Modules: Auth, Command, DSL, DefaultLogging Classes: Comm, Eventloop, Key, MPMessage, Measure, Message, RelaxNGSchema

Constant Summary

DEFAULTS =
{
  development: {
    eventloop: {
      type: 'em'
    },
    logging: {
      level: {
        default: 'debug'
      },
      appenders: {
        stdout: {
          date_pattern: '%H:%M:%S',
          pattern: '%d %5l %c{2}: %m\n',
          color_scheme: 'none'
        }
      }
    }
  },
  production: {
    eventloop: {
      type: :em
    },
    logging: {
      level: {
        default: 'info'
      },
      appenders: {
        rolling_file: {
          log_dir: '/var/log',
          size: 10240,
          keep: 1,
          date_pattern: '%F %T %z',
          pattern: '[%d] %-5l %c: %m\n'
        }
      }

    }
  },
  daemon: {
    daemonize: {
      dir_mode: :script,
      dir: '/tmp',
      backtrace: true,
      log_dir: '/var/log',
      log_output: true
    },
    eventloop: {
      type: :em
    },
    logging: {
      level: {
        default: 'info'
      },
      appenders: {
        file: {
          log_dir: '/var/log',
          #log_file: 'foo.log',
          date_pattern: '%F %T %z',
          pattern: '[%d] %-5l %c: %m\n'
        }
      }

    }
  },
  local: {
    communication: {
      type: :local,
    },
    eventloop: { type: :local},
    logging: {
      level: {
        default: 'debug'
      },
      appenders: {
        stdout: {
          date_pattern: '%H:%M:%S',
          pattern: '%d %5l %c{2}: %m\n',
          color_scheme: 'none'
        }
      }
    }
  },
  test_daemon: {
    daemonize: {
      dir_mode: :script,
      dir: '/tmp',
      backtrace: true,
      log_dir: '/tmp',
      log_output: true
    },
    eventloop: {
      type: :em
    },
    logging: {
      level: {
        default: 'debug'
      },
      appenders: {
        file: {
          log_dir: '/tmp',
          #log_file: 'foo.log',
          date_pattern: '%F %T %z',
          pattern: '[%d] %-5l %c: %m\n'
        }
      }
    }
  }
}
PROTOCOL_VERSION =
"6.0"
VERSION =
version_of('omf_common')

Class Method Summary (collapse)

Class Method Details

+ (Object) _init_logging(opts = {})

Note:

OmfCommon now ONLY provides support for STDOUT, OML, FILE, and ROLLING_FILE.

DO NOT CALL THIS METHOD DIRECTLY

By providing logging section via init method, you could custom how logging messages could be written.

Examples:

Change default logging level to :default, but :info under OmfEc namespace


{
  logging: {
    level: { default: 'debug', 'OmfEc' => 'info' }
  }
}

Write logging message to STDOUT, OML, and ROLLING_FILE

{
  logging: {
    level: { default: 'debug' }, # root logger set to level :debug
    appenders: {
      stdout: {
        level: :info,
        date_pattern: '%H:%M:%S', # show hours, mintues, seconds
        pattern: '%d %5l %c{2}: %m\n' # show date time, logging level, namespace/class
      },
      rolling_file: {
        level: :debug,
        log_dir: '/var/tmp', # files go to /var/tmp
        log_file: 'bob', # name of file
        size: 1024*1024*50, # max 50mb of each log file
        keep: 5, # keep a 5 logs in total
        date_pattern: '%F %T %z', # shows date, time, timezone
        pattern: '[%d] %-5l %c: %m\n'
      },
      oml4r: {
        appName: 'bob', # OML appName
        domain: 'bob_2345', # OML domain (database name)
        collect: 'tcp:localhost:3003' # OML server
      }
    }
  }
}

Parameters:

  • opts (Hash) (defaults to: {})


333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
# File 'omf_common/lib/omf_common.rb', line 333

def self._init_logging(opts = {})
  logger = Logging.logger.root

  if level = opts[:level]
    if level.is_a? Hash
      # package level settings
      level.each do |name, lvl|
        if name.to_s == 'default'
          logger.level = lvl.to_sym
        else
          Logging.logger[name.to_s].level = lvl.to_sym
        end
      end
    else
      logger.level = level.to_sym
    end
  end

  if appenders = opts[:appenders]
    logger.clear_appenders
    appenders.each do |type, topts|
      pattern_opts = {
        pattern:  topts.delete(:pattern),
        date_pattern: topts.delete(:date_pattern),
        color_scheme: topts.delete(:color_scheme),
        date_method: topts.delete(:date_method)
      }

      if pattern_opts[:pattern]
        appender_opts = topts.merge(layout: Logging.layouts.pattern(pattern_opts))
      else
        appender_opts = topts
      end

      case type.to_sym
      when :stdout
        $stdout.sync = true
        logger.add_appenders(Logging.appenders.stdout('custom_stdout', appender_opts))
      when :file, :rolling_file
        dir_name = topts.delete(:log_dir) || DEF_LOG_DIR
        file_name = topts.delete(:log_file) || "#{File.basename($0, File.extname($0))}.log"
        path = File.join(dir_name, file_name)
        logger.add_appenders(Logging.appenders.send(type, path, appender_opts))
      when :oml4r
        logger.add_appenders(Logging.appenders.oml4r('oml4r', appender_opts))
      else
        raise "Unknown logging appender type '#{type}'"
      end
    end
  end
end

+ (Object) _rec_merge(this_hash, other_hash)



385
386
387
388
389
390
391
392
393
# File 'omf_common/lib/omf_common.rb', line 385

def self._rec_merge(this_hash, other_hash)
  # if the dominant side is not a hash we stop recursing and pick the primitive value
  return other_hash unless other_hash.is_a? Hash

  r = {}
  this_hash.merge(other_hash) do |key, oldval, newval|
    r[key] = oldval.is_a?(Hash) ? _rec_merge(oldval, newval) : newval
  end
end

+ (Object) _rec_sym_keys(hash)

Recursively Symbolize keys of hash



397
398
399
400
401
402
403
404
405
406
407
408
# File 'omf_common/lib/omf_common.rb', line 397

def self._rec_sym_keys(hash)
  h = {}
  hash.each do |k, v|
    if v.is_a? Hash
      v = _rec_sym_keys(v)
    elsif v.is_a? Array
      v = v.map {|e| e.is_a?(Hash) ? _rec_sym_keys(e) : e }
    end
    h[k.to_sym] = v
  end
  h
end

+ (Object) comm

Return the communication driver instance



228
229
230
# File 'omf_common/lib/omf_common.rb', line 228

def self.comm()
  Comm.instance
end

+ (Object) eventloop Also known as: el

Return the communication driver instance



234
235
236
# File 'omf_common/lib/omf_common.rb', line 234

def self.eventloop()
  Eventloop.instance
end

+ (Object) init(op_mode, opts = {}, &block)

Initialise the OMF runtime.

The options here can be customised via EC or RC's configuration files.

Given the following example EC configuration file (YAML format):

environment: development
communication:
  url: amqp://localhost

OMF runtime will be configured as:

OmfCommon.init(:development, { communication: { url: "amqp://localhost" }})

Examples:

Use AMQP for communication in :development mode


OmfCommon.init(:development, { communication: { url: "amqp://localhost" }})

Change Logging configuration


options = {
  communication: { url: "amqp://localhost" },
  logging: {
    level: { default: 'debug' },
      appenders: {
        stdout: {
          level: :info,
          date_pattern: '%H:%M:%S',
          pattern: '%d %5l %c{2}: %m\n'
        },
        rolling_file: {
          level: :debug,
          log_dir: '/var/tmp',
          size: 1024*1024*50, # max 50mb of each log file
          keep: 5, # keep a 5 logs in total
          date_pattern: '%F %T %z',
          pattern: '[%d] %-5l %c: %m\n'
        },
      }
   }
}

OmfCommon.init(:development, options)

Parameters:

  • op_mode (Symbol)
  • opts (Hash) (defaults to: {})

See Also:



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'omf_common/lib/omf_common.rb', line 188

def self.init(op_mode, opts = {}, &block)
  opts = _rec_sym_keys(opts)

  if op_mode && defs = DEFAULTS[op_mode.to_sym]
    opts = _rec_merge(defs, opts)
  end
  if dopts = opts.delete(:daemonize)
    dopts[:app_name] ||= "#{File.basename($0, File.extname($0))}_daemon"
    require 'daemons'
    Daemons.run_proc(dopts[:app_name], dopts) do
      init(nil, opts, &block)
    end
    return
  end

  if lopts = opts[:logging]
    _init_logging(lopts) unless lopts.empty?
  end

  unless copts = opts[:communication]
    raise "Missing :communication description"
  end

  if aopts = opts[:auth]
    require 'omf_common/auth/credential_store'
    OmfCommon::Auth::CredentialStore.init(aopts)
  end

  # Initialise event loop
  eopts = opts[:eventloop]
  Eventloop.init(eopts)
  # start eventloop immediately if we received a run block
  eventloop.run do
    Comm.init(copts)
    block.call(eventloop) if block
  end
end

+ (Object) load_credentials(opts)



427
428
429
430
431
432
433
# File 'omf_common/lib/omf_common.rb', line 427

def self.load_credentials(opts)
  unless opts.nil?
    OmfCommon::Auth::CertificateStore.instance.register_default_certs(File.expand_path(opts[:root_cert_dir]))
    cert_and_priv_key = File.read(File.expand_path(opts[:entity_cert])) << "\n" << File.read(File.expand_path(opts[:entity_key]))
    OmfCommon::Auth::Certificate.create_from_pem(cert_and_priv_key)
  end
end

+ (Object) load_logging_config(file_path)

Load a config file compatible with Logging gem

Parameters:

  • file_path (String)

    of the logging config file



413
414
415
416
417
418
419
420
421
422
423
424
425
# File 'omf_common/lib/omf_common.rb', line 413

def self.load_logging_config(file_path)
  unless file_path.nil?
    l_cfg_mime_type = File.extname(file_path)
    case l_cfg_mime_type
    when /rb/
      load file_path
    when /yml|yaml/
      Logging::Config::YamlConfigurator.load(file_path)
    else
      warn "Invalid config file format for logging, please use Ruby or Yaml."
    end
  end
end

+ (Object) load_yaml(file_name, opts = {})

Load a YAML file and return it as hash.

options:

:symbolize_keys FLAG: Symbolize keys if set
:path:
   :same - Look in the same directory as '$0'
:remove_root ROOT_NAME: Remove the root node. Throw exception if not ROOT_NAME
:wait_for_readable SECS: Wait until the yaml file becomes readable. Check every SECS
:erb_process flag: Run the content of the loaded file through ERB first before YAML parsing
:erb_safe_level level: If safe_level is set to a non-nil value, ERB code will be run in a
                                separate thread with $SAFE set to the provided level.
:erb_binding binding: Optional binding given to ERB#result


255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'omf_common/lib/omf_common.rb', line 255

def self.load_yaml(file_name, opts = {})
  if path_opt = opts[:path]
    case path_opt
    when :same
      file_name = File.join(File.dirname($0), file_name)
    else
      raise "Unknown value '#{path_opt}' for 'path' option"
    end
  end
  if readable_check = opts[:wait_for_readable]
    while not File.readable?(file_name)
      puts "WAIT #{file_name}"
      sleep readable_check # wait until file shows up
    end
  end

  str = File.read(file_name)
  if opts[:erb_process]
    require 'erb'
    str = ERB.new(str, opts[:erb_safe_level]).result(opts[:erb_binding] || binding)
  end
  yh = YAML.load(str)

  if opts[:symbolize_keys]
    yh = _rec_sym_keys(yh)
  end
  if root = opts[:remove_root]
    if yh.length != 1 && yh.key?(root)
      raise "Expected root '#{root}', but found '#{yh.keys.inspect}"
    end
    yh = yh.delete(root)
  end
  yh
end

+ (Object) version_of(name)



9
10
11
12
13
14
15
16
17
18
19
20
# File 'omf_common/lib/omf_common/version.rb', line 9

def self.version_of(name)
  git_tag  = `git describe --tags 2> /dev/null`.chomp
  git_root = `git rev-parse --show-toplevel 2> /dev/null`.chomp
  gem_v = Gem.loaded_specs[name].version.to_s rescue '0.0.0'

  # Not in a development environment or git not present
  if git_root != File.absolute_path("#{File.dirname(__FILE__)}/../../../") || git_tag.empty?
    gem_v
  else
    git_tag.gsub(/-/, '.').gsub(/^v/, '')
  end
end