تكوين الأتمتة

تكوين وظيفة التطبيق والأتمتة وتوزيعها.

تكوين تطبيق Oracle Functions

التطبيق عبارة عن تجميع منطقي للوظائف يتيح لك تخصيص الموارد وتكوينها للمجموعة بأكملها وعزل الوظائف أثناء وقت التشغيل.

قبل أن تتمكن من تكوين التطبيق، يجب إعداد مستأجرك لتطوير الوظيفة ويجب إعداد بيئة تطوير الوظيفة.

عند تعريف تطبيق في Oracle Functions، يمكنك تحديد الشبكات الفرعية لتشغيل الوظائف في التطبيق. يمكنك أيضًا تحديد ما إذا كان سيتم تمكين التسجيل للوظائف في التطبيق.

  1. قم بالدخول إلى وحدة التحكم الطرفية كمطور دوال.
  2. في وحدة التحكم، افتح قائمة الاستكشاف. أسفل الحلول والنظام الأساسي، انتقل إلى خدمات المطور وانقر على الوظائف.
  3. حدد المنطقة التي تستخدمها مع Oracle Functions. يوصي Oracle باستخدام نفس المنطقة التي يستخدمها سجل Docker المحدد في سياق Fn Project CLI.
  4. حدد المقطع المحدد في سياق واجهة سطر الأوامر لمشروع Fn. تعرض صفحة التطبيقات التطبيقات المعرفة بالفعل في المقطع.
  5. انقر على تكوين تطبيق وحدد:
    • الاسم: اسم التطبيق الجديد. تجنب إدخال معلومات سرية.
    • VCN والشبكة الفرعية: VCN والشبكة الفرعية التي سيتم تشغيل الدوال فيها.
  6. انقر على تكوين.

    يظهر التطبيق الجديد في قائمة التطبيقات.

تكوين وظيفة الأتمتة ونشرها

تكوين الدالة loadziptojson وتوزيعها وتكوينها في التطبيق ocijsonpub.

  1. بدء الدالة:
     fn init --runtime python loadziptojson

    يتم تكوين دليل باسم الدالة الذي حددته، ويحتوي على ملفات func.py وfunc.yaml وrequirements.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. قم بتعريف دالة تحميل البيانات التي تستدعيها دالة المعالج لفك ضغط الملف، وقراءة ملف csv الموجود في ملف zip، وتكرارات عبر السطر لاستدعاء الدالة 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 Project المفرد التالي لإنشاء الدالة والتبعيات الخاصة بها كصورة 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>