From: <kk...@us...> - 2008-10-02 14:02:08
|
Revision: 1061 http://omc.svn.sourceforge.net/omc/?rev=1061&view=rev Author: kkaempf Date: 2008-10-02 13:31:15 +0000 (Thu, 02 Oct 2008) Log Message: ----------- - add test cases for cmpi_rbwbem_bindings.rb - load Ruby providers on-demand - provide interface modules for the various MI types and their functions Modified Paths: -------------- cmpi-bindings/trunk/src/target_ruby.c cmpi-bindings/trunk/swig/ruby/cmpi_rbwbem_bindings.rb cmpi-bindings/trunk/test/ruby/test_atom_provider.rb Added Paths: ----------- cmpi-bindings/trunk/swig/ruby/test/ cmpi-bindings/trunk/swig/ruby/test/create.rb cmpi-bindings/trunk/swig/ruby/test/loading.rb Modified: cmpi-bindings/trunk/src/target_ruby.c =================================================================== --- cmpi-bindings/trunk/src/target_ruby.c 2008-10-02 13:30:26 UTC (rev 1060) +++ cmpi-bindings/trunk/src/target_ruby.c 2008-10-02 13:31:15 UTC (rev 1061) @@ -20,40 +20,27 @@ static VALUE load_module() { - _SBLIM_TRACE(1,("Ruby: require '%s'...", RB_BINDINGS_FILE)); - - rb_require(RB_BINDINGS_FILE); - - _SBLIM_TRACE(1,("Ruby: ... done")); - - return Qnil; + ruby_script(RB_BINDINGS_FILE); + return rb_require(RB_BINDINGS_FILE); } /* - * create_mi - * call constructor for MI implementation class + * create_mi (called from rb_protect) + * load Ruby provider and create provider instance * * I args : pointer to array of 2 values - * values[0] = broker, passed to constructor - * values[1] = id of class (rb_intern(<classname>)) + * values[0] = classname (String) + * values[1] = broker, passed to constructor */ static VALUE create_mi(VALUE args) { VALUE *values = (VALUE *)args; - _SBLIM_TRACE(1,("Ruby: %s.new ...", rb_id2name(values[1]))); - VALUE klass = rb_const_get(_TARGET_MODULE, values[1]); - _SBLIM_TRACE(1,("Ruby: ... klass -> %ld", klass)); - if (NIL_P(klass)) - { - _SBLIM_TRACE(1,("Ruby: ... klass is NULL")); - return klass; - } - VALUE instance = rb_class_new_instance(1, values, klass); - _SBLIM_TRACE(1,("Ruby: ... done -> %ld", instance)); - return instance; + + _SBLIM_TRACE(1,("Ruby: %s.new ...", StringValuePtr(values[0]))); + return rb_funcall2(_TARGET_MODULE, rb_intern("create_provider"), 2, values); } @@ -78,6 +65,25 @@ /* + * get Ruby exception trace -> CMPIString + * + */ + +#define TB_ERROR(str) {tbstr = str; goto cleanup;} +static CMPIString * +get_exc_trace(const CMPIBroker* broker) +{ + VALUE exception = rb_gv_get("$!"); /* get last exception */ + VALUE reason = rb_funcall(exception, rb_intern("to_s"), 0 ); + VALUE trace = rb_gv_get("$@"); /* get last exception trace */ + VALUE backtrace = rb_funcall(trace, rb_intern("join"), 1, rb_str_new("\n\t", 2)); + + char* tmp = fmtstr("%s\n\t%s", StringValuePtr(reason), StringValuePtr(backtrace)); + return broker->eft->newString(broker, tmp, NULL); +} + + +/* * Global Ruby initializer * loads the Ruby interpreter * init threads @@ -88,11 +94,8 @@ { int error; - _SBLIM_TRACE(1,("<%d> RbGlobalInitialize() called", getpid())); - if (_TARGET_INIT) { - _SBLIM_TRACE(1,("<%d> RbGlobalInitialize() returning: already initialized", getpid())); return 0; } _TARGET_INIT=1;//true @@ -101,14 +104,16 @@ ruby_init(); ruby_init_loadpath(); - ruby_script("cmpi_swig"); + ruby_script("cmpi_swig_ruby"); SWIG_init(); /* load module */ rb_protect(load_module, Qnil, &error); if (error) { - _SBLIM_TRACE(1,("<%d> Ruby: import '%s' failed, error %d", getpid(), RB_BINDINGS_FILE, error)); + CMPIString *trace = get_exc_trace(broker); + + _SBLIM_TRACE(1,("<%d> Ruby: import '%s' failed: %s", getpid(), RB_BINDINGS_FILE, CMGetCharPtr(trace))); /* _CMPI_SETFAIL(<CMPIString *>); */ abort(); return -1; @@ -155,15 +160,17 @@ _SBLIM_TRACE(1,("<%d> TargetInitialize(Ruby) called, miName '%s'", getpid(), hdl->miName)); - args[0] = SWIG_NewPointerObj((void*) hdl->broker, SWIGTYPE_p__CMPIBroker, 0); - args[1] = rb_intern(hdl->miName); + args[0] = rb_str_new2(hdl->miName); + args[1] = SWIG_NewPointerObj((void*) hdl->broker, SWIGTYPE_p__CMPIBroker, 0); hdl->instance = rb_protect(create_mi, (VALUE)args, &error); if (error) { - _SBLIM_TRACE(1,("Ruby: FAILED creating %s, error %d", hdl->miName, error)); + CMPIString *trace = get_exc_trace(hdl->broker); + _SBLIM_TRACE(1,("Ruby: FAILED creating %s:", hdl->miName, CMGetCharPtr(trace))); if (st != NULL) { st->rc = CMPI_RC_ERR_INVALID_CLASS; + st->msg = trace; } } else @@ -189,17 +196,6 @@ VALUE *args, result, op = rb_intern(opname); va_list vargs; - _SBLIM_TRACE(1,("call_provider %s[%d]", opname, nargs)); - - if (!rb_respond_to(hdl->instance, op)) - { - char* str = fmtstr("Ruby provider does not implement \"%s\"", opname); - _SBLIM_TRACE(1,("%s", str)); - st->rc = CMPI_RC_ERR_FAILED; - st->msg = hdl->broker->eft->newString(hdl->broker, str, NULL); - return 1; - } - /* add hdl->instance, op and nargs to the args array, so rb_protect can be called */ nargs += 3; args = (VALUE *)malloc(nargs * sizeof(VALUE)); @@ -228,8 +224,9 @@ if (i) { - char* str = fmtstr("Ruby provider call to \"%s\" failed", opname); - _SBLIM_TRACE(1,("%s", str)); + CMPIString *trace = get_exc_trace(hdl->broker); + char* str = fmtstr("Ruby: calling '%s' failed: %s", opname, CMGetCharPtr(trace)); + _SBLIM_TRACE(1,("%s", str)); st->rc = CMPI_RC_ERR_FAILED; st->msg = hdl->broker->eft->newString(hdl->broker, str, NULL); return 1; Modified: cmpi-bindings/trunk/swig/ruby/cmpi_rbwbem_bindings.rb =================================================================== --- cmpi-bindings/trunk/swig/ruby/cmpi_rbwbem_bindings.rb 2008-10-02 13:30:26 UTC (rev 1060) +++ cmpi-bindings/trunk/swig/ruby/cmpi_rbwbem_bindings.rb 2008-10-02 13:31:15 UTC (rev 1061) @@ -5,27 +5,86 @@ # module Cmpi - STDERR.puts "Hello from cmpi-bindings-ruby" # init - RBCIMPATH = "/usr/lib/rbcim/" + RBCIMPATH = "/usr/lib/rbcim" - # look for .rb files below RBCIMPATH - # and load them - if File.directory?(RBCIMPATH) then + # + # on-demand loading of Ruby providers + # create provider for 'classname' + # pass 'broker' to its constructor + # + def self.create_provider classname, broker $:.unshift RBCIMPATH # add to load path - STDERR.puts "Looking into #{RBCIMPATH}" - Dir.foreach( RBCIMPATH ) do |entry| - STDERR.puts "Found #{entry}" - split = entry.split '.' - if split[1] == 'rb' then - begin - STDERR.puts "Loading #{split[0]}" - require split[0] - rescue Exception => e - STDERR.puts "Loading #{split[0]} failed: #{e}" - end - end - end + # CamelCase -> under_score + underscore = classname. + gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). + gsub(/([a-z\d])([A-Z])/,'\1_\2'). + tr("-", "_"). + downcase + STDERR.puts "create_provider #{classname}: #{underscore}" + # load implementation + require underscore + $:.shift # take load path away + + Cmpi.const_get(classname).new broker end + + # define MI provider interfaces as modules + # so they can be used as mixins + module InstanceProviderIF + def create_instance context, result, reference, newinst + end + def get_instance context, result, objname, plist + end + def delete_instance context, result, objname + end + def method_missing method, *args + STDERR.puts "InstanceProvider.#{method}: not implemented" + end + end + + module MethodProviderIF + def method_missing method, *args + STDERR.puts "MethodProvider.#{method}: not implemented" + end + end + + module AssociationProviderIF + def method_missing method, *args + STDERR.puts "AssociationProvider.#{method}: not implemented" + end + end + module IndicationProviderIF + def method_missing method, *args + STDERR.puts "IndicationProvider.#{method}: not implemented" + end + end + + # now define MI classes, so they can be derived from + class InstanceProvider + include InstanceProviderIF + def initialize broker + @broker = broker + end + end + class MethodProvider + include MethodProviderIF + def initialize broker + @broker = broker + end + end + class AssociationProvider + include AssociationProviderIF + def initialize broker + @broker = broker + end + end + class IndicationProvider + include IndicationProviderIF + def initialize broker + @broker = broker + end + end + end Added: cmpi-bindings/trunk/swig/ruby/test/create.rb =================================================================== --- cmpi-bindings/trunk/swig/ruby/test/create.rb (rev 0) +++ cmpi-bindings/trunk/swig/ruby/test/create.rb 2008-10-02 13:31:15 UTC (rev 1061) @@ -0,0 +1,9 @@ +# +# provider creation +# + +$:.unshift("..") + +require 'cmpi_rbwbem_bindings' + +Cmpi::create_provider "TestProvider", nil Added: cmpi-bindings/trunk/swig/ruby/test/loading.rb =================================================================== --- cmpi-bindings/trunk/swig/ruby/test/loading.rb (rev 0) +++ cmpi-bindings/trunk/swig/ruby/test/loading.rb 2008-10-02 13:31:15 UTC (rev 1061) @@ -0,0 +1,4 @@ +# load cmpi_rbwbem_bindings.rb + +$:.unshift("..") +require 'cmpi_rbwbem_bindings' Modified: cmpi-bindings/trunk/test/ruby/test_atom_provider.rb =================================================================== --- cmpi-bindings/trunk/test/ruby/test_atom_provider.rb 2008-10-02 13:30:26 UTC (rev 1060) +++ cmpi-bindings/trunk/test/ruby/test_atom_provider.rb 2008-10-02 13:31:15 UTC (rev 1061) @@ -1,7 +1,7 @@ # # Ruby Provider for TestAtom # -# Instruments the CIM class TestAtom +# Instruments the CIM class Test_Atom # module Cmpi @@ -12,17 +12,30 @@ # Model an atom, For use with CIMOM and RbWbem Provider # - class TestAtomProvider - STDERR.puts "This is TestAtomProvider within test_atom_provider.rb" - + class TestAtomProvider < InstanceProvider + # create new instance -> check with .mof file def initialize broker - STDERR.puts "TestAtomProvider initialized!" - @broker = broker + super end + # use i.e. 'include MethodProviderIF' to implement multiple MIs def create_instance context, result, reference, newinst - STDERR.puts "TestAtomProvider.create_instance" + STDERR.puts "TestAtomProvider.create_instance: #{reference}" + result.return_objectpath reference + result.done end + + def get_instance context, result, objname, plist + + plist = plist.join(',') if plist.respond_to? :join + + STDERR.puts "TestAtomProvider.get_instance: #{objname}: #{plist}" + end + + def delete_instance context, result, objname + STDERR.puts "TestAtomProvider.delete_instance: #{objname}" + end + end -end \ No newline at end of file +end This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |