Проблемы при создании проблемы в JIRA с пользовательскими полями в Soap Lite и perl
Я бьюсь головой о мыльный API следующим кодом. Моя цель - создать заявку с настраиваемыми полями. Если вы закомментируете часть пользовательского поля, этот код работает нормально. Есть идеи о том, что происходит?
Код
my $soap = SOAP::Lite->service($wsdl);
my $token = $soap->login($_jira_user,$_jira_pass);
my $customFields = [
{'customFieldId' => $_cf_map{'severity'},'values' => [SOAP::Data->type('string', $severity)]},
{'customFieldId' => $_cf_map{'outage_start'}, 'values' => [SOAP::Data->type('string', $start)]},
{'customFieldId' => $_cf_map{'no_auto_close'}, 'values' => [SOAP::Data->type('string', $no_auto_close == 1 ? 'Yes': 'No')]},
{'customFieldId' => $_cf_map{'nco_serials'}, 'values' => [SOAP::Data->type('string', $serial_string)]},
{'customFieldId' => $_cf_map{'services'}, 'values' => \@services},
];
my $remoteIssueHash = {
'project' => SOAP::Data->type('string' => $_projectkey),
'type' => SOAP::Data->type('string' => $_issuetype),
'summary' => SOAP::Data->type('string' => $summary),
'reporter' => SOAP::Data->type('string' => $user),
'assignee' => SOAP::Data->type('string' => $user),
'customFieldValues' => $customFields,
};
my $remote_issue = $soap->call('createIssue', $token, $remoteIssueHash);
print Dumper [$remote_issue->faultcode(), $remote_issue->faultstring(), $soap->transport()->status(), $remote_issue->result(), $remote_issue ]
exit();
Выход
$VAR1 = [
'soapenv:Server.userException',
'org.xml.sax.SAXException: No deserializer for {http://www.w3.org/2001/XMLSchema}anyType',
'500 Internal Server Error',
#big soap object
]
XML отправлено
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:tns2="http://exception.rpc.jira.atlassian.com" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:namesp1="http://soap.rpc.jira.atlassian.com" xmlns:apachesoap="http://xml.apache.org/xml-soap" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns1="http://beans.soap.rpc.jira.atlassian.com" xmlns:impl="http://jira.nyc.hcmny.com:8080/rpc/soap/jirasoapservice-v2" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<namesp1:createIssue>
<c-gensym6 xsi:type="xsd:string">Y6DQd1k2BL</c-gensym6>
<c-gensym8>
<assignee xsi:type="xsd:string">fgulotta</assignee>
<customFieldValues soapenc:arrayType="xsd:anyType[5]" xsi:type="soapenc:Array">
<item>
<customFieldId xsi:type="xsd:string">customfield_10094</customFieldId>
<values soapenc:arrayType="xsd:string[1]" xsi:type="soapenc:Array">
<item xsi:type="xsd:string">4</item>
</values>
<key xsi:type="xsd:string" />
</item>
<item>
<customFieldId xsi:type="xsd:string">customfield_10084</customFieldId>
<values soapenc:arrayType="xsd:string[1]" xsi:type="soapenc:Array">
<item xsi:type="xsd:string">29/Jul/11 05:46 PM</item>
</values>
<key xsi:type="xsd:string" />
</item>
<item>
<customFieldId xsi:type="xsd:string">customfield_10100</customFieldId>
<values soapenc:arrayType="xsd:string[1]" xsi:type="soapenc:Array">
<item xsi:type="xsd:string">Yes</item>
</values>
<key xsi:type="xsd:string" />
</item>
<item>
<customFieldId xsi:type="xsd:string">customfield_10093</customFieldId>
<values soapenc:arrayType="xsd:string[1]" xsi:type="soapenc:Array">
<item xsi:type="xsd:string" />
</values>
<key xsi:type="xsd:string" />
</item>
<item>
<customFieldId xsi:type="xsd:string">customfield_10080</customFieldId>
<values soapenc:arrayType="xsd:string[1]" xsi:type="soapenc:Array">
<item xsi:type="xsd:string">intranet</item>
</values>
<key xsi:type="xsd:string" />
</item>
</customFieldValues>
<summary xsi:type="xsd:string">This is a test ticket.</summary>
<project xsi:type="xsd:string">MON</project>
<type xsi:type="xsd:string">31</type>
<reporter xsi:type="xsd:string">fgulotta</reporter>
</c-gensym8>
</namesp1:createIssue>
</soap:Body>
</soap:Envelope>
XML ПОЛУЧЕНО
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server.userException</faultcode>
<faultstring>org.xml.sax.SAXException: No deserializer for {http://www.w3.org/2001/XMLSchema}anyType</faultstring>
<detail>
<faultData xsi:type="ns1:SAXException" xmlns:ns1="http://sax.xml.org">
<exception xsi:type="ns2:Exception" xsi:nil="true" xmlns:ns2="http://lang.java"/>
<message xsi:type="xsd:string">No deserializer for {http://www.w3.org/2001/XMLSchema}anyType</message>
</faultData>
<ns3:hostname xmlns:ns3="http://xml.apache.org/axis/">deputy.811t.hcmny.com</ns3:hostname>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
Обновлено Исправлены имена полей и помещены значения в строковые массивы, но все еще есть проблемы.
2-е обновление Я нашел некоторый код Java, который работает против службы мыла, и провел свои тесты против этого. Затем я использовал wireshark, чтобы понюхать xml. Игнорирование multirefs - это очень похожая структура, но я не совсем уверен, как моделировать его с помощью Soap::Lite.
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:createIssue soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://soap.rpc.jira.atlassian.com">
<in0 xsi:type="xsd:string">B2P69v5NrS</in0>
<in1 href="#id0"/>
</ns1:createIssue>
<multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:RemoteIssue" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="http://beans.soap.rpc.jira.atlassian.com">
<id xsi:type="xsd:string" xsi:nil="true"/>
<affectsVersions xsi:type="ns2:RemoteVersion" xsi:nil="true"/>
<assignee xsi:type="xsd:string">fgulotta</assignee>
<attachmentNames xsi:type="xsd:string" xsi:nil="true"/>
<components xsi:type="ns2:RemoteComponent" xsi:nil="true"/>
<created xsi:type="xsd:dateTime" xsi:nil="true"/>
<customFieldValues soapenc:arrayType="ns2:RemoteCustomFieldValue[3]" xsi:type="soapenc:Array">
<customFieldValues href="#id1"/>
<customFieldValues href="#id2"/>
<customFieldValues href="#id3"/>
</customFieldValues>
<description xsi:type="xsd:string" xsi:nil="true"/>
<duedate xsi:type="xsd:dateTime" xsi:nil="true"/>
<environment xsi:type="xsd:string" xsi:nil="true"/>
<fixVersions xsi:type="ns2:RemoteVersion" xsi:nil="true"/>
<key xsi:type="xsd:string" xsi:nil="true"/>
<priority xsi:type="xsd:string" xsi:nil="true"/>
<project xsi:type="xsd:string">MON</project>
<reporter xsi:type="xsd:string">fgulotta</reporter>
<resolution xsi:type="xsd:string" xsi:nil="true"/>
<status xsi:type="xsd:string" xsi:nil="true"/>
<summary xsi:type="xsd:string">This is a test ticket.</summary>
<type xsi:type="xsd:string">31</type>
<updated xsi:type="xsd:dateTime" xsi:nil="true"/>
<votes xsi:type="xsd:long" xsi:nil="true"/>
</multiRef>
<multiRef id="id2" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns3:RemoteCustomFieldValue" xmlns:ns3="http://beans.soap.rpc.jira.atlassian.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<customfieldId xsi:type="xsd:string">customfield_10094</customfieldId>
<key xsi:type="xsd:string" xsi:nil="true"/>
<values soapenc:arrayType="xsd:string[1]" xsi:type="soapenc:Array">
<values xsi:type="xsd:string">4</values>
</values>
</multiRef>
<multiRef id="id1" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns4:RemoteCustomFieldValue" xmlns:ns4="http://beans.soap.rpc.jira.atlassian.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<customfieldId xsi:type="xsd:string">customfield_10084</customfieldId>
<key xsi:type="xsd:string" xsi:nil="true"/>
<values soapenc:arrayType="xsd:string[1]" xsi:type="soapenc:Array">
<values xsi:type="xsd:string">27/Jul/11 02:21 PM</values>
</values>
</multiRef>
<multiRef id="id3" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns5:RemoteCustomFieldValue" xmlns:ns5="http://beans.soap.rpc.jira.atlassian.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<customfieldId xsi:type="xsd:string">customfield_10100</customfieldId>
<key xsi:type="xsd:string" xsi:nil="true"/>
<values soapenc:arrayType="xsd:string[1]" xsi:type="soapenc:Array">
<values xsi:type="xsd:string">Yes</values>
</values>
</multiRef>
</soapenv:Body>
</soapenv:Envelope>
3 ответа
Мне удалось создать проблему (требование), используя perl с SOAP::Lite. Ключ заключается в создании запроса с использованием массивов и определении типов с использованием SOAP::Data->type(). Я не мог заполнить версию исправления с помощью атрибута fixVersions, но я сделал это с помощью настраиваемого поля customfield_10040. Вы можете использовать вызов getItem(), чтобы проверить, какой из них используется в вашем случае.
my $soap = SOAP::Lite->service($URI);
my $token = $soap->login($USERNAME,$PASSWORD);
my $fieldValues = [
SOAP::Data->type('RemoteCustomFieldValue', {'customfieldId' => 'customfield_10040',
'values' => [
SOAP::Data->type('string', '10051'),
SOAP::Data->type('string', '10052')
]
}),];
my $affectedValues = [
SOAP::Data->type('RemoteVersion', {'name' => 'FINS 1.16.1',
'id' => SOAP::Data->type('string', '10051')}),
SOAP::Data->type('RemoteVersion', {'name' => 'FINS 1.16.1a',
'id' => SOAP::Data->type('string', '10052')})
];
my $fixedValues = [
SOAP::Data->type('RemoteVersion', {'name' => 'FINS 1.16.1',
'id' => SOAP::Data->type('string', '10051')})
];
my $customFields = SOAP::Data->type('RemoteCustomFieldValue', $fieldValues);
my $fixVersion = SOAP::Data->type('RemoteVersion' , $fixedValues);
my $affectedVersion = SOAP::Data->type('RemoteVersion' , $affectedValues);
my $component = SOAP::Data->type('RemoteComponent', \{'name' => 'CST', 'id' => SOAP::Data->type('string', '10194')});
my $remoteIssueHash = {
'project' => SOAP::Data->type('string' => $PROJECT),
'type' => SOAP::Data->type('string' => 10),
'summary' => SOAP::Data->type('string' => $summary),
'reporter' => SOAP::Data->type('string' => $reporter),
'assignee' => SOAP::Data->type('string' => $assignee),
'customFieldValues' => SOAP::Data->type('array' => $customFields),
'affectsVersions' => SOAP::Data->type('array' => $affectedVersion),
'components' => SOAP::Data->type('array' => $component),
'fixVersions' => SOAP::Data->type('array' => $fixVersion), ## this doesn't do anything
'description' => SOAP::Data->type('string' => $description),
'environment' => SOAP::Data->type('string' => 'Some environment'),
};
my $remote_issue = $soap->call('createIssue', $token, $remoteIssueHash);
print Dumper [$remote_issue->faultcode(), $remote_issue->faultstring(), $soap->transport()->status(), $remote_issue->result(), $remote_issue ];
exit();
Удачи с этим.
Даниил
createIssue принимает объект RemoteIssue. Объект RemoteIssue имеет массив с именем customFieldValues объектов RemoteCustomFieldValue. Пока все хорошо. Объект RemoteCustomFieldValue имеет поле с именем customfieldId (не "id", как у вас) и массив String с именем "values". Похоже, $ серьезность не массив?
Все это пришло из Java-источника для RemoteIssue и RemoteCustomFieldValue. Ошибки SOAP в моем опыте почти всегда бесполезны.
~ Matt
Я бросил пытаться понять SOAP::Lite
, Меня сильно укусили непредвиденные способы работы этого модуля еще в 2005 году, и я научился избегать его использования.
Много раз, простой LWP
плюс XML::LibXML
построить DOM достаточно хорошо.
Возможно, вы даже можете жестко закодировать XML-документ в виде строки в вашей программе и просто интерполировать переменные. Не красиво, но достаточно в некоторых ситуациях.
Теперь вы сталкиваетесь с файлом WSDL, и, скорее всего, ваш сценарий не тривиален. (Я не знаю.)
Я только недавно узнал о существовании превосходного Марка Овермера XML::Compile
набор модулей. Вы должны отдать дань уважения там, где это необходимо. Нам пришлось интегрироваться с сервисом SOAP/MTOM/XOM, поэтому в XML использовались двоичные вложения. Я понятия не имел об этой (раздутой корпоративной) спецификации. С помощью XML::Compile::SOAP
Мы заработали его за три часа, когда большую часть времени теряли тривиальные проблемы, которые были связаны только с нашим (глупым) методом проб и ошибок. Если бы мы следовали документам, прошел бы один час.
Поэтому я очень рекомендую Марка Овермера XML::Compile::SOAP
, Это очень сработало для нас.