浏览 2477 次
锁定老帖子 主题:将QC的COM接口开放成Rest服务
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-11-16
最后修改:2009-11-16
QC平台的SDK以COM组件的形式对外开放,但这种开放方式只限于本机,如果需要进行远程访问QC开放的接口,需要对这套SDK包装一下,做成标准化的远程通讯协议或方式,比如:ice或者rest。 我的设计是将COM用Ruby包装一下,做成一个对外提供Rest方式接口的QCMetaServer服务器。 过程如下: 首先要访问QC的COM组件,建立全局连接,需要的话可以放到公用的池子里。Ruby做成服务发布的时候通常是按多进程方式发布的,所以一般一个进程一个连接就够了,不需要池子。 其次将所需的所有COM接口封装一下,变成Rest接口,这样可以和其它远程服务器进行通讯。 最后,注意在服务器终止之前释放连接,否则QC的COM会报错: QCMetaServer.rb:112: [BUG] Segmentation faultruby 1.8.6 (2008-08-11) [i386-mswin32]This application has requested the Runtime to terminate it in an unusual way.Please contact the application’s support team for more information. QCMetaServer.rb:112: [BUG] Segmentation fault ruby 1.8.6 (2008-08-11) [i386-mswin32] This application has requested the Runtime to terminate it in an unusual way. Please contact the application’s support team for more information. 这个错误对于公司内部少数人使用的情况下没有多大影响,但这种设计对生产环境上的应用来说是不允许的。 对QC接口二次开发之前,需要了解下QC SDK,相关资料请各位网上搜索,我这里资料有限,本人也是边看少而又少的资料,边猜测着开发的。 下面这个图大家引用的较多,这是QC COM中的SDK方法的树状结构图,绝大部分对象都是通过工厂方法生成的,这是规律。 代码如下: require 'rubygems' require 'activerecord' require 'win32ole' require 'pp' p "Global initializion." $qc = WIN32OLE.new("TDApiOle80.TDConnection") p "Loaded COM => TDApiOle80.TDConnection" $qc.InitConnectionEx("http://10.2.226.12/qcbin/"); p "QC connection init." $qc.ConnectProjectEx('ALISOFT_CRM','ALISOFT_CRM2006','cuizheng',''); p "QC project connection init." require 'sinatra/base' require 'coderay' class QCMeta < Sinatra::Base get '/' do h = {} h[:ProjectName] = $qc.ProjectName h[:ServerURL] = $qc.ServerURL h[:ServerTime] = $qc.ServerTime h[:ProjectProperties] = $qc.ProjectProperties h[:ServerName] = $qc.ServerName h.to_xml end get '/ole' do h = { "TDApiOle80.TDConnection<functional>" => $qc.ole_func_methods.map{|f|f.to_s}, "TDApiOle80.TDConnection<property(get)>" => $qc.ole_get_methods.map{|f|f.to_s}, "TDApiOle80.TDConnection<property(set)>" => $qc.ole_put_methods.map{|f|f.to_s} }.to_json params[:color].downcase == "true" ? CodeRay.scan(h,:json).div(:line_number => :tables) : h end get '/projects' do {:ProjectsList => $qc.ProjectsList}.to_xml end =begin <C#> int intSub = 286; SubjectNode nodSub = objTree.get_NodeById(intSub) as SubjectNode; TestFactory objTF = nodSub.TestFactory as TestFactory; lstList = objTF.NewList(""); foreach (Test objTest in lstList) { MessageBox.Show((string)objTest.Name); } =end #~ tm = $qc.TreeManager #~ nod = tm.get_NodeById(id) #~ nod.TestFactory.NewList("").each do |test| #~ pp test.Status #~ end =begin <VB> Dim BugFactory, BugList Set BugFactory = QCConnection.BugFactory Set BugList = BugFactory.NewList("") 'Get a list of all the defects. =end get "/bugs" do bf = $qc.BugFactory bflist = bf.NewList("") max = params[:max] || 100 i = 0 h = {} bflist.each do |bug| h[bug.ID] = { :Status => bug.Status, :AssignedTo => bug.AssignedTo, :DetectedBy => bug.DetectedBy, :Priority => bug.Priority, :Summary => bug.Summary } i >= max ? break : i+=1 end {:BUGS => h,:COUNT => bflist.Count}.to_xml end def self.run!(options={},&trap_handler) set options handler = detect_rack_handler handler_name = handler.name.gsub(/.*::/, '') puts "== Sinatra/#{Sinatra::VERSION} has taken the stage " + "on #{port} for #{environment} with backup from #{handler_name}" unless handler_name =~/cgi/i handler.run self, :Host => host, :Port => port do |server| trap(:INT) do trap_handler.call ## Use thins' hard #stop! if available, otherwise just #stop server.respond_to?(:stop!) ? server.stop! : server.stop puts "\n== Sinatra has ended his set (crowd applauds)" unless handler_name =~/cgi/i end set :running, true end rescue Errno::EADDRINUSE => e puts "== Someone is already performing on port #{port}!" end end QCMeta.run!(:host=>'0.0.0.0', :port => 4567){ begin $qc.DisconnectProject p "QCMeta disconnected to QC." $qc.ReleaseConnection p "QCMeta released to QC." p "QCMeta will shutdown." rescue => e p "QCMeta disconnect and release faile." p "But server still going to shutdown." p e.to end } 服务器启动后,访问如下几个url可得到相应的结果: http://localhost:4567/(QC的一些信息) 引用 <hash>
<ServerURL>http://10.2.226.12/qcbin</ServerURL> <ServerTime>2009/11/16 10:56:57</ServerTime> <ProjectProperties>#<WIN32OLE:0×2cd0404></ProjectProperties> <ServerName>http://10.2.226.12/qcbin/wcomsrv.dll</ServerName> <ProjectName>ALISOFT_CRM2006</ProjectName> </hash> http://localhost:4567/ole(下面是COM中所有方法和属性的列表。) 引用 {”TDApiOle80.TDConnection<property(get)>”=>
["Connected", "ProjectConnected", "ServerName", "ProjectName", "TestRepository", "UserName", "TestFactory", "BugFactory", "TestSetFactory", "UserGroupsList", "HostFactory", "VCS", "ProjectsList", "Command", "TreeManager", "ReqFactory", "ActionPermission", "DBType", "DBManager", "Customization", "Fields", "CommonSettings", "UserSettings", "HostGroupFactory", "UsersList", "Password", "ExtendedStorage", "DirectoryPath", "ChangeFactory", "MailConditions", "ServerTime", "TDSettings", "ProjectProperties", "DomainName", "TextParam", "TDParams", "UsingProgress", "CheckoutRepository", "ViewsRepository", "VcsDbRepository", "RunFactory", "ModuleVisible", "ProjectsListEx", "DomainsList", "Analysis", "VMRepository", "DBName", "Rules", "TestSetTreeManager", "AlertManager", "AllowReconnect", "KeepConnection", "IgnoreHtmlFormat", "ReportRole", "ComponentFactory", "ComponentFolderFactory", "ServerURL", "ProductInfo"], “TDApiOle80.TDConnection<property(set)>”=> ["UsingProgress", "AllowReconnect", "KeepConnection", "IgnoreHtmlFormat", "ClientType"], “TDApiOle80.TDConnection<functional>”=> ["QueryInterface", "AddRef", "Release", "GetTypeInfoCount", "GetTypeInfo", "GetIDsOfNames", "Invoke", "InitConnection", "ReleaseConnection", "ConnectProject", "DisconnectProject", "GetLicense", "SendMail", "ChangePassword", "PurgeRuns", "GetLicenseStatus", "InitConnectionEx", "ConnectProjectEx", "ConnectToVCSAs", "GetLicenses", "SynchronizeFollowUps", "GetTDVersion", "GetTypeInfoCount", "GetTypeInfo", "GetIDsOfNames", "Invoke"]} http://localhost:4567/projects(得到QC中项目列表,COM中的ProjectsList对象怎么使用还没有找到文档) 引用 <hash>
<ProjectsList>#<WIN32OLE:0×344f07c></ProjectsList> </hash> http://localhost:4567/bugs(显示当前项目的Bug信息,目前有乱码问题。通过max参数控制显示的数量) 引用 <hash>
<BUGS> <85> <Summary>²¿ÃÅÃèÊöΪ511¸ö×Ö·ûµÄ²¿ÃÅ£¬ÔÚ²¿ÃÅÐÅÏ¢µÄ²¿ÃÅÃèÊöÖÐÎÞ·¨ÏÔʾ</Summary> <AssignedTo>quake.hongwq</AssignedTo> <DetectedBy>snake.zhangw</DetectedBy> <Status>Closed</Status> <Priority></Priority> </85> <9> <Summary>²úÆ·ÐÅÏ¢ÏÔʾ²»ÍêÕû</Summary> <AssignedTo>morgan.zhul</AssignedTo> <DetectedBy>snake.zhangw</DetectedBy> <Status>Closed</Status> <Priority></Priority> </9> <47> <Summary>±¨¼Û´òÓ¡Ô¤ÀÀҳûÓдòÓ¡ºÍ·µ»Ø°´Å¥</Summary> <AssignedTo>morgan.zhul</AssignedTo> <DetectedBy>jack</DetectedBy> <Status>Closed</Status> <Priority></Priority> </47> <28> <Summary>ÊäÈë·Ç·¨Ò³Â룬³ö´í</Summary> <AssignedTo>quake.hongwq</AssignedTo> <DetectedBy>jack</DetectedBy> <Status>Closed</Status> <Priority></Priority> </28> <66> 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |