use of org.neo4j.causalclustering.discovery.ReadReplica in project neo4j by neo4j.
the class BoltCausalClusteringIT method shouldSendRequestsToNewlyAddedReadReplicas.
@Test
public void shouldSendRequestsToNewlyAddedReadReplicas() throws Throwable {
// given
cluster = clusterRule.withNumberOfReadReplicas(1).withSharedCoreParams(stringMap(CausalClusteringSettings.cluster_routing_ttl.name(), "1s")).startCluster();
CoreClusterMember leader = cluster.awaitLeader();
Driver driver = GraphDatabase.driver(leader.routingURI(), AuthTokens.basic("neo4j", "neo4j"));
String bookmark = inExpirableSession(driver, (d) -> d.session(AccessMode.WRITE), (session) -> {
try (Transaction tx = session.beginTransaction()) {
tx.run("CREATE (p:Person {name: {name} })", Values.parameters("name", "Jim"));
tx.success();
}
return session.lastBookmark();
});
// when
Set<String> readReplicas = new HashSet<>();
for (ReadReplica readReplica : cluster.readReplicas()) {
readReplicas.add(readReplica.boltAdvertisedAddress());
}
for (int i = 10; i <= 13; i++) {
ReadReplica newReadReplica = cluster.addReadReplicaWithId(i);
readReplicas.add(newReadReplica.boltAdvertisedAddress());
newReadReplica.start();
}
assertEventually("Failed to send requests to all servers", () -> {
for (// don't care about cores
int i = 0; // don't care about cores
i < cluster.readReplicas().size(); // don't care about cores
i++) {
try (Session session = driver.session(AccessMode.READ)) {
BoltServerAddress boltServerAddress = ((RoutingNetworkSession) session).address();
executeReadQuery(bookmark, session);
readReplicas.remove(boltServerAddress.toString());
} catch (Throwable throwable) {
return false;
}
}
// have sent something to all replicas
return readReplicas.size() == 0;
}, is(true), 30, SECONDS);
}
use of org.neo4j.causalclustering.discovery.ReadReplica in project neo4j by neo4j.
the class BoltCausalClusteringIT method shouldUseBookmarkFromAWriteSessionInAReadSession.
@Test
public void shouldUseBookmarkFromAWriteSessionInAReadSession() throws Throwable {
// given
cluster = clusterRule.withNumberOfReadReplicas(1).startCluster();
CoreClusterMember leader = cluster.awaitLeader();
ReadReplica readReplica = cluster.getReadReplicaById(0);
readReplica.txPollingClient().stop();
Driver driver = GraphDatabase.driver(leader.directURI(), AuthTokens.basic("neo4j", "neo4j"));
String bookmark = inExpirableSession(driver, (d) -> d.session(AccessMode.WRITE), (session) -> {
try (Transaction tx = session.beginTransaction()) {
tx.run("CREATE (p:Person {name: {name} })", Values.parameters("name", "Jim"));
tx.run("CREATE (p:Person {name: {name} })", Values.parameters("name", "Alistair"));
tx.run("CREATE (p:Person {name: {name} })", Values.parameters("name", "Mark"));
tx.run("CREATE (p:Person {name: {name} })", Values.parameters("name", "Chris"));
tx.success();
}
return session.lastBookmark();
});
assertNotNull(bookmark);
readReplica.txPollingClient().start();
driver = GraphDatabase.driver(readReplica.directURI(), AuthTokens.basic("neo4j", "neo4j"));
try (Session session = driver.session(AccessMode.READ)) {
try (Transaction tx = session.beginTransaction(bookmark)) {
Record record = tx.run("MATCH (n:Person) RETURN COUNT(*) AS count").next();
tx.success();
assertEquals(4, record.get("count").asInt());
}
}
}
use of org.neo4j.causalclustering.discovery.ReadReplica in project neo4j by neo4j.
the class BoltCausalClusteringIT method sessionCreationShouldFailIfCallingDiscoveryProcedureOnEdgeServer.
@Test
public void sessionCreationShouldFailIfCallingDiscoveryProcedureOnEdgeServer() throws Exception {
// given
cluster = clusterRule.withNumberOfReadReplicas(1).startCluster();
ReadReplica readReplica = cluster.getReadReplicaById(0);
try {
GraphDatabase.driver(readReplica.routingURI(), AuthTokens.basic("neo4j", "neo4j"));
fail("Should have thrown an exception using a read replica address for routing");
} catch (ServiceUnavailableException ex) {
// then
assertEquals(format("Server %s couldn't perform discovery", readReplica.boltAdvertisedAddress()), ex.getMessage());
}
}
use of org.neo4j.causalclustering.discovery.ReadReplica in project neo4j by neo4j.
the class ReadReplicaHierarchicalCatchupIT method shouldCatchupThroughHierarchy.
@Test
public void shouldCatchupThroughHierarchy() throws Throwable {
clusterRule = clusterRule.withInstanceReadReplicaParam(CausalClusteringSettings.server_groups, id -> serverGroups.get(id)).withInstanceCoreParam(CausalClusteringSettings.server_groups, id -> serverGroups.get(id));
// given
Cluster cluster = clusterRule.startCluster();
int numberOfNodesToCreate = 100;
cluster.coreTx((db, tx) -> {
db.schema().constraintFor(label("Foo")).assertPropertyIsUnique("foobar").create();
tx.success();
});
// 0, 1, 2 are core instances
createLabelledNodesWithProperty(cluster, numberOfNodesToCreate, label("Foo"), () -> Pair.of("foobar", String.format("baz_bat%s", UUID.randomUUID())));
// 3, 4 are other DCs
ReadReplica east3 = cluster.addReadReplicaWithId(3);
east3.start();
ReadReplica west4 = cluster.addReadReplicaWithId(4);
west4.start();
checkDataHasReplicatedToReadReplicas(cluster, numberOfNodesToCreate);
for (CoreClusterMember coreClusterMember : cluster.coreMembers()) {
coreClusterMember.stopCatchupServer();
}
// 5, 6 are other DCs
ReadReplica east5 = cluster.addReadReplicaWithId(5);
east5.setUpstreamDatabaseSelectionStrategy("connect-within-data-center");
east5.start();
ReadReplica west6 = cluster.addReadReplicaWithId(6);
west6.setUpstreamDatabaseSelectionStrategy("connect-within-data-center");
west6.start();
checkDataHasReplicatedToReadReplicas(cluster, numberOfNodesToCreate);
}
use of org.neo4j.causalclustering.discovery.ReadReplica in project neo4j by neo4j.
the class ReadReplicaReplicationIT method shouldShutdownRatherThanPullUpdatesFromCoreMemberWithDifferentStoreIdIfLocalStoreIsNonEmpty.
@Test
public void shouldShutdownRatherThanPullUpdatesFromCoreMemberWithDifferentStoreIdIfLocalStoreIsNonEmpty() throws Exception {
Cluster cluster = clusterRule.withNumberOfReadReplicas(0).startCluster();
cluster.coreTx(createSomeData);
cluster.awaitCoreMemberWithRole(Role.FOLLOWER, 2, TimeUnit.SECONDS);
// Get a read replica and make sure that it is operational
ReadReplica readReplica = cluster.addReadReplicaWithId(4);
readReplica.start();
readReplica.database().beginTx().close();
// Change the store id, so it should fail to join the cluster again
changeStoreId(readReplica);
readReplica.shutdown();
try {
readReplica.start();
fail("Should have failed to start");
} catch (RuntimeException required) {
// Lifecycle should throw exception, server should not start.
assertThat(required.getCause(), instanceOf(LifecycleException.class));
assertThat(required.getCause().getCause(), instanceOf(Exception.class));
assertThat(required.getCause().getCause().getMessage(), containsString("This read replica cannot join the cluster. " + "The local database is not empty and has a mismatching storeId:"));
}
}
Aggregations