If you use the XML version of this post is works, but tearing my hair out to try and find out why the inline version does not. Its hardly a complex function!!
import wslite.soap.SOAPClient
import wslite.soap.*
import groovy.xml.Namespace
proxy = new SOAPClient("http://www.predic8.com:8080/crm/CustomerService?wsdl")
/*
// THIS WORKS
list = proxy.send(
'''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"xmlns:ns="http://predic8.com/wsdl/crm/CRMService/1/">
<soapenv:Header/>
<soapenv:Body>
<ns:get>
<id>99</id>
</ns:get>
</soapenv:Body>
</soapenv:Envelope>'''
)
*/
//return list.getText()
//THIS DOES NOT
list = proxy.send(SOAPAction:'http://www.predic8.com:8080/crm/CustomerService'){
body{
get(xmlns:ns="http://predic8.com/wsdl/crm/CRMService/1/"){
id(99)
}
} //end body
} //end proxy
return list.getText()
Anyone able to fathom out why?
Attributes should be passed as a Map, so the following change to your code should work.
...
'ns:get'('xmlns:ns': "http://predic8.com/wsdl/crm/CRMService/1/"){
...
or
...
get('xmlns': "http://predic8.com/wsdl/crm/CRMService/1/"){
...
Related
using zeep 3.4.0
wsdl is looking for the following information in header
<soapenv:Header>\n
<vv:sessionHeader soapenv:mustUnderstand=\"1\">\n
<vv:sessionToken>\n
<vv:Token1 xmlns:vv=\"http://www.z.com/zTypes.xsd\">{{Token1Token}}
</vv:Token1>\n
<vv:Token2 xmlns:vv=\"http://www.z.com/zTypes.xsd\">{{Token2Token}}
</vv:Token2>\n
</vv:sessionToken>\n
</vv:sessionHeader>\n
I am passing parameters to _soapheaders as follows
headerQ = xsd.Element('Header',xsd.ComplexType ([
xsd.Element('sessionHeader',xsd.ComplexType ([
xsd.Element('sessionToken', xsd.ComplexType ([
xsd.Element('Token1',xsd.String()),
xsd.Element('Token2',xsd.String())
]))
]))
]))
header_value1 = headerQ({'Token1':Token1T, 'Token2':Token2T} )
client.set_default_soapheaders(header_value1)
header_value1 looks like this
{
'sessionHeader': {
'Token1': 'abcdef=',
'Token2': 'ghijkl='
}
}
I get the following error:
line 365, in _serialize_header
raise ValueError("Invalid value given to _soapheaders")
_serialize_header expects header_value1 to be either a list or a dictionary
isinstance(header_value1,dict) returns False
Questions:
What is the correct way to pass parameters to _soapheaders
Why is sessionToken not reflected in the header
Debugging things with Zeep is always a bit of a challenge, but here's a working implementation:
In order to correctly render two elements (Token1 and Token2) you need a xsd:Sequence element:
headerQ = xsd.Element('Header', xsd.ComplexType([
xsd.Element('{http://www.z.com/zTypes.xsd}sessionHeader', xsd.ComplexType([
xsd.Element('{http://www.z.com/zTypes.xsd}sessionToken', xsd.ComplexType(
xsd.Sequence([
xsd.Element('{http://www.z.com/zTypes.xsd}Token1', xsd.String()),
xsd.Element('{http://www.z.com/zTypes.xsd', xsd.String())
])))
], attributes=[xsd.Attribute('mustUnderstand', xsd.Boolean())
]))
]))
Providing the QNames instead of raw element names will take care of the namespaces and finally you set the attributes on the sessionToken type definition. If your soap server refuses to accept "true" then you can use an xsd:Integer type, or you can rewrite "true" to "1" using an egress plugin as shown here
Setting the header value works as you tried, although you need to wrap into a list:
header_value1 = headerQ(
{'mustUnderstand': True,
'sessionToken': {'Token1': 'Token1T',
'Token2': 'Token2T'}
}
)
client.set_default_soapheaders([header_value1])
This gives the header section:
<Header>
<ns0:sessionHeader xmlns:ns0="http://www.z.com/zTypes.xsd" mustUnderstand="true">
<ns0:sessionToken>
<ns0:Token1>Token1T</ns0:Token1>
<ns0:Token2>Token2T</ns0:Token2>
</ns0:sessionToken>
</ns0:sessionHeader>
</Header>
rather than using the built in method, I got it working with
header_value1 = {'sessionHeader': {'sessionToken': { \
'primary': token1, secondary': token2}}}
I've faced with a problem. I'm new in SoapUI.
I must read excel file and then put some variables in the soap request. This is what I've done:
I've add a groovy script to get the excel file data:
import jxl.*
Workbook workbook = Workbook.getWorkbook(new File("C:\\PATH\\TestData.xls"))
Sheet sheet1 = workbook.getSheet("Sheet1")
def rows = sheet1.getRows()
def cols = sheet1.getColumns()
log.info "Row Count =" + rows
log.info "Column Count =" + cols
def array = []
for(i=1;i<rows;i++) {
for(j=0;j<cols;j++) {
Cell cell = sheet1.getCell(j,i)
def variable = cell.getContents()
log.info cell.getContents()
array << variable
}
}
return array
array returns: 10 and 20.
And this is a soap request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header/>
<soapenv:Body>
<tem:Add>
<tem:intA>10</tem:intA>
<tem:intB>10</tem:intB>
</tem:Add>
</soapenv:Body>
</soapenv:Envelope>
Can I somehow call a groovy script and put variables in
<tem:intA>10</tem:intA>
<tem:intB>20</tem:intB>
Instead of 10 and 20, I should call a groovy script method and put data, which I've taken from excel file.
Since your use-case is trivial: just two variables to be substituted, you can just use two properties.
Change the return array in your script to something like:
testCase.setPropertyValue("intA", array[0].toString())
testCase.setPropertyValue("intB", array[1].toString())
And then your request to:
<tem:intA>${#TestCase#intA}</tem:intA>
<tem:intB>${#TestCase#intB}</tem:intB>
I'm trying to fetch events from a CalDAV server using Sardine (and biweekly). Fetching an entire calendar is working for me:
Sardine sardine = SardineFactory.begin();
InputStream is = sardine.get(CALDAV_URL_STRING);
ICalendar iCalendar = Biweekly.parse(is).first();
Now I would like to fetch events for specific time range. Based on this "Building a CalDAV client" article, I assume you should use Sardines report method to do so, right?
If so, how should you use that method? It's not documented in the wiki, and the Javadoc is also not very clear.
Should I write my own SardineReport? I looks like I should end up with something like:
Sardine sardine = SardineFactory.begin();
SardineReport<List<VEvent>> report = new MyRangeReport(FROM_DATE, END_DATE);
List<VEvent> result = sardine.report(CALDAV_URL_STRING, 1, report);
Am I on the right track? Does anyone have any pointers to how to write your own Sardine report?
You are correct, to run a time range query you need to issue an HTTP REPORT request containing a calendar-query. You can find a sample in RFC 4719 Section 7.8.1. I don't know Sardine, but yes, report sounds right ;-)
Simplified even further:
REPORT /bernard/work/ HTTP/1.1
Host: cal.example.com
Depth: 1
Content-Type: application/xml; charset="utf-8"
Content-Length: xxxx
<?xml version="1.0" encoding="utf-8" ?>
<calendar-query xmlns:D="DAV:" xmlns="urn:ietf:params:xml:ns:caldav">
<D:prop>
<D:getetag/>
<calendar-data />
</D:prop>
<filter>
<comp-filter name="VCALENDAR">
<comp-filter name="VEVENT">
<time-range start="20060104T000000Z" end="20060105T000000Z"/>
</comp-filter>
</comp-filter>
</filter>
</calendar-query>
Should I write my own SardineReport?
Looks like, scanning over the GitHub of Sardine it doesn't seem to include CalDAV queries. You can probably base yours on their
SyncCollectionReport.java.
Note that the response to the calendar-query REPORT is just a regular WebDAV 207 multi-status response. Nothing extra required. (the Result object would be the same like in their SyncCollectionReport but w/o the extra syncToken).
I've implemented a report class which works, however, the result returned by Radicale seem to be incorrect. It looks like Radicale does not support the time-range filter.
For what it's worth, here are the relevant bits of the report:
public class VEventsTimeRangeSardineReport extends SardineReport<List<VEvent>>
{
...
#Override
public String toXml() throws IOException
{
// Hardcode for now
String xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
"<c:calendar-query xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n" +
" <d:prop>\n" +
" <c:calendar-data/>\n" +
" <d:getetag/>\n" +
" </d:prop>\n" +
" <c:filter>\n" +
" <c:comp-filter name=\"VCALENDAR\">\n" +
" <c:comp-filter name=\"VEVENT\">\n" +
" <c:time-range start=\"%s\" end=\"%s\"/>\n" +
" </c:comp-filter>\n" +
" </c:comp-filter>\n" +
" </c:filter>\n" +
"</c:calendar-query>";
return String.format(xml, SDF.format(fromDate), SDF.format(toDate));
}
#Override
public List<VEvent> fromMultistatus(Multistatus multistatus)
{
List<VEvent> events = new ArrayList<>(multistatus.getResponse().size());
for (Response response : multistatus.getResponse()) {
// Here response.getPropstat().get(0).getProp().getAny().get(0).getFirstChild().getTextContent() is parsed
events.addAll(ICalendarSardineReport.getICalendar(response).getEvents());
}
return events;
}
#Override
public Object toJaxb()
{
return null;
}
}
I'm trying to output the following raw url in the view.
https://loopme.me/api/vast/ads?appId=e18c19fa43&vast=2&uid=1234&ip=8.8.8.8&bundleid=com.loopme&appname=my_talking_pet&sdk=16.2&exchange=admarvel
however, even if I wrap the dynamic content with #Html method, the output is always
https://loopme.me/api/vast/ads?appId=e18c19fa43&vast=2&uid=1234&ip=8.8.8.8&bundleid=com.loopme&appname=my_talking_pet&sdk=16.2&exchange=admarvel
that is to say, '&' is still escaped.
Can anyone help me to correctly output raw contents in the view? I'm using scala bases template engine.
code:
<vmap:VMAP xmlns:vmap="http://www.iab.net/videosuite/vmap" version="1.0">
#for(offset <- timeOffsets){
<vmap:AdBreak breakType="linear" breakId="#offset.id"
timeOffset="#timeOffset(offset)">
#for(campaign <- campaigns){
<vmap:AdSource allowMultipleAds="allowMultipleAds"
followRedirects="true" id="#campaign.id">
<AdTagURI templateType="vast3">
<![CDATA[
#Html(campaign.extTag)
]]>
</AdTagURI>
</vmap:AdSource>
}
<vmap:TrackingEvents>
<vmap:Tracking event="breakStart">
http://MyServer.com/breakstart.gif
</vmap:Tracking>
</vmap:TrackingEvents>
</vmap:AdBreak>
}
</vmap:VMAP>
In a HTML template
import play.twirl.api.HtmlFormat
HtmlFormat.raw(yourURL)
In a XML template
import play.twirl.api.XmlFormat
XmlFormat.raw(yourURL)
I need to export content from a typo3 site to a web app. I am considering to use xml or json. But I haven't figure it out how to do it.
I'm new to typo3 development. So I would like to know if someone has suggestions how to do this.
Regards,
This highly depends on your requirements ;)
As a starting point you can use a new page type and disable all header codes to generate XML e.g.
xml = PAGE
xml {
typeNum = 123
config {
disableAllHeaderCode = 1
xhtml_cleaning = none
admPanel = 0
metaCharset = utf-8
additionalHeaders = Content-Type:text/xml;charset=utf-8
}
10 = COA
10 {
wrap = <?xml version="1.0" encoding="UTF-8" standalone="yes" ?><your_root_tag>|</your_root_tag>
# add code here to generate xml content
10 = ...
}
}
If you browse to http://example.com/index.php?type=123 you'll get the XML content.
But if things get more complex writing an extension maybe the better approach.