[SP-pm] Perl para automação em acesso a x3270 IBM
Gabriel Vieira
gabriel.vieira at gmail.com
Mon Jul 9 21:43:10 PDT 2012
Olá,
tenho experiência mas via OLE no Windows.. se tiver interesse te envio
a aplicação... (lembro que havia um problema de delay... o terminal
era bem lento pro script e eu não conseguia identificar como
solucionar).. era pra se conectar so SisBB do Banco do Brasil.
Abraços,
2012/7/9 Marcio - Google <marciorp em gmail.com>:
> 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
> =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
--
Gabriel Vieira
More information about the SaoPaulo-pm
mailing list