[SP-pm] Perl para automação em acesso a x3270 IBM

Marcio - Google marciorp at gmail.com
Mon Jul 9 18:54:54 PDT 2012


Olá Eden, obrigado!

Sim, eu vi as páginas e foi nelas que aprendi os comandos de script
desse apl. A minha dificuldade está com Perl mesmo.

Pois é, como respondi ao Nelson, não consegui usar o pump (pump $h
until $out =~ /\Gvalor esperado/) porque não sei o que esperar de
retorno, pode ser qualquer coisa. Tenho que pegar tudo que voltou e
analisar. Ai acho que entra as expressões regulares.

Quanto ao Expect, desculpa, mais como disse meu conhecimento de Perl é
bastante limitado, então qual a diferença do IPC::Run e do Expect e
porque esse é melhor?

Sobre o código com o Expect, não entendi bem.
$exp->send($cmd1);
$exp->expect(100, [qr/resposta cmd1: (.+)/ =>
sub {
     my $self = shift;

     # $resposta vai ter o que casou com (.+)
     my($resposta) = $self->match_list;

     # faça algo com $resposta aqui

     # enviar segundo comando
     $self->send($cmd2);

     exp_continue;
    },
      qr/resposta cmd2: (.+)/ =>
      sub {
           my $self = shift;
           my($resposta) = $self->match_list;

           # etc...

           exp_continue;
          },
            timeout => sub { die 'o sistema parou de responder' }
]);


Se eu tiver 50 comandos vou ter que "encadear" 50 subs?
O outro detalhe é que não sei o que esperar de volta, não tem como
saber, tenho que pegar tudo que voltar. A única coisa que sei é que o
tamanho do retorno é de no mínimo 1920 caracteres (espaços, números e
letras).

Imaginei algo assim:

1. Conecta
2. Verifica o retorno para saber se conectou e como
3. Envia o primeiro comando
4. Lê o retorno
5. Chama a função que trata retorno passando como parâmetro o conteúdo
do retorno
6. Envia o segundo comando
7. Lê o retorno
8. Chama a mesma função que trata retorno passando como parâmetro o
conteúdo do retorno
...
100. Desconecta e encerra.

A função que trata o retorno irá varrer a string a procura de
informações e erros, e dependendo disso, executar outros comandos,
gravar informações no banco de dados e etc.

Sei que isso é uma gambiarra pronta para explodir, mais o cliente não
vai trocar o sistema legado que roda a 30 anos sem uma única parada. E
a minha é a menor de todas, você precisa ver o que o povo faz com
Excel e VBScript usando automação.
Alguns módulos já foram para SAP, mais o grosso está no Mainframe, que
pelo que ouvi falar deve ficar no ar por pelo menos mais 10 anos.
Eu sou só um grãozinho de areia na TI deles, mexo só com a parte de
telefonia computadorizada. A TI deles tem mais de 250 pessoas, e eu
não tenho poder nem de sugestão em relação a sistemas, só mexo com a
minha área e sou terceirizado ... mais ou menos assim: manda quem
pode, obedece quem tem juízo ... :-)

Agradeço toda ajuda.

Abs,

Marcio.


Em 9 de julho de 2012 16:59, Eden Cardim <edencardim em gmail.com> escreveu:
>>>>>> "Marcio" == Marcio  <- Google <marciorp em gmail.com>> writes:
>     Marcio> Preciso criar um programa para navegar (ler e inserir) em um sistema
>     Marcio> que roda em Mainframe IBM (x3270(9)).
>
> Ai caramba... Lá vem pergunta difícil...
>
>     Marcio> Ele irá simular a interação humana, conecta no host, espera
>     Marcio> pela tela, insere dados em determinadas posições e submete
>     Marcio> para o host, etc.  Se usar Perl com Windows é moleza com o
>     Marcio> módulo Win32::HostExplorer, o problema é que estou usando
>     Marcio> Linux em modo texto, nada de ambiente gráfico.  Não achei
>     Marcio> uma versão do Win32::HostExplorer para Linux, mais achei o
>     Marcio> http://x3270.bgp.nu/, mais especificamente o s3270. Instalei
>     Marcio> e compilei, rodei o módulo c3270 e funciona perfeito,
>     Marcio> conectou no host, montou as telas, entrou dados e tudo mais.
>     Marcio> Agora preciso usar o s3270 que é pelo que entendi o módulo
>     Marcio> para automação. Só que a documentação é muito fraca e
>     Marcio> encontrei meia dúzia de exemplos mais fracos ainda.
>
> Não sei se você chegou a encontrar essas páginas, mas achei bem
> completo:
>
> http://x3270.bgp.nu/s3270-man.html
> http://x3270.bgp.nu/x3270-script.html
>
>     Marcio>  Até consegui fazer um script pequeno em Perl (usando um
>     Marcio> exemplo) que conecta no host, e faz alguma interação, mais
>     Marcio> agora esbarrei no conhecimento limitado de Perl.
>
>     Marcio> O que consegui fazer até agora é isso:
>     Marcio> <snip>
>
>     Marcio> O código funciona, pois a variável $out tem tudo o que foi processado
>     Marcio> (saída) e os dados (telas) estão certos.
>     Marcio> A dificuldade está no fato de que o script é processado como um todo
>     Marcio> quando chega à linha "finish $h or die "s3270 returned $?";" e a
>     Marcio> variável $out só é alimentada ai. A questão é que cada vez que eu
>     Marcio> entro dados eu preciso processar o retorno do host (ler a tela) para
>     Marcio> verificar se está tudo certo e ir para a próxima ação.
>
>     Marcio> Para ficar mais fácil de entender, a cada vez que eu mandar a
>     Marcio> instrução "Ascii(0,0,24,80)\n" preciso que a variável $out seja
>     Marcio> alimentada com tudo o retorno do host até essa ação, para que eu possa
>     Marcio> pegar os dados e ver se está tudo certo, depois disso limpar a
>     Marcio> variável e continuar até a próxima vez que eu precisar ler o retorno.
>     Marcio> Já tentei colocar o "finish ..." no meio e ler a variável de saída,
>     Marcio> mais depois do "finish ..." o script é encerrado, independente de eu
>     Marcio> enviar as instruções “disconnect” ou “quit”.
>     Marcio> A variável de retorno tem as telas que o host retorna (não tem tamanho
>     Marcio> fixo), então tenho que sair garimpando no meio os dados que preciso
>     Marcio> para saber qual a próxima ação a ser enviada.
>     Marcio> Acho que a dificuldade está em saber usar o módulo IPC::Run. Já fui à
>     Marcio> página da documentação, mais não entendi muito bem, acho que eu
>     Marcio> decorrência da minha limitação em Perl.
>
> Isso é consequência de você não estar avaliando a variável $out quando
> alimenta a variável $in. Você teria que fazer algo assim:
>
>   $in .= "connect(10.1.8.192:23)\n";
>   $in .= "wait(InputField)\n";
>   $in .= "String(usertest)\n";
>   pump $h until $out =~ /\Gvalor esperado/
>   # etc...
>
>     Marcio> Alguém já fez algo parecido? Tem exemplos mais completos que possa me passar?
>     Marcio> Ou sabe onde eu possa achar um bom material?
>     Marcio> Ou ao invés de usar esse módulo, tem algo mais simples para essa interação?
>
> O IPC::Run não é o módulo ideal pra fazer esse tipo de coisa. Você vai
> se dar melhor com o Expect.
>
>   my $exp = Expect->spawn('s3270');
>   my $cmd1 = "connect(10.1.8.192:23)\n";
>   $cmd1 .= "wait(InputField)\n";
>   $cmd1 .= "String(usertest)\n";
>   $cmd1 .= "wait(InputField)\n";
>   $cmd1 .= "String(passtest)\n";
>   $cmd1 .= "Ascii(0,0,24,80)\n";
>
>   my $cmd2 = "ENTER\n";
>   $cmd2 .= "wait(1, Seconds)\n";
>   $cmd2 .= "wait(Unlock)\n";
>   $cmd2 .= "wait(InputField)\n";
>   $cmd2 .= "String(A4L2)\n";
>   $cmd2 .= "Ascii(0,0,24,80)\n";
>
>   $exp->send($cmd1);
>   $exp->expect(100, [
>     qr/resposta cmd1: (.+)/ => sub {
>       my $self = shift;
>
>       # $resposta vai ter o que casou com (.+)
>       my($resposta) = $self->match_list;
>
>       # faça algo com $resposta aqui
>
>       # enviar segundo comando
>       $self->send($cmd2);
>
>       exp_continue;
>     },
>     qr/resposta cmd2: (.+)/ => sub {
>        my $self = shift;
>        my($resposta) = $self->match_list;
>
>        # etc...
>
>        exp_continue;
>     },
>     timeout => sub { die 'o sistema parou de responder' }
>   ]);
>
> As subrotinas à direita só são executadas se a expressão à esquerda
> casar com saída do s3270, basicamente, é uma máquina de estados. Além
> disso, o Expect é desenvolvido levando em consideração que você está
> conectado em um terminal, então ele já converte sequências de escape e
> coisas do gênero, coisa que o IPC::Run não faz e que pode complicar sua
> vida.
>
>     Marcio> O cliente usa Mainframe IBM e tem um ERP rodando nele que é acessado
>     Marcio> em estações Windows com o Extra!. Tem também outra aplicação em Linux,
>     Marcio> feito em várias linguagens, e essa aplicação precisa trocar alguns
>     Marcio> dados com o Mainframe. No Windows alguns usuários avançados usam
>     Marcio> automação OLE para fazer scripts em Excel e ler dados dele,
>     Marcio> funcionando muito bem.
>
>     Marcio> A interface entre os dois aplicativos não existe, assim como o sistema
>     Marcio> do Mainframe não tem mais manutenção ou qualquer outra forma de
>     Marcio> acesso, não sendo possível mexer nele e ninguém tem acesso ao OS, só a
>     Marcio> empresa que faz a manutenção. Assim há um trabalho muito complicado de
>     Marcio> ficar atualizando informações entre os dois sistemas, e está gerando
>     Marcio> muitos erros. Está fora de cogitação qualquer ideia que tenha que
>     Marcio> mexer no Mainframe.
>
>     Marcio> A ideia é que o script Perl navegue pelas telas lendo e inserindo
>     Marcio> dados, assim como os scripts em Excel fazem usando a automação OLE do
>     Marcio> Extra!.
>
> Que beleza... :)
>
>     Marcio> Pelo que entendi esse s3270 é para isso mesmo, o duro é só saber como usar.
>
>     Marcio> Em tempo, o que estou fazendo é para facilitar a integração do sistema
>     Marcio> de telefonia com o CRM.
>
> Olha, na real você só está adiando a dor e o custo de trocar o TN3270
> por algo mais manutenível. Isso vai quebrar teu galho agora, mas em
> algum momento no futuro, vai aparecer um requisito muito simples mas que
> vai ficar caro de implementar por conta da complexidade adicional de
> interagir com o sistema dessa forma. Isso sem nem levar em consideração
> os bugs que podem existir dentro do s3270 e do Expect, que podem e vão
> explodir na hora que você menos esperar e vai ser muito difícil de
> consertar. Eu sugiro que você implemente isso como medida provisória e
> planeje uma migração definitiva, se puder. Se não puder, meus pêsames,
> você está montado numa bomba-relógio sem ponteiros.
>
> --
> Eden Cardim
> +55 11 9644 8225
> Insolide TI Ltda.
> http://insoli.de
> =begin disclaimer
>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>  SaoPaulo-pm mailing list: SaoPaulo-pm em pm.org
>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
> =end disclaimer



-- 

[...]'s

Marcio


More information about the SaoPaulo-pm mailing list