空元素的 LDAP 事件过滤器

LDAP Event Filter For Null Element

我的事件属性中有一个列表,其中的元素可能为空。我想创建一个 LDAP 字符串来匹配空元素。

考虑这个工作示例:

private final BundleContext context = FrameworkUtil.getBundle(LdapTest.class).getBundleContext();
private final EventAdmin eventAdmin = this.context.getService(this.context.getServiceReference(EventAdmin.class));

@Test
public void test() throws Exception {
    final String value = "test";

    // register a listener

    final Dictionary<String, Object> serviceProperties = new Hashtable<>();
    serviceProperties.put(EventConstants.EVENT_TOPIC, new String[] { "myTopic" });
    serviceProperties.put(EventConstants.EVENT_FILTER, "(myProperty=" + value + ")");

    final boolean[] called = { false };
    final ServiceRegistration<EventHandler> listener = this.context.
            registerService(EventHandler.class, e -> called[0] = true, serviceProperties);

    // fire event

    Assert.assertFalse(called[0]);
    final Map<String, Object> eventProperties = new HashMap<>();
    eventProperties.put("myProperty", Arrays.asList(value));

    this.eventAdmin.sendEvent(new Event("myTopic", eventProperties));
    Assert.assertTrue(called[0]);

    listener.unregister();
}

现在,如果我设置 value = nullEVENT_FILTER 必须是什么样子才能使测试再次工作?

我尝试了“(!myProperty=*)”和“(!(myProperty=*))”,但没有用。

如果设置了 属性,则 LDAP 过滤器表达式 (myProperty=*) 的计算结果为真,否则为假。在 LDAP 过滤器表达式中无法测试空值。如果事件具有空值,我建议不要设置事件 属性。

使用类似于以下的过滤器可能会取得一些成功:

(myProperty=[=10=])

“\00”是空的转义序列。 其中一些取决于 "null" 是否是值中唯一的东西。 我们遇到过来自 SQL 数据存储的值将以空值结尾并且能够使用该过滤器的情况。

如果 "null" 在属性值范围内(比如 Tom<"null">Smith),除了以二进制形式读取属性值并解析字符以寻找"nulls".

-吉姆

如果有人有类似的问题,我现在就是这样解决的。

我添加了第二个 属性 来保存 null 值是否存在的信息:

 List<String> values = //...
 eventProperties.put("myProperty", values);
 eventProperties.put("myProperty.hasNull", values.contains(null));

所以我可以使用这个新的 属性:

进行查询
serviceProperties.put(EventConstants.EVENT_FILTER, 
        value == null ? "(myProperty.hasNull=true)" : "(myProperty=" + value + ")");

它并不完美,但它完成了工作。