Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Return connection infos
0003  *
0004  * @file brcon.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 <stdio.h>
0035 #include <stdlib.h>
0036 #include <string.h>
0037 #include <errno.h>
0038 #include <regex.h>
0039 #include <utlist.h>
0040 #include <unistd.h>
0041 #include <signal.h>
0042 #include <fcntl.h>
0043 
0044 #include <ndebug.h>
0045 #include <atmi.h>
0046 #include <atmi_int.h>
0047 #include <typed_buf.h>
0048 #include <ndrstandard.h>
0049 #include <ubf.h>
0050 #include <Exfields.h>
0051 #include <Excompat.h>
0052 #include <ubfutil.h>
0053 #include <sys_unix.h>
0054 #include <gencall.h>
0055 #include "tpadmsv.h"
0056 #include "expr.h"
0057 /*---------------------------Externs------------------------------------*/
0058 /*---------------------------Macros-------------------------------------*/
0059 /*---------------------------Enums--------------------------------------*/
0060 /*---------------------------Typedefs-----------------------------------*/
0061     
0062 /**
0063  * Clock infos metrics from connected bridges
0064  */
0065 typedef struct 
0066 {
0067     long nodeid;    /**< local node id                      */
0068     long srvid;     /**< Server id generating resposne      */
0069     long remnodeid; /**< remove node id                     */
0070     char mode;      /**< Connection mode                    */   
0071     long fd;        /**< socket FD number                   */
0072     
0073     long time;      /**< local monotonic time s             */
0074     
0075     /* Clock: */
0076     long conseq;    /**< connection sequence                */
0077     long lastsync;  /**< last sync time ago (seconds)       */
0078     long timediff;  /**< time diff in seconds between hosts */
0079     long timediffms;/**< time diff in seconds between hosts */
0080     long roundtrip; /**< roundtrip in milliseconds          */
0081     
0082     
0083 } ndrx_adm_brcon_t;
0084 
0085 /**
0086  * Bridge clock data
0087  */
0088 expublic ndrx_adm_elmap_t ndrx_G_brcon_map[] =
0089 {  
0090     /* Driving of the Preparing: */
0091      {TA_EX_NODEID,            TPADM_EL(ndrx_adm_brcon_t, nodeid)}
0092     ,{TA_SRVID,                TPADM_EL(ndrx_adm_brcon_t, srvid)}
0093     ,{TA_EX_REMNODEID,         TPADM_EL(ndrx_adm_brcon_t, remnodeid)}
0094     ,{TA_EX_FD,                TPADM_EL(ndrx_adm_brcon_t, fd)}
0095     ,{TA_EX_CONMODE,           TPADM_EL(ndrx_adm_brcon_t, mode)}
0096     ,{TA_EX_TIME,              TPADM_EL(ndrx_adm_brcon_t, time)}
0097     ,{TA_EX_LASTSYNC,          TPADM_EL(ndrx_adm_brcon_t, lastsync)}
0098     ,{TA_EX_TIMEDIFF,          TPADM_EL(ndrx_adm_brcon_t, timediff)}
0099     ,{TA_EX_TIMEDIFFF,         TPADM_EL(ndrx_adm_brcon_t, timediffms)}
0100     ,{TA_EX_ROUNDTRIP,         TPADM_EL(ndrx_adm_brcon_t, roundtrip)}
0101     ,{BBADFLDID}
0102 };
0103 
0104 /*---------------------------Globals------------------------------------*/
0105 /*---------------------------Statics------------------------------------*/
0106 
0107 exprivate ndrx_adm_cursors_t *M_cursnew;
0108 exprivate int M_idx;    /**< Current growlist index             */
0109 exprivate string_list_t *M_qlist; /**< list of admin queues  */
0110 
0111 /*---------------------------Prototypes---------------------------------*/
0112 
0113 /**
0114  * Process actual infos from bridge
0115  * @param reply
0116  * @param reply_len
0117  * @return EXSUCCED/EXFAIL
0118  */
0119 exprivate int ndrx_adm_brconinfo_proc_list(command_reply_t *reply, size_t reply_len)
0120 {
0121     command_reply_brconinfo_t * info = (command_reply_brconinfo_t*)reply;
0122     int ret = EXSUCCEED;
0123     ndrx_adm_brcon_t brcon;
0124     
0125     if (NDRXD_CALL_TYPE_BRCONINFO!=reply->msg_type)
0126     {
0127         /* not payload */
0128         goto out;
0129     }
0130 
0131     /* call the bridge */
0132     memset(&brcon, 0, sizeof(brcon));
0133     
0134     brcon.nodeid = info->locnodeid;
0135     brcon.srvid = info->srvid;
0136     brcon.fd = info->fd;
0137     brcon.mode = info->mode; 
0138     brcon.remnodeid = info->remnodeid;
0139     brcon.lastsync = info->lastsync;
0140     brcon.timediff = info->timediffs;
0141     brcon.timediffms = info->timediffms;
0142     brcon.roundtrip = info->roundtrip;
0143     
0144     brcon.time = info->time;
0145        
0146     if (EXSUCCEED!=ndrx_growlist_add(&M_cursnew->list, (void *)&brcon, M_idx))
0147     {
0148         NDRX_LOG(log_error, "Growlist failed - out of memory?");
0149         EXFAIL_OUT(ret);
0150     }
0151 
0152     M_idx++;
0153     
0154 out:
0155     return ret;
0156 }
0157 
0158 /**
0159  * Bridge admin Q listing
0160  * @param reply
0161  * @param reply_len
0162  * @return 
0163  */
0164 exprivate int ndrx_adm_blist_proc_list(command_reply_t *reply, size_t reply_len)
0165 {
0166     command_reply_blist_t * blist_info = (command_reply_blist_t*)reply;
0167     int ret = EXSUCCEED;
0168 
0169     if (NDRXD_CALL_TYPE_BLIST!=reply->msg_type)
0170     {
0171         /* not payload */
0172         goto out;
0173     }
0174     
0175     NDRX_LOG(log_debug, "Got admin Q for bridge: [%s]", blist_info->qstr);
0176 
0177     if (EXSUCCEED!=ndrx_string_list_add(&M_qlist, blist_info->qstr))
0178     {
0179         NDRX_LOG(log_error, "Failed to populate string list");
0180         EXFAIL_OUT(ret);
0181     }
0182     
0183 out:
0184     return ret;
0185 }
0186 
0187 /**
0188  * Read return clock of connected bridges
0189  * This assumes that we might handle multiple connections by one bridge
0190  * (atleast in future).
0191  * 
0192  * Firstly we need to get admin queues for the bridges from ndrxd by list call
0193  * Then each queue needs to request for list bridge infos.
0194  * 
0195  * @param clazz class name
0196  * @param cursnew this is new cursor domain model
0197  * @param flags not used
0198  */
0199 expublic int ndrx_adm_brcon_get(char *clazz, ndrx_adm_cursors_t *cursnew, long flags)
0200 {
0201     int ret = EXSUCCEED;
0202     string_list_t *qstr;
0203     
0204     /* init cursor */
0205     M_idx = 0;
0206     M_qlist = NULL;
0207     
0208     ndrx_growlist_init(&cursnew->list, 100, sizeof(ndrx_adm_brcon_t));
0209     
0210     M_cursnew = cursnew;
0211     cursnew->map = ndrx_G_brcon_map;
0212     
0213     if (EXSUCCEED!=ndrx_adm_list_call(ndrx_adm_blist_proc_list, 
0214             NDRXD_COM_BLIST_RQ, NDRXD_COM_BLIST_RP, ndrx_get_G_atmi_conf()->ndrxd_q_str))
0215     {
0216         NDRX_LOG(log_error, "Failed to call blist");
0217         EXFAIL_OUT(ret);
0218     }
0219     
0220     LL_FOREACH(M_qlist, qstr)
0221     {
0222         /* process the lists */
0223         if (EXSUCCEED!=ndrx_adm_list_call(ndrx_adm_brconinfo_proc_list, 
0224                 NDRXD_COM_BRCONINFO_RQ, NDRXD_COM_BRCONINFO_RP, qstr->qname))
0225         {
0226             NDRX_LOG(log_error, "Failed to call brclockinfo");
0227             EXFAIL_OUT(ret);
0228         }
0229     }
0230     
0231 out:
0232     
0233     if (EXSUCCEED!=ret)
0234     {
0235         ndrx_growlist_free(&M_cursnew->list);
0236     }
0237 
0238     /* free up the list */
0239     ndrx_string_list_free(M_qlist);
0240 
0241     return ret;
0242 }
0243 
0244 /* vim: set ts=4 sw=4 et smartindent: */