Class AdmissionScope

java.lang.Object
top.wcpe.beacon.agent.api.AdmissionScope

public final class AdmissionScope extends Object
选服决策的「准入作用域」:一组备选,每个备选是一组「候选节点必须自己声明过的键值标签」 (FR-244,本仓对 FR-243 §2.2「声明不进入调度决策」那一条的重新裁定)。

它解决什么

需要在决策之前排除掉「不服务我这个区 / 不具备这个资格」的节点时,用它把条件带进 BeaconScheduling.acquireCandidate(String, String, AdmissionScope)——决策在生成候选的那一刻 就按本作用域收窄,「先选中、再被调用方拒掉」这条路径因此不必再走一遍。

语义(四条,钉死)

  1. 备选之间是 OR:alternatives() 里任一个备选被满足,该节点就算满足本作用域。 它存在的理由是「不限制 ∨ 明确受理某个取值」这类条件——调用方的真值表里 "没有收窄服务范围"与"收窄到正好包含这个取值"是并列的两种受理形态, 用单一 AND 表达不了,而不该让本仓去解释某个键的值结构(如逗号分列的清单)。
  2. 备选之内是 AND:一个备选里的键值对全部满足,该备选才成立。
  3. 精确相等:值按字符串逐字符相等比较,不做 trim、大小写折叠或任何归一化—— 归一化只在写入声明的那一方做一次(谁写标签谁把值写规范), 两边都做二次归一化会让「声明里写的是什么」与「判定用的值是什么」出现两个版本。
  4. 不解释 key 与值结构:本类只承载「哪些键值对是必须的、它们怎么并列」,不定义 任何 key 的业务含义,也不解释任何值的内部结构(与 FR-243 / ADR-0086 §5 同口径)。 命名空间与取值约定由调用方自持,例如接入方的 com.example.*。

与「没有标签」的关系

作用域非空、而某个节点没有声明(或声明里没有该键)时,该节点不满足本作用域 (除非另有备选成立)。这是刻意的:把「读不到声明」读成「满足」会让准入静默失效,方向不对称, 故取严格一侧。反过来,空作用域不要求任何节点有标签——只声明了容量的老节点照样进候选集合。

"空"只有一种形态:empty()、of(null)、 of(空 map)、anyOf(空列表)、含空备选的 OR、以及 anyOf(empty(), ...) 都在入口规约到同一个形态——无约束力、不排除任何候选,isEmpty() 为 true 且与 empty() 内容相等(不变式见 isEmpty() 的 javadoc)。 因此不存在"非空却恒真"的中间态,调用方读 isEmpty() 与读判定结果永远一致。

值对象不可变:备选与其中的键值对在构造时防御性拷贝并包装为不可修改视图, 构造后外部改动不影响本对象。

  • Method Details

    • empty

      public static AdmissionScope empty()
      空作用域:不按标签收窄(与不带作用域的那条重载等价)。

      它不是「没有候选」的意思,也不要求节点声明过任何标签。

    • of

      public static AdmissionScope of(String key, String value)
      单个要求(最常用形态:接入方给「我这台必须服务我这个区」这类单条条件)——一个备选、一条键值。
      Parameters:
      key - 标签键(由调用方命名,本仓不解释其语义);非空白
      value - 标签值;要求与节点声明的值精确相等;非 null
    • of

      public static AdmissionScope of(Map<String,String> requiredLabels)
      一组要求(一个备选,AND 语义)。
      Parameters:
      requiredLabels - 必须全部满足的键值对;null 或空 map = 不按标签收窄。 键非空白、值非 null。同一键只能出现一次(Map 本就不允许重复键), 故「同一个键要接受多个值」不能在一个备选里表达——那种需求要么是 anyOf(java.util.List) 的多个备选,要么属于接入方自己的命名约定
    • anyOf

      public static AdmissionScope anyOf(List<Map<String,String>> alternatives)
      多个备选(OR 语义):任一备选被满足即准入。

      入口规约:列表里一旦出现空 map 备选(该备选恒成立),整个作用域就在入口处 退回 empty()——「恒真 ∨ 任意」恒真,此时它已不排除任何候选。 不做这条规约,对象会同时呈现"不收窄"(判定恒真)与"非空"(isEmpty() 为 false) 两种互相矛盾的形态:调用方据此把一次本来正常的决策读成"不可用",还会把这个空备选 原样下发到线上协议。规约在拷贝并校验之后做,故非法入参(键为空白等)在任何位置 都会被如实拒绝。

      Parameters:
      alternatives - 备选列表;null 或空列表 = 不按标签收窄。 每个备选内部的键值对是 AND;单个备选为空 map 恒成立,故整个列表 规约为 empty()
    • anyOf

      public static AdmissionScope anyOf(AdmissionScope... scopes)
      把若干作用域并列成一个 OR 作用域(便于把 of(String, String) 的产物拼起来)。

      OR 之下方向必须一致:任一入参 isEmpty() 为 true("不按标签收窄")时, 结果就是 empty()——「不限制 ∨ 某个取值」本来就是"不限制"。 若反过来把空作用域当成"零贡献"、只把其余备选取并集,调用方"配置缺失就传 empty()" 的写法会静默收紧准入(本该全放行,却变成只放行剩下那几个备选), 与 empty() 的语义正好相反。

      Parameters:
      scopes - 并列的作用域;null 元素视为"没有这个备选"被跳过(null 数组或空数组 与空列表同义:不按标签收窄)
    • isEmpty

      public boolean isEmpty()
      本作用域是否不按标签收窄(true 时决策行为与不带作用域的那条重载逐位一致)。

      不变式(本类只有这一种"空"):isEmpty() == true 与「无约束力」 严格等价——admits(Map) 对任何入参(含 null)恒为 true, 即不排除任何候选;并且此时本对象与 empty() 内容相等 (equals(Object) 为 true、hashCode() 相同)。所有"空"的写法 (empty()、of(null)、of(空 map)、anyOf(空列表)、 anyOf(listOf(空 map))、anyOf(empty(), ...))都在入口规约到同一形态, 不存在"非空却恒真"的中间态。

      它不是"没有候选"的意思:判"有没有候选"读 ScheduleResult.state(),不要把本方法的结果当结论用。

    • alternatives

      public List<Map<String,String>> alternatives()
      OR 备选:每个元素是一组必须全部满足的键值标签。
      Returns:
      不可修改的列表,元素是不可修改的 map;空列表表示「不按标签收窄」
    • admits

      public boolean admits(Map<String,String> declaredLabels)
      判定一组节点自声明标签是否满足本作用域(纯逻辑,无 I/O)。

      不变式:isEmpty() 为 true 时无约束力——本方法对任何入参 (含 null、空 map)恒为 true,即不排除任何候选。

      Parameters:
      declaredLabels - 节点自己声明的标签;null 视为「没声明过」
      Returns:
      isEmpty() 为 true 时恒为 true(空作用域不要求节点声明过任何标签); 否则要求至少一个备选成立(备选内全部满足,精确相等,不做归一化,见类首段的语义 ③)
    • equals

      public boolean equals(Object other)
      按 alternatives() 的内容相等比较。

      不变式:isEmpty() 为 true 的对象与 empty() 相等, 因为空的写法只有一种(全部在入口规约到 EMPTY 单例的形态), 故"空"与"无约束力"在相等性上也是同一个东西——调用方可以用 scope.equals(AdmissionScope.empty()) 或 isEmpty() 互推。

      Overrides:
      equals in class Object
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • toString

      public String toString()
      诊断用:只印备选个数与各备选的键,不展开值(值可能含运维侧的业务标识)。
      Overrides:
      toString in class Object