From 87b95c5cda0a0df7b5966e88be5297f98208597a Mon Sep 17 00:00:00 2001 From: sajid riaz Date: Thu, 19 Sep 2024 13:03:28 +0200 Subject: [PATCH] Generate Unique EcChronos ID #678 - Generate eccrhonos_Id that should be unique (uuid + host name) - on start up instance, first check nodes_metadata table for ecchronosId, if it already exists, use that one, otherwise generate now one. - So due to persistence of eccronosId, it would be same even instance get reinstalled or restart. - when instance try to acquire nodes then add this newly ecchronosId into nodes_metadata table with datacenter and nodeId. - The new table nodes_metadata schenma, datacenter is partition key and nodeId is clustering colum and ecchrons_id coulum would hold the Id. --- .../application/spring/BeanConfigurator.java | 3 - .../ecchronos/data/sync/EccNodeMetadata.java | 134 ++++++++++++++++++ .../ecchronos/data/sync/EccNodesSync.java | 91 +++++------- .../data/sync/TestEccNodeMetadata.java | 123 ++++++++++++++++ .../ecchronos/data/sync/TestEccNodesSync.java | 45 +++--- 5 files changed, 322 insertions(+), 74 deletions(-) create mode 100644 data/src/main/java/com/ericsson/bss/cassandra/ecchronos/data/sync/EccNodeMetadata.java create mode 100644 data/src/test/java/com/ericsson/bss/cassandra/ecchronos/data/sync/TestEccNodeMetadata.java diff --git a/application/src/main/java/com/ericsson/bss/cassandra/ecchronos/application/spring/BeanConfigurator.java b/application/src/main/java/com/ericsson/bss/cassandra/ecchronos/application/spring/BeanConfigurator.java index 30f582e0..2d071c1e 100644 --- a/application/src/main/java/com/ericsson/bss/cassandra/ecchronos/application/spring/BeanConfigurator.java +++ b/application/src/main/java/com/ericsson/bss/cassandra/ecchronos/application/spring/BeanConfigurator.java @@ -64,7 +64,6 @@ public class BeanConfigurator private final AtomicReference cqlSecurity = new AtomicReference<>(); private final AtomicReference jmxSecurity = new AtomicReference<>(); private final ConfigRefresher configRefresher; - private final String ecChronosID; /** * Constructs a new {@code BeanConfigurator} and initializes the configuration and security settings. If the @@ -91,7 +90,6 @@ public BeanConfigurator() throws ConfigurationException, UnknownHostException Security security = getSecurityConfig(); cqlSecurity.set(security.getCqlSecurity()); jmxSecurity.set(security.getJmxSecurity()); - ecChronosID = ECCHORONS_ID_PRE_STRING.concat(InetAddress.getLocalHost().getHostName()); } /** @@ -282,7 +280,6 @@ private EccNodesSync getEccNodesSync( EccNodesSync myEccNodesSync = EccNodesSync.newBuilder() .withInitialNodesList(distributedNativeConnectionProvider.getNodes()) .withSession(distributedNativeConnectionProvider.getCqlSession()) - .withEcchronosID(ecChronosID) .withConnectionDelayValue(connectionDelay.getTime()) .withConnectionDelayUnit(connectionDelay.getUnit()) .build(); diff --git a/data/src/main/java/com/ericsson/bss/cassandra/ecchronos/data/sync/EccNodeMetadata.java b/data/src/main/java/com/ericsson/bss/cassandra/ecchronos/data/sync/EccNodeMetadata.java new file mode 100644 index 00000000..6eb6a0cb --- /dev/null +++ b/data/src/main/java/com/ericsson/bss/cassandra/ecchronos/data/sync/EccNodeMetadata.java @@ -0,0 +1,134 @@ +/* + * Copyright 2024 Telefonaktiebolaget LM Ericsson + * + * 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 com.ericsson.bss.cassandra.ecchronos.data.sync; + +import com.datastax.oss.driver.api.core.ConsistencyLevel; +import com.datastax.oss.driver.api.core.CqlSession; +import com.datastax.oss.driver.api.core.cql.BoundStatement; +import com.datastax.oss.driver.api.core.cql.PreparedStatement; +import com.datastax.oss.driver.api.core.cql.ResultSet; +import com.datastax.oss.driver.api.core.cql.Row; +import com.datastax.oss.driver.api.core.metadata.Node; +import com.datastax.oss.driver.api.querybuilder.QueryBuilder; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.List; +import java.util.UUID; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.bindMarker; +import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.selectFrom; + +public final class EccNodeMetadata +{ + + private static final Logger LOG = LoggerFactory.getLogger(EccNodeMetadata.class); + private static final String COLUMN_ECCHRONOS_ID = "ecchronos_id"; + private static final String COLUMN_DC_NAME = "datacenter_name"; + private static final String COLUMN_NODE_ID = "node_id"; + private static final String KEYSPACE_NAME = "ecchronos"; + private static final String NODE_METADATA_TABLE_NAME = "nodes_metadata"; + + private final PreparedStatement mySelectStatement; + private final PreparedStatement myCreateStatement; + private final PreparedStatement myTableUpdateStatement; + private final CqlSession mySession; + private final Node myNode; + + public EccNodeMetadata(final List nodes, final CqlSession session) + { + mySession = session; + myNode = nodes.stream().findAny().get(); + myCreateStatement = mySession.prepare(QueryBuilder.insertInto(KEYSPACE_NAME, NODE_METADATA_TABLE_NAME) + .value(COLUMN_DC_NAME, bindMarker()) + .value(COLUMN_NODE_ID, bindMarker()) + .value(COLUMN_ECCHRONOS_ID, bindMarker()) + .build()); + myTableUpdateStatement = mySession.prepare(QueryBuilder.update(KEYSPACE_NAME, NODE_METADATA_TABLE_NAME) + .setColumn(COLUMN_ECCHRONOS_ID, bindMarker()) + .whereColumn(COLUMN_DC_NAME) + .isEqualTo(bindMarker()) + .whereColumn(COLUMN_NODE_ID) + .isEqualTo(bindMarker()) + .build() + .setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM)); + mySelectStatement = mySession.prepare(selectFrom(KEYSPACE_NAME, NODE_METADATA_TABLE_NAME) + .columns(COLUMN_ECCHRONOS_ID) + .whereColumn(COLUMN_DC_NAME) + .isEqualTo(bindMarker()) + .build()); + } + + public String getEccChronosID() throws UnknownHostException + { + ResultSet resultSet = getResultSet(); + + Row row = resultSet.one(); + if (row != null) + { + return row.getString(COLUMN_ECCHRONOS_ID); + } + return generateNewEcChronosID(); + } + + public ResultSet getResultSet() + { + BoundStatement boundStatement = mySelectStatement.bind(myNode.getDatacenter()); + return mySession.execute(boundStatement); + } + + public ResultSet insertNodeMetadataInfo(final String datacenterName, + final UUID nodeID, + final String eccChronosID) + { + BoundStatement insertMetadataInfo = myCreateStatement.bind(datacenterName, nodeID, eccChronosID); + ResultSet tmpResultSet = mySession.execute(insertMetadataInfo); + LOG.info("Preparing to insert node metadata with Datacenter {}, NodeId {} and EccChronosID {}", + datacenterName, nodeID, eccChronosID); + if (tmpResultSet.wasApplied()) + { + LOG.info("Node metadata info successfully stored with EccChronosID {}", eccChronosID); + } + else + { + LOG.error("Unable to store metadata info with NodeId{}", nodeID); + } + return tmpResultSet; + } + + public ResultSet updateNodeMetadataEcChronosIdStatement(final String ecChronosId, + final String datacenterName, + final UUID nodeID) + { + BoundStatement updateEcChronosID = myTableUpdateStatement.bind(ecChronosId, datacenterName, nodeID); + ResultSet tmpResultSet = mySession.execute(updateEcChronosID); + if (tmpResultSet.wasApplied()) + { + LOG.info("Node metadata {} successfully updated", nodeID); + } + else + { + LOG.error("Unable to update node metadata {}", nodeID); + } + return tmpResultSet; + } + + private String generateNewEcChronosID() throws UnknownHostException + { + String uuid = UUID.randomUUID().toString(); + return uuid.concat(InetAddress.getLocalHost().getHostName()); + } +} diff --git a/data/src/main/java/com/ericsson/bss/cassandra/ecchronos/data/sync/EccNodesSync.java b/data/src/main/java/com/ericsson/bss/cassandra/ecchronos/data/sync/EccNodesSync.java index 5b8025c3..e50d88b0 100644 --- a/data/src/main/java/com/ericsson/bss/cassandra/ecchronos/data/sync/EccNodesSync.java +++ b/data/src/main/java/com/ericsson/bss/cassandra/ecchronos/data/sync/EccNodesSync.java @@ -65,6 +65,7 @@ public final class EccNodesSync private final CqlSession mySession; private final List myNodesList; private final String ecChronosID; + private final EccNodeMetadata myEccNodeMetadata; private final PreparedStatement myCreateStatement; private final PreparedStatement myUpdateStatusStatement; @@ -75,8 +76,8 @@ public final class EccNodesSync private EccNodesSync(final Builder builder) throws UnknownHostException { mySession = Preconditions.checkNotNull(builder.mySession, "Session cannot be null"); - myNodesList = Preconditions - .checkNotNull(builder.initialNodesList, "Nodes list cannot be null"); + myNodesList = builder.initialNodesList; + myEccNodeMetadata = new EccNodeMetadata(myNodesList, mySession); myCreateStatement = mySession.prepare(QueryBuilder.insertInto(KEYSPACE_NAME, TABLE_NAME) .value(COLUMN_ECCHRONOS_ID, bindMarker()) .value(COLUMN_DC_NAME, bindMarker()) @@ -91,16 +92,20 @@ private EccNodesSync(final Builder builder) throws UnknownHostException .setColumn(COLUMN_NODE_STATUS, bindMarker()) .setColumn(COLUMN_LAST_CONNECTION, bindMarker()) .setColumn(COLUMN_NEXT_CONNECTION, bindMarker()) - .whereColumn(COLUMN_ECCHRONOS_ID).isEqualTo(bindMarker()) - .whereColumn(COLUMN_DC_NAME).isEqualTo(bindMarker()) - .whereColumn(COLUMN_NODE_ID).isEqualTo(bindMarker()) + .whereColumn(COLUMN_ECCHRONOS_ID) + .isEqualTo(bindMarker()) + .whereColumn(COLUMN_DC_NAME) + .isEqualTo(bindMarker()) + .whereColumn(COLUMN_NODE_ID) + .isEqualTo(bindMarker()) .build() .setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM)); mySelectStatusStatement = mySession.prepare(selectFrom(KEYSPACE_NAME, TABLE_NAME) .columns(COLUMN_NODE_ID, COLUMN_NODE_ENDPOINT, COLUMN_DC_NAME, COLUMN_NODE_STATUS) - .whereColumn(COLUMN_ECCHRONOS_ID).isEqualTo(bindMarker()) + .whereColumn(COLUMN_ECCHRONOS_ID) + .isEqualTo(bindMarker()) .build()); - ecChronosID = builder.myEcchronosID; + ecChronosID = myEccNodeMetadata.getEccChronosID(); connectionDelayValue = builder.myConnectionDelayValue; connectionDelayUnit = builder.myConnectionDelayUnit; @@ -115,10 +120,6 @@ public ResultSet getResultSet() public void acquireNodes() throws EcChronosException { - if (myNodesList.isEmpty()) - { - throw new EcChronosException("Cannot Acquire Nodes because there is no nodes to be acquired"); - } for (Node node : myNodesList) { LOG.info( @@ -129,6 +130,7 @@ public void acquireNodes() throws EcChronosException ResultSet tmpResultSet = acquireNode(node); if (tmpResultSet.wasApplied()) { + myEccNodeMetadata.insertNodeMetadataInfo(node.getDatacenter(), node.getHostId(), ecChronosID); LOG.info("Node successfully acquired by instance {}", ecChronosID); } else @@ -156,13 +158,12 @@ public ResultSet verifyAcquireNode(final Node node) } private ResultSet insertNodeInfo( - final String datacenterName, - final String nodeEndpoint, - final String nodeStatus, - final Instant lastConnection, - final Instant nextConnection, - final UUID nodeID - ) + final String datacenterName, + final String nodeEndpoint, + final String nodeStatus, + final Instant lastConnection, + final Instant nextConnection, + final UUID nodeID) { BoundStatement insertNodeSyncInfo = myCreateStatement.bind(ecChronosID, datacenterName, nodeEndpoint, nodeStatus, lastConnection, nextConnection, nodeID); @@ -170,10 +171,9 @@ private ResultSet insertNodeInfo( } public ResultSet updateNodeStatus( - final NodeStatus nodeStatus, - final String datacenterName, - final UUID nodeID - ) + final NodeStatus nodeStatus, + final String datacenterName, + final UUID nodeID) { ResultSet tmpResultSet = updateNodeStateStatement(nodeStatus, datacenterName, nodeID); if (tmpResultSet.wasApplied()) @@ -188,10 +188,9 @@ public ResultSet updateNodeStatus( } private ResultSet updateNodeStateStatement( - final NodeStatus nodeStatus, - final String datacenterName, - final UUID nodeID - ) + final NodeStatus nodeStatus, + final String datacenterName, + final UUID nodeID) { BoundStatement updateNodeStatus = myUpdateStatusStatement.bind( nodeStatus.toString(), @@ -199,20 +198,18 @@ private ResultSet updateNodeStateStatement( Instant.now().plus(DEFAULT_CONNECTION_DELAY_IN_MINUTES, ChronoUnit.MINUTES), ecChronosID, datacenterName, - nodeID - ); + nodeID); return execute(updateNodeStatus); } @VisibleForTesting public ResultSet verifyInsertNodeInfo( - final String datacenterName, - final String nodeEndpoint, - final String nodeStatus, - final Instant lastConnection, - final Instant nextConnection, - final UUID nodeID - ) + final String datacenterName, + final String nodeEndpoint, + final String nodeStatus, + final Instant lastConnection, + final Instant nextConnection, + final UUID nodeID) { return insertNodeInfo( datacenterName, @@ -220,8 +217,7 @@ public ResultSet verifyInsertNodeInfo( nodeStatus, lastConnection, nextConnection, - nodeID - ); + nodeID); } public ResultSet execute(final BoundStatement statement) @@ -238,7 +234,6 @@ public static class Builder { private CqlSession mySession; private List initialNodesList; - private String myEcchronosID; private Long myConnectionDelayValue; private ChronoUnit myConnectionDelayUnit; @@ -294,29 +289,19 @@ public Builder withConnectionDelayUnit(final TimeUnit connectionDelayUnit) return this; } - /** - * Builds EccNodesSync with ecchronosID. - * - * @param echronosID - * ecchronos ID generated by BeanConfigurator. - * @return Builder - */ - public Builder withEcchronosID(final String echronosID) - { - this.myEcchronosID = echronosID; - return this; - } - /** * Builds EccNodesSync. * * @return Builder * @throws UnknownHostException */ - public EccNodesSync build() throws UnknownHostException + public EccNodesSync build() throws UnknownHostException, EcChronosException { + if (initialNodesList == null || initialNodesList.isEmpty()) + { + throw new EcChronosException("No nodes available because the node list is empty or null"); + } return new EccNodesSync(this); } } } - diff --git a/data/src/test/java/com/ericsson/bss/cassandra/ecchronos/data/sync/TestEccNodeMetadata.java b/data/src/test/java/com/ericsson/bss/cassandra/ecchronos/data/sync/TestEccNodeMetadata.java new file mode 100644 index 00000000..dc1376e6 --- /dev/null +++ b/data/src/test/java/com/ericsson/bss/cassandra/ecchronos/data/sync/TestEccNodeMetadata.java @@ -0,0 +1,123 @@ +/* + * Copyright 2024 Telefonaktiebolaget LM Ericsson + * + * 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 com.ericsson.bss.cassandra.ecchronos.data.sync; + +import com.datastax.oss.driver.api.core.cql.ResultSet; +import com.datastax.oss.driver.api.core.cql.Row; +import com.datastax.oss.driver.api.core.cql.SimpleStatement; +import com.datastax.oss.driver.api.core.metadata.Node; +import com.ericsson.bss.cassandra.ecchronos.data.exceptions.EcChronosException; +import com.ericsson.bss.cassandra.ecchronos.data.utils.AbstractCassandraTest; +import java.io.IOException; +import java.net.UnknownHostException; +import java.util.List; +import java.util.UUID; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +public class TestEccNodeMetadata extends AbstractCassandraTest +{ + private static final String ECCHRONOS_KEYSPACE = "ecchronos"; + private static final String COLUMN_ECCHRONOS_ID = "ecchronos_id"; + + private EccNodeMetadata eccNodeMetadata; + private final List nodesList = getNativeConnectionProvider().getNodes(); + private final UUID nodeID = UUID.randomUUID(); + + @Before + public void setup() throws IOException, EcChronosException + { + mySession.execute(String.format( + "CREATE KEYSPACE IF NOT EXISTS %s WITH replication = {'class': 'NetworkTopologyStrategy', 'DC1': 1}", + ECCHRONOS_KEYSPACE)); + String nodeMetadataQuery = String.format( + "CREATE TABLE IF NOT EXISTS %s.nodes_metadata (" + + "datacenter_name TEXT, " + + "node_id UUID, " + + "ecchronos_id TEXT," + + "PRIMARY KEY (datacenter_name, node_id))", + ECCHRONOS_KEYSPACE); + mySession.execute(nodeMetadataQuery); + eccNodeMetadata = new EccNodeMetadata(nodesList, mySession); + } + + @After + public void testCleanup() + { + mySession.execute(SimpleStatement.newInstance(String.format("TRUNCATE %s.%s", ECCHRONOS_KEYSPACE, "nodes_metadata"))); + } + + @Test + public void testInsertNodeMetadataInfo() throws UnknownHostException + { + String ecchronosId = eccNodeMetadata.getEccChronosID(); + String datacenterName = "datacenter1"; + ResultSet result = eccNodeMetadata.insertNodeMetadataInfo(datacenterName, nodeID, ecchronosId); + assertNotNull(result); + } + + @Test + public void testGetResultSet() throws UnknownHostException + { + String ecchronosId = eccNodeMetadata.getEccChronosID(); + ResultSet resultSet = eccNodeMetadata.getResultSet(); + assertNull(resultSet.one()); + String datacenter = nodesList.get(0).getDatacenter(); + UUID nodeId = nodesList.get(0).getHostId(); + eccNodeMetadata.insertNodeMetadataInfo(datacenter, nodeId, ecchronosId); + resultSet = eccNodeMetadata.getResultSet(); + assertNotNull(resultSet.one()); + } + + @Test + public void testEccChronosIDGenerationAndPersistence() throws UnknownHostException + { + String ecchronosId = eccNodeMetadata.getEccChronosID(); + assertNotNull(ecchronosId); + + String datacenter = nodesList.get(0).getDatacenter(); + UUID nodeId = nodesList.get(0).getHostId(); + ResultSet resultSet = eccNodeMetadata.insertNodeMetadataInfo(datacenter, nodeId, ecchronosId); + assertNotNull(resultSet); + + // This call should not generate new ecchronosId + assertEquals(ecchronosId, eccNodeMetadata.getEccChronosID()); + } + + @Test + public void testUpdateNodeMetadataEcChronosIdStatement() throws UnknownHostException + { + String ecchronosId = eccNodeMetadata.getEccChronosID(); + String datacenter = nodesList.get(0).getDatacenter(); + UUID nodeId = nodesList.get(0).getHostId(); + eccNodeMetadata.insertNodeMetadataInfo(datacenter, nodeId, ecchronosId); + ResultSet resultSet = eccNodeMetadata.getResultSet(); + Row row = resultSet.one(); + String ecchronosIdInDb = row.getString(COLUMN_ECCHRONOS_ID); + assertEquals(ecchronosId, ecchronosIdInDb); + + String newEcchronosId = "newEcchronosId"; + assertNotNull(eccNodeMetadata.updateNodeMetadataEcChronosIdStatement(newEcchronosId, datacenter, nodeId)); + resultSet = eccNodeMetadata.getResultSet(); + row = resultSet.one(); + String updatedEcchronosIdInDb = row.getString(COLUMN_ECCHRONOS_ID); + assertEquals(newEcchronosId, updatedEcchronosIdInDb); + } +} diff --git a/data/src/test/java/com/ericsson/bss/cassandra/ecchronos/data/sync/TestEccNodesSync.java b/data/src/test/java/com/ericsson/bss/cassandra/ecchronos/data/sync/TestEccNodesSync.java index 3fa82668..aaa5ddf3 100644 --- a/data/src/test/java/com/ericsson/bss/cassandra/ecchronos/data/sync/TestEccNodesSync.java +++ b/data/src/test/java/com/ericsson/bss/cassandra/ecchronos/data/sync/TestEccNodesSync.java @@ -35,7 +35,6 @@ import java.util.UUID; import java.util.concurrent.TimeUnit; - import static org.junit.Assert.*; @NotThreadSafe @@ -49,7 +48,7 @@ public class TestEccNodesSync extends AbstractCassandraTest private final String datacenterName = "datacenter1"; @Before - public void setup() throws IOException + public void setup() throws IOException, EcChronosException { mySession.execute(String.format( "CREATE KEYSPACE IF NOT EXISTS %s WITH replication = {'class': 'NetworkTopologyStrategy', 'DC1': 1}", @@ -65,17 +64,25 @@ public void setup() throws IOException "next_connection TIMESTAMP, " + "PRIMARY KEY(ecchronos_id, datacenter_name, node_id)) " + "WITH CLUSTERING ORDER BY( datacenter_name DESC, node_id DESC);", - ECCHRONOS_KEYSPACE - ); + ECCHRONOS_KEYSPACE); + + String nodeMetadataQuery = String.format( + "CREATE TABLE IF NOT EXISTS %s.nodes_metadata (" + + "datacenter_name TEXT, " + + "node_id UUID, " + + "ecchronos_id TEXT," + + "PRIMARY KEY (datacenter_name, node_id))", + ECCHRONOS_KEYSPACE); mySession.execute(query); + mySession.execute(nodeMetadataQuery); eccNodesSync = EccNodesSync.newBuilder() .withSession(mySession) .withInitialNodesList(nodesList) .withConnectionDelayValue(Long.valueOf(10)) .withConnectionDelayUnit(TimeUnit.MINUTES) - .withEcchronosID("ecchronos-test").build(); + .build(); } @After @@ -120,22 +127,22 @@ public void testEccNodesWithNullList() EccNodesSync.Builder tmpEccNodesSyncBuilder = EccNodesSync.newBuilder() .withSession(mySession) .withInitialNodesList(null); - NullPointerException exception = assertThrows( - NullPointerException.class, tmpEccNodesSyncBuilder::build); - assertEquals("Nodes list cannot be null", exception.getMessage()); + EcChronosException exception = assertThrows( + EcChronosException.class, tmpEccNodesSyncBuilder::build); + assertEquals("No nodes available because the node list is empty or null", exception.getMessage()); } @Test - public void testAcquiredNodesWithEmptyList() throws UnknownHostException + public void testEccNodesSyncWithEmptyList() throws UnknownHostException, EcChronosException { - EccNodesSync tmpEccNodesSync = EccNodesSync.newBuilder() - .withSession(mySession) - .withInitialNodesList(new ArrayList<>()).build(); EcChronosException exception = assertThrows( - EcChronosException.class, tmpEccNodesSync::acquireNodes); - assertEquals( - "Cannot Acquire Nodes because there is no nodes to be acquired", - exception.getMessage()); + EcChronosException.class, + () -> EccNodesSync.newBuilder() + .withSession(mySession) + .withInitialNodesList(new ArrayList<>()) + .build() + ); + assertEquals("No nodes available because the node list is empty or null", exception.getMessage()); } @Test @@ -152,8 +159,10 @@ public void testEccNodesWithNullSession() @Test public void testGetAllNodes() { - eccNodesSync.verifyInsertNodeInfo(datacenterName, "127.0.0.1", NodeStatus.AVAILABLE.name(), Instant.now(), Instant.now().plus(30, ChronoUnit.MINUTES), UUID.randomUUID()); - eccNodesSync.verifyInsertNodeInfo(datacenterName, "127.0.0.2", NodeStatus.UNAVAILABLE.name(), Instant.now(), Instant.now().plus(30, ChronoUnit.MINUTES), UUID.randomUUID()); + eccNodesSync.verifyInsertNodeInfo(datacenterName, "127.0.0.1", NodeStatus.AVAILABLE.name(), Instant.now(), + Instant.now().plus(30, ChronoUnit.MINUTES), UUID.randomUUID()); + eccNodesSync.verifyInsertNodeInfo(datacenterName, "127.0.0.2", NodeStatus.UNAVAILABLE.name(), Instant.now(), + Instant.now().plus(30, ChronoUnit.MINUTES), UUID.randomUUID()); ResultSet resultSet = eccNodesSync.getResultSet(); assertNotNull(resultSet); }