Observação:
- Este tutorial requer acesso ao Oracle Cloud. Para se inscrever em uma conta gratuita, consulte Conceitos básicos do Oracle Cloud Infrastructure Free Tier.
- Ele usa valores de exemplo para credenciais, tenancy e compartimentos do Oracle Cloud Infrastructure. Ao concluir seu laboratório, substitua esses valores por valores específicos do seu ambiente de nuvem.
Usar o OCI API Gateway, Functions e Observability para Validar Conteúdo JSON e Monitorar Cabeçalhos e Corpo de API
Introdução
Quando desenvolvemos aplicativos distribuídos, especialmente em arquiteturas baseadas em microsserviços, queremos componentes que sejam dimensionados e tenham um bom desempenho em sua execução. Eles têm arquiteturas muito complexas, componentes que executam outros componentes, que executam outros componentes e assim por diante em um número infinito de chamadas intermináveis.
Planejar como desenvolver cada um deles é uma tarefa enorme. Você pode expor seus microsserviços criados em um cluster do Kubernetes por meio do Oracle Cloud Infrastructure API Gateway (OCI API Gateway). Há uma série de recursos, como executar autenticação e autorização de chamadas, validação de dados e otimização de chamadas, para citar apenas alguns. Há também a possibilidade de executar chamadas com o OCI Functions com o objetivo de criar mecanismos de autenticação e autorização personalizados, quando os métodos existentes não são suficientes para resolver a necessidade.
Este tutorial mostrará como usar o mecanismo personalizado para validar alguns casos de uso, como:
-
Valide o tamanho dos dados do parâmetro JSON.
-
Valide o número máximo de itens JSON.
Apesar de ser um mecanismo para autenticação e autorização no OCI API Gateway, ele pode ajudar com algumas outras necessidades, como:
-
Capture dados de HEADER, parâmetros de consulta ou o corpo da chamada REST.
-
Envie esses dados para o OCI Observability com o objetivo de facilitar a depuração de problemas, que geralmente são impossíveis de detectar sem essas informações.
Observação: Se você estiver enviando dados para o Observability, considere em seu código, como prática recomendada, o uso de redação para conteúdo HEADER ou CORPO, como senhas ou dados confidenciais. Outra abordagem pode ser ativar/desativar sua função para fins de depuração.
Objetivos
-
Configurar uma Implantação de API.
-
Desenvolva uma Função do OCI para capturar o HEADER e o CORPO da solicitação de API.
-
Validar dados JSON de corpo.
-
Envie as informações de HEADER e CORPO para o OCI Observability.
Pré-requisitos
-
Um tenant operacional do Oracle Cloud. Você pode criar uma conta gratuita do Oracle Cloud com US$ 300,00 por mês para experimentar este tutorial. Consulte Criar uma Conta Gratuita do Oracle Cloud.
-
Uma instância do Gateway de API do OCI criada e exposta à Internet. Consulte Criando Seu Primeiro Gateway de API no Oracle Cloud.
Tarefa 1: Configurar a Observabilidade do OCI
-
Crie um log na tenancy do OCI para ingerir os logs da sua função. Navegue até Observabilidade e Gerenciamento e selecione Logs na Console do OCI.
-
Clique em Criar log personalizado.
-
Informe um nome no campo Nome do log personalizado e escolha um compartimento e um Grupo de Logs apropriados.
Observação: é importante capturar o OCID do Log. Você precisará dele para o código.
Tarefa 2: Criar uma Função do OCI para capturar os HEADERs e o BODY da solicitação de API
Para executar as etapas a seguir, faça download do código aqui function.zip.
-
Capture o HEADER e o CORPO da solicitação de API.
-
Valide os dados JSON do corpo, há um método para validar o número de itens em cada array.
-
Envie as informações de HEADER e CORPO para o OCI Observability.
import io import json import logging import requests import oci from fdk import response from datetime import timedelta def count_items(dictData): counting = 0 for item in dictData: if type(dictData[item]) == list: counting += len(dictData[item]) else: if not type(dictData[item]) == str: counting += count_items(dictData[item]) return counting def handler(ctx, data: io.BytesIO = None): jsonData = "API Error" c = 0 try: config = oci.config.from_file("./config","DEFAULT") logging = oci.loggingingestion.LoggingClient(config) rdata = json.dumps({ "active": True, "context": { "requestheader": data.getvalue().decode('utf-8'), }, }) jsonData = data.getvalue().decode('utf-8') # Get the body content from the API request body = dict(json.loads(data.getvalue().decode('utf-8')).get("data"))["body"] body = dict(json.loads(body)) # Count the number of items on arrays inside the JSON body c = count_items(body) # If JSON body content has more than 1 item in arrays, block the authorization for the API backend if (c > 1): # Send a log to observability with out of limit of items in array put_logs_response = logging.put_logs( log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", put_logs_details=oci.loggingingestion.models.PutLogsDetails( specversion="EXAMPLE-specversion-Value", log_entry_batches=[ oci.loggingingestion.models.LogEntryBatch( entries=[ oci.loggingingestion.models.LogEntry( data="out of limit of items in array " + str(c), id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")], source="EXAMPLE-source-Value", type="EXAMPLE-type-Value")])) return response.Response( ctx, status_code=401, response_data=json.dumps({"active": False, "wwwAuthenticate": "API Gateway JSON"}) ) # Send a log to observability with HEADERs and BODY content put_logs_response = logging.put_logs( log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", put_logs_details=oci.loggingingestion.models.PutLogsDetails( specversion="EXAMPLE-specversion-Value", log_entry_batches=[ oci.loggingingestion.models.LogEntryBatch( entries=[ oci.loggingingestion.models.LogEntry( data=jsonData, id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")], source="EXAMPLE-source-Value", type="EXAMPLE-type-Value")])) return response.Response( ctx, response_data=rdata, status_code=200, headers={"Content-Type": "application/json"} ) except(Exception) as ex: jsonData = 'error parsing json payload: ' + str(ex) + ", " + json.dumps(jsonData) pass return response.Response( ctx, status_code=401, response_data=json.dumps({"active": False, "wwwAuthenticate": jsonData}) )
Entender o Código
Este código pode ser encontrado aqui function.zip.
Observação: se você não souber como desenvolver uma função e chamá-la no Gateway de API, consulte Chamar uma função usando o Gateway de API.
-
Método count_items usado para contar itens em qualquer array dentro da estrutura JSON.
-
Esta parte do código usa o OCI SDK para Python para carregar o arquivo de configuração e a chave privada para acessar sua tenancy do OCI.
-
O rdata capturará os parâmetros da solicitação e preparará a resposta para autorizar a função a chamar o backend da configuração do Gateway de API. O
active
=True
executará a autorização. -
jsonData será usado para gerar o conteúdo HEADERs e BODY para OCI Observability.
-
Esse código capturará apenas a estrutura JSON BODY da solicitação.
-
Abaixo do código contará os itens nos arrays dentro da estrutura JSON CORPO. Se a contagem de itens ultrapassar mais de 1 item, ativo será definido como Falso e um log de erros será enviado ao OCI Observability. Para enviar o log, você precisará usar o OCI SDK do Python.
Observação: substitua a variável log_id pelo Log OCID gerado na Tarefa 1.
Se a contagem for menor ou igual a 1, um log com o conteúdo de solicitação HEADERs e BODY será gerado no OCI Observability. Lembre-se de substituir a variável log_id pelo log do OCID.
Observação: você pode produzir logs em outro Log do OCI. Neste tutorial, apenas um log foi criado; no entanto, você pode criar mais logs.
-
Em caso de erro, uma mensagem com o erro será gerada aqui.
Configurar a Autenticação do SDK para o OCI
Configure o arquivo de configuração e coloque sua chave privada e impressão digital do OCI com sua função antes de implantá-lo no OCI. Você deve ter os arquivos config e chave privada gerados na instalação e configuração da Interface de Linha de Comando (CLI do OCI) do Oracle Cloud Infrastructure.
Para instalar e configurar sua CLI do OCI, consulte Instalar a CLI do OCI. Esta instalação e configuração irá gerar dois arquivos para você. Encontre o arquivo config e a chave privada (o padrão é oci_api_key.pem). O caminho da pasta será informado nas instruções de instalação.
Faça download de function.zip para ver o código, o arquivo de configuração e a chave privada. Substitua os arquivos de configuração e de chave privada pelos arquivos da CLI do OCI.
Criar e implantar a OCI Function
Nesta etapa, precisaremos usar a CLI do OCI para criar as funções do OCI e implantar o código em sua tenancy. Para criar uma função do OCI, consulte Funções do OCI QuickStart e procure a opção Python. Você precisará criar sua função com estas informações:
- Aplicativo: fn_apigw_json
Lembre-se do compartimento que você implantou sua função. Você precisará dessas informações para configurar sua implantação do OCI API Gateway.
Tarefa 3: Configurar a Função do OCI no Gateway de API
Vamos implantar sua API e integrar-se ao seu OCI Functions para validar e enviar parâmetros de solicitação (Cabeçalho e CORPO) para o OCI Observability. Se você não souber como expor seu backend no Gateway de API do OCI, consulte Gateway de API do OCI: Configurar, Criar e Implantar uma API.
-
Abra Editar implantação.
-
Clique na Seção Autenticação.
-
Clique em Autenticação Única e selecione Função do Autorizador.
-
Escolha seu compartimento de funções (onde você implantou sua função), selecione o aplicativo fn_apigw_json e sua função python-json-header.
-
Configure os Argumentos de Funções para capturar o HEADER e o BODY. Capture o HEADER denominado cabeçalho e header2 e o conteúdo BODY que será nomeado como body.
-
Clique em Rotas e configure a Transformação de Cabeçalho. Essa configuração é opcional, apenas para ver o conteúdo da resposta com os dados da solicitação (conteúdo HEADER e BODY) ou os erros gerados na solicitação. Será útil para depurar sua função.
Tarefa 4: Testar sua Solicitação
Observação: em sua Implantação de API, um cache para os argumentos do Functions será ativado se você configurar a Função do Autorizador e configurar os Argumentos do Functions. Você pode estabelecer qual tipo de dados será armazenado em cache. É possível configurar o cache para o parâmetro de consulta ou cabeçalho, mas não para o conteúdo do corpo.
Podemos testar a solicitação de API. Vamos testar com apenas um item em uma matriz no corpo.
curl --location 'https://xxxxxxxxxxxxxxxxxxxx.apigateway.us-ashburn-1.oci.customer-oci.com/path_index/path' \
--header 'Content-Type: text/plain' \
--header 'header: header' \
--header 'header2: header2' \
--header 'header3: header3' \
--data '{"data": {"clientID": "xxxxxxxxxxxxxxxxxxx", "secretID": "xxxxxxxxxxxxxxxxxxx", "jList":[{"added_by":"Ani","description":"example description.","start_date":"2014-10-10","mark":255,"id":975}]}}' -i
O header3 foi enviado, mas mostrado no log porque não foi configurado como um Argumento de Função no Gateway de API do OCI. Há apenas 1 item no array BODY JSON; portanto, é uma solicitação de autorização válida.
Vamos colocar mais um item no array e testar.
curl --location 'https://xxxxxxxxxxxxxxxxxxxx.apigateway.us-ashburn-1.oci.customer-oci.com/path_index/path' \
--header 'Content-Type: text/plain' \
--header 'header: header' \
--header 'header2: header2' \
--header 'header3: header3' \
--data '{"data": {"clientID": "xxxxxxxxxxxxxxxxxxx", "secretID": "xxxxxxxxxxxxxxxxxxx", "jList":[{"added_by":"Ani","description":"example description.","start_date":"2014-10-10","mark":255,"id":975}, {"added_by":"Ani","description":"example description.","start_date":"2014-10-10","mark":255,"id":975}]}}' -i
Links Relacionados
-
Observabilidade do OCI - Observabilidade e Gerenciamento na Nuvem
-
Gateway de API do OCI: Configurar, Criar e Implantar uma API
Agradecimentos
- Autor - Cristiano Hoshikawa (Engenheiro de Soluções Oracle LAD A-Team)
Mais Recursos de Aprendizagem
Explore outros laboratórios em docs.oracle.com/learn ou acesse mais conteúdo de aprendizado gratuito no canal Oracle Learning YouTube. Além disso, visite education.oracle.com/learning-explorer para se tornar um Oracle Learning Explorer.
Para obter a documentação do produto, visite o Oracle Help Center.
Use OCI API Gateway, Functions and Observability to Validate JSON Content and Monitor API Headers and Body
F89782-01
November 2023
Copyright © 2023, Oracle and/or its affiliates.