Estrutura do AWS Blu Age de uma aplicação modernizada
Este documento fornece detalhes sobre a estrutura de aplicações modernizadas (usando ferramentas de refatoração do AWS Mainframe Modernization), para que os desenvolvedores possam realizar várias tarefas, como:
-
navegando pelas aplicações sem problemas.
-
desenvolvendo programas personalizados que podem ser chamados a partir das aplicações modernizadas.
-
refatorando com segurança aplicações modernizadas.
Presumimos que você já tenha conhecimentos básicos sobre o seguinte:
-
conceitos de codificação comuns herdados, como registros, conjuntos de dados e seus modos de acesso aos registros — indexados, sequenciais —, VSAM, unidades de execução, scripts jcl, conceitos do CICS e assim por diante.
-
codificação java usando o framework Spring
. -
Em todo o documento, usamos
short class names
para facilitar a leitura. Para obter mais informações, consulte Mapeamentos de nomes totalmente qualificados do AWS Blu Age para recuperar os nomes totalmente qualificados correspondentes para os elementos do AWS Blu Age Runtime e Mapeamentos de nomes totalmente qualificados de terceiros para recuperar os nomes totalmente qualificados correspondentes para elementos de terceiros. -
Todos os artefatos e amostras são retirados das saídas do processo de modernização da aplicação COBOL/CICS CardDemo de amostra
.
Tópicos
Organização de artefatos
As aplicações modernizadas do AWS Blu Age são empacotados como aplicações web java (.war), que você pode implantar em um servidor JEE. Normalmente, o servidor é uma instância do Tomcat
A guerra agrega vários artefatos de componentes (.jar). Cada jar é o resultado da compilação (usando a ferramenta maven

A organização básica se baseia na seguinte estrutura:
-
Projeto de entidades: contém elementos do modelo de negócios e do contexto. O nome do projeto geralmente termina com “-entities”. Normalmente, para um determinado programa COBOL antigo, isso corresponde à modernização da seção de E/S (conjuntos de dados) e da divisão de dados. É possível ter um projeto de mais de uma entidade.
-
Projeto de serviço: contém elementos antigos de modernização da lógica de negócios. Normalmente, a divisão de procedimentos de um programa COBOL. Você pode ter mais de um projeto de serviço.
-
Projeto utilitário: contém ferramentas e utilitários comuns compartilhados, usados por outros projetos.
-
Projeto Web: contém a modernização de elementos relacionados à interface do usuário, quando aplicável. Não é usado para projetos de modernização somente em lote. Esses elementos da interface do usuário podem vir dos mapas do CICS BMS, dos componentes do IMS MFS e de outras fontes de interface do usuário do mainframe. Você pode ter mais de um projeto da Web.
Conteúdo do projeto Entidades
nota
As descrições a seguir se aplicam somente às saídas de modernização COBOL e PL/I. As saídas de modernização do RPG são baseadas em um layout diferente.
Antes de qualquer refatoração, a organização dos pacotes no projeto da entidade está vinculada aos programas modernizados. É possível fazer isso de duas maneiras diferentes. A forma preferida é usar a caixa de ferramentas de refatoração, que opera antes de você acionar o mecanismo de geração de código. Essa é uma operação avançada, que é explicada nos treinamentos do BluAge. Para obter mais informações, consulte Workshop de refatoração

Aulas relacionadas ao programa
Cada programa modernizado está relacionado a dois pacotes, um pacote business.context e um pacote business.model.
-
base package
.program
.business.contextO subpacote business.context contém duas classes, uma classe de configuração e uma classe de contexto.
-
Uma classe de configuração para o programa, que contém detalhes de configuração específicos para um determinado programa, como o conjunto de caracteres a ser usado para representar elementos de dados baseados em caracteres, o valor de byte padrão para preencher elementos da estrutura de dados e assim por diante. O nome da classe termina com “Configuração”. Ele é marcado com a
@org.springframework.context.annotation.Configuration
anotação e contém um único método que deve retornar um objetoConfiguration
configurado corretamente. -
Uma classe de contexto, que serve como uma ponte entre as classes de serviço do programa (veja abaixo) e as estruturas de dados (
Record
) e os conjuntos de dados (File
) do subpacote do modelo (veja abaixo). O nome da classe termina com “Contexto” e é uma subclasse daRuntimeContext
classe.
-
-
base package
.program
.business.modelO subpacote do modelo contém todas as estruturas de dados que o programa fornecido pode usar. Por exemplo, qualquer estrutura de dados COBOL de nível 01 corresponde a uma classe no subpacote do modelo (estruturas de dados de nível inferior são propriedades de sua própria estrutura de nível 01). Para obter mais informações sobre como modernizamos 01 estruturas de dados, consulte O que são simplificadores de dados no AWS Blu Age.
Todas as classes estendem a RecordEntity
classe, que representa o acesso a uma representação de registros comerciais. Alguns dos registros têm um propósito especial, pois estão vinculados a um File
. A associação entre a Record
e a File
é feita nos métodos *FileHandler correspondentes encontrados na classe de contexto ao criar o objeto de arquivo. Por exemplo, a lista a seguir mostra como o TransactfileFile File
está vinculado ao transactFile Record
(do subpacote do modelo).

Conteúdo do projeto de serviço
Cada projeto de serviço vem com uma aplicação SpringbootSpringBootLauncher
, localizada no pacote base das fontes java do serviço:

Essa classe é especialmente responsável por:
-
criando a cola entre as classes do programa e os recursos gerenciados (fontes de dados/gerenciadores de transações/mapeamentos de conjuntos de dados/ etc.).
-
fornecendo dois
ConfigurableApplicationContext
programas. -
descobrindo todas as classes marcadas como componentes de primavera (
@Component
). -
garantindo que os programas sejam registrados corretamente no
ProgramRegistry
-- veja o método de inicialização responsável por esse registro.

Artefatos relacionados ao programa
Sem refatoração prévia, os resultados da modernização da lógica de negócios são organizados em dois ou três pacotes por programa antigo:

O estojo mais exaustivo terá três pacotes:
-
base package.program.service
: contém uma interface chamada ProgramProcess, que tem métodos de negócios para lidar com a lógica de negócios, preservando o fluxo de controle de execução antigo. -
base package.program.service.impl
: contém uma classe chamada ProgramProcessImpl, que é a implantação da interface Process descrita anteriormente. É aqui que as declarações antigas são “traduzidas” para instruções java, com base na estrutura AWS Blu Age: -
base package.program.statemachine
: esse pacote pode nem sempre estar presente. É necessário quando a modernização do fluxo de controle antigo precisa usar uma abordagem de máquina de estado (ou seja, usar a estrutura Spring StateMachine) para cobrir adequadamente o fluxo de execução antigo. Nesse caso, o subpacote statemachine contém duas classes:
-
ProgramProcedureDivisionStateMachineController
: uma classe que estende uma classe que implementa as interfacesStateMachineController
(define as operações necessárias para controlar a execução de uma máquina de estado) eStateMachineRunner
(define as operações necessárias para executar uma máquina de estado), usadas para conduzir a mecânica da máquina de estado Spring; por exemplo,SimpleStateMachineController
como no caso de exemplo.O controlador da máquina de estado define os diferentes estados possíveis e as transições entre eles, que reproduzem o fluxo de controle de execução antigo para o programa em questão.
Ao criar a máquina de estado, o controlador se refere aos métodos definidos na classe de serviço associada localizada no pacote da máquina de estado e descrita abaixo:
subConfigurer.state(States._0000_MAIN, buildAction(() -> {stateProcess._0000Main(lctx, ctrl);}), null); subConfigurer.state(States.ABEND_ROUTINE, buildAction(() -> {stateProcess.abendRoutine(lctx, ctrl);}), null);
-
ProgramProcedureDivisionStateMachineService
: essa classe de serviço representa alguma lógica de negócios que precisa ser vinculada à máquina de estado criada pelo controlador da máquina de estado, conforme descrito anteriormente.O código nos métodos dessa classe usa os eventos definidos no controlador da máquina de estado:
O serviço statemachine também faz chamadas para a implantação do serviço de processo descrita anteriormente:
-
Além disso, um pacote chamado base package.program
desempenha um papel importante, pois reúne uma classe por programa, que servirá como ponto de entrada do programa (mais detalhes sobre isso posteriormente). Cada classe implementa a interface Program
, marcador para um ponto de entrada do programa.

Outros artefatos
-
Companheiros do BMS MAPs
Além dos artefatos relacionados ao programa, o projeto de serviço pode conter outros artefatos para várias finalidades. No caso da modernização de uma aplicação online do CICS, o processo de modernização produz um arquivo json e coloca na pasta map da pasta /src/main/resources:
O Blu Age Runtime consome esses arquivos json para vincular os registros usados pela instrução SEND MAP aos campos da tela.
-
Scripts Groovy
Se a aplicação antiga tinha scripts JCL, eles foram modernizados como scripts groovy
, armazenados na pasta /src/main/resources/scripts (mais sobre esse local específico posteriormente): Esses scripts são usados para iniciar trabalhos em lotes (workloads de processamento de dados dedicadas, não interativas e com uso intenso de CPU).
-
Arquivos SQL
Se a aplicação antiga estava usando consultas SQL, as consultas SQL modernizadas correspondentes foram reunidas em arquivos de propriedades dedicados, com o padrão de nomenclatura program.sql, em que program é o nome do programa que usa essas consultas.
O conteúdo desses arquivos sql é uma coleção de entradas (key=query), em que cada consulta é associada a uma chave exclusiva, que o programa modernizado usa para executar a consulta fornecida:
Por exemplo, o programa COSGN00C está executando a consulta com a chave “COSGN00C_1" (a primeira entrada no arquivo sql):
Conteúdo do projeto de utilitários
O projeto de utilitários, cujo nome termina com “-tools”, contém um conjunto de utilitários técnicos, que podem ser usados por todos os outros projetos.

Conteúdo dos projetos web
O projeto web só está presente ao modernizar elementos antigos da interface do usuário. Os elementos modernos da interface de usuário usados para criar o front-end da aplicação modernizada são baseados no Angular

O projeto web cuida apenas do aspecto de frontend da aplicação. O projeto de serviço, que depende dos projetos de utilitários e de entidades, fornece os serviços de backend. O link entre o frontend e o backend é feito por meio do aplicativo web chamado Gapwalk-Application, que faz parte da distribuição de tempo de execução padrão do AWS Blu Age.
Executando e chamando programas
Em sistemas herdados, os programas são compilados como executáveis autônomos que podem se chamar por meio de um mecanismo CALL, como a instrução COBOL CALL, transmitindo argumentos quando necessário. As aplicações modernizadas oferecem a mesma capacidade, mas usam uma abordagem diferente, porque a natureza dos artefatos envolvidos difere dos antigos.
No lado modernizado, os pontos de entrada do programa são classes específicas que implementam a interface Program
, são componentes do Spring (@Component) e estão localizados em projetos de serviço, em um pacote chamado base package.program
.
Registro de programas
Cada vez que o servidor TomcatProgramRegistry
é preenchido com entradas de programa, cada programa sendo registrado usando seus identificadores, uma entrada por identificador de programa conhecido, o que significa que, se um programa for conhecido por vários identificadores diferentes, o registro conterá tantas entradas quanto identificadores.
O registro de um determinado programa depende da coleção de identificadores retornados pelo método getProgramIdentifiers():

Neste exemplo, o programa é registrado uma vez, sob o nome 'CBACT04C' (veja o conteúdo da coleção programIdentifiers). Os logs do tomcat mostram cada registro do programa. O registro do programa depende apenas dos identificadores declarados do programa e não do nome da classe do programa em si (embora normalmente os identificadores do programa e os nomes das classes do programa estejam alinhados).
O mesmo mecanismo de registro se aplica aos programas utilitários trazidos pelos várias aplicações web utilitários AWS Blu Age, que fazem parte da distribuição do AWS Blu Age Runtime. Por exemplo, a aplicação web Gapwalk-Utility-Pgm fornece os equivalentes funcionais dos utilitários do sistema z/OS (IDCAMS, ICEGENER, SORT etc.) e pode ser chamado por programas ou scripts modernizados. Todos os programas utilitários disponíveis registrados na inicialização do Tomcat são registrados nos logs do Tomcat.
Registro de scripts e daemons
Um processo de registro semelhante, no momento da inicialização do Tomcat, ocorre para scripts groovy que estão localizados na hierarquia de pastas /src/main/resources/scripts. A hierarquia da pasta de scripts é percorrida e todos os scripts groovy descobertos (exceto o script reservado de funções especiais.groovy) são registrados no ScriptRegistry
, usando seu nome curto (a parte do nome do arquivo de script localizada antes do primeiro caractere de ponto) como chave para recuperação.
nota
-
Se vários scripts tiverem nomes de arquivo que resultarão na produção da mesma chave de registro, somente o mais recente será registrado, substituindo qualquer registro encontrado anteriormente para essa chave específica.
-
Considerando a observação acima, preste atenção ao usar subpastas, pois o mecanismo de registro nivela a hierarquia e pode levar a substituições inesperadas. A hierarquia não conta no processo de registro: normalmente, /scripts/a/myscript.groovy e /scripts/b/myscript.groovy farão com que /scripts/b/myscript.groovy sobrescreva /scripts/a/myscript.groovy.
Os scripts groovy na pasta /src/main/resources/daemons são tratados de forma um pouco diferente. Eles ainda estão registrados como scripts regulares, mas, além disso, são lançados uma vez, diretamente no momento da inicialização do Tomcat, de forma assíncrona.
Depois que os scripts são registrados no ScriptRegistry
, uma chamada REST pode iniciá-los, usando os endpoints dedicados que a aplicação Gapwalk expõe. Para obter mais informações, consulte a documentação correspondente.
Programas de chamada de programas
Cada programa pode chamar outro programa como subprograma, passando parâmetros para ele. Os programas usam uma implantação da interface ExecutionController
para fazer isso (na maioria das vezes, isso será uma instância ExecutionControllerImpl
), junto com um mecanismo de API fluente chamado de CallBuilder
para criar os argumentos de chamada do programa.
Todos os métodos de programas usam tanto a RuntimeContext
quanto an ExecutionController
como argumentos de método, portanto, um ExecutionController
está sempre disponível para chamar outros programas.
Veja, por exemplo, o diagrama a seguir, que mostra como o programa CBST03A chama o programa CBST03B como um subprograma, passando parâmetros para ele:

-
O primeiro argumento do
ExecutionController.callSubProgram
é um identificador do programa a ser chamado (ou seja, um dos identificadores usados para o registro do programa -- veja os parágrafos acima). -
O segundo argumento, que é o resultado da estrutura no
CallBuilder
, é uma matriz deRecord
, correspondente aos dados passados do chamador para o chamador. -
O terceiro e último argumento é a instância
RuntimeContext
do chamador.
Todos os três argumentos são obrigatórios e não podem ser nulos, mas o segundo argumento pode ser uma matriz vazia.
O chamador só poderá lidar com os parâmetros passados se tiver sido originalmente projetado para isso. Para um programa COBOL antigo, isso significa ter uma seção LINKAGE e uma cláusula USING para que a divisão de procedimentos faça uso dos elementos LINKAGE.
Por exemplo, consulte o arquivo fonte COBOL CBSTM03B.CBL

Portanto, o programa CBSTM03B usa um único Record
como parâmetro (uma matriz de tamanho 1). Isso é o que CallBuilder
está construindo, usando o encadeamento de métodos byReference () e getArguments ().
A classe de API CallBuilder
fluente tem vários métodos disponíveis para preencher a matriz de argumentos a serem passados para um chamador:
-
asPointer(RecordAdaptable): adicione um argumento do tipo ponteiro, por referência. O ponteiro representa o endereço de uma estrutura de dados de destino.
-
byReference(RecordAdaptable): adicione um argumento por referência. O chamador verá as modificações que o chamador executa.
-
byReference (RecordAdaptable): variante varargs do método anterior.
-
byValue (Object): adicione um argumento, transformado em um
Record
, por valor. O chamador não verá as modificações que o chamador executa. -
byValue(RecordAdaptable): igual ao método anterior, mas o argumento está diretamente disponível como
RecordAdaptable
. -
byValueWithBounds(Object, int, int): adicione um argumento, transformado em um
Record
, extraindo a parte da matriz de bytes definida pelos limites fornecidos, por valor.
Finalmente, o método getArguments coletará todos os argumentos adicionados e os retornará como uma matriz de Record
.
nota
É responsabilidade do chamador garantir que a matriz de argumentos tenha o tamanho necessário, que os itens estejam devidamente ordenados e compatíveis, em termos de layout de memória com os layouts esperados para os elementos de ligação.
Scripts chamando programas
Chamar programas registrados a partir de scripts groovy requer o uso de uma instância de classe implementando a interface MainProgramRunner
. Normalmente, a obtenção dessa instância é obtida por meio do uso do ApplicationContext do Spring:

Depois que uma interface MainProgramRunner
estiver disponível, use o método runProgram para chamar um programa e passar o identificador do programa de destino como parâmetro:

No exemplo anterior, uma etapa de trabalho chama o IDCAMS (programa utilitário de manipulação de arquivos), fornecendo um mapeamento entre as definições reais do conjunto de dados e seus identificadores lógicos.
Ao lidar com conjuntos de dados, os programas antigos geralmente usam nomes lógicos para identificar conjuntos de dados. Quando o programa é chamado a partir de um script, o script deve mapear nomes lógicos com conjuntos de dados físicos reais. Esses conjuntos de dados podem estar no sistema de arquivos, em um armazenamento Blusam ou até mesmo definidos por um fluxo embutido, pela concatenação de vários conjuntos de dados ou pela geração de um GDG.
Use o método withFileConfiguration para criar um mapa lógico para físico dos conjuntos de dados e disponibilizá-lo para o programa chamado.
Escreva seu próprio programa
Escrever seu próprio programa para que scripts ou outros programas modernizados possam ser chamados é uma tarefa comum. Normalmente, em projetos de modernização, você escreve seus próprios programas quando um programa antigo executável é escrito em uma linguagem que o processo de modernização não suporta, ou as fontes foram perdidas (sim, isso pode acontecer) ou o programa é um utilitário cujas fontes não estão disponíveis.
Nesse caso, talvez você precise escrever o programa ausente, em java, sozinho (supondo que você tenha conhecimento suficiente sobre qual deve ser o comportamento esperado do programa, o layout de memória dos argumentos do programa, se houver, e assim por diante). Seu programa java deve estar em conformidade com a mecânica do programa descrita neste documento, para que outros programas e scripts possam executá-lo.
Para garantir que o programa seja utilizável, você deve concluir duas etapas obrigatórias:
-
Escreva uma classe que implemente a interface
Program
corretamente, para que ela possa ser registrada e chamada. -
Certifique-se de que seu programa esteja registrado corretamente, para que fique visível em outros programas/scripts.
Escrevendo a implantação do programa
Use seu IDE para criar uma nova classe java que implemente a interface Program
:

A imagem a seguir mostra o Eclipse IDE, que se encarrega de criar todos os métodos obrigatórios a serem implementados:

Integração com o Spring
Primeiro, a classe deve ser declarada como um componente Spring. Anote a classe com a anotação @Component
:

Em seguida, implemente os métodos necessários corretamente. No contexto desse exemplo, adicionamos o MyUtilityProgram
ao pacote que já contém todos os programas modernizados. Esse posicionamento permite que o programa use a aplicação Springboot existente para fornecer o necessário ConfigurableApplicationContext
para a implantação do método getSpringApplication:

Você pode escolher um local diferente para seu próprio programa. Por exemplo, você pode localizar o determinado programa em outro projeto de serviço dedicado. Certifique-se de que o projeto de serviço fornecido tenha sua própria aplicação Springboot, o que possibilita recuperar o ApplicationContext (que deve ser um ConfigurableApplicationContext
).
Dando uma identidade ao programa
Para ser chamado por outros programas e scripts, o programa deve receber pelo menos um identificador, que não deve colidir com nenhum outro programa registrado existente no sistema. A escolha do identificador pode ser motivada pela necessidade de cobrir a substituição de um programa legado existente; nesse caso, você precisará usar o identificador esperado, conforme encontrado nas ocorrências de CALL encontradas em todos os programas legados. A maioria dos identificadores de programas tem 8 caracteres em sistemas herdados.
Criar um conjunto não modificável de identificadores no programa é uma forma de fazer isso. O exemplo a seguir mostra a escolha de “MYUTILPG” como identificador único:

Associar o programa a um contexto
O programa precisa de uma instância RuntimeContext
complementar. Para programas modernizados, o AWS Blu Age gera automaticamente o contexto complementar, usando as estruturas de dados que fazem parte do programa antigo.
Se você estiver escrevendo seu próprio programa, também deverá escrever o contexto complementar.
Referindo-se a Aulas relacionadas ao programa, você pode ver que um programa requer pelo menos duas classes complementares:
-
uma classe de configuração.
-
uma classe de contexto que usa a configuração.
Se o programa utilitário usa alguma estrutura de dados extra, ela também deve ser escrita e usada pelo contexto.
Essas classes devem estar em um pacote que faça parte de uma hierarquia de pacotes que será verificada na inicialização da aplicação, para garantir que o componente de contexto e a configuração sejam tratados pela estrutura Spring.
Vamos escrever uma configuração e um contexto mínimos, no pacote base package.myutilityprogram.business.context
, recém-criado no projeto de entidades:

Aqui está o conteúdo da configuração. Ele está usando uma configuração similar a outros programas -- modernizados -- nas proximidades. Você provavelmente precisará personalizar isso de acordo com as necessidades específicas.

Observações:
-
A convenção geral de nomenclatura é ProgramNameConfiguration.
-
Ele deve usar as anotações @org.springframework.context.annotation.Configuration e @Lazy.
-
O nome do bean geralmente segue a convenção ProgramNameContextConfiguration, mas isso não é obrigatório. Certifique-se de evitar colisões de nomes de beans em todo o projeto.
-
O único método a ser implementado deve retornar um objeto
Configuration
. Use a APIConfigurationBuilder
fluente para ajudar a criar uma.
E o contexto associado:

Observações
-
A classe de contexto deve estender uma implantação de interface
Context
existente (RuntimeContext
ouJicsRuntimeContext
, que éRuntimeContext
aprimorado com itens específicos do JICS). -
A convenção geral de nomenclatura é ProgramNameContext.
-
Você deve declará-lo como um componente de protótipo e usar a anotação @Lazy.
-
O construtor se refere à configuração associada, usando a anotação @Qualifier para direcionar a classe de configuração adequada.
-
Se o programa utilitário usar algumas estruturas de dados extras, elas devem ser:
-
Escrito e adicionado ao pacote
base package.business.model
. -
referenciado no contexto. Dê uma olhada em outras classes de contexto existentes para ver como referenciar classes de estruturas de dados e adaptar os métodos de contexto (constructor/clean-up/reset) conforme necessário.
-
Agora que um contexto dedicado está disponível, deixe o novo programa usá-lo:

Observações:
-
O método getContext deve ser implementado estritamente conforme mostrado, usando-se uma delegação ao método getOrCreate da classe
ProgramContextStore
e ao Spring conectado automaticamenteBeanFactory
. Um único identificador de programa é usado para armazenar o contexto do programa noProgramContextStore
; esse identificador é referenciado como sendo o “identificador principal do programa”. -
A configuração complementar e as classes de contexto devem ser referenciadas usando a anotação spring
@Import
.
Implementando a lógica de negócios
Quando o esqueleto do programa estiver concluído, implemente a lógica de negócios para o novo programa utilitário.
Faça isso no método run
do programa. Esse método será executado sempre que o programa for chamado, seja por outro programa ou por um script.
Feliz codificação!
Gerenciando o registro do programa
Por fim, verifique se o novo programa está registrado corretamente no ProgramRegistry
. Se você adicionou o novo programa ao pacote que já contém outros programas, não há mais nada a ser feito. O novo programa é selecionado e registrado em todos os programas vizinhos na inicialização da aplicação.
Se você escolheu outro local para o programa, verifique se o programa está registrado corretamente na inicialização do Tomcat. Para se inspirar sobre como fazer isso, veja o método initialize das classes SpringbootLauncher geradas nos projetos de serviço (consulte Conteúdo do projeto de serviço).
Verifique os logs de inicialização do Tomcat. Cada registro do programa é registrado. Se o seu programa for registrado com sucesso, você encontrará a entrada de log correspondente.
Quando tiver certeza de que seu programa está registrado corretamente, você pode começar a iterar na codificação da lógica de negócios.
Mapeamentos de nomes totalmente qualificados
Esta seção contém listas do AWS Blu Age e de mapeamentos de nomes totalmente qualificados de terceiros para uso em suas aplicações modernizadas.
Mapeamentos de nomes totalmente qualificados do AWS Blu Age
Nome curto | Nome totalmente qualificado |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mapeamentos de nomes totalmente qualificados de terceiros
Nome curto | Nome totalmente qualificado |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|