Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief List messages
0003  *
0004  * @file cmd_mqlm.c
0005  */
0006 /* -----------------------------------------------------------------------------
0007  * Enduro/X Middleware Platform for Distributed Transaction Processing
0008  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0009  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0010  * This software is released under one of the following licenses:
0011  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0012  * See LICENSE file for full text.
0013  * -----------------------------------------------------------------------------
0014  * AGPL license:
0015  *
0016  * This program is free software; you can redistribute it and/or modify it under
0017  * the terms of the GNU Affero General Public License, version 3 as published
0018  * by the Free Software Foundation;
0019  *
0020  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0021  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0022  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0023  * for more details.
0024  *
0025  * You should have received a copy of the GNU Affero General Public License along 
0026  * with this program; if not, write to the Free Software Foundation, Inc.,
0027  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0028  *
0029  * -----------------------------------------------------------------------------
0030  * A commercial use license is available from Mavimax, Ltd
0031  * contact@mavimax.com
0032  * -----------------------------------------------------------------------------
0033  */
0034 #include <string.h>
0035 #include <stdio.h>
0036 #include <stdlib.h>
0037 #include <memory.h>
0038 #include <sys/param.h>
0039 
0040 #include <ndrstandard.h>
0041 #include <ndebug.h>
0042 #include <nstdutil.h>
0043 
0044 #include <ndrxdcmn.h>
0045 #include <atmi_int.h>
0046 #include <gencall.h>
0047 #include <utlist.h>
0048 #include <Exfields.h>
0049 
0050 #include "xa_cmn.h"
0051 #include <ndrx.h>
0052 #include <qcommon.h>
0053 #include <nclopt.h>
0054 /*---------------------------Externs------------------------------------*/
0055 /*---------------------------Macros-------------------------------------*/
0056 /*---------------------------Enums--------------------------------------*/
0057 /*---------------------------Typedefs-----------------------------------*/
0058 /*---------------------------Globals------------------------------------*/
0059 /*---------------------------Statics------------------------------------*/
0060 exprivate char M_qspace[XATMI_SERVICE_NAME_LENGTH+1] = "";
0061 /*---------------------------Prototypes---------------------------------*/
0062 
0063 /**
0064  * Print header
0065  * @return
0066  */
0067 exprivate void print_hdr(void)
0068 {
0069     fprintf(stderr, "Nd SRVID MSGID (STR/Base64 mod)                            TSTAMP (UTC) TRIES L\n");
0070     fprintf(stderr, "-- ----- -------------------------------------------- ----------------- ----- -\n");
0071 }
0072 
0073 /**
0074  * List queue definitions
0075  * We will run in conversation mode.
0076  * @param svcnm
0077  * @return SUCCEED/FAIL
0078  */
0079 exprivate int print_buffer(UBFH *p_ub, char *svcnm)
0080 {
0081     int ret = EXSUCCEED;
0082     
0083     short nodeid;
0084     short srvid;
0085     
0086     char msgid_str[TMMSGIDLEN_STR+1];
0087     
0088     char tstamp1[20];
0089     char tstamp2[20];
0090     long tires;
0091     short is_locked;
0092     
0093     if (
0094             EXSUCCEED!=Bget(p_ub, TMNODEID, 0, (char *)&nodeid, 0L) ||
0095             EXSUCCEED!=Bget(p_ub, TMSRVID, 0, (char *)&srvid, 0L) ||
0096             EXSUCCEED!=Bget(p_ub, EX_QMSGIDSTR, 0, msgid_str, 0L)  ||
0097             EXSUCCEED!=Bget(p_ub, EX_TSTAMP1_STR, 0, tstamp1, 0L) ||
0098             EXSUCCEED!=Bget(p_ub, EX_TSTAMP2_STR, 0, tstamp2, 0L) ||
0099             EXSUCCEED!=Bget(p_ub, EX_QMSGTRIES, 0, (char *)&tires, 0L) ||
0100             EXSUCCEED!=Bget(p_ub, EX_QMSGLOCKED, 0, (char *)&is_locked, 0L)
0101         )
0102     {
0103         fprintf(stderr, "Protocol error - TMQ did not return data, see logs!\n");
0104         NDRX_LOG(log_error, "Failed to read fields: [%s]", 
0105                 Bstrerror(Berror));
0106         EXFAIL_OUT(ret);
0107     }    
0108        
0109     fprintf(stdout, "%2d %5d %-44.44s %17.17s %5.5s %s",
0110             nodeid, 
0111             srvid, 
0112             msgid_str,
0113             tstamp1+2, 
0114             ndrx_decode_num(tires, 0, 0, 1),
0115             is_locked?"Y":"N"
0116             );
0117     
0118     printf("\n");
0119     
0120 out:
0121     return ret;
0122 }
0123 
0124 /**
0125  * This basically tests the normal case when all have been finished OK!
0126  * @return
0127  */
0128 exprivate int call_tmq(char *svcnm, char *qname)
0129 {
0130     UBFH *p_ub = (UBFH *)tpalloc("UBF", "", 1024);
0131     int ret=EXSUCCEED;
0132     int cd;
0133     long revent;
0134     int recv_continue = 1;
0135     int tp_errno;
0136     int rcv_count = 0;
0137     char cmd = TMQ_CMD_MQLM;
0138     
0139     /* Setup the call buffer... */
0140     if (NULL==p_ub)
0141     {
0142         NDRX_LOG(log_error, "Failed to alloc FB!");        
0143         EXFAIL_OUT(ret);
0144     }
0145     
0146     if (EXSUCCEED!=Bchg(p_ub, EX_QCMD, 0, &cmd, 0L))
0147     {
0148         NDRX_LOG(log_error, "Failed to install command code");
0149         EXFAIL_OUT(ret);
0150     }
0151     
0152     if (EXSUCCEED!=Bchg(p_ub, EX_QNAME, 0, qname, 0L))
0153     {
0154         NDRX_LOG(log_error, "Failed to install qname");
0155         EXFAIL_OUT(ret);
0156     }
0157     
0158     if (EXFAIL == (cd = tpconnect(svcnm,
0159                                     (char *)p_ub,
0160                                     0,
0161                                     TPNOTRAN |
0162                                     TPRECVONLY)))
0163     {
0164         NDRX_LOG(log_error, "Connect error [%s]", tpstrerror(tperrno) );
0165         ret = EXFAIL;
0166         goto out;
0167     }
0168     NDRX_LOG(log_debug, "Connected OK, cd = %d", cd );
0169 
0170     while (recv_continue)
0171     {
0172         recv_continue=0;
0173         if (EXFAIL == tprecv(cd,
0174                             (char **)&p_ub,
0175                             0L,
0176                             0L,
0177                             &revent))
0178         {
0179             ret = EXFAIL;
0180             tp_errno = tperrno;
0181             if (TPEEVENT == tp_errno)
0182             {
0183                     if (TPEV_SVCSUCC == revent)
0184                             ret = EXSUCCEED;
0185                     else
0186                     {
0187                         NDRX_LOG(log_error,
0188                                  "Unexpected conv event %lx", revent );
0189                         EXFAIL_OUT(ret);
0190                     }
0191             }
0192             else
0193             {
0194                 NDRX_LOG(log_error, "recv error %d", tp_errno  );
0195                 EXFAIL_OUT(ret);
0196             }
0197         }
0198         else
0199         {
0200             if (EXSUCCEED!=print_buffer(p_ub, svcnm))
0201             {
0202                 EXFAIL_OUT(ret);
0203             }
0204             rcv_count++;
0205             recv_continue=1;
0206         }
0207     }
0208 
0209 out:
0210 
0211     if (NULL!=p_ub)
0212     {
0213         tpfree((char *)p_ub);
0214     }
0215 
0216     return ret;
0217 }
0218 
0219 /**
0220  * Filter the service names, return TRUE for those which matches individual TMs
0221  * @param svcnm
0222  * @return TRUE/FALSE
0223  */
0224 exprivate int mqfilter_qspace(char *svcnm)
0225 {
0226     char tmp[XATMI_SERVICE_NAME_LENGTH+1];
0227     
0228     
0229     snprintf(tmp, sizeof(tmp), NDRX_SVC_QSPACE, M_qspace);
0230     
0231     
0232     if (0==strcmp(svcnm, tmp))
0233     {
0234         return EXTRUE;
0235     }
0236     
0237     return EXFALSE;
0238 }
0239 
0240 
0241 /**
0242  * List messages in q
0243  * @param p_cmd_map
0244  * @param argc
0245  * @param argv
0246  * @return SUCCEED
0247  */
0248 expublic int cmd_mqlm(cmd_mapping_t *p_cmd_map, int argc, char **argv, int *p_have_next)
0249 {
0250     int ret = EXSUCCEED;
0251     atmi_svc_list_t *el, *tmp, *list;
0252     char qname[TMQNAMELEN+1];
0253     
0254     ncloptmap_t clopt[] =
0255     {
0256         {'s', BFLD_STRING, M_qspace, sizeof(M_qspace)-3, 
0257                                 NCLOPT_MAND|NCLOPT_HAVE_VALUE, "Qspace name"},
0258         {'q', BFLD_STRING, qname, sizeof(qname), 
0259                                 NCLOPT_MAND|NCLOPT_HAVE_VALUE, "Queue name"},
0260         {0}
0261     };
0262     
0263     /* parse command line */
0264     if (nstd_parse_clopt(clopt, EXTRUE,  argc, argv, EXFALSE))
0265     {
0266         fprintf(stderr, XADMIN_INVALID_OPTIONS_MSG);
0267         EXFAIL_OUT(ret);
0268     }
0269     
0270     
0271     /* we need to init TP subsystem... */
0272     if (EXSUCCEED!=tpinit(NULL))
0273     {
0274         fprintf(stderr, "Failed to tpinit(): %s\n", tpstrerror(tperrno));
0275         EXFAIL_OUT(ret);
0276     }
0277     
0278     print_hdr();
0279     
0280     list = ndrx_get_svc_list(mqfilter_qspace);
0281     
0282     LL_FOREACH_SAFE(list,el,tmp)
0283     {
0284         
0285         NDRX_LOG(log_info, "About to call service: [%s]\n", el->svcnm);
0286 
0287         call_tmq(el->svcnm, qname);
0288         /* Have some housekeep. */
0289         LL_DELETE(list,el);
0290         NDRX_FREE(el);
0291     }
0292     
0293 out:
0294     return ret;
0295 }
0296 
0297 /* vim: set ts=4 sw=4 et smartindent: */