diff --git a/.github/workflows/build-check.yml b/.github/workflows/build-check.yml
index 5a5c9f3c..e8866bc6 100644
--- a/.github/workflows/build-check.yml
+++ b/.github/workflows/build-check.yml
@@ -15,11 +15,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
- - name: Set up JDK 8
- uses: actions/setup-java@v1
- with:
- java-version: '1.8'
- cache: maven
- - name: Build with Maven
- run: mvn -B clean package --file pom.xml
+ - uses: actions/checkout@v4
+ - name: Set up JDK 17
+ uses: actions/setup-java@v3
+ with:
+ java-version: 17
+ cache: maven
+ distribution: 'temurin'
+ - name: Build with Maven
+ run: mvn -B clean package --file pom.xml
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f76813fc..a758d08b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,15 @@
# Changelog
All notable changes to this project will be documented in this file.
+## [1.0-RC15]
+- Moved discovery bundle from https://github.com/appform-io/dropwizard-service-discovery.
+- Updated to dropwizard version 2.1.10 : BOM update.
+- Upgraded to java version 17 with release in 11
+- Removed com.fasterxml and introduced dropwizard-jackson for the jackson bindings.
+- Upgraded to junit 5 and fixed the necessary tests including wiremock versions and tests.
+- Upgraded the curator framework version
+- Done sonar fixes after the java version upgrade
+
## [1.0-RC14]
- When the Collection of Services is empty the monitor should gracefully return [PR](https://github.com/appform-io/ranger/pull/27)
diff --git a/pom.xml b/pom.xml
index 018c326b..b14a9849 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
io.appform.ranger
ranger
pom
- 1.0-RC14
+ 1.0-RC15
Ranger
https://github.com/appform-io/ranger
Service Discovery for Java
@@ -27,6 +27,7 @@
ranger-http-model
ranger-http-server-bundle
ranger-zk-server-bundle
+ ranger-discovery-bundle
@@ -82,26 +83,45 @@
UTF-8
31.0.1-jre
- 5.1.0
- 2.13.1
+ 5.5.0
1.7.32
3.8.0
- 1.8
+ 17
+ 11
1.18.22
3.0.1u2
- 4.13.2
+ 5.8.2
4.1.1
2.0.0
4.9.3
- 2.27.2
+ 3.3.1
4.2.0
- 1.2.10
+ 2.1.10
+
+
+
+ org.junit
+ junit-bom
+ ${junit.jupiter.version}
+ pom
+ import
+
+
+ io.dropwizard
+ dropwizard-bom
+ pom
+ import
+ ${dropwizard.version}
+
+
+
+
org.projectlombok
@@ -124,32 +144,25 @@
slf4j-api
${slf4j.version}
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
- test
+ io.dropwizard
+ dropwizard-jackson
- ch.qos.logback
- logback-classic
- ${logback.version}
+ org.junit.jupiter
+ junit-jupiter-api
test
-
- junit
- junit
- ${junit.version}
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
-
com.github.rholder
guava-retrying
${guava-retrying.version}
-
org.awaitility
awaitility
@@ -167,12 +180,18 @@
${java.version}
+ ${java.release.version}
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0-M5
+
org.jacoco
jacoco-maven-plugin
- 0.8.6
+ 0.8.8
@@ -206,7 +225,10 @@
org.apache.maven.plugins
maven-javadoc-plugin
- 3.3.0
+ 3.6.3
+
+ all,-missing
+
attach-javadocs
@@ -265,6 +287,20 @@
+
+
+ add-java-open-options-for-jdk16+
+
+ [16,)
+
+
+
+ --add-opens java.base/java.net=ALL-UNNAMED
+ --add-opens java.base/sun.net=ALL-UNNAMED
+
+
+
diff --git a/ranger-client/pom.xml b/ranger-client/pom.xml
index caf0f078..727e9c1b 100644
--- a/ranger-client/pom.xml
+++ b/ranger-client/pom.xml
@@ -5,7 +5,7 @@
ranger
io.appform.ranger
- 1.0-RC14
+ 1.0-RC15
4.0.0
@@ -23,11 +23,6 @@
${project.version}
test-jar
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
-
diff --git a/ranger-client/src/test/java/io/appform/ranger/client/AbstractRangerHubClientTest.java b/ranger-client/src/test/java/io/appform/ranger/client/AbstractRangerHubClientTest.java
index d027f463..b741b627 100644
--- a/ranger-client/src/test/java/io/appform/ranger/client/AbstractRangerHubClientTest.java
+++ b/ranger-client/src/test/java/io/appform/ranger/client/AbstractRangerHubClientTest.java
@@ -20,42 +20,41 @@
import io.appform.ranger.core.utils.RangerTestUtils;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
-import lombok.var;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
@Slf4j
-public class AbstractRangerHubClientTest {
+class AbstractRangerHubClientTest {
private static final Service service = RangerTestUtils.getService("test-ns", "test-s");
@Test
- public void testAbstractHubClient() {
+ void testAbstractHubClient() {
val testAbstractHub = RangerHubTestUtils.getTestHub();
testAbstractHub.start();
var node = testAbstractHub.getNode(service).orElse(null);
- Assert.assertNotNull(node);
- Assert.assertTrue(node.getHost().equalsIgnoreCase("localhost"));
- Assert.assertEquals(9200, node.getPort());
- Assert.assertEquals(1, node.getNodeData().getShardId());
- Assert.assertFalse(testAbstractHub.getNode(RangerTestUtils.getService("test", "test")).isPresent());
- Assert.assertFalse(testAbstractHub.getNode(service, nodeData -> nodeData.getShardId() == 2).isPresent());
- Assert.assertFalse(testAbstractHub.getNode(RangerTestUtils.getService("test", "test"), nodeData -> nodeData.getShardId() == 1).isPresent());
+ Assertions.assertNotNull(node);
+ Assertions.assertTrue(node.getHost().equalsIgnoreCase("localhost"));
+ Assertions.assertEquals(9200, node.getPort());
+ Assertions.assertEquals(1, node.getNodeData().getShardId());
+ Assertions.assertFalse(testAbstractHub.getNode(RangerTestUtils.getService("test", "test")).isPresent());
+ Assertions.assertFalse(testAbstractHub.getNode(service, nodeData -> nodeData.getShardId() == 2).isPresent());
+ Assertions.assertFalse(testAbstractHub.getNode(RangerTestUtils.getService("test", "test"), nodeData -> nodeData.getShardId() == 1).isPresent());
testAbstractHub.stop();
}
@Test
- public void testAbstractHubClientWithDataSource() {
+ void testAbstractHubClientWithDataSource() {
val testAbstractHub = RangerHubTestUtils.getTestHubWithDataSource();
testAbstractHub.start();
- var node = testAbstractHub.getNode(service).orElse(null);
- Assert.assertNotNull(node);
- Assert.assertTrue(node.getHost().equalsIgnoreCase("localhost"));
- Assert.assertEquals(9200, node.getPort());
- Assert.assertEquals(1, node.getNodeData().getShardId());
- Assert.assertFalse(testAbstractHub.getNode(RangerTestUtils.getService("test", "test")).isPresent());
- Assert.assertFalse(testAbstractHub.getNode(service, nodeData -> nodeData.getShardId() == 2).isPresent());
- Assert.assertFalse(testAbstractHub.getNode(RangerTestUtils.getService("test", "test"), nodeData -> nodeData.getShardId() == 1).isPresent());
+ val node = testAbstractHub.getNode(service).orElse(null);
+ Assertions.assertNotNull(node);
+ Assertions.assertTrue(node.getHost().equalsIgnoreCase("localhost"));
+ Assertions.assertEquals(9200, node.getPort());
+ Assertions.assertEquals(1, node.getNodeData().getShardId());
+ Assertions.assertFalse(testAbstractHub.getNode(RangerTestUtils.getService("test", "test")).isPresent());
+ Assertions.assertFalse(testAbstractHub.getNode(service, nodeData -> nodeData.getShardId() == 2).isPresent());
+ Assertions.assertFalse(testAbstractHub.getNode(RangerTestUtils.getService("test", "test"), nodeData -> nodeData.getShardId() == 1).isPresent());
testAbstractHub.stop();
}
}
diff --git a/ranger-client/src/test/java/io/appform/ranger/client/CriteriaUtilsTest.java b/ranger-client/src/test/java/io/appform/ranger/client/CriteriaUtilsTest.java
index 457b20dd..31a6b425 100644
--- a/ranger-client/src/test/java/io/appform/ranger/client/CriteriaUtilsTest.java
+++ b/ranger-client/src/test/java/io/appform/ranger/client/CriteriaUtilsTest.java
@@ -18,27 +18,26 @@
import io.appform.ranger.client.utils.CriteriaUtils;
import io.appform.ranger.core.units.TestNodeData;
import lombok.val;
-import lombok.var;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
import java.util.function.Predicate;
-public class CriteriaUtilsTest {
+class CriteriaUtilsTest {
private Predicate getCriteria(int shardId){
return testNodeData -> testNodeData.getShardId() == shardId;
}
@Test
- public void testGetCriteria(){
+ void testGetCriteria(){
val initialCriteria = getCriteria(1);
val argCriteria = getCriteria(2);
var mergedCriteria = CriteriaUtils.getCriteria(true, initialCriteria, argCriteria);
- Assert.assertFalse(mergedCriteria.test(TestNodeData.builder().shardId(1).build()));
- Assert.assertFalse(mergedCriteria.test(TestNodeData.builder().shardId(2).build()));
+ Assertions.assertFalse(mergedCriteria.test(TestNodeData.builder().shardId(1).build()));
+ Assertions.assertFalse(mergedCriteria.test(TestNodeData.builder().shardId(2).build()));
mergedCriteria = CriteriaUtils.getCriteria(false, initialCriteria, argCriteria);
- Assert.assertFalse(mergedCriteria.test(TestNodeData.builder().shardId(1).build()));
- Assert.assertTrue(mergedCriteria.test(TestNodeData.builder().shardId(2).build()));
+ Assertions.assertFalse(mergedCriteria.test(TestNodeData.builder().shardId(1).build()));
+ Assertions.assertTrue(mergedCriteria.test(TestNodeData.builder().shardId(2).build()));
}
}
diff --git a/ranger-client/src/test/java/io/appform/ranger/client/stubs/TestServiceFinderFactory.java b/ranger-client/src/test/java/io/appform/ranger/client/stubs/TestServiceFinderFactory.java
index 11068e9b..c682e992 100644
--- a/ranger-client/src/test/java/io/appform/ranger/client/stubs/TestServiceFinderFactory.java
+++ b/ranger-client/src/test/java/io/appform/ranger/client/stubs/TestServiceFinderFactory.java
@@ -30,7 +30,8 @@ public ServiceFinder> build
val finder = new TestSimpleUnshardedServiceFinder()
.withNamespace(service.getNamespace())
.withServiceName(service.getServiceName())
- .withDeserializer(new Deserializer() {})
+ .withDeserializer(new Deserializer<>() {
+ })
.build();
finder.start();
return finder;
diff --git a/ranger-core/pom.xml b/ranger-core/pom.xml
index 1a1931f5..634ab4a9 100644
--- a/ranger-core/pom.xml
+++ b/ranger-core/pom.xml
@@ -5,7 +5,7 @@
ranger
io.appform.ranger
- 1.0-RC14
+ 1.0-RC15
4.0.0
diff --git a/ranger-core/src/main/java/io/appform/ranger/core/finder/serviceregistry/MapBasedServiceRegistry.java b/ranger-core/src/main/java/io/appform/ranger/core/finder/serviceregistry/MapBasedServiceRegistry.java
index 95f177f1..5204ba93 100644
--- a/ranger-core/src/main/java/io/appform/ranger/core/finder/serviceregistry/MapBasedServiceRegistry.java
+++ b/ranger-core/src/main/java/io/appform/ranger/core/finder/serviceregistry/MapBasedServiceRegistry.java
@@ -16,7 +16,6 @@
package io.appform.ranger.core.finder.serviceregistry;
import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ListMultimap;
import io.appform.ranger.core.model.Service;
@@ -46,7 +45,7 @@ public ListMultimap> nodes() {
@Override
public List> nodeList() {
val nodeList = nodes.get();
- return null == nodeList ? ImmutableList.of() : new ArrayList<>(nodeList.values());
+ return null == nodeList ? List.of() : new ArrayList<>(nodeList.values());
}
@Override
diff --git a/ranger-core/src/main/java/io/appform/ranger/core/finder/serviceregistry/ServiceRegistryUpdater.java b/ranger-core/src/main/java/io/appform/ranger/core/finder/serviceregistry/ServiceRegistryUpdater.java
index 38790182..63756741 100644
--- a/ranger-core/src/main/java/io/appform/ranger/core/finder/serviceregistry/ServiceRegistryUpdater.java
+++ b/ranger-core/src/main/java/io/appform/ranger/core/finder/serviceregistry/ServiceRegistryUpdater.java
@@ -25,7 +25,6 @@
import io.appform.ranger.core.util.Exceptions;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
-import lombok.var;
import java.util.List;
import java.util.concurrent.ExecutorService;
@@ -67,7 +66,7 @@ public void start() {
log.info("Started updater for [{}]. Triggering initial update.", serviceName);
checkForUpdate(null);
log.info("Waiting for initial update to complete for: {}", serviceName);
- var stopwatch = Stopwatch.createStarted();
+ val stopwatch = Stopwatch.createStarted();
try {
RetryerBuilder.newBuilder()
.retryIfResult(r -> null == r || !r)
diff --git a/ranger-core/src/main/java/io/appform/ranger/core/healthservice/monitor/IsolatedHealthMonitor.java b/ranger-core/src/main/java/io/appform/ranger/core/healthservice/monitor/IsolatedHealthMonitor.java
index 0a84a0fb..8ac7a2df 100644
--- a/ranger-core/src/main/java/io/appform/ranger/core/healthservice/monitor/IsolatedHealthMonitor.java
+++ b/ranger-core/src/main/java/io/appform/ranger/core/healthservice/monitor/IsolatedHealthMonitor.java
@@ -20,6 +20,7 @@
import io.appform.ranger.core.healthservice.monitor.sample.CountMonitor;
import io.appform.ranger.core.healthservice.monitor.sample.PingCheckMonitor;
import io.appform.ranger.core.healthservice.monitor.sample.RotationStatusMonitor;
+import lombok.Getter;
import java.util.Date;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -36,6 +37,7 @@
public abstract class IsolatedHealthMonitor implements Runnable, Monitor {
/* name of the monitor */
+ @Getter
protected String name;
/* reference of the health that this monitor tracks */
@@ -45,6 +47,7 @@ public abstract class IsolatedHealthMonitor implements Runnable, Monitor {
private Date lastStatusUpdateTime;
/* how often should this monitor run */
+ @Getter
private final TimeEntity runInterval;
/* reference to if this monitor is disabled or not (default: false) */
@@ -102,18 +105,10 @@ public void enable() {
disabled.set(false);
}
- public TimeEntity getRunInterval() {
- return runInterval;
- }
-
public T getHealthStatus() {
return healthStatus.get();
}
- public String getName() {
- return name;
- }
-
@Override
public boolean isDisabled() {
return disabled.get();
diff --git a/ranger-core/src/test/java/io/appform/ranger/core/finder/SimpleShardFinderTest.java b/ranger-core/src/test/java/io/appform/ranger/core/finder/SimpleShardFinderTest.java
index c547fe7c..85563cba 100644
--- a/ranger-core/src/test/java/io/appform/ranger/core/finder/SimpleShardFinderTest.java
+++ b/ranger-core/src/test/java/io/appform/ranger/core/finder/SimpleShardFinderTest.java
@@ -23,14 +23,14 @@
import io.appform.ranger.core.utils.RangerTestUtils;
import io.appform.ranger.core.utils.RegistryTestUtils;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
-public class SimpleShardFinderTest {
+class SimpleShardFinderTest {
static class TestSimpleShardSelector implements ShardSelector> {
@@ -41,7 +41,7 @@ public List> nodes(Predicate criteria, MapBasedServiceRegistry
}
@Test
- public void testSimpleShardedFinder() {
+ void testSimpleShardedFinder() {
val serviceRegistry = RegistryTestUtils.getServiceRegistry();
val shardSelector = new TestSimpleShardSelector();
val roundRobinServiceNodeSelector = new RoundRobinServiceNodeSelector();
@@ -49,6 +49,6 @@ public void testSimpleShardedFinder() {
serviceRegistry, shardSelector, roundRobinServiceNodeSelector);
val testNodeDataServiceNode = simpleShardedFinder.get(
RangerTestUtils.getCriteria(2));
- Assert.assertFalse(testNodeDataServiceNode.isPresent());
+ Assertions.assertFalse(testNodeDataServiceNode.isPresent());
}
}
diff --git a/ranger-core/src/test/java/io/appform/ranger/core/finder/UnshardedClusterFinderTest.java b/ranger-core/src/test/java/io/appform/ranger/core/finder/UnshardedClusterFinderTest.java
index f9a185eb..4b5f214b 100644
--- a/ranger-core/src/test/java/io/appform/ranger/core/finder/UnshardedClusterFinderTest.java
+++ b/ranger-core/src/test/java/io/appform/ranger/core/finder/UnshardedClusterFinderTest.java
@@ -22,12 +22,12 @@
import io.appform.ranger.core.utils.RangerTestUtils;
import io.appform.ranger.core.utils.RegistryTestUtils;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
import java.util.List;
-public class UnshardedClusterFinderTest {
+class UnshardedClusterFinderTest {
static class TestUnshardedNodeSelector implements ServiceNodeSelector {
@@ -37,7 +37,7 @@ public ServiceNode select(List> serviceN
}
}
@Test
- public void unshardedClusterFinder(){
+ void unshardedClusterFinder(){
val unshardedRegistry = RegistryTestUtils.getUnshardedRegistry();
val shardSelector = new ListShardSelector();
val simpleUnshardedServiceFinder = new SimpleUnshardedServiceFinder<>(
@@ -46,7 +46,7 @@ public void unshardedClusterFinder(){
new TestUnshardedNodeSelector()
);
val serviceNode = simpleUnshardedServiceFinder.get(RangerTestUtils.getCriteria(1));
- Assert.assertTrue(serviceNode.isPresent());
- Assert.assertEquals("localhost-1", serviceNode.get().getHost());
+ Assertions.assertTrue(serviceNode.isPresent());
+ Assertions.assertEquals("localhost-1", serviceNode.get().getHost());
}
}
diff --git a/ranger-core/src/test/java/io/appform/ranger/core/finder/nodeselector/RoundRobinServiceNodeSelectorTest.java b/ranger-core/src/test/java/io/appform/ranger/core/finder/nodeselector/RoundRobinServiceNodeSelectorTest.java
index 57e005f6..f563f00d 100644
--- a/ranger-core/src/test/java/io/appform/ranger/core/finder/nodeselector/RoundRobinServiceNodeSelectorTest.java
+++ b/ranger-core/src/test/java/io/appform/ranger/core/finder/nodeselector/RoundRobinServiceNodeSelectorTest.java
@@ -18,21 +18,21 @@
import io.appform.ranger.core.model.ServiceNode;
import io.appform.ranger.core.units.TestNodeData;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
import java.util.ArrayList;
-public class RoundRobinServiceNodeSelectorTest {
+class RoundRobinServiceNodeSelectorTest {
@Test
- public void testRandomNodeSelector(){
+ void testRandomNodeSelector(){
val roundRobinSelector = new RoundRobinServiceNodeSelector();
val serviceNodes = new ArrayList>();
serviceNodes.add(ServiceNode.builder().host("localhost-1").port(9000).nodeData(TestNodeData.builder().shardId(1).build()).build());
serviceNodes.add(ServiceNode.builder().host("localhost-2").port(9001).nodeData(TestNodeData.builder().shardId(2).build()).build());
serviceNodes.add(ServiceNode.builder().host("localhost-3").port(9002).nodeData(TestNodeData.builder().shardId(3).build()).build());
- Assert.assertEquals("localhost-2", roundRobinSelector.select(serviceNodes).getHost());
- Assert.assertEquals("localhost-3", roundRobinSelector.select(serviceNodes).getHost());
- Assert.assertEquals("localhost-1", roundRobinSelector.select(serviceNodes).getHost());
+ Assertions.assertEquals("localhost-2", roundRobinSelector.select(serviceNodes).getHost());
+ Assertions.assertEquals("localhost-3", roundRobinSelector.select(serviceNodes).getHost());
+ Assertions.assertEquals("localhost-1", roundRobinSelector.select(serviceNodes).getHost());
}
}
diff --git a/ranger-core/src/test/java/io/appform/ranger/core/finder/serviceregistry/MapBasedServiceRegistryTest.java b/ranger-core/src/test/java/io/appform/ranger/core/finder/serviceregistry/MapBasedServiceRegistryTest.java
index 667d7731..6aee37db 100644
--- a/ranger-core/src/test/java/io/appform/ranger/core/finder/serviceregistry/MapBasedServiceRegistryTest.java
+++ b/ranger-core/src/test/java/io/appform/ranger/core/finder/serviceregistry/MapBasedServiceRegistryTest.java
@@ -20,20 +20,20 @@
import io.appform.ranger.core.utils.RangerTestUtils;
import io.appform.ranger.core.utils.RegistryTestUtils;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
-public class MapBasedServiceRegistryTest {
+class MapBasedServiceRegistryTest {
@Test
- public void testMapBasedServiceRegistryWithMatchingShardSelector(){
+ void testMapBasedServiceRegistryWithMatchingShardSelector(){
val serviceRegistry = RegistryTestUtils.getServiceRegistry();
- Assert.assertTrue(null != serviceRegistry.nodes() && !serviceRegistry.nodes().isEmpty());
+ Assertions.assertTrue(null != serviceRegistry.nodes() && !serviceRegistry.nodes().isEmpty());
val matchingShardSelector = new MatchingShardSelector();
val nodes = matchingShardSelector.nodes(
RangerTestUtils.getCriteria(1), serviceRegistry);
- Assert.assertFalse(nodes.isEmpty());
- Assert.assertEquals("localhost-1", nodes.get(0).getHost());
+ Assertions.assertFalse(nodes.isEmpty());
+ Assertions.assertEquals("localhost-1", nodes.get(0).getHost());
}
}
diff --git a/ranger-core/src/test/java/io/appform/ranger/core/finder/shardselector/ListShardSelectorTest.java b/ranger-core/src/test/java/io/appform/ranger/core/finder/shardselector/ListShardSelectorTest.java
index 8355f9b1..6c867d37 100644
--- a/ranger-core/src/test/java/io/appform/ranger/core/finder/shardselector/ListShardSelectorTest.java
+++ b/ranger-core/src/test/java/io/appform/ranger/core/finder/shardselector/ListShardSelectorTest.java
@@ -19,17 +19,17 @@
import io.appform.ranger.core.utils.RangerTestUtils;
import io.appform.ranger.core.utils.RegistryTestUtils;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
-public class ListShardSelectorTest {
+class ListShardSelectorTest {
@Test
- public void testListShardSelector(){
+ void testListShardSelector(){
val serviceRegistry = RegistryTestUtils.getUnshardedRegistry();
val shardSelector = new ListShardSelector();
val nodes = shardSelector.nodes(RangerTestUtils.getCriteria(1), serviceRegistry);
- Assert.assertFalse(nodes.isEmpty());
- Assert.assertEquals("localhost-1", nodes.get(0).getHost());
+ Assertions.assertFalse(nodes.isEmpty());
+ Assertions.assertEquals("localhost-1", nodes.get(0).getHost());
}
}
diff --git a/ranger-core/src/test/java/io/appform/ranger/core/finder/shardselector/MatchingShardSelectorTest.java b/ranger-core/src/test/java/io/appform/ranger/core/finder/shardselector/MatchingShardSelectorTest.java
index 6fee777f..9c8c7d12 100644
--- a/ranger-core/src/test/java/io/appform/ranger/core/finder/shardselector/MatchingShardSelectorTest.java
+++ b/ranger-core/src/test/java/io/appform/ranger/core/finder/shardselector/MatchingShardSelectorTest.java
@@ -19,18 +19,18 @@
import io.appform.ranger.core.utils.RangerTestUtils;
import io.appform.ranger.core.utils.RegistryTestUtils;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
-public class MatchingShardSelectorTest {
+class MatchingShardSelectorTest {
@Test
- public void testMatchingShardSelector(){
+ void testMatchingShardSelector(){
val serviceRegistry = RegistryTestUtils.getServiceRegistry();
val shardSelector = new MatchingShardSelector();
val nodes = shardSelector.nodes(
RangerTestUtils.getCriteria(1), serviceRegistry);
- Assert.assertFalse(nodes.isEmpty());
- Assert.assertEquals("localhost-1", nodes.get(0).getHost());
+ Assertions.assertFalse(nodes.isEmpty());
+ Assertions.assertEquals("localhost-1", nodes.get(0).getHost());
}
}
diff --git a/ranger-core/src/test/java/io/appform/ranger/core/finder/shardselector/NoopShardSelectorTest.java b/ranger-core/src/test/java/io/appform/ranger/core/finder/shardselector/NoopShardSelectorTest.java
index 858b5461..c4b89f11 100644
--- a/ranger-core/src/test/java/io/appform/ranger/core/finder/shardselector/NoopShardSelectorTest.java
+++ b/ranger-core/src/test/java/io/appform/ranger/core/finder/shardselector/NoopShardSelectorTest.java
@@ -4,17 +4,17 @@
import io.appform.ranger.core.utils.RangerTestUtils;
import io.appform.ranger.core.utils.RegistryTestUtils;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
-public class NoopShardSelectorTest {
+class NoopShardSelectorTest {
@Test
- public void testNoOpShardSelector(){
+ void testNoOpShardSelector(){
val serviceRegistry = RegistryTestUtils.getUnshardedRegistry();
val shardSelector = new NoopShardSelector();
val nodes = shardSelector.nodes(RangerTestUtils.getCriteria(1), serviceRegistry);
- Assert.assertFalse(nodes.isEmpty());
- Assert.assertEquals("localhost-1", nodes.get(0).getHost());
+ Assertions.assertFalse(nodes.isEmpty());
+ Assertions.assertEquals("localhost-1", nodes.get(0).getHost());
}
}
diff --git a/ranger-core/src/test/java/io/appform/ranger/core/finderhub/ServiceFinderHubTest.java b/ranger-core/src/test/java/io/appform/ranger/core/finderhub/ServiceFinderHubTest.java
index 1ca9fcb2..cc76b11c 100644
--- a/ranger-core/src/test/java/io/appform/ranger/core/finderhub/ServiceFinderHubTest.java
+++ b/ranger-core/src/test/java/io/appform/ranger/core/finderhub/ServiceFinderHubTest.java
@@ -12,14 +12,14 @@
import io.appform.ranger.core.units.TestNodeData;
import java.util.Optional;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
-public class ServiceFinderHubTest {
+class ServiceFinderHubTest {
private final ServiceFinderHub> serviceFinderHub = new ServiceFinderHub<>(
new DynamicDataSource(Lists.newArrayList(new Service("NS", "PRE_REGISTERED_SERVICE"))),
@@ -32,38 +32,38 @@ public class ServiceFinderHubTest {
.build());
@Test
- public void testDynamicServiceAddition() {
+ void testDynamicServiceAddition() {
serviceFinderHub.start();
val preRegisteredServiceFinder = serviceFinderHub.finder(new Service("NS", "PRE_REGISTERED_SERVICE"))
.orElseThrow(() -> new IllegalStateException("Finder should be present"));
val node = preRegisteredServiceFinder.get(null, (criteria, serviceRegistry) -> serviceRegistry.nodeList());
- Assert.assertTrue(node.isPresent());
- Assert.assertEquals("HOST", node.get().getHost());
- Assert.assertEquals(0, node.get().getPort());
+ Assertions.assertTrue(node.isPresent());
+ Assertions.assertEquals("HOST", node.get().getHost());
+ Assertions.assertEquals(0, node.get().getPort());
serviceFinderHub.buildFinder(new Service("NS", "SERVICE")).join();
val dynamicServiceFinder = serviceFinderHub.finder(new Service("NS", "SERVICE"))
.orElseThrow(() -> new IllegalStateException("Finder should be present"));
val dynamicServiceNode = dynamicServiceFinder.get(null, (criteria, serviceRegistry) -> serviceRegistry.nodeList());
- Assert.assertTrue(dynamicServiceNode.isPresent());
- Assert.assertEquals("HOST", dynamicServiceNode.get().getHost());
- Assert.assertEquals(0, dynamicServiceNode.get().getPort());
+ Assertions.assertTrue(dynamicServiceNode.isPresent());
+ Assertions.assertEquals("HOST", dynamicServiceNode.get().getHost());
+ Assertions.assertEquals(0, dynamicServiceNode.get().getPort());
}
@Test
- public void testDynamicServiceAdditionAsync() throws InterruptedException {
+ void testDynamicServiceAdditionAsync() throws InterruptedException {
serviceFinderHub.start();
serviceFinderHub.buildFinder(new Service("NS", "SERVICE_NAME"));
val finderOpt = serviceFinderHub.finder(new Service("NS", "SERVICE_NAME"));
- Assert.assertFalse("Finders will not be availbale immediately", finderOpt.isPresent());
+ Assertions.assertFalse(finderOpt.isPresent(), "Finders will not be availbale immediately");
Thread.sleep(1000);
val finderAfterWaitOpt = serviceFinderHub.finder(new Service("NS", "SERVICE_NAME"));
- Assert.assertTrue("Finders should be availble after some time", finderAfterWaitOpt.isPresent());
+ Assertions.assertTrue(finderAfterWaitOpt.isPresent(), "Finders should be availble after some time");
}
@Test
- public void testDynamicServiceAdditionWithNonDynamicDataSource() {
+ void testDynamicServiceAdditionWithNonDynamicDataSource() {
val serviceFinderHub = new ServiceFinderHub<>(new StaticDataSource(new HashSet<>()), service -> new TestServiceFinderBuilder()
.withNamespace(service.getNamespace())
@@ -75,11 +75,10 @@ public void testDynamicServiceAdditionWithNonDynamicDataSource() {
try {
val future = serviceFinderHub.buildFinder(new Service("NS", "SERVICE_NAME"));
future.join();
- Assert.fail("Exception should have been thrown");
+ Assertions.fail("Exception should have been thrown");
} catch (Exception exception) {
- Assert.assertTrue("Unsupported exception should be thrown", exception instanceof UnsupportedOperationException);
+ Assertions.assertTrue(exception instanceof UnsupportedOperationException, "Unsupported exception should be thrown");
}
-
}
private static class TestServiceFinderBuilder extends BaseServiceFinderBuilder, ServiceFinder>, TestServiceFinderBuilder, Deserializer> {
diff --git a/ranger-core/src/test/java/io/appform/ranger/core/serviceprovider/ServiceProviderTest.java b/ranger-core/src/test/java/io/appform/ranger/core/serviceprovider/ServiceProviderTest.java
index afb1c2bf..cff88392 100644
--- a/ranger-core/src/test/java/io/appform/ranger/core/serviceprovider/ServiceProviderTest.java
+++ b/ranger-core/src/test/java/io/appform/ranger/core/serviceprovider/ServiceProviderTest.java
@@ -24,10 +24,10 @@
import io.appform.ranger.core.model.ServiceNode;
import io.appform.ranger.core.units.TestNodeData;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
-public class ServiceProviderTest {
+class ServiceProviderTest {
static TestNodeData testNodeData = null;
@@ -98,29 +98,29 @@ protected NodeDataSink> dataSink(Service service) {
}
}
- @Test(expected = NullPointerException.class)
- public void testInvalidServiceProvider(){
- new TestServiceProviderBuilder<>()
+ @Test
+ void testInvalidServiceProvider() {
+ Assertions.assertThrowsExactly(NullPointerException.class, () -> new TestServiceProviderBuilder<>()
.withServiceName("test-service")
.withNamespace("test")
.withHostname("localhost-1")
.withPort(9000)
- .build();
+ .build());
}
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidServiceProviderNoHealthCheck(){
- new TestServiceProviderBuilder<>()
+ @Test
+ void testInvalidServiceProviderNoHealthCheck() {
+ Assertions.assertThrowsExactly(IllegalArgumentException.class, () -> new TestServiceProviderBuilder<>()
.withServiceName("test-service")
.withNamespace("test")
.withHostname("localhost-1")
.withPort(9000)
.withSerializer(new TestSerializerImpl())
- .build();
+ .build());
}
@Test
- public void testBuildServiceProvider(){
+ void testBuildServiceProvider() {
val testProvider = new TestServiceProviderBuilder<>()
.withServiceName("test-service")
.withNamespace("test")
@@ -132,8 +132,8 @@ public void testBuildServiceProvider(){
.withHealthUpdateIntervalMs(1000)
.build();
testProvider.start();
- Assert.assertNotNull(testNodeData);
- Assert.assertEquals(1, testNodeData.getShardId());
+ Assertions.assertNotNull(testNodeData);
+ Assertions.assertEquals(1, testNodeData.getShardId());
}
}
diff --git a/ranger-discovery-bundle/README.md b/ranger-discovery-bundle/README.md
new file mode 100644
index 00000000..e69de29b
diff --git a/ranger-discovery-bundle/perf/results/io.appform.ranger.discovery.bundle.id.IdGeneratorPerfTest.testGenerate.json b/ranger-discovery-bundle/perf/results/io.appform.ranger.discovery.bundle.id.IdGeneratorPerfTest.testGenerate.json
new file mode 100644
index 00000000..f19b937b
--- /dev/null
+++ b/ranger-discovery-bundle/perf/results/io.appform.ranger.discovery.bundle.id.IdGeneratorPerfTest.testGenerate.json
@@ -0,0 +1,8 @@
+{
+ "name" : "io.appform.ranger.discovery.bundle.id.IdGeneratorPerfTest.testGenerate",
+ "mode" : "Throughput",
+ "iterations" : 4,
+ "threads" : 1,
+ "forks" : 3,
+ "mean_ops" : 644166.1778513143
+}
\ No newline at end of file
diff --git a/ranger-discovery-bundle/perf/results/io.appform.ranger.discovery.bundle.id.IdGeneratorPerfTest.testGenerateBase36.json b/ranger-discovery-bundle/perf/results/io.appform.ranger.discovery.bundle.id.IdGeneratorPerfTest.testGenerateBase36.json
new file mode 100644
index 00000000..272db000
--- /dev/null
+++ b/ranger-discovery-bundle/perf/results/io.appform.ranger.discovery.bundle.id.IdGeneratorPerfTest.testGenerateBase36.json
@@ -0,0 +1,8 @@
+{
+ "name" : "io.appform.ranger.discovery.bundle.id.IdGeneratorPerfTest.testGenerateBase36",
+ "mode" : "Throughput",
+ "iterations" : 4,
+ "threads" : 1,
+ "forks" : 3,
+ "mean_ops" : 502644.4941310657
+}
\ No newline at end of file
diff --git a/ranger-discovery-bundle/pom.xml b/ranger-discovery-bundle/pom.xml
new file mode 100644
index 00000000..11233eb1
--- /dev/null
+++ b/ranger-discovery-bundle/pom.xml
@@ -0,0 +1,82 @@
+
+
+
+ ranger
+ io.appform.ranger
+ 1.0-RC15
+
+ 4.0.0
+
+ ranger-discovery-bundle
+
+
+ 1.7.2
+ 3.2.4
+
+
+
+
+ org.openjdk.jmh
+ jmh-core
+ 1.35
+ test
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ 1.35
+ test
+
+
+ io.dropwizard
+ dropwizard-core
+ provided
+
+
+ dev.failsafe
+ failsafe
+ ${failsafe.version}
+
+
+ org.apache.curator
+ curator-test
+ ${curator.version}
+ test
+
+
+ log4j
+ log4j
+
+
+ io.netty
+ *
+
+
+
+
+ org.mockito
+ mockito-core
+ ${mockito.version}
+ test
+
+
+ io.appform.ranger
+ ranger-zk-client
+ ${project.version}
+
+
+ io.appform.ranger
+ ranger-server-common
+ ${project.version}
+
+
+ com.alibaba
+ dns-cache-manipulator
+ ${dns.cache.manipulator.version}
+ test
+
+
+
+
\ No newline at end of file
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/Constants.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/Constants.java
new file mode 100644
index 00000000..bd32cfa8
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/Constants.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2019 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle;
+
+import com.google.common.collect.ImmutableSet;
+import lombok.experimental.UtilityClass;
+
+import java.util.Set;
+
+/**
+ * Constants
+ */
+@UtilityClass
+public class Constants {
+ public static final String DEFAULT_NAMESPACE = "default";
+ public static final String DEFAULT_HOST = "__DEFAULT_SERVICE_HOST";
+ public static final int DEFAULT_PORT = -1;
+ public static final int DEFAULT_DW_CHECK_INTERVAL = 15;
+ public static final int DEFAULT_RETRY_CONN_INTERVAL = 5000;
+
+ public static final String ZOOKEEPER_HOST_DELIMITER = ",";
+ public static final String HOST_PORT_DELIMITER = ":";
+ public static final String PATH_DELIMITER = "/";
+
+ public static final Set LOCAL_ADDRESSES = ImmutableSet.of("127.0.0.1", "127.0.1.1", "localhost");
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/InfoResource.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/InfoResource.java
new file mode 100644
index 00000000..ca255fd8
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/InfoResource.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle;
+
+import io.appform.ranger.client.RangerClient;
+import io.appform.ranger.common.server.ShardInfo;
+import io.appform.ranger.core.finder.serviceregistry.MapBasedServiceRegistry;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+/**
+ * Given information about the cluster.
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Path("/instances")
+public class InfoResource {
+ private final RangerClient> serviceDiscoveryClient;
+
+ public InfoResource(RangerClient> serviceDiscoveryClient) {
+ this.serviceDiscoveryClient = serviceDiscoveryClient;
+ }
+
+ @GET
+ public Response get() {
+ return Response.ok(serviceDiscoveryClient.getAllNodes()).build();
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundle.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundle.java
new file mode 100644
index 00000000..c9397312
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundle.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2019 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import io.appform.ranger.client.RangerClient;
+import io.appform.ranger.client.zk.SimpleRangerZKClient;
+import io.appform.ranger.common.server.ShardInfo;
+import io.appform.ranger.core.finder.serviceregistry.MapBasedServiceRegistry;
+import io.appform.ranger.core.healthcheck.Healthcheck;
+import io.appform.ranger.core.healthcheck.HealthcheckStatus;
+import io.appform.ranger.core.healthservice.TimeEntity;
+import io.appform.ranger.core.healthservice.monitor.IsolatedHealthMonitor;
+import io.appform.ranger.core.model.ServiceNode;
+import io.appform.ranger.core.model.ShardSelector;
+import io.appform.ranger.core.serviceprovider.ServiceProvider;
+import io.appform.ranger.discovery.bundle.healthchecks.InitialDelayChecker;
+import io.appform.ranger.discovery.bundle.healthchecks.InternalHealthChecker;
+import io.appform.ranger.discovery.bundle.healthchecks.RotationCheck;
+import io.appform.ranger.discovery.bundle.id.IdGenerator;
+import io.appform.ranger.discovery.bundle.id.NodeIdManager;
+import io.appform.ranger.discovery.bundle.id.constraints.IdValidationConstraint;
+import io.appform.ranger.discovery.bundle.monitors.DropwizardHealthMonitor;
+import io.appform.ranger.discovery.bundle.monitors.DropwizardServerStartupCheck;
+import io.appform.ranger.discovery.bundle.resolvers.DefaultNodeInfoResolver;
+import io.appform.ranger.discovery.bundle.resolvers.DefaultPortSchemeResolver;
+import io.appform.ranger.discovery.bundle.resolvers.NodeInfoResolver;
+import io.appform.ranger.discovery.bundle.resolvers.PortSchemeResolver;
+import io.appform.ranger.discovery.bundle.rotationstatus.BIRTask;
+import io.appform.ranger.discovery.bundle.rotationstatus.DropwizardServerStatus;
+import io.appform.ranger.discovery.bundle.rotationstatus.OORTask;
+import io.appform.ranger.discovery.bundle.rotationstatus.RotationStatus;
+import io.appform.ranger.discovery.bundle.selectors.HierarchicalEnvironmentAwareShardSelector;
+import io.appform.ranger.discovery.bundle.util.ConfigurationUtils;
+import io.appform.ranger.zookeeper.ServiceProviderBuilders;
+import io.appform.ranger.zookeeper.serde.ZkNodeDataSerializer;
+import io.dropwizard.Configuration;
+import io.dropwizard.ConfiguredBundle;
+import io.dropwizard.lifecycle.Managed;
+import io.dropwizard.setup.Bootstrap;
+import io.dropwizard.setup.Environment;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+import lombok.val;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.retry.RetryForever;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static io.appform.ranger.discovery.bundle.Constants.LOCAL_ADDRESSES;
+
+
+/**
+ * A dropwizard bundle for service discovery.
+ */
+@SuppressWarnings("unused")
+@Slf4j
+public abstract class ServiceDiscoveryBundle implements ConfiguredBundle {
+
+ private final List healthchecks = Lists.newArrayList();
+ private final List globalIdConstraints;
+ private ServiceDiscoveryConfiguration serviceDiscoveryConfiguration;
+ private ServiceProvider> serviceProvider;
+
+ @Getter
+ private CuratorFramework curator;
+ @Getter
+ private RangerClient> serviceDiscoveryClient;
+ @Getter
+ @VisibleForTesting
+ private RotationStatus rotationStatus;
+ @Getter
+ @VisibleForTesting
+ private DropwizardServerStatus serverStatus;
+
+ protected ServiceDiscoveryBundle() {
+ globalIdConstraints = Collections.emptyList();
+ }
+
+ protected ServiceDiscoveryBundle(List globalIdConstraints) {
+ this.globalIdConstraints = globalIdConstraints != null
+ ? globalIdConstraints
+ : Collections.emptyList();
+ }
+
+ @Override
+ public void initialize(Bootstrap> bootstrap) {
+
+ }
+
+ @Override
+ public void run(T configuration,
+ Environment environment) throws Exception {
+ val portSchemeResolver = createPortSchemeResolver();
+ Preconditions.checkNotNull(portSchemeResolver, "Port scheme resolver can't be null");
+ val portScheme = portSchemeResolver.resolve(configuration);
+ serviceDiscoveryConfiguration = getRangerConfiguration(configuration);
+ val objectMapper = environment.getObjectMapper();
+ val namespace = serviceDiscoveryConfiguration.getNamespace();
+ val serviceName = getServiceName(configuration);
+ val hostname = getHost();
+ val port = getPort(configuration);
+ val initialCriteria = getInitialCriteria(configuration);
+ val useInitialCriteria = alwaysMergeWithInitialCriteria(configuration);
+ val shardSelector = getShardSelector(configuration);
+ rotationStatus = new RotationStatus(serviceDiscoveryConfiguration.isInitialRotationStatus());
+ serverStatus = new DropwizardServerStatus(false);
+ curator = CuratorFrameworkFactory.builder()
+ .connectString(serviceDiscoveryConfiguration.getZookeeper())
+ .namespace(namespace)
+ .retryPolicy(new RetryForever(serviceDiscoveryConfiguration.getConnectionRetryIntervalMillis()))
+ .build();
+ serviceProvider = buildServiceProvider(environment, objectMapper, namespace, serviceName, hostname, port,
+ portScheme);
+ serviceDiscoveryClient = buildDiscoveryClient(environment, namespace, serviceName, initialCriteria,
+ useInitialCriteria, shardSelector);
+ environment.lifecycle()
+ .manage(new ServiceDiscoveryManager(serviceName));
+ environment.jersey()
+ .register(new InfoResource(serviceDiscoveryClient));
+ environment.admin()
+ .addTask(new OORTask(rotationStatus));
+ environment.admin()
+ .addTask(new BIRTask(rotationStatus));
+ }
+
+ protected ShardSelector> getShardSelector(T configuration) {
+ return new HierarchicalEnvironmentAwareShardSelector(getRangerConfiguration(configuration).getEnvironment());
+ }
+
+ protected abstract ServiceDiscoveryConfiguration getRangerConfiguration(T configuration);
+
+ protected abstract String getServiceName(T configuration);
+
+ protected NodeInfoResolver createNodeInfoResolver() {
+ return new DefaultNodeInfoResolver();
+ }
+
+ protected PortSchemeResolver createPortSchemeResolver() {
+ return new DefaultPortSchemeResolver<>();
+ }
+
+ /**
+ * Override the following if you require.
+ **/
+ protected Predicate getInitialCriteria(T configuration) {
+ return shardInfo -> true;
+ }
+
+ protected boolean alwaysMergeWithInitialCriteria(T configuration) {
+ return false;
+ }
+
+ protected List> getHealthMonitors() {
+ return Collections.emptyList();
+ }
+
+ @SuppressWarnings("unused")
+ protected int getPort(T configuration) {
+ Preconditions.checkArgument(Constants.DEFAULT_PORT != serviceDiscoveryConfiguration.getPublishedPort()
+ && 0 != serviceDiscoveryConfiguration.getPublishedPort(),
+ "Looks like publishedPost has not been set and getPort() has not been overridden. This is wrong. \n"
+ + "Either set publishedPort in config or override getPort() to return the port on which the service is running");
+ return serviceDiscoveryConfiguration.getPublishedPort();
+ }
+
+ protected String getHost() throws UnknownHostException {
+ val host = ConfigurationUtils.resolveNonEmptyPublishedHost(serviceDiscoveryConfiguration.getPublishedHost());
+
+ val publishedHostAddress = InetAddress.getByName(host)
+ .getHostAddress();
+
+ val zkHostAddresses = ConfigurationUtils.resolveZookeeperHosts(serviceDiscoveryConfiguration.getZookeeper())
+ .stream()
+ .map(zkHost -> {
+ try {
+ return InetAddress.getByName(zkHost)
+ .getHostAddress();
+ } catch (UnknownHostException e) {
+ throw new IllegalArgumentException(
+ String.format("Couldn't resolve host address for zkHost : %s", zkHost), e);
+ }
+ })
+ .collect(Collectors.toSet());
+
+ Preconditions.checkArgument(
+ !LOCAL_ADDRESSES.contains(publishedHostAddress) || LOCAL_ADDRESSES.containsAll(zkHostAddresses),
+ "Not allowed to publish localhost address to remote zookeeper");
+
+ return host;
+ }
+
+ public void registerHealthcheck(Healthcheck healthcheck) {
+ this.healthchecks.add(healthcheck);
+ }
+
+ public void registerHealthchecks(List healthchecks) {
+ this.healthchecks.addAll(healthchecks);
+ }
+
+
+ private RangerClient> buildDiscoveryClient(Environment environment,
+ String namespace,
+ String serviceName,
+ Predicate initialCriteria,
+ boolean mergeWithInitialCriteria,
+ ShardSelector> shardSelector) {
+ return SimpleRangerZKClient.builder()
+ .curatorFramework(curator)
+ .namespace(namespace)
+ .serviceName(serviceName)
+ .mapper(environment.getObjectMapper())
+ .nodeRefreshIntervalMs(serviceDiscoveryConfiguration.getRefreshTimeMs())
+ .disableWatchers(serviceDiscoveryConfiguration.isDisableWatchers())
+ .deserializer(data -> {
+ try {
+ return environment.getObjectMapper()
+ .readValue(data, new TypeReference>() {
+ });
+ } catch (IOException e) {
+ log.warn("Error parsing node data with value {}", new String(data));
+ }
+ return null;
+ })
+ .initialCriteria(initialCriteria)
+ .alwaysUseInitialCriteria(mergeWithInitialCriteria)
+ .shardSelector(shardSelector)
+ .build();
+ }
+
+ private ServiceProvider> buildServiceProvider(Environment environment,
+ ObjectMapper objectMapper,
+ String namespace,
+ String serviceName,
+ String hostname,
+ int port,
+ String portScheme) {
+ val nodeInfoResolver = createNodeInfoResolver();
+ val nodeInfo = nodeInfoResolver.resolve(serviceDiscoveryConfiguration);
+ val initialDelayForMonitor = serviceDiscoveryConfiguration.getInitialDelaySeconds() > 1
+ ? serviceDiscoveryConfiguration.getInitialDelaySeconds() - 1
+ : 0;
+ val dwMonitoringInterval = serviceDiscoveryConfiguration.getDropwizardCheckInterval() == 0
+ ? Constants.DEFAULT_DW_CHECK_INTERVAL
+ : serviceDiscoveryConfiguration.getDropwizardCheckInterval();
+ val dwMonitoringStaleness = Math.max(serviceDiscoveryConfiguration.getDropwizardCheckStaleness(),
+ dwMonitoringInterval + 1);
+ val serviceProviderBuilder = ServiceProviderBuilders.shardedServiceProviderBuilder()
+ .withCuratorFramework(curator)
+ .withNamespace(namespace)
+ .withServiceName(serviceName)
+ .withSerializer(data -> {
+ try {
+ return objectMapper.writeValueAsBytes(data);
+ } catch (Exception e) {
+ log.warn("Could not parse node data", e);
+ }
+ return null;
+ })
+ .withPortScheme(portScheme)
+ .withNodeData(nodeInfo)
+ .withHostname(hostname)
+ .withPort(port)
+ .withHealthcheck(new InternalHealthChecker(healthchecks))
+ .withHealthcheck(new RotationCheck(rotationStatus))
+ .withHealthcheck(new InitialDelayChecker(serviceDiscoveryConfiguration.getInitialDelaySeconds()))
+ .withHealthcheck(new DropwizardServerStartupCheck(environment, serverStatus))
+ .withIsolatedHealthMonitor(new DropwizardHealthMonitor(
+ new TimeEntity(initialDelayForMonitor, dwMonitoringInterval, TimeUnit.SECONDS),
+ dwMonitoringStaleness * 1_000L, environment))
+ .withHealthUpdateIntervalMs(serviceDiscoveryConfiguration.getRefreshTimeMs())
+ .withStaleUpdateThresholdMs(10000);
+
+ val healthMonitors = getHealthMonitors();
+ if (healthMonitors != null && !healthMonitors.isEmpty()) {
+ healthMonitors.forEach(serviceProviderBuilder::withIsolatedHealthMonitor);
+ }
+ return serviceProviderBuilder.build();
+ }
+
+ @AllArgsConstructor
+ private class ServiceDiscoveryManager implements Managed {
+
+ private final String serviceName;
+
+ @Override
+ public void start() {
+ log.debug("Starting the discovery manager");
+ curator.start();
+ serviceProvider.start();
+ serviceDiscoveryClient.start();
+ val nodeIdManager = new NodeIdManager(curator, serviceName);
+ IdGenerator.initialize(nodeIdManager.fixNodeId(), globalIdConstraints, Collections.emptyMap());
+ log.debug("Discovery manager has been successfully started.");
+ }
+
+ @Override
+ public void stop() {
+ serviceDiscoveryClient.stop();
+ serviceProvider.stop();
+ curator.close();
+ IdGenerator.cleanUp();
+ }
+ }
+
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryConfiguration.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryConfiguration.java
new file mode 100644
index 00000000..516f6c75
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryConfiguration.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2019 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle;
+
+import com.google.common.base.Strings;
+import lombok.*;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.Set;
+
+/**
+ * Ranger configuration.
+ */
+@Data
+@EqualsAndHashCode
+@ToString
+@NoArgsConstructor
+public class ServiceDiscoveryConfiguration {
+
+
+ @NotNull
+ @NotEmpty
+ private String namespace = Constants.DEFAULT_NAMESPACE;
+
+ @NotNull
+ @NotEmpty
+ private String environment;
+
+ @NotNull
+ @NotEmpty
+ private String zookeeper;
+
+ @Min(1000)
+ @Max(60000)
+ private int connectionRetryIntervalMillis = Constants.DEFAULT_RETRY_CONN_INTERVAL;
+
+ @NotNull
+ @NotEmpty
+ private String publishedHost = Constants.DEFAULT_HOST;
+
+ @NotNull
+ @Min(-1)
+ @Max(65535)
+ private int publishedPort = Constants.DEFAULT_PORT;
+
+ private int refreshTimeMs;
+
+ private boolean disableWatchers;
+
+ @Min(0)
+ @Max(600)
+ private long initialDelaySeconds;
+
+ private boolean initialRotationStatus = true;
+
+ private int dropwizardCheckInterval = Constants.DEFAULT_DW_CHECK_INTERVAL;
+
+ private int dropwizardCheckStaleness;
+
+ private Set tags;
+
+ @Builder
+ public ServiceDiscoveryConfiguration(String namespace,
+ String environment,
+ String zookeeper,
+ int connectionRetryIntervalMillis,
+ String publishedHost,
+ int publishedPort,
+ int refreshTimeMs,
+ boolean disableWatchers,
+ long initialDelaySeconds,
+ boolean initialRotationStatus,
+ int dropwizardCheckInterval,
+ int dropwizardCheckStaleness,
+ Set tags) {
+ this.namespace = Strings.isNullOrEmpty(namespace)
+ ? Constants.DEFAULT_NAMESPACE
+ : namespace;
+ this.environment = environment;
+ this.zookeeper = zookeeper;
+ this.connectionRetryIntervalMillis = connectionRetryIntervalMillis == 0
+ ? Constants.DEFAULT_RETRY_CONN_INTERVAL
+ : connectionRetryIntervalMillis;
+ this.publishedHost = Strings.isNullOrEmpty(publishedHost)
+ ? Constants.DEFAULT_HOST
+ : publishedHost;
+ this.publishedPort = publishedPort == 0
+ ? Constants.DEFAULT_PORT
+ : publishedPort;
+ this.refreshTimeMs = refreshTimeMs;
+ this.disableWatchers = disableWatchers;
+ this.initialDelaySeconds = initialDelaySeconds;
+ this.initialRotationStatus = initialRotationStatus;
+ this.dropwizardCheckInterval = dropwizardCheckInterval == 0
+ ? Constants.DEFAULT_DW_CHECK_INTERVAL
+ : dropwizardCheckInterval;
+ this.dropwizardCheckStaleness = dropwizardCheckStaleness;
+ this.tags = tags;
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/healthchecks/InitialDelayChecker.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/healthchecks/InitialDelayChecker.java
new file mode 100644
index 00000000..c7e4a9e4
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/healthchecks/InitialDelayChecker.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.healthchecks;
+
+import io.appform.ranger.core.healthcheck.Healthcheck;
+import io.appform.ranger.core.healthcheck.HealthcheckStatus;
+
+/**
+ * The following will return healthy only after stipulated time
+ * This will give other bundles etc to startup properly
+ * By the time the node joins the cluster
+ */
+public class InitialDelayChecker implements Healthcheck {
+ private final long validRegistrationTime;
+
+
+ public InitialDelayChecker(long initialDelaySeconds) {
+ validRegistrationTime = System.currentTimeMillis() + initialDelaySeconds * 1000;
+ }
+
+ @Override
+ public HealthcheckStatus check() {
+ return System.currentTimeMillis() > validRegistrationTime
+ ? HealthcheckStatus.healthy
+ : HealthcheckStatus.unhealthy;
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/healthchecks/InternalHealthChecker.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/healthchecks/InternalHealthChecker.java
new file mode 100644
index 00000000..df6655f1
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/healthchecks/InternalHealthChecker.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2019 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.healthchecks;
+
+import io.appform.ranger.core.healthcheck.Healthcheck;
+import io.appform.ranger.core.healthcheck.HealthcheckStatus;
+
+import java.util.List;
+
+/**
+ * Evaluates all registered healthchecks
+ */
+public class InternalHealthChecker implements Healthcheck {
+ private final List healthchecks;
+
+ public InternalHealthChecker(List healthchecks) {
+ this.healthchecks = healthchecks;
+ }
+
+ @Override
+ public HealthcheckStatus check() {
+ return healthchecks.stream()
+ .map(Healthcheck::check)
+ .filter(healthcheckStatus -> healthcheckStatus == HealthcheckStatus.unhealthy)
+ .findFirst()
+ .orElse(HealthcheckStatus.healthy);
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/healthchecks/RotationCheck.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/healthchecks/RotationCheck.java
new file mode 100644
index 00000000..3741b035
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/healthchecks/RotationCheck.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2019 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.healthchecks;
+
+import io.appform.ranger.core.healthcheck.Healthcheck;
+import io.appform.ranger.core.healthcheck.HealthcheckStatus;
+import io.appform.ranger.discovery.bundle.rotationstatus.RotationStatus;
+
+/**
+ * This allows the node to be taken offline in the cluster but still keep running
+ */
+public class RotationCheck implements Healthcheck {
+
+ private final RotationStatus rotationStatus;
+
+ public RotationCheck(RotationStatus rotationStatus) {
+ this.rotationStatus = rotationStatus;
+ }
+
+ @Override
+ public HealthcheckStatus check() {
+ return (rotationStatus.status())
+ ? HealthcheckStatus.healthy
+ : HealthcheckStatus.unhealthy;
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/CollisionChecker.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/CollisionChecker.java
new file mode 100644
index 00000000..b3e947a7
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/CollisionChecker.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.id;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.BitSet;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Checks collisions between ids in given period
+ */
+@Slf4j
+public class CollisionChecker {
+ private final BitSet bitSet = new BitSet(1000);
+ private long currentInstant = 0;
+
+ private final Lock dataLock = new ReentrantLock();
+
+ public CollisionChecker() {
+ //Nothing to do here
+ }
+
+ public boolean check(long time, int location) {
+ dataLock.lock();
+ try {
+ if (currentInstant != time) {
+ currentInstant = time;
+ bitSet.clear();
+ }
+
+ if (bitSet.get(location)) {
+ return false;
+ }
+ bitSet.set(location);
+ return true;
+ }
+ finally {
+ dataLock.unlock();
+ }
+ }
+
+ public void free(long time, int location) {
+ dataLock.lock();
+ try {
+ if (currentInstant != time) {
+ return;
+ }
+ bitSet.clear(location);
+ }
+ finally {
+ dataLock.unlock();
+ }
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/Constants.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/Constants.java
new file mode 100644
index 00000000..f191b90e
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/Constants.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2023 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package io.appform.ranger.discovery.bundle.id;
+
+import lombok.experimental.UtilityClass;
+
+/**
+ * All constants for this project
+ */
+@UtilityClass
+public class Constants {
+ public static final int MAX_ID_PER_MS = 1000;
+ public static final int MAX_NUM_NODES = 10000;
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/CuratorPathUtils.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/CuratorPathUtils.java
new file mode 100644
index 00000000..806b5f41
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/CuratorPathUtils.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.id;
+
+/**
+ * Utilities for curator
+ */
+public class CuratorPathUtils {
+ private final String processName;
+
+ public CuratorPathUtils(String processName) {
+ this.processName = processName;
+ }
+
+ public String path(int nodeId) {
+ return String.format("/%s/%s/%03d", "id-generator", processName, nodeId);
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/Id.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/Id.java
new file mode 100644
index 00000000..0ef6edc4
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/Id.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.id;
+
+import lombok.*;
+
+import java.util.Date;
+
+/**
+ * A representation of an ID
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+@ToString
+public class Id {
+ private String id;
+ private Date generatedDate;
+ private int node;
+ private int exponent;
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/IdGenerator.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/IdGenerator.java
new file mode 100644
index 00000000..3a0f9dbd
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/IdGenerator.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2016 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.id;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import dev.failsafe.Failsafe;
+import dev.failsafe.FailsafeExecutor;
+import dev.failsafe.RetryPolicy;
+import io.appform.ranger.discovery.bundle.id.constraints.IdValidationConstraint;
+import io.appform.ranger.discovery.bundle.id.formatter.IdFormatter;
+import io.appform.ranger.discovery.bundle.id.formatter.IdFormatters;
+import io.appform.ranger.discovery.bundle.id.request.IdGenerationRequest;
+import lombok.Value;
+import lombok.extern.slf4j.Slf4j;
+import lombok.val;
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+
+import java.security.SecureRandom;
+import java.util.*;
+import java.util.regex.Pattern;
+
+/**
+ * Id generation
+ */
+@SuppressWarnings("unused")
+@Slf4j
+public class IdGenerator {
+
+ private static final int MINIMUM_ID_LENGTH = 22;
+ private static final SecureRandom SECURE_RANDOM = new SecureRandom(Long.toBinaryString(System.currentTimeMillis()).getBytes());
+ private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyMMddHHmmssSSS");
+ private static final CollisionChecker COLLISION_CHECKER = new CollisionChecker();
+ private static final RetryPolicy RETRY_POLICY = RetryPolicy.builder()
+ .withMaxAttempts(readRetryCount())
+ .handleIf(throwable -> true)
+ .handleResultIf(Objects::isNull)
+ .handleResultIf(generationResult -> generationResult.getState() == IdValidationState.INVALID_RETRYABLE)
+ .onRetry(event -> {
+ val res = event.getLastResult();
+ if(null != res && !res.getState().equals(IdValidationState.VALID)) {
+ val id = res.getId();
+ COLLISION_CHECKER.free(id.getGeneratedDate().getTime(), id.getExponent());
+ }
+ })
+ .build();
+ private static final FailsafeExecutor RETRIER
+ = Failsafe.with(Collections.singletonList(RETRY_POLICY));
+ private static final Pattern PATTERN = Pattern.compile("(.*)([0-9]{15})([0-9]{4})([0-9]{3})");
+
+ private static final List GLOBAL_CONSTRAINTS = new ArrayList<>();
+ private static final Map> DOMAIN_SPECIFIC_CONSTRAINTS = new HashMap<>();
+ private static int nodeId;
+
+ public static void initialize(int node) {
+ nodeId = node;
+ }
+
+ public static synchronized void cleanUp() {
+ GLOBAL_CONSTRAINTS.clear();
+ DOMAIN_SPECIFIC_CONSTRAINTS.clear();
+ }
+
+
+ public static synchronized void initialize(
+ int node, List globalConstraints, Map> domainSpecificConstraints) {
+ nodeId = node;
+ if(null != globalConstraints) {
+ IdGenerator.GLOBAL_CONSTRAINTS.addAll(globalConstraints);
+ }
+ if(null != domainSpecificConstraints) {
+ IdGenerator.DOMAIN_SPECIFIC_CONSTRAINTS.putAll(domainSpecificConstraints);
+ }
+ }
+
+ public static synchronized void registerGlobalConstraints(IdValidationConstraint... constraints) {
+ registerGlobalConstraints(ImmutableList.copyOf(constraints));
+ }
+
+ public static synchronized void registerGlobalConstraints(List constraints) {
+ Preconditions.checkArgument(null != constraints && !constraints.isEmpty());
+ GLOBAL_CONSTRAINTS.addAll(constraints);
+ }
+
+ public static synchronized void registerDomainSpecificConstraints(
+ String domain,
+ IdValidationConstraint... validationConstraints) {
+ registerDomainSpecificConstraints(domain, ImmutableList.copyOf(validationConstraints));
+ }
+
+ public static synchronized void registerDomainSpecificConstraints(
+ String domain,
+ List validationConstraints) {
+ Preconditions.checkArgument(null != validationConstraints && !validationConstraints.isEmpty());
+ DOMAIN_SPECIFIC_CONSTRAINTS.computeIfAbsent(domain, key -> new ArrayList<>())
+ .addAll(validationConstraints);
+ }
+
+ /**
+ * Generate id with given prefix
+ *
+ * @param prefix String prefix with will be used to blindly merge
+ * @return Generated Id
+ */
+ public static Id generate(String prefix) {
+ return generate(prefix, IdFormatters.original());
+ }
+
+ public static Id generate(final String prefix,
+ final IdFormatter idFormatter) {
+ val idInfo = random();
+ val dateTime = new DateTime(idInfo.time);
+ val id = String.format("%s%s", prefix, idFormatter.format(dateTime, nodeId, idInfo.exponent));
+ return Id.builder()
+ .id(id)
+ .exponent(idInfo.exponent)
+ .generatedDate(dateTime.toDate())
+ .node(nodeId)
+ .build();
+ }
+
+ /**
+ * Generate id that mathces all passed constraints.
+ * NOTE: There are performance implications for this.
+ * The evaluation of constraints will take it's toll on id generation rates. Tun rests to check speed.
+ *
+ * @param prefix String prefix
+ * @param domain Domain for constraint selection
+ * @return Return generated id or empty if it was impossible to satisfy constraints and generate
+ */
+ public static Optional generateWithConstraints(String prefix, String domain) {
+ return generateWithConstraints(prefix, DOMAIN_SPECIFIC_CONSTRAINTS.getOrDefault(domain, Collections.emptyList()), true);
+ }
+
+ /**
+ * Generate id that mathces all passed constraints.
+ * NOTE: There are performance implications for this.
+ * The evaluation of constraints will take it's toll on id generation rates. Tun rests to check speed.
+ *
+ * @param prefix String prefix
+ * @param domain Domain for constraint selection
+ * @param skipGlobal Skip global constrains and use only passed ones
+ * @return Id if it could be generated
+ */
+ public static Optional generateWithConstraints(String prefix, String domain, boolean skipGlobal) {
+ return generateWithConstraints(prefix, DOMAIN_SPECIFIC_CONSTRAINTS.getOrDefault(domain, Collections.emptyList()), skipGlobal);
+ }
+
+ /**
+ * Generate id that mathces all passed constraints.
+ * NOTE: There are performance implications for this.
+ * The evaluation of constraints will take it's toll on id generation rates. Tun rests to check speed.
+ *
+ * @param prefix String prefix
+ * @param inConstraints Constraints that need to be validated.
+ * @return Id if it could be generated
+ */
+ public static Optional generateWithConstraints(String prefix, final List inConstraints) {
+ return generateWithConstraints(prefix, inConstraints, false);
+ }
+
+ /**
+ * Generate id by parsing given string
+ *
+ * @param idString String idString
+ * @return Id if it could be generated
+ */
+ public static Optional parse(final String idString) {
+ if (idString == null
+ || idString.length() < MINIMUM_ID_LENGTH) {
+ return Optional.empty();
+ }
+ try {
+ val matcher = PATTERN.matcher(idString);
+ if (matcher.find()) {
+ return Optional.of(Id.builder()
+ .id(idString)
+ .node(Integer.parseInt(matcher.group(3)))
+ .exponent(Integer.parseInt(matcher.group(4)))
+ .generatedDate(DATE_TIME_FORMATTER.parseDateTime(matcher.group(2)).toDate())
+ .build());
+ }
+ return Optional.empty();
+ }
+ catch (Exception e) {
+ log.warn("Could not parse idString {}", e.getMessage());
+ return Optional.empty();
+ }
+ }
+
+ /**
+ * Generate id that mathces all passed constraints.
+ * NOTE: There are performance implications for this.
+ * The evaluation of constraints will take it's toll on id generation rates. Tun rests to check speed.
+ *
+ * @param prefix String prefix
+ * @param inConstraints Constraints that need to be validate.
+ * @param skipGlobal Skip global constrains and use only passed ones
+ * @return Id if it could be generated
+ */
+ public static Optional generateWithConstraints(String prefix, final List inConstraints, boolean skipGlobal) {
+ return generate(IdGenerationRequest.builder()
+ .prefix(prefix)
+ .constraints(inConstraints)
+ .skipGlobal(skipGlobal)
+ .idFormatter(IdFormatters.original())
+ .build());
+ }
+
+ public static Optional generate(final IdGenerationRequest request) {
+ return Optional.ofNullable(RETRIER.get(
+ () -> {
+ Id id = generate(request.getPrefix(), request.getIdFormatter());
+ return new GenerationResult(id, validateId(request.getConstraints(), id, request.isSkipGlobal()));
+ }))
+ .filter(generationResult -> generationResult.getState() == IdValidationState.VALID)
+ .map(GenerationResult::getId);
+ }
+
+ private static IdInfo random() {
+ int randomGen;
+ long time;
+ do {
+ time = System.currentTimeMillis();
+ randomGen = SECURE_RANDOM.nextInt(Constants.MAX_ID_PER_MS);
+ } while (!COLLISION_CHECKER.check(time, randomGen));
+ return new IdInfo(randomGen, time);
+ }
+
+ private static IdValidationState validateId(List inConstraints, Id id, boolean skipGlobal) {
+ //First evaluate global constraints
+ val failedGlobalConstraint
+ = skipGlobal
+ ? null
+ : GLOBAL_CONSTRAINTS.stream()
+ .filter(constraint -> !constraint.isValid(id))
+ .findFirst()
+ .orElse(null);
+ if (null != failedGlobalConstraint) {
+ return failedGlobalConstraint.failFast()
+ ? IdValidationState.INVALID_NON_RETRYABLE
+ : IdValidationState.INVALID_RETRYABLE;
+ }
+ //Evaluate local + domain constraints
+ val failedLocalConstraint
+ = null == inConstraints
+ ? null
+ : inConstraints.stream()
+ .filter(constraint -> !constraint.isValid(id))
+ .findFirst()
+ .orElse(null);
+ if (null != failedLocalConstraint) {
+ return failedLocalConstraint.failFast()
+ ? IdValidationState.INVALID_NON_RETRYABLE
+ : IdValidationState.INVALID_RETRYABLE;
+ }
+ return IdValidationState.VALID;
+ }
+
+ private static int readRetryCount() {
+ try {
+ val count = Integer.parseInt(System.getenv().getOrDefault("NUM_ID_GENERATION_RETRIES", "512"));
+ if (count <= 0) {
+ throw new IllegalArgumentException(
+ "Negative number of retries does not make sense. Please set a proper value for " +
+ "NUM_ID_GENERATION_RETRIES");
+ }
+ return count;
+ }
+ catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Please provide a valid positive integer for NUM_ID_GENERATION_RETRIES");
+ }
+ }
+
+ private enum IdValidationState {
+ VALID,
+ INVALID_RETRYABLE,
+ INVALID_NON_RETRYABLE
+ }
+
+ @Value
+ private static class IdInfo {
+ int exponent;
+ long time;
+
+ public IdInfo(int exponent, long time) {
+ this.exponent = exponent;
+ this.time = time;
+ }
+ }
+
+ @Value
+ private static class GenerationResult {
+ Id id;
+ IdValidationState state;
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/NodeIdManager.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/NodeIdManager.java
new file mode 100644
index 00000000..bc865cf9
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/NodeIdManager.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.id;
+
+import com.github.rholder.retry.RetryException;
+import com.github.rholder.retry.RetryerBuilder;
+import com.github.rholder.retry.StopStrategies;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+import lombok.val;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+
+import java.security.SecureRandom;
+import java.util.Objects;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Created by santanu on 2/5/16.
+ */
+@Slf4j
+public class NodeIdManager {
+
+ private final CuratorFramework curatorFramework;
+ private final SecureRandom secureRandom;
+ private final CuratorPathUtils pathUtils;
+
+ @Getter
+ private int node;
+
+ public NodeIdManager(CuratorFramework curatorFramework, String processName) {
+ this.curatorFramework = curatorFramework;
+ this.secureRandom = new SecureRandom(Long.toBinaryString(System.currentTimeMillis()).getBytes());
+ this.pathUtils = new CuratorPathUtils(processName);
+ }
+
+ public int fixNodeId() {
+ try {
+ log.info("Waiting for curator to start");
+ curatorFramework.blockUntilConnected();
+ log.info("Curator started");
+ } catch (InterruptedException e) {
+ log.error("Wait for curator start interrupted", e);
+ Thread.currentThread().interrupt();
+ }
+ val retryer = RetryerBuilder.newBuilder()
+ .retryIfResult(aBoolean -> Objects.equals(aBoolean, false))
+ .retryIfException()
+ .withStopStrategy(StopStrategies.neverStop())
+ .build();
+ try {
+ retryer.call(() -> {
+ node = secureRandom.nextInt(Constants.MAX_NUM_NODES);
+ val path = pathUtils.path(node);
+ try {
+ curatorFramework.create()
+ .creatingParentContainersIfNeeded()
+ .withMode(CreateMode.EPHEMERAL)
+ .forPath(path);
+ } catch (KeeperException.NodeExistsException e) {
+ log.warn("Collision on node {}, will retry with new node.", node);
+ return false;
+ }
+ log.info("Node will be set to node id {}", node);
+ return true;
+ });
+ } catch (RetryException e) {
+ log.error("Error creating node", e);
+ } catch (ExecutionException e) {
+ log.error("Execution exception while creating node", e);
+ }
+ return node;
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/constraints/IdValidationConstraint.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/constraints/IdValidationConstraint.java
new file mode 100644
index 00000000..eb43a6ed
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/constraints/IdValidationConstraint.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.id.constraints;
+
+
+import io.appform.ranger.discovery.bundle.id.Id;
+
+/**
+ *
+ */
+public interface IdValidationConstraint {
+
+ boolean isValid(Id id);
+
+ default boolean failFast() {
+ return false;
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/constraints/impl/JavaHashCodeBasedKeyPartitioner.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/constraints/impl/JavaHashCodeBasedKeyPartitioner.java
new file mode 100644
index 00000000..65bcee36
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/constraints/impl/JavaHashCodeBasedKeyPartitioner.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.id.constraints.impl;
+
+
+import io.appform.ranger.discovery.bundle.id.Id;
+
+/**
+ *
+ */
+public class JavaHashCodeBasedKeyPartitioner implements KeyPartitioner {
+
+ private final int maxPartitions;
+
+ public JavaHashCodeBasedKeyPartitioner(int maxPartitions) {
+ this.maxPartitions = maxPartitions;
+ }
+
+ @Override
+ public int partition(Id id) {
+ var hashCode = id.getId().hashCode();
+ hashCode *= hashCode < 0 ? -1 : 1;
+ return hashCode % maxPartitions;
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/constraints/impl/KeyPartitioner.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/constraints/impl/KeyPartitioner.java
new file mode 100644
index 00000000..87eee3b7
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/constraints/impl/KeyPartitioner.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.id.constraints.impl;
+
+
+import io.appform.ranger.discovery.bundle.id.Id;
+
+/**
+ * Takes an id and generates a partition
+ */
+@FunctionalInterface
+public interface KeyPartitioner {
+ int partition(Id id);
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/constraints/impl/MurmurBasedKeyPartitioner.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/constraints/impl/MurmurBasedKeyPartitioner.java
new file mode 100644
index 00000000..f4b3d488
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/constraints/impl/MurmurBasedKeyPartitioner.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.id.constraints.impl;
+
+import com.google.common.hash.Hashing;
+import io.appform.ranger.discovery.bundle.id.Id;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ *
+ */
+@SuppressWarnings("unused")
+public class MurmurBasedKeyPartitioner implements KeyPartitioner {
+
+ private final int maxPartitions;
+
+ public MurmurBasedKeyPartitioner(int maxPartitions) {
+ this.maxPartitions = maxPartitions;
+ }
+
+ @Override
+ @SuppressWarnings("UnstableApiUsage")
+ public int partition(Id id) {
+ int hashCode = Hashing.murmur3_128().hashString(id.toString(), StandardCharsets.UTF_8).asInt();
+ hashCode *= hashCode < 0 ? -1 : 1;
+ return hashCode % maxPartitions;
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/constraints/impl/PartitionValidator.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/constraints/impl/PartitionValidator.java
new file mode 100644
index 00000000..474c2404
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/constraints/impl/PartitionValidator.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2018 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.id.constraints.impl;
+
+import com.google.common.base.Preconditions;
+import io.appform.ranger.discovery.bundle.id.Id;
+import io.appform.ranger.discovery.bundle.id.constraints.IdValidationConstraint;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Checks if key is same partition as provided.
+ */
+@Slf4j
+public class PartitionValidator implements IdValidationConstraint {
+
+ private final int partition;
+ private final KeyPartitioner partitioner;
+
+ public PartitionValidator(int partition, KeyPartitioner partitioner) {
+ Preconditions.checkArgument(partition > 0,
+ "Provide a non-negative and non-zero partition count");
+ Preconditions.checkArgument(partitioner != null,
+ "Provide a non null key partitioner");
+ this.partition = partition;
+ this.partitioner = partitioner;
+ }
+
+ @Override
+ public boolean isValid(Id id) {
+ return partition == partitioner.partition(id);
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/Base36IdFormatter.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/Base36IdFormatter.java
new file mode 100644
index 00000000..1af19d86
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/Base36IdFormatter.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2023 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package io.appform.ranger.discovery.bundle.id.formatter;
+
+import org.joda.time.DateTime;
+
+import java.math.BigInteger;
+
+public class Base36IdFormatter implements IdFormatter {
+
+ private final IdFormatter idFormatter;
+
+ public Base36IdFormatter(IdFormatter idFormatter) {
+ this.idFormatter = idFormatter;
+ }
+
+ @Override
+ public String format(final DateTime dateTime,
+ final int nodeId,
+ final int randomNonce) {
+ return toBase36(idFormatter.format(dateTime, nodeId, randomNonce));
+ }
+
+ private static String toBase36(final String payload) {
+ return new BigInteger(payload).toString(36).toUpperCase();
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java
new file mode 100644
index 00000000..7bd27c6a
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2023 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package io.appform.ranger.discovery.bundle.id.formatter;
+
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+
+public class DefaultIdFormatter implements IdFormatter {
+
+ private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyMMddHHmmssSSS");
+
+ @Override
+ public String format(final DateTime dateTime,
+ final int nodeId,
+ final int randomNonce) {
+ return String.format("%s%04d%03d", DATE_TIME_FORMATTER.print(dateTime), nodeId, randomNonce);
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatter.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatter.java
new file mode 100644
index 00000000..6a38f073
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatter.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2023 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package io.appform.ranger.discovery.bundle.id.formatter;
+
+import org.joda.time.DateTime;
+
+public interface IdFormatter {
+
+ String format(final DateTime dateTime,
+ final int nodeId,
+ final int randomNonce);
+
+
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatters.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatters.java
new file mode 100644
index 00000000..30bca972
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatters.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2023 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package io.appform.ranger.discovery.bundle.id.formatter;
+
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+public class IdFormatters {
+
+ private static final IdFormatter originalIdFormatter = new DefaultIdFormatter();
+ private static final IdFormatter base36IdFormatter = new Base36IdFormatter(originalIdFormatter);
+
+ public static IdFormatter original() {
+ return originalIdFormatter;
+ }
+
+ public static IdFormatter base36() {
+ return base36IdFormatter;
+ }
+
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/request/IdGenerationRequest.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/request/IdGenerationRequest.java
new file mode 100644
index 00000000..444ccfa2
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/request/IdGenerationRequest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package io.appform.ranger.discovery.bundle.id.request;
+
+import io.appform.ranger.discovery.bundle.id.constraints.IdValidationConstraint;
+import io.appform.ranger.discovery.bundle.id.formatter.IdFormatter;
+import lombok.Builder;
+import lombok.Value;
+
+import java.util.List;
+
+@Value
+@Builder
+public class IdGenerationRequest {
+
+ String prefix;
+ String domain;
+ boolean skipGlobal;
+ List constraints;
+ IdFormatter idFormatter;
+
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/monitors/DropwizardHealthMonitor.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/monitors/DropwizardHealthMonitor.java
new file mode 100644
index 00000000..af6a4c45
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/monitors/DropwizardHealthMonitor.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2019 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.monitors;
+
+import com.codahale.metrics.health.HealthCheck;
+import io.appform.ranger.core.healthcheck.HealthcheckStatus;
+import io.appform.ranger.core.healthservice.TimeEntity;
+import io.appform.ranger.core.healthservice.monitor.IsolatedHealthMonitor;
+import io.dropwizard.setup.Environment;
+
+/**
+ * This monitor calls dropwizard healthchecks every few secs.
+ */
+public class DropwizardHealthMonitor extends IsolatedHealthMonitor {
+
+ private final Environment environment;
+
+ public DropwizardHealthMonitor(
+ TimeEntity runInterval,
+ long stalenessAllowedInMillis,
+ Environment environment) {
+ super("dropwizard-health-monitor", runInterval, stalenessAllowedInMillis);
+ this.environment = environment;
+ }
+
+ @Override
+ public HealthcheckStatus monitor() {
+ return (null != environment.healthChecks()
+ && environment.healthChecks()
+ .runHealthChecks()
+ .values()
+ .stream()
+ .allMatch(HealthCheck.Result::isHealthy))
+ ? HealthcheckStatus.healthy
+ : HealthcheckStatus.unhealthy;
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/monitors/DropwizardServerStartupCheck.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/monitors/DropwizardServerStartupCheck.java
new file mode 100644
index 00000000..94e4156d
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/monitors/DropwizardServerStartupCheck.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2019 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.monitors;
+
+import io.appform.ranger.core.healthcheck.Healthcheck;
+import io.appform.ranger.core.healthcheck.HealthcheckStatus;
+import io.appform.ranger.discovery.bundle.rotationstatus.DropwizardServerStatus;
+import io.dropwizard.setup.Environment;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * This healthcheck listens to server started event to mark service healthy on ranger.
+ */
+@Slf4j
+public class DropwizardServerStartupCheck implements Healthcheck {
+
+ private final DropwizardServerStatus serverStatus;
+
+ public DropwizardServerStartupCheck(Environment environment,
+ DropwizardServerStatus serverStatus) {
+ this.serverStatus = serverStatus;
+ environment.lifecycle().addServerLifecycleListener(server -> {
+ log.info("Dropwizard server started. Marking healthcheck as healthy");
+ serverStatus.markStarted();
+ });
+ }
+
+ @Override
+ public HealthcheckStatus check() {
+ return serverStatus.started() ? HealthcheckStatus.healthy : HealthcheckStatus.unhealthy;
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/resolvers/CriteriaResolver.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/resolvers/CriteriaResolver.java
new file mode 100644
index 00000000..32637445
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/resolvers/CriteriaResolver.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2023 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package io.appform.ranger.discovery.bundle.resolvers;
+
+/**
+ * CriteriaResolver.java
+ * Interface to help resolve from an argument A to the typed object T.
+ * Keeping this as the qualified class instead of using Function so that in the future if all criteria resolvers were to
+ * be fetched to register using reflections et. al, there is a qualified naming.
+ */
+@FunctionalInterface
+public interface CriteriaResolver {
+
+ T resolve(A args);
+
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/resolvers/DefaultNodeInfoResolver.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/resolvers/DefaultNodeInfoResolver.java
new file mode 100644
index 00000000..c75bbdff
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/resolvers/DefaultNodeInfoResolver.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2023 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package io.appform.ranger.discovery.bundle.resolvers;
+
+import io.appform.ranger.common.server.ShardInfo;
+import io.appform.ranger.discovery.bundle.ServiceDiscoveryConfiguration;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import lombok.val;
+
+
+@NoArgsConstructor
+@Slf4j
+public class DefaultNodeInfoResolver implements NodeInfoResolver {
+
+ private static final String FARM_ID = "FARM_ID";
+
+ @Override
+ public ShardInfo resolve(ServiceDiscoveryConfiguration configuration) {
+ val region = System.getenv(FARM_ID);
+ log.debug("The region received from the env variable FARM_ID is {}. Setting the same in nodeInfo", region);
+ return ShardInfo.builder()
+ .environment(configuration.getEnvironment())
+ .region(region)
+ .tags(configuration.getTags())
+ .build();
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/resolvers/DefaultPortSchemeResolver.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/resolvers/DefaultPortSchemeResolver.java
new file mode 100644
index 00000000..74185e28
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/resolvers/DefaultPortSchemeResolver.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2023 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package io.appform.ranger.discovery.bundle.resolvers;
+
+import io.appform.ranger.core.model.PortSchemes;
+import io.dropwizard.Configuration;
+import io.dropwizard.jetty.ConnectorFactory;
+import io.dropwizard.jetty.HttpsConnectorFactory;
+import io.dropwizard.server.DefaultServerFactory;
+import io.dropwizard.server.ServerFactory;
+import io.dropwizard.server.SimpleServerFactory;
+import lombok.val;
+
+import java.util.Optional;
+
+/**
+ * DefaultPortSchemeResolver.java
+ * To derive PortScheme from the ServerFactory from Dropwizard startup config
+ */
+public class DefaultPortSchemeResolver implements PortSchemeResolver {
+
+ /**
+ * Returns a PortScheme basis the configuration. The default in case of a new
+ * Connector found (Possibly on version upgrades, if we have forgotten mutate it,
+ * is HTTP)
+ *
+ * @param configuration {@link Configuration} the dropwizard startup config
+ * @return {@link String} The relevant portScheme with HTTP as default
+ */
+ @Override
+ public String resolve(T configuration) {
+ val connectionFactory = getConnectorFactory(configuration.getServerFactory());
+ return connectionFactory.filter(HttpsConnectorFactory.class::isInstance)
+ .map(factory -> PortSchemes.HTTPS)
+ .orElse(PortSchemes.HTTP);
+ }
+
+ private Optional getConnectorFactory(ServerFactory serverFactory) {
+ if (serverFactory instanceof DefaultServerFactory) {
+ val defaultFactory = (DefaultServerFactory) serverFactory;
+ return defaultFactory.getApplicationConnectors()
+ .stream()
+ .findFirst();
+ } else if (serverFactory instanceof SimpleServerFactory) {
+ val defaultFactory = (SimpleServerFactory) serverFactory;
+ return Optional.ofNullable(defaultFactory.getConnector());
+ } else {
+ return Optional.empty();
+ }
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/resolvers/NodeInfoResolver.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/resolvers/NodeInfoResolver.java
new file mode 100644
index 00000000..04504735
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/resolvers/NodeInfoResolver.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2023 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package io.appform.ranger.discovery.bundle.resolvers;
+
+import io.appform.ranger.common.server.ShardInfo;
+import io.appform.ranger.discovery.bundle.ServiceDiscoveryBundle;
+import io.appform.ranger.discovery.bundle.ServiceDiscoveryConfiguration;
+
+/**
+ * NodeInfoResolver.java
+ * Interface to help build a node to be saved in the discovery backend while building the serviceProvider.
+ * To define your custom nodeData {@link ShardInfo}, please define your own implementation, during the bundle {@link
+ * ServiceDiscoveryBundle} init.
+ */
+@FunctionalInterface
+public interface NodeInfoResolver extends CriteriaResolver {
+
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/resolvers/PortSchemeResolver.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/resolvers/PortSchemeResolver.java
new file mode 100644
index 00000000..4c772e38
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/resolvers/PortSchemeResolver.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2023 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package io.appform.ranger.discovery.bundle.resolvers;
+
+import io.dropwizard.Configuration;
+
+/**
+ * NodeInfoResolver.java
+ * Interface to help build a portScheme basis the server {@link Configuration}
+ */
+@FunctionalInterface
+public interface PortSchemeResolver extends CriteriaResolver {
+
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/rotationstatus/BIRTask.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/rotationstatus/BIRTask.java
new file mode 100644
index 00000000..086d8be1
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/rotationstatus/BIRTask.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.rotationstatus;
+
+
+import io.dropwizard.servlets.tasks.Task;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Admin task to take node bir in ranger
+ */
+@Slf4j
+public class BIRTask extends Task {
+ private final RotationStatus rotationStatus;
+ public BIRTask(RotationStatus rotationStatus) {
+ super("ranger-bir");
+ this.rotationStatus = rotationStatus;
+ }
+
+ @Override
+ public void execute(Map> map, PrintWriter printWriter) {
+ rotationStatus.bir();
+ log.info("Taking node back into rotation on ranger");
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/rotationstatus/DropwizardServerStatus.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/rotationstatus/DropwizardServerStatus.java
new file mode 100644
index 00000000..77de15ea
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/rotationstatus/DropwizardServerStatus.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.rotationstatus;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Current server startup started
+ */
+@SuppressWarnings("unused")
+public class DropwizardServerStatus {
+
+ private final AtomicBoolean serverStarted;
+
+ public DropwizardServerStatus(boolean initialStatus) {
+ serverStarted = new AtomicBoolean(initialStatus);
+ }
+
+ public void markStarted() {
+ serverStarted.set(true);
+ }
+
+ public void markStopped() {
+ serverStarted.set(false);
+ }
+
+ public boolean started() {
+ return serverStarted.get();
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/rotationstatus/OORTask.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/rotationstatus/OORTask.java
new file mode 100644
index 00000000..b4d1984b
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/rotationstatus/OORTask.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.rotationstatus;
+
+import io.dropwizard.servlets.tasks.Task;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Admin task to take node oor in ranger
+ */
+@Slf4j
+public class OORTask extends Task {
+ private final RotationStatus rotationStatus;
+ public OORTask(RotationStatus rotationStatus) {
+ super("ranger-oor");
+ this.rotationStatus = rotationStatus;
+ }
+
+ @Override
+ public void execute(Map> map, PrintWriter printWriter) {
+ rotationStatus.oor();
+ log.info("Taking node out of rotation on ranger");
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/rotationstatus/RotationStatus.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/rotationstatus/RotationStatus.java
new file mode 100644
index 00000000..369c1bcb
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/rotationstatus/RotationStatus.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.rotationstatus;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Current rotation status
+ */
+public class RotationStatus {
+ private final AtomicBoolean inRotation;
+
+ public RotationStatus(boolean initialStatus) {
+ inRotation = new AtomicBoolean(initialStatus);
+ }
+
+ public void oor() {
+ inRotation.set(false);
+ }
+
+ public void bir() {
+ inRotation.set(true);
+ }
+
+ public boolean status() {
+ return inRotation.get();
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/selectors/HierarchicalEnvironmentAwareShardSelector.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/selectors/HierarchicalEnvironmentAwareShardSelector.java
new file mode 100644
index 00000000..c3f442d3
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/selectors/HierarchicalEnvironmentAwareShardSelector.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2022 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.selectors;
+
+import com.google.common.base.Strings;
+import io.appform.ranger.common.server.ShardInfo;
+import io.appform.ranger.core.finder.serviceregistry.MapBasedServiceRegistry;
+import io.appform.ranger.core.model.ServiceNode;
+import io.appform.ranger.core.model.ShardSelector;
+import lombok.extern.slf4j.Slf4j;
+import lombok.val;
+
+import java.util.*;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ *
+ */
+@Slf4j
+public class HierarchicalEnvironmentAwareShardSelector implements ShardSelector> {
+ private static final String DEFAULT_SEPARATOR = ".";
+ private static final Predicate DEFAULT_PREDICATE = shardInfo -> true;
+
+ private final String environment;
+ private final String separator;
+
+ public HierarchicalEnvironmentAwareShardSelector(String environment) {
+ this(environment, DEFAULT_SEPARATOR);
+ }
+
+ public HierarchicalEnvironmentAwareShardSelector(String environment, String separator) {
+ this.environment = environment;
+ this.separator = separator;
+ }
+
+ @Override
+ public List> nodes(
+ Predicate criteria, MapBasedServiceRegistry serviceRegistry) {
+ val serviceNodes = serviceRegistry.nodes();
+ val serviceName = serviceRegistry.getService().getServiceName();
+ val evalPredicate = null != criteria
+ ? criteria
+ : DEFAULT_PREDICATE;
+ for (val env : new IterableEnvironment(environment, separator)) {
+ val eligibleNodes = serviceNodes.entries()
+ .stream()
+ .filter(e -> e.getKey().getEnvironment().equals(env.environment) && evalPredicate.test(e.getKey()))
+ .map(Map.Entry::getValue)
+ .collect(Collectors.toList());
+ if (!eligibleNodes.isEmpty()) {
+ log.debug("Effective environment for discovery of {} is {}", serviceName, env.environment);
+ return eligibleNodes;
+ }
+ log.trace("No nodes found for environment: {}", env.environment);
+ }
+ log.warn("No valid nodes could be found for environment: {}", environment);
+ return Collections.emptyList();
+ }
+
+ private static final class IterableEnvironment implements Iterable {
+ private final String environment;
+ private final String separator;
+
+ private IterableEnvironment(String environment, String separator) {
+ this.environment = environment;
+ this.separator = separator;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return new EnvironmentIterator(environment, separator);
+ }
+
+ public static final class EnvironmentIterator implements Iterator {
+
+ private String remainingEnvironment;
+ private final String separator;
+
+ public EnvironmentIterator(String remainingEnvironment, String separator) {
+ this.remainingEnvironment = remainingEnvironment;
+ this.separator = separator;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return !Strings.isNullOrEmpty(remainingEnvironment);
+ }
+
+ @Override
+ public IterableEnvironment next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ log.debug("Effective environment for discovery is {}", remainingEnvironment);
+ val shardInfo = new IterableEnvironment(remainingEnvironment, separator);
+ val sepIndex = remainingEnvironment.indexOf(this.separator);
+ remainingEnvironment = sepIndex < 0
+ ? ""
+ : remainingEnvironment.substring(0, sepIndex);
+ return shardInfo;
+ }
+ }
+ }
+}
diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/util/ConfigurationUtils.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/util/ConfigurationUtils.java
new file mode 100644
index 00000000..ad1ca77b
--- /dev/null
+++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/util/ConfigurationUtils.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2023 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package io.appform.ranger.discovery.bundle.util;
+
+import com.google.common.base.Strings;
+import io.appform.ranger.discovery.bundle.Constants;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static io.appform.ranger.discovery.bundle.Constants.*;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class ConfigurationUtils {
+
+ public static String resolveNonEmptyPublishedHost(String publishedHost) throws UnknownHostException {
+ if (Strings.isNullOrEmpty(publishedHost) || publishedHost.equals(Constants.DEFAULT_HOST)) {
+ return InetAddress.getLocalHost()
+ .getCanonicalHostName();
+ }
+ return publishedHost;
+ }
+
+ public static Set resolveZookeeperHosts(String zkHostString) {
+ return Arrays.stream(zkHostString.split(ZOOKEEPER_HOST_DELIMITER))
+ .map(zkHostPort -> zkHostPort.split(HOST_PORT_DELIMITER)[0])
+ .map(zkHostPath -> zkHostPath.split(PATH_DELIMITER)[0])
+ .collect(Collectors.toSet());
+ }
+
+}
diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleCustomHostPortTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleCustomHostPortTest.java
new file mode 100644
index 00000000..12c2b9d3
--- /dev/null
+++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleCustomHostPortTest.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2016 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.health.HealthCheckRegistry;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Lists;
+import io.appform.ranger.core.healthcheck.HealthcheckStatus;
+import io.dropwizard.Configuration;
+import io.dropwizard.jersey.DropwizardResourceConfig;
+import io.dropwizard.jersey.setup.JerseyEnvironment;
+import io.dropwizard.jetty.ConnectorFactory;
+import io.dropwizard.jetty.HttpConnectorFactory;
+import io.dropwizard.lifecycle.setup.LifecycleEnvironment;
+import io.dropwizard.server.DefaultServerFactory;
+import io.dropwizard.setup.AdminEnvironment;
+import io.dropwizard.setup.Bootstrap;
+import io.dropwizard.setup.Environment;
+import lombok.extern.slf4j.Slf4j;
+import lombok.val;
+import org.apache.curator.test.TestingCluster;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.slf4j.LoggerFactory;
+
+import static io.appform.ranger.discovery.bundle.TestUtils.assertNodeAbsence;
+import static io.appform.ranger.discovery.bundle.TestUtils.assertNodePresence;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+
+@Slf4j
+class ServiceDiscoveryBundleCustomHostPortTest {
+
+ static {
+ val root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+ root.setLevel(Level.INFO);
+ }
+
+ private final HealthCheckRegistry healthChecks = mock(HealthCheckRegistry.class);
+ private final JerseyEnvironment jerseyEnvironment = mock(JerseyEnvironment.class);
+ private final MetricRegistry metricRegistry = mock(MetricRegistry.class);
+ private final LifecycleEnvironment lifecycleEnvironment = new LifecycleEnvironment(metricRegistry);
+ private final Environment environment = mock(Environment.class);
+ private final Bootstrap> bootstrap = mock(Bootstrap.class);
+ private final Configuration configuration = mock(Configuration.class);
+ private final DefaultServerFactory serverFactory = mock(DefaultServerFactory.class);
+ private final ConnectorFactory connectorFactory = mock(HttpConnectorFactory.class);
+ private final TestingCluster testingCluster = new TestingCluster(1);
+ private ServiceDiscoveryConfiguration serviceDiscoveryConfiguration;
+ private final ServiceDiscoveryBundle bundle = new ServiceDiscoveryBundle() {
+ @Override
+ protected ServiceDiscoveryConfiguration getRangerConfiguration(Configuration configuration) {
+ return serviceDiscoveryConfiguration;
+ }
+
+ @Override
+ protected String getServiceName(Configuration configuration) {
+ return "TestService";
+ }
+
+ @Override
+ protected int getPort(Configuration configuration) {
+ return 21000;
+ }
+
+ @Override
+ protected String getHost() {
+ return "CustomHost";
+ }
+
+ };
+ private HealthcheckStatus status = HealthcheckStatus.healthy;
+
+ @BeforeEach
+ void setup() throws Exception {
+ when(serverFactory.getApplicationConnectors()).thenReturn(Lists.newArrayList(connectorFactory));
+ when(configuration.getServerFactory()).thenReturn(serverFactory);
+ when(jerseyEnvironment.getResourceConfig()).thenReturn(new DropwizardResourceConfig());
+ when(environment.jersey()).thenReturn(jerseyEnvironment);
+ when(environment.lifecycle()).thenReturn(lifecycleEnvironment);
+ when(environment.healthChecks()).thenReturn(healthChecks);
+ when(environment.getObjectMapper()).thenReturn(new ObjectMapper());
+ AdminEnvironment adminEnvironment = mock(AdminEnvironment.class);
+ doNothing().when(adminEnvironment)
+ .addTask(any());
+ when(environment.admin()).thenReturn(adminEnvironment);
+
+ testingCluster.start();
+
+ serviceDiscoveryConfiguration = ServiceDiscoveryConfiguration.builder()
+ .zookeeper(testingCluster.getConnectString())
+ .namespace("test")
+ .environment("testing")
+ .connectionRetryIntervalMillis(5000)
+ .publishedHost("TestHost")
+ .publishedPort(8021)
+ .initialRotationStatus(true)
+ .build();
+ bundle.initialize(bootstrap);
+ bundle.run(configuration, environment);
+ bundle.getServerStatus()
+ .markStarted();
+ for (LifeCycle lifeCycle : lifecycleEnvironment.getManagedObjects()) {
+ lifeCycle.start();
+ }
+ bundle.registerHealthcheck(() -> status);
+
+ }
+
+ @AfterEach
+ void tearDown() throws Exception {
+ for (LifeCycle lifeCycle : lifecycleEnvironment.getManagedObjects()) {
+ lifeCycle.stop();
+ }
+ testingCluster.stop();
+ }
+
+ @Test
+ void testDiscovery() {
+ assertNodePresence(bundle);
+ val info = bundle.getServiceDiscoveryClient()
+ .getNode()
+ .orElse(null);
+
+ Assertions.assertNotNull(info);
+ Assertions.assertNotNull(info.getNodeData());
+ Assertions.assertEquals("testing", info.getNodeData()
+ .getEnvironment());
+ Assertions.assertEquals("CustomHost", info.getHost());
+ Assertions.assertEquals(21000, info.getPort());
+ status = HealthcheckStatus.unhealthy;
+
+ assertNodeAbsence(bundle);
+ }
+}
\ No newline at end of file
diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleDwMonitorTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleDwMonitorTest.java
new file mode 100644
index 00000000..80bf6ab8
--- /dev/null
+++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleDwMonitorTest.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2016 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.health.HealthCheck;
+import com.codahale.metrics.health.HealthCheckRegistry;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Lists;
+import io.appform.ranger.core.healthcheck.HealthcheckStatus;
+import io.dropwizard.Configuration;
+import io.dropwizard.jersey.DropwizardResourceConfig;
+import io.dropwizard.jersey.setup.JerseyEnvironment;
+import io.dropwizard.jetty.ConnectorFactory;
+import io.dropwizard.jetty.HttpConnectorFactory;
+import io.dropwizard.lifecycle.setup.LifecycleEnvironment;
+import io.dropwizard.server.DefaultServerFactory;
+import io.dropwizard.setup.AdminEnvironment;
+import io.dropwizard.setup.Bootstrap;
+import io.dropwizard.setup.Environment;
+import lombok.extern.slf4j.Slf4j;
+import lombok.val;
+import org.apache.curator.test.TestingCluster;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static io.appform.ranger.discovery.bundle.TestUtils.assertNodeAbsence;
+import static io.appform.ranger.discovery.bundle.TestUtils.assertNodePresence;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+
+@Slf4j
+class ServiceDiscoveryBundleDwMonitorTest {
+
+ static {
+ val root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+ root.setLevel(Level.INFO);
+ }
+
+ private final HealthCheckRegistry healthChecks = new HealthCheckRegistry();
+ private final JerseyEnvironment jerseyEnvironment = mock(JerseyEnvironment.class);
+ private final MetricRegistry metricRegistry = mock(MetricRegistry.class);
+ private final LifecycleEnvironment lifecycleEnvironment = new LifecycleEnvironment(metricRegistry);
+ private final Environment environment = mock(Environment.class);
+ private final Bootstrap> bootstrap = mock(Bootstrap.class);
+ private final Configuration configuration = mock(Configuration.class);
+ private final DefaultServerFactory serverFactory = mock(DefaultServerFactory.class);
+ private final ConnectorFactory connectorFactory = mock(HttpConnectorFactory.class);
+ private final TestingCluster testingCluster = new TestingCluster(1);
+ private final HealthcheckStatus status = HealthcheckStatus.healthy;
+ private ServiceDiscoveryConfiguration serviceDiscoveryConfiguration;
+ private final ServiceDiscoveryBundle bundle = new ServiceDiscoveryBundle() {
+ @Override
+ protected ServiceDiscoveryConfiguration getRangerConfiguration(Configuration configuration) {
+ return serviceDiscoveryConfiguration;
+ }
+
+ @Override
+ protected String getServiceName(Configuration configuration) {
+ return "TestService";
+ }
+
+ @Override
+ protected int getPort(Configuration configuration) {
+ return 21000;
+ }
+
+ @Override
+ protected String getHost() {
+ return "CustomHost";
+ }
+
+ };
+
+ @BeforeEach
+ void setup() throws Exception {
+ healthChecks.register("twice-healthy-only", new HealthCheck() {
+ private final AtomicInteger counter = new AtomicInteger(5);
+
+ @Override
+ protected Result check() {
+ val result = (counter.decrementAndGet() < 0)
+ ? Result.unhealthy("unhealthy")
+ : Result.healthy();
+ log.info("Marking node as {}", result.isHealthy());
+ return result;
+ }
+ });
+
+ when(serverFactory.getApplicationConnectors()).thenReturn(Lists.newArrayList(connectorFactory));
+ when(configuration.getServerFactory()).thenReturn(serverFactory);
+ when(jerseyEnvironment.getResourceConfig()).thenReturn(new DropwizardResourceConfig());
+ when(environment.jersey()).thenReturn(jerseyEnvironment);
+ when(environment.lifecycle()).thenReturn(lifecycleEnvironment);
+ when(environment.healthChecks()).thenReturn(healthChecks);
+ when(environment.getObjectMapper()).thenReturn(new ObjectMapper());
+ AdminEnvironment adminEnvironment = mock(AdminEnvironment.class);
+ doNothing().when(adminEnvironment)
+ .addTask(any());
+ when(environment.admin()).thenReturn(adminEnvironment);
+
+ testingCluster.start();
+
+ serviceDiscoveryConfiguration = ServiceDiscoveryConfiguration.builder()
+ .zookeeper(testingCluster.getConnectString())
+ .namespace("test")
+ .environment("testing")
+ .connectionRetryIntervalMillis(5000)
+ .publishedHost("TestHost")
+ .publishedPort(8021)
+ .initialRotationStatus(true)
+ .dropwizardCheckInterval(2)
+ .dropwizardCheckStaleness(2)
+ .build();
+ bundle.initialize(bootstrap);
+ bundle.run(configuration, environment);
+ bundle.getServerStatus()
+ .markStarted();
+ for (LifeCycle lifeCycle : lifecycleEnvironment.getManagedObjects()) {
+ lifeCycle.start();
+ }
+ bundle.registerHealthcheck(() -> status);
+ }
+
+ @AfterEach
+ void tearDown() throws Exception {
+ for (LifeCycle lifeCycle : lifecycleEnvironment.getManagedObjects()) {
+ lifeCycle.stop();
+ }
+ testingCluster.stop();
+ }
+
+ @Test
+ void testDiscovery() {
+ assertNodePresence(bundle);
+ val info = bundle.getServiceDiscoveryClient()
+ .getNode()
+ .orElse(null);
+ Assertions.assertNotNull(info);
+ Assertions.assertNotNull(info.getNodeData());
+ Assertions.assertEquals("testing", info.getNodeData()
+ .getEnvironment());
+ Assertions.assertEquals("CustomHost", info.getHost());
+ Assertions.assertEquals(21000, info.getPort());
+
+ /* after 5 turns, the healthcheck will return unhealthy, and since dropwizardCheckInterval
+ is 5 seconds, within 2*5=10 seconds, nodes should be absent */
+ assertNodeAbsence(bundle);
+ }
+}
\ No newline at end of file
diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleDwStalenessMonitorTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleDwStalenessMonitorTest.java
new file mode 100644
index 00000000..64d4d1ad
--- /dev/null
+++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleDwStalenessMonitorTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2016 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.health.HealthCheck;
+import com.codahale.metrics.health.HealthCheckRegistry;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Lists;
+import io.appform.ranger.core.healthcheck.HealthcheckStatus;
+import io.dropwizard.Configuration;
+import io.dropwizard.jersey.DropwizardResourceConfig;
+import io.dropwizard.jersey.setup.JerseyEnvironment;
+import io.dropwizard.jetty.ConnectorFactory;
+import io.dropwizard.jetty.HttpConnectorFactory;
+import io.dropwizard.lifecycle.setup.LifecycleEnvironment;
+import io.dropwizard.server.DefaultServerFactory;
+import io.dropwizard.setup.AdminEnvironment;
+import io.dropwizard.setup.Bootstrap;
+import io.dropwizard.setup.Environment;
+import lombok.extern.slf4j.Slf4j;
+import lombok.val;
+import org.apache.curator.test.TestingCluster;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static io.appform.ranger.discovery.bundle.TestUtils.assertNodeAbsence;
+import static io.appform.ranger.discovery.bundle.TestUtils.assertNodePresence;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+
+@Slf4j
+class ServiceDiscoveryBundleDwStalenessMonitorTest {
+
+ static {
+ val root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+ root.setLevel(Level.INFO);
+ }
+
+ private final HealthCheckRegistry healthChecks = new HealthCheckRegistry();
+ private final JerseyEnvironment jerseyEnvironment = mock(JerseyEnvironment.class);
+ private final MetricRegistry metricRegistry = mock(MetricRegistry.class);
+ private final LifecycleEnvironment lifecycleEnvironment = new LifecycleEnvironment(metricRegistry);
+ private final Environment environment = mock(Environment.class);
+ private final Bootstrap> bootstrap = mock(Bootstrap.class);
+ private final Configuration configuration = mock(Configuration.class);
+ private final DefaultServerFactory serverFactory = mock(DefaultServerFactory.class);
+ private final ConnectorFactory connectorFactory = mock(HttpConnectorFactory.class);
+ private final TestingCluster testingCluster = new TestingCluster(1);
+ private final AtomicBoolean healthySucceeded = new AtomicBoolean(false);
+ private ServiceDiscoveryConfiguration serviceDiscoveryConfiguration;
+ private final ServiceDiscoveryBundle bundle = new ServiceDiscoveryBundle() {
+ @Override
+ protected ServiceDiscoveryConfiguration getRangerConfiguration(Configuration configuration) {
+ return serviceDiscoveryConfiguration;
+ }
+
+ @Override
+ protected String getServiceName(Configuration configuration) {
+ return "TestService";
+ }
+
+ @Override
+ protected int getPort(Configuration configuration) {
+ return 21000;
+ }
+
+ @Override
+ protected String getHost() {
+ return "CustomHost";
+ }
+
+ };
+
+ @BeforeEach
+ void setup() throws Exception {
+ healthChecks.register("healthy-once-but-then-sleep5", new HealthCheck() {
+
+ @Override
+ protected Result check() {
+ if (healthySucceeded.get()) {
+ return Result.unhealthy("Forced unhealthy as healthy check has succeded");
+ }
+ return Result.healthy();
+ }
+ });
+
+ when(serverFactory.getApplicationConnectors()).thenReturn(Lists.newArrayList(connectorFactory));
+ when(configuration.getServerFactory()).thenReturn(serverFactory);
+ when(jerseyEnvironment.getResourceConfig()).thenReturn(new DropwizardResourceConfig());
+ when(environment.jersey()).thenReturn(jerseyEnvironment);
+ when(environment.lifecycle()).thenReturn(lifecycleEnvironment);
+ when(environment.healthChecks()).thenReturn(healthChecks);
+ when(environment.getObjectMapper()).thenReturn(new ObjectMapper());
+ AdminEnvironment adminEnvironment = mock(AdminEnvironment.class);
+ doNothing().when(adminEnvironment)
+ .addTask(any());
+ when(environment.admin()).thenReturn(adminEnvironment);
+
+ testingCluster.start();
+
+ serviceDiscoveryConfiguration = ServiceDiscoveryConfiguration.builder()
+ .zookeeper(testingCluster.getConnectString())
+ .namespace("test")
+ .environment("testing")
+ .connectionRetryIntervalMillis(5000)
+ .publishedHost("TestHost")
+ .publishedPort(8021)
+ .initialRotationStatus(true)
+ .dropwizardCheckInterval(6)
+ .dropwizardCheckStaleness(6)
+ .build();
+ bundle.initialize(bootstrap);
+ bundle.run(configuration, environment);
+ bundle.getServerStatus()
+ .markStarted();
+ for (LifeCycle lifeCycle : lifecycleEnvironment.getManagedObjects()) {
+ lifeCycle.start();
+ }
+ bundle.registerHealthcheck(() -> HealthcheckStatus.healthy);
+ }
+
+ @AfterEach
+ void tearDown() throws Exception {
+ for (LifeCycle lifeCycle : lifecycleEnvironment.getManagedObjects()) {
+ lifeCycle.stop();
+ }
+ testingCluster.stop();
+ }
+
+ @Test
+ void testDiscovery() {
+ assertNodePresence(bundle);
+ val info = bundle.getServiceDiscoveryClient()
+ .getNode()
+ .orElse(null);
+ Assertions.assertNotNull(info);
+ Assertions.assertNotNull(info.getNodeData());
+ Assertions.assertEquals("testing", info.getNodeData()
+ .getEnvironment());
+ Assertions.assertEquals("CustomHost", info.getHost());
+ Assertions.assertEquals(21000, info.getPort());
+ healthySucceeded.set(true);
+
+ /* once the first check has succeeded it should get unhealthy and hence no node */
+ assertNodeAbsence(bundle);
+ healthySucceeded.set(false);
+
+ /* again mark healthy and check */
+
+ assertNodePresence(bundle);
+ }
+}
\ No newline at end of file
diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleHierarchicalSelectorTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleHierarchicalSelectorTest.java
new file mode 100644
index 00000000..decb76fc
--- /dev/null
+++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleHierarchicalSelectorTest.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2019 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import com.alibaba.dcm.DnsCacheManipulator;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.health.HealthCheckRegistry;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Lists;
+import io.appform.ranger.core.healthcheck.HealthcheckStatus;
+import io.appform.ranger.discovery.bundle.util.ConfigurationUtils;
+import io.dropwizard.Configuration;
+import io.dropwizard.jersey.DropwizardResourceConfig;
+import io.dropwizard.jersey.setup.JerseyEnvironment;
+import io.dropwizard.jetty.ConnectorFactory;
+import io.dropwizard.jetty.HttpConnectorFactory;
+import io.dropwizard.lifecycle.setup.LifecycleEnvironment;
+import io.dropwizard.server.DefaultServerFactory;
+import io.dropwizard.setup.AdminEnvironment;
+import io.dropwizard.setup.Bootstrap;
+import io.dropwizard.setup.Environment;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+import lombok.val;
+import org.apache.curator.test.TestingCluster;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.slf4j.LoggerFactory;
+
+import static io.appform.ranger.discovery.bundle.TestUtils.assertNodeAbsence;
+import static io.appform.ranger.discovery.bundle.TestUtils.assertNodePresence;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+
+@Slf4j
+class ServiceDiscoveryBundleHierarchicalSelectorTest {
+
+ static {
+ val root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+ root.setLevel(Level.INFO);
+ }
+
+ private final HealthCheckRegistry healthChecks = mock(HealthCheckRegistry.class);
+ private final JerseyEnvironment jerseyEnvironment = mock(JerseyEnvironment.class);
+ private final MetricRegistry metricRegistry = mock(MetricRegistry.class);
+ private final LifecycleEnvironment lifecycleEnvironment = new LifecycleEnvironment(metricRegistry);
+ private final Environment environment = mock(Environment.class);
+ private final Bootstrap> bootstrap = mock(Bootstrap.class);
+ private final Configuration configuration = mock(Configuration.class);
+ private final DefaultServerFactory serverFactory = mock(DefaultServerFactory.class);
+ private final ConnectorFactory connectorFactory = mock(HttpConnectorFactory.class);
+ private final TestingCluster testingCluster = new TestingCluster(1);
+ private ServiceDiscoveryConfiguration serviceDiscoveryConfiguration;
+ private final ServiceDiscoveryBundle bundle = new ServiceDiscoveryBundle() {
+ @Override
+ protected ServiceDiscoveryConfiguration getRangerConfiguration(TestConfig configuration) {
+ return serviceDiscoveryConfiguration;
+ }
+
+ @Override
+ protected String getServiceName(TestConfig configuration) {
+ return "TestService";
+ }
+ };
+ private HealthcheckStatus status = HealthcheckStatus.healthy;
+
+ @BeforeEach
+ void setup() throws Exception {
+ when(serverFactory.getApplicationConnectors()).thenReturn(Lists.newArrayList(connectorFactory));
+ when(configuration.getServerFactory()).thenReturn(serverFactory);
+ when(jerseyEnvironment.getResourceConfig()).thenReturn(new DropwizardResourceConfig());
+ when(environment.jersey()).thenReturn(jerseyEnvironment);
+ when(environment.lifecycle()).thenReturn(lifecycleEnvironment);
+ when(environment.healthChecks()).thenReturn(healthChecks);
+ when(environment.getObjectMapper()).thenReturn(new ObjectMapper());
+ AdminEnvironment adminEnvironment = mock(AdminEnvironment.class);
+ doNothing().when(adminEnvironment)
+ .addTask(any());
+ when(environment.admin()).thenReturn(adminEnvironment);
+
+ testingCluster.start();
+
+ DnsCacheManipulator.setDnsCache("TestHost", "127.0.0.1");
+
+ serviceDiscoveryConfiguration = ServiceDiscoveryConfiguration.builder()
+ .zookeeper(testingCluster.getConnectString())
+ .namespace("test")
+ .environment("x.y")
+ .connectionRetryIntervalMillis(5000)
+ .publishedHost("TestHost")
+ .publishedPort(8021)
+ .initialRotationStatus(true)
+ .build();
+ ConfigurationUtils.resolveZookeeperHosts(serviceDiscoveryConfiguration.getZookeeper())
+ .forEach(zkHost -> {
+ DnsCacheManipulator.setDnsCache(zkHost, "127.0.0.1");
+ });
+ val testConfig = new TestConfig(serviceDiscoveryConfiguration);
+ testConfig.setServerFactory(serverFactory);
+ bundle.initialize(bootstrap);
+ bundle.run(testConfig, environment);
+ bundle.getServerStatus()
+ .markStarted();
+ for (LifeCycle lifeCycle : lifecycleEnvironment.getManagedObjects()) {
+ lifeCycle.start();
+ }
+ bundle.registerHealthcheck(() -> status);
+ }
+
+ @AfterEach
+ void tearDown() throws Exception {
+ for (LifeCycle lifeCycle : lifecycleEnvironment.getManagedObjects()) {
+ lifeCycle.stop();
+ }
+ testingCluster.stop();
+ }
+
+ @Test
+ void testDiscovery() {
+ assertNodePresence(bundle);
+ val info = bundle.getServiceDiscoveryClient()
+ .getNode()
+ .orElse(null);
+ Assertions.assertNotNull(info);
+ Assertions.assertNotNull(info.getNodeData());
+ Assertions.assertEquals("x.y", info.getNodeData()
+ .getEnvironment());
+ Assertions.assertEquals("TestHost", info.getHost());
+ Assertions.assertEquals(8021, info.getPort());
+
+ status = HealthcheckStatus.unhealthy;
+
+ assertNodeAbsence(bundle);
+ }
+
+ private static final class TestConfig extends Configuration {
+
+ @Getter
+ private final ServiceDiscoveryConfiguration configuration;
+
+ private TestConfig(ServiceDiscoveryConfiguration configuration) {
+ this.configuration = configuration;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleLocalHostPortTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleLocalHostPortTest.java
new file mode 100644
index 00000000..d0db400a
--- /dev/null
+++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleLocalHostPortTest.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2016 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle;
+
+import com.alibaba.dcm.DnsCacheManipulator;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.health.HealthCheckRegistry;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.appform.ranger.discovery.bundle.util.ConfigurationUtils;
+import io.dropwizard.Configuration;
+import io.dropwizard.jersey.DropwizardResourceConfig;
+import io.dropwizard.jersey.setup.JerseyEnvironment;
+import io.dropwizard.lifecycle.setup.LifecycleEnvironment;
+import io.dropwizard.setup.AdminEnvironment;
+import io.dropwizard.setup.Bootstrap;
+import io.dropwizard.setup.Environment;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.net.UnknownHostException;
+import java.util.UUID;
+
+import static io.appform.ranger.discovery.bundle.Constants.LOCAL_ADDRESSES;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+
+@Slf4j
+class ServiceDiscoveryBundleLocalHostPortTest {
+
+ private final HealthCheckRegistry healthChecks = mock(HealthCheckRegistry.class);
+ private final JerseyEnvironment jerseyEnvironment = mock(JerseyEnvironment.class);
+ private final MetricRegistry metricRegistry = mock(MetricRegistry.class);
+ private final LifecycleEnvironment lifecycleEnvironment = new LifecycleEnvironment(metricRegistry);
+ private final Environment environment = mock(Environment.class);
+ private final Bootstrap> bootstrap = mock(Bootstrap.class);
+ private final Configuration configuration = mock(Configuration.class);
+
+ private final ServiceDiscoveryBundle bundle = new ServiceDiscoveryBundle() {
+ @Override
+ protected ServiceDiscoveryConfiguration getRangerConfiguration(Configuration configuration) {
+ return serviceDiscoveryConfiguration;
+ }
+
+ @Override
+ protected String getServiceName(Configuration configuration) {
+ return "TestService";
+ }
+
+
+ };
+
+ @AfterEach
+ public void afterMethod() {
+ DnsCacheManipulator.clearDnsCache();
+ }
+
+ private ServiceDiscoveryConfiguration serviceDiscoveryConfiguration;
+
+
+ @Test
+ void shouldFailLocalhostPublish() {
+ DnsCacheManipulator.setDnsCache("myzookeeper", "19.10.1.1");
+ DnsCacheManipulator.setDnsCache("myfavzookeeper", "127.0.0.1");
+ DnsCacheManipulator.setDnsCache("custom-host", "127.0.0.1");
+
+ when(jerseyEnvironment.getResourceConfig()).thenReturn(new DropwizardResourceConfig());
+ when(environment.jersey()).thenReturn(jerseyEnvironment);
+ when(environment.lifecycle()).thenReturn(lifecycleEnvironment);
+ when(environment.healthChecks()).thenReturn(healthChecks);
+ when(environment.getObjectMapper()).thenReturn(new ObjectMapper());
+ AdminEnvironment adminEnvironment = mock(AdminEnvironment.class);
+ doNothing().when(adminEnvironment)
+ .addTask(any());
+ when(environment.admin()).thenReturn(adminEnvironment);
+
+ serviceDiscoveryConfiguration = ServiceDiscoveryConfiguration.builder()
+ .zookeeper("myzookeeper:2181,myfavzookeeper:2181")
+ .namespace("test")
+ .environment("testing")
+ .connectionRetryIntervalMillis(5000)
+ .publishedHost("custom-host")
+ .publishedPort(8021)
+ .initialRotationStatus(true)
+ .build();
+ bundle.initialize(bootstrap);
+ assertLocalHostNotAllowed();
+
+ }
+
+ @Test
+ void shouldThrowExceptionForInvalidZkHost() {
+ DnsCacheManipulator.setDnsCache("custom-host", "127.0.0.1");
+
+ when(jerseyEnvironment.getResourceConfig()).thenReturn(new DropwizardResourceConfig());
+ when(environment.jersey()).thenReturn(jerseyEnvironment);
+ when(environment.lifecycle()).thenReturn(lifecycleEnvironment);
+ when(environment.healthChecks()).thenReturn(healthChecks);
+ when(environment.getObjectMapper()).thenReturn(new ObjectMapper());
+ AdminEnvironment adminEnvironment = mock(AdminEnvironment.class);
+ doNothing().when(adminEnvironment)
+ .addTask(any());
+ when(environment.admin()).thenReturn(adminEnvironment);
+
+ serviceDiscoveryConfiguration = ServiceDiscoveryConfiguration.builder()
+ .zookeeper(String.format("%s:2181", UUID.randomUUID()))
+ .namespace("test")
+ .environment("testing")
+ .connectionRetryIntervalMillis(5000)
+ .publishedHost("custom-host")
+ .publishedPort(8021)
+ .initialRotationStatus(true)
+ .build();
+ bundle.initialize(bootstrap);
+
+ IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> {
+ bundle.run(configuration, environment);
+
+ });
+
+ assertTrue(thrown.getMessage()
+ .contains("Couldn't resolve host address for zkHost"));
+
+ }
+
+ @Test
+ void testPublishWithEmptyZkHost() throws UnknownHostException {
+ DnsCacheManipulator.setDnsCache("myzookeeper", "19.10.1.1");
+ DnsCacheManipulator.setDnsCache("myfavzookeeper", "127.0.0.1");
+ DnsCacheManipulator.setDnsCache("custom-host", "127.0.0.1");
+ when(jerseyEnvironment.getResourceConfig()).thenReturn(new DropwizardResourceConfig());
+ when(environment.jersey()).thenReturn(jerseyEnvironment);
+ when(environment.lifecycle()).thenReturn(lifecycleEnvironment);
+ when(environment.healthChecks()).thenReturn(healthChecks);
+ when(environment.getObjectMapper()).thenReturn(new ObjectMapper());
+ AdminEnvironment adminEnvironment = mock(AdminEnvironment.class);
+ doNothing().when(adminEnvironment)
+ .addTask(any());
+ when(environment.admin()).thenReturn(adminEnvironment);
+
+ serviceDiscoveryConfiguration = ServiceDiscoveryConfiguration.builder()
+ .zookeeper("myzookeeper:2181,myfavzookeeper:2181")
+ .namespace("test")
+ .environment("testing")
+ .connectionRetryIntervalMillis(5000)
+ .publishedHost("")
+ .publishedPort(8021)
+ .initialRotationStatus(true)
+ .build();
+ bundle.initialize(bootstrap);
+
+ String publishedHost = ConfigurationUtils.resolveNonEmptyPublishedHost(
+ serviceDiscoveryConfiguration.getPublishedHost());
+ if (LOCAL_ADDRESSES.contains(publishedHost)) {
+ assertLocalHostNotAllowed();
+ } else {
+ assertDoesNotThrow();
+ }
+ }
+
+ @Test
+ void testPublishWithNullZkHost() throws UnknownHostException {
+ DnsCacheManipulator.setDnsCache("myzookeeper", "19.10.1.1");
+ DnsCacheManipulator.setDnsCache("myfavzookeeper", "127.0.0.1");
+ DnsCacheManipulator.setDnsCache("custom-host", "127.0.0.1");
+ when(jerseyEnvironment.getResourceConfig()).thenReturn(new DropwizardResourceConfig());
+ when(environment.jersey()).thenReturn(jerseyEnvironment);
+ when(environment.lifecycle()).thenReturn(lifecycleEnvironment);
+ when(environment.healthChecks()).thenReturn(healthChecks);
+ when(environment.getObjectMapper()).thenReturn(new ObjectMapper());
+ AdminEnvironment adminEnvironment = mock(AdminEnvironment.class);
+ doNothing().when(adminEnvironment)
+ .addTask(any());
+ when(environment.admin()).thenReturn(adminEnvironment);
+
+ serviceDiscoveryConfiguration = ServiceDiscoveryConfiguration.builder()
+ .zookeeper("myzookeeper:2181,myfavzookeeper:2181")
+ .namespace("test")
+ .environment("testing")
+ .connectionRetryIntervalMillis(5000)
+ .publishedPort(8021)
+ .initialRotationStatus(true)
+ .build();
+ bundle.initialize(bootstrap);
+
+ String publishedHost = ConfigurationUtils.resolveNonEmptyPublishedHost(
+ serviceDiscoveryConfiguration.getPublishedHost());
+ if (LOCAL_ADDRESSES.contains(publishedHost)) {
+ assertLocalHostNotAllowed();
+ } else {
+ assertDoesNotThrow();
+ }
+ }
+
+ @Test
+ void shouldPublishingToLocalZk() {
+ DnsCacheManipulator.setDnsCache("myfavzookeeper", "127.0.0.1");
+ DnsCacheManipulator.setDnsCache("custom-host", "127.0.0.1");
+
+ when(jerseyEnvironment.getResourceConfig()).thenReturn(new DropwizardResourceConfig());
+ when(environment.jersey()).thenReturn(jerseyEnvironment);
+ when(environment.lifecycle()).thenReturn(lifecycleEnvironment);
+ when(environment.healthChecks()).thenReturn(healthChecks);
+ when(environment.getObjectMapper()).thenReturn(new ObjectMapper());
+ AdminEnvironment adminEnvironment = mock(AdminEnvironment.class);
+ doNothing().when(adminEnvironment)
+ .addTask(any());
+ when(environment.admin()).thenReturn(adminEnvironment);
+
+ serviceDiscoveryConfiguration = ServiceDiscoveryConfiguration.builder()
+ .zookeeper("localhost:2181,myfavzookeeper:2181")
+ .namespace("test")
+ .environment("testing")
+ .connectionRetryIntervalMillis(5000)
+ .publishedHost("localhost")
+ .publishedPort(8021)
+ .initialRotationStatus(true)
+ .build();
+ bundle.initialize(bootstrap);
+
+ assertDoesNotThrow();
+
+ }
+
+ @Test
+ void shouldPublishToRemoteZk() {
+ DnsCacheManipulator.setDnsCache("myfavzookeeper", "17.4.0.1");
+ DnsCacheManipulator.setDnsCache("custom-host", "17.1.2.1");
+
+ when(jerseyEnvironment.getResourceConfig()).thenReturn(new DropwizardResourceConfig());
+ when(environment.jersey()).thenReturn(jerseyEnvironment);
+ when(environment.lifecycle()).thenReturn(lifecycleEnvironment);
+ when(environment.healthChecks()).thenReturn(healthChecks);
+ when(environment.getObjectMapper()).thenReturn(new ObjectMapper());
+ AdminEnvironment adminEnvironment = mock(AdminEnvironment.class);
+ doNothing().when(adminEnvironment)
+ .addTask(any());
+ when(environment.admin()).thenReturn(adminEnvironment);
+
+ serviceDiscoveryConfiguration = ServiceDiscoveryConfiguration.builder()
+ .zookeeper("myfavzookeeper:2181")
+ .namespace("test")
+ .environment("testing")
+ .connectionRetryIntervalMillis(5000)
+ .publishedHost("custom-host")
+ .publishedPort(8021)
+ .initialRotationStatus(true)
+ .build();
+ bundle.initialize(bootstrap);
+
+ assertDoesNotThrow();
+ }
+
+ private void assertLocalHostNotAllowed() {
+ IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> {
+ bundle.run(configuration, environment);
+
+ });
+ assertTrue(thrown.getMessage()
+ .contains("Not allowed to publish localhost address to remote zookeeper"));
+ }
+
+
+ private void assertDoesNotThrow() {
+ Assertions.assertDoesNotThrow(() -> {
+ bundle.run(configuration, environment);
+ });
+ }
+
+}
\ No newline at end of file
diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleRotationTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleRotationTest.java
new file mode 100644
index 00000000..98b457d9
--- /dev/null
+++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleRotationTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2019 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import com.alibaba.dcm.DnsCacheManipulator;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.health.HealthCheckRegistry;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Lists;
+import io.appform.ranger.discovery.bundle.rotationstatus.BIRTask;
+import io.appform.ranger.discovery.bundle.rotationstatus.OORTask;
+import io.appform.ranger.discovery.bundle.rotationstatus.RotationStatus;
+import io.appform.ranger.discovery.bundle.util.ConfigurationUtils;
+import io.dropwizard.Configuration;
+import io.dropwizard.jersey.DropwizardResourceConfig;
+import io.dropwizard.jersey.setup.JerseyEnvironment;
+import io.dropwizard.jetty.ConnectorFactory;
+import io.dropwizard.jetty.HttpConnectorFactory;
+import io.dropwizard.lifecycle.setup.LifecycleEnvironment;
+import io.dropwizard.server.DefaultServerFactory;
+import io.dropwizard.setup.AdminEnvironment;
+import io.dropwizard.setup.Bootstrap;
+import io.dropwizard.setup.Environment;
+import lombok.extern.slf4j.Slf4j;
+import lombok.val;
+import org.apache.curator.test.TestingCluster;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collections;
+
+import static io.appform.ranger.discovery.bundle.TestUtils.assertNodeAbsence;
+import static io.appform.ranger.discovery.bundle.TestUtils.assertNodePresence;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+
+@Slf4j
+class ServiceDiscoveryBundleRotationTest {
+
+ static {
+ val root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+ root.setLevel(Level.INFO);
+ }
+
+ private final HealthCheckRegistry healthChecks = mock(HealthCheckRegistry.class);
+ private final JerseyEnvironment jerseyEnvironment = mock(JerseyEnvironment.class);
+ private final MetricRegistry metricRegistry = mock(MetricRegistry.class);
+ private final LifecycleEnvironment lifecycleEnvironment = new LifecycleEnvironment(metricRegistry);
+ private final Environment environment = mock(Environment.class);
+ private final Bootstrap> bootstrap = mock(Bootstrap.class);
+ private final Configuration configuration = mock(Configuration.class);
+ private final DefaultServerFactory serverFactory = mock(DefaultServerFactory.class);
+ private final ConnectorFactory connectorFactory = mock(HttpConnectorFactory.class);
+ private final TestingCluster testingCluster = new TestingCluster(1);
+ private ServiceDiscoveryConfiguration serviceDiscoveryConfiguration;
+ private final ServiceDiscoveryBundle bundle = new ServiceDiscoveryBundle() {
+ @Override
+ protected ServiceDiscoveryConfiguration getRangerConfiguration(Configuration configuration) {
+ return serviceDiscoveryConfiguration;
+ }
+
+ @Override
+ protected String getServiceName(Configuration configuration) {
+ return "TestService";
+ }
+
+ };
+ private RotationStatus rotationStatus;
+
+ @BeforeEach
+ void setup() throws Exception {
+ when(serverFactory.getApplicationConnectors()).thenReturn(Lists.newArrayList(connectorFactory));
+ when(configuration.getServerFactory()).thenReturn(serverFactory);
+ when(jerseyEnvironment.getResourceConfig()).thenReturn(new DropwizardResourceConfig());
+ when(environment.jersey()).thenReturn(jerseyEnvironment);
+ when(environment.lifecycle()).thenReturn(lifecycleEnvironment);
+ when(environment.healthChecks()).thenReturn(healthChecks);
+ when(environment.getObjectMapper()).thenReturn(new ObjectMapper());
+ AdminEnvironment adminEnvironment = mock(AdminEnvironment.class);
+ doNothing().when(adminEnvironment)
+ .addTask(any());
+ when(environment.admin()).thenReturn(adminEnvironment);
+
+ testingCluster.start();
+
+ serviceDiscoveryConfiguration = ServiceDiscoveryConfiguration.builder()
+ .zookeeper(testingCluster.getConnectString())
+ .namespace("test")
+ .environment("testing")
+ .connectionRetryIntervalMillis(5000)
+ .publishedHost("TestHost")
+ .publishedPort(8021)
+ .initialRotationStatus(true)
+ .build();
+
+ DnsCacheManipulator.setDnsCache("TestHost", "127.0.0.1");
+ ConfigurationUtils.resolveZookeeperHosts(serviceDiscoveryConfiguration.getZookeeper())
+ .forEach(zkHost -> {
+ DnsCacheManipulator.setDnsCache(zkHost, "127.0.0.1");
+ });
+ bundle.initialize(bootstrap);
+ bundle.run(configuration, environment);
+ rotationStatus = bundle.getRotationStatus();
+ bundle.getServerStatus()
+ .markStarted();
+ for (LifeCycle lifeCycle : lifecycleEnvironment.getManagedObjects()) {
+ lifeCycle.start();
+ }
+ }
+
+ @AfterEach
+ void tearDown() throws Exception {
+ for (LifeCycle lifeCycle : lifecycleEnvironment.getManagedObjects()) {
+ lifeCycle.stop();
+ }
+ testingCluster.stop();
+ }
+
+ @Test
+ void testDiscovery() {
+ assertNodePresence(bundle);
+ val info = bundle.getServiceDiscoveryClient()
+ .getNode()
+ .orElse(null);
+ Assertions.assertNotNull(info);
+ Assertions.assertNotNull(info.getNodeData());
+ Assertions.assertEquals("testing", info.getNodeData()
+ .getEnvironment());
+ Assertions.assertEquals("TestHost", info.getHost());
+ Assertions.assertEquals(8021, info.getPort());
+
+ val oorTask = new OORTask(rotationStatus);
+ oorTask.execute(Collections.emptyMap(), null);
+
+ assertNodeAbsence(bundle);
+
+ val birTask = new BIRTask(rotationStatus);
+ birTask.execute(Collections.emptyMap(), null);
+
+ assertNodePresence(bundle);
+ }
+}
\ No newline at end of file
diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleTest.java
new file mode 100644
index 00000000..844a1073
--- /dev/null
+++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/ServiceDiscoveryBundleTest.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2019 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import com.alibaba.dcm.DnsCacheManipulator;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.health.HealthCheckRegistry;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Lists;
+import io.appform.ranger.core.healthcheck.HealthcheckStatus;
+import io.appform.ranger.discovery.bundle.resolvers.DefaultNodeInfoResolver;
+import io.appform.ranger.discovery.bundle.resolvers.NodeInfoResolver;
+import io.appform.ranger.discovery.bundle.util.ConfigurationUtils;
+import io.dropwizard.Configuration;
+import io.dropwizard.jersey.DropwizardResourceConfig;
+import io.dropwizard.jersey.setup.JerseyEnvironment;
+import io.dropwizard.jetty.ConnectorFactory;
+import io.dropwizard.jetty.HttpConnectorFactory;
+import io.dropwizard.lifecycle.setup.LifecycleEnvironment;
+import io.dropwizard.server.DefaultServerFactory;
+import io.dropwizard.setup.AdminEnvironment;
+import io.dropwizard.setup.Bootstrap;
+import io.dropwizard.setup.Environment;
+import lombok.extern.slf4j.Slf4j;
+import lombok.val;
+import org.apache.curator.test.TestingCluster;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.slf4j.LoggerFactory;
+
+import static io.appform.ranger.discovery.bundle.TestUtils.assertNodeAbsence;
+import static io.appform.ranger.discovery.bundle.TestUtils.assertNodePresence;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+
+@Slf4j
+class ServiceDiscoveryBundleTest {
+
+ static {
+ val root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+ root.setLevel(Level.INFO);
+ }
+
+ private final HealthCheckRegistry healthChecks = mock(HealthCheckRegistry.class);
+ private final JerseyEnvironment jerseyEnvironment = mock(JerseyEnvironment.class);
+ private final MetricRegistry metricRegistry = mock(MetricRegistry.class);
+ private final LifecycleEnvironment lifecycleEnvironment = new LifecycleEnvironment(metricRegistry);
+ private final Environment environment = mock(Environment.class);
+ private final Bootstrap> bootstrap = mock(Bootstrap.class);
+ private final Configuration configuration = mock(Configuration.class);
+ private final DefaultServerFactory serverFactory = mock(DefaultServerFactory.class);
+ private final ConnectorFactory connectorFactory = mock(HttpConnectorFactory.class);
+ private final TestingCluster testingCluster = new TestingCluster(1);
+ private ServiceDiscoveryConfiguration serviceDiscoveryConfiguration;
+ private final ServiceDiscoveryBundle bundle = new ServiceDiscoveryBundle() {
+ @Override
+ protected ServiceDiscoveryConfiguration getRangerConfiguration(Configuration configuration) {
+ return serviceDiscoveryConfiguration;
+ }
+
+ @Override
+ protected String getServiceName(Configuration configuration) {
+ return "TestService";
+ }
+
+ @Override
+ protected NodeInfoResolver createNodeInfoResolver() {
+ return new DefaultNodeInfoResolver();
+ }
+ };
+ private HealthcheckStatus status = HealthcheckStatus.healthy;
+
+ @BeforeEach
+ void setup() throws Exception {
+ when(serverFactory.getApplicationConnectors()).thenReturn(Lists.newArrayList(connectorFactory));
+ when(configuration.getServerFactory()).thenReturn(serverFactory);
+ when(jerseyEnvironment.getResourceConfig()).thenReturn(new DropwizardResourceConfig());
+ when(environment.jersey()).thenReturn(jerseyEnvironment);
+ when(environment.lifecycle()).thenReturn(lifecycleEnvironment);
+ when(environment.healthChecks()).thenReturn(healthChecks);
+ when(environment.getObjectMapper()).thenReturn(new ObjectMapper());
+ AdminEnvironment adminEnvironment = mock(AdminEnvironment.class);
+ doNothing().when(adminEnvironment)
+ .addTask(any());
+ when(environment.admin()).thenReturn(adminEnvironment);
+
+ testingCluster.start();
+
+ serviceDiscoveryConfiguration = ServiceDiscoveryConfiguration.builder()
+ .zookeeper(testingCluster.getConnectString())
+ .namespace("test")
+ .environment("testing")
+ .connectionRetryIntervalMillis(5000)
+ .publishedHost("TestHost")
+ .publishedPort(8021)
+ .initialRotationStatus(true)
+ .build();
+
+ DnsCacheManipulator.setDnsCache("TestHost", "127.0.0.1");
+ ConfigurationUtils.resolveZookeeperHosts(serviceDiscoveryConfiguration.getZookeeper())
+ .forEach(zkHost -> {
+ DnsCacheManipulator.setDnsCache(zkHost, "127.0.0.1");
+ });
+
+ bundle.initialize(bootstrap);
+ bundle.run(configuration, environment);
+ bundle.getServerStatus()
+ .markStarted();
+ for (LifeCycle lifeCycle : lifecycleEnvironment.getManagedObjects()) {
+ lifeCycle.start();
+ }
+ bundle.registerHealthcheck(() -> status);
+ }
+
+ @AfterEach
+ void tearDown() throws Exception {
+ for (LifeCycle lifeCycle : lifecycleEnvironment.getManagedObjects()) {
+ lifeCycle.stop();
+ }
+ testingCluster.stop();
+ }
+
+ @Test
+ void testDiscovery() {
+ assertNodePresence(bundle);
+ val info = bundle.getServiceDiscoveryClient()
+ .getNode()
+ .orElse(null);
+ Assertions.assertNotNull(info);
+ Assertions.assertNotNull(info.getNodeData());
+ Assertions.assertEquals("testing", info.getNodeData()
+ .getEnvironment());
+ Assertions.assertEquals("TestHost", info.getHost());
+ Assertions.assertEquals(8021, info.getPort());
+ Assertions.assertNull(info.getNodeData()
+ .getRegion());
+
+ status = HealthcheckStatus.unhealthy;
+
+ assertNodeAbsence(bundle);
+ }
+}
\ No newline at end of file
diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/TestUtils.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/TestUtils.java
new file mode 100644
index 00000000..1c9663d7
--- /dev/null
+++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/TestUtils.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2021 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle;
+
+import io.dropwizard.Configuration;
+import lombok.experimental.UtilityClass;
+import org.awaitility.Awaitility;
+
+import java.time.Duration;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+
+/**
+ *
+ */
+@UtilityClass
+public class TestUtils {
+ public static void assertNodePresence(ServiceDiscoveryBundle bundle) {
+ Awaitility.await()
+ .pollInterval(Duration.ofSeconds(1))
+ .atMost(Duration.ofSeconds(30))
+ .untilAsserted(() -> assertNotNull(bundle.getServiceDiscoveryClient()
+ .getNode()
+ .orElse(null)));
+ }
+ public static void assertNodeAbsence(ServiceDiscoveryBundle bundle) {
+ Awaitility.await()
+ .pollInterval(Duration.ofSeconds(1))
+ .atMost(Duration.ofSeconds(30))
+ .untilAsserted(() -> assertNull(bundle.getServiceDiscoveryClient()
+ .getNode()
+ .orElse(null)));
+ }
+}
diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/BenchmarkTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/BenchmarkTest.java
new file mode 100644
index 00000000..fd8fdd11
--- /dev/null
+++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/BenchmarkTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2023 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package io.appform.ranger.discovery.bundle.id;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.SneakyThrows;
+import lombok.val;
+import org.junit.jupiter.api.Test;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.results.RunResult;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+import org.openjdk.jmh.runner.options.TimeValue;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+public abstract class BenchmarkTest {
+
+ public static final ObjectMapper mapper = new ObjectMapper();
+
+ @Test
+ void testBenchmark() throws RunnerException {
+ val opt = new OptionsBuilder()
+ .include(String.format("%s.*", this.getClass().getName()))
+ .mode(Mode.Throughput)
+ .timeUnit(TimeUnit.SECONDS)
+ .warmupTime(TimeValue.seconds(5))
+ .warmupIterations(1)
+ .measurementTime(TimeValue.seconds(5))
+ .measurementIterations(4)
+ .threads(1)
+ .forks(3)
+ .shouldFailOnError(true)
+ .shouldDoGC(true)
+ .build();
+ val results = new Runner(opt).run();
+ results.iterator()
+ .forEachRemaining(new Consumer() {
+ @SneakyThrows
+ @Override
+ public void accept(RunResult runResult) {
+ val benchmarkName = runResult.getParams().getBenchmark();
+ val outputFilePath = Paths.get(String.format("perf/results/%s.json", benchmarkName));
+ val outputNode = mapper.createObjectNode();
+ outputNode.put("name", benchmarkName);
+ outputNode.put("mode", runResult.getParams().getMode().name());
+ outputNode.put("iterations", runResult.getParams().getMeasurement().getCount());
+ outputNode.put("threads", runResult.getParams().getThreads());
+ outputNode.put("forks", runResult.getParams().getForks());
+ outputNode.put("mean_ops", runResult.getPrimaryResult().getStatistics().getMean());
+ Files.write(outputFilePath, mapper.writerWithDefaultPrettyPrinter().writeValueAsBytes(outputNode));
+ }
+ });
+ }
+
+
+}
\ No newline at end of file
diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/CollisionCheckerTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/CollisionCheckerTest.java
new file mode 100644
index 00000000..8342a787
--- /dev/null
+++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/CollisionCheckerTest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.id;
+
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.stream.IntStream;
+
+/**
+ * Test on {@link CollisionChecker}
+ */
+class CollisionCheckerTest {
+
+ @Test
+ void testCheck() {
+ CollisionChecker collisionChecker = new CollisionChecker();
+ Assertions.assertTrue(collisionChecker.check(100, 1));
+ Assertions.assertFalse(collisionChecker.check(100, 1));
+ IntStream.range(0, 1000).forEach(i -> {
+ Assertions.assertTrue(collisionChecker.check(101, i));
+ Assertions.assertFalse(collisionChecker.check(101, i));
+ });
+ }
+}
\ No newline at end of file
diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdGeneratorPerfTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdGeneratorPerfTest.java
new file mode 100644
index 00000000..55f6cd92
--- /dev/null
+++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdGeneratorPerfTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2022. Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package io.appform.ranger.discovery.bundle.id;
+
+import io.appform.ranger.discovery.bundle.id.formatter.IdFormatters;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.io.IOException;
+
+/**
+ * Test performance between different constructs
+ */
+@Slf4j
+public class IdGeneratorPerfTest extends BenchmarkTest {
+
+ @State(Scope.Benchmark)
+ public static class BenchmarkState {
+
+ @Setup(Level.Trial)
+ public void setUp() throws IOException {
+ IdGenerator.initialize(23);
+ }
+ }
+
+ @SneakyThrows
+ @Benchmark
+ public void testGenerateBase36(Blackhole blackhole, BenchmarkState state) {
+ IdGenerator.generate("X", IdFormatters.base36());
+ }
+
+ @SneakyThrows
+ @Benchmark
+ public void testGenerate(Blackhole blackhole, BenchmarkState state) {
+ IdGenerator.generate("X", IdFormatters.original());
+ }
+}
\ No newline at end of file
diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdGeneratorTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdGeneratorTest.java
new file mode 100644
index 00000000..0089eaac
--- /dev/null
+++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdGeneratorTest.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2016 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.id;
+
+import com.google.common.collect.ImmutableList;
+import io.appform.ranger.discovery.bundle.id.constraints.IdValidationConstraint;
+import io.appform.ranger.discovery.bundle.id.constraints.impl.JavaHashCodeBasedKeyPartitioner;
+import io.appform.ranger.discovery.bundle.id.constraints.impl.PartitionValidator;
+import io.appform.ranger.discovery.bundle.id.formatter.IdFormatters;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+import lombok.val;
+import org.awaitility.Awaitility;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.time.*;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Optional;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+/**
+ * Test for {@link IdGenerator}
+ */
+@Slf4j
+@SuppressWarnings({"unused", "FieldMayBeFinal"})
+class IdGeneratorTest {
+
+ @Getter
+ private static final class Runner implements Callable {
+ private boolean stop = false;
+ private long count = 0L;
+
+ @Override
+ public Long call() {
+ while (!stop) {
+ val id = IdGenerator.generate("X");
+ count++;
+ }
+ return count;
+ }
+ }
+
+ @Getter
+ private static final class ConstraintRunner implements Callable {
+ private final IdValidationConstraint constraint;
+ private boolean stop = false;
+ private long count = 0L;
+
+ private ConstraintRunner(IdValidationConstraint constraint) {
+ this.constraint = constraint;
+ }
+
+ @Override
+ public Long call() {
+ while (!stop) {
+ Optional id = IdGenerator.generateWithConstraints("X", Collections.singletonList(constraint));
+ Assertions.assertTrue(id.isPresent());
+ count++;
+ }
+ return count;
+ }
+ }
+
+ @Test
+ void testGenerate() {
+ IdGenerator.initialize(23);
+ val numRunners = 20;
+ val runners = IntStream.range(0, numRunners).mapToObj(i -> new Runner()).collect(Collectors.toList());
+ val executorService = Executors.newFixedThreadPool(numRunners);
+ runners.forEach(executorService::submit);
+ Awaitility.await()
+ .pollInterval(Duration.ofSeconds(10))
+ .timeout(Duration.ofSeconds(11))
+ .until(() -> true);
+ executorService.shutdownNow();
+ val totalCount = runners.stream().mapToLong(Runner::getCount).sum();
+ log.debug("Generated ID count: {}", totalCount);
+ log.debug("Generated ID rate: {}/sec", totalCount / 10);
+ Assertions.assertTrue(totalCount > 0);
+ }
+
+ @Test
+ void testGenerateOriginal() {
+ IdGenerator.initialize(23);
+ String id = IdGenerator.generate("TEST", IdFormatters.original()).getId();
+ Assertions.assertEquals(26, id.length());
+ }
+
+ @Test
+ void testGenerateBase36() {
+ IdGenerator.initialize(23);
+ String id = IdGenerator.generate("TEST", IdFormatters.base36()).getId();
+ Assertions.assertEquals(18, id.length());
+ }
+
+
+ @Test
+ void testGenerateWithConstraintsNoConstraint() {
+ IdGenerator.initialize(23);
+ int numRunners = 20;
+
+ val runners = IntStream.range(0, numRunners).mapToObj(i -> new ConstraintRunner(new PartitionValidator(4, new JavaHashCodeBasedKeyPartitioner(16)))).collect(Collectors.toList());
+ val executorService = Executors.newFixedThreadPool(numRunners);
+ runners.forEach(executorService::submit);
+ Awaitility.await()
+ .pollInterval(Duration.ofSeconds(10))
+ .timeout(Duration.ofSeconds(11))
+ .until(() -> true);
+ executorService.shutdownNow();
+ val totalCount = runners.stream().mapToLong(ConstraintRunner::getCount).sum();
+ log.debug("Generated ID count: {}", totalCount);
+ log.debug("Generated ID rate: {}/sec", totalCount / 10);
+ Assertions.assertTrue(totalCount > 0);
+
+ }
+
+ @Test
+ void testConstraintFailure() {
+ IdGenerator.initialize(23);
+ Assertions.assertFalse(IdGenerator.generateWithConstraints(
+ "TST",
+ ImmutableList.of(id -> false),
+ false).isPresent());
+ }
+
+ @Test
+ void testParseFailure() {
+ //Null or Empty String
+ Assertions.assertFalse(IdGenerator.parse(null).isPresent());
+ Assertions.assertFalse(IdGenerator.parse("").isPresent());
+
+ //Invalid length
+ Assertions.assertFalse(IdGenerator.parse("TEST").isPresent());
+
+ //Invalid chars
+ Assertions.assertFalse(IdGenerator.parse("XCL983dfb1ee0a847cd9e7321fcabc2f223").isPresent());
+ Assertions.assertFalse(IdGenerator.parse("XCL98-3df-b1e:e0a847cd9e7321fcabc2f223").isPresent());
+
+ //Invalid month
+ Assertions.assertFalse(IdGenerator.parse("ABC2032250959030643972247").isPresent());
+ //Invalid date
+ Assertions.assertFalse(IdGenerator.parse("ABC2011450959030643972247").isPresent());
+ //Invalid hour
+ Assertions.assertFalse(IdGenerator.parse("ABC2011259659030643972247").isPresent());
+ //Invalid minute
+ Assertions.assertFalse(IdGenerator.parse("ABC2011250972030643972247").isPresent());
+ //Invalid sec
+ Assertions.assertFalse(IdGenerator.parse("ABC2011250959720643972247").isPresent());
+ }
+
+ @Test
+ void testParseSuccess() {
+ val idString = "ABC2011250959030643972247";
+ val id = IdGenerator.parse(idString).orElse(null);
+ Assertions.assertNotNull(id);
+ Assertions.assertEquals(idString, id.getId());
+ Assertions.assertEquals(247, id.getExponent());
+ Assertions.assertEquals(3972, id.getNode());
+ Assertions.assertEquals(generateDate(2020, 11, 25, 9, 59, 3, 64, ZoneId.systemDefault()),
+ id.getGeneratedDate());
+ }
+
+ @Test
+ void testParseSuccessAfterGeneration() {
+ val generatedId = IdGenerator.generate("TEST123");
+ val parsedId = IdGenerator.parse(generatedId.getId()).orElse(null);
+ Assertions.assertNotNull(parsedId);
+ Assertions.assertEquals(parsedId.getId(), generatedId.getId());
+ Assertions.assertEquals(parsedId.getExponent(), generatedId.getExponent());
+ Assertions.assertEquals(parsedId.getNode(), generatedId.getNode());
+ Assertions.assertEquals(parsedId.getGeneratedDate(), generatedId.getGeneratedDate());
+ }
+
+
+ @SuppressWarnings("SameParameterValue")
+ private Date generateDate(int year, int month, int day, int hour, int min, int sec, int ms, ZoneId zoneId) {
+ return Date.from(
+ Instant.from(
+ ZonedDateTime.of(
+ LocalDateTime.of(
+ year, month, day, hour, min, sec, Math.multiplyExact(ms, 1000000)
+ ),
+ zoneId
+ )
+ )
+ );
+ }
+
+
+}
\ No newline at end of file
diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/resolvers/DefaultNodeInfoResolverTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/resolvers/DefaultNodeInfoResolverTest.java
new file mode 100644
index 00000000..5e3527e6
--- /dev/null
+++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/resolvers/DefaultNodeInfoResolverTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2023 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package io.appform.ranger.discovery.bundle.resolvers;
+
+import io.appform.ranger.discovery.bundle.ServiceDiscoveryConfiguration;
+import lombok.val;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+class DefaultNodeInfoResolverTest {
+
+ @Test
+ void testNodeInfoResolver() {
+ val configuration = ServiceDiscoveryConfiguration.builder()
+ .zookeeper("connectionString")
+ .namespace("test")
+ .environment("testing")
+ .connectionRetryIntervalMillis(5000)
+ .publishedHost("TestHost")
+ .publishedPort(8021)
+ .initialRotationStatus(true)
+ .build();
+ val resolver = new DefaultNodeInfoResolver();
+ val nodeInfo = resolver.resolve(configuration);
+ Assertions.assertNotNull(nodeInfo);
+ Assertions.assertEquals("testing", configuration.getEnvironment());
+ Assertions.assertNull(nodeInfo.getRegion());
+ Assertions.assertNull(nodeInfo.getTags());
+ }
+}
diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/resolvers/DefaultPortSchemeResolverTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/resolvers/DefaultPortSchemeResolverTest.java
new file mode 100644
index 00000000..236c714a
--- /dev/null
+++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/resolvers/DefaultPortSchemeResolverTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2023 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package io.appform.ranger.discovery.bundle.resolvers;
+
+import com.google.common.collect.Lists;
+import io.dropwizard.Configuration;
+import io.dropwizard.jetty.HttpConnectorFactory;
+import io.dropwizard.jetty.HttpsConnectorFactory;
+import io.dropwizard.server.DefaultServerFactory;
+import io.dropwizard.server.SimpleServerFactory;
+import lombok.val;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class DefaultPortSchemeResolverTest {
+
+ @Test
+ void testPortSchemeDefaultServerFactory() {
+ val server = mock(DefaultServerFactory.class);
+ val connectorFactory = mock(HttpConnectorFactory.class);
+ when(server.getApplicationConnectors()).thenReturn(Lists.newArrayList(connectorFactory));
+ val resolver = new DefaultPortSchemeResolver<>();
+ val configuration = mock(Configuration.class);
+ when(configuration.getServerFactory()).thenReturn(server);
+ Assertions.assertEquals("http", resolver.resolve(configuration));
+ }
+
+ @Test
+ void testPortSchemeSimpleServerFactory() {
+ val server = mock(SimpleServerFactory.class);
+ val connectorFactory = mock(HttpsConnectorFactory.class);
+ when(server.getConnector()).thenReturn(connectorFactory);
+ val resolver = new DefaultPortSchemeResolver<>();
+ val configuration = mock(Configuration.class);
+ when(configuration.getServerFactory()).thenReturn(server);
+ Assertions.assertEquals("https", resolver.resolve(configuration));
+ }
+
+ @Test
+ void testPortSchemeDefault() {
+ val server = mock(SimpleServerFactory.class);
+ when(server.getConnector()).thenReturn(null);
+ val resolver = new DefaultPortSchemeResolver<>();
+ val configuration = mock(Configuration.class);
+ when(configuration.getServerFactory()).thenReturn(server);
+ Assertions.assertEquals("http", resolver.resolve(configuration));
+ }
+}
diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/selectors/HierarchicalEnvironmentAwareShardSelectorTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/selectors/HierarchicalEnvironmentAwareShardSelectorTest.java
new file mode 100644
index 00000000..472919c1
--- /dev/null
+++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/selectors/HierarchicalEnvironmentAwareShardSelectorTest.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2022 Santanu Sinha
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.appform.ranger.discovery.bundle.selectors;
+
+import com.google.common.collect.ArrayListMultimap;
+import io.appform.ranger.common.server.ShardInfo;
+import io.appform.ranger.core.finder.serviceregistry.MapBasedServiceRegistry;
+import io.appform.ranger.core.healthcheck.HealthcheckStatus;
+import io.appform.ranger.core.model.Service;
+import io.appform.ranger.core.model.ServiceNode;
+import lombok.val;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.UUID;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.doReturn;
+
+/**
+ *
+ */
+class HierarchicalEnvironmentAwareShardSelectorTest {
+
+ @Mock
+ private MapBasedServiceRegistry serviceRegistry;
+
+ @BeforeEach
+ public void setUp() {
+ MockitoAnnotations.openMocks(this);
+ }
+
+ @Test
+ void testNoNodeAvailableForTheEnvironment() {
+ val serviceName = UUID.randomUUID().toString();
+ val service = Mockito.mock(Service.class);
+ doReturn(serviceName).when(service).getServiceName();
+ doReturn(service).when(serviceRegistry).getService();
+
+ val serviceNodes = ArrayListMultimap.create();
+ serviceNodes.put(
+ ShardInfo.builder().environment("x.y").build(),
+ new ServiceNode<>("host1",
+ 8888,
+ ShardInfo.builder().environment("x.y").build(),
+ HealthcheckStatus.healthy,
+ System.currentTimeMillis(),
+ "http"));
+
+ serviceNodes.put(
+ ShardInfo.builder().environment("x").build(),
+ new ServiceNode<>("host2",
+ 8888,
+ ShardInfo.builder().environment("x.y").build(),
+ HealthcheckStatus.healthy,
+ System.currentTimeMillis(),
+ "http"));
+
+ doReturn(serviceNodes).when(serviceRegistry).nodes();
+
+ val nodes = selector("z").nodes(null, serviceRegistry);
+ assertEquals(0, nodes.size());
+ }
+
+ @Test
+ void testNodeAvailableForChildEnv() {
+ val serviceName = UUID.randomUUID().toString();
+ val service = Mockito.mock(Service.class);
+ doReturn(serviceName).when(service).getServiceName();
+ doReturn(service).when(serviceRegistry).getService();
+
+ val serviceNodes = ArrayListMultimap.create();
+ serviceNodes.put(
+ ShardInfo.builder().environment("x.y").build(),
+ new ServiceNode<>("host1",
+ 8888,
+ ShardInfo.builder().environment("x.y").build(),
+ HealthcheckStatus.healthy,
+ System.currentTimeMillis(),
+ "http"));
+ serviceNodes.put(
+ ShardInfo.builder().environment("x").build(),
+ new ServiceNode<>("host2",
+ 8888,
+ ShardInfo.builder().environment("x").build(),
+ HealthcheckStatus.healthy,
+ System.currentTimeMillis(),
+ "http"));
+ doReturn(serviceNodes).when(serviceRegistry).nodes();
+
+ val nodes = selector("x.y")
+ .nodes(null, serviceRegistry);
+ assertEquals(1, nodes.size());
+ assertEquals("host1", nodes.get(0).getHost());
+ assertEquals(8888, nodes.get(0).getPort());
+ }
+
+ private HierarchicalEnvironmentAwareShardSelector selector(String environment) {
+ return new HierarchicalEnvironmentAwareShardSelector(environment);
+ }
+
+ @Test
+ void testNoNodeAvailableForChildEnvButAvailableForParentEnv() {
+ val serviceName = UUID.randomUUID().toString();
+ val service = Mockito.mock(Service.class);
+ doReturn(serviceName).when(service).getServiceName();
+ doReturn(service).when(serviceRegistry).getService();
+
+ val serviceNodes = ArrayListMultimap.create();
+ serviceNodes.put(
+ ShardInfo.builder().environment("x.y.z").build(),
+ new ServiceNode<>("host1",
+ 8888,
+ ShardInfo.builder().environment("x.y").build(),
+ HealthcheckStatus.healthy,
+ System.currentTimeMillis(),
+ "http"));
+ serviceNodes.put(
+ ShardInfo.builder().environment("x").build(),
+ new ServiceNode<>("host2",
+ 9999,
+ ShardInfo.builder().environment("x").build(),
+ HealthcheckStatus.healthy,
+ System.currentTimeMillis(),
+ "http"));
+ doReturn(serviceNodes).when(serviceRegistry).nodes();
+
+ val nodes = selector("x.y").nodes(null, serviceRegistry);
+ assertEquals(1, nodes.size());
+ assertEquals("host2", nodes.get(0).getHost());
+ assertEquals(9999, nodes.get(0).getPort());
+ }
+}
\ No newline at end of file
diff --git a/ranger-http-client/pom.xml b/ranger-http-client/pom.xml
index 42d7c92b..ff13feea 100644
--- a/ranger-http-client/pom.xml
+++ b/ranger-http-client/pom.xml
@@ -5,7 +5,7 @@
ranger
io.appform.ranger
- 1.0-RC14
+ 1.0-RC15
4.0.0
@@ -23,17 +23,17 @@
${project.version}
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
-
-
- com.github.tomakehurst
+ org.wiremock
wiremock
${wiremock.version}
test
+
+
+ commons-fileupload
+ commons-fileupload
+
+
-
\ No newline at end of file
diff --git a/ranger-http-client/src/test/java/io/appform/ranger/client/http/BaseRangerHttpClientTest.java b/ranger-http-client/src/test/java/io/appform/ranger/client/http/BaseRangerHttpClientTest.java
index 6841320f..bdab6924 100644
--- a/ranger-http-client/src/test/java/io/appform/ranger/client/http/BaseRangerHttpClientTest.java
+++ b/ranger-http-client/src/test/java/io/appform/ranger/client/http/BaseRangerHttpClientTest.java
@@ -17,7 +17,7 @@
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.github.tomakehurst.wiremock.junit.WireMockRule;
+import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import io.appform.ranger.core.healthcheck.HealthcheckStatus;
@@ -31,9 +31,8 @@
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.extension.RegisterExtension;
import java.io.IOException;
@@ -45,12 +44,15 @@
public abstract class BaseRangerHttpClientTest {
private final ObjectMapper objectMapper = new ObjectMapper();
- @Rule
- public WireMockRule server = new WireMockRule(wireMockConfig().dynamicPort());
private HttpClientConfig httpClientConfig;
- @Before
- public void startTestCluster() throws Exception {
+ @RegisterExtension
+ static WireMockExtension wireMockExtension = WireMockExtension.newInstance()
+ .options(wireMockConfig().dynamicPort().dynamicHttpsPort())
+ .build();
+
+ @BeforeEach
+ public void prepareHttpMocks() throws Exception {
val testNode = TestNodeData.builder().shardId(1).build();
val node = ServiceNode.builder().host("127.0.0.1").port(80).nodeData(testNode).build();
node.setHealthcheckStatus(HealthcheckStatus.healthy);
@@ -59,7 +61,7 @@ public void startTestCluster() throws Exception {
ServiceNodesResponse.builder()
.data(Lists.newArrayList(node))
.build());
- server.stubFor(get(urlEqualTo("/ranger/nodes/v1/test-n/test-s"))
+ wireMockExtension.stubFor(get(urlEqualTo("/ranger/nodes/v1/test-n/test-s"))
.willReturn(aResponse()
.withBody(payload)
.withStatus(200)));
@@ -70,25 +72,20 @@ public void startTestCluster() throws Exception {
))
.build();
val response = objectMapper.writeValueAsBytes(responseObj);
- server.stubFor(get(urlEqualTo("/ranger/services/v1"))
+ wireMockExtension.stubFor(get(urlEqualTo("/ranger/services/v1"))
.willReturn(aResponse()
.withBody(response)
.withStatus(200)));
httpClientConfig = HttpClientConfig.builder()
.host("127.0.0.1")
- .port(server.port())
+ .port(wireMockExtension.getPort())
.connectionTimeoutMs(30_000)
.operationTimeoutMs(30_000)
.build();
log.debug("Started http subsystem");
}
- @After
- public void stopTestCluster() {
- log.debug("Stopping http subsystem");
- }
-
protected ServiceNodesResponse read(final byte[] data) {
try {
return getObjectMapper().readValue(data, new TypeReference>() {});
diff --git a/ranger-http-client/src/test/java/io/appform/ranger/client/http/ShardedRangerHttpClientTest.java b/ranger-http-client/src/test/java/io/appform/ranger/client/http/ShardedRangerHttpClientTest.java
index 6f5fae4c..1e09e1e6 100644
--- a/ranger-http-client/src/test/java/io/appform/ranger/client/http/ShardedRangerHttpClientTest.java
+++ b/ranger-http-client/src/test/java/io/appform/ranger/client/http/ShardedRangerHttpClientTest.java
@@ -18,13 +18,13 @@
import io.appform.ranger.core.units.TestNodeData;
import io.appform.ranger.core.utils.RangerTestUtils;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
-public class ShardedRangerHttpClientTest extends BaseRangerHttpClientTest {
+class ShardedRangerHttpClientTest extends BaseRangerHttpClientTest {
@Test
- public void testShardedHttpHubClient(){
+ void testShardedHttpHubClient(){
val client = ShardedRangerHttpHubClient.builder()
.clientConfig(getHttpClientConfig())
.namespace("test-n")
@@ -34,9 +34,9 @@ public void testShardedHttpHubClient(){
.build();
client.start();
val service = RangerTestUtils.getService("test-n", "test-s");
- Assert.assertNotNull(client.getNode(service).orElse(null));
- Assert.assertNotNull(client.getNode(service, nodeData -> nodeData.getShardId() == 1).orElse(null));
- Assert.assertNull(client.getNode(service, nodeData -> nodeData.getShardId() == 2).orElse(null));
+ Assertions.assertNotNull(client.getNode(service).orElse(null));
+ Assertions.assertNotNull(client.getNode(service, nodeData -> nodeData.getShardId() == 1).orElse(null));
+ Assertions.assertNull(client.getNode(service, nodeData -> nodeData.getShardId() == 2).orElse(null));
client.stop();
}
}
diff --git a/ranger-http-client/src/test/java/io/appform/ranger/client/http/SimpleRangerHttpClientTest.java b/ranger-http-client/src/test/java/io/appform/ranger/client/http/SimpleRangerHttpClientTest.java
index c37a07e9..e379f272 100644
--- a/ranger-http-client/src/test/java/io/appform/ranger/client/http/SimpleRangerHttpClientTest.java
+++ b/ranger-http-client/src/test/java/io/appform/ranger/client/http/SimpleRangerHttpClientTest.java
@@ -18,13 +18,13 @@
import io.appform.ranger.core.units.TestNodeData;
import io.appform.ranger.core.utils.RangerTestUtils;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
-public class SimpleRangerHttpClientTest extends BaseRangerHttpClientTest{
+class SimpleRangerHttpClientTest extends BaseRangerHttpClientTest{
@Test
- public void testSimpleHttpRangerClient(){
+ void testSimpleHttpRangerClient(){
val client = SimpleRangerHttpClient.builder()
.clientConfig(getHttpClientConfig())
.mapper(getObjectMapper())
@@ -35,10 +35,10 @@ public void testSimpleHttpRangerClient(){
.build();
client.start();
RangerTestUtils.sleepUntilFinderStarts(client.getServiceFinder());
- Assert.assertNotNull(client.getNode().orElse(null));
- Assert.assertFalse(client.getAllNodes().isEmpty());
- Assert.assertNotNull(client.getNode(nodeData -> nodeData.getShardId() == 1).orElse(null));
- Assert.assertFalse(client.getAllNodes(nodeData -> nodeData.getShardId() == 1).isEmpty());
+ Assertions.assertNotNull(client.getNode().orElse(null));
+ Assertions.assertFalse(client.getAllNodes().isEmpty());
+ Assertions.assertNotNull(client.getNode(nodeData -> nodeData.getShardId() == 1).orElse(null));
+ Assertions.assertFalse(client.getAllNodes(nodeData -> nodeData.getShardId() == 1).isEmpty());
client.stop();
}
}
diff --git a/ranger-http-client/src/test/java/io/appform/ranger/client/http/UnshardedRangerHttpClientTest.java b/ranger-http-client/src/test/java/io/appform/ranger/client/http/UnshardedRangerHttpClientTest.java
index 9470a32f..a3ced34c 100644
--- a/ranger-http-client/src/test/java/io/appform/ranger/client/http/UnshardedRangerHttpClientTest.java
+++ b/ranger-http-client/src/test/java/io/appform/ranger/client/http/UnshardedRangerHttpClientTest.java
@@ -18,13 +18,13 @@
import io.appform.ranger.core.units.TestNodeData;
import io.appform.ranger.core.utils.RangerTestUtils;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
-public class UnshardedRangerHttpClientTest extends BaseRangerHttpClientTest {
+class UnshardedRangerHttpClientTest extends BaseRangerHttpClientTest {
@Test
- public void testUnshardedRangerHubClient(){
+ void testUnshardedRangerHubClient(){
val client = UnshardedRangerHttpHubClient.builder()
.clientConfig(getHttpClientConfig())
.namespace("test-n")
@@ -34,9 +34,9 @@ public void testUnshardedRangerHubClient(){
.build();
client.start();
val service = RangerTestUtils.getService("test-n", "test-s");
- Assert.assertNotNull(client.getNode(service).orElse(null));
- Assert.assertNotNull(client.getNode(service, nodeData -> nodeData.getShardId() == 1).orElse(null));
- Assert.assertNull(client.getNode(service, nodeData -> nodeData.getShardId() == 2).orElse(null));
+ Assertions.assertNotNull(client.getNode(service).orElse(null));
+ Assertions.assertNotNull(client.getNode(service, nodeData -> nodeData.getShardId() == 1).orElse(null));
+ Assertions.assertNull(client.getNode(service, nodeData -> nodeData.getShardId() == 2).orElse(null));
client.stop();
}
}
diff --git a/ranger-http-model/pom.xml b/ranger-http-model/pom.xml
index 30d69a33..d3937423 100644
--- a/ranger-http-model/pom.xml
+++ b/ranger-http-model/pom.xml
@@ -5,18 +5,9 @@
ranger
io.appform.ranger
- 1.0-RC14
+ 1.0-RC15
4.0.0
ranger-http-model
-
-
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
-
-
-
\ No newline at end of file
diff --git a/ranger-http-server-bundle/pom.xml b/ranger-http-server-bundle/pom.xml
index aec77d72..740183ff 100644
--- a/ranger-http-server-bundle/pom.xml
+++ b/ranger-http-server-bundle/pom.xml
@@ -5,14 +5,14 @@
ranger
io.appform.ranger
- 1.0-RC14
+ 1.0-RC15
4.0.0
ranger-http-server-bundle
- 2.0.23
+ 2.1.10
@@ -31,15 +31,9 @@
ranger-server-common
${project.version}
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
-
io.dropwizard
dropwizard-core
- ${dropwizard.version}
provided
diff --git a/ranger-http-server-bundle/src/main/java/io/appform/ranger/http/server/bundle/HttpServerBundle.java b/ranger-http-server-bundle/src/main/java/io/appform/ranger/http/server/bundle/HttpServerBundle.java
index 159ad237..a40e02b3 100644
--- a/ranger-http-server-bundle/src/main/java/io/appform/ranger/http/server/bundle/HttpServerBundle.java
+++ b/ranger-http-server-bundle/src/main/java/io/appform/ranger/http/server/bundle/HttpServerBundle.java
@@ -17,14 +17,10 @@
import com.codahale.metrics.health.HealthCheck;
import com.fasterxml.jackson.core.type.TypeReference;
-import com.google.common.collect.ImmutableList;
import io.appform.ranger.client.RangerHubClient;
-import io.appform.ranger.client.http.ShardedRangerHttpHubClient;
import io.appform.ranger.client.http.UnshardedRangerHttpHubClient;
import io.appform.ranger.common.server.ShardInfo;
import io.appform.ranger.core.finder.serviceregistry.ListBasedServiceRegistry;
-import io.appform.ranger.core.finder.serviceregistry.MapBasedServiceRegistry;
-import io.appform.ranger.http.model.ServiceNodesResponse;
import io.appform.ranger.http.server.bundle.config.RangerHttpConfiguration;
import io.appform.ranger.http.server.bundle.healthcheck.RangerHttpHealthCheck;
import io.appform.ranger.server.bundle.RangerServerBundle;
@@ -56,7 +52,7 @@ protected List>>
.nodeRefreshTimeMs(rangerConfiguration.getNodeRefreshTimeMs())
.deserializer(data -> {
try {
- return getMapper().readValue(data, new TypeReference>() {
+ return getMapper().readValue(data, new TypeReference<>() {
});
} catch (IOException e) {
log.warn("Error parsing node data with value {}", new String(data));
@@ -67,6 +63,6 @@ protected List>>
}
protected List withHealthChecks(U configuration) {
- return ImmutableList.of(new RangerHttpHealthCheck());
+ return List.of(new RangerHttpHealthCheck());
}
}
diff --git a/ranger-http-server/config/local.yml b/ranger-http-server/config/local.yml
index 67d450c5..bffca045 100644
--- a/ranger-http-server/config/local.yml
+++ b/ranger-http-server/config/local.yml
@@ -1,6 +1,5 @@
name: ranger-http-server
-initialRotationStatus: false
rangerConfiguration:
namespace: test
diff --git a/ranger-http-server/pom.xml b/ranger-http-server/pom.xml
index 5972c301..4989fdb9 100644
--- a/ranger-http-server/pom.xml
+++ b/ranger-http-server/pom.xml
@@ -5,16 +5,12 @@
ranger
io.appform.ranger
- 1.0-RC14
+ 1.0-RC15
4.0.0
ranger-http-server
-
- 2.0.23
-
-
io.appform.ranger
@@ -24,22 +20,6 @@
io.dropwizard
dropwizard-core
- ${dropwizard.version}
-
-
- ch.qos.logback
- logback-classic
- ${logback.version}
-
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
-
-
- com.fasterxml.jackson.core
- jackson-annotations
- ${jackson.version}
diff --git a/ranger-http-server/src/main/java/io/appform/ranger/http/server/App.java b/ranger-http-server/src/main/java/io/appform/ranger/http/server/App.java
index 75698075..e482827a 100644
--- a/ranger-http-server/src/main/java/io/appform/ranger/http/server/App.java
+++ b/ranger-http-server/src/main/java/io/appform/ranger/http/server/App.java
@@ -29,7 +29,7 @@ public static void main(String[] args) throws Exception {
@Override
public void initialize(Bootstrap bootstrap) {
- bootstrap.addBundle(new HttpServerBundle() {
+ bootstrap.addBundle(new HttpServerBundle<>() {
@Override
protected RangerHttpConfiguration getRangerConfiguration(HttpAppConfiguration configuration) {
return configuration.getRangerConfiguration();
diff --git a/ranger-http-server/src/main/java/io/appform/ranger/http/server/HttpAppConfiguration.java b/ranger-http-server/src/main/java/io/appform/ranger/http/server/HttpAppConfiguration.java
index 259a915c..d2a5c4e3 100644
--- a/ranger-http-server/src/main/java/io/appform/ranger/http/server/HttpAppConfiguration.java
+++ b/ranger-http-server/src/main/java/io/appform/ranger/http/server/HttpAppConfiguration.java
@@ -15,6 +15,7 @@
*/
package io.appform.ranger.http.server;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.appform.ranger.http.server.bundle.config.RangerHttpConfiguration;
import io.dropwizard.Configuration;
import lombok.AllArgsConstructor;
@@ -30,6 +31,7 @@
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
+@JsonIgnoreProperties(ignoreUnknown = true)
public class HttpAppConfiguration extends Configuration {
@NotEmpty
@NotNull
diff --git a/ranger-http/pom.xml b/ranger-http/pom.xml
index f8770bfd..ab190b79 100644
--- a/ranger-http/pom.xml
+++ b/ranger-http/pom.xml
@@ -5,7 +5,7 @@
ranger
io.appform.ranger
- 1.0-RC14
+ 1.0-RC15
4.0.0
@@ -28,20 +28,16 @@
${http.client.version}
- com.fasterxml.jackson.core
- jackson-annotations
- ${jackson.version}
-
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
-
-
- com.github.tomakehurst
+ org.wiremock
wiremock
${wiremock.version}
test
+
+
+ commons-fileupload
+ commons-fileupload
+
+
io.appform.ranger
diff --git a/ranger-http/src/test/java/io/appform/ranger/http/common/HttpNodeDataStoreConnectorTest.java b/ranger-http/src/test/java/io/appform/ranger/http/common/HttpNodeDataStoreConnectorTest.java
index 0f4c98b0..07e76767 100644
--- a/ranger-http/src/test/java/io/appform/ranger/http/common/HttpNodeDataStoreConnectorTest.java
+++ b/ranger-http/src/test/java/io/appform/ranger/http/common/HttpNodeDataStoreConnectorTest.java
@@ -18,20 +18,20 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import io.appform.ranger.http.config.HttpClientConfig;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
-public class HttpNodeDataStoreConnectorTest {
+class HttpNodeDataStoreConnectorTest {
@Test
- public void testHttpNodeDataStoreConnector(){
+ void testHttpNodeDataStoreConnector(){
val objectMapper = new ObjectMapper();
val httpClientConfig = HttpClientConfig.builder()
.host("localhost-1")
.port(80)
.build();
val httpNodeDataStoreConnector = new HttpNodeDataStoreConnector<>(httpClientConfig, objectMapper);
- Assert.assertNotNull(httpNodeDataStoreConnector);
- Assert.assertTrue(httpNodeDataStoreConnector.isActive());
+ Assertions.assertNotNull(httpNodeDataStoreConnector);
+ Assertions.assertTrue(httpNodeDataStoreConnector.isActive());
}
}
diff --git a/ranger-http/src/test/java/io/appform/ranger/http/config/HttpClientConfigTest.java b/ranger-http/src/test/java/io/appform/ranger/http/config/HttpClientConfigTest.java
index a272610e..aef7a34c 100644
--- a/ranger-http/src/test/java/io/appform/ranger/http/config/HttpClientConfigTest.java
+++ b/ranger-http/src/test/java/io/appform/ranger/http/config/HttpClientConfigTest.java
@@ -17,18 +17,18 @@
import io.appform.ranger.http.ResourceHelper;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
-public class HttpClientConfigTest {
+class HttpClientConfigTest {
@Test
- public void testHttpClientConfig(){
+ void testHttpClientConfig(){
val resource = ResourceHelper.getResource("fixtures/httpClientConfig.json", HttpClientConfig.class);
- Assert.assertNotNull(resource);
- Assert.assertEquals("localhost-1", resource.getHost());
- Assert.assertEquals(80, resource.getPort());
- Assert.assertEquals(10, resource.getConnectionTimeoutMs());
- Assert.assertEquals(10, resource.getOperationTimeoutMs());
+ Assertions.assertNotNull(resource);
+ Assertions.assertEquals("localhost-1", resource.getHost());
+ Assertions.assertEquals(80, resource.getPort());
+ Assertions.assertEquals(10, resource.getConnectionTimeoutMs());
+ Assertions.assertEquals(10, resource.getOperationTimeoutMs());
}
}
diff --git a/ranger-http/src/test/java/io/appform/ranger/http/model/ServiceNodeResponseTest.java b/ranger-http/src/test/java/io/appform/ranger/http/model/ServiceNodeResponseTest.java
index ae706110..f5d77eb8 100644
--- a/ranger-http/src/test/java/io/appform/ranger/http/model/ServiceNodeResponseTest.java
+++ b/ranger-http/src/test/java/io/appform/ranger/http/model/ServiceNodeResponseTest.java
@@ -21,8 +21,8 @@
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
public class ServiceNodeResponseTest {
@@ -37,11 +37,11 @@ static class TestNodeInfo{
@Test
public void testServiceNodesResponse(){
val serviceNodesResponse = ResourceHelper.getResource("fixtures/serviceNodesResponse.json", ServiceNodesResponse.class);
- Assert.assertNotNull(serviceNodesResponse);
- Assert.assertFalse(serviceNodesResponse.getData().isEmpty());
- Assert.assertNotNull(((ServiceNode>) serviceNodesResponse.getData().get(0)).getNodeData());
- Assert.assertNotNull(((ServiceNode>) serviceNodesResponse.getData().get(1)).getNodeData());
- Assert.assertEquals("localhost-1", ((ServiceNode>) serviceNodesResponse.getData().get(0)).getHost());
- Assert.assertEquals("localhost-2", ((ServiceNode>) serviceNodesResponse.getData().get(1)).getHost());
+ Assertions.assertNotNull(serviceNodesResponse);
+ Assertions.assertFalse(serviceNodesResponse.getData().isEmpty());
+ Assertions.assertNotNull(((ServiceNode>) serviceNodesResponse.getData().get(0)).getNodeData());
+ Assertions.assertNotNull(((ServiceNode>) serviceNodesResponse.getData().get(1)).getNodeData());
+ Assertions.assertEquals("localhost-1", ((ServiceNode>) serviceNodesResponse.getData().get(0)).getHost());
+ Assertions.assertEquals("localhost-2", ((ServiceNode>) serviceNodesResponse.getData().get(1)).getHost());
}
}
diff --git a/ranger-http/src/test/java/io/appform/ranger/http/model/ServiceRegistrationResponseTest.java b/ranger-http/src/test/java/io/appform/ranger/http/model/ServiceRegistrationResponseTest.java
index 69375dda..95a18148 100644
--- a/ranger-http/src/test/java/io/appform/ranger/http/model/ServiceRegistrationResponseTest.java
+++ b/ranger-http/src/test/java/io/appform/ranger/http/model/ServiceRegistrationResponseTest.java
@@ -17,15 +17,15 @@
import io.appform.ranger.http.ResourceHelper;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
public class ServiceRegistrationResponseTest {
@Test
public void testServiceRegistrationResponse(){
val resource = ResourceHelper.getResource("fixtures/serviceResponse.json", ServiceRegistrationResponse.class);
- Assert.assertNotNull(resource);
- Assert.assertTrue(resource.valid());
+ Assertions.assertNotNull(resource);
+ Assertions.assertTrue(resource.valid());
}
}
diff --git a/ranger-http/src/test/java/io/appform/ranger/http/servicefinder/HttpShardedServiceFinderBuilderTest.java b/ranger-http/src/test/java/io/appform/ranger/http/servicefinder/HttpShardedServiceFinderBuilderTest.java
index 26ef7efd..df51b998 100644
--- a/ranger-http/src/test/java/io/appform/ranger/http/servicefinder/HttpShardedServiceFinderBuilderTest.java
+++ b/ranger-http/src/test/java/io/appform/ranger/http/servicefinder/HttpShardedServiceFinderBuilderTest.java
@@ -18,7 +18,8 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.github.tomakehurst.wiremock.junit.WireMockRule;
+import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
+import com.github.tomakehurst.wiremock.junit5.WireMockTest;
import io.appform.ranger.core.healthcheck.HealthcheckStatus;
import io.appform.ranger.core.model.ServiceNode;
import io.appform.ranger.core.utils.RangerTestUtils;
@@ -26,20 +27,19 @@
import io.appform.ranger.http.model.ServiceNodesResponse;
import lombok.Data;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.Collections;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
-import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
/**
*
*/
-public class HttpShardedServiceFinderBuilderTest {
+@WireMockTest
+class HttpShardedServiceFinderBuilderTest {
@Data
private static final class NodeData {
@@ -52,11 +52,8 @@ public NodeData(@JsonProperty("name") String name) {
private static final ObjectMapper MAPPER = new ObjectMapper();
- @Rule
- public WireMockRule server = new WireMockRule(wireMockConfig().dynamicPort());
-
@Test
- public void testFinder() throws Exception {
+ void testFinder(WireMockRuntimeInfo wireMockRuntimeInfo) throws Exception {
val testNode = new NodeData("testNode");
val node = ServiceNode.builder().host("127.0.0.1").port(80).nodeData(testNode).build();
node.setHealthcheckStatus(HealthcheckStatus.healthy);
@@ -65,13 +62,13 @@ public void testFinder() throws Exception {
ServiceNodesResponse.builder()
.data(Collections.singletonList(node))
.build());
- server.stubFor(get(urlEqualTo("/ranger/nodes/v1/testns/test"))
+ stubFor(get(urlEqualTo("/ranger/nodes/v1/testns/test"))
.willReturn(aResponse()
.withBody(payload)
.withStatus(200)));
val clientConfig = HttpClientConfig.builder()
.host("127.0.0.1")
- .port(server.port())
+ .port(wireMockRuntimeInfo.getHttpPort())
.connectionTimeoutMs(30_000)
.operationTimeoutMs(30_000)
.build();
@@ -94,7 +91,7 @@ public void testFinder() throws Exception {
.build();
finder.start();
RangerTestUtils.sleepUntilFinderStarts(finder);
- Assert.assertNotNull(finder.get(nodeData -> true).orElse(null));
+ Assertions.assertNotNull(finder.get(nodeData -> true).orElse(null));
}
}
\ No newline at end of file
diff --git a/ranger-http/src/test/java/io/appform/ranger/http/servicefinderhub/HttpServiceDataSourceTest.java b/ranger-http/src/test/java/io/appform/ranger/http/servicefinderhub/HttpServiceDataSourceTest.java
index 97175fc1..1996364f 100644
--- a/ranger-http/src/test/java/io/appform/ranger/http/servicefinderhub/HttpServiceDataSourceTest.java
+++ b/ranger-http/src/test/java/io/appform/ranger/http/servicefinderhub/HttpServiceDataSourceTest.java
@@ -16,30 +16,26 @@
package io.appform.ranger.http.servicefinderhub;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.github.tomakehurst.wiremock.junit.WireMockRule;
+import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
+import com.github.tomakehurst.wiremock.junit5.WireMockTest;
import com.google.common.collect.Sets;
import io.appform.ranger.core.utils.RangerTestUtils;
import io.appform.ranger.http.config.HttpClientConfig;
import io.appform.ranger.http.model.ServiceDataSourceResponse;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
import java.io.IOException;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
-import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
-public class HttpServiceDataSourceTest {
+@WireMockTest
+class HttpServiceDataSourceTest {
private static final ObjectMapper MAPPER = new ObjectMapper();
-
- @Rule
- public WireMockRule server = new WireMockRule(wireMockConfig().dynamicPort());
-
@Test
- public void testServiceDataSource() throws IOException {
+ void testServiceDataSource(WireMockRuntimeInfo wireMockRuntimeInfo) throws IOException {
val responseObj = ServiceDataSourceResponse.builder()
.data(Sets.newHashSet(
RangerTestUtils.getService("test-n", "test-s"),
@@ -48,24 +44,24 @@ public void testServiceDataSource() throws IOException {
))
.build();
val response = MAPPER.writeValueAsBytes(responseObj);
- server.stubFor(get(urlEqualTo("/ranger/services/v1"))
+ stubFor(get(urlEqualTo("/ranger/services/v1"))
.willReturn(aResponse()
.withBody(response)
.withStatus(200)));
val clientConfig = HttpClientConfig.builder()
.host("127.0.0.1")
- .port(server.port())
+ .port(wireMockRuntimeInfo.getHttpPort())
.connectionTimeoutMs(30_000)
.operationTimeoutMs(30_000)
.build();
val httpServiceDataSource = new HttpServiceDataSource<>(clientConfig, MAPPER);
val services = httpServiceDataSource.services();
- Assert.assertNotNull(services);
- Assert.assertFalse(services.isEmpty());
- Assert.assertEquals(3, services.size());
- Assert.assertFalse(services.stream().noneMatch(each -> each.getServiceName().equalsIgnoreCase("test-s")));
- Assert.assertFalse(services.stream().noneMatch(each -> each.getServiceName().equalsIgnoreCase("test-s1")));
- Assert.assertFalse(services.stream().noneMatch(each -> each.getServiceName().equalsIgnoreCase("test-s2")));
+ Assertions.assertNotNull(services);
+ Assertions.assertFalse(services.isEmpty());
+ Assertions.assertEquals(3, services.size());
+ Assertions.assertFalse(services.stream().noneMatch(each -> each.getServiceName().equalsIgnoreCase("test-s")));
+ Assertions.assertFalse(services.stream().noneMatch(each -> each.getServiceName().equalsIgnoreCase("test-s1")));
+ Assertions.assertFalse(services.stream().noneMatch(each -> each.getServiceName().equalsIgnoreCase("test-s2")));
}
}
diff --git a/ranger-http/src/test/java/io/appform/ranger/http/serviceprovider/HttpShardedServiceProviderBuilderTest.java b/ranger-http/src/test/java/io/appform/ranger/http/serviceprovider/HttpShardedServiceProviderBuilderTest.java
index 6c1936d3..39cd8cb2 100644
--- a/ranger-http/src/test/java/io/appform/ranger/http/serviceprovider/HttpShardedServiceProviderBuilderTest.java
+++ b/ranger-http/src/test/java/io/appform/ranger/http/serviceprovider/HttpShardedServiceProviderBuilderTest.java
@@ -17,7 +17,8 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.github.tomakehurst.wiremock.junit.WireMockRule;
+import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
+import com.github.tomakehurst.wiremock.junit5.WireMockTest;
import io.appform.ranger.core.healthcheck.Healthchecks;
import io.appform.ranger.core.model.PortSchemes;
import io.appform.ranger.core.model.ServiceNode;
@@ -26,14 +27,13 @@
import lombok.Builder;
import lombok.Data;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
-import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
-public class HttpShardedServiceProviderBuilderTest {
+@WireMockTest
+class HttpShardedServiceProviderBuilderTest {
@Data
private static final class TestNodeData {
@@ -47,14 +47,11 @@ public TestNodeData(@JsonProperty("farmId") String farmId) {
private static final ObjectMapper MAPPER = new ObjectMapper();
- @Rule
- public WireMockRule server = new WireMockRule(wireMockConfig().dynamicPort());
-
@Test
- public void testProvider() throws Exception {
+ void testProvider(WireMockRuntimeInfo wireMockRuntimeInfo) throws Exception {
val farmNodeData = TestNodeData.builder().farmId("farm1").build();
val testNode = ServiceNode.builder().host("127.0.0.1").port(80).nodeData(farmNodeData).build();
- Assert.assertEquals(PortSchemes.HTTP, testNode.getPortScheme());
+ Assertions.assertEquals(PortSchemes.HTTP, testNode.getPortScheme());
val response = MAPPER.writeValueAsBytes(
GenericResponse.builder()
.data(ServiceNode.builder()
@@ -64,14 +61,14 @@ public void testProvider() throws Exception {
)
.build());
byte[] requestBytes = MAPPER.writeValueAsBytes(testNode);
- server.stubFor(post(urlEqualTo("/ranger/nodes/v1/add/testns/test"))
+ stubFor(post(urlEqualTo("/ranger/nodes/v1/add/testns/test"))
.withRequestBody(binaryEqualTo(requestBytes))
.willReturn(aResponse()
.withBody(response)
.withStatus(200)));
val clientConfig = HttpClientConfig.builder()
.host("127.0.0.1")
- .port(server.port())
+ .port(wireMockRuntimeInfo.getHttpPort())
.connectionTimeoutMs(30_000)
.operationTimeoutMs(30_000)
.build();
@@ -88,7 +85,7 @@ public void testProvider() throws Exception {
.withSerializer(node -> requestBytes)
.build();
serviceProvider.start();
- Assert.assertNotNull(serviceProvider);
+ Assertions.assertNotNull(serviceProvider);
}
}
diff --git a/ranger-server-bundle/pom.xml b/ranger-server-bundle/pom.xml
index ad3b6f69..ba3c9510 100644
--- a/ranger-server-bundle/pom.xml
+++ b/ranger-server-bundle/pom.xml
@@ -5,37 +5,26 @@
ranger
io.appform.ranger
- 1.0-RC14
+ 1.0-RC15
4.0.0
ranger-server-bundle
-
- 2.0.23
-
-
io.appform.ranger
ranger-client
${project.version}
-
io.appform.ranger
ranger-http-model
${project.version}
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
-
io.dropwizard
dropwizard-core
- ${dropwizard.version}
provided
diff --git a/ranger-server-bundle/src/test/java/io/appform/ranger/server/bundle/RangerServerBundleTest.java b/ranger-server-bundle/src/test/java/io/appform/ranger/server/bundle/RangerServerBundleTest.java
index e5fc1576..b5059bcd 100644
--- a/ranger-server-bundle/src/test/java/io/appform/ranger/server/bundle/RangerServerBundleTest.java
+++ b/ranger-server-bundle/src/test/java/io/appform/ranger/server/bundle/RangerServerBundleTest.java
@@ -33,12 +33,8 @@
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import lombok.val;
-import lombok.var;
import org.eclipse.jetty.util.component.LifeCycle;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.*;
import java.util.Collections;
import java.util.List;
@@ -49,15 +45,15 @@
public class RangerServerBundleTest {
- private final JerseyEnvironment jerseyEnvironment = mock(JerseyEnvironment.class);
- private final MetricRegistry metricRegistry = mock(MetricRegistry.class);
- private final LifecycleEnvironment lifecycleEnvironment = new LifecycleEnvironment(metricRegistry);
- private final Environment environment = mock(Environment.class);
- private final Bootstrap> bootstrap = mock(Bootstrap.class);
- private final Configuration configuration = mock(Configuration.class);
+ private static final JerseyEnvironment JERSEY_ENVIRONMENT = mock(JerseyEnvironment.class);
+ private static final MetricRegistry METRIC_REGISTRY = mock(MetricRegistry.class);
+ private static final LifecycleEnvironment LIFECYCLE_ENVIRONMENT = new LifecycleEnvironment(METRIC_REGISTRY);
+ private static final Environment ENVIRONMENT = mock(Environment.class);
+ private static final Bootstrap> BOOTSTRAP = mock(Bootstrap.class);
+ private static final Configuration CONFIGURATION = mock(Configuration.class);
- private final RangerServerBundle, Configuration>
- rangerServerBundle = new RangerServerBundle, Configuration>() {
+ private static final RangerServerBundle, Configuration>
+ RANGER_SERVER_BUNDLE = new RangerServerBundle<>() {
@Override
protected List>> withHubs(Configuration configuration) {
@@ -70,46 +66,46 @@ protected List withHealthChecks(Configuration configuration) {
}
};
- @Before
- public void setup() throws Exception {
- when(jerseyEnvironment.getResourceConfig()).thenReturn(new DropwizardResourceConfig());
- when(environment.jersey()).thenReturn(jerseyEnvironment);
- when(environment.lifecycle()).thenReturn(lifecycleEnvironment);
- when(environment.getObjectMapper()).thenReturn(new ObjectMapper());
+ @BeforeAll
+ public static void setup() throws Exception {
+ when(JERSEY_ENVIRONMENT.getResourceConfig()).thenReturn(new DropwizardResourceConfig());
+ when(ENVIRONMENT.jersey()).thenReturn(JERSEY_ENVIRONMENT);
+ when(ENVIRONMENT.lifecycle()).thenReturn(LIFECYCLE_ENVIRONMENT);
+ when(ENVIRONMENT.getObjectMapper()).thenReturn(new ObjectMapper());
val adminEnvironment = mock(AdminEnvironment.class);
doNothing().when(adminEnvironment).addTask(any());
- when(environment.admin()).thenReturn(adminEnvironment);
+ when(ENVIRONMENT.admin()).thenReturn(adminEnvironment);
val healthCheckRegistry = mock(HealthCheckRegistry.class);
doNothing().when(healthCheckRegistry).register(anyString(), any());
- when(environment.healthChecks()).thenReturn(healthCheckRegistry);
+ when(ENVIRONMENT.healthChecks()).thenReturn(healthCheckRegistry);
- rangerServerBundle.initialize(bootstrap);
- rangerServerBundle.run(configuration, environment);
- for (val lifeCycle : lifecycleEnvironment.getManagedObjects()) {
+ RANGER_SERVER_BUNDLE.initialize(BOOTSTRAP);
+ RANGER_SERVER_BUNDLE.run(CONFIGURATION, ENVIRONMENT);
+ for (val lifeCycle : LIFECYCLE_ENVIRONMENT.getManagedObjects()) {
lifeCycle.start();
}
}
@Test
- public void testRangerBundle() {
- var hub = rangerServerBundle.getHubs().get(0);
- Assert.assertTrue(hub instanceof RangerTestHub);
+ void testRangerBundle() {
+ var hub = RANGER_SERVER_BUNDLE.getHubs().get(0);
+ Assertions.assertTrue(hub instanceof RangerTestHub);
var node = hub.getNode(service).orElse(null);
- Assert.assertNotNull(node);
- Assert.assertTrue(node.getHost().equalsIgnoreCase("localhost"));
- Assert.assertEquals(9200, node.getPort());
- Assert.assertEquals(1, node.getNodeData().getShardId());
- Assert.assertNull(hub.getNode(RangerTestUtils.getService("test", "test")).orElse(null));
- Assert.assertNull(hub.getNode(service, nodeData -> nodeData.getShardId() == 2).orElse(null));
- Assert.assertNull(hub.getNode(RangerTestUtils.getService("test", "test"),
+ Assertions.assertNotNull(node);
+ Assertions.assertTrue(node.getHost().equalsIgnoreCase("localhost"));
+ Assertions.assertEquals(9200, node.getPort());
+ Assertions.assertEquals(1, node.getNodeData().getShardId());
+ Assertions.assertNull(hub.getNode(RangerTestUtils.getService("test", "test")).orElse(null));
+ Assertions.assertNull(hub.getNode(service, nodeData -> nodeData.getShardId() == 2).orElse(null));
+ Assertions.assertNull(hub.getNode(RangerTestUtils.getService("test", "test"),
nodeData -> nodeData.getShardId() == 1).orElse(null));
}
- @After
- public void tearDown() throws Exception {
- for (LifeCycle lifeCycle : lifecycleEnvironment.getManagedObjects()) {
+ @AfterAll
+ public static void tearDown() throws Exception {
+ for (LifeCycle lifeCycle : LIFECYCLE_ENVIRONMENT.getManagedObjects()) {
lifeCycle.stop();
}
}
diff --git a/ranger-server-common/pom.xml b/ranger-server-common/pom.xml
index fe745dbf..ab777715 100644
--- a/ranger-server-common/pom.xml
+++ b/ranger-server-common/pom.xml
@@ -5,17 +5,10 @@
ranger
io.appform.ranger
- 1.0-RC14
+ 1.0-RC15
4.0.0
ranger-server-common
-
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
-
-
\ No newline at end of file
diff --git a/ranger-server-common/src/test/java/io/appform/ranger/common/server/ShardInfoTest.java b/ranger-server-common/src/test/java/io/appform/ranger/common/server/ShardInfoTest.java
index 284621fd..9c86b9df 100644
--- a/ranger-server-common/src/test/java/io/appform/ranger/common/server/ShardInfoTest.java
+++ b/ranger-server-common/src/test/java/io/appform/ranger/common/server/ShardInfoTest.java
@@ -3,8 +3,8 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
import java.io.BufferedReader;
import java.io.InputStreamReader;
@@ -36,14 +36,14 @@ private T getResource(String path, Class klass) {
public void testShardInfo(){
val shardInfo1 = getResource("fixtures/env1.json", ShardInfo.class);
val shardInfo2 = getResource("fixtures/env2.json", ShardInfo.class);
- Assert.assertNotNull(shardInfo1);
- Assert.assertNotNull(shardInfo2);
- Assert.assertNotEquals(shardInfo1, shardInfo2);
- Arrays.asList(shardInfo1, shardInfo2).forEach(shardInfo -> Assert.assertEquals("e", shardInfo.getEnvironment()));
- Assert.assertEquals("r", shardInfo1.getRegion());
- Assert.assertNull(shardInfo2.getRegion());
- Assert.assertNotNull(shardInfo1.getTags());
- Assert.assertNotNull(shardInfo2.getTags());
- Assert.assertTrue(shardInfo2.getTags().contains("tag1"));
+ Assertions.assertNotNull(shardInfo1);
+ Assertions.assertNotNull(shardInfo2);
+ Assertions.assertNotEquals(shardInfo1, shardInfo2);
+ Arrays.asList(shardInfo1, shardInfo2).forEach(shardInfo -> Assertions.assertEquals("e", shardInfo.getEnvironment()));
+ Assertions.assertEquals("r", shardInfo1.getRegion());
+ Assertions.assertNull(shardInfo2.getRegion());
+ Assertions.assertNotNull(shardInfo1.getTags());
+ Assertions.assertNotNull(shardInfo2.getTags());
+ Assertions.assertTrue(shardInfo2.getTags().contains("tag1"));
}
}
diff --git a/ranger-zk-client/pom.xml b/ranger-zk-client/pom.xml
index 9c42804b..8b6443d3 100644
--- a/ranger-zk-client/pom.xml
+++ b/ranger-zk-client/pom.xml
@@ -5,7 +5,7 @@
ranger
io.appform.ranger
- 1.0-RC14
+ 1.0-RC15
4.0.0
@@ -22,11 +22,6 @@
ranger-client
${project.version}
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
-
org.apache.curator
curator-test
diff --git a/ranger-zk-client/src/test/java/io/appform/ranger/client/zk/BaseRangerZKClientTest.java b/ranger-zk-client/src/test/java/io/appform/ranger/client/zk/BaseRangerZKClientTest.java
index 4b804b02..7f7c69e4 100644
--- a/ranger-zk-client/src/test/java/io/appform/ranger/client/zk/BaseRangerZKClientTest.java
+++ b/ranger-zk-client/src/test/java/io/appform/ranger/client/zk/BaseRangerZKClientTest.java
@@ -33,8 +33,9 @@
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.test.TestingCluster;
-import org.junit.After;
-import org.junit.Before;
+import org.junit.jupiter.api.AfterEach;
+
+import org.junit.jupiter.api.BeforeEach;
import java.io.IOException;
import java.util.Collections;
@@ -49,7 +50,7 @@ public abstract class BaseRangerZKClientTest {
private CuratorFramework curatorFramework;
private ServiceProvider> provider;
- @Before
+ @BeforeEach
public void startTestCluster() throws Exception {
objectMapper = new ObjectMapper();
testingCluster = new TestingCluster(3);
@@ -65,7 +66,7 @@ public void startTestCluster() throws Exception {
log.debug("Started zk subsystem");
}
- @After
+ @AfterEach
public void stopTestCluster() throws Exception {
log.debug("Stopping zk subsystem");
curatorFramework.close();
@@ -112,7 +113,7 @@ protected void initilizeProvider(){
.withNodeData(TestNodeData.builder().shardId(1).build())
.withHealthcheck(() -> HealthcheckStatus.healthy)
.withAdditionalRefreshSignal(refreshProviderSignal)
- .withCuratorFramework(getCuratorFramework())
+ .withCuratorFramework(curatorFramework)
.build();
provider.start();
refreshProviderSignal.trigger();
diff --git a/ranger-zk-client/src/test/java/io/appform/ranger/client/zk/ShardedZKRangerClientTest.java b/ranger-zk-client/src/test/java/io/appform/ranger/client/zk/ShardedZKRangerClientTest.java
index efb3685a..cfbfac71 100644
--- a/ranger-zk-client/src/test/java/io/appform/ranger/client/zk/ShardedZKRangerClientTest.java
+++ b/ranger-zk-client/src/test/java/io/appform/ranger/client/zk/ShardedZKRangerClientTest.java
@@ -19,14 +19,14 @@
import io.appform.ranger.core.utils.RangerTestUtils;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
@Slf4j
-public class ShardedZKRangerClientTest extends BaseRangerZKClientTest {
+class ShardedZKRangerClientTest extends BaseRangerZKClientTest {
@Test
- public void testShardedHub(){
+ void testShardedHub(){
val zkHubClient = ShardedRangerZKHubClient.builder()
.namespace("test-n")
.connectionString(getTestingCluster().getConnectString())
@@ -37,8 +37,8 @@ public void testShardedHub(){
.nodeRefreshTimeMs(1000)
.build();
zkHubClient.start();
- Assert.assertNotNull(zkHubClient.getNode(RangerTestUtils.getService("test-n", "s1")).orElse(null));
- Assert.assertNotNull(zkHubClient.getNode(RangerTestUtils.getService("test-n", "s1"), nodeData -> nodeData.getShardId() == 1).orElse(null));
+ Assertions.assertNotNull(zkHubClient.getNode(RangerTestUtils.getService("test-n", "s1")).orElse(null));
+ Assertions.assertNotNull(zkHubClient.getNode(RangerTestUtils.getService("test-n", "s1"), nodeData -> nodeData.getShardId() == 1).orElse(null));
zkHubClient.stop();
}
}
diff --git a/ranger-zk-client/src/test/java/io/appform/ranger/client/zk/SimpleRangerZKClientTest.java b/ranger-zk-client/src/test/java/io/appform/ranger/client/zk/SimpleRangerZKClientTest.java
index c2c6ec09..233cbc33 100644
--- a/ranger-zk-client/src/test/java/io/appform/ranger/client/zk/SimpleRangerZKClientTest.java
+++ b/ranger-zk-client/src/test/java/io/appform/ranger/client/zk/SimpleRangerZKClientTest.java
@@ -17,13 +17,13 @@
import io.appform.ranger.core.units.TestNodeData;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
-public class SimpleRangerZKClientTest extends BaseRangerZKClientTest {
+class SimpleRangerZKClientTest extends BaseRangerZKClientTest {
@Test
- public void testBaseClient(){
+ void testBaseClient(){
val client = SimpleRangerZKClient.builder()
.curatorFramework(getCuratorFramework())
.deserializer(this::read)
@@ -33,8 +33,8 @@ public void testBaseClient(){
.mapper(getObjectMapper())
.build();
client.start();
- Assert.assertNotNull( client.getNode().orElse(null));
- Assert.assertNotNull(client.getNode(c -> c.getShardId() == 1).orElse(null));
- Assert.assertNull(client.getNode(c -> c.getShardId() == 2).orElse(null));
+ Assertions.assertNotNull( client.getNode().orElse(null));
+ Assertions.assertNotNull(client.getNode(c -> c.getShardId() == 1).orElse(null));
+ Assertions.assertNull(client.getNode(c -> c.getShardId() == 2).orElse(null));
}
}
diff --git a/ranger-zk-client/src/test/java/io/appform/ranger/client/zk/UnshardedZKRangerClientTest.java b/ranger-zk-client/src/test/java/io/appform/ranger/client/zk/UnshardedZKRangerClientTest.java
index de3ffaaf..c42eb2ad 100644
--- a/ranger-zk-client/src/test/java/io/appform/ranger/client/zk/UnshardedZKRangerClientTest.java
+++ b/ranger-zk-client/src/test/java/io/appform/ranger/client/zk/UnshardedZKRangerClientTest.java
@@ -19,14 +19,14 @@
import io.appform.ranger.core.utils.RangerTestUtils;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
@Slf4j
-public class UnshardedZKRangerClientTest extends BaseRangerZKClientTest {
+class UnshardedZKRangerClientTest extends BaseRangerZKClientTest {
@Test
- public void testShardedHub(){
+ void testShardedHub(){
val zkHubClient =UnshardedRangerZKHubClient.builder()
.namespace("test-n")
.connectionString(getTestingCluster().getConnectString())
@@ -38,8 +38,8 @@ public void testShardedHub(){
.build();
zkHubClient.start();
val service = RangerTestUtils.getService("test-n", "s1");
- Assert.assertNotNull(zkHubClient.getNode(service).orElse(null));
- Assert.assertNotNull(zkHubClient.getNode(service, nodeData -> nodeData.getShardId() == 1).orElse(null));
+ Assertions.assertNotNull(zkHubClient.getNode(service).orElse(null));
+ Assertions.assertNotNull(zkHubClient.getNode(service, nodeData -> nodeData.getShardId() == 1).orElse(null));
zkHubClient.stop();
}
}
diff --git a/ranger-zk-server-bundle/pom.xml b/ranger-zk-server-bundle/pom.xml
index 6dfd7b63..cf76d7d5 100644
--- a/ranger-zk-server-bundle/pom.xml
+++ b/ranger-zk-server-bundle/pom.xml
@@ -5,16 +5,12 @@
ranger
io.appform.ranger
- 1.0-RC14
+ 1.0-RC15
4.0.0
ranger-zk-server-bundle
-
- 2.0.23
-
-
io.appform.ranger
@@ -31,15 +27,9 @@
ranger-server-common
${project.version}
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
-
io.dropwizard
dropwizard-core
- ${dropwizard.version}
provided
diff --git a/ranger-zk-server-bundle/src/main/java/io/appform/ranger/server/bundle/ZKServerBundle.java b/ranger-zk-server-bundle/src/main/java/io/appform/ranger/server/bundle/ZKServerBundle.java
index d3d02eb2..19e4b243 100644
--- a/ranger-zk-server-bundle/src/main/java/io/appform/ranger/server/bundle/ZKServerBundle.java
+++ b/ranger-zk-server-bundle/src/main/java/io/appform/ranger/server/bundle/ZKServerBundle.java
@@ -17,7 +17,6 @@
import com.codahale.metrics.health.HealthCheck;
import com.fasterxml.jackson.core.type.TypeReference;
-import com.google.common.collect.ImmutableList;
import io.appform.ranger.client.RangerClientConstants;
import io.appform.ranger.client.RangerHubClient;
import io.appform.ranger.client.zk.UnshardedRangerZKHubClient;
@@ -62,7 +61,7 @@ protected void preBundle(U configuration) {
@Override
protected List>> withHubs(U configuration) {
val rangerConfiguration = getRangerConfiguration(configuration);
- return ImmutableList.of(UnshardedRangerZKHubClient.builder()
+ return List.of(UnshardedRangerZKHubClient.builder()
.namespace(rangerConfiguration.getNamespace())
.connectionString(rangerConfiguration.getZookeeper())
.curatorFramework(curatorFramework)
@@ -82,12 +81,12 @@ protected List>>
}
protected List> withLifecycleSignals(U configuration) {
- return ImmutableList.of(
+ return List.of(
new CuratorLifecycle(curatorFramework)
);
}
protected List withHealthChecks(U configuration) {
- return ImmutableList.of(new RangerHealthCheck(curatorFramework));
+ return List.of(new RangerHealthCheck(curatorFramework));
}
}
diff --git a/ranger-zk-server/config/local.yml b/ranger-zk-server/config/local.yml
index ee2f0adc..793a1b29 100644
--- a/ranger-zk-server/config/local.yml
+++ b/ranger-zk-server/config/local.yml
@@ -1,10 +1,8 @@
name: ranger-server
-initialRotationStatus: false
rangerConfiguration:
namespace: test
zookeeper: localhost:2181
- disablePushUpdaters: true
server:
maxThreads: 128
diff --git a/ranger-zk-server/pom.xml b/ranger-zk-server/pom.xml
index cd01721d..b4a7f298 100644
--- a/ranger-zk-server/pom.xml
+++ b/ranger-zk-server/pom.xml
@@ -5,16 +5,12 @@
ranger
io.appform.ranger
- 1.0-RC14
+ 1.0-RC15
4.0.0
ranger-zk-server
-
- 2.0.23
-
-
io.appform.ranger
@@ -24,22 +20,6 @@
io.dropwizard
dropwizard-core
- ${dropwizard.version}
-
-
- ch.qos.logback
- logback-classic
- ${logback.version}
-
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
-
-
- com.fasterxml.jackson.core
- jackson-annotations
- ${jackson.version}
diff --git a/ranger-zk-server/src/main/java/io/appform/ranger/zk/server/App.java b/ranger-zk-server/src/main/java/io/appform/ranger/zk/server/App.java
index 4c8b0b6e..2d68b0e8 100644
--- a/ranger-zk-server/src/main/java/io/appform/ranger/zk/server/App.java
+++ b/ranger-zk-server/src/main/java/io/appform/ranger/zk/server/App.java
@@ -29,7 +29,7 @@ public static void main(String[] args) throws Exception {
@Override
public void initialize(Bootstrap bootstrap) {
- bootstrap.addBundle(new ZKServerBundle() {
+ bootstrap.addBundle(new ZKServerBundle<>() {
@Override
protected RangerConfiguration getRangerConfiguration(AppConfiguration configuration) {
return configuration.getRangerConfiguration();
diff --git a/ranger-zk-server/src/main/java/io/appform/ranger/zk/server/AppConfiguration.java b/ranger-zk-server/src/main/java/io/appform/ranger/zk/server/AppConfiguration.java
index e9583ad5..d04e2482 100644
--- a/ranger-zk-server/src/main/java/io/appform/ranger/zk/server/AppConfiguration.java
+++ b/ranger-zk-server/src/main/java/io/appform/ranger/zk/server/AppConfiguration.java
@@ -15,6 +15,7 @@
*/
package io.appform.ranger.zk.server;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.appform.ranger.server.bundle.config.RangerConfiguration;
import io.dropwizard.Configuration;
import lombok.AllArgsConstructor;
@@ -30,6 +31,7 @@
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
+@JsonIgnoreProperties(ignoreUnknown = true)
public class AppConfiguration extends Configuration {
@NotEmpty
@NotNull
diff --git a/ranger-zookeeper/pom.xml b/ranger-zookeeper/pom.xml
index d026d139..e9356012 100644
--- a/ranger-zookeeper/pom.xml
+++ b/ranger-zookeeper/pom.xml
@@ -5,7 +5,7 @@
ranger
io.appform.ranger
- 1.0-RC14
+ 1.0-RC15
4.0.0
@@ -17,7 +17,6 @@
ranger-core
${project.version}
-
org.apache.curator
@@ -30,7 +29,6 @@
-
org.apache.curator
curator-recipes
diff --git a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/ServiceHealthAggregatorTest.java b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/ServiceHealthAggregatorTest.java
index 71b60903..eb9199e5 100644
--- a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/ServiceHealthAggregatorTest.java
+++ b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/ServiceHealthAggregatorTest.java
@@ -21,20 +21,20 @@
import io.appform.ranger.core.healthservice.monitor.IsolatedHealthMonitor;
import io.appform.ranger.core.healthservice.monitor.Monitor;
import io.appform.ranger.core.utils.RangerTestUtils;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import java.util.Date;
-public class ServiceHealthAggregatorTest {
+class ServiceHealthAggregatorTest {
ServiceHealthAggregator serviceHealthAggregator = new ServiceHealthAggregator();
TestMonitor testMonitor;
@SuppressWarnings("unchecked")
- @Before
+ @BeforeEach
public void setUp() {
testMonitor = new TestMonitor("TestHealthMonitor", TimeEntity.everySecond(), 1000);
serviceHealthAggregator.addIsolatedMonitor(testMonitor);
@@ -54,13 +54,13 @@ public boolean isDisabled() {
RangerTestUtils.sleepUntil(3, () -> serviceHealthAggregator.getRunning().get());
}
- @After
+ @AfterEach
public void tearDown() {
serviceHealthAggregator.stop();
}
@Test
- public void testStaleRun() {
+ void testStaleRun() {
testMonitor.run();
testMonitor.setThreadSleep(2000);
@@ -69,14 +69,14 @@ public void testStaleRun() {
/* in the TestMonitor, thread was sleeping for 2 seconds, */
/* so its state is supposed to be stale (>1 second) and service has to be unhealthy */
- Assert.assertEquals(HealthcheckStatus.unhealthy, serviceHealthAggregator.getServiceHealth());
+ Assertions.assertEquals(HealthcheckStatus.unhealthy, serviceHealthAggregator.getServiceHealth());
testMonitor.setThreadSleep(5);
RangerTestUtils.sleepUntil(3, () -> testMonitor.hasValidUpdatedTime(new Date()));
/* in the TestMonitor, thread is sleeping only for 10 milliseconds, */
/* so its state is supposed to be NOT stale (>1 second) and service has to be healthy */
- Assert.assertEquals(HealthcheckStatus.healthy, serviceHealthAggregator.getServiceHealth());
+ Assertions.assertEquals(HealthcheckStatus.healthy, serviceHealthAggregator.getServiceHealth());
}
diff --git a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/ServiceProviderIntegrationTest.java b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/ServiceProviderIntegrationTest.java
index 057fd911..b3e6819b 100644
--- a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/ServiceProviderIntegrationTest.java
+++ b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/ServiceProviderIntegrationTest.java
@@ -31,16 +31,16 @@
import io.appform.ranger.zookeeper.ServiceProviderBuilders;
import lombok.val;
import org.apache.curator.test.TestingCluster;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.IOException;
import java.util.List;
-public class ServiceProviderIntegrationTest {
+class ServiceProviderIntegrationTest {
final String filePath = "/tmp/rangerRotationFile.html";
File file = new File(filePath);
@@ -52,7 +52,7 @@ public class ServiceProviderIntegrationTest {
SimpleShardedServiceFinder serviceFinder;
- @Before
+ @BeforeEach
public void startTestCluster() throws Exception {
objectMapper = new ObjectMapper();
testingCluster = new TestingCluster(3);
@@ -82,7 +82,7 @@ public void startTestCluster() throws Exception {
serviceFinder.start();
}
- @After
+ @AfterEach
public void stopTestCluster() throws Exception {
if (null != testingCluster) {
testingCluster.close();
@@ -92,7 +92,7 @@ public void stopTestCluster() throws Exception {
@SuppressWarnings("ResultOfMethodCallIgnored")
@Test
- public void testBasicDiscovery() throws Exception {
+ void testBasicDiscovery() throws Exception {
/* clean slate */
file.delete();
@@ -104,7 +104,7 @@ public void testBasicDiscovery() throws Exception {
RangerTestUtils.sleepUntil(5);
List> all = serviceFinder.getAll(null);
System.out.println("all = " + all);
- Assert.assertEquals(3, all.size());
+ Assertions.assertEquals(3, all.size());
/* with file deleted, all 3 nodes should be unhealthy */
file.delete();
@@ -112,7 +112,7 @@ public void testBasicDiscovery() throws Exception {
RangerTestUtils.sleepUntil(5);
all = serviceFinder.getAll(null);
System.out.println("all = " + all);
- Assert.assertEquals(0, all.size());
+ Assertions.assertEquals(0, all.size());
/* with anotherFile created, the 4th node should become healthy and discoverable */
anotherFile.createNewFile();
@@ -120,7 +120,7 @@ public void testBasicDiscovery() throws Exception {
RangerTestUtils.sleepUntil(5);
all = serviceFinder.getAll(null);
System.out.println("all = " + all);
- Assert.assertEquals(1, all.size());
+ Assertions.assertEquals(1, all.size());
/* clean slate */
file.delete();
diff --git a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/monitor/RollingWindowHealthQueueTest.java b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/monitor/RollingWindowHealthQueueTest.java
index 36388018..a3845472 100644
--- a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/monitor/RollingWindowHealthQueueTest.java
+++ b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/monitor/RollingWindowHealthQueueTest.java
@@ -18,97 +18,97 @@
import io.appform.ranger.core.healthcheck.HealthcheckStatus;
import io.appform.ranger.core.healthservice.monitor.RollingWindowHealthQueue;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
-public class RollingWindowHealthQueueTest {
+class RollingWindowHealthQueueTest {
@Test
- public void testCheckInRollingWindow1() {
+ void testCheckInRollingWindow1() {
val rollingWindowHealthQueue = new RollingWindowHealthQueue(5, 3);
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
}
@Test
- public void testCheckInRollingWindowEdge() {
+ void testCheckInRollingWindowEdge() {
try {
val rollingWindowHealthQueue = new RollingWindowHealthQueue(1, 3);
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
} catch (Exception u) {
- Assert.assertTrue(u instanceof UnsupportedOperationException);
+ Assertions.assertTrue(u instanceof UnsupportedOperationException);
}
}
@Test
- public void testCheckInRollingWindowEdge2() {
+ void testCheckInRollingWindowEdge2() {
val rollingWindowHealthQueue = new RollingWindowHealthQueue(3, 3);
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
}
@Test
- public void testCheckInRollingWindowEdge3() {
+ void testCheckInRollingWindowEdge3() {
val rollingWindowHealthQueue = new RollingWindowHealthQueue(5, 1);
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
}
@Test
- public void testCheckInRollingWindow2() {
+ void testCheckInRollingWindow2() {
val rollingWindowHealthQueue = new RollingWindowHealthQueue(5, 3);
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
}
@Test
- public void testCheckInRollingWindow3() {
+ void testCheckInRollingWindow3() {
val rollingWindowHealthQueue = new RollingWindowHealthQueue(5, 3);
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
}
@Test
- public void testCheckInRollingWindow4() {
+ void testCheckInRollingWindow4() {
val rollingWindowHealthQueue = new RollingWindowHealthQueue(5, 3);
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
- Assert.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
- Assert.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
+ Assertions.assertFalse(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.healthy));
+ Assertions.assertTrue(rollingWindowHealthQueue.checkInRollingWindow(HealthcheckStatus.unhealthy));
}
}
\ No newline at end of file
diff --git a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/monitor/sample/DiskSpaceMonitorTest.java b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/monitor/sample/DiskSpaceMonitorTest.java
index 5e29dd48..609281ed 100644
--- a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/monitor/sample/DiskSpaceMonitorTest.java
+++ b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/monitor/sample/DiskSpaceMonitorTest.java
@@ -18,24 +18,23 @@
import io.appform.ranger.core.healthcheck.HealthcheckStatus;
import io.appform.ranger.core.healthservice.TimeEntity;
-import io.appform.ranger.core.healthservice.monitor.IsolatedHealthMonitor;
import io.appform.ranger.core.healthservice.monitor.sample.DiskSpaceMonitor;
import lombok.val;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
import java.util.concurrent.TimeUnit;
-public class DiskSpaceMonitorTest {
+class DiskSpaceMonitorTest {
@Test
- public void testGetCount() {
+ void testGetCount() {
val diskSpaceMonitor = new DiskSpaceMonitor("/", 1000, new TimeEntity(2, TimeUnit.SECONDS));
- Assert.assertEquals(HealthcheckStatus.healthy, diskSpaceMonitor.monitor());
- Assert.assertEquals(HealthcheckStatus.healthy, diskSpaceMonitor.monitor());
- Assert.assertEquals(HealthcheckStatus.healthy, diskSpaceMonitor.monitor());
- Assert.assertEquals(HealthcheckStatus.healthy, diskSpaceMonitor.monitor());
- Assert.assertEquals(HealthcheckStatus.healthy, diskSpaceMonitor.monitor());
- Assert.assertEquals(HealthcheckStatus.healthy, diskSpaceMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.healthy, diskSpaceMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.healthy, diskSpaceMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.healthy, diskSpaceMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.healthy, diskSpaceMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.healthy, diskSpaceMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.healthy, diskSpaceMonitor.monitor());
}
}
\ No newline at end of file
diff --git a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/monitor/sample/PingCheckMonitorTest.java b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/monitor/sample/PingCheckMonitorTest.java
index 70e467b4..573418a5 100644
--- a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/monitor/sample/PingCheckMonitorTest.java
+++ b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/monitor/sample/PingCheckMonitorTest.java
@@ -20,32 +20,32 @@
import io.appform.ranger.core.healthservice.monitor.sample.PingCheckMonitor;
import lombok.val;
import org.apache.http.client.methods.HttpGet;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
import java.util.concurrent.TimeUnit;
-public class PingCheckMonitorTest {
+class PingCheckMonitorTest {
@Test
- public void testMonitor() {
+ void testMonitor() {
val httpRequest = new HttpGet("/");
val pingCheckMonitor = new PingCheckMonitor(new TimeEntity(2, TimeUnit.SECONDS), httpRequest, 5000, 5, 3, "google.com", 80);
- Assert.assertEquals(HealthcheckStatus.healthy, pingCheckMonitor.monitor());
- Assert.assertEquals(HealthcheckStatus.healthy, pingCheckMonitor.monitor());
- Assert.assertEquals(HealthcheckStatus.healthy, pingCheckMonitor.monitor());
- Assert.assertEquals(HealthcheckStatus.healthy, pingCheckMonitor.monitor());
- Assert.assertEquals(HealthcheckStatus.healthy, pingCheckMonitor.monitor());
- Assert.assertEquals(HealthcheckStatus.healthy, pingCheckMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.healthy, pingCheckMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.healthy, pingCheckMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.healthy, pingCheckMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.healthy, pingCheckMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.healthy, pingCheckMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.healthy, pingCheckMonitor.monitor());
}
@Test
- public void testMonitor2() {
+ void testMonitor2() {
val httpRequest = new HttpGet("/help");
val pingCheckMonitor = new PingCheckMonitor(new TimeEntity(2, TimeUnit.SECONDS), httpRequest, 5000, 5, 3, "google.com", 80);
- Assert.assertEquals(HealthcheckStatus.healthy, pingCheckMonitor.monitor());
- Assert.assertEquals(HealthcheckStatus.healthy, pingCheckMonitor.monitor());
- Assert.assertEquals(HealthcheckStatus.unhealthy, pingCheckMonitor.monitor());
- Assert.assertEquals(HealthcheckStatus.unhealthy, pingCheckMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.healthy, pingCheckMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.healthy, pingCheckMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.unhealthy, pingCheckMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.unhealthy, pingCheckMonitor.monitor());
}
}
\ No newline at end of file
diff --git a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/monitor/sample/RotationStatusMonitorTest.java b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/monitor/sample/RotationStatusMonitorTest.java
index f92be35c..7a0b3f5b 100644
--- a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/monitor/sample/RotationStatusMonitorTest.java
+++ b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/healthservice/monitor/sample/RotationStatusMonitorTest.java
@@ -18,41 +18,41 @@
import io.appform.ranger.core.healthcheck.HealthcheckStatus;
import io.appform.ranger.core.healthservice.monitor.sample.RotationStatusMonitor;
import lombok.val;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import java.io.File;
-public class RotationStatusMonitorTest {
+class RotationStatusMonitorTest {
final String filePath = "/tmp/rangerRotationFile.html";
File file = new File(filePath);
- @Before
+ @BeforeEach
public void setUp() throws Exception {
deleteRotationFile();
}
- @After
+ @AfterEach
public void tearDown() throws Exception {
deleteRotationFile();
}
@Test
- public void testMonitor() throws Exception {
+ void testMonitor() throws Exception {
deleteRotationFile();
val rotationStatusMonitor = new RotationStatusMonitor("/tmp/rotationFile.html");
- Assert.assertEquals(HealthcheckStatus.unhealthy, rotationStatusMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.unhealthy, rotationStatusMonitor.monitor());
}
@Test
- public void testMonitor2() throws Exception {
+ void testMonitor2() throws Exception {
deleteRotationFile();
if (file.createNewFile()) {
val rotationStatusMonitor = new RotationStatusMonitor(filePath);
- Assert.assertEquals(HealthcheckStatus.healthy, rotationStatusMonitor.monitor());
+ Assertions.assertEquals(HealthcheckStatus.healthy, rotationStatusMonitor.monitor());
} else {
System.out.println("Unable to create file = " + filePath);
throw new Exception("Unable to create file = " + filePath);
diff --git a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/CustomShardSelectorTest.java b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/CustomShardSelectorTest.java
index 1197d3e7..aeec80f1 100644
--- a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/CustomShardSelectorTest.java
+++ b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/CustomShardSelectorTest.java
@@ -31,10 +31,10 @@
import lombok.extern.jackson.Jacksonized;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.test.TestingCluster;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.ArrayList;
@@ -43,12 +43,12 @@
@Slf4j
-public class CustomShardSelectorTest {
+class CustomShardSelectorTest {
private TestingCluster testingCluster;
private ObjectMapper objectMapper;
private final List>> serviceProviders = Lists.newArrayList();
- @Before
+ @BeforeEach
public void startTestCluster() throws Exception {
objectMapper = new ObjectMapper();
testingCluster = new TestingCluster(3);
@@ -58,7 +58,7 @@ public void startTestCluster() throws Exception {
registerService("localhost-3", 9002, 2, 3);
}
- @After
+ @AfterEach
public void stopTestCluster() throws Exception {
serviceProviders.forEach(ServiceProvider::stop);
if (null != testingCluster) {
@@ -94,7 +94,7 @@ public List> nodes(Predicate criteria,
}
@Test
- public void testBasicDiscovery() {
+ void testBasicDiscovery() {
val serviceFinder = ServiceFinderBuilders.shardedFinderBuilder()
.withConnectionString(testingCluster.getConnectString())
.withNamespace("test")
@@ -113,16 +113,16 @@ public void testBasicDiscovery() {
serviceFinder.start();
{
val node = serviceFinder.get(TestShardInfo.getCriteria(1, 10)).orElse(null);
- Assert.assertNull(node);
+ Assertions.assertNull(node);
}
{
val node = serviceFinder.get(TestShardInfo.getCriteria(1, 2)).orElse(null);
- Assert.assertNotNull(node);
- Assert.assertEquals(new TestShardInfo(1, 2), node.getNodeData());
+ Assertions.assertNotNull(node);
+ Assertions.assertEquals(new TestShardInfo(1, 2), node.getNodeData());
}
{
val node = serviceFinder.get(TestShardInfo.getCriteria(2, 3)).orElse(null);
- Assert.assertNotNull(node);
+ Assertions.assertNotNull(node);
}
serviceFinder.stop();
}
diff --git a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/ServiceNoProviderTest.java b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/ServiceNoProviderTest.java
index cd2732fe..a5bd64eb 100644
--- a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/ServiceNoProviderTest.java
+++ b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/ServiceNoProviderTest.java
@@ -24,26 +24,27 @@
import io.appform.ranger.zookeeper.ServiceFinderBuilders;
import lombok.val;
import org.apache.curator.test.TestingCluster;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
import java.io.IOException;
-public class ServiceNoProviderTest {
+class ServiceNoProviderTest {
private TestingCluster testingCluster;
private ObjectMapper objectMapper;
- @Before
+ @BeforeEach
public void startTestCluster() throws Exception {
objectMapper = new ObjectMapper();
testingCluster = new TestingCluster(3);
testingCluster.start();
}
- @After
+ @AfterEach
public void stopTestCluster() throws Exception {
if (null != testingCluster) {
testingCluster.close();
@@ -51,7 +52,7 @@ public void stopTestCluster() throws Exception {
}
@Test
- public void testBasicDiscovery() {
+ void testBasicDiscovery() {
val serviceFinder = ServiceFinderBuilders.shardedFinderBuilder()
.withConnectionString(testingCluster.getConnectString())
.withNamespace("test")
@@ -70,13 +71,13 @@ public void testBasicDiscovery() {
.build();
serviceFinder.start();
val node = serviceFinder.get(RangerTestUtils.getCriteria(1)).orElse(null);
- Assert.assertNull(node);
+ Assertions.assertNull(node);
serviceFinder.stop();
}
@Test
- public void testBasicDiscoveryRR() {
+ void testBasicDiscoveryRR() {
val serviceFinder = ServiceFinderBuilders.shardedFinderBuilder()
.withConnectionString(testingCluster.getConnectString())
.withNamespace("test")
@@ -96,7 +97,7 @@ public void testBasicDiscoveryRR() {
.build();
serviceFinder.start();
val node = serviceFinder.get(RangerTestUtils.getCriteria(1)).orElse(null);
- Assert.assertNull(node);
+ Assertions.assertNull(node);
serviceFinder.stop();
}
diff --git a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/ServiceProviderExtCuratorTest.java b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/ServiceProviderExtCuratorTest.java
index db175338..5705fa78 100644
--- a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/ServiceProviderExtCuratorTest.java
+++ b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/ServiceProviderExtCuratorTest.java
@@ -33,24 +33,24 @@
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.test.TestingCluster;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.List;
import java.util.stream.LongStream;
@Slf4j
-public class ServiceProviderExtCuratorTest {
+class ServiceProviderExtCuratorTest {
private TestingCluster testingCluster;
private ObjectMapper objectMapper;
private final List>> serviceProviders = Lists.newArrayList();
private CuratorFramework curatorFramework;
- @Before
+ @BeforeEach
public void startTestCluster() throws Exception {
objectMapper = new ObjectMapper();
testingCluster = new TestingCluster(3);
@@ -65,7 +65,7 @@ public void startTestCluster() throws Exception {
registerService("localhost-3", 9002, 2);
}
- @After
+ @AfterEach
public void stopTestCluster() throws Exception {
serviceProviders.forEach(ServiceProvider::stop);
curatorFramework.close();
@@ -75,7 +75,7 @@ public void stopTestCluster() throws Exception {
}
@Test
- public void testBasicDiscovery() {
+ void testBasicDiscovery() {
val serviceFinder = ServiceFinderBuilders.shardedFinderBuilder()
.withCuratorFramework(curatorFramework)
.withNamespace("test")
@@ -94,23 +94,23 @@ public void testBasicDiscovery() {
serviceFinder.start();
{
val node = serviceFinder.get(RangerTestUtils.getCriteria(1)).orElse(null);
- Assert.assertNotNull(node);
- Assert.assertEquals(1, node.getNodeData().getShardId());
+ Assertions.assertNotNull(node);
+ Assertions.assertEquals(1, node.getNodeData().getShardId());
}
{
val node = serviceFinder.get(RangerTestUtils.getCriteria(1)).orElse(null);
- Assert.assertNotNull(node);
- Assert.assertEquals(1, node.getNodeData().getShardId());
+ Assertions.assertNotNull(node);
+ Assertions.assertEquals(1, node.getNodeData().getShardId());
}
val startTime = System.currentTimeMillis();
LongStream.range(0, 1000000).mapToObj(i -> serviceFinder.get(RangerTestUtils.getCriteria(2)).orElse(null)).forEach(node -> {
- Assert.assertNotNull(node);
- Assert.assertEquals(2, node.getNodeData().getShardId());
+ Assertions.assertNotNull(node);
+ Assertions.assertEquals(2, node.getNodeData().getShardId());
});
log.info("PERF::RandomSelector::Took (ms):" + (System.currentTimeMillis() - startTime));
{
val node = serviceFinder.get(RangerTestUtils.getCriteria(99)).orElse(null);
- Assert.assertNull(node);
+ Assertions.assertNull(node);
}
serviceFinder.stop();
}
diff --git a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/ServiceProviderHealthcheckTest.java b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/ServiceProviderHealthcheckTest.java
index 88dfc36a..0ec4377d 100644
--- a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/ServiceProviderHealthcheckTest.java
+++ b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/ServiceProviderHealthcheckTest.java
@@ -30,21 +30,21 @@
import lombok.Getter;
import lombok.val;
import org.apache.curator.test.TestingCluster;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.Map;
-public class ServiceProviderHealthcheckTest {
+class ServiceProviderHealthcheckTest {
private TestingCluster testingCluster;
private ObjectMapper objectMapper;
private final Map serviceProviders = Maps.newHashMap();
- @Before
+ @BeforeEach
public void startTestCluster() throws Exception {
objectMapper = new ObjectMapper();
testingCluster = new TestingCluster(3);
@@ -53,7 +53,7 @@ public void startTestCluster() throws Exception {
registerService("localhost-3", 9001, 2);
}
- @After
+ @AfterEach
public void stopTestCluster() throws Exception {
if (null != testingCluster) {
testingCluster.close();
@@ -61,7 +61,7 @@ public void stopTestCluster() throws Exception {
}
@Test
- public void testBasicDiscovery() {
+ void testBasicDiscovery() {
val serviceFinder = ServiceFinderBuilders.shardedFinderBuilder()
.withConnectionString(testingCluster.getConnectString())
.withNamespace("test")
@@ -80,12 +80,12 @@ public void testBasicDiscovery() {
.build();
serviceFinder.start();
val node = serviceFinder.get(RangerTestUtils.getCriteria(1)).orElse(null);
- Assert.assertNotNull(node);
- Assert.assertEquals("localhost-1", node.getHost());
+ Assertions.assertNotNull(node);
+ Assertions.assertEquals("localhost-1", node.getHost());
TestServiceProvider testServiceProvider = serviceProviders.get(node.getHost());
testServiceProvider.oor();
RangerTestUtils.sleepUntil(2); //Sleep till the increment refresh healthCheck interval (> 1sec), no upper bound condition.
- Assert.assertFalse(serviceFinder.get(RangerTestUtils.getCriteria(1)).isPresent());
+ Assertions.assertFalse(serviceFinder.get(RangerTestUtils.getCriteria(1)).isPresent());
serviceFinder.stop();
}
@@ -134,7 +134,7 @@ public void oor() {
healthcheck.setStatus(HealthcheckStatus.unhealthy);
}
- public void start() throws Exception {
+ public void start() {
val serviceProvider = ServiceProviderBuilders.shardedServiceProviderBuilder()
.withConnectionString(connectionString)
.withNamespace("test")
diff --git a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/ServiceProviderTest.java b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/ServiceProviderTest.java
index 899e4407..73d8e1a3 100644
--- a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/ServiceProviderTest.java
+++ b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/ServiceProviderTest.java
@@ -32,23 +32,23 @@
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.curator.test.TestingCluster;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.List;
import java.util.stream.LongStream;
@Slf4j
-public class ServiceProviderTest {
+class ServiceProviderTest {
private TestingCluster testingCluster;
private ObjectMapper objectMapper;
private final List>> serviceProviders = Lists.newArrayList();
- @Before
+ @BeforeEach
public void startTestCluster() throws Exception {
objectMapper = new ObjectMapper();
testingCluster = new TestingCluster(3);
@@ -59,7 +59,7 @@ public void startTestCluster() throws Exception {
registerService("localhost-4", 9003, 2);
}
- @After
+ @AfterEach
public void stopTestCluster() throws Exception {
serviceProviders.forEach(ServiceProvider::stop);
if (null != testingCluster) {
@@ -68,7 +68,7 @@ public void stopTestCluster() throws Exception {
}
@Test
- public void testBasicDiscovery() {
+ void testBasicDiscovery() {
val serviceFinder = ServiceFinderBuilders.shardedFinderBuilder()
.withConnectionString(testingCluster.getConnectString())
.withNamespace("test")
@@ -86,29 +86,29 @@ public void testBasicDiscovery() {
serviceFinder.start();
{
val node = serviceFinder.get(RangerTestUtils.getCriteria(1)).orElse(null);
- Assert.assertNotNull(node);
- Assert.assertEquals(1, node.getNodeData().getShardId());
+ Assertions.assertNotNull(node);
+ Assertions.assertEquals(1, node.getNodeData().getShardId());
}
{
val node = serviceFinder.get(RangerTestUtils.getCriteria(1)).orElse(null);
- Assert.assertNotNull(node);
- Assert.assertEquals(1, node.getNodeData().getShardId());
+ Assertions.assertNotNull(node);
+ Assertions.assertEquals(1, node.getNodeData().getShardId());
}
val startTime = System.currentTimeMillis();
LongStream.range(0, 1000000).mapToObj(i -> serviceFinder.get(RangerTestUtils.getCriteria(2)).orElse(null)).forEach(node -> {
- Assert.assertNotNull(node);
- Assert.assertEquals(2, node.getNodeData().getShardId());
+ Assertions.assertNotNull(node);
+ Assertions.assertEquals(2, node.getNodeData().getShardId());
});
log.info("PERF::RandomSelector::Took (ms):" + (System.currentTimeMillis() - startTime));
{
val node = serviceFinder.get(RangerTestUtils.getCriteria(99)).orElse(null);
- Assert.assertNull(node);
+ Assertions.assertNull(node);
}
serviceFinder.stop();
}
@Test
- public void testBasicDiscoveryRR() {
+ void testBasicDiscoveryRR() {
val serviceFinder
= ServiceFinderBuilders.shardedFinderBuilder()
.withConnectionString(testingCluster.getConnectString())
@@ -129,30 +129,30 @@ public void testBasicDiscoveryRR() {
serviceFinder.start();
{
val node = serviceFinder.get(RangerTestUtils.getCriteria(1));
- Assert.assertTrue(node.isPresent());
- Assert.assertEquals(1, node.get().getNodeData().getShardId());
+ Assertions.assertTrue(node.isPresent());
+ Assertions.assertEquals(1, node.get().getNodeData().getShardId());
}
{
val node = serviceFinder.get(RangerTestUtils.getCriteria(1));
- Assert.assertTrue(node.isPresent());
- Assert.assertEquals(1, node.get().getNodeData().getShardId());
+ Assertions.assertTrue(node.isPresent());
+ Assertions.assertEquals(1, node.get().getNodeData().getShardId());
}
long startTime = System.currentTimeMillis();
LongStream.range(0, 1000000).mapToObj(i -> serviceFinder.get(RangerTestUtils.getCriteria(2))).forEach(node -> {
- Assert.assertTrue(node.isPresent());
- Assert.assertEquals(2, node.get().getNodeData().getShardId());
+ Assertions.assertTrue(node.isPresent());
+ Assertions.assertEquals(2, node.get().getNodeData().getShardId());
});
log.info("PERF::RoundRobinSelector::Took (ms):" + (System.currentTimeMillis() - startTime));
{
val node = serviceFinder.get(RangerTestUtils.getCriteria(99));
- Assert.assertFalse(node.isPresent());
+ Assertions.assertFalse(node.isPresent());
}
serviceFinder.stop();
//while (true);
}
@Test
- public void testVisibility() {
+ void testVisibility() {
val serviceFinder = ServiceFinderBuilders.
shardedFinderBuilder()
.withConnectionString(testingCluster.getConnectString())
@@ -175,7 +175,7 @@ public void testVisibility() {
log.info("Testing ServiceFinder.getAll()");
all.stream().map(serviceNode -> "node = " + serviceNode.getHost() + ":" + serviceNode.getPort() + " " + serviceNode.getHealthcheckStatus() + " " + serviceNode
.getLastUpdatedTimeStamp()).forEach(log::info);
- Assert.assertEquals(3, all.size());
+ Assertions.assertEquals(3, all.size());
serviceFinder.stop();
}
diff --git a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/SimpleServiceProviderTest.java b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/SimpleServiceProviderTest.java
index 255900a6..f92ec88c 100644
--- a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/SimpleServiceProviderTest.java
+++ b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/model/SimpleServiceProviderTest.java
@@ -26,20 +26,20 @@
import io.appform.ranger.zookeeper.ServiceProviderBuilders;
import lombok.val;
import org.apache.curator.test.TestingCluster;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.stream.LongStream;
-public class SimpleServiceProviderTest {
+class SimpleServiceProviderTest {
private TestingCluster testingCluster;
private ObjectMapper objectMapper;
- @Before
+ @BeforeEach
public void startTestCluster() throws Exception {
objectMapper = new ObjectMapper();
testingCluster = new TestingCluster(3);
@@ -49,7 +49,7 @@ public void startTestCluster() throws Exception {
registerService("localhost-3", 9002);
}
- @After
+ @AfterEach
public void stopTestCluster() throws Exception {
if(null != testingCluster) {
testingCluster.close();
@@ -70,7 +70,7 @@ public boolean equals(Object obj) {
}
@Test
- public void testBasicDiscovery() {
+ void testBasicDiscovery() {
val serviceFinder = ServiceFinderBuilders.unshardedFinderBuilder()
.withConnectionString(testingCluster.getConnectString())
.withNamespace("test")
@@ -90,13 +90,13 @@ public void testBasicDiscovery() {
serviceFinder.start();
{
val node = serviceFinder.get(null).orElse(null);
- Assert.assertNotNull(node);
+ Assertions.assertNotNull(node);
System.out.println(node.getHost());
}
val frequency = HashMultiset.create();
val startTime = System.currentTimeMillis();
LongStream.range(0, 1000000).mapToObj(i -> serviceFinder.get(null).orElse(null)).forEach(node -> {
- Assert.assertNotNull(node);
+ Assertions.assertNotNull(node);
frequency.add(node.getHost());
});
System.out.println("1 Million lookups and freq counting took (ms):" + (System.currentTimeMillis() -startTime));
diff --git a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/servicehub/ServiceHubTest.java b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/servicehub/ServiceHubTest.java
index 6a818cee..f082548a 100644
--- a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/servicehub/ServiceHubTest.java
+++ b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/servicehub/ServiceHubTest.java
@@ -35,10 +35,10 @@
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.test.TestingCluster;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.Collections;
@@ -48,7 +48,7 @@
*
*/
@Slf4j
-public class ServiceHubTest {
+class ServiceHubTest {
private static final String NAMESPACE = "test";
@@ -56,7 +56,7 @@ public class ServiceHubTest {
private ObjectMapper objectMapper = new ObjectMapper();
private CuratorFramework curatorFramework;
- @Before
+ @BeforeEach
public void startTestCluster() throws Exception {
objectMapper = new ObjectMapper();
testingCluster = new TestingCluster(3);
@@ -71,7 +71,7 @@ public void startTestCluster() throws Exception {
log.debug("Started zk subsystem");
}
- @After
+ @AfterEach
public void stopTestCluster() throws Exception {
log.debug("Stopping zk subsystem");
curatorFramework.close();
@@ -81,7 +81,7 @@ public void stopTestCluster() throws Exception {
}
@Test
- public void testHub() {
+ void testHub() {
val refreshProviderSignal = new ExternalTriggeredSignal<>(
() -> HealthcheckResult.builder()
.status(HealthcheckStatus.healthy)
@@ -118,7 +118,7 @@ public void testHub() {
val node = hub.finder(RangerTestUtils.getService(NAMESPACE, "s1"))
.flatMap(finder -> finder.get(nodeData -> nodeData.getShardId() == 1)).orElse(null);
- Assert.assertNotNull(node);
+ Assertions.assertNotNull(node);
hub.stop();
provider1.stop();
}
diff --git a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/serviceprovider/BaseServiceProviderBuilderTest.java b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/serviceprovider/BaseServiceProviderBuilderTest.java
index 7cadf7c5..33aabf64 100644
--- a/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/serviceprovider/BaseServiceProviderBuilderTest.java
+++ b/ranger-zookeeper/src/test/java/io/appform/ranger/zookeeper/serviceprovider/BaseServiceProviderBuilderTest.java
@@ -22,29 +22,29 @@
import io.appform.ranger.zookeeper.ServiceProviderBuilders;
import lombok.val;
import org.apache.curator.test.TestingCluster;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
/**
* @author tushar.naik
* @version 1.0
* @date 12/03/16 - 7:40 PM
*/
-public class BaseServiceProviderBuilderTest {
+class BaseServiceProviderBuilderTest {
private TestingCluster testingCluster;
private ObjectMapper objectMapper;
- @Before
+ @BeforeEach
public void startTestCluster() throws Exception {
objectMapper = new ObjectMapper();
testingCluster = new TestingCluster(3);
testingCluster.start();
}
- @After
+ @AfterEach
public void stopTestCluster() throws Exception {
if(null != testingCluster) {
testingCluster.close();
@@ -52,7 +52,7 @@ public void stopTestCluster() throws Exception {
}
@Test
- public void testServiceProviderBuilder() {
+ void testServiceProviderBuilder() {
val host = "localhost";
val port = 9000;
Exception exception = null;
@@ -77,7 +77,7 @@ public void testServiceProviderBuilder() {
} catch (Exception e) {
exception = e;
}
- Assert.assertTrue(exception instanceof IllegalArgumentException);
+ Assertions.assertTrue(exception instanceof IllegalArgumentException);
val serviceProvider = ServiceProviderBuilders.unshardedServiceProviderBuilder()
.withConnectionString(testingCluster.getConnectString())