Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Feature #139 mvitolin, 09/05/2017
0003  *   Test the shared memory service registry reuse - when unique service names
0004  *   in app session overflows the NDRX_SVCMAX
0005  *
0006  * @file atmisv34.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 #include <string.h>
0037 #include <stdio.h>
0038 #include <stdlib.h>
0039 #include <memory.h>
0040 #include <math.h>
0041 
0042 #include <ndebug.h>
0043 #include <atmi.h>
0044 
0045 
0046 #include <ubf.h>
0047 #include <Exfields.h>
0048 #include <test.fd.h>
0049 #include <ndrstandard.h>
0050 /*---------------------------Externs------------------------------------*/
0051 /*---------------------------Macros-------------------------------------*/
0052 
0053 #ifndef EXSUCCEED
0054 #define EXSUCCEED           0
0055 #endif
0056 
0057 #ifndef EXFAIL
0058 #define EXFAIL          -1
0059 #endif
0060 
0061 #define USED_SERVICES           2   /**< used by bootet server */
0062 /*---------------------------Enums--------------------------------------*/
0063 /*---------------------------Typedefs-----------------------------------*/
0064 /*---------------------------Globals------------------------------------*/
0065 /*---------------------------Statics------------------------------------*/
0066 /*---------------------------Prototypes---------------------------------*/
0067 
0068 /**
0069  * Dynamic function
0070  */
0071 void DYNFUNC(TPSVCINFO *p_svc)
0072 {
0073     int ret = EXSUCCEED;
0074     UBFH *p_ub = (UBFH *)p_svc->data;
0075 
0076     if (NULL==(p_ub = (UBFH *)tprealloc((char *)p_ub, 4096)))
0077     {
0078         EXFAIL_OUT(ret);
0079     }
0080 
0081     if (EXFAIL==Badd(p_ub, T_STRING_2_FLD, p_svc->name, 0L))
0082     {
0083         EXFAIL_OUT(ret);
0084     }
0085     
0086  out:
0087 
0088     tpreturn(  ret==EXSUCCEED?TPSUCCESS:TPFAIL,
0089             0L,
0090             (char *)p_ub,
0091             0L,
0092             0L);
0093 }
0094 
0095 /**
0096  * Check that when service table becomes full...
0097  * Afterwards remove all un-needed.
0098  * This shall be run first, we have 100 places in service table.
0099  * 2 is already used by this in GETNEXT
0100  * @return SUCCEED/FAIL
0101  */
0102 void CHKFULL (TPSVCINFO *p_svc)
0103 {
0104     int ret = EXSUCCEED;
0105     char svcnm[MAXTIDENT+1];
0106     long i, service_slots;
0107     long fill_max;
0108     UBFH *p_ub = (UBFH *)p_svc->data;
0109     
0110     if (EXFAIL==Bget(p_ub, T_LONG_FLD, 0, (char *)&service_slots, 0L))
0111     {
0112         NDRX_LOG(log_error, "Failed to get T_LONG_FLD: %s", Bstrerror(Berror));
0113         EXFAIL_OUT(ret);
0114     }
0115     
0116     NDRX_LOG(log_debug, "Fill all");
0117     fill_max = service_slots-USED_SERVICES;
0118     
0119     for (i=0; i<fill_max; i++)
0120     {
0121         snprintf(svcnm, sizeof(svcnm), "FULL%06ld", i);
0122         
0123         if (EXSUCCEED!=tpadvertise(svcnm, DYNFUNC))
0124         {
0125             NDRX_LOG(log_error, "TESTERROR! Failed to advertise [%s]: %s", 
0126                      svcnm, tpstrerror(tperrno));
0127             EXFAIL_OUT(ret);
0128         }
0129     }
0130     
0131     snprintf(svcnm, sizeof(svcnm), "FULL%06ld", i+1);
0132     /* that's it, all is full! */
0133     if (EXSUCCEED==tpadvertise(svcnm, DYNFUNC))
0134     {
0135         NDRX_LOG(log_error, "TESTERROR! We shall fail to advertise!");
0136         EXFAIL_OUT(ret);
0137     }
0138     
0139     if (TPELIMIT!=tperrno)
0140     {
0141         NDRX_LOG(log_error, "TESTERROR: Invalid error expected TPELIMIT got %d: %s", 
0142                 tperrno, tpstrerror(tperrno));
0143         EXFAIL_OUT(ret);
0144     }
0145 
0146     /* clean up the stuff.. */
0147     for (i=0; i<service_slots-USED_SERVICES; i++)
0148     {
0149         snprintf(svcnm, sizeof(svcnm), "FULL%06ld", i);
0150         
0151         if (EXSUCCEED!=tpunadvertise(svcnm))
0152         {
0153             NDRX_LOG(log_error, "TESTERROR! Failed to advertise [%s]: %s", 
0154                      svcnm, tpstrerror(tperrno));
0155             EXFAIL_OUT(ret);
0156         }
0157     }
0158     
0159 out:
0160 
0161     tpreturn(  ret==EXSUCCEED?TPSUCCESS:TPFAIL,
0162             0L,
0163             (char *)p_ub,
0164             0L,
0165             0L);
0166 }
0167 
0168 /**
0169  * Service entry
0170  * @return SUCCEED/FAIL
0171  */
0172 void GETNEXT (TPSVCINFO *p_svc)
0173 {
0174     int ret = EXSUCCEED;
0175     long svcNr;
0176     static int first = EXTRUE;
0177     UBFH *p_ub = (UBFH *)p_svc->data;
0178     char svcnm[MAXTIDENT+1];
0179     char svcnm_prev[MAXTIDENT+1];
0180 
0181     tplogprintubf(log_info, "Got request", p_ub);
0182 
0183 
0184     if (EXFAIL==Bget(p_ub, T_LONG_FLD, 0, (char *)&svcNr, 0L))
0185     {
0186         EXFAIL_OUT(ret);
0187     }
0188 
0189     /* Get the service number to advertise */
0190     snprintf(svcnm, sizeof(svcnm), "SVC%06ld", svcNr);
0191     snprintf(svcnm_prev, sizeof(svcnm_prev), "SVC%06ld", svcNr-1);
0192     
0193     NDRX_LOG(log_info, "Got service name: [%s], prev: [%s]", svcnm, svcnm_prev);
0194     
0195     if (first)
0196     {
0197         first = EXFALSE;
0198     }
0199     else
0200     {
0201         /* Unadvertise service... */
0202         if (EXSUCCEED!=tpunadvertise(svcnm_prev))
0203         {
0204             NDRX_LOG(log_error, "TESTERROR! Failed to unadvertise [%s]: %s", 
0205                      svcnm_prev, tpstrerror(tperrno));
0206             EXFAIL_OUT(ret);
0207         }
0208     }
0209 
0210     while (EXSUCCEED!=tpadvertise(svcnm, DYNFUNC))
0211     {
0212         if (TPELIMIT==tperrno)
0213         {
0214             /* wait for ndrxd to catch up... */
0215             usleep(1000);
0216         }
0217         else
0218         {
0219             NDRX_LOG(log_error, "TESTERROR! Failed to advertise [%s]: %s", 
0220                  svcnm, tpstrerror(tperrno));
0221             EXFAIL_OUT(ret);
0222         }
0223     }
0224 out:
0225 
0226     tpreturn(  ret==EXSUCCEED?TPSUCCESS:TPFAIL,
0227             0L,
0228             (char *)p_ub,
0229             0L,
0230             0L);
0231 }
0232 
0233 /**
0234  * Initialize the application
0235  * @param argc  argument count
0236  * @param argv  argument values
0237  * @return SUCCEED/FAIL
0238  */
0239 int init(int argc, char** argv)
0240 {
0241     int ret = EXSUCCEED;
0242     
0243     TP_LOG(log_info, "Initialising...");
0244 
0245     if (EXSUCCEED!=tpinit(NULL))
0246     {
0247         TP_LOG(log_error, "Failed to Initialise: %s", 
0248                 tpstrerror(tperrno));
0249         ret = EXFAIL;
0250         goto out;
0251     }
0252 
0253     /* Advertise our service */
0254     if (EXSUCCEED!=tpadvertise("GETNEXT", GETNEXT))
0255     {
0256         TP_LOG(log_error, "Failed to initialise GETNEXT!");
0257         ret=EXFAIL;
0258         goto out;
0259     }
0260     
0261     if (EXSUCCEED!=tpadvertise("CHKFULL", CHKFULL))
0262     {
0263         TP_LOG(log_error, "Failed to initialise CHKFULL!");
0264         ret=EXFAIL;
0265         goto out;
0266     }
0267     
0268 out:
0269 
0270     
0271     return ret;
0272 }
0273 
0274 /**
0275  * Terminate the application
0276  */
0277 void uninit(void)
0278 {
0279     TP_LOG(log_info, "Uninitialising...");
0280 }
0281 
0282 /**
0283  * Server program main entry
0284  * @param argc  argument count
0285  * @param argv  argument values
0286  * @return SUCCEED/FAIL
0287  */
0288 int main(int argc, char** argv)
0289 {
0290     /* Launch the Enduro/x thread */
0291     return ndrx_main_integra(argc, argv, init, uninit, 0);
0292 }
0293 
0294 /* vim: set ts=4 sw=4 et smartindent: */