I am trying to upload a jrxml file to Jasper server through putRequest api. A report entry is added in server MyReports path using following xml input
xml
<?xml version="1.0" encoding="UTF-8"?>
<request operationName="put" locale="en">
<argument name="CREATE_REPORTUNIT_BOOLEAN">true</argument>
<!--MainReportunit-->
<resourceDescriptor name="TestReport1" wsType="reportUnit" uriString="/reports/Myreports/TestReport1" isNew="true">
<label><![CDATA[TestReport1]]></label>
<description><![CDATA[TestReport1]]></description>
<resourceProperty name="PROP_RESOURCE_TYPE">
<value><![CDATA[com.jaspersoft.jasperserver.api.metadata.jasperreports.domain.ReportUnit]]></value>
</resourceProperty>
<resourceProperty name="PROP_PARENT_FOLDER">
<value><![CDATA[/reports/Myreports]]></value>
</resourceProperty>
<resourceProperty name="PROP_RU_ALWAYS_PROPMT_CONTROLS">
<value><![CDATA[true]]></value>
</resourceProperty>
<resourceProperty name="PROP_RU_CONTROLS_LAYOUT">
<value><![CDATA[1]]></value>
</resourceProperty>
<resourceDescriptor wsType="datasource" isNew="false">
<resourceProperty name="PROP_REFERENCE_URI">
<value><![CDATA[/datasources/{DATASOURCE_NAME}]]></value>
</resourceProperty>
<resourceProperty name="PROP_IS_REFERENCE">
<value><![CDATA[true]]></value>
</resourceProperty>
</resourceDescriptor>
<resourceDescriptor name="TestReport1" wsType="jrxml" uriString="/reports/Myreports/TestReport1" isNew="true">
<label><![CDATA[TestReport1]]></label>
<description><![CDATA[TestReport1]]></description>
<resourceProperty name="PROP_RESOURCE_TYPE">
<value><![CDATA[com.jaspersoft.jasperserver.api.metadata.common.domain.FileResource]]></value>
</resourceProperty>
<resourceProperty name="PROP_HAS_DATA">
<value><![CDATA[true]]></value>
</resourceProperty>
<resourceProperty name="PROP_RU_IS_MAIN_REPORT">
<value><![CDATA[true]]></value>
</resourceProperty>
</resourceDescriptor>
</resourceDescriptor>
</request>
node js code
var parameters = {
putRequest: RequestXmlStr
}
var soap = require('soap');
soap.createClient(url, function (err, client) {
client.put(parameters, function (err, result) {
if (err) console.error(err);
});
});
It is working fine without attachment. But I dont know, where to include the jrxml data or base64 string in this xml.
Since SOAP is not a requirement, here is how I got it working with the REST_v2 service:
var request = require("request"),
fs = require("fs"),
reportUnitDescriptor = {
"label": "My Report Unit",
"description": "My First Report Unit",
"alwaysPromptControls": "true",
"controlsLayout": "popupScreen",
"dataSource": {
"dataSourceReference": {
"uri": "/analysis/datasources/FoodmartDataSourceJNDI"
}
},
"jrxml": {
"jrxmlFile": {
"label": "Main JRXML",
"type": "jrxml"
}
}
};
request.post({
url: "http://localhost:8080/jasperserver/rest_v2/resources/public",
auth: { user: "jasperadmin", password: "jasperadmin" },
formData: {
resource: {
value: JSON.stringify(reportUnitDescriptor),
options: {
contentType: "application/repository.reportUnit+json"
}
},
jrxml: fs.createReadStream(__dirname + '/MainReport.jrxml'),
}
}, function(err, response, body) {
console.log("status: " + response.statusCode + "; message: " + response.statusMessage);
});
Some notes:
The reportUnit will be created in the Public folder. You specify that in the URL after the /resources part.
The MainReport.jrxml is located in the same directory as this script is
More info on the REST_v2 API here
Related
In SharePoint and using SPServices, I am trying to update the content of the files uploaded in the sub folders
This is the image and also the file metatdata i want to update.
The library structure looks like this:
List Name: Shared Documents
Folder #1 - Documents
Subfolder #1 - Procurement
File #1 - uploaded files
File #2
So basically i want to update the requestID, filetype, etc
Can anyone help? Thanks!
Here is my code
var oldFolderName = "Procurement";
$().SPServices({
operation: "GetListItems",
async: false,
listName: 'Documents',
CAMLViewFields: "<ViewFields Properties='True' />",
CAMLQuery: "<Query><Where><Eq><FieldRef Name='FSObjType' /><Value Type='Integer'>1</Value></Eq></Where></Query>",
CAMLQueryOptions: "<QueryOptions><IncludeMandatoryColumns>FALSE</IncludeMandatoryColumns></QueryOptions>",
completefunc: function (xData, Status) {
$(xData.responseXML).SPFilterNode('z:row').each(function () {
var existingFolderName = $(this).attr("ows_FileLeafRef").split(";#")[1];
if (existingFolderName == oldFolderName) {
var Folder_ID = $(this).attr("ows_ID");
$().SPServices({
operation: "UpdateListItems",
async: false,
batchCmd: "Update",
listName: 'Documents',
valuepairs: [["Title", "Working"], ["requestID", "Working"]],
ID: Folder_ID,
completefunc: function (xData, Status) {
console.log("Folder Name Updated Successfully...");
}
});
}
});
}
});
But the code is only updating the Sub folder metadata (Procurement) not the list in the procurement folder.
This is what i actually mean
No need to use SPService to loop folder firstly and then update file metadata, instead,use Rest API getfilebyserverrelativeurl to get file and update metadata like below:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
updateFileMetadata();
function updateFileMetadata() {
var def = jQuery.Deferred();
var restSource= _spPageContextInfo.webAbsoluteUrl+"/_api/Web/getfilebyserverrelativeurl('/sites/Sitename/Shared%20Documents/Procurement/filename')/ListItemAllFields";
var itemPayload = {"__metadata": {"type":"SP.Data.Shared_x0020_DocumentsItem"},"Title":"Updated","requestID","Working","filetype":"Working"};
var dfd = jQuery.Deferred();
$.ajax(
{
url: restSource,
method: "POST",
contentType: "application/json;odata=verbose",
data: JSON.stringify(itemPayload),
headers:
{
"Accept": "application/json;odata=verbose",
"X-RequestDigest": $('#__REQUESTDIGEST').val(),
"X-HTTP-Method":"MERGE",
"If-Match": "*"
},
success: function (data) {
alert("Success");
dfd.resolve(data);
},
error: function (err) {
dfd.reject(err);
alert("Error");
}
});
return dfd.promise();
}
</script>
For _api/Web/getfilebyserverrelativeurl:
the url value should be
/sites/sitename/Shared%20Documents/Procurement/filename in this case,
if it's a root site which no "sites" character in the site url, then change like this:
/Shared%20Documents/Procurement/filename
I would like to send an API request to https://api-test.onlineszamla.nav.gov.hu/invoiceService/queryTaxpayer and they expect an XML, as a sample provided below. What is the appropriate syntax in Node.js that processes this request? Unfortuantely I couldn't find this out from the API documentation.
EDIT: part of the XML contents will be from user data, part of it from input fields.
<?xml version="1.0" encoding="UTF-8"?><QueryTaxpayerRequest xmlns="http://schemas.nav.gov.hu/OSA/1.0/api">
<header>
<requestId></requestId>
<timestamp></timestamp>
<requestVersion></requestVersion>
<headerVersion></headerVersion>
</header>
<user>
<login></login>
<passwordHash></passwordHash>
<taxNumber></taxNumber>
<requestSignature></requestSignature>
</user>
<software>
<softwareId></softwareId>
</software>
<taxNumber></taxNumber>
</QueryTaxpayerRequest>
Use XML parser and then Set the response type as XML like below :
var xml = require('xml');
response.set('Content-Type', 'text/xml');
response.send(xml(YOUR_XML_OBJECT));
in the above I have used XML as the parser, you should be able to use any other available packages.
You can use a library like xmlbuilder to make creating xml string easier.
var builder = require('xmlbuilder');
var obj = {
root: {
xmlbuilder: {
repo: {
'#type': 'git', // attributes start with #
'#text': 'git://github.com/oozcitak/xmlbuilder-js.git' // text node
}
}
}
};
var xml = builder.create(obj).end({ pretty: true});
console.log(xml);
And then you can use any library to make the request and use the xml string above in the body.
This works for me awesome.
var Request = require("request");
const express = require("express");
const app = express();
app.use(express.urlencoded({extended: true}));
app.use(express.text())
app.post("/api/getXML", (req, res) => {
Request.post({
"headers": { "content-type": "text/plain; charset=utf-8"},
"url": "<url which return xml response>",
"body": req.body
}, (error, response, body) => {
if(error) {
console.error(error);
res.send(error)
}
console.log("XML body :",body);
res.send(body);
});
});
The idea got from the link https://www.thepolyglotdeveloper.com/2017/10/consume-remote-api-data-nodejs-application/
I consumed a SOAP Webservice through Nodejs :
$(document).ready(function() {
$.ajax({
url: "/track/vehicule/getWebserviceRetourKYC",
type: "POST",
success : function(data, status, xhr) {
console.dir(data);
},
error : function(xhr, status, error) {
console.dir(error);
}
});
});
var express = require('express');
var request = require("request");
var fs = require('fs');
var path = require('path');
var async = require('async');
var router = express.Router();
var db = require('./db');
var utils = require('./utils');
var connexion = db.getConnexion();
router.post("/getWebserviceRetourKYC", function(req, res) {
var soap = require('strong-soap').soap;
// wsdl of the web service this client is going to invoke. For local wsdl you can use, url = './wsdls/stockquote.wsdl'
var url = "https://www.telma.net/sentimsa/mvola/wsdl.php?module=jWSDL&action=WSDL:wsdl&service=mvola~WSMVolaGetInfosKYC";
var requestArgs = {
module:'jWSDL',
action:'WSDL:wsdl',
service:'mvola~WSMVolaGetInfosKYC'
};
var options = {};
soap.createClient(url, options, function(err, client) {
var method = client['WSMVolaGetInfosKYCCtrl']['WSMVolaGetInfosKYCCtrlPort']['getInfosKYC'];
console.dir(client);//here
method(requestArgs, function(err, result, envelope, soapHeader) {
//response envelope
console.log('Response Envelope: \n' + envelope);
//'result' is the response body
console.log('Result: \n' + JSON.stringify(result));
});
});
res.send();
});
module.exports = router;
At runtime the returned result is :
{
"statusCode": 500,
"body": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Client<\/faultcode><faultstring>Error cannot find parameter<\/faultstring><\/SOAP-ENV:Fault><\/SOAP-ENV:Body><\/SOAP-ENV:Envelope>\n",
"headers":
{
"date": "Thu, 04 Jul 2019 05:51:26 GMT",
"server": "Apache/2.2.3 (Red Hat)",
"content-length": "294",
"content-type": "text/xml; charset=utf-8",
"content-language": "en",
"connection": "close"
},
"request":
{
"uri":
{
"protocol": "https:",
"slashes": true,
"auth": null,
"host": "www.telma.net",
"port": 443,
"hostname": "www.telma.net",
"hash": null,
"search": "?service=mvola%7EWSMVolaGetInfosKYC",
"query": "service=mvola%7EWSMVolaGetInfosKYC",
"pathname": "/sentimsa/mvola/soap.php",
"path": "/sentimsa/mvola/soap.php?service=mvola%7EWSMVolaGetInfosKYC",
"href": "https://www.telma.net/sentimsa/mvola/soap.php?service=mvola%7EWSMVolaGetInfosKYC"
},
"method": "POST",
"headers":
{
"User-Agent": "strong-soap/1.20.0",
"Accept": "text/html,application/xhtml+xml,application/xml,text/xml;q=0.9,*/*;q=0.8",
"Accept-Encoding": "none",
"Accept-Charset": "utf-8",
"Connection": "close",
"Host": "www.telma.net",
"Content-Length": 396,
"Content-Type": "text/xml; charset=utf-8",
"SOAPAction": "\"https://www.telma.net/sentimsa/mvola/soap.php?service=mvola%7EWSMVolaGetInfosKYC&method=getInfosKYC\""
}
}
}
So what is wrong in my codes ?
------ edit ------ :
Here is an example of the envelope and the desired result :
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mvol="https://www.telma.net/sentimsa/mvola/">
<soapenv:Header/>
<soapenv:Body>
<mvol:getInfosKYC soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<zSubscriberId xsi:type="xsd:string"> 0340017729</zSubscriberId>
</mvol:getInfosKYC>
</soapenv:Body>
</soapenv:Envelope>
Response :
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="https://www.telma.net/sentimsa/mvola/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:getInfosKYCResponse>
<getInfosKYCReturn xsi:type="ns1:CCodeReponse">
<oDataKYC xsi:nil="true" xsi:type="ns1:CKycInfos"/>
<status_Code xsi:type="xsd:string">101</status_Code>
<status_Reason xsi:type="xsd:string">Le numéro 0340017728 n’existe pas dans Sentinel.</status_Reason>
</getInfosKYCReturn>
</ns1:getInfosKYCResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The error:
<faultstring>Error cannot find parameter<\/faultstring>
Suggests you're missing a required parameter from your request. Do you have documentation for the SOAP service you're consuming? Are module, action, and service the only required parameters?
Also, you've included those parameters in the URL string as well:
var url = "https://www.telma.net/sentimsa/mvola/wsdl.php?module=jWSDL&action=WSDL:wsdl&service=mvola~WSMVolaGetInfosKYC";
Not sure if this would cause a problem, but at the very least it shouldn't be required. I'd try removing those parameters from the URL string.
I have a problem with soap-node, my header have auth:
XML-service SOAP
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<Autentication xmlns="http://tempuri.org/">
<Pass>string</Pass>
<Us>string</Us>
</Autentication>
</soap:Header>
<soap:Body>
<getdata xmlns="http://tempuri.org/" />
</soap:Body>
</soap:Envelope>
App.js - Node.js
var soap = require('soap');
var url = "http://localhost/abc/example.asmx?WSDL"
var Autentication = {
"Autentication": {
"Pass" : "david",
"Us" : "hackro"
}
}
var args = {}
soap.createClient(url, function(err, client) {
if(err)return console.log(err)
client.addSoapHeader(Autenticacion)
client.ObtieneKey(args, function(err, result,body) {
if(err) return console.log(body)
console.log(result);
console.log(body);
})
})
But my auth fail because return empty
{ data: "" }
I see this answer but it doesn't work.
I solved my problem sending my header in this way
var Autentication ='<Autentication xmlns="http://tempuri.org/">Pass>david</Pass><Us>hackro</Us>/Autentication></soap:Header>'
Add header
client.addSoapHeader(Autentication)
Good Luck
I've finally got the jsreportonline at least generating the file. Here's my code:
request.post({
url: 'https://xxxx.jsreportonline.net/api/report',
json: true,
headers: {
"Content-Type": "application/json",
"Authorization" : "Basic "+new Buffer(username:pwd).toString('base64')
},
body: {
"template" : {'shortid" : xxxxx},
"data" : xxxx,
}
}, function(err, res, body) {
**** HERE IS THE PROBLEM ****
});
I have no clue how to write the pdf output stored within variable 'body' to a file. I've tried:
var pbs = fs.createWriteStream('./report.pdf');
pbs.write(body);
pbs.end();
I've tried:
var pbs = fs.createWriteStream('./report.pdf', {defaultEncoding: 'binary'});
... but the PDF file never is displayed properly. I know the code works because I can set an option on the call:
"options" : {
"reports" : {"save" : true}
}
... and the report is saved to my jsreportonline account and renders fine.
Thanks for any help.
You shouldn't use the callback but rather directly pipe the stream returned from the request.post. See this in docs here. Example:
var request = require('request')
var fs = require('fs')
request.post({
url: 'https://xxx.jsreportonline.net/api/report',
json: true,
headers: {
'Content-Type': 'application/json',
'Authorization' : 'Basic '+new Buffer('xxx:yyy').toString('base64')
},
body: {
'template' : {'shortid" : xxxxx},
'data' : xxxx,
}
}).on('error', function (err) {
console.log(err)
}).pipe(fs.createWriteStream('report.pdf'))
You can use 'busboy' to write the uploaded file to a file in server directory.
Saving the file:-
var
express = require("express"), os = require('os'), path = require('path'), Busboy = require('busboy'), fs = require('fs'), app = express();
app.post('/savepdf', function(req, res) {
var busboy = new Busboy({
headers : req.headers
});
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
console.log("OS tmp dir ========>" + os.tmpDir());
console.log("Base name ========>" + path.basename(filename));
var saveTo = path.join(os.tmpDir(), path.basename(filename));
file.pipe(fs.createWriteStream(saveTo));
});
busboy.on('finish', function() {
res.writeHead(200, {
'Connection' : 'close'
});
console.log("Upload finished !!!");
res.end("Success!");
});
return req.pipe(busboy);
});
app.listen(3000);
console.log('app started ');
HTML Page used to test the file:-
<html>
<head>
<title>Post Tool</title>
</head>
<body>
<h1>Save PDF </h1>
<h2>Upload Document</h2>
<form action="/savepdf" method="post" enctype="multipart/form-data">
<input type="text" name="uploadtext" id="uploadtext" value="Good" />
Choose a file : <input type="file" name="uploadfile" id="uploadfile" multiple/>
<input type="submit" value="Upload" />
</form>
</body>
</html>
Output:-
The file has been saved successfully in temp folder (i.e. windows path below).
C:\Users\userid\AppData\Local\Temp
The file name would be same as the uploaded file name.