From 493b4aa09100415b82a883ffb11ef8b365e812b6 Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Wed, 27 Jun 2018 11:55:36 -0400 Subject: [PATCH] INT-4493: ZK MStore binary compatiblity JIRA: https://jira.spring.io/browse/INT-4493 Use reflection to enable binary compatibility with curator 4.x. The return type of `ExistsBuilder.creatingParentContainersIfNeeded()` is now a sub-interface of `ExistsBuilderMain`. Tested with a boot app with curator 4.0.1. * Polishing - add cause --- .../metadata/ZookeeperMetadataStore.java | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/spring-integration-zookeeper/src/main/java/org/springframework/integration/zookeeper/metadata/ZookeeperMetadataStore.java b/spring-integration-zookeeper/src/main/java/org/springframework/integration/zookeeper/metadata/ZookeeperMetadataStore.java index 6443c01a61..9b3c8f2afd 100644 --- a/spring-integration-zookeeper/src/main/java/org/springframework/integration/zookeeper/metadata/ZookeeperMetadataStore.java +++ b/spring-integration-zookeeper/src/main/java/org/springframework/integration/zookeeper/metadata/ZookeeperMetadataStore.java @@ -16,12 +16,16 @@ package org.springframework.integration.zookeeper.metadata; +import java.lang.reflect.Method; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicReference; import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.api.ExistsBuilder; +import org.apache.curator.framework.api.ExistsBuilderMain; import org.apache.curator.framework.recipes.cache.ChildData; import org.apache.curator.framework.recipes.cache.PathChildrenCache; import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; @@ -35,6 +39,7 @@ import org.springframework.integration.metadata.ListenableMetadataStore; import org.springframework.integration.metadata.MetadataStoreListener; import org.springframework.integration.support.utils.IntegrationUtils; import org.springframework.util.Assert; +import org.springframework.util.ReflectionUtils; /** * Zookeeper-based {@link ListenableMetadataStore} based on a Zookeeper node. @@ -48,6 +53,26 @@ import org.springframework.util.Assert; */ public class ZookeeperMetadataStore implements ListenableMetadataStore, SmartLifecycle { + private final static Method creatingParentContainersIfNeeded; + + static { + AtomicReference method = new AtomicReference<>(); + try { + ReflectionUtils.doWithMethods(ExistsBuilder.class, m -> { + method.set(m); + }, m -> { + return "creatingParentContainersIfNeeded".equals(m.getName()) && m.getParameterCount() == 0; + }); + } + catch (Exception e) { + throw new IllegalStateException("Cannot find ExistsBuilder.creatingParentContainersIfNeeded()", e); + } + if (method.get() == null) { + throw new IllegalStateException("Cannot find ExistsBuilder.creatingParentContainersIfNeeded()"); + } + creatingParentContainersIfNeeded = method.get(); + } + private final Object lifecycleMonitor = new Object(); private final CuratorFramework client; @@ -277,9 +302,10 @@ public class ZookeeperMetadataStore implements ListenableMetadataStore, SmartLif synchronized (this.lifecycleMonitor) { if (!this.running) { try { - this.client.checkExists() - .creatingParentContainersIfNeeded() - .forPath(this.root); + ExistsBuilder checkExists = this.client.checkExists(); + ExistsBuilderMain builderMain = (ExistsBuilderMain) creatingParentContainersIfNeeded + .invoke(checkExists, new Object[0]); + builderMain.forPath(this.root); this.cache = new PathChildrenCache(this.client, this.root, true); this.cache.getListenable()