إن مسطرة الأحداث (وتسمى مسطرة في بقية المستند للإيجاز) هي مكتبة Java تسمح بمطابقة القواعد مع الأحداث . الحدث عبارة عن قائمة من الحقول، والتي يمكن تقديمها كأزواج اسم/قيمة أو ككائن JSON. تقوم القاعدة بربط أسماء حقول الأحداث بقوائم القيم المحتملة. هناك سببان لاستخدام المسطرة:
محتويات:
من الأسهل الشرح بالقدوة.
الحدث هو كائن JSON. هنا مثال:
{
"version" : "0" ,
"id" : "ddddd4-aaaa-7777-4444-345dd43cc333" ,
"detail-type" : "EC2 Instance State-change Notification" ,
"source" : "aws.ec2" ,
"account" : "012345679012" ,
"time" : "2017-10-02T16:24:49Z" ,
"region" : "us-east-1" ,
"resources" : [
"arn:aws:ec2:us-east-1:123456789012:instance/i-000000aaaaaa00000"
] ,
"detail" : {
"c-count" : 5 ,
"d-count" : 3 ,
"x-limit" : 301.8 ,
"source-ip" : "10.0.0.33" ,
"instance-id" : "i-000000aaaaaa00000" ,
"state" : "running"
}
}
يمكنك أيضًا رؤية هذا كمجموعة من أزواج الاسم/القيمة. للإيجاز، نقدم عينة فقط. يحتوي المسطرة على واجهات برمجة التطبيقات لتوفير الأحداث في نموذج JSON وكأزواج اسم/قيمة:
+--------------+------------------------------------------+
| name | value |
|--------------|------------------------------------------|
| source | "aws.ec2" |
| detail-type | "EC2 Instance State-change Notification" |
| detail.state | "running" |
+--------------+------------------------------------------+
قد يتم توفير الأحداث في نموذج JSON في شكل سلسلة JSON خام، أو Jackson JsonNode التي تم تحليلها.
تتطابق جميع القواعد الموجودة في هذا القسم مع نموذج الحدث أعلاه:
{
"detail-type" : [ "EC2 Instance State-change Notification" ] ,
"resources" : [ "arn:aws:ec2:us-east-1:123456789012:instance/i-000000aaaaaa00000" ] ,
"detail" : {
"state" : [ "initializing" , "running" ]
}
}
سيؤدي هذا إلى مطابقة أي حدث مع القيم المتوفرة لقيم resource
detail-type
و detail.state
، مع تجاهل أي حقول أخرى في الحدث. سيكون متطابقًا أيضًا إذا كانت قيمة detail.state
قد تم "initializing"
.
يتم توفير القيم في القواعد دائمًا كمصفوفات، وتتطابق إذا كانت القيمة في الحدث إحدى القيم المتوفرة في المصفوفة. يوضح المرجع إلى resources
أنه إذا كانت القيمة في الحدث عبارة عن مصفوفة أيضًا، فإن القاعدة تتطابق إذا كان التقاطع بين مصفوفة الحدث ومصفوفة القاعدة غير فارغ.
{
"time" : [ { "prefix" : "2017-10-02" } ]
}
تعمل مطابقات البادئة فقط على الحقول ذات قيمة السلسلة.
{
"source" : [ { "prefix" : { "equals-ignore-case" : "EC2" } } ]
}
تعمل مطابقات حالة الأحرف يساوي تجاهل البادئة فقط على الحقول ذات قيمة السلسلة.
{
"source" : [ { "suffix" : "ec2" } ]
}
تعمل مطابقات اللاحقة فقط على الحقول ذات قيمة السلسلة.
{
"source" : [ { "suffix" : { "equals-ignore-case" : "EC2" } } ]
}
تعمل مطابقات اللاحقة يساوي تجاهل حالة الأحرف فقط على الحقول ذات قيمة السلسلة.
{
"source" : [ { "equals-ignore-case" : "EC2" } ]
}
تعمل مطابقات حالة التساوي والتجاهل فقط على الحقول ذات قيمة السلسلة.
{
"source" : [ { "wildcard" : "Simple*Service" } ]
}
تعمل مطابقات أحرف البدل فقط على الحقول ذات قيمة السلسلة. يمكن أن تحتوي القيمة الواحدة على صفر أو العديد من أحرف البدل، ولكن لا يُسمح بأحرف البدل المتتالية. لمطابقة حرف العلامة النجمية على وجه التحديد، يمكن تخطي حرف البدل باستخدام شرطة مائلة عكسية. يمثل خطان مائلان عكسيان متتاليان (أي خط مائل عكسي تم تجاوزه بشرطة مائلة عكسية) حرف الخط المائل العكسي الفعلي. غير مسموح بشرطة مائلة عكسية للهروب من أي حرف بخلاف العلامة النجمية أو الشرطة المائلة العكسية.
أي شيء ما عدا المطابقة يفعل ما يقوله الاسم: يطابق أي شيء باستثناء ما هو منصوص عليه في القاعدة.
يعمل أي شيء باستثناء سلسلة واحدة وقيم أو قوائم رقمية، والتي يجب أن تحتوي على سلاسل كاملة أو أرقام كاملة. ويمكن أيضًا تطبيقه على بادئة أو لاحقة أو مطابقة حالة يساوي تجاهل سلسلة أو قائمة سلاسل.
مفردة أي شيء ولكن (سلسلة، ثم رقمية):
{
"detail" : {
"state" : [ { "anything-but" : "initializing" } ]
}
}
{
"detail" : {
"x-limit" : [ { "anything-but" : 123 } ]
}
}
أي شيء ما عدا القائمة (سلاسل):
{
"detail" : {
"state" : [ { "anything-but" : [ "stopped" , "overloaded" ] } ]
}
}
أي شيء باستثناء القائمة (الأرقام):
{
"detail" : {
"x-limit" : [ { "anything-but" : [ 100 , 200 , 300 ] } ]
}
}
أي شيء باستثناء البادئة:
{
"detail" : {
"state" : [ { "anything-but" : { "prefix" : "init" } } ]
}
}
أي شيء باستثناء قائمة البادئات (السلاسل):
{
"detail" : {
"state" : [ { "anything-but" : { "prefix" : [ "init" , "error" ] } } ]
}
}
أي شيء ما عدا اللاحقة:
{
"detail" : {
"instance-id" : [ { "anything-but" : { "suffix" : "1234" } } ]
}
}
أي شيء باستثناء قائمة اللاحقة (السلاسل):
{
"detail" : {
"instance-id" : [ { "anything-but" : { "suffix" : [ "1234" , "6789" ] } } ]
}
}
أي شيء ولكن تجاهل الحالة:
{
"detail" : {
"state" : [ { "anything-but" : { "equals-ignore-case" : "Stopped" } } ]
}
}
قائمة أي شيء ولكن تجاهل الحالة (سلاسل):
{
"detail" : {
"state" : [ { "anything-but" : { "equals-ignore-case" : [ "Stopped" , "OverLoaded" ] } } ]
}
}
أي شيء ما عدا حرف البدل:
{
"detail" : {
"state" : [ { "anything-but" : { "wildcard" : "*/bin/*.jar" } } ]
}
}
أي شيء باستثناء قائمة أحرف البدل (سلاسل):
{
"detail" : {
"state" : [ { "anything-but" : { "wildcard" : [ "*/bin/*.jar" , "*/bin/*.class" ] } } ]
}
}
{
"detail" : {
"c-count" : [ { "numeric" : [ ">" , 0 , "<=" , 5 ] } ] ,
"d-count" : [ { "numeric" : [ "<" , 10 ] } ] ,
"x-limit" : [ { "numeric" : [ "=" , 3.018e2 ] } ]
}
}
أعلاه، توضح المراجع إلى c-count
و d-count
و x-limit
المطابقة الرقمية، وتعمل فقط مع القيم التي هي أرقام JSON. تدعم المطابقة الرقمية نفس الدقة والنطاق مثل البدائي double
لـ Java والذي يطبق معيار IEEE 754 binary64
.
{
"detail" : {
"source-ip" : [ { "cidr" : "10.0.0.0/24" } ]
}
}
يعمل هذا أيضًا مع عناوين IPv6.
توجد أعمال مطابقة لوجود أو عدم وجود حقل في حدث JSON.
سوف تتطابق القاعدة أدناه مع أي حدث يحتوي على حقل Detail.c-count.
{
"detail" : {
"c-count" : [ { "exists" : true } ]
}
}
سوف تتطابق القاعدة أدناه مع أي حدث لا يحتوي على حقل التفاصيل.c-count.
{
"detail" : {
"c-count" : [ { "exists" : false } ]
}
}
ملاحظة: التطابق Exists
يعمل فقط على العقد الطرفية. لا يعمل على العقد المتوسطة.
على سبيل المثال، المثال أعلاه exists : false
سيطابق الحدث أدناه:
{
"detail-type" : [ "EC2 Instance State-change Notification" ] ,
"resources" : [ "arn:aws:ec2:us-east-1:123456789012:instance/i-000000aaaaaa00000" ] ,
"detail" : {
"state" : [ "initializing" , "running" ]
}
}
ولكنه سيطابق أيضًا الحدث أدناه لأن c-count
ليس عقدة طرفية:
{
"detail-type" : [ "EC2 Instance State-change Notification" ] ,
"resources" : [ "arn:aws:ec2:us-east-1:123456789012:instance/i-000000aaaaaa00000" ] ,
"detail" : {
"state" : [ "initializing" , "running" ]
"c-count" : {
"c1" : 100
}
}
}
{
"time" : [ { "prefix" : "2017-10-02" } ] ,
"detail" : {
"state" : [ { "anything-but" : "initializing" } ] ,
"c-count" : [ { "numeric" : [ ">" , 0 , "<=" , 5 ] } ] ,
"d-count" : [ { "numeric" : [ "<" , 10 ] } ] ,
"x-limit" : [ { "anything-but" : [ 100 , 200 , 300 ] } ] ,
"source-ip" : [ { "cidr" : "10.0.0.0/8" } ]
}
}
كما توضح الأمثلة أعلاه، يعتبر المسطرة قاعدة متطابقة إذا كانت جميع الحقول المذكورة في القاعدة متطابقة، ويعتبر حقلًا مطابقًا إذا كانت أي من قيم الحقول المتوفرة متطابقة، أي أن المسطرة قد طبقت منطق "و" إلى كافة الحقول بشكل افتراضي بدون "و" البدائية مطلوبة .
هناك طريقتان للوصول إلى تأثيرات "أو":
"$or" البدائي للسماح للعميل بوصف العلاقة "Or" مباشرة بين الحقول في القاعدة.
يتعرف المسطرة على العلاقة "أو" فقط عندما تستوفي القاعدة جميع الشروط التالية:
/src/main/software/amazon/event/ruler/Constants.java#L38
على سبيل المثال، لن يتم تحليل القاعدة أدناه على أنها " أو" لأن "الرقمية" و"البادئة" هي كلمات رئيسية محجوزة للمسطرة. {
"$or": [ {"numeric" : 123}, {"prefix": "abc"} ]
}
بخلاف ذلك، يتعامل المسطرة مع "$or" كاسم ملف عادي مثل السلسلة الأخرى في القاعدة.
عادي "أو":
// Effect of "source" && ("metricName" || "namespace")
{
"source" : [ "aws.cloudwatch" ] ,
"$or" : [
{ "metricName" : [ "CPUUtilization" , "ReadLatency" ] } ,
{ "namespace" : [ "AWS/EC2" , "AWS/ES" ] }
]
}
الموازي "أو":
// Effect of ("metricName" || "namespace") && ("detail.source" || "detail.detail-type")
{
"$or" : [
{ "metricName" : [ "CPUUtilization" , "ReadLatency" ] } ,
{ "namespace" : [ "AWS/EC2" , "AWS/ES" ] }
] ,
"detail" : {
"$or" : [
{ "source" : [ "aws.cloudwatch" ] } ,
{ "detail-type" : [ "CloudWatch Alarm State Change" ] }
]
}
}
"أو" لديه "و" في الداخل
// Effect of ("source" && ("metricName" || ("metricType && "namespace") || "scope"))
{
"source" : [ "aws.cloudwatch" ] ,
"$or" : [
{ "metricName" : [ "CPUUtilization" , "ReadLatency" ] } ,
{
"metricType" : [ "MetricType" ] ,
"namespace" : [ "AWS/EC2" , "AWS/ES" ]
} ,
{ "scope" : [ "Service" ] }
]
}
متداخلة "أو" و"و"
// Effect of ("source" && ("metricName" || ("metricType && "namespace" && ("metricId" || "spaceId")) || "scope"))
{
"source" : [ "aws.cloudwatch" ] ,
"$or" : [
{ "metricName" : [ "CPUUtilization" , "ReadLatency" ] } ,
{
"metricType" : [ "MetricType" ] ,
"namespace" : [ "AWS/EC2" , "AWS/ES" ] ,
"$or" : [
{ "metricId" : [ 1234 ] } ,
{ "spaceId" : [ 1000 ] }
]
} ,
{ "scope" : [ "Service" ] }
]
}
من المحتمل أن يكون "$or" مستخدمًا بالفعل كمفتاح عادي في بعض التطبيقات (على الرغم من أنه نادر على الأرجح). في هذه الحالات، يبذل تطبيق Ruler قصارى جهده للحفاظ على التوافق مع الإصدارات السابقة. فقط عند توفر الشروط الثلاثة المذكورة أعلاه، ستغير المسطرة سلوكها لأنها تفترض أن قاعدتك كانت تريد حقًا OR وتم تكوينها بشكل خاطئ حتى اليوم. على سبيل المثال، ستستمر القاعدة أدناه في العمل كقاعدة عادية مع التعامل مع "$or" كاسم حقل عادي في القاعدة والحدث:
{
"source" : [ "aws.cloudwatch" ] ,
"$or" : {
"metricType" : [ "MetricType" ] ,
"namespace" : [ "AWS/EC2" , "AWS/ES" ]
}
}
ارجع إلى /src/test/data/normalRulesWithOrWording.json
لمزيد من الأمثلة على أن "$or" تم تحليله كاسم حقل عادي بواسطة Ruler.
لا ينبغي تصميم الكلمة الأساسية "$or" كعلاقة بدائية "Or" كحقل عادي في كل من الأحداث والقواعد. يدعم المسطرة القواعد القديمة حيث يتم تحليل "$or" كاسم حقل عادي للحفاظ على التوافق مع الإصدارات السابقة وإعطاء الوقت للفريق لترحيل استخدامهم القديم "$or" بعيدًا عن الأحداث والقواعد كاسم ملف عادي. الاستخدام المختلط لـ "$or" باعتباره "Or" بدائيًا، و"$or" كاسم حقل عادي لا يتم دعمه عمدًا بواسطة Ruler لتجنب حدوث الغموض المحرج للغاية في "$or".
هناك طريقتان لاستخدام المسطرة. يمكنك تجميع قواعد متعددة في "جهاز"، ثم استخدام أي من أسلوب rulesForEvent()
أو أساليب rulesForJSONEvent()
للتحقق من القواعد التي تطابق أي حدث. تمت مناقشة الفرق بين هاتين الطريقتين أدناه. ستستخدم هذه المناقشة rulesForEvent()
بشكل عام باستثناء الحالات التي يكون فيها الاختلاف مهمًا.
وبدلاً من ذلك، يمكنك استخدام طريقة منطقية ثابتة واحدة لتحديد ما إذا كان حدث فردي يطابق قاعدة معينة.
توجد طريقة منطقية ثابتة واحدة Ruler.matchesRule(event, rule)
- يتم توفير كلا الوسيطتين كسلاسل JSON.
ملاحظة: هناك طريقة أخرى مهملة تسمى Ruler.matches(event, rule)
والتي لا ينبغي استخدامها لأن نتائجها غير متوافقة مع rulesForJSONEvent()
و rulesForEvent()
. راجع الوثائق الموجودة على Ruler.matches(event, rule)
للحصول على التفاصيل.
وقت المطابقة لا يعتمد على عدد القواعد. هذا هو الخيار الأفضل إذا كان لديك العديد من القواعد المحتملة التي تريد الاختيار منها، وخاصة إذا كان لديك طريقة لتخزين الجهاز المترجم.
يتأثر وقت المطابقة بدرجة عدم الحتمية الناتجة عن قواعد أحرف البدل وأي شيء ما عدا أحرف البدل. يتدهور الأداء نظرًا لتزايد عدد بادئات قاعدة أحرف البدل التي تتطابق مع حدث أسوأ حالة نظريًا. لتجنب ذلك، يجب أن تتجنب قواعد أحرف البدل المتعلقة بنفس حقل الحدث البادئات الشائعة التي تؤدي إلى حرف البدل الأول الخاص بها. إذا كانت هناك حاجة إلى بادئة شائعة، فاستخدم الحد الأدنى لعدد أحرف البدل وحدد تسلسلات الأحرف المتكررة التي تحدث بعد حرف البدل. يمكن استخدام MachineComplexityEvaluator لتقييم الجهاز وتحديد درجة عدم الحتمية أو "التعقيد" (أي عدد بادئات قاعدة أحرف البدل التي تتطابق مع حدث أسوأ حالة نظريًا). فيما يلي بعض نقاط البيانات التي توضح انخفاضًا نموذجيًا في الأداء لزيادة درجات التعقيد.
من المهم الحد من تعقيد الماكينة لحماية تطبيقك. هناك استراتيجيتان مختلفتان على الأقل للحد من تعقيد الآلة. أيهما أكثر منطقية قد يعتمد على طلبك.
تعتبر الإستراتيجية رقم 1 أكثر مثالية لأنها تقيس التعقيد الفعلي للآلة التي تحتوي على جميع القواعد. عندما يكون ذلك ممكنا، ينبغي استخدام هذه الاستراتيجية. الجانب السلبي هو، لنفترض أن لديك مستوى تحكم يسمح بإنشاء قاعدة واحدة في كل مرة، حتى عدد كبير جدًا. ثم بالنسبة لكل عملية من عمليات مستوى التحكم هذه، يجب عليك تحميل كافة القواعد الموجودة لإجراء التحقق من الصحة. قد يكون هذا مكلفًا للغاية. كما أنه عرضة لظروف السباق. الإستراتيجية رقم 2 هي حل وسط. ستكون العتبة التي تستخدمها الإستراتيجية رقم 2 أقل من الإستراتيجية رقم 1 نظرًا لأنها عتبة لكل قاعدة. لنفترض أنك تريد ألا يزيد تعقيد الآلة، مع إضافة جميع القواعد، عن 300. ثم باستخدام الاستراتيجية رقم 2، على سبيل المثال، يمكنك قصر كل آلة ذات قاعدة واحدة على تعقيد قدره 10، والسماح بـ 30 قاعدة تحتوي على أنماط أحرف البدل . في أسوأ الحالات على الإطلاق، حيث يكون التعقيد مضافًا تمامًا (وهو أمر غير مرجح)، قد يؤدي هذا إلى آلة يبلغ تعقيدها 300. الجانب السلبي هو أنه من غير المرجح أن يكون التعقيد مضافًا تمامًا، وبالتالي فإن عدد القواعد التي تحتوي على أحرف البدل سوف يتغير. من المحتمل أن تكون محدودة دون داع.
بالنسبة للاستراتيجية رقم 2، اعتمادًا على كيفية تخزين القواعد، قد يلزم إضافة سمة إضافية إلى القواعد للإشارة إلى القواعد غير المحددة (أي تحتوي على أنماط أحرف البدل) من أجل الحد من عدد القواعد التي تحتوي على أحرف البدل.
فيما يلي مقتطف من التعليمات البرمجية يوضح كيفية الحد من التعقيد لنمط معين، مثل الإستراتيجية رقم 2.
public class Validate {
private void validate ( String pattern , MachineComplexityEvaluator machineComplexityEvaluator ) {
// If we cannot compile, then return exception.
List < Map < String , List < Patterns >>> compilationResult = Lists . newArrayList ();
try {
compilationResult . addAll ( JsonRuleCompiler . compile ( pattern ));
} catch ( Exception e ) {
InvalidPatternException internalException =
EXCEPTION_FACTORY . invalidPatternException ( e . getLocalizedMessage ());
throw ExceptionMapper . mapToModeledException ( internalException );
}
// Validate wildcard patterns. Look for wildcard patterns out of all patterns that have been used.
Machine machine = new Machine ();
int i = 0 ;
for ( Map < String , List < Patterns >> rule : compilationResult ) {
if ( containsWildcard ( rule )) {
// Add rule to machine for complexity evaluation.
machine . addPatternRule ( Integer . toString (++ i ), rule );
}
}
// Machine has all rules containing wildcard match types. See if the complexity is under the limit.
int complexity = machine . evaluateComplexity ( machineComplexityEvaluator );
if ( complexity > MAX_MACHINE_COMPLEXITY ) {
InvalidPatternException internalException = EXCEPTION_FACTORY . invalidPatternException ( "Rule is too complex" );
throw ExceptionMapper . mapToModeledException ( internalException );
}
}
private boolean containsWildcard ( Map < String , List < Patterns >> rule ) {
for ( List < Patterns > fieldPatterns : rule . values ()) {
for ( Patterns fieldPattern : fieldPatterns ) {
if ( fieldPattern . type () == WILDCARD || fieldPattern . type () == ANYTHING_BUT_WILDCARD ) {
return true ;
}
}
}
return false ;
}
}
يقوم الفصل الرئيسي الذي ستتفاعل معه بتطبيق مطابقة القواعد القائمة على آلة الحالة. الأساليب المثيرة للاهتمام هي:
addRule()
- يضيف قاعدة جديدة إلى الجهازdeleteRule()
- يحذف قاعدة من الجهازrulesForEvent()
/ rulesForJSONEvent()
- يبحث عن القواعد الموجودة في الجهاز التي تطابق حدثًا ما هناك نوعان من النكهات: Machine
و GenericMachine<T>
. الآلة هي ببساطة GenericMachine<String>
. تشير واجهة برمجة التطبيقات (API) إلى النوع العام باسم "الاسم"، والذي يعكس التاريخ: تم إنشاء إصدار السلسلة أولاً، وكان يُنظر إلى السلاسل التي تم تخزينها وإعادتها على أنها أسماء قواعد.
من أجل السلامة، يجب أن يكون النوع المستخدم لقواعد "التسمية" غير قابل للتغيير. إذا قمت بتغيير محتوى كائن أثناء استخدامه كاسم قاعدة، فقد يؤدي ذلك إلى تعطيل تشغيل المسطرة.
تقبل منشئات GenericMachine وMachine بشكل اختياري كائن GenericMachineConfiguration، الذي يعرض خيارات التكوين التالية.
الافتراضي: خطأ عادةً، يتم إعادة استخدام NameStates لتسلسل مفتاح ونمط محددين إذا تمت إضافة هذا النمط والتسلسل الرئيسي مسبقًا، أو إذا تمت إضافة نمط بالفعل لتسلسل المفتاح المحدد. وبالتالي، بشكل افتراضي، تكون إعادة استخدام NameState انتهازية. ولكن من خلال تعيين هذه العلامة على "صحيح"، سيتم فرض إعادة استخدام NameState لتسلسل رئيسي. هذا يعني أن النمط الأول الذي تتم إضافته لتسلسل مفتاح لاحق سيعيد استخدام NameState إذا تمت إضافة تسلسل المفتاح هذا من قبل. وهذا يعني أن كل تسلسل رئيسي له حالة اسم واحدة. يعمل هذا على تحسين استخدام الذاكرة بشكل كبير في بعض الحالات ولكنه يؤدي إلى تخزين المزيد من القواعد الفرعية في NameStates الفردية، والتي تتكرر المسطرة عليها أحيانًا، مما قد يتسبب في تراجع متواضع في أداء وقت التشغيل. يتم تعيين هذا افتراضيًا على "خطأ" للتوافق مع الإصدارات السابقة، ولكن من المحتمل أن تستفيد جميع التطبيقات، باستثناء التطبيقات الأكثر حساسية لزمن الاستجابة، من تعيين هذا على "صحيح".
وهنا مثال بسيط. يعتبر:
machine . addRule ( "0" , "{"key1": ["a", "b", "c"]}" ) ;
يقوم النمط "a" بإنشاء NameState، وبعد ذلك، حتى مع extraNameStateReuse=false، فإن النمط الثاني ("b") والنمط الثالث ("c") يعيدان استخدام نفس NameState. لكن ضع في اعتبارك ما يلي بدلاً من ذلك:
machine . addRule ( "0" , "{"key1": ["a"]}" ) ;
machine . addRule ( "1" , "{"key1": ["b"]}" ) ;
machine . addRule ( "2" , "{"key1": ["c"]}" ) ;
الآن، مع extraNameStateReuse=false، سينتهي بنا الأمر بثلاث حالات NameState، لأن النمط الأول الذي نواجهه لتسلسل فرعي رئيسي في كل إضافة قاعدة سينشئ حالة NameState جديدة. لذلك، تحصل كل من "a" و"b" و"c" على حالات الاسم الخاصة بها. ومع ذلك، مع extraNameStateReuse=true، سيُنشئ "a" حالة NameState جديدة، ثم سيعيد "b" و"c" استخدام NameState نفسه. يتم تحقيق ذلك عن طريق تخزين أن لدينا بالفعل حالة اسم للتسلسل الرئيسي "key1".
لاحظ أنه لا يهم إذا كان كل addRule يستخدم اسم قاعدة مختلفًا أو نفس اسم القاعدة.
جميع أشكال هذه الطريقة لها نفس الوسيط الأول، وهي سلسلة توفر اسم القاعدة ويتم إرجاعها بواسطة rulesForEvent()
. توفر بقية الوسائط أزواج الاسم/القيمة. يمكن توفيرها بتنسيق JSON كما في الأمثلة أعلاه (عبر String أو Reader أو InputStream أو byte[]
) أو على شكل Map<String, List<String>>
، حيث المفاتيح هي أسماء الحقول و القيم هي قائمة التطابقات المحتملة؛ باستخدام المثال أعلاه، سيكون هناك مفتاح اسمه detail.state
وقيمته هي القائمة التي تحتوي على "initializing"
و "running"
.
ملاحظة: تتم مزامنة هذه الطريقة (وكذلك deleteRule()
) لذا قد يقوم مؤشر ترابط واحد فقط بتحديث الجهاز في أي وقت.