From 504101b22ae80640fec1a3a5e9d09f8beab28865 Mon Sep 17 00:00:00 2001 From: Nadia Mayor Date: Thu, 29 Jun 2023 18:35:37 -0300 Subject: [PATCH 1/4] [SDKS-7199] SegmentFetcher refactor --- .../java/io/split/client/jmx/JmxMonitor.java | 133 ------------------ .../io/split/client/jmx/SplitJmxMonitor.java | 72 ---------- .../client/jmx/SplitJmxMonitorMBean.java | 39 ----- .../split/engine/segments/SegmentFetcher.java | 2 +- .../engine/segments/SegmentFetcherImp.java | 58 +++----- .../segments/SegmentFetcherImpTest.java | 9 +- .../SegmentSynchronizationTaskImpTest.java | 14 +- 7 files changed, 24 insertions(+), 303 deletions(-) delete mode 100644 client/src/main/java/io/split/client/jmx/JmxMonitor.java delete mode 100644 client/src/main/java/io/split/client/jmx/SplitJmxMonitor.java delete mode 100644 client/src/main/java/io/split/client/jmx/SplitJmxMonitorMBean.java diff --git a/client/src/main/java/io/split/client/jmx/JmxMonitor.java b/client/src/main/java/io/split/client/jmx/JmxMonitor.java deleted file mode 100644 index ce2e3ff48..000000000 --- a/client/src/main/java/io/split/client/jmx/JmxMonitor.java +++ /dev/null @@ -1,133 +0,0 @@ -package io.split.client.jmx; - -import java.lang.management.ManagementFactory; -import java.net.URL; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.management.InstanceAlreadyExistsException; -import javax.management.InstanceNotFoundException; -import javax.management.MBeanRegistrationException; -import javax.management.MBeanServer; -import javax.management.MalformedObjectNameException; -import javax.management.NotCompliantMBeanException; -import javax.management.ObjectName; - -/** - * A JMX monitor singleton. - * - * @author patricioe - */ -public class JmxMonitor { - - private final Logger log = LoggerFactory.getLogger(getClass()); - - private MBeanServer mbs; - private static JmxMonitor monitorInstance; - - private JmxMonitor() { - mbs = ManagementFactory.getPlatformMBeanServer(); - } - - public static JmxMonitor getInstance() { - if (monitorInstance == null) { - monitorInstance = new JmxMonitor(); - } - return monitorInstance; - } - - - public void registerMonitor(String name, String monitorType, Object monitoringInterface) - throws MalformedObjectNameException, InstanceAlreadyExistsException, - MBeanRegistrationException, NotCompliantMBeanException { - - String monitorName = generateMonitorName(name, monitorType); - log.info("Registering JMX {}", monitorName); - - ObjectName oName = new ObjectName(monitorName); - - // Check if the monitor is already registered - if (mbs.isRegistered(oName)) { - log.info("Monitor already registered: {}", oName); - return; - } - - mbs.registerMBean(monitoringInterface, oName); - } - - public void unregisterMonitor(String name, String monitorType) - throws MalformedObjectNameException, InstanceAlreadyExistsException, - MBeanRegistrationException, NotCompliantMBeanException { - - String monitorName = generateMonitorName(name, monitorType); - log.info("Unregistering JMX {}", monitorName); - - ObjectName oName = new ObjectName(monitorName); - - // Check if the monitor is already registered - if (!mbs.isRegistered(oName)) { - log.info("Monitor is not registered: {}", oName); - return; - } - - try { - mbs.unregisterMBean(oName); - } catch (InstanceNotFoundException e) { - log.warn("Failed to unregister monitor: {}" + oName.toString(), e); - } - } - - private String generateMonitorName(String className, String monitorType) { - StringBuilder sb = new StringBuilder(); - sb.append(className); - //sb.append(":ServiceType="); - sb.append(":"); - // append the classloader name so we have unique names in web apps. - sb.append(getUniqueClassloaderIdentifier()); - if (null != monitorType && monitorType.length() > 0) { - sb.append("Type=" + monitorType); - } - return sb.toString(); - } - - /** - * Generates a unique, but still nice and predictable name representing this classloader so that - * even apps operating under a web server such as tomcat with multiple classloaders would bee able - * to register each with its own unique mbean. - */ - private String getUniqueClassloaderIdentifier() { - String contextPath = getContextPath(); - if (contextPath != null) { - return contextPath; - } - return "split"; - } - - /** - * Tries to guess a context path for the running application. - * If this is a web application running under a tomcat server this will work. - * If unsuccessful, returns null. - * - * @return A string representing the current context path or null if it cannot be determined. - */ - private String getContextPath() { - ClassLoader loader = getClass().getClassLoader(); - if (loader == null) - - return null; - URL url = loader.getResource("/"); - if (url != null) { - String[] elements = url.toString().split("/"); - for (int i = elements.length - 1; i > 0; --i) { - // URLs look like this: file:/.../ImageServer/WEB-INF/classes/ - // And we want that part that's just before WEB-INF - if ("WEB-INF".equals(elements[i])) { - return elements[i - 1]; - } - } - } - return null; - } - -} diff --git a/client/src/main/java/io/split/client/jmx/SplitJmxMonitor.java b/client/src/main/java/io/split/client/jmx/SplitJmxMonitor.java deleted file mode 100644 index 052d726ad..000000000 --- a/client/src/main/java/io/split/client/jmx/SplitJmxMonitor.java +++ /dev/null @@ -1,72 +0,0 @@ -package io.split.client.jmx; - -import io.split.client.SplitClient; -import io.split.engine.common.FetchOptions; -import io.split.engine.experiments.SplitFetcher; -import io.split.engine.segments.SegmentFetcher; -import io.split.engine.segments.SegmentSynchronizationTask; -import io.split.storages.SegmentCacheConsumer; -import io.split.storages.SplitCacheConsumer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Created by patricioe on 1/18/16. - */ -public class SplitJmxMonitor implements SplitJmxMonitorMBean { - - private static final Logger _log = LoggerFactory.getLogger(SplitJmxMonitor.class); - - private final SplitClient _client; - private final SplitFetcher _featureFetcher; - private final SplitCacheConsumer _splitCacheConsumer; - private final SegmentSynchronizationTask _segmentSynchronizationTask; - private SegmentCacheConsumer segmentCacheConsumer; - - public SplitJmxMonitor(SplitClient splitClient, SplitFetcher featureFetcher, SplitCacheConsumer splitCacheConsumer, SegmentSynchronizationTask segmentSynchronizationTask, SegmentCacheConsumer segmentCacheConsumer) { - _client = checkNotNull(splitClient); - _featureFetcher = checkNotNull(featureFetcher); - _splitCacheConsumer = checkNotNull(splitCacheConsumer); - _segmentSynchronizationTask = checkNotNull(segmentSynchronizationTask); - this.segmentCacheConsumer = checkNotNull(segmentCacheConsumer); - } - - @Override - public boolean forceSyncFeatures() { - _featureFetcher.forceRefresh(new FetchOptions.Builder().cacheControlHeaders(true).build()); - _log.info("Features successfully refreshed via JMX"); - return true; - } - - @Override - public boolean forceSyncSegment(String segmentName) { - SegmentFetcher fetcher = _segmentSynchronizationTask.getFetcher(segmentName); - try{ - fetcher.fetch(new FetchOptions.Builder().build()); - } - //We are sure this will never happen because getFetcher firts initiate the segment. This try/catch is for safe only. - catch (NullPointerException np){ - throw new NullPointerException(); - } - - _log.info("Segment " + segmentName + " successfully refreshed via JMX"); - return true; - } - - @Override - public String getTreatment(String key, String featureName) { - return _client.getTreatment(key, featureName); - } - - @Override - public String fetchDefinition(String featureName) { - return _splitCacheConsumer.get(featureName).toString(); - } - - @Override - public boolean isKeyInSegment(String key, String segmentName) { - return segmentCacheConsumer.isInSegment(segmentName, key); - } -} diff --git a/client/src/main/java/io/split/client/jmx/SplitJmxMonitorMBean.java b/client/src/main/java/io/split/client/jmx/SplitJmxMonitorMBean.java deleted file mode 100644 index 6b492043d..000000000 --- a/client/src/main/java/io/split/client/jmx/SplitJmxMonitorMBean.java +++ /dev/null @@ -1,39 +0,0 @@ -package io.split.client.jmx; - -/** - * JMX Interface. - *

- * Created by patricioe on 1/18/16. - */ -public interface SplitJmxMonitorMBean { - - /** - * @returns TRUE if the sync features worked successfully. - */ - boolean forceSyncFeatures(); - - /** - * @returns TRUE if the sync segments worked successfully. - */ - boolean forceSyncSegment(String segmentName); - - /** - * @param key account of user key identifier - * @param featureName the name of the feature - * @return the evaluation of this feature for the identifier. - */ - String getTreatment(String key, String featureName); - - /** - * @param featureName - * @return the feature definition - */ - String fetchDefinition(String featureName); - - /** - * @param key - * @return TRUE if the key is in the segment - */ - boolean isKeyInSegment(String key, String segmentName); - -} diff --git a/client/src/main/java/io/split/engine/segments/SegmentFetcher.java b/client/src/main/java/io/split/engine/segments/SegmentFetcher.java index 0c8820b6e..3d5c3a48e 100644 --- a/client/src/main/java/io/split/engine/segments/SegmentFetcher.java +++ b/client/src/main/java/io/split/engine/segments/SegmentFetcher.java @@ -9,7 +9,7 @@ public interface SegmentFetcher { /** * fetch */ - void fetch(FetchOptions opts); + boolean fetch(FetchOptions opts); boolean runWhitCacheHeader(); } diff --git a/client/src/main/java/io/split/engine/segments/SegmentFetcherImp.java b/client/src/main/java/io/split/engine/segments/SegmentFetcherImp.java index 1f9d5f91e..466a529a7 100644 --- a/client/src/main/java/io/split/engine/segments/SegmentFetcherImp.java +++ b/client/src/main/java/io/split/engine/segments/SegmentFetcherImp.java @@ -1,6 +1,5 @@ package io.split.engine.segments; -import com.google.common.annotations.VisibleForTesting; import io.split.client.dtos.SegmentChange; import io.split.storages.SegmentCacheProducer; import io.split.telemetry.domain.enums.LastSynchronizationRecordsEnum; @@ -34,14 +33,27 @@ public SegmentFetcherImp(String segmentName, SegmentChangeFetcher segmentChangeF } @Override - public void fetch(FetchOptions opts){ + public boolean fetch(FetchOptions opts){ try { - fetchUntil(opts); + final long INITIAL_CN = _segmentCacheProducer.getChangeNumber(_segmentName); + while (true) { + long start = _segmentCacheProducer.getChangeNumber(_segmentName); + runWithoutExceptionHandling(opts); + if (INITIAL_CN == start) { + opts = new FetchOptions.Builder(opts).targetChangeNumber(FetchOptions.DEFAULT_TARGET_CHANGENUMBER).build(); + } + long end = _segmentCacheProducer.getChangeNumber(_segmentName); + if (start >= end) { + break; + } + } + return true; } catch (Exception e){ _log.error("RefreshableSegmentFetcher failed: " + e.getMessage()); if (_log.isDebugEnabled()) { _log.debug("Reason:", e); } + return false; } } @@ -108,44 +120,8 @@ private String summarize(List changes) { return bldr.toString(); } - @VisibleForTesting - void fetchUntil(FetchOptions opts){ - final long INITIAL_CN = _segmentCacheProducer.getChangeNumber(_segmentName); - while (true) { - long start = _segmentCacheProducer.getChangeNumber(_segmentName); - runWithoutExceptionHandling(opts); - if (INITIAL_CN == start) { - opts = new FetchOptions.Builder(opts).targetChangeNumber(FetchOptions.DEFAULT_TARGET_CHANGENUMBER).build(); - } - long end = _segmentCacheProducer.getChangeNumber(_segmentName); - if (start >= end) { - break; - } - } - } - @Override public boolean runWhitCacheHeader(){ - return this.fetchAndUpdate(new FetchOptions.Builder().cacheControlHeaders(true).build()); - } - - /** - * Calls callLoopRun and after fetchs segment. - * @param opts contains all soft of options used when issuing the fetch request - */ - @VisibleForTesting - boolean fetchAndUpdate(FetchOptions opts) { - try { - // Do this again in case the previous call errored out. - fetchUntil(opts); - return true; - - } catch (Exception e){ - _log.error("RefreshableSegmentFetcher failed: " + e.getMessage()); - if (_log.isDebugEnabled()) { - _log.debug("Reason:", e); - } - return false; - } + return this.fetch(new FetchOptions.Builder().cacheControlHeaders(true).build()); } -} +} \ No newline at end of file diff --git a/client/src/test/java/io/split/engine/segments/SegmentFetcherImpTest.java b/client/src/test/java/io/split/engine/segments/SegmentFetcherImpTest.java index d9803d6cf..ce263bfe4 100644 --- a/client/src/test/java/io/split/engine/segments/SegmentFetcherImpTest.java +++ b/client/src/test/java/io/split/engine/segments/SegmentFetcherImpTest.java @@ -1,6 +1,5 @@ package io.split.engine.segments; -import com.google.common.collect.Sets; import io.split.storages.SegmentCache; import io.split.storages.SegmentCacheProducer; import io.split.storages.memory.SegmentCacheInMemoryImpl; @@ -18,7 +17,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -45,7 +43,6 @@ public void works_when_we_start_without_state() throws InterruptedException { @Test public void works_when_we_start_with_state() throws InterruptedException { works(20L); - } @Test @@ -76,11 +73,8 @@ public void works_when_there_are_no_changes() throws InterruptedException { Thread.currentThread().interrupt(); } - Set expected = Sets.newHashSet("" + (startingChangeNumber + 1)); - assertNotNull(segmentCache.getChangeNumber(SEGMENT_NAME)); assertEquals(10L, segmentCache.getChangeNumber(SEGMENT_NAME)); - } private void works(long startingChangeNumber) throws InterruptedException { @@ -114,7 +108,6 @@ private void works(long startingChangeNumber) throws InterruptedException { Thread.currentThread().interrupt(); } Mockito.verify(segmentChangeFetcher, Mockito.times(2)).fetch(Mockito.anyString(), Mockito.anyLong(), Mockito.anyObject()); - } @@ -150,7 +143,7 @@ public void testBypassCdnClearedAfterFirstHit() { response2.added = new ArrayList<>(); response2.removed = new ArrayList<>(); response2.since = 1; - response1.till = 1; + response2.till = 1; ArgumentCaptor optionsCaptor = ArgumentCaptor.forClass(FetchOptions.class); ArgumentCaptor cnCaptor = ArgumentCaptor.forClass(Long.class); diff --git a/client/src/test/java/io/split/engine/segments/SegmentSynchronizationTaskImpTest.java b/client/src/test/java/io/split/engine/segments/SegmentSynchronizationTaskImpTest.java index d4a71ccbd..06261a54f 100644 --- a/client/src/test/java/io/split/engine/segments/SegmentSynchronizationTaskImpTest.java +++ b/client/src/test/java/io/split/engine/segments/SegmentSynchronizationTaskImpTest.java @@ -33,8 +33,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertEquals; /** * Tests for SegmentSynchronizationTaskImp @@ -93,8 +92,8 @@ public void run() { Thread.currentThread().interrupt(); } - assertThat(fetcher1.get(), is(notNullValue())); - assertThat(fetcher1.get(), is(sameInstance(fetcher2.get()))); + Assert.assertNotNull(fetcher1.get()); + assertEquals(fetcher1.get(), fetcher2.get()); } @Test @@ -107,10 +106,8 @@ public void testFetchAllAsynchronousAndGetFalse() throws NoSuchFieldException, I _segmentFetchers.put("SF", segmentFetcher); final SegmentSynchronizationTaskImp fetchers = new SegmentSynchronizationTaskImp(segmentChangeFetcher, 1L, 1, segmentCacheProducer, TELEMETRY_STORAGE, Mockito.mock(SplitCacheConsumer.class), null); - Mockito.doNothing().when(segmentFetcher).fetchUntil(Mockito.anyObject()); Mockito.when(segmentFetcher.runWhitCacheHeader()).thenReturn(false); - Mockito.when(segmentFetcher.fetchAndUpdate(Mockito.anyObject())).thenReturn(false); - Mockito.doNothing().when(segmentFetcher).fetchUntil(Mockito.anyObject()); + Mockito.when(segmentFetcher.fetch(Mockito.anyObject())).thenReturn(false); // Before executing, we'll update the map of segmentFecthers via reflection. Field segmentFetchersForced = SegmentSynchronizationTaskImp.class.getDeclaredField("_segmentFetchers"); @@ -141,9 +138,8 @@ public void testFetchAllAsynchronousAndGetTrue() throws NoSuchFieldException, Il modifiersField.setAccessible(true); modifiersField.setInt(segmentFetchersForced, segmentFetchersForced.getModifiers() & ~Modifier.FINAL); segmentFetchersForced.set(fetchers, _segmentFetchers); - Mockito.doNothing().when(segmentFetcher).fetchUntil(Mockito.anyObject()); Mockito.when(segmentFetcher.runWhitCacheHeader()).thenReturn(true); - Mockito.when(segmentFetcher.fetchAndUpdate(Mockito.anyObject())).thenReturn(true); + Mockito.when(segmentFetcher.fetch(Mockito.anyObject())).thenReturn(true); boolean fetch = fetchers.fetchAllSynchronous(); Assert.assertEquals(true, fetch); } From b6a79753a9a243cb8e0c4711d6ee7f5ef6acceee Mon Sep 17 00:00:00 2001 From: Nadia Mayor Date: Fri, 30 Jun 2023 18:34:06 -0300 Subject: [PATCH 2/4] [SDKS-7199] Pr suggestion --- .../java/io/split/client/jmx/JmxMonitor.java | 133 ++++++++++++++++++ .../io/split/client/jmx/SplitJmxMonitor.java | 72 ++++++++++ .../client/jmx/SplitJmxMonitorMBean.java | 39 +++++ 3 files changed, 244 insertions(+) create mode 100644 client/src/main/java/io/split/client/jmx/JmxMonitor.java create mode 100644 client/src/main/java/io/split/client/jmx/SplitJmxMonitor.java create mode 100644 client/src/main/java/io/split/client/jmx/SplitJmxMonitorMBean.java diff --git a/client/src/main/java/io/split/client/jmx/JmxMonitor.java b/client/src/main/java/io/split/client/jmx/JmxMonitor.java new file mode 100644 index 000000000..0acd7deda --- /dev/null +++ b/client/src/main/java/io/split/client/jmx/JmxMonitor.java @@ -0,0 +1,133 @@ +package io.split.client.jmx; + +import java.lang.management.ManagementFactory; +import java.net.URL; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.NotCompliantMBeanException; +import javax.management.ObjectName; + +/** + * A JMX monitor singleton. + * + * @author patricioe + */ +public class JmxMonitor { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + private MBeanServer mbs; + private static JmxMonitor monitorInstance; + + private JmxMonitor() { + mbs = ManagementFactory.getPlatformMBeanServer(); + } + + public static JmxMonitor getInstance() { + if (monitorInstance == null) { + monitorInstance = new JmxMonitor(); + } + return monitorInstance; + } + + + public void registerMonitor(String name, String monitorType, Object monitoringInterface) + throws MalformedObjectNameException, InstanceAlreadyExistsException, + MBeanRegistrationException, NotCompliantMBeanException { + + String monitorName = generateMonitorName(name, monitorType); + log.info("Registering JMX {}", monitorName); + + ObjectName oName = new ObjectName(monitorName); + + // Check if the monitor is already registered + if (mbs.isRegistered(oName)) { + log.info("Monitor already registered: {}", oName); + return; + } + + mbs.registerMBean(monitoringInterface, oName); + } + + public void unregisterMonitor(String name, String monitorType) + throws MalformedObjectNameException, InstanceAlreadyExistsException, + MBeanRegistrationException, NotCompliantMBeanException { + + String monitorName = generateMonitorName(name, monitorType); + log.info("Unregistering JMX {}", monitorName); + + ObjectName oName = new ObjectName(monitorName); + + // Check if the monitor is already registered + if (!mbs.isRegistered(oName)) { + log.info("Monitor is not registered: {}", oName); + return; + } + + try { + mbs.unregisterMBean(oName); + } catch (InstanceNotFoundException e) { + log.warn("Failed to unregister monitor: {}" + oName.toString(), e); + } + } + + private String generateMonitorName(String className, String monitorType) { + StringBuilder sb = new StringBuilder(); + sb.append(className); + //sb.append(":ServiceType="); + sb.append(":"); + // append the classloader name so we have unique names in web apps. + sb.append(getUniqueClassloaderIdentifier()); + if (null != monitorType && monitorType.length() > 0) { + sb.append("Type=" + monitorType); + } + return sb.toString(); + } + + /** + * Generates a unique, but still nice and predictable name representing this classloader so that + * even apps operating under a web server such as tomcat with multiple classloaders would bee able + * to register each with its own unique mbean. + */ + private String getUniqueClassloaderIdentifier() { + String contextPath = getContextPath(); + if (contextPath != null) { + return contextPath; + } + return "split"; + } + + /** + * Tries to guess a context path for the running application. + * If this is a web application running under a tomcat server this will work. + * If unsuccessful, returns null. + * + * @return A string representing the current context path or null if it cannot be determined. + */ + private String getContextPath() { + ClassLoader loader = getClass().getClassLoader(); + if (loader == null) + + return null; + URL url = loader.getResource("/"); + if (url != null) { + String[] elements = url.toString().split("/"); + for (int i = elements.length - 1; i > 0; --i) { + // URLs look like this: file:/.../ImageServer/WEB-INF/classes/ + // And we want that part that's just before WEB-INF + if ("WEB-INF".equals(elements[i])) { + return elements[i - 1]; + } + } + } + return null; + } + +} \ No newline at end of file diff --git a/client/src/main/java/io/split/client/jmx/SplitJmxMonitor.java b/client/src/main/java/io/split/client/jmx/SplitJmxMonitor.java new file mode 100644 index 000000000..6f4e0522c --- /dev/null +++ b/client/src/main/java/io/split/client/jmx/SplitJmxMonitor.java @@ -0,0 +1,72 @@ +package io.split.client.jmx; + +import io.split.client.SplitClient; +import io.split.engine.common.FetchOptions; +import io.split.engine.experiments.SplitFetcher; +import io.split.engine.segments.SegmentFetcher; +import io.split.engine.segments.SegmentSynchronizationTask; +import io.split.storages.SegmentCacheConsumer; +import io.split.storages.SplitCacheConsumer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Created by patricioe on 1/18/16. + */ +public class SplitJmxMonitor implements SplitJmxMonitorMBean { + + private static final Logger _log = LoggerFactory.getLogger(SplitJmxMonitor.class); + + private final SplitClient _client; + private final SplitFetcher _featureFetcher; + private final SplitCacheConsumer _splitCacheConsumer; + private final SegmentSynchronizationTask _segmentSynchronizationTask; + private SegmentCacheConsumer segmentCacheConsumer; + + public SplitJmxMonitor(SplitClient splitClient, SplitFetcher featureFetcher, SplitCacheConsumer splitCacheConsumer, SegmentSynchronizationTask segmentSynchronizationTask, SegmentCacheConsumer segmentCacheConsumer) { + _client = checkNotNull(splitClient); + _featureFetcher = checkNotNull(featureFetcher); + _splitCacheConsumer = checkNotNull(splitCacheConsumer); + _segmentSynchronizationTask = checkNotNull(segmentSynchronizationTask); + this.segmentCacheConsumer = checkNotNull(segmentCacheConsumer); + } + + @Override + public boolean forceSyncFeatures() { + _featureFetcher.forceRefresh(new FetchOptions.Builder().cacheControlHeaders(true).build()); + _log.info("Features successfully refreshed via JMX"); + return true; + } + + @Override + public boolean forceSyncSegment(String segmentName) { + SegmentFetcher fetcher = _segmentSynchronizationTask.getFetcher(segmentName); + try{ + fetcher.fetch(new FetchOptions.Builder().build()); + } + //We are sure this will never happen because getFetcher firts initiate the segment. This try/catch is for safe only. + catch (NullPointerException np){ + throw new NullPointerException(); + } + + _log.info("Segment " + segmentName + " successfully refreshed via JMX"); + return true; + } + + @Override + public String getTreatment(String key, String featureName) { + return _client.getTreatment(key, featureName); + } + + @Override + public String fetchDefinition(String featureName) { + return _splitCacheConsumer.get(featureName).toString(); + } + + @Override + public boolean isKeyInSegment(String key, String segmentName) { + return segmentCacheConsumer.isInSegment(segmentName, key); + } +} \ No newline at end of file diff --git a/client/src/main/java/io/split/client/jmx/SplitJmxMonitorMBean.java b/client/src/main/java/io/split/client/jmx/SplitJmxMonitorMBean.java new file mode 100644 index 000000000..94d1728bf --- /dev/null +++ b/client/src/main/java/io/split/client/jmx/SplitJmxMonitorMBean.java @@ -0,0 +1,39 @@ +package io.split.client.jmx; + +/** + * JMX Interface. + *

+ * Created by patricioe on 1/18/16. + */ +public interface SplitJmxMonitorMBean { + + /** + * @returns TRUE if the sync features worked successfully. + */ + boolean forceSyncFeatures(); + + /** + * @returns TRUE if the sync segments worked successfully. + */ + boolean forceSyncSegment(String segmentName); + + /** + * @param key account of user key identifier + * @param featureName the name of the feature + * @return the evaluation of this feature for the identifier. + */ + String getTreatment(String key, String featureName); + + /** + * @param featureName + * @return the feature definition + */ + String fetchDefinition(String featureName); + + /** + * @param key + * @return TRUE if the key is in the segment + */ + boolean isKeyInSegment(String key, String segmentName); + +} \ No newline at end of file From d26a76773d55d00551c032026d457e9f9523fc6c Mon Sep 17 00:00:00 2001 From: Nadia Mayor Date: Mon, 10 Jul 2023 10:59:52 -0300 Subject: [PATCH 3/4] Update client version --- client/pom.xml | 2 +- pluggable-storage/pom.xml | 2 +- pom.xml | 2 +- redis-wrapper/pom.xml | 2 +- testing/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/pom.xml b/client/pom.xml index d23164bc2..66255013d 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -5,7 +5,7 @@ io.split.client java-client-parent - 4.7.2 + 4.7.3-rc3 java-client jar diff --git a/pluggable-storage/pom.xml b/pluggable-storage/pom.xml index 973356e62..05f295dff 100644 --- a/pluggable-storage/pom.xml +++ b/pluggable-storage/pom.xml @@ -6,7 +6,7 @@ java-client-parent io.split.client - 4.7.2 + 4.7.3-rc3 2.0.0 diff --git a/pom.xml b/pom.xml index bcdb9e209..ebfc04c89 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 io.split.client java-client-parent - 4.7.2 + 4.7.3-rc3 diff --git a/redis-wrapper/pom.xml b/redis-wrapper/pom.xml index d91cee285..7b1d2d7d8 100644 --- a/redis-wrapper/pom.xml +++ b/redis-wrapper/pom.xml @@ -6,7 +6,7 @@ java-client-parent io.split.client - 4.7.2 + 4.7.3-rc3 redis-wrapper 3.0.0 diff --git a/testing/pom.xml b/testing/pom.xml index 8d146fd11..d0069140c 100644 --- a/testing/pom.xml +++ b/testing/pom.xml @@ -5,7 +5,7 @@ io.split.client java-client-parent - 4.7.2 + 4.7.3-rc3 java-client-testing jar From 1a5a9b766c23fbd15abb27948b15c0fb2d55fac6 Mon Sep 17 00:00:00 2001 From: Nadia Mayor Date: Tue, 11 Jul 2023 11:23:43 -0300 Subject: [PATCH 4/4] Update client version --- client/pom.xml | 2 +- pluggable-storage/pom.xml | 2 +- pom.xml | 2 +- redis-wrapper/pom.xml | 2 +- testing/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/pom.xml b/client/pom.xml index 66255013d..d23164bc2 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -5,7 +5,7 @@ io.split.client java-client-parent - 4.7.3-rc3 + 4.7.2 java-client jar diff --git a/pluggable-storage/pom.xml b/pluggable-storage/pom.xml index 05f295dff..973356e62 100644 --- a/pluggable-storage/pom.xml +++ b/pluggable-storage/pom.xml @@ -6,7 +6,7 @@ java-client-parent io.split.client - 4.7.3-rc3 + 4.7.2 2.0.0 diff --git a/pom.xml b/pom.xml index ebfc04c89..bcdb9e209 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 io.split.client java-client-parent - 4.7.3-rc3 + 4.7.2 diff --git a/redis-wrapper/pom.xml b/redis-wrapper/pom.xml index 7b1d2d7d8..d91cee285 100644 --- a/redis-wrapper/pom.xml +++ b/redis-wrapper/pom.xml @@ -6,7 +6,7 @@ java-client-parent io.split.client - 4.7.3-rc3 + 4.7.2 redis-wrapper 3.0.0 diff --git a/testing/pom.xml b/testing/pom.xml index d0069140c..8d146fd11 100644 --- a/testing/pom.xml +++ b/testing/pom.xml @@ -5,7 +5,7 @@ io.split.client java-client-parent - 4.7.3-rc3 + 4.7.2 java-client-testing jar