jueves, 31 de marzo de 2011

Pasar objetos entre un AS400 y otro por FTP (SAVF – SAVOBJ - RSTOBJ)

Pasar fuentes por FTP desde un AS400 a otro es simple, solo es direccionar las librerías (LCD – CD) y utilizar el comando get.
GET  MILIBRERIA.LIB/QRPGLESRC.FILE/MIFUENTES.MBR   (REPLACE
Si queremos pasar objetos, ya sea de tipo *PGM, *FILE, *DTAARA, etc. es algo menos fácil. No podemos hacerlo directamente. Para ello necesitaremos grabar los objetos (SAVOBJ) en un archivo de salvar (SAVF)  o si eres operador de sistemas lo haces grabando en una cinta u medio óptico.

Un archivo de salvar debe limpiarse para poder utilizarlo de nuevo para recibir datos procedentes de un mandato de salvar o para recibir otro archivo de salvar. Si el usuario intenta grabar datos de salvar nuevos en un archivo de salvar que ya contiene registros, se envía un mensaje de consulta a la estación de trabajo en el caso de un trabajo interactivo, o al operador del sistema en el caso de un trabajo por lotes, a menos que se utilice un mandato de salvar y se especifique CLEAR(*ALL). O previamente se limpie el archivo de salvar con el comando CLRSAVF.


Basta de teoría, vayamos a la práctica, que es donde se aprende mejor.


Ejemplo:
Voy a pasar el objeto MIPROGRAMA (*PGM) desde mi MILIBRERIA de MIAS400 a OTROAS400 en la librería OTRALIB con el mismo nombre.

MIAS400
OTROAS400
OBJETO ORIGEN
LIBRERIA ORIGEN
OBJETO DESTINO
LIBRERIA DESTINO
MIPROGRAMA
MILIBRERIA
MIPROGRAMA
OTRALIB


1.- Crear en ambos sistemas (si no existen) los objetos de salvar, de preferencia del mismo nombre (SAVF = SAVE FILE)

     CRTSAVF FILE(MILIBRERIA/OBJETOS)
     CRTSAVF FILE(OTRALIB/OBJETOS) 

2.- Salvamos los objetos en el archivo de salvar desde el AS400 Origen


SAVOBJ OBJ(MIPROGRAMA) LIB(MILIBRERIA) DEV(*SAVF) SAVF(MILIBRERIA/OBJETOS)

CLEAR(*ALL)   


Nota: Se pueden salvar los objetos que desees, si se quiere salvar una librería completa usar el comando SAVLIB.

3.- Si tenemos los servicios TCP/FTP en funcionamiento y las autorizaciones necesarios abrimos una sesión interactiva del FTP y enviamos el archivo de salvar (*SAVF) desde un Iseries al otro.


Podemos hacerlo de esta dos maneras diferentes:
A.- DESDE EL ORIGEN (MIAS400)
            FTP  OTROAS400
            USUARIO
            PASSWORD
            CD OTRALIB
            LCD MILIBRERIA
            BIN
            PUT OBJETOS OBJETOS
            QUIT

B.- DESDE EL DESTINO (OTROAS400)

            FTP  MIAS400
            USUARIO
            PASSWORD
            CD LIBRERIA
            LCD OTRALIB
            BIN
            GET OBJETOS OBJETOS (REPLACE
            QUIT
Nota: Para ambos casos se debe incluir el comando BINARY (bin) para establecer el tipo de transferencia Binaria. 


No está demás verificar el Formato de Denominación de Archivos del servicio FTP.
GET  MILIBRERIA.LIB/QRPGLESRC.FILE/MIFUENTES.MBR   (REPLACE
ó
GET MILIBRERIA/QRPGLESRC.MIFUENTE (REPLACE 

4.- Desde el sistema destino realizar la restauración del objeto. Es decir, sacar el objeto del archivo de salvar (SAVF) a la librería que deseemos. Si el archivo de salvar fuera visto como un archivo .ZIP, restaurar sería algo como descomprimir el objeto.


RSTOBJ OBJ(MIPROGRAMA) SAVLIB(MILIBRERIA) DEV(*SAVF) SAVF(OTRALIB/OBJETOS) RSTLIB(OTRALIB)


Nota: Si se salvo una librería completa al archivo de salvar SAVF se debe usar el comando RSTLIB. El parámetro SAVLIB es la librería desde donde se salvo el objeto al archivo de salvar (Librería Origen). El parámetro RSTLIB indica la librería donde se restaurará el objeto (Librería Destino).

lunes, 28 de marzo de 2011

Procesar múltiples archivos en FTP Batch desde AS400 (Lista LSOUTPUT)

De manera complementaria al post anterior referente a como procesar archivos vía FTP por lotes, aquí describo una manera de procesar una lista de archivos dentro de una determinada ruta (directorio).
Esto es útil cuando no sabemos cuántos archivos vamos a procesar o cuando los nombres de los archivos son variables, ejemplo: ARCHIVO_20110328.TXT


Previamente a todo, logearnos manualmente por FTP y nos ubicamos en la carpeta que contiene los archivos y ejecutar el comando LS. En la figura la carpeta contiene 4 archivos de formato texto, los cuales deben ser “bajados” y procesados individualmente.




Para hacer esto generamos la lista de archivos con el comando LS y derivamos la salida a archivo. Esto lo haremos en el CL.

            El sistema genera un archivo plano de nombre LSOUTPUT y lo deposita en la librería que indiquemos como destino.
      ===> ls *.* (Disk              

  200 PORT subcommand request successful.           
  125 List started.                                 
  250 List completed.                               


Con el comando LS podemos indicar que tipo de archivos incluir en la lista.
En el ejemplo se considera todos los archivos.






Para procesar solamente archivos XML el comando sería:

===> ls *.XML (Disk          


Ejemplo de programa para bajar y procesar múltiples archivos por FTP.

            Serían 2 programas para hacer este trabajo, el primero genera la lista de archivos (archivo LSOUTPUT ) y el segundo lee dicho archivo y realiza el ftp para cada registro.

             PGM                                                           
                                                                           
   /* Crea o Limpia Miembros */                                            
                                                                           
             CLRPFM    FILE(MILIBRERIA/QFTPLOG) MBR(LISTA)                   
             MONMSG    MSGID(CPF3141) EXEC(ADDPFM +                        
                       FILE(MILIBRERIA/QFTPLOG) MBR(LISTA))                  
             CHGCURLIB  CURLIB(MILIBRERIA)                                   
                                                                           
   /* FTP Lista de archivos */                        
                                                                           
             OVRDBF     FILE(INPUT)  TOFILE(MILIBRERIA/QFTPSRC) MBR(LISTA)   
             OVRDBF     FILE(OUTPUT) TOFILE(MILIBRERIA/QFTPLOG) MBR(LISTA)   
             FTP        RMTSYS(SERVIDOR)                                      
             DLTOVR     FILE(INPUT OUTPUT)                                 
                                                                           
   /* Chequea si hay Archivos en lista */                              
                                                                     
          RTVMBRD    FILE(MILIBRERIA/LSOUTPUT) NBRCURRCD(&NROREG)    
          IF         COND(&NROREG *EQ 0) THEN(SNDUSRMSG +           
                       MSG('GENERA LISTA: CARPETA NO CONTIENE +     
                       ARCHIVOS PARA PROCESAR') MSGTYPE(*INFO) +    
                       TOMSGQ(QSYSOPR))                             
          GOTO       CMDLBL(FIN)                                    
          ENDDO                                                      
                                                                    
          OVRDBF     FILE(LSOUTPUT) TOFILE(MILIBRERIA/LSOUTPUT)      
          CALL       PGM(MILIBRERIA/PROCESACL)                            
                                                                    
      FIN:                                                          


PROCESACL

             PGM                                                   
             DCL        VAR(&NOMFILE) TYPE(*CHAR) LEN(20)          
             DCLF       FILE(MILIBRERIA/LSOUTPUT)                    
                                                                   
     LOOP:                                                         
             RCVF       RCDFMT(LSOUTPUT)                           
             MONMSG     MSGID(CPF0864) EXEC(GOTO CMDLBL(FIN))      
             CHGVAR     VAR(&NOMFILE) VALUE(%SST(&LSOUTPUT 1 20))  
                                                                   
   /* Actualiza nombre de archivos en fuente QFTPSRC/ARCHIVO */                
                                                                    
             OVRDBF     FILE(QFTPSRC) TOFILE(MILIBRERIA/QFTPSRC) +     
                        MBR(ARCHIVO)                                
             CALL       PGM(MILIBRERIA/ACTUALIZA) PARM(&NOMFILE)         
                                                                   
   /* Crea o Limpia Miembros */                                    
                                                                   
             CLRPFM    FILE(MILIBRERIA/QFTPLOG) MBR(ARCHIVO)            
             MONMSG    MSGID(CPF3141) EXEC(ADDPFM +                     
                       FILE(MILIBRERIA/QFTPLOG) MBR(ARCHIVO))                
                                                                        
   /* FTP Archivo Txt al AS400 */                     
                                                                        
             OVRDBF     FILE(INPUT)  TOFILE(MILIBRERIA/QFTPSRC) MBR(ARCHIVO) 
             OVRDBF     FILE(OUTPUT) TOFILE(MILIBRERIA/QFTPLOG) MBR(ARCHIVO) 
             FTP        RMTSYS(SERVIDOR)                                   
             DLTOVR     FILE(INPUT OUTPUT)                              

    /* Rpg que procesa el archivo */
                     
             OVRDBF     FILE(ARCHIVO)  TOFILE(MILIBRERIA/ARCHIVO)          
             CALL       PGM(MILIBRERIA/PROCESARPG)                             
             DLTOVR     FILE(*ALL)                                      
                                                                         
             DLTF       FILE(MILIBRERIA/ARCHIVO)                          
             MONMSG     MSGID(CPF2105)                                  
                                                                        
             GOTO       CMDLBL(LOOP)                                    
                                                        
         FIN:                                           
             DLTF       FILE(MILIBRERIA/LSOUTPUT)        
             MONMSG     MSGID(CPF2105)                  
                                                        
             ENDPGM                                      

Fuente de comandos FTP  QFTPSRC/LISTA

USUARIO   CLAVE           
lcd MILIBRERIA                    
cd CARPETA                 
ls *.* (DISK                     
quit                             


Fuente de commandos Ftp para cada archivo QFTPSRC/ARCHIVO

USUARIO    CLAVE              
lcd MILIBRERIA                           
cd CARPETA                        
get Archivo1.txt ARCHIVO              
quit                                    


NOTAS:
·         El programa ACTUALIZA es un RPG que actualiza la línea 4 del fuente QFTPSRC/ARCHIVO
get Archivo1.txt ARCHIVO              
get Archivo2.txt ARCHIVO              
get Archivo3.txt ARCHIVO              
get Archivo4.txt ARCHIVO              
·         El programa PROCESARPG es quien procesa cada archivo texto.
·         El archivo LOG para la lista mostrará lo siguiente:

Se ha redirigido la salida a un archivo.                               
Lectura de entrada del archivo de la alteración temporal especificado. 
Conectando con el sistema principal SERVIDOR en la dirección xx.xx.xx.xxx 
 utilizando el puerto 21.                                              
220 Microsoft FTP Service                                              
Entre el ID de inicio de sesión (USUARIO):                              
331 Password required for USUARIO.                                  
230 User USUARIO logged in.                                         
Windows_NT                                                             
Entre un submandato FTP.                                               
> lcd MILIBRERIA                                                        
El directorio de trabajo local es MILIBRERIA                                                        
Entre un submandato FTP.                                               
> cd CARPETA                                                     
250 CWD command successful.                                            
Entre un submandato FTP.                                                
> ls *.* (DISK                                         
227 Entering Passive Mode (xx,xx,xx,xxx,xxx,xx).        
125 Data connection already open; Transfer starting.   
226 Transfer complete.                                  
Entre un submandato FTP.                               
> quit                                                 
221                                                    

Espero haber sido lo más claro posible, si tienes alguna duda, pregunta no mas =P

viernes, 25 de marzo de 2011

Monitorear Status de Job Sometido PARTE I (WRKACTJOB *PRINT)


Muchas veces hay procesos batch que tenemos ejecutando en el sistema y que queremos monitorear de manera automática. Es decir, si el job se encuentra en MSGW, LCKW, etc. Se pueda cancelar y lanzar nuevamente.



En esta primera parte lo hacemos de manera “artesanal” por decirlo de alguna manera.


A continuación el programa CL que será sometido para monitorear el Job.


Parametros:
Jobname = Nombre del Job a monitorear
Sbsname = Subsistema donde se encuentra ejecutando el Job

             PGM        PARM(&JOBNAME &SBSNAME)                       
             DCL        VAR(&JOBNAME) TYPE(*CHAR) LEN(10)             
             DCL        VAR(&SBSNAME) TYPE(*CHAR) LEN(10)             
                                                                      
/* Datos de trabajo actual */                                         
             DCL        VAR(&NROJOB) TYPE(*CHAR) LEN(6)               
             DCL        VAR(&NAMJOB) TYPE(*CHAR) LEN(10)              
             DCL        VAR(&USRJOB) TYPE(*CHAR) LEN(10)              
                                                                      
             DCLF       FILE(QTEMP/PLANO)                             
                                                                       
             RTVJOBA    JOB(&NAMJOB) USER(&USRJOB) NBR(&NROJOB)       
                                                                      
             DLTF       FILE(QTEMP/PLANO)                              
             MONMSG     MSGID(CPF0000)                                
             CRTPF      FILE(QTEMP/PLANO) RCDLEN(132)                 

/* La pantalla del comando WrkActJob se deposita en archivo */
                                                                      
             WRKACTJOB  OUTPUT(*PRINT) SBS(&SBSNAME)                  
             CPYSPLF    FILE(QPDSPAJB) TOFILE(QTEMP/PLANO) +          
                          JOB(&NROJOB/&USRJOB/&NAMJOB) SPLNBR(*LAST)  
             DLTSPLF    FILE(QPDSPAJB) JOB(&NROJOB/&USRJOB/&NAMJOB) + 
                          SPLNBR(*LAST)                               
LOOP:       RCVF   
                                                  
             MONMSG     MSGID(CPF0864) EXEC(DO)                        
                        DLYJOB     DLY(60)                             
                        TFRCTL     PGM(MONITOR) PARM(&JOBNAME &SBSNAME)
             ENDDO                                                     
/* Si el job esta en MSGW se finaliza y somete nuevamente */
                                                                        
             IF         COND(%SST(&PLANO 4 10) *EQ &JOBNAME *AND +     
                          %SST(&PLANO 111 4) *EQ 'MSGW') THEN(DO)      
                                                                       
             CHGVAR     VAR(&NAMJOB) VALUE(%SST(&PLANO 04 10))         
             CHGVAR     VAR(&USRJOB) VALUE(%SST(&PLANO 17 10))         
             CHGVAR     VAR(&NROJOB) VALUE(%SST(&PLANO 29 06))         
                                                                       
             ENDJOB     JOB(&NROJOB/&USRJOB/&NAMJOB) OPTION(*IMMED) +  
                          DELAY(1)                                     
                                                                        
             DLYJOB     DLY(120)                                       
                                                                       
             SBMJOB     CMD(CALL PGM(MILIBRERIA/MIPROGRAMA)) +          
                          JOB(&JOBNAME) JOBQ(&SBSNAME)                 
             ENDDO                                                     
                                                                       
             GOTO       CMDLBL(LOOP)                                    

             ENDPGM                                                    

2 cosas importantes:
-       Luego de finalizar el job espero 2 minutos para estar seguro que el Job finalizó antes de someterlo nuevamente, puesto que a veces se demora en generar el joblog, cerrar los programas de servicio, etc. Esto es para evitar posibles bloqueos de archivos u otro tipo de objetos.
-       Al finalizar la lectura del archivo plano que contiene información del comando WRKACTJOB *PRINT, se realiza la llamada recursiva al programa con el comando TFRCTL, esto permite que entre en un bucle infinito, pero controlado por un DLYJOB de 1 minuto.

Al ejecutar el comando WRKACTJOB OUTPUT(*PRINT) SBS(QBATCH2) obtendremos el siguiente reporte en el spool.


Archivo QPDSPAJB