[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Ftpapi] Application error. MCH3601 unmonitored by YAJL at statement 0000000001
Hi,
In the CUSTDETAIL sample program, how was the web service defined in the Apache server? My problem maybe in the definition of the web service in the Apache server.
Thanks,
Jose
On Monday, January 14, 2019, 8:51:35 AM GMT+8, Jose Tumbaga <diamond_jose@xxxxxxxxx> wrote:
Hi,
Please help me resolve this issue with run time exception error. The error appears both in SOAPUI and Postman, when I try to send JSON data to our iSeries machine.
Regards,
Jose Tumbaga
On Friday, January 11, 2019, 7:35:54 PM GMT+8, Jose Tumbaga <diamond_jose@xxxxxxxxx> wrote:
Hi,
I am creating a web service for the first time in our IBM i machine. Currently, I have an RPG program that accepts as input JSON data from HTTP server, using HTTP POST method.
I keep getting the following error message:
java.lang.RuntimeException: Invocation of program failed.
AS400Message (ID: CEE9901 text: Application error. MCH3601 unmonitored by YAJL at statement 0000000001, instruction X'0000'.):com.ibm.as400.access.AS400Message@c93517ec
Please help me resolve this error. Can't seem to determine if this is a setup error when I deployed the service, or a problem with user access, or a problem with the program itself.
I used the following code to accept the JSON data from HTTP input, following the standard declaration from the sample RESP API program codes.
docNode = yajl_stdin_load_tree( *ON: errMsg );
if errMsg <> '';
cusord.errMsg = 'json parse: ' + errMsg;
cusord.success = *off;
yajl_writeStdout(500: errMsg);
endif;
Can't seem to get past the first line of code.
Thanks in advance.
Jose Tumbaga
**FREE
// A REST API that allows you to retrieve, create, update and
// delete customer information. Basically, a full maintenance
// APIs written with YAJL.
// Scott Klement, March 2018
//
// Can get a list of customers with GET to:
// http://example.com/rest/custdetail/
//
// Can GET, PUT, DELETE and specific customer
// http://example.com/rest/custdetail/1234
//
// Can POST to create a new customer
// http://example.com/rest/custdetail/
//
// The customer record is sent/received over the network
// in JSON format like this:
//
// {
// "success": true,
// "errorMsg": "Only used if success=false",
// "data": {
// "custno": 496,
// "name": "Acme Foods",
// "address": {
// "street": "123 Main Street",
// "city": "Boca Raton",
// "state": "FL",
// "postal": "12345-6789",
// }
// }
// }
//
// In the cast of a list, the "data" element above will
// be an array.
//
// Before compiling:
// - Install YAJL, put it in your *LIBL
// - Create the CUSTFILE file (see the CUSTFILE member)
// - Create the NEXTCUST data area
// CRTDTAARA DTAARA(NEXTCUST) TYPE(*DEC) LEN(5 0) VALUE(1)
//
// To compile:
// *> CRTSQLRPGI CUSTDETAIL SRCFILE(QRPGLESRC) DBGVIEW(*SOURCE)
//
// To install in Apache, add these directives, and restart:
//
// ScriptAliasMatch /rest/([a-z0-9]*)/.* /qsys.lib/yajlrest.lib/$1.pgm
// <Directory /qsys.lib/yajlrest.lib>
// SetEnv QIBM_CGI_LIBRARY_LIST "YAJL;MYDATA;MYSRV;YAJLREST"
// require valid-user
// AuthType basic
// AuthName "REST APIs"
// PasswdFile %%SYSTEM%%
// UserId %%CLIENT%%
// </Directory>
//
ctl-opt dftactgrp(*no) actgrp('KLEMENT') decedit('0.')
bnddir('YAJL') option(*srcstmt: *nodebugio: *noshowcpy);
/include YAJL_H
dcl-c UPPER const('ABCDEFGHIJKLMNOPQRSTUVWXYZ');
dcl-c lower const('abcdefghijklmnopqrstuvwxyz');
dcl-s NEXTCUST packed(5: 0) dtaara;
dcl-ds CUSTFILE extname('CUSTFILE') qualified end-ds;
dcl-ds address_t qualified template;
street varchar(30) inz('');
city varchar(20) inz('');
state char(2) inz(' ');
postal varchar(10) inz('');
end-ds;
dcl-ds data_t qualified template;
custno packed(5: 0) inz(0);
name varchar(30) inz('');
address likeds(address_t) inz(*likeds);
end-ds;
dcl-ds cust_t qualified template;
success ind inz(*on);
errorMsg varchar(500) inz('');
data likeds(data_t) inz(*likeds);
end-ds;
dcl-ds cust likeds(cust_t) inz(*likeds);
dcl-s custid like(data_t.custno);
dcl-s errmsg varchar(500) inz('');
dcl-s method varchar(10);
exec SQL
set option naming=*sys, commit=*none;
reset cust;
if getInput( method: custid: errmsg ) = *off;
cust.success = *off;
cust.errorMsg = errmsg;
sendResponse(cust);
return;
endif;
select;
when method = 'GET' and custid = 0;
listCustomers();
when method = 'GET';
loadDbRecord(custid: cust);
sendResponse(cust);
when method = 'PUT';
if loadDbRecord(custid: cust) = *on;
if loadInputJson(cust) = *on;
cust.data.custno = custid;
updateDbRecord(cust);
endif;
endif;
sendResponse(cust);
when method = 'POST';
if loadInputJson(cust) = *on;
writeDbRecord(cust);
endif;
sendResponse(cust);
when method = 'DELETE';
if loadDbRecord(custid: cust) = *on;
deleteDbRecord(cust);
endif;
sendResponse(cust);
endsl;
return;
// ------------------------------------------------------------------------
// getInput(): Retrieve the basic HTTP input for this call
//
// method = (output) HTTP method used (GET, POST, DELETE, PUT)
// custid = (output) customer id, or 0 if none provided
// errmsg = (output) error message that occurred (if any)
//
// Returns *ON if successful, *OFF otherwise
// ------------------------------------------------------------------------
dcl-proc getInput;
dcl-pi *n ind;
method varchar(10);
custid like(data_t.custno);
errmsg varchar(500);
end-pi;
dcl-pr getenv pointer extproc(*dclcase);
var pointer value options(*string);
end-pr;
dcl-c REQUIRED_PART const('/rest/custdetail/');
dcl-s env pointer;
dcl-s pos int(10);
dcl-s custpart varchar(50);
dcl-s url varchar(1000);
errMsg = '';
method = 'GET';
url = '';
// ------------------------------------------------------
// Retrieve the HTTP method.
// - Default to GET if not provided
// ------------------------------------------------------
env = getenv('REQUEST_METHOD');
if env <> *null;
method = %xlate(lower: UPPER: %str(env));
endif;
// ------------------------------------------------------
// Retrieve the URL
// - Should always be provided!
// ------------------------------------------------------
env = getenv('REQUEST_URI');
if env = *null;
errMsg = 'Unable to retrieve URL';
return *off;
else;
url = %xlate(UPPER: lower: %str(env));
endif;
// ------------------------------------------------------
// Extract the customer ID from the URL.
// - if not provided, set to 0
// - should always be provided for PUT/POST/DELETE
// ------------------------------------------------------
monitor;
pos = %scan(REQUIRED_PART:url) + %len(REQUIRED_PART);
custpart = %subst(url: pos);
custid = %int(custpart);
on-error;
custid = 0;
endmon;
if custid = 0 and method <> 'GET' and method <> 'POST';
errMsg = 'You must supply a customer ID!';
return *off;
endif;
return *on;
end-proc;
// ------------------------------------------------------------------------
// loadDbRecord(): Load customer database record
//
// custid = (input) customer number to retrieve
// cust = (output) customer record
//
// returns *on if record loaded, *off otherwise
// ------------------------------------------------------------------------
dcl-proc loadDbRecord;
dcl-pi *n ind;
custid like(data_t.custno) const;
cust likeds(cust_t);
end-pi;
dcl-ds Rec extname('CUSTFILE') qualified end-ds;
exec SQL
select *
into :Rec
from CUSTFILE
where custno = :custid;
if %subst(sqlstt:1:2) <> '00' and %subst(sqlstt:1:2) <> '01';
cust.success = *off;
cust.errorMsg = 'Customer not found!';
return *off;
endif;
cust.data.custno = rec.custno;
cust.data.name = rec.name;
cust.data.address.street = rec.street;
cust.data.address.city = rec.city;
cust.data.address.state = rec.state;
cust.data.address.postal = rec.postal;
return *on;
end-proc;
// ------------------------------------------------------------------------
// updateDbRecord(): Updates an existing customer record
//
// cust = (i/o) customer information DS
//
// returns *ON if successful, *OFF otherwise.
// ------------------------------------------------------------------------
dcl-proc updateDbRecord;
dcl-pi *n ind;
cust likeds(cust_t);
end-pi;
dcl-ds udata likeds(data_t);
dcl-ds uaddress likeds(address_t);
eval-corr udata = cust.data;
eval-corr uaddress = cust.data.address;
exec SQL
update CUSTFILE
set
name = :udata.Name,
street = :uaddress.Street,
city = :uaddress.City,
state = :uaddress.state,
postal = :uaddress.postal
where
custno = :udata.CustNo;
if %subst(sqlstt:1:2)<>'00' and %subst(sqlstt:1:2)<>'01';
cust.success = *off;
cust.errorMsg = 'SQL State ' + sqlstt + ' updating CUSTFILE';
endif;
return cust.success;
end-proc;
// ------------------------------------------------------------------------
// getNextCustno(): Gets the next available customer number from
// the data area.
//
// For this to work, the NEXTCUST data area must exist. If you don't have
// it, create it with:
//
// CRTDTAARA DTAARA(your-lib/NEXTCUST) TYPE(*DEC) LEN(5 0) VALUE(1)
//
// returns the next custno, or 0 upon failure
// ------------------------------------------------------------------------
dcl-proc getNextCustno;
dcl-pi *n packed(5: 0);
end-pi;
dcl-s newCust packed(5: 0);
monitor;
in *lock NEXTCUST;
newCust = NEXTCUST;
if NEXTCUST = *hival;
NEXTCUST = 1;
else;
NEXTCUST += 1;
endif;
out NEXTCUST;
on-error;
return 0;
endmon;
return newCust;
end-proc;
// ------------------------------------------------------------------------
// writeDbRecord(): Creates a new customer record
//
// cust = (i/o) customer information DS
//
// returns *ON if successful, *OFF otherwise.
// ------------------------------------------------------------------------
dcl-proc writeDbRecord;
dcl-pi *n ind;
cust likeds(cust_t);
end-pi;
dcl-ds idata likeds(data_t);
dcl-ds iaddress likeds(address_t);
cust.data.custno = getNextCustno();
if cust.data.custno = 0;
cust.success = *off;
cust.errorMsg = 'Unable to get next available customer number';
return *off;
endif;
eval-corr idata = cust.data;
eval-corr iaddress = cust.data.address;
exec SQL
insert into CUSTFILE
(custno, name, street, city, state, postal)
values( :idata.custno, :idata.name,
:iaddress.street, :iaddress.city,
:iaddress.state, :iaddress.postal );
if %subst(sqlstt:1:2)<>'00' and %subst(sqlstt:1:2)<>'01';
cust.success = *off;
cust.errorMsg = 'SQL State ' + sqlstt + ' writing CUSTFILE';
endif;
return cust.success;
end-proc;
// ------------------------------------------------------------------------
// deleteDbRecord(): Deletes the customer record if it exists
//
// cust = (i/o) customer information DS
//
// returns *ON if successful, *OFF otherwise.
// ------------------------------------------------------------------------
dcl-proc deleteDbRecord;
dcl-pi *n ind;
cust likeds(cust_t);
end-pi;
dcl-s custid packed(5: 0);
custid = cust.data.custno;
exec SQL
delete from CUSTFILE
where custno = :custid;
if %subst(sqlstt:1:2) <> '00' and %subst(sqlstt:1:2) <> '01';
cust.success = *off;
cust.errorMsg = 'SQL state ' + sqlstt + ' deleting customer';
endif;
return cust.success;
end-proc;
// ------------------------------------------------------------------------
// loadInputJson(): If a PUT or POST was requested (write/update)
// load the customer record provided by the consumer
//
// cust = (i/o) customer info data structure.
//
// returns *ON if successful, *OFF otherwise
// ------------------------------------------------------------------------
dcl-proc loadInputJson;
dcl-pi *n ind;
cust likeds(cust_t);
end-pi;
dcl-s docNode like(yajl_val);
dcl-s node like(yajl_val);
dcl-s dataNode like(yajl_val);
dcl-s data like(yajl_val);
dcl-s addrNode like(yajl_val);
dcl-s errMsg varchar(500);
dcl-s i int(10);
dcl-s j int(10);
dcl-s field varchar(50);
//--------------------------------------------------
// get the JSON document sent from the consumer
//--------------------------------------------------
docNode = yajl_stdin_load_tree(*on: errMsg);
if errMsg <> '';
cust.errorMsg = 'json parse: ' + errMsg;
cust.success = *off;
return *off;
endif;
//--------------------------------------------------
// Load the success/errorMsg fields provided by
// consumer.
//--------------------------------------------------
node = yajl_object_find(docNode: 'success');
if node = *null;
cust.errorMsg = 'Required field "success" not found.';
cust.success = *off;
yajl_tree_free(docNode);
return *off;
endif;
node = yajl_object_find(docNode: 'errorMsg');
if node = *null;
cust.errorMsg = '';
else;
cust.errorMsg = yajl_get_string(node);
endif;
if cust.success = *off;
yajl_tree_free(docNode);
return *off;
endif;
//--------------------------------------------------
// Load the customer information provided by
// the consumer.
//--------------------------------------------------
data = yajl_object_find(docNode: 'data');
if data = *null;
cust.errorMsg = 'Required field "data" not found.';
cust.success = *off;
yajl_tree_free(docNode);
return *off;
endif;
i = 0;
dow yajl_object_loop(data: i: field: dataNode);
select;
when field = 'custno';
cust.data.custno = yajl_get_number(dataNode);
when field = 'name';
cust.data.name = yajl_get_string(dataNode);
when field = 'address';
j = 0;
dow yajl_object_loop(dataNode: j: field: addrNode);
select;
when field = 'street';
cust.data.address.street = yajl_get_string(addrNode);
when field = 'city';
cust.data.address.city = yajl_get_string(addrNode);
when field = 'state';
cust.data.address.state = yajl_get_string(addrNode);
when field = 'postal';
cust.data.address.postal = yajl_get_string(addrNode);
endsl;
enddo;
endsl;
enddo;
yajl_tree_free(docNode);
return *on;
end-proc;
// ------------------------------------------------------------------------
// sendResponse(): Send the JSON response document
//
// cust = (input) customer information DS
//
// returns *ON if successful, *OFF otherwise.
// ------------------------------------------------------------------------
dcl-proc sendResponse;
dcl-pi *n ind;
cust likeds(cust_t) const;
end-pi;
dcl-s errMsg varchar(500) inz('');
yajl_genOpen(*on);
yajl_beginObj();
yajl_addBool('success': cust.success);
yajl_addChar('errorMsg': cust.errorMsg);
if cust.success = *on;
yajl_beginObj('data');
yajl_addNum('custno': %char(cust.data.custno));
yajl_addChar('name': %trim(cust.data.name));
yajl_beginObj('address');
yajl_addChar('street': %trim(cust.data.address.street));
yajl_addChar('city': %trim(cust.data.address.city ));
yajl_addChar('state': %trim(cust.data.address.state ));
yajl_addChar('postal': %trim(cust.data.address.postal));
yajl_endObj();
yajl_endObj();
endif;
yajl_endObj();
if cust.success;
yajl_writeStdout(200: errMsg);
else;
yajl_writeStdout(500: errMsg);
endif;
yajl_genClose();
return (errMsg = '');
end-proc;
// ------------------------------------------------------------------------
// Provide list of all customers (called when GET without any custno)
//
// NOTE: Output is written directly to consumer
//
// Returns *ON if successful, *OFF otherwise.
// ------------------------------------------------------------------------
dcl-proc listCustomers;
dcl-pi *n ind;
end-pi;
dcl-s errmsg varchar(500);
dcl-s success ind;
dcl-ds CUSTLIST qualified;
custno like(CUSTFILE.custno);
name like(CUSTFILE.name);
street like(CUSTFILE.street);
city like(CUSTFILE.city);
state like(CUSTFILE.state);
postal like(CUSTFILE.postal);
end-ds;
exec SQL declare custlist cursor for
select custno, name, street, city, state, postal
from custfile
order by custno;
exec SQL open custlist;
exec SQL fetch next from custlist into :CUSTLIST;
yajl_genOpen(*on);
yajl_beginObj();
success = *on;
errmsg = '';
if %subst(sqlstt:1:2) <> '00' and %subst(sqlstt:1:2) <> '01';
success = *off;
errMsg = 'SQL State ' + sqlstt + ' querying customer list';
endif;
yajl_addBool('success': success);
yajl_addChar('errorMsg': errmsg);
if (success = *off);
yajl_endObj();
yajl_writeStdout(500: errMsg);
yajl_genClose();
return success;
endif;
yajl_beginArray('data');
dow %subst(sqlstt:1:2)='00' or %subst(sqlstt:1:2)='01';
yajl_beginObj();
yajl_addNum('custno': %char(custlist.custno));
yajl_addChar('name': %trim(custlist.name) );
yajl_beginObj('address');
yajl_addChar('street': %trim(custlist.street));
yajl_addChar('city': %trim(custlist.city));
yajl_addChar('state': custlist.state);
yajl_addChar('postal': %trim(custlist.postal));
yajl_endObj();
yajl_endObj();
exec SQL fetch next from custlist into :CUSTLIST;
enddo;
exec SQL close custlist;
if (success);
yajl_endArray();
endif;
yajl_endObj();
yajl_writeStdout(200: errMsg);
yajl_genClose();
return success;
end-proc;
--
_______________________________________________
Ftpapi mailing list
Ftpapi@xxxxxxxxxxxxxxxxxxxxxx
http://scottklement.com/mailman/listinfo/ftpapi