Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Command's `psc' backend
0003  *
0004  * @file cmd_psc.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 <utlist.h>
0039 #include <exhash.h>
0040 
0041 #include <ndrstandard.h>
0042 
0043 #include <ndebug.h>
0044 #include <userlog.h>
0045 #include <ndrxd.h>
0046 #include <ndrxdcmn.h>
0047 
0048 #include "cmd_processor.h"
0049 #include "bridge_int.h"
0050 #include <atmi_shm.h>
0051 /*---------------------------Externs------------------------------------*/
0052 /*---------------------------Macros-------------------------------------*/
0053 /*---------------------------Enums--------------------------------------*/
0054 /*---------------------------Typedefs-----------------------------------*/
0055 /*---------------------------Globals------------------------------------*/
0056 /*---------------------------Statics------------------------------------*/
0057 /*---------------------------Prototypes---------------------------------*/
0058 
0059 /**
0060  * Modify reply according the data.
0061  * @param call
0062  * @param pm
0063  */
0064 expublic void psc_reply_mod(command_reply_t *reply, size_t *send_size, mod_param_t *params)
0065 {
0066     command_reply_psc_t * psc_info = (command_reply_psc_t *)reply;
0067     pm_node_t *p_pm = (pm_node_t *)params->mod_param1;
0068     pm_node_svc_t *elt;
0069     /* we must be attached to shm! */
0070     shm_srvinfo_t * srv_shm = ndrxd_shm_getsrv(p_pm->srvid);
0071     int svc=0;
0072     /* nothing to do! */
0073     if (NULL==srv_shm)
0074     {
0075         userlog("No shm record for srvid %d!", p_pm->srvid);
0076         return;
0077     }
0078     
0079     reply->msg_type = NDRXD_CALL_TYPE_SVCINFO;
0080     /* calculate new send size */
0081     *send_size += (sizeof(command_reply_psc_t) - sizeof(command_reply_t));
0082 
0083     NDRX_STRCPY_SAFE(psc_info->binary_name, p_pm->binary_name);
0084     psc_info->srvid = p_pm->srvid;
0085     psc_info->state = p_pm->state;
0086     psc_info->nodeid = ndrx_get_G_atmi_env()->our_nodeid;
0087     /* Now build up stats? */
0088     
0089     /* Prepare service details... */
0090     DL_FOREACH(p_pm->svcs,elt)
0091     {
0092         psc_info->svcdet[svc].done=srv_shm->svc_succeed[svc];
0093         psc_info->svcdet[svc].fail=srv_shm->svc_fail[svc];
0094         psc_info->svcdet[svc].max=srv_shm->max_rsp_msec[svc];
0095         psc_info->svcdet[svc].min=srv_shm->min_rsp_msec[svc];
0096         psc_info->svcdet[svc].last=srv_shm->last_rsp_msec[svc];
0097         psc_info->svcdet[svc].status=srv_shm->svc_status[svc];
0098         NDRX_STRCPY_SAFE(psc_info->svcdet[svc].svc_nm, elt->svc.svc_nm);
0099         NDRX_STRCPY_SAFE(psc_info->svcdet[svc].fn_nm, elt->svc.fn_nm);
0100         svc++;
0101     }
0102     psc_info->svc_count = svc;
0103 
0104     /* additional size of services! */
0105     *send_size += psc_info->svc_count * sizeof(command_reply_psc_det_t);
0106 
0107     NDRX_LOG(log_debug, "magic: %ld", psc_info->rply.magic);
0108 }
0109 
0110 
0111 /**
0112  * Modify reply according the data (for bridge)
0113  * @param call
0114  * @param pm
0115  */
0116 expublic void psc_reply_mod_br(command_reply_t *reply, size_t *send_size, mod_param_t *params)
0117 {
0118     command_reply_psc_t * psc_info = (command_reply_psc_t *)reply;
0119     
0120     bridgedef_t *br = (bridgedef_t *)params->mod_param1;
0121     /*Service listing*/
0122     bridgedef_svcs_t *rs = (bridgedef_svcs_t *)params->mod_param3;
0123     int i;
0124     int svc=0;
0125     
0126     reply->msg_type = NDRXD_CALL_TYPE_SVCINFO;
0127     /* calculate new send size */
0128     *send_size += (sizeof(command_reply_psc_t) - sizeof(command_reply_t));
0129 
0130     NDRX_STRCPY_SAFE(psc_info->binary_name, "N/A");
0131     psc_info->srvid = EXFAIL;
0132     psc_info->state = EXFAIL;
0133     psc_info->nodeid = br->nodeid;
0134     /* Bridge svc id: */
0135     psc_info->srvid = br->srvid;
0136     /* Now build up stats? */
0137     
0138     /* Prepare service details... */
0139     for (i=0; i<rs->count; i++)
0140     {
0141         psc_info->svcdet[svc].done=EXFAIL;
0142         psc_info->svcdet[svc].fail=EXFAIL;
0143         psc_info->svcdet[svc].max=EXFAIL;
0144         psc_info->svcdet[svc].min=EXFAIL;
0145         psc_info->svcdet[svc].last=EXFAIL;
0146         psc_info->svcdet[svc].status=0;
0147         NDRX_STRCPY_SAFE(psc_info->svcdet[svc].svc_nm, rs->svc_nm);
0148         NDRX_STRCPY_SAFE(psc_info->svcdet[svc].fn_nm, "N/A");
0149         svc++;
0150     }
0151     psc_info->svc_count = svc;
0152     
0153     /* additional size of services! */
0154     *send_size += psc_info->svc_count * sizeof(command_reply_psc_det_t);
0155     
0156     NDRX_LOG(log_debug, "magic: %ld", psc_info->rply.magic);
0157 }
0158 
0159 /**
0160  * Callback to report startup progress
0161  * @param call
0162  * @param pm
0163  * @return
0164  */
0165 exprivate void psc_progress(command_call_t * call, pm_node_t *pm)
0166 {
0167     int ret=EXSUCCEED;
0168     mod_param_t params;
0169 
0170     NDRX_LOG(log_debug, "startup_progress enter");
0171     memset(&params, 0, sizeof(mod_param_t));
0172 
0173     /* pass to reply process model node */
0174     params.mod_param1 = (void *)pm;
0175 
0176     if (EXSUCCEED!=simple_command_reply(call, ret, NDRXD_CALL_FLAGS_RSPHAVE_MORE,
0177                             /* hook up the reply */
0178                             &params, psc_reply_mod, 0L, 0, NULL))
0179     {
0180         userlog("Failed to send progress back to [%s]", call->reply_queue);
0181     }
0182 
0183     NDRX_LOG(log_debug, "startup_progress exit");
0184 }
0185 
0186 /**
0187  * Process bridge service
0188  * @param call
0189  * @param pm
0190  */
0191 exprivate void psc_progress_br(command_call_t * call, bridgedef_t *br, bridgedef_svcs_t *brs)
0192 {
0193     int ret=EXSUCCEED;
0194     mod_param_t params;
0195 
0196     NDRX_LOG(log_debug, "startup_progress enter");
0197     memset(&params, 0, sizeof(mod_param_t));
0198 
0199     /* pass to reply process model node */
0200     params.mod_param1 = br;
0201     params.mod_param3 = brs;
0202 
0203     if (EXSUCCEED!=simple_command_reply(call, ret, NDRXD_CALL_FLAGS_RSPHAVE_MORE,
0204                             /* hook up the reply */
0205                             &params, psc_reply_mod_br, 0L, 0, NULL))
0206     {
0207         userlog("Failed to send progress back to [%s]", call->reply_queue);
0208     }
0209 
0210     NDRX_LOG(log_debug, "startup_progress exit");
0211 }
0212 
0213 /**
0214  * Call to psc command
0215  * @param args
0216  * @return
0217  */
0218 expublic int cmd_psc (command_call_t * call, char *data, size_t len, int context)
0219 {
0220     int ret=EXSUCCEED;
0221     pm_node_t *pm;
0222     /*Bridge listing*/
0223     bridgedef_t *br = NULL;
0224     bridgedef_t *brt = NULL;
0225     /*Service listing*/
0226     bridgedef_svcs_t *brs;
0227     bridgedef_svcs_t *brst;
0228     
0229     /* list all services from all servers, right? */
0230     DL_FOREACH(G_process_model, pm)
0231     {
0232         if (NDRXD_PM_RUNNING_OK==pm->state)
0233             psc_progress(call, pm);
0234     }
0235     
0236     /* Process bridges? */
0237     EXHASH_ITER(hh, G_bridge_hash, br, brt)
0238     {
0239         EXHASH_ITER(hh, br->theyr_services, brs, brst)
0240         {
0241             psc_progress_br(call, br, brs);
0242         }
0243     }
0244     
0245     if (EXSUCCEED!=simple_command_reply(call, ret, 0L, NULL, NULL, 0L, 0, NULL))
0246     {
0247         userlog("Failed to send reply back to [%s]", call->reply_queue);
0248     }
0249     NDRX_LOG(log_warn, "cmd_psc returns with status %d", ret);
0250     
0251 out:
0252     return ret;
0253 }
0254 
0255 /* vim: set ts=4 sw=4 et smartindent: */