Criar a Automação

Crie e implante o aplicativo e a função de automação.

Criar o Aplicativo Oracle Functions

Um aplicativo é um agrupamento lógico de funções que permite alocar e configurar recursos para todo o grupo e isolar as funções durante o runtime.

Antes de criar o aplicativo, você deve configurar sua tenancy para o desenvolvimento de funções e deve configurar seu ambiente de desenvolvimento de funções.

Ao definir um aplicativo no Oracle Functions, especifique as sub-redes nas quais executar as funções no aplicativo. Você também especifica se ativar o log para as funções no aplicativo.

  1. Faça log-in na Console como desenvolvedor de funções.
  2. Na Console, abra o menu de navegação. Em Soluções e Plataforma, vá para Serviços do Desenvolvedor e clique em Funções.
  3. Selecione a região que você está usando com o Oracle Functions. A Oracle recomenda que você use a mesma região que o registro Docker especificado no contexto da CLI do Fn Project.
  4. Selecione o compartimento especificado no contexto da CLI do Projeto Fn. A página Aplicações mostra as aplicações já definidas no compartimento.
  5. Clique em Criar Aplicativo e especifique:
    • Nome: Um nome para o novo aplicativo. Evite digitar informações confidenciais.
    • VCN e sub-rede: a VCN e a sub-rede em que executar funções.
  6. Clique em Criar.

    A nova aplicação é exibida na lista de aplicações.

Criar e Implantar a Função de Automação

Crie, implante e configure a função loadziptojson no aplicativo ocijsonpub.

  1. Inicialize a função:
     fn init --runtime python loadziptojson

    Um diretório é criado com o nome da função especificado, contendo arquivos func.py, func.yaml e requirements.txt. O arquivo func.yaml contém a quantidade mínima de informações necessárias para criar e executar a função.

  2. Abra func.py e substitua o conteúdo pelos seguintes blocos de código:
    1. Importe os módulos Python necessários:
      import io
      import json
      import oci
      import csv
      import requests
      import traceback
      from io import StringIO
      from io import BytesIO
       
      from zipfile import ZipFile, is_zipfile
      from fdk import responsecode
    2. Defina um handler de função para descompactar o arquivo e inserir no banco de dados JSON quando o upload do arquivo for feito no armazenamento de objetos:
      def handler(ctx, data: io.BytesIO=None):
          signer = oci.auth.signers.get_resource_principals_signer()
       
          object_name = bucket_name = namespace = ordsbaseurl = schema = dbuser = dbpwd = ""
          try:
              cfg = ctx.Config()
              input_bucket = cfg["inputbucket"]
              processed_bucket = cfg["processedbucket"]
              ordsbaseurl = cfg["ordsbaseurl"]
              schema = cfg["dbschema"]
              dbuser = cfg["dbuser"]
              dbpwd = cfg["dbpwd"]
          except Exception as e:
              print('Missing function parameters: bucket_name, ordsbaseurl, schema, dbuser, dbpwd', flush=True)
              raise
          try:
              body = json.loads(data.getvalue())
              object_name = body["data"]["resourceName"]
              if body["data"]["additionalDetails"]["bucketName"] != input_bucket:
                  raise ValueError("Event Bucket name error")
              namespace = body["data"]["additionalDetails"]["namespace"]
          except Exception as e:
              print('ERROR: bad Event!', flush=True)
              raise
          try:   
              insert_status = load_data(signer, namespace, input_bucket, object_name, ordsbaseurl, schema, dbuser, dbpwd)
              #move_object(signer, namespace, input_bucket, processed_bucket, object_name)
       
              return response.Response(
                 ctx,
                 response_data=json.dumps(insert_status),
                 headers={"Content-Type": "application/json"}
              )
          except Exception as e:
              return response.Response(
                  ctx, response_data=json.dumps([{'Error': traceback.format_exc()}
                                                , ]),
                  headers={"Content-Type": "application/json"}
              )
    3. Defina uma função de carregamento de dados que a função do handler chama para descompactar o arquivo, ler o arquivo csv que está no arquivo zip e percorrer linha por linha para chamar a função soda_insert.
      def load_data(signer, namespace, bucket_name, object_name, ordsbaseurl, schema, dbuser, dbpwd):
          client = oci.object_storage.ObjectStorageClient(config={}, signer=signer)
          zipfile = client.get_object(namespace, bucket_name, object_name)
          insert_status = {}
       
          if zipfile.status == 200:
             print("INFO - Object {0} is read".format(object_name), flush=True)
             #object_storage_client.get_object
       
             with ZipFile(BytesIO(zipfile.data.content)) as zippy:
                for item in zippy.infolist():
                   print(item.filename, flush=True)
                   try:
                       if not 'MACOS' in item.filename and 'csv' in item.filename:
                          csvdata = csv.DictReader(zippy.read(item.filename).decode('utf-8').split('\n'),delimiter=',')
                          for row in csvdata:
                             insert_status = soda_insert(ordsbaseurl, schema, dbuser, dbpwd, dict(row))
                   except Exception:
                       print('trouble decoding the file ', flush=True)
                       continue
        
              
          else:
               raise SystemExit("cannot retrieve the object" + str(object_name))
          return insert_status
    4. Defina uma função de inserção que crie a coleta e insira dados na coleta.
      def soda_insert(ordsbaseurl, schema, dbuser, dbpwd, document):
         
          auth=(dbuser, dbpwd)
          sodaurl = ordsbaseurl + schema + '/soda/latest/'
          collectionurl = sodaurl + "censusdata"
       
          headers = {'Content-Type': 'application/json'}
          print("INFO - calling SODA with requests:", flush=True)
          print("INFO - before calling SODA :dbuser : "+dbuser, flush=True)
          print("INFO - before calling SODA :dbpwd : "+dbpwd, flush=True)
          reqjson={}
          r = requests.put(collectionurl, auth=auth, headers=headers, data=reqjson)
          print("INFO - before calling SODA :document : "+json.dumps(document), flush=True)
          i = requests.post(collectionurl, auth=auth, headers=headers, data=json.dumps(document))
       
          r_json = {}
          r_json = json.dumps(r.text)
          return r_json
  3. Abra func.yaml e substitua o conteúdo pelo seguinte:
    schema_version: 20180708
    name: loadziptojson
    version: 0.0.31
    runtime: python
    entrypoint: /python/bin/fdk /function/func.py handler
    memory: 256
  4. Abra requirements.txt e substitua o conteúdo pelo seguinte:
    fdk
    oci
    requests
  5. Informe o comando Fn Project único a seguir para criar a função e suas dependências como uma imagem do Docker, enviar a imagem para o registro do Docker especificado e implantar a função no Oracle Functions na aplicação especificada:
    fn -v deploy --app ocijsonpub
  6. Configure os parâmetros de função usando o formato a seguir:
    $ fn config function <application_name> <function_name> --<property> <value>

    Por exemplo, configure a função ocijsonpub usando as instruções a seguir, substituindo os valores necessários quando indicados:

    #Autonomous Database schema
    fn config function ocijsonpub loadziptojson dbschema <db_schema>
    #Autonomous Database Username
    fn config function ocijsonpub loadziptojson dbuser <db_user_name>
    #Autonomous Database password
    fn config function ocijsonpub loadziptojson dbpwd <db_password>
    # Object storage bucket for input file
    fn config function ocijsonpub loadziptojson inputbucket <input_files_bucket>
    # Object storage bucket to archive the zip file after processing
    fn config function ocijsonpub loadziptojson processedbucket <processed_files_bucket>