martes, 7 de octubre de 2014

Aplicación MTA utilizando un archivo como entrada

Generalmente cuando desarrollamos una aplicación en la cual utilizacmos el framework MTA de BRM lo hacemos definiendo un template de búsqueda (en la base de datos) en la función pin_mta_init_search.

También existe la posibilidad de que nuestra aplicación MTA tome como entrada un archivo de texto que contiene un flist y procese los objetos que están en dentro del archivo (tal como se puede hacer en el pin_bill_accts y/o pin_inv_accts).

Para procesar los objetos que están en el archivo, en el pin_mta_init_search solamente debemos indicar el nombre del archivo y la cantidad de campos que tiene cada PIN_FLD_RESULTS del flist.
El nombre del archivo va en el campo PIN_FLD_FILENAME y la cantidad de campos de cada PIN_FLD_RESULTS va en el campo PIN_FLD_COUNT.

Suponiendo que nuestro archivo de entrada se llama objetos.txt y que cada PIN_FLD_RESULTS tiene este formato:
     0 PIN_FLD_RESULTS         ARRAY [0]
     1  PIN_FLD_ACCOUNT_OBJ     POID [0] 0.0.0.1 /account 405532 0
     1  PIN_FLD_POID            POID [0] 0.0.0.1 /service 305533 0
     1  PIN_FLD_PROFILE_OBJ     POID [0] 0.0.0.1 /profile 98364 0
El flist debe quedar así:
     0    PIN_FLD_FILENAME     STR [0] "objetos.txt"
     0    PIN_FLD_COUNT        INT [0] 3
Ejemplo de programa MTA utilizando un archivo como entrada (basic_mta.c):
#ifndef lint
static  char    Sccs_id[] = "@(#)%Portal Version: basic_mta.c 1.0 %";
#endif

#include "pin_errs.h"
#include "pinlog.h"
#include "pin_mta.h"
#include "pcm.h"

/*******************************************************************
* Usage information for the specific app.
* Called prior MTA_USAGE policy opcode
*******************************************************************/
PIN_EXPORT void
 pin_mta_usage(
 char *prog)
{
 pin_errbuf_t ebuf;
 pin_flist_t  *ext_flistp = NULL;
 char   *usage_str = NULL;
 char   *format = "\nModo de uso:\t %s -file archivo \n\t\t -file Archivo donde se encuentran los registros a procesar.\n";

 PIN_ERRBUF_CLEAR (&ebuf);
 
 usage_str = (char*)pin_malloc( strlen(format) + strlen(prog) + 1 );

 if (usage_str == NULL) {
  PIN_ERR_LOG_MSG(PIN_ERR_LEVEL_ERROR,"No Memory error");
  return;
 }

 sprintf(usage_str, format ,prog);

 ext_flistp = pin_mta_global_flist_node_get_no_lock(PIN_FLD_EXTENDED_INFO, &ebuf);

 PIN_FLIST_FLD_SET (ext_flistp, PIN_FLD_DESCR, usage_str, &ebuf);
 printf("%s \n", usage_str);
 if (PIN_ERR_IS_ERR(&ebuf)) {
  PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "pin_mta_usage error", &ebuf);
 }
 
 pin_free(usage_str);
}

/*******************************************************************
 * Configuration of application
 * Called prior MTA_CONFIG policy opcode
 *******************************************************************/
PIN_EXPORT void 
pin_mta_config(
 pin_flist_t  *param_flistp,
 pin_flist_t  *app_flistp,
 pin_errbuf_t *ebufp)
{
 pin_cookie_t prev_cookie = NULL;
 pin_cookie_t cookie = NULL;
 pin_flist_t  *flistp = NULL;
 int32   mta_flags = 0;
 int32   rec_id = 0;
 char   *option = NULL;
 void   *vp = NULL;
 int    parametros = 0;

 if (PIN_ERR_IS_ERR(ebufp)) {
  return;
 }

 //Muestro la version del programa en el log
 PIN_ERR_LOG_MSG(PIN_ERR_LEVEL_DEBUG, Sccs_id);
 PIN_ERR_LOG_FLIST (PIN_ERR_LEVEL_DEBUG, "pin_mta_config parameters flist", param_flistp);
 PIN_ERR_LOG_FLIST (PIN_ERR_LEVEL_DEBUG, "pin_mta_config application info flist", app_flistp);
 
 while((flistp = PIN_FLIST_ELEM_GET_NEXT(param_flistp, PIN_FLD_PARAMS, &rec_id, 1, &cookie, ebufp))!= NULL){
  option = PIN_FLIST_FLD_GET (flistp, PIN_FLD_PARAM_NAME, 0, ebufp);
  if(option != NULL && strcmp(option, "-file") == 0){
   PIN_FLIST_FLD_COPY(flistp, PIN_FLD_PARAM_VALUE, app_flistp, PIN_FLD_FILENAME, ebufp);
   PIN_FLIST_ELEM_DROP(param_flistp, PIN_FLD_PARAMS, rec_id, ebufp);
   cookie = prev_cookie;
   parametros++;
  } else {
   prev_cookie = cookie;
  }
 }
 
 vp = PIN_FLIST_FLD_GET (app_flistp, PIN_FLD_FLAGS, 0,ebufp);
 if(vp)
  mta_flags = *((int32*)vp);

 /***********************************************************
         * The new flag MTA_FLAG_VERSION_NEW has been introduced to
         * differentiate between new mta & old mta applications as
         * only new applications have the ability to drop PIN_FLD_PARAMS
         * for valid parameters . It is only for new apps that
         * checking err_params_cnt is valid, otherwise for old applications
         * this check without a distincion for new applications would hamper
         * normal functioning.
         ***********************************************************/
 mta_flags = mta_flags | MTA_FLAG_VERSION_NEW;
 mta_flags = mta_flags | MTA_FLAG_BATCH_MODE;
 if(parametros != 1){
  mta_flags = mta_flags | MTA_FLAG_USAGE_MSG;
 }
 
 PIN_FLIST_FLD_SET (app_flistp, PIN_FLD_FLAGS, &mta_flags, ebufp);
 if (PIN_ERR_IS_ERR(ebufp)) {
  PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "pin_mta_config error", ebufp);
 }
}

/*******************************************************************
* Application defined search criteria.
* Called prior MTA_INIT_SEARCH policy opcode
*******************************************************************/
PIN_EXPORT void
pin_mta_init_search(
 pin_flist_t  *app_flistp,
 pin_flist_t  **s_flistpp,
 pin_errbuf_t *ebufp)
{
 pin_flist_t  *s_flistp = NULL;
 pin_flist_t  *tmp_flistp = NULL;
 int32   count = 3;

 if (PIN_ERR_IS_ERR(ebufp)) {
  return;
 }
 
 PIN_ERR_LOG_FLIST (PIN_ERR_LEVEL_DEBUG, "pin_mta_init_search application info flist", app_flistp);
 s_flistp = PIN_FLIST_CREATE(ebufp);
 PIN_FLIST_FLD_COPY(app_flistp, PIN_FLD_FILENAME, s_flistp, PIN_FLD_FILENAME, ebufp);
 PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_COUNT, &count, ebufp);
 
 if (PIN_ERR_IS_ERR(ebufp)) {
  PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "pin_mta_init_search error", ebufp);
  PIN_FLIST_DESTROY_EX (&s_flistp, NULL);
  *s_flistpp = NULL;
 }else{
  *s_flistpp = s_flistp;
  PIN_ERR_LOG_FLIST (PIN_ERR_LEVEL_DEBUG, "pin_mta_init_search search flist", s_flistp);
 }
}


/*******************************************************************
* Search results may be updated, modified or enriched
* Called prior MTA_TUNE policy opcode
*******************************************************************/
PIN_EXPORT void 
pin_mta_tune(
 pin_flist_t  *app_flistp,
 pin_flist_t  *srch_res_flistp,
 pin_errbuf_t *ebufp)
{
 pin_const_poid_type_t  type = NULL;
 pin_cookie_t    s_cookie = NULL;
 pin_cookie_t    m_cookie = NULL;
 pin_flist_t     *multi_res_flistp = NULL;
 pin_flist_t     *tmp_flistp = NULL;
 poid_t      *pdp = NULL;
 poid_t      *n_pdp = NULL;
 int64      db = 0;
 int64      id = 0;
 int32      i = 0;
 int32      s_rec_id = 0;
 int32      m_rec_id = 0;
 void      *vp = NULL;

 if (PIN_ERR_IS_ERR(ebufp)) {
  return;
 }

 PIN_ERR_LOG_FLIST (PIN_ERR_LEVEL_DEBUG, "basic_mta application info flist", app_flistp);
 PIN_ERR_LOG_FLIST (PIN_ERR_LEVEL_DEBUG, "basic_mta search results flist", srch_res_flistp);

 vp = PIN_FLIST_FLD_GET (app_flistp, PIN_FLD_OPS_ERROR, MTA_OPTIONAL, ebufp);
 if(vp){
  i = *((int32*)vp);
 }
 
 if (i) {
  while((multi_res_flistp = PIN_FLIST_ELEM_GET_NEXT(srch_res_flistp, PIN_FLD_MULTI_RESULTS, &s_rec_id, 1, &s_cookie, ebufp)) != NULL) {
   m_cookie = 0;
   while((tmp_flistp = PIN_FLIST_ELEM_GET_NEXT(multi_res_flistp, PIN_FLD_RESULTS, &m_rec_id, 1, &m_cookie, ebufp)) != NULL) {
    vp = PIN_FLIST_FLD_TAKE (tmp_flistp, PIN_FLD_POID, 0, ebufp);
    if(vp) {
     pdp = (poid_t*)vp;
     db = PIN_POID_GET_DB (pdp);
     id = PIN_POID_GET_ID (pdp);
     type = PIN_POID_GET_TYPE (pdp);
     id = id * i;
     n_pdp = PIN_POID_CREATE (db, type,id, ebufp);
     PIN_POID_DESTROY (pdp, ebufp);
     PIN_FLIST_FLD_PUT (tmp_flistp, PIN_FLD_POID, n_pdp, ebufp);
    }
   }
  }
 }

 if (PIN_ERR_IS_ERR(ebufp)) {
  PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "pin_mta_tune error", ebufp);
 } else {
  PIN_ERR_LOG_FLIST (PIN_ERR_LEVEL_DEBUG, "basic_mta search results flist salida", srch_res_flistp);
 }
}



/*******************************************************************
* Function executed at application exit
* Called prior MTA_EXIT policy opcode
*******************************************************************/
PIN_EXPORT void
pin_mta_exit(
 pin_flist_t  *app_flistp,
 pin_errbuf_t *ebufp)
{
 PIN_ERR_LOG_FLIST (PIN_ERR_LEVEL_DEBUG, "pin_mta_exit application info flist", app_flistp);
 if (PIN_ERR_IS_ERR(ebufp)) {
  PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "pin_mta_exit error", ebufp);
  printf("Error durante la ejecucion.\n");
 } else {
  printf("Ejecucion exitosa.\n");
 }
}

/*******************************************************************
* Main application opcode is called here
*******************************************************************/
PIN_EXPORT void 
 pin_mta_worker_opcode(
 pcm_context_t *ctxp,
 pin_flist_t  *srch_res_flistp,
 pin_flist_t  *op_in_flistp,
 pin_flist_t  **op_out_flistpp,
 pin_flist_t  *ti_flistp,
 pin_errbuf_t *ebufp)
{
 pin_cookie_t cookie = NULL; 
 pin_flist_t  *app_flistp = NULL;
 pin_flist_t  *tmp_flistp = NULL;
 int32   mta_flags = 0;
 int32   elemid = 0;
 void   *vp = NULL;
 
 if (PIN_ERR_IS_ERR(ebufp)) {
  PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "pin_mta_worker_opcode error entro con error, saliendo", ebufp);
  return;
 }
 
 app_flistp = pin_mta_global_flist_node_get_with_lock (PIN_FLD_APPLICATION_INFO, ebufp);

 vp = PIN_FLIST_FLD_GET (app_flistp, PIN_FLD_FLAGS, 0,ebufp);
 if(vp){
  mta_flags = *((int32*)vp);
 }
 pin_mta_global_flist_node_release(PIN_FLD_APPLICATION_INFO, ebufp);
 
 while ((tmp_flistp = PIN_FLIST_ELEM_GET_NEXT(op_in_flistp, PIN_FLD_RESULTS, &elemid, 1, &cookie, ebufp)) != NULL) {
  //aqui se procesa cada PIN_FLD_RESULTS
 }
 
 if (PIN_ERR_IS_ERR(ebufp)) {
  PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "pin_mta_worker_opcode saliendo con error", ebufp);
 } 
 
}

Archivo de entrada para el ejemplo (objetos.txt):
0 PIN_FLD_RESULTS     ARRAY [0]
1  PIN_FLD_ACCOUNT_OBJ     POID [0] 0.0.0.1 /account 405532 0
1  PIN_FLD_POID     POID [0] 0.0.0.1 /service 305533 0
1  PIN_FLD_PROFILE_OBJ     POID [0] 0.0.0.1 /profile 98364 0
0 PIN_FLD_RESULTS     ARRAY [1]
1  PIN_FLD_ACCOUNT_OBJ     POID [0] 0.0.0.1 /account 401569 0
1  PIN_FLD_POID     POID [0] 0.0.0.1 /service 501565 0
1  PIN_FLD_PROFILE_OBJ     POID [0] 0.0.0.1 /profile 501565 0
0 PIN_FLD_RESULTS     ARRAY [2]
1  PIN_FLD_ACCOUNT_OBJ     POID [0] 0.0.0.1 /account 403491 0
1  PIN_FLD_POID     POID [0] 0.0.0.1 /service 603496 0
1  PIN_FLD_PROFILE_OBJ     POID [0] 0.0.0.1 /profile 603496 0
0 PIN_FLD_RESULTS     ARRAY [3]
1  PIN_FLD_ACCOUNT_OBJ     POID [0] 0.0.0.1 /account 9999 0
1  PIN_FLD_POID     POID [0] 0.0.0.1 /service 8888 0
1  PIN_FLD_PROFILE_OBJ     POID [0] 0.0.0.1 /profile 8888 0
0 PIN_FLD_RESULTS     ARRAY [4]
1  PIN_FLD_ACCOUNT_OBJ     POID [0] 0.0.0.1 /account 405532 0
1  PIN_FLD_POID     POID [0] 0.0.0.1 /service 305533 0
1  PIN_FLD_PROFILE_OBJ     POID [0] 0.0.0.1 /profile 305533 0
0 PIN_FLD_RESULTS     ARRAY [5]
1  PIN_FLD_ACCOUNT_OBJ     POID [0] 0.0.0.1 /account 401569 0
1  PIN_FLD_POID     POID [0] 0.0.0.1 /service 501565 0
1  PIN_FLD_PROFILE_OBJ     POID [0] 0.0.0.1 /profile 501565 0
0 PIN_FLD_RESULTS     ARRAY [6]
1  PIN_FLD_ACCOUNT_OBJ     POID [0] 0.0.0.1 /account 403491 0
1  PIN_FLD_POID     POID [0] 0.0.0.1 /service 603496 0
1  PIN_FLD_PROFILE_OBJ     POID [0] 0.0.0.1 /profile 603496 0
0 PIN_FLD_RESULTS     ARRAY [7]
1  PIN_FLD_ACCOUNT_OBJ     POID [0] 0.0.0.1 /account 9999 0
1  PIN_FLD_POID     POID [0] 0.0.0.1 /service 8888 0
1  PIN_FLD_PROFILE_OBJ     POID [0] 0.0.0.1 /profile 8888 0

Una vez que nuestra aplicación MTA está terminada podemos comprobar que no posea memory leaks.

Martín Falconi

No hay comentarios.:

Publicar un comentario