Crea automazione

Creare e distribuire l'applicazione e la funzione di automazione.

Creare l'applicazione Oracle Functions

Un'applicazione è un raggruppamento logico di funzioni che consente di allocare e configurare risorse per l'intero gruppo e di isolare le funzioni durante il runtime.

Prima di poter creare l'applicazione, è necessario impostare la tenancy per lo sviluppo delle funzioni ed è necessario impostare l'ambiente di sviluppo delle funzioni.

Quando si definisce un'applicazione in Oracle Functions, si specificano le subnet in cui eseguire le funzioni nell'applicazione. Specificare anche se abilitare il log per le funzioni nell'applicazione.

  1. Eseguire il login alla console come sviluppatore di funzioni.
  2. Nella console aprire il menu di navigazione. In Soluzioni e piattaforma andare a Servizi sviluppatori e fare clic su Funzioni.
  3. Selezionare l'area in uso con Oracle Functions. Oracle consiglia di utilizzare la stessa area del registro Docker specificata nel contesto CLI Fn Project.
  4. Selezionare il compartimento specificato nel contesto CLI progetto Fn. La pagina Applicazioni mostra le applicazioni già definite nel compartimento.
  5. Fare clic su Crea applicazione e specificare quanto segue.
    • Nome: nome della nuova applicazione. Evitare di fornire informazioni riservate.
    • VCN e subnet: VCN e subnet in cui eseguire le funzioni.
  6. Fare clic su Crea.

    La nuova applicazione viene visualizzata nella lista di applicazioni.

Creare e distribuire la funzione di automazione

Creare, distribuire e configurare la funzione loadziptojson nell'applicazione ocijsonpub.

  1. Inizializza la funzione:
     fn init --runtime python loadziptojson

    Viene creata una directory con il nome funzione specificato, contenente i file func.py, func.yaml e requirements.txt. Il file func.yaml contiene la quantità minima di informazioni richieste per la creazione e l'esecuzione della funzione.

  2. Aprire func.py e sostituire il contenuto con i seguenti blocchi di codice:
    1. Importare i moduli Python necessari:
      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. Definire un handler di funzioni per estrarre il file e inserirlo nel database JSON quando il file viene caricato nello storage degli oggetti:
      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. Definire una funzione di caricamento dati chiamata dalla funzione handler per decomprimere il file, leggere il file csv presente nel file zip e eseguire loop riga per riga per richiamare la funzione 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. Definire una funzione di inserimento che crea la raccolta e inserisce i dati nella raccolta.
      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. Aprire func.yaml e sostituire il contenuto con quanto segue:
    schema_version: 20180708
    name: loadziptojson
    version: 0.0.31
    runtime: python
    entrypoint: /python/bin/fdk /function/func.py handler
    memory: 256
  4. Aprire requirements.txt e sostituire il contenuto con quanto segue:
    fdk
    oci
    requests
  5. Immettere il comando Fn Project riportato di seguito per creare la funzione e le relative dipendenze come immagine Docker, eseguire il push dell'immagine nel registro Docker specificato e distribuire la funzione in Oracle Functions nell'applicazione specificata.
    fn -v deploy --app ocijsonpub
  6. Configurare i parametri funzione utilizzando il seguente formato:
    $ fn config function <application_name> <function_name> --<property> <value>

    Ad esempio, configurare la funzione ocijsonpub utilizzando le istruzioni riportate di seguito, sostituendo i valori richiesti dove indicato:

    #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>