forum.bitel.ru http://forum.bitel.ru/ |
|
запрос SOAP через perl http://forum.bitel.ru/viewtopic.php?f=19&t=11088 |
Страница 1 из 2 |
Автор: | Darg [ 11 ноя 2015, 13:28 ] |
Заголовок сообщения: | запрос SOAP через perl |
Привет! Хочу через perl используя SOAP::Lite вызвать paymentUpdate, но пока что то не очень. Может кто делал уже и поделится кусочком кода? В примерах есть PHP, а вот Perl'а нет. |
Автор: | Darg [ 11 ноя 2015, 14:49 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
если смотреть в access_log, видны запросы [11/Nov/2015:11:47:11 +0300] 0.002 200 13950 "GET /bgbilling/executer/ru.bitel.bgbilling.kernel.contract.balance/PaymentService ?wsdl HTTP/1.1" wsdl=& [11/Nov/2015:11:47:11 +0300] 0.005 500 4508 "POST /bgbilling/executer/ru.bitel.bgbilling.kernel.contract.balance/PaymentService HTTP/1.1" [11/Nov/2015:11:47:11 +0300] 0.040 500 4508 "POST /bgbilling/executer/ru.bitel.bgbilling.kernel.contract.balance/PaymentService HTTP/1.1" и ошибок нет, но и платежей в BG нет. Разработчики почему так ? |
Автор: | Darg [ 11 ноя 2015, 15:39 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
а вообще есть другой метод занести платеж в bg используя perl ? |
Автор: | skn [ 11 ноя 2015, 15:40 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
не знаю не пробовали из перла попробуйте в перле включить отладку и посмотрите, что он отправляет и что получает в ответ |
Автор: | stark [ 11 ноя 2015, 17:07 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
Darg писал(а): Привет! Хочу через perl используя SOAP::Lite вызвать paymentUpdate, но пока что то не очень. Может кто делал уже и поделится кусочком кода? В примерах есть PHP, а вот Perl'а нет. а что не очень ? со стороны сервера ошибок нет в логах? ответ приходит ? |
Автор: | Darg [ 11 ноя 2015, 18:46 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
my $pay = PaymentUpdate->new(); $pay::payment = Payment->new(); $pay::payment::id = -1; $pay::payment::comment = "$comment"; $pay::payment::contractId = $contract_id + 0; $pay::payment::sum = 0 + $sum; $pay::payment::summa = 0 + $sum; $pay::payment::typeId = 3; $pay::payment::userId = 0; $pay::payment::date = $now; $pay::payment::timeChange = $now; $wsdl = "http://xxxxxx:8080/bgbilling/executer/ru.bitel.bgbilling.kernel.contract.balance/PaymentService?wsdl"; $authoriz = 'Basic '.encode_base64('login:password');<-> $client = SOAP::Lite->new(service=>$wsdl.'?wsdl'); $client->service($wsdl); $client->proxy($wsdl); $client->default_ns("http://common.balance.contract.kernel.bgbilling.bitel.ru/"); $client->outputxml('true'); $client->transport->http_request->headers->push_header('Authorization' => $authoriz ); print $client->call('paymentUpdate',$pay); это пока фрагмент кода, где формируется запрос. На данной стадии, авторизацию прохожу как я понял, но возникает проблема при вызове метода. Скорей всего как то не правильно передаю или формирую класс payment. В итоге ошибка: S:Serverru.bitel.bgbilling.kernel.container.security.server.ServiceAction.isCoincide@60![8,15]: 'payment.getId() > 0;' attempting to call method on null |
Автор: | Darg [ 11 ноя 2015, 18:50 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
а в server.out 2015 3:41:31 PM com.sun.xml.ws.server.sei.EndpointMethodHandler invoke SEVERE: ru.bitel.bgbilling.kernel.container.security.server.ServiceAction.isCoincide@60![8,15]: 'payment.getId() > 0;' attempting to call metho d on null org.apache.commons.jexl2.JexlException: ru.bitel.bgbilling.kernel.container.security.server.ServiceAction.isCoincide@60![8,15]: 'payment.getId( ) > 0;' attempting to call method on null at org.apache.commons.jexl2.Interpreter.visit(Interpreter.java:1095) at org.apache.commons.jexl2.parser.ASTMethodNode.jjtAccept(ASTMethodNode.java:18) at org.apache.commons.jexl2.Interpreter.visit(Interpreter.java:1317) at org.apache.commons.jexl2.parser.ASTReference.jjtAccept(ASTReference.java:18) at org.apache.commons.jexl2.Interpreter.visit(Interpreter.java:793) at org.apache.commons.jexl2.parser.ASTGTNode.jjtAccept(ASTGTNode.java:18) at org.apache.commons.jexl2.Interpreter.interpret(Interpreter.java:232) at org.apache.commons.jexl2.ExpressionImpl.evaluate(ExpressionImpl.java:65) at ru.bitel.bgbilling.kernel.container.security.server.ServiceAction.isCoincide(ServiceAction.java:60) at ru.bitel.bgbilling.kernel.container.security.server.ModuleInfo.findAction(ModuleInfo.java:51) at ru.bitel.bgbilling.kernel.container.security.server.PermissionChecker.findAction(PermissionChecker.java:352) at ru.bitel.bgbilling.kernel.container.ws.server.JaxWsHandler.invoke(JaxWsHandler.java:277) at ru.bitel.bgbilling.kernel.container.ws.server.AbstractJaxWsHandler$ServiceInstanceResolver$1.invoke(AbstractJaxWsHandler.java:335) at com.sun.xml.ws.server.InvokerTube$2.invoke(InvokerTube.java:150) at com.sun.xml.ws.server.sei.EndpointMethodHandler.invoke(EndpointMethodHandler.java:261) at com.sun.xml.ws.server.sei.SEIInvokerTube.processRequest(SEIInvokerTube.java:100) at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:641) at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:600) at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:585) at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:482) at com.sun.xml.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:314) at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:608) at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:259) at com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAdapter.java:162) at ru.bitel.bgbilling.kernel.container.ws.server.JaxWSAdapter.handle(JaxWSAdapter.java:288) at bitel.billing.server.Executer.doPost(Unknown Source) at javax.servlet.http.HttpServlet.service(HttpServlet.java:647) at javax.servlet.http.HttpServlet.service(HttpServlet.java:728) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) |
Автор: | skn [ 11 ноя 2015, 20:44 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
а откуда вы взяли объект Код: my $pay = PaymentUpdate->new();
|
Автор: | Darg [ 11 ноя 2015, 20:48 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
это два самопальных класса package Payment; use strict; our $id = -1; our $comment = ""; our $contractId = 0; our $sum = 0; our $summa = 0; our $typeId = 0; our $userId = 0; our $date = ""; our $timeChange = ""; sub new { my $class = shift; my $self = bless {} , $class; return $self } 1; package paymentUpdate; use strict; our $payment; our $distribution; sub new { my $class = shift; my $self = bless {} , $class; return $self } 1; |
Автор: | Amir [ 11 ноя 2015, 20:54 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
Цитата: print $client->call('paymentUpdate',$pay); А агрументы не должны быть именованными?
|
Автор: | Akhmat [ 11 ноя 2015, 21:02 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
Код: use LWP::UserAgent;
$armuser = "user" ; $armpass = "pswd" ; $URL = "http://127.0.0.1:8080/bgbilling/executer?user=$armuser&pswd=$armpass&module=contract" ; ... eval{ $uURL = "$URL&action=UpdateContractPayment&date=$datepaym&pt=$paytypeID&cid=$cid&comment=testpay&summa=$sum&id=new" ; my $req = HTTP::Request->new( "GET", $uURL, $hdrs, $request ); my $ua = LWP::UserAgent->new; my $resp = $ua->request($req); if ($resp->is_success ) { my($content, $status) ; $content = $resp -> content ; if ( ($status ) = $content =~ /status=\"(.+)\"/ ){ if ( $status eq "ok" ) { print "Счёт клиента $title пополнен на $sum рублей\n" ; }else { print "Невозможно пополнить счёт для $title.Ответ сервера $content\n" ; } }else { print "Невозможно пополнить счёт для $title.Произошла ошибка\n" ; } } }; print "DIED(main): $@\n" if ($@) ; |
Автор: | stark [ 11 ноя 2015, 21:05 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
Darg писал(а): это два самопальных класса package Payment; use strict; our $id = -1; our $comment = ""; our $contractId = 0; our $sum = 0; our $summa = 0; our $typeId = 0; our $userId = 0; our $date = ""; our $timeChange = ""; sub new { my $class = shift; my $self = bless {} , $class; return $self } 1; package paymentUpdate; use strict; our $payment; our $distribution; sub new { my $class = shift; my $self = bless {} , $class; return $self } 1; ну вообще это неправильный путь при работе с web-сервисами . вот тут есть статейка про это : http://habrahabr.ru/post/75248/ Но там пример на питон, но общий подход хорошо описан. Если хотите вручную, то может быть вам стоит json rpc попробовать наш . |
Автор: | Darg [ 11 ноя 2015, 21:08 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
Amir насчет именованных аргументов, как только я не пробовал,перебрал кучу вариантов, уже фантазия на исходе, что ты имеешь ввиду? |
Автор: | stark [ 11 ноя 2015, 21:09 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
вот тут есть примеры какие-то : http://guide.soaplite.com/ запрос клиента Код: 5.d. client (exchange.pl) #!perl -w use SOAP::Lite; # GLUE http://www.themindelectric.com/ (running on XMethods.net) my $s = SOAP::Lite -> uri('urn:xmethods-CurrencyExchange') -> proxy('http://services.xmethods.net/soap'); my $r = $s->getRate(SOAP::Data->name(country1 => 'England'), SOAP::Data->name(country2 => 'Japan')) ->result; print "Currency rate for England/Japan is $r\n"; результат вывода Код: 5.d. result
Currency rate for England/Japan is 175.4608 |
Автор: | Darg [ 11 ноя 2015, 21:10 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
Akhmat, спасибо большое попробую и это вариант! stark, сейчас гляну ка вашу сылочку, спасибо! |
Автор: | stark [ 11 ноя 2015, 21:15 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
Darg писал(а): Akhmat, спасибо большое попробую и это вариант! Это не soap ![]() |
Автор: | Amir [ 11 ноя 2015, 21:16 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
http://stackoverflow.com/questions/6797 ... rver-issue Цитата: I was having the same problem. I made it work with the following two changes:
Name your arguments as in the XSD (http://localhost:8080/tomcat/calculator?xsd=1) Don't use the default namespace, but a namespace prefix for the SOAP method (ns() method). Example code: my $soap = SOAP::Lite -> proxy('http://localhost:8080/tomcat/calculator') -> ns ('http://operation.calculator/'); my $response = $soap->call('add', SOAP::Data->name( arg0 => 'Peter Pan')); |
Автор: | Akhmat [ 11 ноя 2015, 21:17 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
да. почему старые? планируется их убирать? |
Автор: | stark [ 11 ноя 2015, 21:19 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
Akhmat писал(а): да. почему старые? планируется их убирать? Они потихоньку заменяются web-сервисами и перестают поддерживаться. С 6.1 уже не стоит например с балансом( платежи , расходы) работать через Action-ы. |
Автор: | Akhmat [ 11 ноя 2015, 21:23 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
плохо. все расширения мои работают в основном так. почему веб сервисы? когдато смотрел их, хрень громоздкая показалось. upd в плане чем лучше они чем старый вариант? |
Автор: | Amir [ 11 ноя 2015, 21:32 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
Цитата: плохо. все расширения мои работают в основном так. почему веб сервисы? когдато смотрел их, хрень громоздкая показалось. upd в плане чем лучше они чем старый вариант? stark писал(а): вот тут есть статейка про это : Ну и плюс через JSON-RPC можно вызывать, если SOAP не нравится.
http://habrahabr.ru/post/75248/ |
Автор: | stark [ 11 ноя 2015, 21:35 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
Akhmat писал(а): плохо. все расширения мои работают в основном так. почему веб сервисы? когдато смотрел их, хрень громоздкая показалось. upd в плане чем лучше они чем старый вариант? Нам разрабатывать так удобнее и быстрее . Теоретически web-сервисы позволяют и вам жизнь упростить . Для java-разработчика во всяком случае проще работать в коде вызывая метод явно, не думая о том, какие параметры передать. Т.е я просто пишу точку после объекта определенно типа и он сразу мне предлагает все его методы и там видно какие атрибуты и каких типов в него надо передавать. Мне не нужно даже лезть куда-то в доку, чтобы узнать что передать. Я не знаю как в перле, не пробовал из него, скорее всего там все равно надо изучать wsdl чтобы узнать список аргументов и их тип. |
Автор: | Amir [ 11 ноя 2015, 21:37 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
Мне кажется нужно попробовать имена аргументов указать, раз почти до вызова метода доходит, но payment==null. В доке еще такой пример есть. Код: use SOAP::Lite; Можно попробовать посмотреть через какой-нибудь http-proxy, что формирует perl и что формирует клиент биллинга.
my $soap = SOAP::Lite->new( proxy => 'http://localhost:81/soap-wsdl-test/helloworld.pl'); $soap->default_ns('urn:HelloWorld'); my $som = $soap->call('sayHello', SOAP::Data->name('name')->value('Kutter'), SOAP::Data->name('givenName')->value('Martin') ); die $som->faultstring if ($som->fault); print $som->result, "\n"; |
Автор: | Darg [ 11 ноя 2015, 21:39 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
Amir писал(а): http://stackoverflow.com/questions/6797030/perl-client-to-jax-ws-java-server-issue Цитата: I was having the same problem. I made it work with the following two changes: Name your arguments as in the XSD (http://localhost:8080/tomcat/calculator?xsd=1) Don't use the default namespace, but a namespace prefix for the SOAP method (ns() method). Example code: my $soap = SOAP::Lite -> proxy('http://localhost:8080/tomcat/calculator') -> ns ('http://operation.calculator/'); my $response = $soap->call('add', SOAP::Data->name( arg0 => 'Peter Pan')); В этом как и во многих других примерах , передаются обычные строковые параметры. А ведь PaymentUpdate требует paymentUpdate который в свою очередь состоит из payment и этот в свою очередь из своих аттрибутов. Как передать такой аргумент ? пробовал $v={'id'=>'-1','userId'=>'0','contractId'=>$contract_id,typeId'=>'3','date'=>$now,'comment'=>"fdgdf",'sum'=>$sum,'timeChange'=>$now}; $var = {'paymentUpdate'=>$v} $client->call('paymentUpdate',$var); не работает пробовал $client->call('paymentUpdate',SOAP::Data->name('paymentUpdate'=> SOAP::Data->name('id'=>'-1','userId'=>'0','contractId'=>$contract_id, 'typeId'=>'3','date'=>$now,'comment'=>"fdgdf",'sum'=>$sum,'timeChange'=>$now))); тоже не работает |
Автор: | Amir [ 11 ноя 2015, 21:44 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
Я плохо знаю perl, могу написать что-нибудь смешное, но если так: Код: $client->call('paymentUpdate', или такSOAP::Data->name('payment')->value( $pay ) ); Код: $client->call('paymentUpdate', ?
SOAP::Data->name( payment => $pay ) ); |
Автор: | stark [ 11 ноя 2015, 21:50 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
Darg писал(а): Amir писал(а): http://stackoverflow.com/questions/6797030/perl-client-to-jax-ws-java-server-issue Цитата: I was having the same problem. I made it work with the following two changes: Name your arguments as in the XSD (http://localhost:8080/tomcat/calculator?xsd=1) Don't use the default namespace, but a namespace prefix for the SOAP method (ns() method). Example code: my $soap = SOAP::Lite -> proxy('http://localhost:8080/tomcat/calculator') -> ns ('http://operation.calculator/'); my $response = $soap->call('add', SOAP::Data->name( arg0 => 'Peter Pan')); В этом как и во многих других примерах , передаются обычные строковые параметры. А ведь PaymentUpdate требует paymentUpdate который в свою очередь состоит из payment и этот в свою очередь из своих аттрибутов. Как передать такой аргумент ? пробовал $v={'id'=>'-1','userId'=>'0','contractId'=>$contract_id,typeId'=>'3','date'=>$now,'comment'=>"fdgdf",'sum'=>$sum,'timeChange'=>$now}; $var = {'paymentUpdate'=>$v} $client->call('paymentUpdate',$var); не работает пробовал $client->call('paymentUpdate',SOAP::Data->name('paymentUpdate'=> SOAP::Data->name('id'=>'-1','userId'=>'0','contractId'=>$contract_id, 'typeId'=>'3','date'=>$now,'comment'=>"fdgdf",'sum'=>$sum,'timeChange'=>$now))); тоже не работает может быть это поможет Цитата: Handling LoLs (List of Lists, Structs, Objects, or something else) Processing of complex data structures isn't different in any aspect from usual processing in your programming language. General rule is simple: 'Treat the result of SOAP call as variable of specified type'. Next example shows service that works with array of structs (strictly speaking, Perl has no structs. Structs are often emulated with hashes, and that is exactly what is happening here): 8.a. client (lol_serv.pl) #!perl -w use SOAP::Lite; my $result = SOAP::Lite -> uri('urn:xmethodsServicesManager') -> proxy('http://www.xmethods.net/soap/servlet/rpcrouter') -> getAllSOAPServices(); if ($result->fault) { print $result->faultcode, " ", $result->faultstring, "\n"; } else { # reference to array of structs is returned my @listings = @{$result->result}; # @listings is the array of structs foreach my $listing (@listings) { print "-----------------------------------------\n"; # print description for every listing foreach my $key (keys %{$listing}) { print $key, ": ", $listing->{$key} || '', "\n"; } } } Exactly the same thing is true about structs inside of other structs, list of objects, objects that have lists inside, etc. 'What you return on server side is what you get on client side, and let me know if you get something else.' (Ok, not always. You MAY get a blessed array even when you return a simple array on the other side and you MAY get a blessed hash when you return a simple one, but it won't change anything in your code, just access it as you usually do). Т.е в перле объекты это хэши. Попробуйте создать хеш вместо объекта. |
Автор: | Akhmat [ 11 ноя 2015, 21:51 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
Спасибо. Ок, попробую снова соап) |
Автор: | stark [ 11 ноя 2015, 21:52 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
и чуть выше там еще про wsdl есть: Цитата: Access with service description (WSDL)
Although support for WSDL 1.1 is limited in SOAP::Lite for now (service description may work in some cases, but hasn't been extensively tested), you can access services that don't have complex types in their description: 6.a. client (wsdl_oo.pl) #!perl -w use SOAP::Lite; print SOAP::Lite -> service('http://www.xmethods.net/sd/StockQuoteService.wsdl') -> getQuote('MSFT'); |
Автор: | Darg [ 11 ноя 2015, 22:17 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
через service это практически тоже самое что и call, пробую хэшами пока безуспешно |
Автор: | Darg [ 12 ноя 2015, 20:32 ] |
Заголовок сообщения: | Re: запрос SOAP через perl |
Чудо произошло! Смог все таки решить эту задачку с долбанными perl+soap. Вот фрагмент, чтоб больше никто не парился, может кому то понадобится: $wsdl = "http://xxxxxxxxxxxxxx:8080/bgbilling/executer/ru.bitel.bgbilling.kernel.contract.balance/PaymentService?wsdl"; @comment = ("<comment>$comment</comment>"); $authoriz = 'Basic '.encode_base64('login:password'); #$SOAP::Constants::PREFIX_ENV = 'SOAP-ENV'; #$SOAP::Constants::PREFIX_ENC = "SOAP-ENC"; $client = SOAP::Lite->new(service=>$wsdl); $client->proxy($wsdl); $client->ns("http://common.balance.contract.kernel.bgbilling.bitel.ru/","ns1"); $client->outputxml('true'); $client->transport->http_request->headers->push_header('Authorization' => $authoriz ); $soap = $client->service($wsdl.'?wsdl'); my $pm = SOAP::Data->new(name=>"payment"); $pm->type("ts:payment"); $pm->attr({ id => "$id", contractId=>"$cid", date=>"$dt", sum=>"$sum", summa=>"$sum", typeId=>"3", userId=>"0"}); $pm->value(@comment); print $client->call('paymentUpdate',$pm); |
Страница 1 из 2 | Часовой пояс: UTC + 5 часов [ Летнее время ] |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |