Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief XID Convert from/to DB, using Java format so that we can share the
0003  *   C based tmsrv with Java code for faster operations.
0004  *
0005  * @file pgxid.c
0006  */
0007 /* -----------------------------------------------------------------------------
0008  * Enduro/X Middleware Platform for Distributed Transaction Processing
0009  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0010  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0011  * This software is released under one of the following licenses:
0012  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0013  * See LICENSE file for full text.
0014  * -----------------------------------------------------------------------------
0015  * AGPL license:
0016  *
0017  * This program is free software; you can redistribute it and/or modify it under
0018  * the terms of the GNU Affero General Public License, version 3 as published
0019  * by the Free Software Foundation;
0020  *
0021  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0022  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0023  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0024  * for more details.
0025  *
0026  * You should have received a copy of the GNU Affero General Public License along 
0027  * with this program; if not, write to the Free Software Foundation, Inc.,
0028  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0029  *
0030  * -----------------------------------------------------------------------------
0031  * A commercial use license is available from Mavimax, Ltd
0032  * contact@mavimax.com
0033  * -----------------------------------------------------------------------------
0034  */
0035 #include <stdlib.h>
0036 #include <string.h>
0037 #include <memory.h>
0038 #include <ctype.h>
0039 #include <errno.h>
0040 
0041 #include <userlog.h>
0042 
0043 #include <ndrstandard.h>
0044 #include <ndebug.h>
0045 
0046 #include <exparson.h>
0047 #include <pgxa.h>
0048 #include <exbase64.h>
0049 
0050 #include "xa.h"
0051 
0052 /*------------------------------Externs---------------------------------------*/
0053 /*------------------------------Macros----------------------------------------*/
0054 /*------------------------------Enums-----------------------------------------*/
0055 /*------------------------------Typedefs--------------------------------------*/
0056 /*------------------------------Globals---------------------------------------*/
0057 /*------------------------------Statics---------------------------------------*/
0058 /*------------------------------Prototypes------------------------------------*/
0059 
0060 /**
0061  * Convert XID to Posgres in PG JDBC Format style
0062  * @param[in] xid C XID
0063  * @param[out] buf output buffer 
0064  * @param[in] output buffer size
0065  * @return EXSUCCEED/EXFAIL
0066  */
0067 expublic int ndrx_pg_xid_to_db(XID *xid, char *buf, int bufsz)
0068 {
0069     int ret = EXSUCCEED;
0070     size_t outsz = 0;
0071     size_t curpos;
0072     snprintf(buf, bufsz, "%ld", xid->formatID);
0073     
0074     NDRX_STRCAT_S(buf, bufsz, "_");
0075     
0076     curpos = strlen(buf);
0077             
0078     outsz = bufsz - curpos;
0079     if (NULL==ndrx_base64_encode((unsigned char *)xid->data,
0080                     xid->gtrid_length,
0081                     &outsz,
0082                     buf + curpos))
0083     {
0084         NDRX_LOG(log_error, "Failed to encode gtrid!");
0085         EXFAIL_OUT(ret);
0086     }
0087     
0088     /* *(buf + curpos + outsz) = EXEOS; */
0089     
0090     NDRX_STRCAT_S(buf, bufsz, "_");
0091     
0092     
0093     curpos = strlen(buf);
0094     
0095     /* build up the bqual part */
0096     outsz = bufsz - curpos;
0097     if (NULL==ndrx_base64_encode((unsigned char *)xid->data + xid->gtrid_length,
0098                     xid->bqual_length,
0099                     &outsz,
0100                     buf + curpos))
0101     {
0102         NDRX_LOG(log_error, "Failed to encode bqual!");
0103         EXFAIL_OUT(ret);
0104     }
0105     
0106     /* *(buf + curpos + outsz) = EXEOS; */
0107     
0108     NDRX_LOG(log_debug, "Got PG XID: [%s]", buf);
0109     
0110     
0111 out:
0112     return ret;
0113 }
0114 
0115 /**
0116  * Convert Database TX ID to XID
0117  * @param[in] buf db string.
0118  * @param[out] xid XID 
0119  * @return EXSUCCEED/EXFAIL (invalid format)
0120  */
0121 expublic int ndrx_pg_db_to_xid(char *buf, XID *xid)
0122 {
0123     int ret = EXSUCCEED;
0124     char *tok, *saveptr1;
0125     int cnt=0;
0126     char tmp[201];
0127     size_t len;
0128     int i;
0129     
0130     NDRX_STRCPY_SAFE(tmp, buf);
0131     
0132     NDRX_LOG(log_debug, "About to process PG xid: [%s]", tmp);
0133     
0134     len = strlen(buf);
0135     
0136     for (i=0; i<len; i++)
0137     {
0138         if ('_'==buf[i])
0139         {
0140             cnt++;
0141         }
0142     }
0143     
0144     if (cnt!=2)
0145     {
0146         NDRX_LOG(log_warn, "Not Enduor/X XID format transaction id: "
0147                 "[%s] - not parsing", buf);
0148         goto out;
0149     }
0150     
0151     cnt=0;
0152     tok=strtok_r (tmp, "_", &saveptr1);
0153     while( tok != NULL ) 
0154     {
0155         NDRX_LOG(log_debug, "Got token: [%s]", tok);
0156         switch (cnt)
0157         {
0158             case 0:
0159                 /* format id */
0160                 xid->formatID = atol(tok);
0161                 break;
0162             case 1:
0163                 
0164                 /* gtrid */
0165                 len = MAXGTRIDSIZE;
0166                 if (NULL==ndrx_base64_decode(tok, strlen(tok), &len, xid->data))
0167                 {
0168                     NDRX_LOG(log_error, "Failed to decode gtrid!");
0169                     EXFAIL_OUT(ret);
0170                 }
0171                 xid->gtrid_length = len;
0172                 
0173                 NDRX_LOG(log_debug, "gtrid len: %d", xid->gtrid_length);
0174                 
0175                 break;
0176             case 2:
0177                 /* bqual */
0178                 len = MAXBQUALSIZE;
0179                 if (NULL==ndrx_base64_decode(tok, strlen(tok), 
0180                         &len, xid->data+xid->gtrid_length))
0181                 {
0182                     NDRX_LOG(log_error, "Failed to decode bqual!");
0183                     EXFAIL_OUT(ret);
0184                 }
0185                 xid->bqual_length = len;
0186                 NDRX_LOG(log_debug, "bqual len: %d", xid->bqual_length);
0187                 
0188                 break;
0189             default:
0190                 /* Invalid format ID! */
0191                 NDRX_LOG(log_error, "Invalid PG XID, token nr: %d", cnt);
0192                 EXFAIL_OUT(ret);
0193                 break;
0194         }
0195         cnt++;
0196         tok=strtok_r (NULL,"_", &saveptr1);
0197     }
0198     
0199     NDRX_DUMP(log_debug, "Got XID from PG", xid, sizeof(*xid));
0200 
0201 out:
0202 
0203     return ret;
0204 }
0205 
0206 /* vim: set ts=4 sw=4 et smartindent: */