Classificar utilitários - AWS Modernização do mainframe

AWS O Mainframe Modernization Service (experiência em Managed Runtime Environment) não está mais aberto a novos clientes. Para recursos semelhantes ao AWS Mainframe Modernization Service (experiência em Managed Runtime Environment), explore o AWS Mainframe Modernization Service (experiência autogerenciada). Os clientes atuais podem continuar usando o serviço normalmente. Para obter mais informações, consulte Alteração na disponibilidade AWS da modernização do mainframe.

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Classificar utilitários

Os utilitários de classificação dependem de conjuntos de dados cuja referência tem um significado especial para o utilitário. Portanto, todos os utilitários de classificação no lado modernizado compartilham o mesmo padrão de invocação em scripts groovy:

mpr.withFileConfigurations(<FILE CONFIGURATIONS DETAILS>...) .withParameters(params) .runProgram("<SORT UTILITY ALIAS>")

onde mpr está uma MainProgramRunner instância (consulte a seção Scripts chamando programas nesta página). Os aliases dos utilitários de classificação são fornecidos nas seções abaixo.

As entradas DD (definições de conjuntos de dados) do script JCL são modernizadas como entradas nos detalhes da configuração do arquivo que servem como argumento para o método. mpr.withFileConfigurations() Veja os exemplos abaixo para ver ilustrações desse conceito.

SORT/SYNCSORT/ICEMAN

Finalidade

Esse programa emula vários utilitários SORT de mainframe, usados para sort/merge/copy dados de conjuntos de dados, com base nos critérios fornecidos. Os seguintes aliases de programa podem ser usados (e correspondem ao nome do utilitário de classificação legado correspondente):

  • SORT

  • SYNCSORT

  • ICEMAN

Os detalhes sobre as SORT/MERGE diretivas encontradas nos cartões de controle e os recursos antigos do utilitário de classificação não são fornecidos aqui, mas devem ser obtidos nas documentações de plataformas legadas relevantes existentes.

Signature

O programa não aceita nenhum argumento, mas se baseia em referências de conjuntos de dados específicos:

  • O SYSIN conjunto de dados (também conhecido como “cartão de controle”) contém as declarações de controle sort/merge

  • O SYMNAMES conjunto de dados opcional contém diretivas de substituição de variáveis no conteúdo SYSIN

  • O opcional SORTXDUP ou o SORTXSUM conjunto de dados podem ser usados para armazenar registros duplicados.

  • Os conjuntos de dados prefixados com SORTIN ou SORTDBIN mantêm registros a serem processados (entradas)

  • O SORTOUT conjunto de dados contém os resultados do programa (saída)

  • As SORTWK definições dos conjuntos de dados SORT WORK encontradas em alguns scripts de trabalhos antigos são ignoradas (e não são representadas na chamada modernizada); os conjuntos de dados de trabalho de classificação sempre serão alocados dinamicamente no ambiente moderno

  • Os dois conjuntos de dados cujo DD começa com SORTJN (prefixo) contêm registros que serão afetados pelas diretivas de chaves de junção (usadas para unir conjuntos de dados durante o processo de classificação)

Por exemplo, considerando as seguintes diretivas de chaves de junção:

JOINKEYS FILE=F1,FIELDS=(13,5,A) JOINKEYS FILE=F2,FIELDS=(24,5,A)

Aqui, a chave de junção tem comprimento 5 e começa em:

  • posição 13 para registros no conjunto de dados SORTJNF1 (concatenação de SORTJN prefixo e arquivo) F1

  • posição 24 para registros no conjunto de dados SORTJNF2 (concatenação de SORTJN prefixo e arquivo) F2

Verificações e tratamento de erros

  • Se o arquivo de entrada (SORTIN) tiver uma SHR disposição, mas não puder ser encontrado, uma mensagem de erro será registrada, o código de retorno do programa será definido como 1 e a execução do programa será interrompida (nenhuma classificação acontecerá, nenhuma saída será produzida)

Nos seguintes casos, uma mensagem dedicada em RuntimeException espera será lançada:

  • Se a invocação do programa exigir conexão com um banco de dados (quando o SORTDBIN conjunto de dados for usado, nãoSORTIN), mas não for possível encontrar uma fonte de dados válida

  • Se o arquivo de saída (SORTOUT) não estiver definido corretamente

  • Se um comando encontrado na placa de controle não puder ser entendido ou não for suportado

  • Caso contrário, são fornecidos exatamente dois arquivos de entrada para um SORT JOINKEYS caso.

Uso da amostra

Amostra MERGE

Aqui está um exemplo de ICEMAN invocação de um trecho de script de trabalho:

O cartão de controle é embutido e comanda para mesclar campos dos arquivos de entrada (veja a SYSIN entrada)

//* //PASOSO03 EXEC PGM=ICEMAN,REGION=0M //SORTIN01 DD DSN=input(input809a.data),DISP=SHR,LRECL=10 //SORTIN02 DD DSN=input(input809b.data),DISP=SHR,LRECL=10 //SORTOUT DD DSN=output(out809.txt),DISP=(,PASS),LRECL=10 //SORTWK01 DD SPACE=(281,(156300,156300),RLSE),AVGREC=U //SORTWK02 DD SPACE=(281,(156300,156300),RLSE),AVGREC=U //SYSIN DD * MERGE FIELDS=(1,6,PD,A,7,2,CH,A) END /*

E o trecho de script groovy modernizado correspondente -- observe que, como já mencionado, as SORTWK entradas não são levadas em consideração durante o processo de modernização e que a placa de controle embutida corresponde exatamente ao conteúdo antigo da placa de controle.

// STEP PASOSO03 - PGM - ICEMAN*************************************************** def stepPASOSO03(Object shell, Map params, Map programResults){ shell.with { if (checkValidProgramResults(programResults)) { return execStep("PASOSO03", "ICEMAN", programResults, { mpr .withFileConfigurations(new FileConfigurationUtils() .withJobContext(jobContext) .fileSystem("SORTIN01") .path("input(input809a.data)").recordSize(10) .disposition("SHR") .build() .fileSystem("SORTIN02") .path("input(input809b.data)").recordSize(10) .disposition("SHR") .build() .fileSystem("SORTOUT") .path("output(out809.txt)").recordSize(10) .normalTermination("PASS") .build() .fileSystem("SYSIN") .stream( """ MERGE FIELDS=(1,6,PD,A,7,2,CH,A) END """, getEncoding()) .build() .getFileConfigurations()) .withParameters(params) .runProgram("ICEMAN") }) } } }

Amostra SORT simples

Uma simples etapa antiga do SORT (trecho do script de trabalho) com cartão de controle embutido, obtida do aplicativo de amostra carddemo:

//********************************************************************* //* CREATE COPY OF TRANSACT FILE WITH CARD NUMBER AND TRAN ID AS KEY //********************************************************************* //STEP010 EXEC PGM=SORT //SORTIN DD DISP=SHR,DSN=AWS.M2.CARDDEMO.TRANSACT.VSAM.KSDS //SYSPRINT DD SYSOUT=* //SYSOUT DD SYSOUT=* //SORTOUT DD DSN=AWS.M2.CARDDEMO.TRXFL.SEQ, // DISP=(NEW,CATLG,DELETE),UNIT=SYSDA, // DCB=(LRECL=350,BLKSIZE=3500,RECFM=FB), // SPACE=(CYL,(1,1),RLSE) //SYSIN DD * SORT FIELDS=(263,16,CH,A,1,16,CH,A) OUTREC FIELDS=(1:263,16,17:1,262,279:279,50) /*

e o trecho de script groovy modernizado correspondente:

// STEP STEP010 - PGM - SORT****************************************************** def stepSTEP010(Object shell, Map params, Map programResults){ shell.with { if (checkValidProgramResults(programResults)) { return execStep("STEP010", "SORT", programResults, { mpr .withFileConfigurations(new FileConfigurationUtils() .withJobContext(jobContext) .bluesam("SORTIN") .dataset("AWS.M2.CARDDEMO.TRANSACT.VSAM.KSDS") .disposition("SHR") .build() .systemOut("SYSPRINT") .output("*") .build() .systemOut("SYSOUT") .output("*") .build() .fileSystem("SORTOUT") .path("AWS.M2.CARDDEMO.TRXFL.SEQ").recordSize(350) .disposition("NEW") .normalTermination("CATLG") .abnormalTermination("DELETE") .build() .fileSystem("SYSIN") .stream( """ SORT FIELDS=(263,16,CH,A,1,16,CH,A) OUTREC FIELDS=(1:263,16,17:1,262,279:279,50)""", getEncoding()) .build() .getFileConfigurations()) .withParameters(params) .runProgram("SORT") }) } } }

Observe que a placa de controle embutida é usada “como está”, sem qualquer modificação do conteúdo da placa de controle antiga.

FERRAMENTA DE GELO

Finalidade

O utilitário ICETOOL é usado para realizar várias operações em conjuntos de dados em uma única etapa do trabalho (manipulação, classificação e análise de dados).

Os seguintes operadores principais estão sendo suportados:

  • COPY- Copia dados dos arquivos de entrada para saída

  • SORT- Classifica dados usando cartões/critérios de classificação especificados

  • SELECT- Filtra e seleciona registros específicos com base nas condições

  • SPLICE- Merges/joins dados de várias fontes

  • COUNT- Conta os registros que atendem aos critérios especificados

  • OCCUR- Analisa padrões de ocorrência em dados

Para o operador SPLICE, a concessionária usará uma abordagem multisegmentada com base em estratégias de agrupamento de dados para garantir um desempenho otimizado.

Detalhes sobre os operadores devem ser obtidos na documentação adequada da plataforma legada.

Signature

O ICETOOL utilitário não usa nenhum parâmetro, mas depende de conjuntos de dados específicos:

  • TOOLINconjunto de dados contém as instruções de controle a serem processadas pelo utilitário

  • TOOLMSGe DFSMSG os conjuntos de dados não são usados pelo ICETOOL utilitário modernizado por enquanto (ignorados)

  • INé o prefixo dos conjuntos de dados de entrada (registros a serem processados)

  • OUTé o prefixo para conjuntos de dados de saída (registros resultantes do processamento)

  • outros conjuntos de dados podem ser referenciados por declarações de controle no cartão de controle

Verificações e tratamento de erros

Nos seguintes casos, um RuntimeException será lançado com uma mensagem relacionada:

  • Se o operador usado em uma das instruções de controle não for suportado

  • Para qualquer operador, se uma diretiva não suportada for fornecida

Uso da amostra

Amostra ICETOOL SORT

Aqui está uma amostra antiga do jcl usando o ICETOOL para fins de classificação:

  • cada instrução de controle do operador SORT usa um cartão de controle dedicado, cuja referência é especificada por meio da palavra-chave USING

  • todas as placas de controle são definidas após a TOOLIN definição e são embutidas (consulte SEL1CNTL as *CNTL entradas seguintes)

//SAMPLO52 EXEC PGM=ICETOOL,REGION=1024K //TOOLMSG DD SYSOUT=* //DFSMSG DD SYSOUT=* //IN1 DD DSN=input(input846a.data),DISP=SHR // DCB=(RECFM=F,LRECL=8) //IN2 DD DSN=input(input846b.data),DISP=SHR // DCB=(RECFM=F,LRECL=8) //OUT1 DD DSN=output(out846a.txt),DISP=(,CATLG) // DCB=(RECFM=F,LRECL=8) //OUT2 DD DSN=output(out846b.txt),DISP=(,CATLG) // DCB=(RECFM=V) //OUT3 DD DSN=output(out846c.txt),DISP=(,CATLG) // DCB=(RECFM=V) //TOOLIN DD * SORT FROM(IN1) TO(OUT1) USING(SEL1) SORT FROM(IN2) TO(OUT1) USING(SEL2) SORT FROM(IN1) TO(OUT2) USING(SEL3) SORT FROM(IN2) TO(OUT2) USING(SEL4) SORT FROM(IN1) TO(OUT3) USING(SEL5) SORT FROM(IN2) TO(OUT3) USING(SEL6) /* //SEL1CNTL DD * OPTION COPY OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')) //* //SEL2CNTL DD * OPTION COPY,SKIPREC=1 OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')) //* //SEL3CNTL DD * OPTION COPY OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')), FTOV,VLTRIM=C' ' //* //SEL4CNTL DD * OPTION COPY,SKIPREC=1 OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')), FTOV,VLTRIM=C' ' //* //SEL5CNTL DD * OPTION COPY OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')), FTOV,VLTRIM=C' ' //* //SEL6CNTL DD * OPTION COPY,SKIPREC=1 OUTFIL BUILD=(1,7,JFY=(SHIFT=LEFT,TRAIL=C'*')), FTOV,VLTRIM=C' ' //*

Depois de modernizado, o trecho de script groovy correspondente se parece com:

// STEP SAMPLO52 - PGM - ICETOOL************************************************** def stepSAMPLO52(Object shell, Map params, Map programResults){ shell.with { if (checkValidProgramResults(programResults)) { return execStep("SAMPLO52", "ICETOOL", programResults, { mpr .withFileConfigurations(new FileConfigurationUtils() .withJobContext(jobContext) .systemOut("TOOLMSG") .output("*") .build() .systemOut("DFSMSG") .output("*") .build() .fileSystem("IN1") .path("input(input846a.data)").recordSize(8) .disposition("SHR") .build() .fileSystem("IN2") .path("input(input846b.data)").recordSize(8) .disposition("SHR") .build() .fileSystem("OUT1") .path("output(out846a.txt)").recordSize(8) .normalTermination("CATLG") .build() .fileSystem("OUT2") .path("output(out846b.txt)").rdw(true) .normalTermination("CATLG") .build() .fileSystem("OUT3") .path("output(out846c.txt)").rdw(true) .normalTermination("CATLG") .build() .fileSystem("TOOLIN") .stream( """ SORT FROM(IN1) TO(OUT1) USING(SEL1) SORT FROM(IN2) TO(OUT1) USING(SEL2) SORT FROM(IN1) TO(OUT2) USING(SEL3) SORT FROM(IN2) TO(OUT2) USING(SEL4) SORT FROM(IN1) TO(OUT3) USING(SEL5) SORT FROM(IN2) TO(OUT3) USING(SEL6) """, getEncoding()) .build() .fileSystem("SEL1CNTL") .stream( """ OPTION COPY OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')) """, getEncoding()) .build() .fileSystem("SEL2CNTL") .stream( """ OPTION COPY,SKIPREC=1 OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*'))""", getEncoding()) .build() .fileSystem("SEL3CNTL") .stream( """ OPTION COPY OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')), FTOV,VLTRIM=C' '""", getEncoding()) .build() .fileSystem("SEL4CNTL") .stream( """ OPTION COPY,SKIPREC=1 OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')), FTOV,VLTRIM=C' '""", getEncoding()) .build() .fileSystem("SEL5CNTL") .stream( """ OPTION COPY OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')), FTOV,VLTRIM=C' '""", getEncoding()) .build() .fileSystem("SEL6CNTL") .stream( """ OPTION COPY,SKIPREC=1 OUTFIL BUILD=(1,7,JFY=(SHIFT=LEFT,TRAIL=C'*')), FTOV,VLTRIM=C' '""", getEncoding()) .build() .getFileConfigurations()) .withParameters(params) .runProgram("ICETOOL") }) } } }

Observações:

  • As placas de controle embutidas são usadas “como estão”; nenhuma transformação aconteceu a partir das placas de controle antigas

  • TOOLMSGe DFSMSG são definidos na versão modernizada, mas serão ignorados em tempo de execução

  • Tanto nas versões antigas quanto nas modernizadas, os cartões de controle são definidos com o CNTL sufixo, mas referenciados sem o sufixo nas diretivas do conjunto de dados: por exemploSORT FROM(IN1) TO(OUT1) USING(SEL1), In, o se refere à definição do TOOLIN conjunto de dados USING(SEL1) SEL1CNTL

Amostra ICETOOL COPY

Aqui está outro exemplo do ICETOOL, usando o operador COPY. Isso TOOLIN está embutido no trecho do script jcl:

//SAMPLO51 EXEC PGM=ICETOOL,REGION=1024K //TOOLMSG DD SYSOUT=* //DFSMSG DD SYSOUT=* //IN1 DD DSN=input(input831.data),DISP=SHR // DCB=(RECFM=F,LRECL=12) //OUT1 DD DSN=output(out831a.txt),DISP=OLD // DCB=(RECFM=F,LRECL=12) //OUT2 DD DSN=output(out831b.txt),DISP=OLD // DCB=(RECFM=F,LRECL=12) //TOOLIN DD * COPY FROM(IN1) TO(OUT1,OUT2) USING(SEL1) /* //SEL1CNTL DD * OPTION COPY OUTFIL INCLUDE=(7,2,CH,EQ,C'10') //*

E aqui está o trecho de script groovy modernizado correspondente:

// STEP SAMPLO51 - PGM - ICETOOL************************************************** def stepSAMPLO51(Object shell, Map params, Map programResults){ shell.with { if (checkValidProgramResults(programResults)) { return execStep("SAMPLO51", "ICETOOL", programResults, { mpr .withFileConfigurations(new FileConfigurationUtils() .withJobContext(jobContext) .systemOut("TOOLMSG") .output("*") .build() .systemOut("DFSMSG") .output("*") .build() .fileSystem("IN1") .path("input(input831.data)").recordSize(12) .disposition("SHR") .build() .fileSystem("OUT1") .path("output(out831a.txt)").recordSize(12) .disposition("OLD") .build() .fileSystem("OUT2") .path("output(out831b.txt)").recordSize(12) .disposition("OLD") .build() .fileSystem("TOOLIN") .stream( """ COPY FROM(IN1) TO(OUT1,OUT2) USING(SEL1) COPY FROM(IN1) TO(OUT3,OUT4) COPY FROM(IN1) TO(OUT4) COPY FROM(IN1) TO(OUT5,OUT6) """, getEncoding()) .build() .fileSystem("SEL1CNTL") .stream( """ OPTION COPY OUTFIL INCLUDE=(7,2,CH,EQ,C'10')""", getEncoding()) .build() .getFileConfigurations()) .withParameters(params) .runProgram("ICETOOL") }) } } }

MFSORT

Finalidade

Esse programa utilitário tem como objetivo imitar o comportamento do utilitário de classificação chamado MFSORT encontrado em ambientes Micro Focus (geralmente é invocado na linha de comando ou em scripts em ambientes legados).

Internamente, o programa está delegando as operações de classificação reais ao programa SORT/SYNCSORT/ICEMAN utilitário.

Signature

Somente a seguinte sintaxe legada está sendo suportada: mfsort take <control card>

As instruções diretas ligam como mfsort <instructions> NÃO são suportadas.

Não aceita nenhum argumento; a diretiva take é emulada usando um conjunto de dados referenciado comoTAKE, que contém os comandos para o MFSORT operar.

Verificações e tratamento de erros

  • Se o TAKE conjunto de dados estiver ausente ou for inválido, um RuntimeException será lançado

  • Eles também Verificações e tratamento de erros se inscrevem aqui, dada a delegação do MFSORT para o SORT

Uso da amostra

A seguinte invocação de comando mostra um exemplo de uso do MFSORT:

mfsort take TESTSRT1.CTL

Aqui está o trecho de script groovy adaptado e modernizado correspondente:

mpr.withFileConfigurations(new FileConfigurationUtils() .fileSystem("TAKE") .path("input(TESTSRT1.CTL)") .build() .getFileConfigurations()) .withArguments("input") // relative path for use and give files .runProgram("MFSORT");