Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Integration library with different platforms.
0003  *   Currently provides linked entry points of tpsvrinit() and tpsvrdone(),
0004  *   but does call the registered callbacks (currently needed for golang linking)
0005  *
0006  * @file integra.c
0007  */
0008 /* -----------------------------------------------------------------------------
0009  * Enduro/X Middleware Platform for Distributed Transaction Processing
0010  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0011  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0012  * This software is released under one of the following licenses:
0013  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0014  * See LICENSE file for full text.
0015  * -----------------------------------------------------------------------------
0016  * AGPL license:
0017  *
0018  * This program is free software; you can redistribute it and/or modify it under
0019  * the terms of the GNU Affero General Public License, version 3 as published
0020  * by the Free Software Foundation;
0021  *
0022  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0023  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0024  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0025  * for more details.
0026  *
0027  * You should have received a copy of the GNU Affero General Public License along 
0028  * with this program; if not, write to the Free Software Foundation, Inc.,
0029  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0030  *
0031  * -----------------------------------------------------------------------------
0032  * A commercial use license is available from Mavimax, Ltd
0033  * contact@mavimax.com
0034  * -----------------------------------------------------------------------------
0035  */
0036 
0037 /*---------------------------Includes-----------------------------------*/
0038 #include <stdio.h>
0039 #include <stdlib.h>
0040 #include <ndrstandard.h>
0041 #include <ndebug.h>
0042 #include <utlist.h>
0043 #include <string.h>
0044 #include <unistd.h>
0045 
0046 #include "srv_int.h"
0047 #include <atmi_int.h>
0048 #include <tx.h>
0049 /*---------------------------Externs------------------------------------*/
0050 /*---------------------------Macros-------------------------------------*/
0051 /*---------------------------Enums--------------------------------------*/
0052 /*---------------------------Typedefs-----------------------------------*/
0053 /*---------------------------Globals------------------------------------*/
0054 
0055 /** server init call */
0056 expublic int (*G_tpsvrinit__)(int, char **) = NULL;
0057 
0058 /** system call for server init */
0059 expublic int (*ndrx_G_tpsvrinit_sys)(int, char **) = NULL;
0060 
0061 /** call for server done */
0062 expublic void (*G_tpsvrdone__)(void) = NULL;
0063 
0064 /** No jump please (default for integra) */
0065 expublic long G_libatmisrv_flags     =   ATMI_SRVLIB_NOLONGJUMP; 
0066 
0067 /** Server boot structure           */
0068 expublic NDRX_API_EXPORT struct tmsvrargs_t *ndrx_G_tmsvrargs = NULL;
0069 /** XA Switch passed to server      */
0070 expublic NDRX_API_EXPORT struct xa_switch_t *ndrx_G_p_xaswitch = NULL;
0071 
0072 /** Server init func        */
0073 expublic int (*ndrx_G_tpsvrthrinit)(int, char **) = NULL;
0074 
0075 /** thread server done func */
0076 expublic void (*ndrx_G_tpsvrthrdone)(void) = NULL;
0077 
0078 /*---------------------------Statics------------------------------------*/
0079 /*---------------------------Prototypes---------------------------------*/
0080 
0081 /**
0082  * Return built in switch
0083  * @return 
0084  */
0085 expublic struct xa_switch_t * ndrx_xa_builtin_get(void)
0086 {
0087     return ndrx_G_p_xaswitch;
0088 }
0089 
0090 /**
0091  * Dummy for build compatibility
0092  * @param 
0093  * @return 
0094  */
0095 expublic int _tmrunserver(int arg1)
0096 {
0097     
0098   return 0;
0099 }
0100 
0101 /**
0102  * System init, advertise by table.
0103  * TODO: This shall use -N flag. Also new param -S shall be introduced
0104  * which would allow to advertise by function names from CLI. Probably parsed
0105  * lists and flags shall be pushed in some global variable so that we do not corrupt
0106  * the current position of the opts parser.
0107  * Also -N shall be applied to these bellow services which we are about to advertise???
0108  * Also -s flag shall be processed here against the system services...
0109  * or that will be done later, not ?
0110  * So if we use -N and we have -S aliases, then not having -s will kill the service first
0111  * maybe we need to automatically "unblacklist particular service" ??
0112  * Thus any function aliased service must be added to G_server_conf.svc_list with out further
0113  * aliase. Then it will pass the advertise loop
0114  * @param argc CLI arg count
0115  * @param argv CLI values
0116  * @return EXSUCCEED/EXFAIL
0117  */
0118 exprivate int tpsrvinit_sys(int argc, char** argv)
0119 {
0120     int ret = EXSUCCEED;
0121     struct tmdsptchtbl_t *tab = ndrx_G_tmsvrargs->svctab;
0122     svc_entry_t *el;
0123     int found;
0124     if (NULL!=tab)
0125     {
0126         /* run advertise loop over all services */
0127         while (NULL!=tab->svcnm)
0128         {
0129             /* advertise only if have service name */
0130             if (EXEOS!=tab->svcnm[0] &&
0131                     !G_server_conf.no_built_advertise &&
0132                     EXSUCCEED!=tpadvertise_full(tab->svcnm, tab->p_func, tab->funcnm))
0133             {
0134                 if (tperrno!=TPEMATCH)
0135                 {
0136                     NDRX_LOG(log_error, "Failed to advertise svcnm "
0137                         "[%s] funcnm [%s] ptr=%p: %s",
0138                         tab->svcnm, tab->funcnm, tab->p_func,
0139                         tpstrerror(tperrno));
0140                     EXFAIL_OUT(ret);
0141                 }
0142             }
0143         
0144             tab++;
0145         }
0146         
0147         /* run -S loop function maps -> loop over G_server_conf.funcsvc_list
0148          * and loop over the "svctab", find the functions, and call the
0149          * tpadvertise_full call.
0150          */
0151         DL_FOREACH(G_server_conf.funcsvc_list, el)
0152         {
0153             tab = ndrx_G_tmsvrargs->svctab;
0154             found = EXFALSE;
0155             while (NULL!=tab->svcnm)
0156             {
0157                 if ((0==strcmp(el->svc_aliasof, tab->funcnm)) ||
0158                     (EXEOS==el->svc_aliasof[0] && 0==strcmp(el->svc_nm, tab->funcnm)))
0159                 {
0160                     /* advertise only if have service name */
0161                     if (EXSUCCEED!=tpadvertise_full(el->svc_nm, tab->p_func, tab->funcnm))
0162                     {
0163                         if (tperrno!=TPEMATCH)
0164                         {
0165                             NDRX_LOG(log_error, "Failed to advertise svcnm "
0166                                 "[%s] funcnm [%s] ptr=%p: %s",
0167                                 el->svc_nm, tab->funcnm, tab->p_func,
0168                                 tpstrerror(tperrno));
0169                             EXFAIL_OUT(ret);
0170                         }
0171                     }
0172                     
0173                     /* Adding this service to exception list
0174                      * in case if doing G_server_conf.advertise_all=0
0175                      * As -S we shall still present in the final
0176                      */
0177                     if (!G_server_conf.advertise_all)
0178                     {
0179                         NDRX_LOG(log_debug, "Marking alias of function [%s] for advertise", el->svc_nm);
0180                         if (EXSUCCEED!=ndrx_svchash_add(&ndrx_G_svchash_funcs, el->svc_nm))
0181                         {
0182                             NDRX_LOG(log_error, "Failed to mark service [%s] for advertise",
0183                                     el->svc_nm);
0184                             EXFAIL_OUT(ret);
0185                         }
0186                     }
0187                     
0188                     found = EXTRUE;
0189                     break;
0190                 }
0191                 tab++;
0192             }
0193             
0194             if (!found)
0195             {
0196                 ndrx_TPset_error_fmt(TPEMATCH, "ERROR Function not found for "
0197                         "service mapping (-S) service name [%s] function [%s]!",
0198                         el->svc_nm, el->svc_aliasof);
0199                 EXFAIL_OUT(ret);
0200             }
0201         }
0202         
0203     } /* if there is tab */
0204     
0205 out:
0206     return ret;
0207 }
0208 
0209 /**
0210  * Forward the call to NDRX
0211  */
0212 expublic int ndrx_main_integra(int argc, char** argv, int (*in_tpsvrinit)(int, char **), 
0213             void (*in_tpsvrdone)(void), long flags) 
0214 {
0215 
0216     G_tpsvrinit__ =  in_tpsvrinit;
0217     G_tpsvrdone__ =  in_tpsvrdone;
0218     G_libatmisrv_flags = flags;
0219 
0220     return ndrx_main(argc, argv);
0221 }
0222 
0223 /**
0224  * Boot the Enduro/X 
0225  * Feature #397
0226  * @param argc command line argument count
0227  * @param argv command line values
0228  * @param tmsvrargs server startup info
0229  * @return EXSUCCEED/EXFAIL
0230  */
0231 expublic int _tmstartserver( int argc, char **argv, struct tmsvrargs_t *tmsvrargs)
0232 {
0233     int ret = EXSUCCEED;
0234     
0235     if (NULL==tmsvrargs)
0236     {
0237         NDRX_LOG(log_error, "Error ! tmsvrargs is NULL!");
0238         userlog("Error ! tmsvrargs is NULL!");
0239         EXFAIL_OUT(ret);
0240     }
0241     
0242     ndrx_G_tmsvrargs = tmsvrargs;
0243     
0244     if (NULL!=tmsvrargs)
0245     {
0246         ndrx_G_p_xaswitch = tmsvrargs->xa_switch;
0247     }
0248     G_libatmisrv_flags = 0;
0249     
0250     G_tpsvrinit__ =  tmsvrargs->p_tpsvrinit;
0251     /* use system init locally provided */
0252     ndrx_G_tpsvrinit_sys = tpsrvinit_sys;
0253     G_tpsvrdone__ =  tmsvrargs->p_tpsvrdone;
0254     
0255     /* warning ! for rearly releases p_tpsvrthrinit and p_tpsvrthrdone where
0256      * not present.
0257      */
0258     ndrx_G_tpsvrthrinit = tmsvrargs->p_tpsvrthrinit;
0259     ndrx_G_tpsvrthrdone = tmsvrargs->p_tpsvrthrdone;
0260     
0261 out:
0262     return ndrx_main(argc, argv);
0263 }
0264 
0265 /**
0266  * Default thread init
0267  * @param argc
0268  * @param argv
0269  * @return 
0270  */
0271 expublic int tpsvrthrinit(int argc, char **argv)
0272 {
0273     int ret=EXSUCCEED;
0274     
0275     NDRX_LOG(log_info, "Default tpsvrthrinit()");
0276     
0277     if (EXSUCCEED!=tx_open())
0278     {
0279         userlog("tx_open() failed: %s", tpstrerror(tperrno));
0280         ret=EXFAIL;
0281     }
0282     
0283     return EXSUCCEED;
0284 }
0285 
0286 /**
0287  * Default version of server init as required in API standard.
0288  * 
0289  * @param argc command line argument count
0290  * @param argv array of cli arguments
0291  * @return EXSUCCEED/EXFAIL
0292  */
0293 expublic int tpsvrinit(int argc, char **argv)
0294 {
0295     int ret =  EXSUCCEED;
0296     
0297     NDRX_LOG(log_info, "Default tpsvrinit() _tmbuilt_with_thread_option=%d",
0298             _tmbuilt_with_thread_option);
0299     
0300     userlog("Default tpsvrinit() function used");
0301     /*
0302      * Only if not multi-threaded
0303      */
0304     if (!_tmbuilt_with_thread_option)
0305     {
0306         if (NULL!=ndrx_G_tpsvrthrinit)
0307         {
0308             if (EXSUCCEED!=(ret=ndrx_G_tpsvrthrinit(argc, argv)))
0309             {
0310                 EXFAIL_OUT(ret);
0311             }
0312         }
0313         else
0314         {
0315             NDRX_LOG(log_warn, "tpsvrthrinit() not set");
0316         }
0317     }
0318     
0319 out:
0320     
0321     if (EXSUCCEED==ret)
0322     {
0323         userlog("Server started successfully");
0324     }
0325 
0326     return ret;
0327 }
0328 
0329 /**
0330  * Default function for server thread done
0331  */
0332 expublic void tpsvrthrdone(void)
0333 {
0334     NDRX_LOG(log_info, "Default tpsvrthrdone()");
0335     if (EXSUCCEED!=tx_close())
0336     {
0337         userlog("tx_close() failed: %s", tpstrerror(tperrno));
0338     }
0339 }
0340 
0341 /**
0342  * Server done, default version
0343  */
0344 expublic void tpsvrdone(void)
0345 {
0346     
0347     NDRX_LOG(log_info, "Default tpsvrdone()");
0348     userlog("Default tpsvrdone() function used");
0349     
0350     /* only for single threaded */
0351     if (!_tmbuilt_with_thread_option)
0352     {
0353         /* if calling from older version with direct binary upgrade
0354          * then the only chance it is not backwards compatible is in case
0355          * if default tpsrvinit and done is used.
0356          * all other versions may directly upgrade as, these fields are not
0357          * used else where
0358          * (exept in MT mode)
0359          */
0360         if (NULL!=ndrx_G_tpsvrthrdone)
0361         {
0362             ndrx_G_tpsvrthrdone();
0363         }
0364         else
0365         {
0366             userlog("tpsvrthrdone() not set");
0367         }
0368     }
0369 }
0370 
0371 /* vim: set ts=4 sw=4 et smartindent: */