Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Ruby: Общие вопросы > xml-rpc с граблями и trac


Автор: bilbobagginz 22.8.2010, 13:38
привет. 
ситуация такова (все в интeрнете), есть 
  • trac сайт
  • в wiki 2 странички: builds, builds2
  • hudson, который в данном случае создает несколько (11) файлов.
  • эти файлы вручную закачиваются как аттачменты на данные 2 страницы, и обновляется табличка ссылок, с которой файлы скачиваются.
  • связь с сервером защищена SSL + user certificate (X.509) + пользователь + пароль.
процесс с момента законченного билда занимает ~ 10-30 минут закачки, проверки корректности и т.д.

задача:
автоматизировать эту процедуру, тем самым экономить эти минуты на билд. в день может быть несколько.
присмотрелся на XML-RPC. разбил на под-задачи, т.е. из руби скрипта:
  • 1. соединиться с сервантом
  • 2. записать страничку вики
  • 3. загрузить файл на созданную страничку.
процесс шел так:
1. накопал trac4r.
2. понял, что стандартный xmlrpc клиент не поддерживает работу с SSL+certificates
3. понял что проблема в конфигурации объекта. создал патчи (приатачил) для xmlrpc/client.rb, и для trac4r/lib/query.rb, trac4r/trac4r.rb

Прошел легко пункты 1, 2.
на третьем завис.

код клиента  подключения (опустил данные аутентификации) тут:
Код

require 'rubygems'
require 'uri'
require 'net/https'
require 'openssl'
require 'trac4r'
require 'base64'

vars = YAML::loadfile(ENV['HOME'] + "/.credentials/creds.yml")

pkcs = OpenSSL::PKCS12.new(File.open(vars['certname']),vars['certpass'])
cert = pkcs.certificate
key = pkcs.key

url = vars['tracserver']
user = vars['tracuser']
pass = vars['tracpass']

trg_page = vars['pagename1']
file_to_attach = vars['srcfname']

begin
trac = Trac.new(url, user, pass, vars['ca_cert'], cert, key)
rescue Exception => e
    puts "e.message: #{e.message}, e.backtrace: #{e.backtrace}"
end

result = trac.wiki.get_raw trg_page

new_out = " = New Title! =\n"
new_out += "I am kukuriku!"

trac.wiki.put trg_page,new_out

puts "result:"
result = trac.wiki.get_raw trg_page
puts result
gets
# до сих пор - РАБОТАЕТ!
fh = File.open(file_to_attach)
fdata = fh.read
enc_data = [fdata].pack("m")

comment = vars['filecomment']
name = vars['filename']
trac.wiki.put_attachment(trg_page, name, comment, enc_data, true)


Получил:
Код

/usr/lib/ruby/gems/1.8/gems/trac4r-1.2.3/lib/trac4r/query.rb:60:in `query': 
Wrong content-type (received 'application/xml' but expected 'text/xml') when trying 
URL http://server.domain:443/project/login/xmlrpc 
and method wiki.putAttachmentEx(TestXML.make-diskimage.sh.nice script to create disk image 
on Mac.IyEvYmluL2Jhc2gKIyBDcmVhdGUgYSByZWFkLW9ubHkgZGlzayBpbWFnZSBv (Trac::TracException)
<и тут дамп файла в кодировке Base64>


я не совсем понимаю где я устанавливаю (и я ли)  это content-type.



помогите старому хоббиту пинком в нужное направление.

Автор: source777 22.8.2010, 16:45
В XMLRPC::Client#do_rpc есть проверка следующего вида:
Код

      ct = parse_content_type(resp["Content-Type"]).first
      if ct != "text/xml"
        if ct == "text/html"
          raise "Wrong content-type (received '#{ct}' but expected 'text/xml'): \n#{data}"
        else
          raise "Wrong content-type (received '#{ct}' but expected 'text/xml')" # твой вариант
        end
      end


А Trac по ходу дела возвращает данные с Content-Type = application/xml
Так что придётся тебе через class_eval переопределить вышеуказанный метод, чтобы он application/xml тоже переваривал.

P.S. А вообще совет на будущее, как искать причину исключения:
1) Смотришь что находится по указанному адресу: /usr/lib/ruby/gems/1.8/gems/trac4r-1.2.3/lib/trac4r/query.rb:60:in `query'
А там глобальный перехват исключений:
Код

      begin
        return @connection.call(command,*args)
      rescue => e
        raise TracException.new(e.message,@host,@port,@path,command,args,e)
      end


2) Оставляешь только 
return @connection.call(command,*args) 
и сразу видишь где на самом деле произошла ошибка. Хоть и не комильфо, но зато помогает, когда некоторые умельцы stack trace прячут.

Автор: bilbobagginz 22.8.2010, 20:10
я обратил внимание, что есть очень немало реализаций XMLRPC клиента.
интересно почему выбор разработчика trac4r пал именно на эту реализацию, и еще интересно почему именно эта реализация находится в дистрибутиве ruby :(


Цитата(source777 @  22.8.2010,  15:45 Найти цитируемый пост)
Так что придётся тебе через class_eval переопределить вышеуказанный метод, чтобы он application/xml тоже переваривал

a почему бы не расширить класс Client ?
есть какие-то "против" ?

Автор: source777 22.8.2010, 23:02
Цитата(bilbobagginz @  22.8.2010,  20:10 Найти цитируемый пост)
интересно почему выбор разработчика trac4r пал именно на эту реализацию

вероятно, потому что она входит в стандартную библиотеку Ruby

Цитата(bilbobagginz @  22.8.2010,  20:10 Найти цитируемый пост)
и еще интересно почему именно эта реализация находится в дистрибутиве ruby :(

Спроси что полегче... В стандартную библиотеку вообще входит достаточно много отстойных классов, взять тот же Net::HTTP или REXML. Почему так получилось хз, видимо исторически сложилось... Благо отказаться от использования этих классов ничего не стоит, т.к. есть масса достойных альтернатив.


Цитата(bilbobagginz @  22.8.2010,  20:10 Найти цитируемый пост)
a почему бы не расширить класс Client ?

Что ты подразумеваешь под "расширить"?




Автор: bilbobagginz 23.8.2010, 08:55
Цитата(source777 @  22.8.2010,  22:02 Найти цитируемый пост)
Что ты подразумеваешь под "расширить"?

я о реализации: когда вижу какой-то eval у меня ушки на макушке, т.к. стараюсь им пользоваться редко и с богобоязнью.
если на настоящий момент единственный контент, поддерживаемый trac4r - "text/xml", то надеюсь можно сделать и без eval-oв.
как начинающий, для мя метапрограммирование пока тонкое искусство...

акромя того, это как добавить в только свои instances какую-то методу, а другим - не дам. жадно smile
я как-раз за то, чтобы мои добавки кода проревизили и влили в стабильную ветку.
и мне хорошо, и людям. авось откликнется.


Автор: source777 23.8.2010, 12:55
Цитата(bilbobagginz @  23.8.2010,  08:55 Найти цитируемый пост)
я как-раз за то, чтобы мои добавки кода проревизили и влили в стабильную ветку.

Это хороший подход, но в данном случае придётся ждать Ruby 1.9.3, чтобы насладиться твоим патчем, если его примут. Или ты trac4r решил на другой XML-RPC клиент перевести? В общем я запутался, что ты собрался делать...  smile 

Автор: bilbobagginz 23.8.2010, 20:41
khm... 
проблема оказалась меж клавиатурой и стулом.
сервер накрывался, если получал некорректно упакованные данные.

нужно было посылать в функцию putAttachmentEx 
объект типа XMLRPC::Base64. его создание было тупо:
Код

fh = File.open(filename, "rb")
d = fh.read
data = XMLRPC::Base64.new(d)

меня вдуплила инструкция, в которой написано было "конвертировать в Base64", и я принял его как кодировку, а не тип объекта.
в общем разобрался!

теперь мой хадсон шлет билды на вику трэка, и оповещает о них по джабберу/почте к делу относящихся. smile

Автор: source777 23.8.2010, 22:59
Ну что ж, поздравляю. Оказывается надо было просто заглянуть в логи Trac'a  smile 

Автор: bilbobagginz 23.8.2010, 23:24
smile нет, этого не было достаточно, т.к. я не догнал, что за структура данных там использовалась.
пообщался по irc, там один питонец меня направил, сказав, что видимо я не загрузил в правильную структуру на клиенте. 
все доработал скрипт работает как часы, табличку со ссылками заполняет. прикольно smile
надо кинуть куда-то скрипт на github

Автор: source777 24.8.2010, 14:38
Цитата(bilbobagginz @  23.8.2010,  23:24 Найти цитируемый пост)
надо кинуть куда-то скрипт на github

http://gist.github.com/

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)