مشاركة عبر


إنشاء مشروع Azure Logic Apps Rules Engine باستخدام Visual Studio Code

ينطبق على: Azure Logic Apps (قياسي)

عندما تريد دمج منطق العمل مع مهام سير العمل القياسية في Azure Logic Apps، يمكنك إنشاء وبناء مشروع Azure Logic Apps Rules Engine باستخدام Visual Studio Code. تحكم القواعد منطق العمل لكيفية عمل عمليات الأعمال.

يصف هذا الدليل الإرشادي كيفية إنشاء مشروع Azure Logic Apps Rules Engine:

  • المتطلبات الأساسية والإعداد لإنشاء مشروع Azure Logic Apps Rules Engine، بما في ذلك إنشاء قواعد العمل لمشروعك باستخدام Microsoft Rules Composer.

  • تصدير القواعد الموجودة من Microsoft خادم BizTalk، إذا كان لديك أي منها.

  • إنشاء مشروع تطبيقات منطقية قياسية لمحرك قواعد Azure Logic Apps باستخدام Visual Studio Code.

المتطلبات الأساسية

قبل إنشاء مشروعك

لمساعدتك على ضمان نجاح مشروع محرك القواعد، راجع المهام العامة وأفضل الممارسات التالية وقم بتنفيذها:

  1. تحديد كيفية احتواء قواعد العمل مع عمليات عملك.

  2. خطط لكيفية دمج قواعد العمل في تطبيقك.

  3. حدد منطق العمل الذي تريد تمثيله مع القواعد في التطبيق الخاص بك.

    يمكن أن يشير مصطلح "منطق العمل" إلى أشياء كثيرة. على سبيل المثال، قد يكون منطق العمل "تتطلب أوامر الشراء التي تزيد عن 500 دولار موافقة المدير".

  4. تحديد مصادر البيانات لعناصر القاعدة الخاصة بك. يمكنك تحديد المفردات اختياريا، وهي تسمية خاصة بالمجال تمثل الارتباطات الأساسية.

  5. حدد القواعد التي يجب استخدامها من تعريفات المفردات أو مباشرة من روابط البيانات. من هذه القواعد، قم بإنشاء مجموعة قواعد تمثل منطق عملك.

تصدير القواعد من Microsoft خادم BizTalk

لإعادة استخدام القواعد الموجودة من Microsoft خادم BizTalk، يمكنك تصديرها. ومع ذلك، فإن حقائق قاعدة البيانات غير مدعومة حاليا. قبل تصدير القواعد، قم بإزالتها أو إعادة بناء التعليمات البرمجية لها إلى أنواع أخرى من الحقائق باستخدام Microsoft BizTalk Rules Composer.

  1. من Microsoft خادم BizTalk، ابدأ تشغيل معالج نشر محرك قواعد العمل.

  2. في صفحة مرحبا بك في معالج توزيع محرك القواعد، حدد التالي.

  3. في صفحة Deployment Task ، حدد Export Policy/Vocabulary to file from database، وحدد Next.

  4. في صفحة مخزن النهج، في قائمة اسم خادم SQL، حدد خادم SQL. في قائمة قاعدة بيانات التكوين على الخادم المحدد، حدد BizTalkRuleEngineDb، ثم حدد التالي.

  5. في صفحة سياسة التصدير/المفردات، من قائمة النهج، حدد النهج الذي تريده. للبحث عن ملف التعريف واختياره، حدد استعراض.

  6. عندما تصبح مستعداً، حدد "Next".

  7. قم بتأكيد معلومات الخادم وقاعدة البيانات والنهج أو المفردات، وحدد التالي.

  8. بعد انتهاء الاستيراد أو التصدير، حدد التالي.

  9. راجع حالة الإكمال للاستيراد أو التصدير، وحدد إنهاء.

إنشاء مشروع Azure Logic Apps Rules Engine

  1. في Visual Studio Code، في شريط النشاط، حدد أيقونة Azure . (لوحة المفاتيح: Shift+Alt+A)

  2. في نافذة Azure التي تفتح، على شريط أدوات قسم Workspace ، من قائمة Azure Logic Apps ، حدد Create new logic app workspace.

    تظهر لقطة الشاشة Visual Studio Code ونافذة Azure وشريط أدوات قسم مساحة العمل والخيار المحدد لإنشاء مساحة عمل تطبيق منطق جديد.

  3. في المربع تحديد مجلد ، استعرض وصولا إلى المجلد المحلي الذي أنشأته لمشروعك وحدده.

  4. عند ظهور مربع المطالبة إنشاء مساحة عمل تطبيق منطق جديد، قم بتوفير اسم لمساحة العمل الخاصة بك:

    تظهر لقطة الشاشة Visual Studio Code مع مطالبة بإدخال اسم مساحة العمل.

    يستمر هذا المثال مع MyLogicAppRulesWorkspace.

  5. عند ظهور مربع المطالبة Select a project template for your logic app workspace ، حدد Logic app with rules engine project.

    تظهر لقطة الشاشة Visual Studio Code مع مطالبة بتحديد قالب المشروع لمساحة عمل التطبيق المنطقي.

  6. اتبع المطالبات اللاحقة لتوفير قيم المثال التالية:

    العنصر مثال للقيمة
    اسم الدالة لمشروع الوظائف وظيفة القواعد
    اسم مساحة الاسم لمشروع الوظائف "Contoso"
    Logic App: LogicApp
    قالب سير العمل:
    - سير عمل ذي حالة
    - سير عمل عديم الحالة
    سير عمل ذي حالة
    اسم سير العمل MyRulesWorkflow
  7. حدد فتح في النافذة الحالية.

    بعد الانتهاء من هذه الخطوة، ينشئ Visual Studio Code مساحة العمل الخاصة بك، والتي تتضمن مشروع وظائف ومشروع محرك قواعد تطبيق منطقي، بشكل افتراضي، على سبيل المثال:

    تظهر لقطة الشاشة Visual Studio Code مع مساحة عمل تم إنشاؤها.

    العقدة ‏‏الوصف
    < اسم مساحة العمل> يحتوي على كل من مشروع الدالة ومشروع سير عمل تطبيق المنطق.
    دالة يحتوي على البيانات الاصطناعية لمشروع الدالة الخاص بك. على سبيل المثال، <ملف function-name>.cs هو ملف التعليمات البرمجية حيث يمكنك تأليف التعليمات البرمجية الخاصة بك.
    LogicApp يحتوي على البيانات الاصطناعية لمشروع محرك قواعد التطبيق المنطقي، بما في ذلك سير العمل.

كتابة التعليمات البرمجية لمحرك القواعد

  1. في مساحة العمل الخاصة بك، قم بتوسيع عقدة Functions ، إذا لم تكن موسعة بالفعل.

  2. افتح < المسمى RulesFunction.cs في هذا المثال.

    بشكل افتراضي، يحتوي هذا الملف على نموذج التعليمات البرمجية التي تحتوي على عناصر التعليمات البرمجية التالية جنبا إلى جنب مع قيم المثال المقدمة مسبقا عند الاقتضاء:

    • اسم مساحة الاسم
    • اسم الفئة
    • اسم الوظيفة
    • معلمات الوظيفة
    • نوع الإرجاع
    • نوع مركب

    يوضح المثال التالي نموذج التعليمات البرمجية الكامل للدالة المسماة RulesFunction:

    //------------------------------------------------------------
    // Copyright (c) Microsoft Corporation. All rights reserved.
    //------------------------------------------------------------
    
    namespace Contoso
    {
         using System;
         using System.Collections.Generic;
         using System.Threading.Tasks;
         using Microsoft.Azure.Functions.Extensions.Workflows;
         using Microsoft.Azure.WebJobs;
         using Microsoft.Azure.Workflows.RuleEngine;
         using Microsoft.Azure.Workflows.RuleEngine.Common;
         using Microsoft.Extensions.Logging;
         using System.Xml;
         using System.Text;
    
         /// <summary>
         /// Represents the RulesFunction flow invoked function.
         /// </summary>
         public class RulesFunction
         {
             private readonly ILogger<RulesFunction> logger;
    
             private FileStoreRuleExplorer ruleExplorer;
    
             public RulesFunction(ILoggerFactory loggerFactory)
             {
                 logger = loggerFactory.CreateLogger<RulesFunction>();
                 this.ruleExplorer = new FileStoreRuleExplorer(loggerFactory); 
             }
    
             /// <summary>
             /// Executes the logic app workflow.
             /// </summary>
             /// <param name="ruleSetName">The rule set name.</param>
             /// <param name="documentType">document type of input xml.</param>
             /// <param name="inputXml">input xml type fact</param>
             /// <param name="purchaseAmount">purchase amount, value used to create .NET fact </param>
             /// <param name="zipCode">zip code value used to create .NET fact .</param>
             [FunctionName("RulesFunction")]
             public Task<RuleExecutionResult> RunRules(
                 [WorkflowActionTrigger] string ruleSetName, 
                 string documentType, 
                 string inputXml, 
                 int purchaseAmount, 
                 string zipCode)
             {
             /***** Summary of steps below *****
                  * 1. Get the rule set to Execute 
                  * 2. Check if the rule set was retrieved successfully
                  * 3. create the rule engine object
                  * 4. Create TypedXmlDocument facts for all xml document facts
                  * 5. Initialize .NET facts
                  * 6. Execute rule engine
                  * 7. Retrieve relevant updates facts and send them back
             */
    
                 try
                 {
                     var ruleSet = this.ruleExplorer.GetRuleSet(ruleSetName);
    
                     // Check if ruleset exists
                     if(ruleSet == null)
                     {
                         // Log an error in finding the rule set
                         this.logger.LogCritical($"RuleSet instance for '{ruleSetName}' was not found(null)");
                         throw new Exception($"RuleSet instance for '{ruleSetName}' was not found.");
                     }             
    
                     // Create rule engine instance
                     var ruleEngine = new RuleEngine(ruleSet: ruleSet);
    
                     // Create a typedXml Fact(s) from input xml(s)
                     XmlDocument doc = new XmlDocument();
                     doc.LoadXml(inputXml);
                     var typedXmlDocument = new TypedXmlDocument(documentType, doc);
    
                     // Initialize .NET facts
                     var currentPurchase = new ContosoNamespace.ContosoPurchase(purchaseAmount, zipCode);
    
                     // Provide facts to rule engine and run it
                     ruleEngine.Execute(new object[] { typedXmlDocument, currentPurchase });
    
                     // Send the relevant results(facts) back
                     var updatedDoc = typedXmlDocument.Document as XmlDocument;
                     var ruleExectionOutput = new RuleExecutionResult()
                     {
                         XmlDoc = updatedDoc.OuterXml,
                         PurchaseAmountPostTax = currentPurchase.PurchaseAmount + currentPurchase.GetSalesTax()
                     };
    
                     return Task.FromResult(ruleExectionOutput);
                 }
                 catch(RuleEngineException ruleEngineException)
                 {
                     // Log any rule engine exceptions
                     this.logger.LogCritical(ruleEngineException.ToString());
                     throw;
                 }
                 catch(XmlException xmlException)
                 {
                     // Log any xml exceptions
                     this.logger.LogCritical("Encountered exception while handling xml. " + xmlException.ToString());
                     throw;
                 }
                 catch(Exception ex)
                 {
                     // Log any other exceptions
                     this.logger.LogCritical(ex.ToString());
                     throw;
                 }
             }
    
             /// <summary>
             /// Results of the rule execution
             /// </summary>
             public class RuleExecutionResult
             {
                 /// <summary>
                 /// rules updated xml document
                 /// </summary>
                 public string XmlDoc { get; set;}
    
                 /// <summary>
                 /// Purchase amount post tax
                 /// </summary>
                 public int PurchaseAmountPostTax { get; set;}
             }
         }
    }
    

    يتضمن تعريف الدالة ل RulesFunction أسلوب افتراضي RunRules يمكنك استخدامه للبدء. يوضح هذا الأسلوب النموذجي RunRules كيفية تمرير المعلمات إلى Azure Logic Apps Rules Engine. في هذا المثال، يمرر الأسلوب اسم مجموعة القواعد ونوع مستند الإدخال وحقيقة XML والقيم الأخرى لمزيد من المعالجة.

    < يتضمن ملف function-name>.cs أيضا الواجهة ILogger التي توفر دعما لتسجيل الأحداث إلى مورد Application Insights. يمكنك إرسال معلومات التتبع إلى Application Insights وتخزين هذه المعلومات جنبا إلى جنب مع معلومات التتبع من مهام سير العمل الخاصة بك. يتضمن < ملف كما يمكنك ملاحظة، يستخدم FileStoreRuleExplorer الدالة الإنشائية لإرسال loggerFactory معلومات القياس عن بعد أيضا إلى Application Insights:

    private readonly ILogger<RulesFunction> logger;
    
    private FileStoreRuleExplorer ruleExplorer;
    
    public RulesFunction(ILoggerFactory loggerFactory)
         {
             logger = loggerFactory.CreateLogger<RulesFunction>();
             this.ruleExplorer = new FileStoreRuleExplorer(loggerFactory); 
         }
    
        <...>
    
    

    يعمل Azure Logic Apps Rules Engine كما هو موضح في الخطوات التالية:

    1. يستخدم FileStoreRuleExplorer المحرك الكائن للوصول إلى مجموعة القواعد. يتم تخزين ملف مجموعة القواعد في دليل القواعد لتطبيق المنطق القياسي.

      على سبيل المثال، يسمى SampleRuleSet.xmlملف مجموعة القواعد ، الذي تم إنشاؤه باستخدام Microsoft Rules Composer أو تصديره باستخدام Microsoft خادم BizTalk.

    var ruleSet = this.ruleExplorer.GetRuleSet(ruleSetName);
    
    // Check if ruleset exists
    if(ruleSet == null)
    {
    // Log an error in finding the rule set
      this.logger.LogCritical($"RuleSet instance for '{ruleSetName}' was not found(null)");
      throw new Exception($"RuleSet instance for '{ruleSetName}' was not found.");
    }             
    

    هام

    تحتوي مجموعات القواعد على مراجع لحقائقها. يبحث Microsoft Rules Composer عن تجميعات الحقائق للتحقق من صحة مجموعة القواعد للتحرير. لفتح مجموعات القواعد كما هو الحال SampleRuleSet.xml في Microsoft Rules Composer، يجب وضعها مع تجميعات حقائق .NET المقابلة. وإلا، فستحصل على استثناء.

    1. يستخدم ruleSet المحرك الكائن لإنشاء مثيل للكائن RuleEngine .

    2. RuleEngine يتلقى الكائن حقائق القاعدة باستخدام Execute الأسلوب .

      في هذا المثال، Execute يتلقى الأسلوب حقيقتين: حقيقة XML المسماة typedXmlDocument وحقيقة .NET المسماة currentPurchase.

      بعد تشغيل المحرك، تتم الكتابة فوق قيم الحقائق بالقيم الناتجة عن تنفيذ المحرك:

    // Create rule engine instance
    var ruleEngine = new RuleEngine(ruleSet: ruleSet);
    // Create a typedXml Fact(s) from input xml(s)
    XmlDocument doc = new XmlDocument();
    doc.LoadXml(inputXml);
    var typedXmlDocument = new TypedXmlDocument(documentType, doc);
    // Initialize .NET facts
    var currentPurchase = new ContosoNamespace.ContosoPurchase(purchaseAmount, zipCode);
    // Provide facts to rule engine and run it
    ruleEngine.Execute(new object[] { typedXmlDocument, currentPurchase });
    // Send the relevant results(facts) back
       var updatedDoc = typedXmlDocument.Document as XmlDocument;
    
    1. يستخدم RuleExecutionResult المحرك الفئة المخصصة لإرجاع القيم إلى RunRules الأسلوب :
    var ruleExectionOutput = new RuleExecutionResult()
                 {
                     XmlDoc = updatedDoc.OuterXml,
                     PurchaseAmountPostTax = currentPurchase.PurchaseAmount + currentPurchase.GetSalesTax()
                 };
    
                 return Task.FromResult(ruleExectionOutput);
    
    1. استبدل نموذج التعليمات البرمجية للدالة بالتعليمات البرمجية الخاصة بك، ثم قم بتحرير الأسلوب الافتراضي RunRules للسيناريوهات الخاصة بك.

      يستمر هذا المثال في استخدام نموذج التعليمات البرمجية دون أي تغييرات.

تحويل التعليمات البرمجية برمجيا وبناءها

بعد الانتهاء من كتابة التعليمات البرمجية الخاصة بك، قم بالتحويل البرمجي للتأكد من عدم وجود أخطاء في البنية. يتضمن مشروع الدالة تلقائيا مهام الإنشاء، والتي تقوم بتجميع ثم إضافة أي من مكتبات التعليمات البرمجية المخصصة، بما في ذلك تجميعات حقائق .NET، إلى المجلد lib\custom في مشروع تطبيق المنطق الخاص بك حيث تبحث مهام سير العمل عن وظائف مخصصة لتشغيلها. تضع هذه المهام التجميعات في المجلد lib\custom\net472 .

  1. في Visual Studio Code، من القائمة Terminal ، حدد New Terminal.

  2. من قائمة دليل العمل التي تظهر، حدد Functions كدليل العمل الحالي للمحطة الطرفية الجديدة.

    تظهر لقطة الشاشة Visual Studio Code، والمطالبة بدليل العمل الحالي، ودليل Functions المحدد.

    يفتح Visual Studio Code نافذة طرفية مع موجه أوامر.

  3. في نافذة Terminal ، في موجه الأوامر، أدخل dotnet restore .\RulesFunction.csproj.

    تظهر لقطة الشاشة Visual Studio Code ونافذة Terminal وأمر استعادة dotnet المكتمل.

  4. بعد ظهور موجه الأوامر مرة أخرى، أدخل dotnet build .\RulesFunction.csproj.

    إذا نجح البناء الخاص بك، تبلغ نافذة Terminal عن نجاح البنية.

  5. تأكد من وجود العناصر التالية في مشروع تطبيق المنطق الخاص بك:

    • في مساحة العمل الخاصة بك، قم بتوسيع المجلدات التالية: >net472. تأكد من أن المجلد الفرعي المسمى net472 يحتوي على التجميعات المتعددة المطلوبة لتشغيل التعليمات البرمجية الخاصة بك، بما في ذلك ملف يسمى< function-name>.dll.

    • في مساحة العمل الخاصة بك، قم بتوسيع المجلدات التالية: LogicApp>lib\custom><function-name.> تأكد من أن المجلد الفرعي المسمى <function-name> يحتوي على ملف function.json، والذي يتضمن بيانات التعريف حول التعليمات البرمجية للدالة التي كتبتها. يستخدم مصمم سير العمل هذا الملف لتحديد المدخلات والمخرجات الضرورية عند استدعاء التعليمات البرمجية الخاصة بك.

    يوضح المثال التالي عينة التجميعات التي تم إنشاؤها والملفات الأخرى في مشروع تطبيق المنطق:

    تظهر لقطة الشاشة مساحة عمل تطبيق المنطق مع مشروع الوظيفة ومشروع تطبيق المنطق، الآن مع التجميعات التي تم إنشاؤها والملفات المطلوبة الأخرى.

استدعاء القواعد من سير عمل

بعد التأكد من أن التعليمات البرمجية الخاصة بك تقوم بالتحويل البرمجي وأن مشروع محرك قواعد تطبيق المنطق الخاص بك يحتوي على الملفات الضرورية لتشغيل التعليمات البرمجية الخاصة بك، افتح سير العمل الافتراضي المضمن مع مشروع تطبيق المنطق الخاص بك.

  1. في مساحة العمل الخاصة بك، ضمن LogicApp، قم بتوسيع عقدة< سير العمل، وافتح القائمة المختصرة workflow.json>، وحدد Open Designer.

    على مصمم سير العمل الذي يفتح، يظهر سير العمل الافتراضي، المضمن مع مشروع تطبيق المنطق الخاص بك، مع المشغل والإجراءات التالية:

    • مشغل الطلب المضمن المسمى عند تلقي طلب HTTP.
    • الإجراء المضمن المسمى استدعاء دالة قواعد محلية في هذا التطبيق المنطقي.
    • إجراء الاستجابة المضمن المسمى Response، والذي تستخدمه للرد على المتصل فقط عند استخدام مشغل الطلب.
  2. حدد الإجراء المسمى Call a local rules function في هذا التطبيق المنطقي.

    يفتح جزء معلومات الإجراء على الجانب الأيسر.

    تظهر لقطة الشاشة Visual Studio Code ومصمم سير العمل وسير العمل الافتراضي مع المشغل والإجراءات.

  3. راجع وتأكد من تعيين قيمة معلمة Function Name إلى دالة القواعد التي تريد تشغيلها. مراجعة أو تغيير أي قيم معلمات أخرى تستخدمها الدالة.

تصحيح التعليمات البرمجية وسير العمل

  1. كرر الخطوات التالية لبدء تشغيل محاكي تخزين Azurite ثلاث مرات: مرة واحدة لكل من خدمات Azure Storage التالية:

    • خدمة Azure Blob
    • خدمة قائمة انتظار Azure
    • Azure Table Service
    1. من قائمة Visual Studio Code View ، حدد Command Palette.

    2. في المطالبة التي تظهر، ابحث عن Azurite: Start Blob Service وحددها.

    3. من قائمة دليل العمل التي تظهر، حدد LogicApp.

    4. كرر هذه الخطوات ل Azurite: Start Queue Service و Azurite: Start Table Service.

    تكون ناجحا عندما يعرض شريط مهام Visual Studio Code في أسفل الشاشة خدمات التخزين الثلاث قيد التشغيل، على سبيل المثال:

    تظهر لقطة الشاشة شريط مهام Visual Studio Code مع Azure Blob Service وAzure Queue Service وAzure Table Service قيد التشغيل.

  2. في شريط نشاط Visual Studio Code، حدد Run and Debug. (لوحة المفاتيح: Ctrl+Shift+D)

    تظهر لقطة الشاشة شريط نشاط Visual Studio Code مع تحديد Run و Debug.

  3. من قائمة Run and Debug، حدد Attach to logic app (LogicApp)، إذا لم يكن محددا بالفعل، ثم حدد Play (سهم أخضر).

    تظهر لقطة الشاشة قائمة

    تفتح نافذة Terminal وتعرض عملية تصحيح الأخطاء التي بدأت. ثم تظهر نافذة وحدة تحكم تتبع الأخطاء وتعرض حالات تصحيح الأخطاء. في الجزء السفلي من Visual Studio Code، يتحول شريط المهام إلى اللون البرتقالي، مما يشير إلى أنه يتم تحميل مصحح الأخطاء .NET.

  4. لتعيين أي نقاط توقف، في تعريف الدالة (<اسم> الدالة.cs) أو تعريف سير العمل (workflow.json)، ابحث عن رقم السطر حيث تريد نقطة التوقف، وحدد العمود إلى الجانب الأيسر، على سبيل المثال:

    تظهر لقطة الشاشة Visual Studio Code وملف التعليمات البرمجية للوظيفة المفتوحة مع تعيين نقطة توقف لخط في التعليمات البرمجية.

  5. لتشغيل مشغل الطلب يدويا في سير العمل، افتح صفحة نظرة عامة على سير العمل.

    1. من مشروع تطبيق المنطق، افتح القائمة المختصرة لملف workflow.json ، وحدد نظرة عامة.

      في صفحة نظرة عامة على سير العمل، يتوفر زر تشغيل المشغل عندما تريد بدء سير العمل يدويا. ضمن خصائص سير العمل، قيمة عنوان URL رد الاتصال هي عنوان URL لنقطة نهاية قابلة للاستدعاء يتم إنشاؤها بواسطة مشغل الطلب في سير العمل الخاص بك. يمكنك إرسال طلبات إلى عنوان URL هذا لتشغيل سير العمل الخاص بك من تطبيقات أخرى، بما في ذلك مهام سير عمل تطبيق المنطق الأخرى.

      تظهر لقطة الشاشة Visual Studio Code وفتح صفحة نظرة عامة على سير العمل.

  6. في شريط أدوات صفحة نظرة عامة ، حدد تشغيل المشغل.

    بعد بدء تشغيل سير العمل، يقوم مصحح الأخطاء بتنشيط نقطة التوقف الأولى.

  7. في قائمة تشغيل أو شريط أدوات مصحح الأخطاء، حدد إجراء تصحيح الأخطاء.

    بعد اكتمال تشغيل سير العمل، تعرض صفحة نظرة عامة التشغيل النهائي والتفاصيل الأساسية حول هذا التشغيل.

  8. لمراجعة مزيد من المعلومات حول تشغيل سير العمل، حدد التشغيل النهائي. أو، من القائمة إلى جانب عمود المدة، حدد إظهار التشغيل.

    تظهر لقطة الشاشة Visual Studio Code وانتهاء تشغيل سير العمل.

  9. لنشر تطبيقات المنطق الخاصة بك مع مشروع محرك القواعد إلى Azure Logic Apps، اتبع الخطوات في التحضير للنشر.