자동화 생성

애플리케이션 및 자동화 기능을 생성하고 배포합니다.

Oracle Functions 애플리케이션 생성

응용 프로그램은 전체 그룹에 대한 리소스를 할당 및 구성하고 런타임 중 함수를 격리할 수 있는 논리적 함수 그룹입니다.

애플리케이션을 생성하려면 먼저 함수 개발에 대한 테넌시를 설정하고 함수 개발 환경을 설정해야 합니다.

Oracle Functions에서 애플리케이션을 정의할 때 애플리케이션에서 함수를 실행할 서브넷을 지정합니다. 또한 응용 프로그램에서 함수에 대한 로깅을 사용할지 여부를 지정합니다.

  1. 콘솔에 함수 개발자로 로그인합니다.
  2. 콘솔에서 탐색 메뉴를 엽니다. 솔루션 및 플랫폼 에서 개발자 서비스 로 이동하고 함수 를 누릅니다.
  3. Oracle Functions에서 사용 중인 영역을 선택합니다. Oracle은 Fn Project CLI 컨텍스트에 지정된 Docker 레지스트리와 동일한 영역을 사용할 것을 권장합니다.
  4. Fn 프로젝트 CLI 컨텍스트에 지정된 구획을 선택합니다. [애플리케이션] 페이지에는 구획에 이미 정의된 애플리케이션이 표시됩니다.
  5. 애플리케이션 생성 을 누르고 다음을 지정합니다:
    • 이름: 새 애플리케이션의 이름입니다. 기밀 정보를 입력하지 마십시오.
    • VCN 및 서브넷: 함수를 실행할 VCN 및 서브넷입니다.
  6. 생성 을 누릅니다.

    새 응용 프로그램이 응용 프로그램 목록에 나타납니다.

자동화 함수 생성 및 배포

ocijsonpub 애플리케이션에서 loadziptojson 함수를 생성, 배치 및 구성합니다.

  1. 함수를 초기화합니다:
     fn init --runtime python loadziptojson

    func.py, func.yamlrequirements.txt 파일이 포함된 지정한 함수 이름으로 디렉토리가 생성됩니다. func.yaml 파일에는 함수를 빌드하고 실행하는 데 필요한 최소 정보가 포함되어 있습니다.

  2. func.py를 열고 콘텐츠를 다음 코드 블록으로 바꿉니다:
    1. 필요한 Python 모듈을 임포트합니다:
      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. 파일의 압축을 해제하고 파일이 객체 스토리지에 업로드될 때 JSON 데이터베이스에 삽입할 함수 처리기를 정의합니다:
      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. 처리기 함수가 파일 압축을 해제하기 위해 호출하는 데이터 로드 함수를 정의하고 zip 파일에 있는 csv 파일을 읽고 행별로 루프하여 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. 컬렉션을 생성하고 컬렉션에 데이터를 삽입하는 삽입 함수를 정의합니다.
      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. func.yaml를 열고 콘텐츠를 다음으로 바꿉니다:
    schema_version: 20180708
    name: loadziptojson
    version: 0.0.31
    runtime: python
    entrypoint: /python/bin/fdk /function/func.py handler
    memory: 256
  4. requirements.txt를 열고 콘텐츠를 다음으로 바꿉니다:
    fdk
    oci
    requests
  5. 다음 단일 Fn 프로젝트 명령을 입력하여 함수 및 종속성을 Docker 이미지로 작성하고, 지정된 Docker 레지스트리에 이미지를 푸시하고, 함수를 지정된 애플리케이션의 Oracle Functions에 배치합니다:
    fn -v deploy --app ocijsonpub
  6. 다음 형식을 사용하여 함수 매개변수를 구성합니다:
    $ fn config function <application_name> <function_name> --<property> <value>

    예를 들어 표시된 필수 값을 대체하여 다음 명령문을 사용하여 ocijsonpub 함수를 구성합니다:

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