Avançar para a área de conteúdo

ir para o conteúdo principal

developerWorks Brasil  >  Software livre  >

Construir um Serviço RESTful no CICS com PHP

developerWorks
Ir para a página anteriorPágina 3 de 10 Ir para a próxima página

Opções de documento

Código de amostra


Classificar este tutorial

Ajude-nos a melhorar este conteúdo


Invocando o Programa Library a partir do PHP

Disponibilizando COMMAREA para PHP

Quando COMMAREA for definida no programa COBOL e ADATA tiver sido gerado, a próxima etapa será criar classes Java™ que representam a COMMAREA. Estas classes são usadas para tornar a COMMAREA acessível a partir de scripts PHP.

Será necessário gerar as classes Java apenas uma vez: assim que as classes estiverem disponíveis para o CA1S, poderá ser gravada qualquer quantidade de scripts para usá-las para interação com o programa COBOL. No entanto, se o programa COBOL for modificado de maneira que altere a forma da COMMAREA, será necessário gerar novamente o ADATA e as classes Java e adaptar os scripts PHP conforme necessário.

As etapas a seguir requerem um Java SDK e assumem que os comandos java e javac estejam disponíveis no PATH do sistema. Execute-os em sua estação de trabalho ou diretamente no sistema CICS.

1. Gerar a origem das classes de COMMAREA

java -cp jzos_recgen.jar com.ibm.jzos.recordgen.cobol.RecordClassGenerator genCache=false
adataFile=LIBRARY symbol=DFHCOMMAREA class=Library_Commarea package=library outputDir=.
             

Vamos descrever o propósito de cada parte do comando acima:

java -cp jzos_recgen.jar com.ibm.jzos.recordgen.cobol.RecordClassGenerator
             

Isto invoca o JZOS Record Generator, que é um programa Java contido no arquivo jzos_recgen.jar. Este arquivo está incluído no CA1S, e a versão mais recente está disponível no site do IBM JZOS Batch Toolkit for z/OS SDKs no alphaWorks (consulte Recursos).

Por que recebo uma exceção Java quando tento executar o gerador de registro do JZOS?

Antes de recuperar o ADATA usando FTP, lembre-se de executar o comando 'quote site rdw' e 'bin'.

Para obter informações adicionais, consulte a seção "Running the COBOL RecordClassGenerator" da documentação do JZOS, que está incluída no pacote do CA1S como "JZOS Cobol Record Generator Users Guide.pdf".

genCache=false
             

Esta opção assegura que o código Java gerado não tentará armazenar em cache o valor de campos de COMMAREA. Esta opção é necessária para que o CA1S interaja corretamente com as classes geradas.

adataFile=LIBRARY
             

Isto especifica o caminho para o arquivo ADATA obtido na seção anterior.

symbol=DFHCOMMAREA 

Isto especifica o nome da COMMAREA para a qual gerar a classe.

class=Library_Commarea
             

Isto especifica o nome da classe Java resultante.

package=library
             

Isto especifica o pacote da classe Java resultante.

outputDir=.
             

Isto especifica o caminho no qual a classe Java será gravada no sistema de arquivos.

2. Gerar a origem Java para a classe que representa constantes COBOL

No aplicativo de biblioteca de amostra, as constantes usadas no programa COBOL (para os nomes de operações e códigos de resposta) são definidas em uma estrutura de dados na seção WORKING-STORAGE. Isto significa que uma classe Java que representa estas constantes pode ser gerada e usada a partir do PHP de forma semelhante à classe que representa a COMMAREA, neste caso, para obter os valores das constantes definidas quando necessário.

java -cp jzos_recgen.jar com.ibm.jzos.recordgen.cobol.RecordClassGenerator genCache=false
adataFile=LIBRARY symbol=LIBRARY-CONSTANTS class=Library_Constants package=library
outputDir=.
             

A vantagem desta abordagem é que a reflexão de PHP pode ser usada para examinar os nomes de constantes disponíveis, e o programador de PHP não precisa consultar diretamente os valores definidos no COBOL. Lembre-se de que isto pode ser feito para o aplicativo LIBRARY devido à forma de definição das constantes, e nem sempre isso será possível, por exemplo, quando valores codificados permanentemente estiverem integrados na origem COBOL.

Nos scripts PHP fornecidos com este artigo, é adotada uma abordagem mista, na qual algumas destas constantes são usadas em seus formatos literais (por exemplo, os nomes de operações), e algumas são extraídas usando a classe Java gerada (os códigos de resposta numéricos).

3. Compilar os arquivo de origem .java para criar arquivos de classe Java

A origem Java gerada estará no outputDir especificado acima, na biblioteca do subdiretório (que corresponde ao nome do pacote). Usar javac para compilar os arquivos de origem da seguinte forma:

javac -cp jzos_recgen.jar library/*

4. Disponibilizar os arquivos de classe para o CA1S

O diretório da biblioteca agora contém as classes compiladas. Para que o CA1S possa usá-las, elas devem estar disponíveis no caminho de classe Java. Se você gerou as classes em sua estação de trabalho, será necessário transferir o diretório para o servidor (por exemplo, usando o FTP).

O caminho de classe Java é determinado pelo atributo CLASSPATH_SUFFIX do JVMPROFILE usado pelo CA1S. O JVMPROFILE padrão no CA1S (denominado CA1SJVMP) já está configurado para incluir o diretório ca1s/work/classes/ no CLASSPATH_SUFFIX:

CLASSPATH_SUFFIX=/u/p8build/ca1s/config/ini:\
                 /u/p8build/ca1s/p8/jars/p8api.jar:\
                 /u/p8build/ca1s/p8/jars/p8.jar:\
                 /u/p8build/ca1s/p8/jars/p8cics.jar:\
                 /u/p8build/ca1s/work/classes:\
                 /usr/lpp/db2910/classes/db2jcc.jar:\
                 /usr/lpp/db2910/classes/db2jcc_javax.jar:\
                 /usr/lpp/db2910/classes/db2jcc_license_cisuz.jar
             

Portanto, se você estiver usando JVMPROFILE CA1SJVMP, poderá copiar o diretório da biblioteca para ca1s/work/classes/. Como alternativa, é possível alterar seu CLASSPATH_SUFFIX para incluir um diretório ou arquivo JAR que contenha o diretório da biblioteca.

Observe que a estrutura de diretório que representa o nome do pacote deve ser preservada no local do caminho de classe. Portanto, se você estiver usando ca1s/work/classes/, copie o próprio diretório da biblioteca de forma que as classes estejam em ca1s/work/classes/library (e não diretamente em ca1s/work/classes/).

Por último, encerre gradualmente suas JVMs para assegurar que as novas classes sejam selecionadas pelo CA1S.



Voltar para parte superior


Acessando o Programa a partir do Código PHP

O Código

A chamada de um programa COMMAREA consiste em 3 etapas:

  1. Preparação da COMMAREA antes de vincular-se ao programa.
  2. Vínculo ao programa.
  3. Recuperação do resultado do link da COMMAREA.

Para ilustrar, a Listagem 3 mostra um script que invoca o programa de biblioteca para obter uma lista de books, em seguida, imprime-os:


Listagem 3. Invocando um programa CICS Commarea a partir do PHP


<?php
// Etapa 1: criar e preparar a instância COMMAREA
java_import('library.Library_Commarea');
$COMMAREA = new Library_Commarea();
$COMMAREA->setLibRequestType('LIST');

// Etapa 2: criar a instância do programa e invocá-la usando COMMAREA
$program = new CICSProgram('LIBRARY');
try {
  $program->link($COMMAREA);
} catch (CICSException $e) {
  echo 'Error: ' . $e->getMessage();
  return;
}

// Etapa 3: recuperar o resultado do link da COMMAREA
$totalBooks = $COMMAREA->getLibItemCount();
echo "Total number of books: $totalBooks <br/>";

for ($i=0; $i<$totalBooks; $i++) {
  $book = $COMMAREA->getLibBookItem($i);
  $title = $book->getBookTitle();
  $author = $book->getBookAuthor();
  echo "Book $i is '$title' by '$author'. <br/>";
}
?>

Por que vejo apenas caracteres inválidos quando acesso um script em meu navegador?

Isto pode ocorrer se o script for codificado na página de códigos incorreta. Por padrão, o tempo de execução para PHP no CA1S é configurado para esperar scripts na codificação UTF-8. Portanto, se você transferir scripts entre uma estação de trabalho do Windows® ou Linux® e seu servidor CICS, certifique-se de configurar modo "binary", para que os scripts não sejam convertidos em uma página de códigos EBCDIC durante a transferência. Para obter informações adicionais sobre questões de codificação e opções de configuração no CA1S, consulte a documentação do CA1S.

Este script é fornecido no download do código de amostra como library/scripts/library.php. Se você transferir este script em seu sistema CICS para ca1s/work/scripts/library.php e acessá-lo em seu navegador, deverá ver uma lista de books como:

Total number of books: 18
Book 0 is 'PHP for Beginners ' by 'Rob Nicholson '.
Book 1 is 'Project Management ' by 'A N IBMer '.
Book 2 is 'Easy Z Specification' by 'Jonathan '.
Book 3 is 'REST Protocol Design' by 'Zoe, Ant & Rob '.
etc...
             

Vamos examinar detalhadamente as três etapas no código.


Preparando a COMMAREA
java_import('library.Library_Commarea');
             

A função java_import(), que é integrada ao tempo de execução para PHP no CA1S, carrega uma classe Java e a disponibiliza para uso no PHP. No código acima, carregamos a classe Java que representa a classe COMMAREA da biblioteca gerada anteriormente.

$COMMAREA = new Library_Commarea();
             

Em seguida, criamos uma instância desta classe. Esta instância será usada como um contêiner para os dados de entrada e saída da chamada.

$COMMAREA->setLibRequestType('LIST');
             

Por último, na terceira linha, configuramos alguns dados de entrada na COMMAREA. O método setLibRequestType é específico da classe Java que representa a COMMAREA do programa COBOL usado neste tutorial: ele define a operação que desejamos executar na biblioteca, neste caso, obter uma LISTA de todos os books. Consulte Investigando a COMMAREA Usando Reflexão para saber como usar o PHP para descobrir todos os métodos na classe Java.


Vinculando-se ao Programa
$program = new CICSProgram('LIBRARY');
             

Primeiro, criamos uma instância da classe integrada CICSProgram, que representa o programa CICS com o qual desejamos interagir. O nome do programa CICS é especificado como o argumento do construtor, neste caso, "LIBRARY." Se o programa precisasse ser renomeado, este programa precisaria ser alterado.

Por que eu vejo "com.ibm.cics.server.InvalidProgramIdException: CICS PGMIDERR Condition" em vez da saída esperada?

Verifique se o argumento passado para o construtor CICSProgram representa o nome do programa COBOL instalado em seu sistema CICS.

$program->link($COMMAREA);

O método de link na classe CICSProgram aciona a execução do programa CICS. Se um único argumento de COMMAREA for fornecido, como neste caso, ele será usado pelo programa CICS como um contêiner para dados de entrada e de saída. Também é possível fornecer dois argumentos de COMMAREA separados, neste caso, o primeiro argumento deverá conter dados de entrada e os dados de saída serão gravados no segundo. Também é possível não fornecer nenhum argumento, o que é útil nos casos em que o programa CICS não possui entrada e saída.

try / catch block

Se o link falhar ou o programa vinculado for finalizado anormalmente, o método de link lançará uma CICSException. O método getMessage() no objeto de exceção exibe detalhes da falha, incluindo o tipo de exceção Java subjacente. Por exemplo, se um nome de programa inválido for especificado como o argumento para o construtor CICSProgram o código acima será impresso:

Error: com.ibm.cics.server.InvalidProgramIdException: CICS PGMIDERR Condition


Recuperando Dados da COMMAREA
$totalBooks = $COMMAREA->getLibItemCount();

Quando link() for retornado com êxito, a COMMAREA conterá a saída da chamada. Na etapa 3 do script PHP acima, usamos vários métodos específicos da classe Library_Commarea para obter o número total de books, em seguida, para iterar sobre a lista de books, imprimindo o título e autor de cada um.



Voltar para parte superior


Investigando a Commarea Usando a Reflexão PHP

Configurar dados de entrada em uma COMMAREA antes de um link e recuperar dados de saída dele posteriormente requer conhecimento dos métodos setter e getter na classe de COMMAREA. Se você não tiver uma lista destes métodos acessível, será simples obter uma com reflexão PHP.

Por exemplo, o seguinte script usa as classes de reflexão PHP (consulte Recursos) para obter a lista de métodos disponíveis da classe Library_Commarea:


Listagem 4. Usando a reflexão, parte 1
<?php
java_import('library.Library_Commarea');
$COMMAREA = new Library_Commarea();
$rc = new ReflectionObject($COMMAREA);
foreach ($rc->getMethods() as $method) {
	echo $method->getName() . '<br/>';
}
?>
             

A saída do script na Listagem 4 é:

Library_Commarea
__tostring
setLibItemCount
getLibReturnCode
setLibRequestType
setLibReturnCode
getByteBuffer
getLibRequestType
getLibBookItem
getLibItemCount


Além do método Library_Commarea() (que é o construtor) e de getByteBuffer() (que fornece acesso ao array de bytes brutos que contém os dados de COMMAREA), todos os demais métodos são getters e setters para campos de COMMAREA. Os usados no script inicial são marcados em negrito.

Alguns getters retornam estruturas de dados complexos, como o método getLibBookItem() acima, que retorna um objeto que representa um book. A mesma técnica pode ser usada nestas estruturas de dados para descobrir quais campos podem ser acessados. Por exemplo, usamos aqui a função do PHP get_class_methods() de Joshua Bloch (consulte Recursos) para estabelecer quais campos podem ser acessados em um book:


Listando 5. Usando a reflexão, parte 2
<?php
// Etapa 1: criar e preparar a instância de COMMAREA
java_import('library.Library_Commarea');
$COMMAREA = new Library_Commarea();
$COMMAREA->setLibRequestType('LIST');

// Etapa 2: criar a instância do programa e invocar o programa usando a COMMAREA
$program = new CICSProgram('LIBRARY');
$program->link($COMMAREA);

// Investigar os campos disponíveis em um objeto book
$book = $COMMAREA->getLibBookItem(0);
print_r(get_class_methods($book));
?>
             

A saída do script na Listagem 5 é:

Array
(
    [0] => LibBookItem
    [1] => getBookTitle
    [2] => setBookItemRef
    [3] => isBookOnloan
    [4] => getBookAuthor
    [5] => isBookUnlent
    [6] => getByteBuffer
    [7] => setBookAuthor
    [8] => setBookBorrower
    [9] => getBookLoanStatus
    [10] => getByteBufferOffset
    [11] => getBookBorrower
    [12] => __tostring
    [13] => getFiller_1
    [14] => getBookItemRef
    [15] => setBookTitle
    [16] => setFiller_1
    [17] => setBookLoanStatus
)
             



Voltar para parte superior


Resolução de Problemas do Caminho de Classe com phpinfo()

Se aparecerem avisos ou erros sugerindo que a classe de COMMAREA não pode ser localizada, verifique o caminho de classe Java para assegurar que ele inclua um diretório ou arquivo JAR contendo o diretório da biblioteca (que contém as classes geradas).

Isto pode ser feito diretamente do código php usando a função do PHP phpinfo():

<?php
phpinfo();
?>
             

Acessar esse script em um navegador exibirá uma grande quantidade de informações, incluindo o caminho de classe completo:


Figura 1. Verificando o caminho de classe Java com phpinfo()
Uma tela de saída de amostra que exibe várias configurações de variável

classpath.png

Mais comumente, phpinfo() é uma ferramenta útil para investigar muitos aspectos do ambiente PHP.



Voltar para parte superior



Ir para a página anteriorPágina 3 de 10 Ir para a próxima página