Crie um Site Mínimo em Angular com o Oracle Content Management sem Elevação
Introdução
Angular é uma plataforma para criar aplicativos web móveis e de desktop.
Para consumir nosso conteúdo do Oracle Content Management em um aplicativo Angular, podemos usar a amostra mínima Angular disponível como repositório de código-fonte aberto no GitHub.
Neste tutorial, vamos construir um site mínimo simples em Angular aproveitando o Oracle Content Management como um CMS sem supervisão, bem como seu kit de desenvolvimento de software (SDK) para entrega de conteúdo em JavaScript. Esta amostra angular está disponível no GitHub.
O tutorial consiste de três etapas:
- Preparar o Oracle Content Management
- Construa o site mínimo em Angular
- Preparar seu aplicativo para implantação
Pré-requisitos
Antes de prosseguir com este tutorial, recomendamos que você leia as seguintes informações primeiro:
Para seguir este tutorial, você precisará:
- uma assinatura do Oracle Content Management
- uma conta do Oracle Content Management com a atribuição de Administrador de Conteúdo
- um computador Windows ou Mac com o Node versão 10 ou superior
O que estamos construindo
Com o mínimo Angular, você pode recuperar facilmente imagens e outro conteúdo do repositório do Oracle Content Management.
Para dar uma olhada no que estamos construindo, aqui está o estado final de nosso tutorial, um site angular básico que consome conteúdo do Oracle Content Management:
https://headless.mycontentdemo.com/samples/oce-angular-minimal-sample
Esta é a aparência da página inicial no fim deste tutorial:
Esta é a aparência da página entre em contato conosco no final deste tutorial:
Para continuar, será necessário ter uma inscrição ativa no Oracle Content Management e fazer log-in com a função Administrador de Conteúdo.
Tarefa 1: Preparar o Oracle Content Management
Se você ainda não tiver uma instância do Oracle Content Management, consulte o Início Rápido para saber como se registrar no Oracle Cloud, provisionar uma instância do Oracle Content Management e configurar o Oracle Content Management como um CMS sem interface do usuário.
Para este tutorial, você precisará criar um modelo de conteúdo. Há um pacote de ativos descarregáveis disponível que preencherá seu repositório vazio com tipos de conteúdo e conteúdo associado.
Para preparar o Oracle Content Management:
- Crie um canal e um repositório de ativos.
- Crie um modelo de conteúdo usando um dos dois métodos:
Criar um Repositório de Ativos e Canal
Primeiro você precisa criar um canal e um repositório de ativos no Oracle Content Management para que possa publicar conteúdo.
Para criar um canal e um repositório de ativos no Oracle Content Management:
Efetue log-in na interface Web do Oracle Content Management como administrador.
Escolha Conteúdo no menu de navegação à esquerda e escolha Publicando Canais na lista de seleção no cabeçalho da página.
No canto superior direito, clique em Criar para criar um novo canal. Nomeie o canal 'OCEMinimalChannel' para a finalidade deste tutorial e mantenha o acesso público. Clique em Salvar para criar o canal.
Escolha Conteúdo no menu de navegação à esquerda e escolha Repositórios na lista de seleção no cabeçalho da página.
No canto superior direito, clique em Criar para criar um novo repositório de ativos. Nomeie o repositório de ativos 'OCEMinimalRepository' para a finalidade deste tutorial.
No campo Canais de Publicação, selecione o canal OCEMinimalChannel para indicar ao Oracle Content Management que o conteúdo no repositório OCEMinimalRepository pode ser publicado no canal OCEMinimalChannel. Clique em Salvar quando terminar.
Criar um Modelo de Conteúdo
A próxima etapa é criar um modelo de conteúdo. Você pode usar um dos dois métodos:
- Método 1: Importar o Pacote de Ativos de Amostras do Oracle Content Management
- Método 2: Criar seu próprio modelo de conteúdo
Importar o Pacote de Ativos de Amostras do Oracle Content Management
Você pode fazer download de um pacote de ativos de amostra pré-configurado do Oracle Content Management que contém todos os tipos de conteúdo e ativos necessários para este tutorial. Se preferir, você também poderá criar seu próprio modelo de conteúdo em vez de fazer download do pacote de ativos de amostra.
Você pode fazer upload de uma cópia do conteúdo que estamos usando neste tutorial a partir do Pacote de Ativos de Amostras do Oracle Content Management. Isso permitirá que você experimente os tipos de conteúdo e modifique o conteúdo. Se quiser importar o Pacote de Ativos de Amostras do Oracle Content Management, você poderá fazer download do arquivo compactado do pacote de ativos, OCESamplesAssetPack.zip e extraí-lo para um diretório de sua escolha:
Faça download do Pacote de Ativos de Amostras do Oracle Content Management (OCESamplesAssetPack.zip) na página downloads do Oracle Content Management. Extraia o arquivo zip baixado para um local no computador. Após a extração, esse local incluirá um arquivo chamado OCEMinimal_data.zip.
Efetue log-in na interface Web do Oracle Content Management como administrador.
Escolha Conteúdo no menu de navegação à esquerda e escolha Repositórios na lista de seleção no cabeçalho da página. Agora selecione OCEMinimalRepository e clique no botão Importar Conteúdo na barra de ação superior.
Faça upload do OCEMinimal_data.zip do computador local para a pasta Documentos.
Após fazer upload, selecione OCEMinimal_data.zip e clique em OK para importar o conteúdo para o repositório de ativos.
Depois que o conteúdo tiver sido importado com sucesso, navegue até a página Ativos e abra o repositório OCEMinimalRepository. Você verá que todas as imagens e itens de conteúdo relacionados foram adicionados ao repositório de ativos.
Clique em Selecionar Tudo no canto superior esquerdo e em Publicar para adicionar todos os ativos importados ao canal de publicação criado anteriormente, OCEGettingStartedChannel.
Antes da publicação, é necessário validar todos os ativos. Primeiro, adicione OCEMinimalChannel como um canal selecionado e, em seguida, clique no botão Validar.
Depois que os ativos tiverem sido validados, você poderá publicar todos os ativos no canal selecionado clicando no botão Publicar no canto superior direito.
Quando isso for feito, você poderá ver na página Ativos que todos os ativos foram publicados. (Você pode informar pelo ícone acima do nome do ativo.)
Depois de importar o Pacote de Ativos de Amostras do Oracle Content Management, você pode iniciar a construção do Site Mínimo em Reação.
Crie seu próprio modelo de conteúdo
Em vez de importar o Pacote de Ativos de Amostras do Oracle Content Management, você também pode criar seu próprio modelo de conteúdo.
Para este tutorial, estamos usando um tipo de conteúdo chamado 'MinimalMain' como o tipo de conteúdo principal para esta amostra. Esse tipo de conteúdo consiste em logotipos de cabeçalho e rodapé e em uma lista de páginas que devem ser incluídas no nav.
Para criar tipos de conteúdo para o modelo de conteúdo:
- Efetue log-in na interface Web do Oracle Content Management como administrador.
- Escolha Conteúdo no menu de navegação à esquerda e, em seguida, escolha Tipos de Ativo na lista de seleção no cabeçalho da página.
- Clique em Criar no canto direito superior.
- Escolha criar um tipo de conteúdo (não um tipo de ativo digital). Repita isso para todos os tipos de conteúdo necessários.
Criaremos três tipos de conteúdo, cada um com seu próprio conjunto de campos:
- MinimalMain
- MinimalPage
- MinimalSection
O primeiro tipo de conteúdo, MinimalMain, deve ter os seguintes campos:
Nome de exibição | Tipo de Campo | Obrigatórias | Nome da Máquina |
---|---|---|---|
headerLogo | Campo de mídia de valor único | headerLogo | |
footerLogo | Campo de mídia de valor único | footerLogo | |
páginas | Campo de referência de vários valores | páginas |
Essa é a aparência da sua definição de tipo de conteúdo MinimalMain:
O segundo tipo de conteúdo, MinimalPage, deve ter o seguinte campo:
Nome de exibição | Tipo de Campo | Obrigatórias | Nome da Máquina |
---|---|---|---|
seções | Campo de referência de vários valores | seções |
É assim que seu tipo de conteúdo MinimalPage deve ser:
O terceiro e o último tipo de conteúdo, MinimalSection, devem ter os seguintes campos:
Nome de exibição | Tipo de Campo | Obrigatórias | Nome da Máquina |
---|---|---|---|
tipo | Campo de texto de valor único | X | tipo |
da coluna Tipo | Campo de texto de valor único | da coluna Tipo | |
body | Campo de texto grande de valor único | body | |
imagem | Campo de imagem de valor único | imagem | |
ações | Campo de conteúdo incorporado de valor único | ações |
É assim que seu tipo de conteúdo MinimalSection deve ser:
Depois de criar seus tipos de conteúdo, você poderá adicionar esses tipos de conteúdo ao repositório criado anteriormente, OCEMinimalRepository:
- Efetue log-in na interface Web do Oracle Content Management como administrador.
- Navegue até OCEMinimalRepository.
- Edite o repositório e, em Tipos de Ativo, especifique os três tipos de conteúdo recém-criados. Clique no botão Salvar para salvar as alterações.
Depois de adicionar os tipos de conteúdo ao repositório, você pode abrir o repositório OCEMinimalRepository na página Ativos e começar a criar seus itens de conteúdo para todos os tipos de conteúdo.
Tarefa 2: Criar o Site Mínimo no Ângular
Para consumir nosso conteúdo do Oracle Content Management em um aplicativo Angular renderizado no lado do servidor, podemos usar a amostra de site angular mínima, que está disponível como repositório de código-fonte aberto no GitHub.
Observação: Lembre-se de que o uso da amostra Angular é opcional e nós a usamos neste tutorial para começar rapidamente. Você também pode criar seu próprio aplicativo Angular.
Para construir o site mínimo em Angular:
- Clonar o repositório de amostra e instalar dependências
- Configurar o aplicativo Angular
- Trabalhar com o SDK do Oracle Content Management Content
- Usar o Content SDK para Obter Conteúdo
Clonar o Repositório de Amostra e Instalar Dependências
A amostra mínima do site Angular está disponível como um repositório de código-fonte aberto no GitHub.
Primeiro você precisará clonar a amostra do GitHub para seu computador local e alterar o diretório para a raiz do repositório:
git clone https://github.com/oracle/oce-angular-minimal-sample.git
cd oce-angular-minimal-sample
Agora que você tem sua base de código, é necessário fazer download das dependências do aplicativo. Execute o seguinte comando no diretório raiz:
npm install
Configurar o Aplicativo Angular
Nesta amostra de site mínima Angular, você precisa configurar algumas informações para que o SDK do Oracle Content Management Content (e quaisquer outras solicitações) possa direcionar o URL da instância e a versão da API corretos com o token de canal correto. Esses valores são usados em src/scripts/server-config-utils.js para instanciar um novo cliente de entrega.
Este aplicativo utiliza um arquivo .env que é lido pelo Webpack ao empacotar os aplicativos cliente e servidor. Usando webpack.DefinePlugin, qualquer valor lido do arquivo .env pode ser disponibilizado para qualquer lugar no aplicativo.
Abra o arquivo .env em um editor de texto. Você verá o seguinte:
# The connection details for the Oracle Content Management server to be used for this application
SERVER_URL=https://samples.mycontentdemo.com
API_VERSION=v1.1
CHANNEL_TOKEN=ba0efff9c021422cb134c2fd5daf6015
Altere cada par de chave/valor para refletir o URL da sua instância, a versão da API que você deseja direcionar e o token do canal associado ao seu canal de publicação. O canal deste tutorial é OCEMinimalChannel.
Trabalhar com o SDK do Oracle Content Management Content
O Oracle Content Management oferece um SDK para ajudar a descobrir e usar conteúdo em seus aplicativos. O SDK é publicado como um módulo NPM e o projeto é hospedado no GitHub.
Saiba mais sobre o SDK aqui.
O SDK foi registrado como uma dependência de runtime deste projeto no arquivo package.json.
Usar o Content SDK para Obter Conteúdo
Agora podemos aproveitar o SDK de Conteúdo para extrair conteúdo para que possamos renderizá-lo em nosso aplicativo Angular.
O SDK de Conteúdo usa um objeto DeliveryClient para especificar o ponto final. Você pode fazer todas as solicitações usando esse objeto cliente.
A pasta src/scripts contém o código para obter dados do Oracle Content Management usando o Content SDK.
O arquivo src/scripts/server-config-utils.js importa o SDK de Conteúdo e, em seguida, cria um cliente de entrega usando a configuração especificada em .env.
O seguinte comando importa o SDK:
import { createDeliveryClient, createPreviewClient } from '@oracle/content-management-sdk';
O seguinte comando cria o cliente de entrega:
return createDeliveryClient(serverconfig);
O arquivo src/scripts/services.js contém funções para obter os dados deste aplicativo mínimo React.
O método fetchOceMinimalMain() recupera o tipo de conteúdo MinimalMain com um slug de minimalmain.
export async function fetchOceMinimalMain() {
const data = await getItem('minimalmain', 'fields.headerlogo,fields.footerlogo,fields.pages');
if (!data.hasError) {
const { fields } = data;
const { headerlogo, footerlogo } = fields;
// Extract the sourceset for the headerImage and footerImage and put it back in the data
.headerRenditionURLs = getSourceSet(headerlogo);
data.footerRenditionURLs = getSourceSet(footerlogo);
data
}return data;
}
Para renderizar as imagens, o service.js fornece um método auxiliar para recuperar o conjunto de origens de um ativo que é construído a partir das renderizações do ativo.
function getSourceSet(asset) {
const urls = {};
.srcset = '';
urls.jpgSrcset = '';
urlsif (asset.fields && asset.fields.renditions) {
.fields.renditions.forEach((rendition) => {
assetaddRendition(urls, rendition, 'jpg');
addRendition(urls, rendition, 'webp');
;
})
}// add the native rendition to the srcset as well
.srcset += `${asset.fields.native.links[0].href} ${asset.fields.metadata.width}w`;
urls.native = asset.fields.native.links[0].href;
urls.width = asset.fields.metadata.width;
urls.height = asset.fields.metadata.height;
urlsreturn urls;
}
O método fetchPage() recupera o tipo de conteúdo MinimalPage usando o valor de slug para a página obtida da consulta anterior.
export async function fetchPage(pageslug) {
// Get the page details
const page = await getItem(pageslug, 'fields.sections');
return page;
}
O método getRenditionURLs() recupera os urls de renderização de qualquer imagem que possa ser definida em uma seção usando o id dessa imagem. Essa chamada é feita no lado do cliente.
export function getRenditionURLs(identifier) {
const client = getClient();
return client.getItem({
id: identifier,
expand: 'fields.renditions',
.then((asset) => getSourceSet(asset))
}).catch((error) => logError('Fetching Rendition URLs failed', error));
}
Agora que temos nossa consulta de dados, podemos renderizar as respostas em nossos componentes Angulares.
Renderização no Lado Cliente Versus no Servidor
Com a renderização do cliente (CSR), o cliente é responsável por criar e renderizar o conteúdo de uma página da Web usando JavaScript. Com a renderização do servidor (SSR), toda a página é criada no servidor e uma página Web completa é retornada ao cliente.
Quando a página Web é solicitada do servidor na renderização do cliente, o documento HTML retornado contém HTML esqueleto e nenhum conteúdo real. Ele contém uma referência a um pacote JavaScript, que o cliente então solicita do servidor. Ao receber este pacote, o cliente executa o JavaScript e preenche a página Web. Até que o cliente termine de executar o JavaScript, todo o usuário visualiza uma página da Web em branco. Uma desvantagem dos aplicativos renderizados no lado do cliente é que quando alguns crawlers da Web indexam o site, não há conteúdo real a ser indexado.
Com a renderização do servidor (SSR), toda a página é criada no servidor e uma página Web completa é retornada ao cliente. A vantagem disso é que os crawlers Web podem indexar todo o conteúdo na página Web.
Renderização angular do lado servidor
O fluxo da aplicação da galeria de imagens angular é o seguinte:
- O cliente faz uma solicitação ao servidor para uma determinada rota.
- O servidor Express recebe a solicitação.
- O servidor Express transmite todas as solicitações do cliente para páginas para o Mecanismo Express do Angular Univeral
- O Mecanismo Express do Angular Univeral usa um arquivo HTML de modelo e o preenche com o seguinte
- A marcação da rota fornecida
- Os dados da rota foram serializados fora
- Referências a qualquer folha de estilo
- Referências a pacotes JavaScript a serem executados no cliente
- O servidor Express retorna o documento HTML criado pelo Mecanismo Express do Angular Univeral ao cliente
- O cliente recebe o HTML e o renderiza. O usuário verá uma página Web totalmente formada.
- O cliente solicita qualquer pacote JavaScript do servidor. Depois de recebê-lo, o cliente executa o JavaScript no pacote.
- Ele "hidra" o HTML, adicionando em qualquer JavaScript do cliente, como listeners de eventos.
- Angular automaticamente leva os dados serializados da página e os injeta no código JavaScript para ficarem disponíveis para os componentes
- Se o documento HTML contiver uma folha de estilo, o cliente solicitará a folha de estilo.
A CLI angular suporta a adição de suporte de renderização no lado do servidor a um aplicativo Angular existente. Consulte https://angular.io/guide/universal para obter mais detalhes.
Servidor Express no Servidor
O aplicativo de servidor utiliza um servidor Express para receber a solicitação e encaminhar para o Mecanismo Express do Angular Univeral.
O arquivo do servidor Express está localizado no server.js. Esse arquivo é criado pela CLI Angular ao adicionar suporte à renderização do lado do servidor.
Componentes Angulares
Os componentes angulares são gravados no TypeScript e definem um modelo que define a exibição. Esses modelos contêm HTML comum, diretivas Angulares e marcação de vinculação, que permitem que Angular ajuste o HTML antes de ser renderizado.
As próximas seções fornecem uma visão geral de como Angular renderiza nossa aplicação em cada um de nossos componentes:
- Módulo do Aplicativo
- Módulo Raiz para Renderização no Lado do Servidor
- Resolvedor de Dados da Página
- Componente do Aplicativo
- Componentes de Cabeçalho e Rodapé
- Componente da Seção
- PageComponent
Módulo do Aplicativo
O módulo de aplicativo localizado em src/app/app.module.ts. Ela inicializa o aplicativo com o componente do aplicativo.
Esse arquivo define as diferentes rotas para nosso aplicativo. Em nosso site, queremos fornecer duas rotas: - o caminho raiz (/) - e um caminho de página (/page/:slug)
A rota raiz é redirecionada para a rota de página sem slug de página especificado. A rota da página define o resolvedor PageDataResolver, usado para obter todos os dados necessários para a rota antes que os componentes da rota sejam criados.
Abra o componente raiz, localizado em src/app/app.module.ts, e veja as rotas definidas:
const appRoutes: Routes = [
// no path specified, go to home
{path: '',
redirectTo: '/page/',
pathMatch: 'full',
runGuardsAndResolvers: 'always',
,
}
{path: 'page/:slug',
component: PageComponent,
resolve: { routeData: PageDataResolver },
runGuardsAndResolvers: 'always',
,
}; ]
Este módulo de aplicativo é o ponto de entrada ao renderizar o aplicativo no cliente.
Módulo Raiz para Renderização no Lado do Servidor
O ponto de entrada principal deste aplicativo Angular, ao renderizar o aplicativo no servidor, é o módulo do servidor de aplicativos localizado em src/app/app.server.module.ts.
Este módulo importa o módulo de aplicativo, localizado em src/app/app.server.module.ts, juntamente com ServerModule do Angular. O aplicativo do servidor inicializa o mesmo componente de Aplicativo que o cliente e usa todos os mesmos componentes.
A CLI Angular cria o arquivo de módulo do servidor ao adicionar suporte de renderização do lado do servidor.
Resolvedor de Dados da Página
O resolvedor de dados da página, localizado em src/resolvers/page-data.resolver.ts, trata da obtenção dos dados a serem renderizados nas páginas.
Quando o cliente está sendo hidratado, esses dados são obtidos do transferState que foi preenchido durante a renderização do servidor e serializado para fora no documento HTML retornado ao cliente.
Durante a renderização do servidor ou a renderização do cliente quando a navegação do cliente tiver ocorrido, o transferState não conterá os dados. Os dados são obtidos do servidor do Oracle Content Management usando o SDK de Conteúdo.
return fetchOceMinimalMain()
.then((appData) => {
if (pageSlug === null || pageSlug === '') {
= appData.fields.pages[0].slug;
pageSlug
}return fetchPage(pageSlug).then((pageData) => {
if (isPlatformServer(this.platformId)) {
// add the two pieces of data to the transfer state separately
this.transferState.set(APP_KEY, appData);
this.transferState.set(PAGE_KEY, pageData);
}
// return the two pieces of data in a single object
const fullData = { appData, pageData };
return fullData;
;
}); })
Componente do Aplicativo
O componente Aplicativo, localizado em src/app/app.component.ts, define a exibição raiz.
Este componente contém as tags de link do roteador. Angular trocará componentes na página dentro dessas tags, com base na rota atual.
Componentes de Cabeçalho e Rodapé
Os componentes Cabeçalho e Rodapé são usados no componente Página para exibir o cabeçalho e o rodapé respectivamente.
Os dados do cabeçalho são passados para o componente Cabeçalho, localizado em src/app/header/header.component.ts, e os dados do rodapé são passados para o componente Rodapé, localizado em src/app/footer/footer/footer.component.ts. Os componentes Cabeçalho e Rodapé simplesmente usam os dados transmitidos para eles; eles não obtêm dados adicionais do servidor. Consulte os bindings em src/app/header/header.component.html e src/app/footer/footer.component.html.
Componente da Seção
O componente Seção, localizado em src/app/section/section.component.ts, é usado pelo componente Página e é usado para renderizar qualquer item de conteúdo do tipo MinimalSection.
Esse componente tem dados passados para ele do componente Página e, se os dados da seção tiverem uma imagem, ele fará uma chamada do cliente para obter os urls de renderização da imagem do servidor.
ngOnInit() {
this.heading = this.section.fields.heading;
this.type = this.section.fields.type;
// sanitize the content for html display
const content = this.section.fields.body;
const options = {
stripIgnoreTag: true, // filter out all HTML not in the whitelist
stripIgnoreTagBody: ['script'],
;
}this.body = filterXSS(content, options);
this.actions = this.section.fields.actions;
if (this.section.fields.image) {
getRenditionURLs(this.section.fields.image.id).then((urls) => {
this.renditionURLs = urls;
;
})
} }
Componente da Página
O componente Página é responsável por processar o cabeçalho, o rodapé e todas as seções definidas para uma página.
Abra o componente Página, localizado em src/app/page/page.component.ts. Em ngOnInit, você pode ver que o componente obtém os dados da rota ativa, que foi preenchida pelo resolvedor da home page.
ngOnInit() {
const fullData = this.route.snapshot.data.routeData;
this.appData = fullData.appData;
this.headerRenditionURLs = this.appData.headerRenditionURLs;
this.footerRenditionURLs = this.appData.footerRenditionURLs;
this.pageData = fullData.pageData;
if (!this.pageData.hasError) {
this.sections = this.pageData.fields.sections;
this.pages = this.appData.fields.pages;
} }
A marcação do componente Página está localizada em src/app/page/page.component.html.
Tarefa 3: Preparar Seu Aplicativo para Implantação
Agora que construímos nosso local mínimo angular, precisamos vê-lo em um servidor de desenvolvimento local para que possamos depurar qualquer problema e visualizar o aplicativo antes que ele entre em operação.
Prepare o aplicativo para implantação em duas etapas:
Otimizar um Servidor de Desenvolvimento Local
Você pode iniciar um servidor de desenvolvimento localmente executando o comando a seguir.
npm run dev
Em seguida, abra seu navegador para http://localhost:4200 para ver seu site em ação.
Testar seu Aplicativo no Ambiente de Produção
Para produção, o script de construção seria usado para construir o cliente e o código do servidor.
Use o seguinte comando para executar o script de build:
npm run build
Este script executa primeiro a compilação do cliente e, em seguida, executa a compilação do servidor.
Implante o dist/servidor e o dist/navegador incorporados na máquina do servidor antes de iniciar o aplicativo. Em seguida, use o seguinte comando para iniciá-lo:
npm run start
Conclusão
Neste tutorial, criamos um site mínimo em Angular, que pode ser encontrado no GitHub. Este site usa o Oracle Content Management como um CMS sem interface do usuário. Após configurar e configurar o Oracle Content Management com um canal de conteúdo publicado para o tutorial de site mínimo, instalamos e executamos o site Angular para extrair o conteúdo necessário e criar o site.
Para obter mais informações sobre o Angular, vá para o site angular.
Saiba mais sobre conceitos importantes do Oracle Content Management na documentação.
Você pode encontrar mais amostras assim na página Amostras do Oracle Content Management no Oracle Help Center.
Crie um Site Mínimo em Angular com o Oracle Content Management sem Elevação
F51764-01
Dezembro de 2021
Copyright © 2021, Oracle and/or its affiliates.
Autor Principal: Oracle Corporation