XML Editor
Sign up for a WebBoard account Sign Up Keyword Search Search More Options... Options
Chat Rooms Chat Help Help News News Log in to WebBoard Log in Not Logged in
Show tree view Topic
Go to previous topicPrev TopicGo to next topicNext Topic
Postnext
Bruce CantorSubject: Problems posting multipart form via http-post
Author: Bruce Cantor
Date: 06 Oct 2023 01:50 PM
I am having trouble making a http-post via Xquery in Stylus studio.
I have created a successfully post via Postman but cannot recreate the success in Xquery in Stylus Studio.

In Postman this exported code is working successfully:

POST /api/private/portugal/invoice-sender-feedback HTTP/1.1
Host: sii.marosavat.com
Environment: TEST
Company: PT501234569
Id: 4587
Authorization: Basic YnQuY2FudG9yQGVldGdyb3VwLmNb==
Content-Length: 257
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="/C:/GitHub/xml/PipelineTransformations/Marosa/testdata/2000003B_Invoice_test_marosa.csv"
Content-Type: text/csv

(data)
------WebKitFormBoundary7MA4YWxkTrZu0gW--

In stylus studio I am trying to achieve the same result with this code (part of):

if(exists(/*[local-name() = 'Invoice'])) then
(:Create invoice via library:)
let $document := Marosa:CreateInvoiceCSV(/)
return ddtek:http-post($endpoints/@URLInvoiceCreditNote, $document, $options)

where $document is the content and $options are set in a configuration file like this:

<Marosa>
<WS URLInvoiceCreditNote="(https)://sii.marosavat.com/api/private/portugal/invoice-sender-feedback___"/>
<request>
<request-header>
<header name="Authorization"
value="Basic YnQuY2FudG9yQGVldGdyb3Vwg=="/>
<header name="Content-Type" value="multipart/form-data"/>
<!-- additional required header values-->
<header name="Environment" value="TEST"/>
<header name="Company" value="PT501234569"/>
<header name="Id" value="4587"/>
</request-header>
</request>
</Marosa>

When I run the Xquery code I get an error 400-bad request.
Am I doing this correct? I am thinking that I might be setting the multipart file part wrong?

Kind regards
Bruce

Postnext
Ivan PedruzziSubject: Problems posting multipart form via http-post
Author: Ivan Pedruzzi
Date: 06 Oct 2023 04:11 PM


You should not try to handle authentication manually, ddtek:http functions support and user/password for BASIC and DIGEST
Mime type it is also managed automatically.

<request username="..." password="...">
<header name="Environment" value="TEST"/>
<header name="Company" value="PT501234569"/>
<header name="Id" value="4587"/>
</request>

Make sure to pass the element "request" to the function and not element "Marosa" as in your example

<Marosa>
<WS URLInvoiceCreditNote="(https)://sii.marosavat.com/api/private/portugal/invoice-sender-feedback___"/>
....
</Marosa>

Try the above first, if the multi-part is really a requirement. you may need to use a different function.
Here is an example of extension function HTTP.VERB available from XPS build 150 or greater, which was designed to be compatible with ddtek:http option and response.

Element "parameter" you can point to a local file using local path.
Attribute "type" supports 3 values: file, base64, text
When type is base64 or text you need to place the value directly as text, see second example.


declare namespace xps_http = 'ddtekjava:com.ivitechnologies.pipeline.ext.net.HTTP';\n";
declare function xps_http:VERB($verb as xs:string, $url, $options as document-node()?, $payload as document-node()?) external;\n";

declare variable $options :=

<request username="..." password="...">
<header name="Environment" value="TEST"/>
<header name="Company" value="PT501234569"/>
<header name="Id" value="4587"/>
<parameters>
<parameter name="file" type="file">c:\temp\image.png</parameter>
<parameters>
</request>

xps_http:VERB('POST', url, $options, ())


You can also simulate a browser FORM POST, here an example

<request username="..." password="...">
<header name="Environment" value="TEST"/>
<header name="Company" value="PT501234569"/>
<header name="Id" value="4587"/>
<form>
<parameters>
<parameter name="first" type="text">Ivan</parameter>
<parameter name="last" type="text">Pedruzzi</parameter>
<parameters>
</form>
</request>

xps_http:VERB('POST', url, $options, ())





Ivan Pedruzzi
Stylus Studio Team

Postnext
Bruce CantorSubject: Problems posting multipart form via http-post
Author: Bruce Cantor
Date: 09 Oct 2023 11:00 AM
Originally Posted: 09 Oct 2023 08:36 AM
Hi Ivan,

Thank you for your input.

I looks like as if it needs to be a form, so I tried this approach:

import module namespace Marosa = "Marosa:library" at "Marosa_lib.xqm";
declare namespace xps_http = "ddtekjava:com.ivitechnologies.pipeline.ext.net.HTTP";
declare function xps_http:VERB($verb as xs:string, $url, $options as document-node()?, $payload as document-node()?) external;

declare variable $request := /;
(: Load transactionlogdir from global environment file :)
declare variable $logFileDir := doc(resolve-uri("../../environment/environment.xml", fn:static-base-uri()))/Params/TransactionLogDir;
declare variable $origFileName := string(processing-instruction(Original-FileName));
declare variable $endpoints := doc(resolve-uri("../Config/config.xml", fn:static-base-uri()))/config/Marosa/WS;

declare variable $LogFileFullPath := concat('file:////', $logFileDir, $origFileName, '.log');
declare option ddtek:serialize "indent=yes";


let $options := <request username="***" password="*********">
<request-header>

<form>
<parameters>
<parameter name="file" type="text">{Marosa:CreateInvoiceCSV(/)}</parameter>
</parameters>
</form>

<!--<header name="Content-Type" value="undefined"/>-->
<!-- additional required header values-->
<header name="Environment" value="TEST"/>
<header name="Company" value="PT50284474"/>
<header name="Id" value="5587"/>
</request-header>
</request>


return xps_http:VERB('POST', $endpoints/@URLInvoiceCreditNote, document { $options }, ())


But this result in an error:

[DataDirect][XQuery]Error at line 33, column 87. Static error during resolving of external Java function. No matching Java external function found for 'com.ivitechnologies.pipeline.ext.net.HTTP:VERB(xs:string, attribute(URLInvoiceCreditNote, xs:untypedAtomic)*, document-node()?, document-node()?)'. [Call stack: xps_http:VERB@33.8]


javax.xml.xquery.XQQueryException: [DataDirect][XQuery]Error at line 33, column 87. Static error during resolving of external Java function. No matching Java external function found for 'com.ivitechnologies.pipeline.ext.net.HTTP:VERB(xs:string, attribute(URLInvoiceCreditNote, xs:untypedAtomic)*, document-node()?, document-node()?)'. [Call stack: xps_http:VERB@33.8]

at com.ddtek.xquery.xqj.Util.createXQQueryException(Util.java:341)

at com.ddtek.xquery.xqj.Util.createXQException(Util.java:241)

at com.ddtek.xquery.xqj.DDXQAbstractExpression.createOrGetExecutionContext(DDXQAbstractExpression.java:519)

at com.ddtek.xquery.xqj.DDXQAbstractExpression.createOrGetExecutionContext(DDXQAbstractExpression.java:481)

at com.ddtek.xquery.xqj.DDXQPreparedExpression.<init>(DDXQPreparedExpression.java:37)

at com.ddtek.xquery.xqj.DDXQConnection.prepareExpression(DDXQConnection.java:243)

Caused by: com.ddtek.xquery.typing.TypeVisitor$TypeVisitorException: [EJF0002][DataDirect][XQuery]Static error during resolving of external Java function. No matching Java external function found for 'com.ivitechnologies.pipeline.ext.net.HTTP:VERB(xs:string, attribute(URLInvoiceCreditNote, xs:untypedAtomic)*, document-node()?, document-node()?)'. [Call stack: xps_http:VERB@33.8]

at com.ddtek.xquery.typing.TypeVisitor.createException(TypeVisitor.java:5111)

at com.ddtek.xquery.typing.TypeVisitor.getExternalJavaFunction(TypeVisitor.java:7775)

at com.ddtek.xquery.typing.TypeVisitor.visit(TypeVisitor.java:2980)

at com.ddtek.xquery.expr.FunctionCall.accept(FunctionCall.java:224)

at com.ddtek.xquery.typing.TypeVisitor.visit(TypeVisitor.java:2794)

at com.ddtek.xquery.expr.FLWORExpr.accept(FLWORExpr.java:204)

at com.ddtek.xquery.expr.AllExpressionVisitor.visit(AllExpressionVisitor.java:455)

at com.ddtek.xquery.typing.TypeVisitor.visit(TypeVisitor.java:3450)

at com.ddtek.xquery.expr.MainModule.accept(MainModule.java:57)

at com.ddtek.xquery.typing.TypeVisitor.typeExpression(TypeVisitor.java:740)

at com.ddtek.xquery.mediator.ContextFactory$MediatorTypeVisitor.typeExpression(ContextFactory.java:581)

at com.ddtek.xquery.mediator.ContextFactory.prepareQuery(ContextFactory.java:254)

at com.ddtek.xquery.xqj.DDXQAbstractExpression.createOrGetExecutionContext(DDXQAbstractExpression.java:512)

... 3 more


In the classpath I am refering to the latest xmlpipelineserver.jar that I copied from the pipeline server. (MD-5: 0x99C067E7B4C8DC6264C1B2CC1F62B050).

What am I missing??

Postnext
Ivan PedruzziSubject: Problems posting multipart form via http-post
Author: Ivan Pedruzzi
Date: 09 Oct 2023 07:51 PM
Originally Posted: 09 Oct 2023 04:16 PM
Try the following.

You may also need to add additional XPS libraries in your Stylus Studio project's classpath:

httpmime-4.5.3.jar
httpcore-4.4.6.jar
httpclient-4.5.3.jar
xmlpipelineserver.jar
commons-logging-1.2.jar
commons-codec-1.9.jar



import module namespace Marosa = "Marosa:library" at "Marosa_lib.xqm";

declare namespace xps_http = "ddtekjava:com.ivitechnologies.pipeline.ext.net.HTTP";

declare function xps_http:VERB(
$verb as xs:string,
$url as xs:string,
$options as document-node()?,
$payload as document-node()?) external;

declare variable $request := /;
(: Load transactionlogdir from global environment file :)
declare variable $logFileDir := doc(resolve-uri("../../environment/environment.xml", fn:static-base-uri()))/Params/TransactionLogDir;
declare variable $origFileName := string(processing-instruction(Original-FileName));
declare variable $endpoints := doc(resolve-uri("../Config/config.xml", fn:static-base-uri()))/config/Marosa/WS;

declare variable $LogFileFullPath := concat('file:////', $logFileDir, $origFileName, '.log');

declare option ddtek:serialize "indent=yes";


declare variable $VERB_OPTIONS_POST :=
document{
<options username="*****" password="*****">
<request-header>
<header name="Content-Type" value="application/x-www-form-urlencoded"/>
<header name="Environment" value="TEST"/>
<header name="Company" value="PT50284474"/>
<header name="Id" value="5587"/>
</request-header>
</options>
};

declare variable $payload :=
document{
<request>
<form>
<parameters>
<parameter name="file" type="text">{Marosa:CreateInvoiceCSV(/)}</parameter>
</parameters>
</form>
</request>
};

xps_http:VERB(
'POST',
xs:string($endpoints/@URLInvoiceCreditNote),
$VERB_OPTIONS_POST,
$payload)

Posttop
Bruce CantorSubject: Problems posting multipart form via http-post
Author: Bruce Cantor
Date: 10 Oct 2023 08:43 AM
Dear Ivan,

Please remind me, where can I find the documentation for the ivitechnologies.pipeline java classes (including com.ivitechnologies.pipeline.ext.net.HTTP)?

Your help is much appreciated, but without the documentation I am coding in the dark and very much depended on your input.

I added some more libraries as suggested and I think I got closer but stuck in something that looks like as if I am not getting the username, password correctly sent.

This solution gives an "Not authorized error":

let $options := document {<request username="****" password="*******">
<request-header>

<form>
<parameters>
<parameter name="file" type="text">{Marosa:CreateInvoiceCSV(/)}</parameter>
</parameters>
</form>


<!-- additional required header values-->

<header name="Environment" value="TEST"/>
<header name="Company" value="PT50284307474"/>
<header name="Id" value="543581"/>

</request-header>
</request>}




return xps_http:VERB('POST', $endpoints/@URLInvoiceCreditNote, $options , ())


If I try your latest method where an additional payload parameter is added, I get an error saying: Exception in extension function "java.lang.IllegalStateException: Name is blank"


 
Go to previous topicPrev TopicGo to next topicNext Topic
Download A Free Trial of Stylus Studio 6 XML Professional Edition Today! Powered by Stylus Studio, the world's leading XML IDE for XML, XSLT, XQuery, XML Schema, DTD, XPath, WSDL, XHTML, SQL/XML, and XML Mapping!  
go

Log In Options

Site Map | Privacy Policy | Terms of Use | Trademarks
Stylus Scoop XML Newsletter:
W3C Member
Stylus Studio® and DataDirect XQuery ™are from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2016 All Rights Reserved.