**free
//  WATSONTR5R:  This is a demo of Watson's Language Translator V3
//               using input/output with JSON documents.
//
//               This version uses the IBM port of AXISC
//               to implement HTTP and YAJL for JSON
//
//               Diagnostic info is written in /tmp/axistransport.log
//
ctl-opt option(*srcstmt) dftactGrp(*no)
        bnddir('AXIS');

/include /QIBM/ProdData/OS/WebServices/V1/client/include/Axis.rpgleinc

dcl-f WATSONTR1D workstn indds(dspf);

dcl-Ds dspf qualified;
   F3Exit ind pos(3);
end-Ds;

dcl-pr QCMDEXC extpgm;
  command char(200) const;
  length  packed(15: 5) const;
  igc char(3) const options(*nopass);
end-pr;

dcl-c UPPER 'ENESFRITPT';
dcl-c lower 'enesfritpt';

QCMDEXC('CHGJOB CCSID(37)': 200);

fromLang = 'en';
toLang   = 'es';

dou dspf.F3Exit = *on;

   exfmt screen1;
   if dspf.F3exit = *on;
      leave;
   endif;

   fromLang = %xlate(UPPER:lower:fromLang);
   toLang   = %xlate(UPPER:lower:toLang);
   toText = translate( fromLang: toLang: %trim(fromText) );

enddo;

*inlr = *on;
return;


dcl-proc translate;

   dcl-pi *n varchar(1000);
      fromLang char(2)       const;
      tolang   char(2)       const;
      fromText varchar(1000) const;
   end-pi;

   dcl-s userid   varchar(10);
   dcl-s password varchar(200);
   dcl-s hdr      varchar(200);
   dcl-s url      varchar(2000);
   dcl-s request  varchar(2000);
   dcl-s response varchar(5000);
   dcl-s rcvBuf   char(5000);
   dcl-s rc       int(10);
   dcl-s propName char(200);
   dcl-s propVal  char(200);
   dcl-s transportHandle pointer;

   dcl-ds result qualified;
     dcl-ds translations dim(1);
        translation varchar(1000) inz('');
     end-ds;
     word_count int(10) inz(0);
     character_count int(10) inz(0);
   end-ds;

   exec sql select json_object(
                     'source' value :fromLang,
                     'target' value :toLang,
                     'text' value json_array(:fromText)
                   )
              into :request
              from SYSIBM.SYSDUMMY1;
   if %subst(sqlstt:1:2) <> '00' and %subst(sqlstt:1:2) <> '01';
      return '**ERROR CREATING: SQLSTT=' + sqlstt;
   endif;

   axiscAxisStartTrace('/tmp/axistransport.log': *NULL);

   userid = 'apikey';
   password = '8OD0RY71zMwXjkNiBLzTN8i848R9wXMOmADjuvoKY2zw';

   url = 'https://gateway.watsonplatform.net/language-translator/api'
       + '/v3/translate?version=2018-05-01';

   transportHandle = axiscTransportCreate(url: AXISC_PROTOCOL_HTTP11);
   if (transportHandle = *null);
     failWithError(transportHandle: 'axiscTransportCreate');
   endif;

   propName = 'POST' + x'00';
   axiscTransportSetProperty( transportHandle
                            : AXISC_PROPERTY_HTTP_METHOD
                            : %addr(propName));

   propName = userid + x'00';
   propVal  = password + x'00';
   axiscTransportSetProperty( transportHandle
                            : AXISC_PROPERTY_HTTP_BASICAUTH
                            : %addr(propName)
                            : %addr(propVal) );

   propName = 'Content-Type' + x'00';
   propVal  = 'application/json' + x'00';

   axiscTransportSetProperty( transportHandle
                            : AXISC_PROPERTY_HTTP_HEADER
                            : %addr(propName)
                            : %addr(propVal) );

   propName = '*SYSTEM' + x'00';
   propVal = x'00';

   axiscTransportSetProperty( transportHandle
                            : AXISC_PROPERTY_HTTP_SSL
                            : %addr(propName)
                            : %addr(propVal) );

   rc = axiscTransportSend( transportHandle
                          : %addr(request: *data)
                          : %len(request)
                          : 0 );
   if rc = -1;
     failWithError(transportHandle: 'axiscTransportSend');
   endif;

   rc = axiscTransportFlush(transportHandle);
   if rc = -1;
     failWithError(transportHandle: 'axiscTransportFlush');
   endif;

   response = '';

   dou rc < 1;

     rc = axiscTransportReceive( transportHandle
                               : %addr(rcvBuf)
                               : %size(rcvBuf)
                               : 0 );
     if rc >= 1;
       response += %subst(rcvBuf:1:rc);
     endif;

   enddo;

   if rc = -1;
     failWithError(transportHandle: 'axiscTransportReceive');
   else;
     httpCode = getHttpStatus(transportHandle);
   endif;

   axiscTransportDestroy(transportHandle);

   if %len(response) > 0;
     data-into result %DATA(response) %PARSER('YAJLINTO');
   endif;

   return result.translations(1).translation;

end-Proc;


dcl-proc getHttpStatus;

  dcl-pi *n varchar(10);
    transportHandle pointer value;
  end-pi;

  dcl-s result varchar(10) inz('');
  dcl-s statusCode pointer;

  if transportHandle <> *null;
     axiscTransportGetProperty( transportHandle
                              : AXISC_PROPERTY_HTTP_STATUS_CODE
                              : %addr(statusCode) );
  endif;

  if statusCode <> *null;
    result = %str(statusCode);
  endif;

  return result;
end-proc;


dcl-proc getLastError;

  dcl-pi *n varchar(5000);
    transportHandle pointer value;
    errorNum int(10) options(*nopass);
    httpStatus varchar(100) options(*nopass);
  end-pi;

  dcl-s lastCode int(10);
  dcl-s lastMsg  varchar(5000);
  dcl-s statusCode varchar(10) inz('');

  // transportHandle should only be null if axiscCreateTransportHandle
  //   failed. Note that since the transport handle is used to retrieve
  //   the error message, there's no way to get the actual message in
  //   this case.

  if transportHandle = *null;

     lastCode = -1;
     lastMsg  = 'Could not create transport handle';

  else;

     lastCode = axiscTransportGetLastErrorCode(transportHandle);
     lastMsg  = %str(axiscTransportGetLastError(transportHandle));

     if lastCode = EXC_TRANSPORT_HTTP_EXCEPTION;
        statusCode = getHttpStatus(transportHandle);
     endif;

  endif;

  if %parms >= 2 and %addr(errorNum) <> *null;
    errorNum = lastCode;
  endif;

  if %parms >= 3 and %addr(httpStatus) <> *null;
    httpStatus = statusCode;
  endif;

  return lastMsg;

end-proc;



dcl-proc failWithError;

  dcl-pi *n;
    transportHandle pointer value;
    location varchar(100) const;
  end-pi;

  dcl-pr QMHSNDPM extpgm;
    msgid      char(7)     const;
    msgf       char(20)    const;
    msgdta     char(32767) const options(*varsize);
    msgdtalen  int(10)     const;
    msgtype    char(10)    const;
    callstack  char(10)    const;
    stackcount int(10)     const;
    msgkey     char(4);
    errorCode  char(32767) options(*varsize);
  end-pr;

  dcl-ds errorEscape qualified;
    bytesProv int(10) inz(0);
    bytesAvail int(10) inz(0);
  end-ds;

  dcl-s axisMsg    varchar(5000);
  dcl-s msg        varchar(5500);
  dcl-s errorNum   int(10);
  dcl-s httpStatus varchar(100);
  dcl-s msgkey     char(4);

  axisMsg = getLastError( transportHandle
                        : errorNum
                        : httpStatus );

  msg = %trimr(location) + ': '
      + %trimr(axisMsg)
      + ' (err=' + %char(errorNum)
      + ', status=' + %trim(httpStatus)
      + ')';

  if %len(axisMsg) > 0;
     QMHSNDPM( 'CPF9897'
             : 'QCPFMSG   QSYS'
             : msg
             : %len(msg)
             : '*ESCAPE'
             : '*'
             : 1
             : msgkey
             : errorEscape );
  endif;

end-proc; 
