1
0
Fork 0

Bug fix/allow agency ops in active failover (#9881)

* allow agency operations in active failover too

* Added regression test

* Allowed more calls in active failover for the health endpoint to work

* Updated CHANGELOG
This commit is contained in:
Tobias Gödderz 2019-09-09 16:53:57 +02:00 committed by Michael Hackstein
parent 98fea326ea
commit 9e9fa3a4f1
3 changed files with 99 additions and 106 deletions

View File

@ -1,6 +1,9 @@
devel devel
----- -----
* Fixed "ArangoDB is not running in cluster mode" errors in active failover setups.
This affected at least /_admin/cluster/health.
* Fixed the removal (including a collection drop) of an orphanCollection from a * Fixed the removal (including a collection drop) of an orphanCollection from a
graph definition when using the arango shell. The boolean graph definition when using the arango shell. The boolean
flag whether to drop the collection or not was not transferred properly. flag whether to drop the collection or not was not transferred properly.
@ -16,7 +19,7 @@ devel
above inconsistencies. Also creation of databases are now secured against above inconsistencies. Also creation of databases are now secured against
coordinator outages, they will either be fully created or not visible and coordinator outages, they will either be fully created or not visible and
eventually dropped. This does not require any change on the client code. eventually dropped. This does not require any change on the client code.
* Added UI support to create documents in a collection using smartGraphAttribute * Added UI support to create documents in a collection using smartGraphAttribute
and/or smartJoinAttribute. and/or smartJoinAttribute.

View File

@ -28,11 +28,13 @@
#include "Agency/AgencyComm.h" #include "Agency/AgencyComm.h"
#include "ApplicationFeatures/ApplicationServer.h" #include "ApplicationFeatures/ApplicationServer.h"
#include "Basics/Exceptions.h"
#include "Basics/StringBuffer.h" #include "Basics/StringBuffer.h"
#include "Cluster/ClusterComm.h" #include "Cluster/ClusterComm.h"
#include "Cluster/ClusterInfo.h" #include "Cluster/ClusterInfo.h"
#include "Cluster/ServerState.h" #include "Cluster/ServerState.h"
#include "GeneralServer/AuthenticationFeature.h" #include "GeneralServer/AuthenticationFeature.h"
#include "Replication/ReplicationFeature.h"
#include "Sharding/ShardDistributionReporter.h" #include "Sharding/ShardDistributionReporter.h"
#include "V8/v8-buffer.h" #include "V8/v8-buffer.h"
#include "V8/v8-conv.h" #include "V8/v8-conv.h"
@ -54,12 +56,24 @@ using namespace arangodb::basics;
CreateAgencyException(args, data); \ CreateAgencyException(args, data); \
return; return;
#define ONLY_IN_CLUSTER \ static void onlyInCluster() {
if (!ServerState::instance()->isRunningInCluster()) { \ if (ServerState::instance()->isRunningInCluster()) {
TRI_V8_THROW_EXCEPTION_INTERNAL( \ return;
"ArangoDB is not running in cluster mode"); \
} }
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "ArangoDB is not running in cluster mode");
}
static void onlyInClusterOrActiveFailover() {
auto replicationFeature = ReplicationFeature::INSTANCE;
if (replicationFeature != nullptr && replicationFeature->isActiveFailoverEnabled()) {
// active failover enabled
return;
}
return onlyInCluster();
}
static void CreateAgencyException(v8::FunctionCallbackInfo<v8::Value> const& args, static void CreateAgencyException(v8::FunctionCallbackInfo<v8::Value> const& args,
AgencyCommResult const& result) { AgencyCommResult const& result) {
v8::Isolate* isolate = args.GetIsolate(); v8::Isolate* isolate = args.GetIsolate();
@ -102,7 +116,7 @@ static void JS_CasAgency(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER; onlyInClusterOrActiveFailover();
if (args.Length() < 3) { if (args.Length() < 3) {
TRI_V8_THROW_EXCEPTION_USAGE( TRI_V8_THROW_EXCEPTION_USAGE(
@ -164,7 +178,7 @@ static void JS_CreateDirectoryAgency(v8::FunctionCallbackInfo<v8::Value> const&
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER; onlyInClusterOrActiveFailover();
if (args.Length() != 1) { if (args.Length() != 1) {
TRI_V8_THROW_EXCEPTION_USAGE("createDirectory(<key>)"); TRI_V8_THROW_EXCEPTION_USAGE("createDirectory(<key>)");
@ -211,7 +225,7 @@ static void JS_IncreaseVersionAgency(v8::FunctionCallbackInfo<v8::Value> const&
TRI_V8_TRY_CATCH_BEGIN(isolate) TRI_V8_TRY_CATCH_BEGIN(isolate)
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER; onlyInClusterOrActiveFailover();
if (args.Length() != 1) { if (args.Length() != 1) {
TRI_V8_THROW_EXCEPTION_USAGE("increaseVersion(<key>)"); TRI_V8_THROW_EXCEPTION_USAGE("increaseVersion(<key>)");
@ -237,7 +251,7 @@ static void JS_GetAgency(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate) TRI_V8_TRY_CATCH_BEGIN(isolate)
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER; onlyInClusterOrActiveFailover();
if (args.Length() < 1) { if (args.Length() < 1) {
TRI_V8_THROW_EXCEPTION_USAGE("get(<key>)"); TRI_V8_THROW_EXCEPTION_USAGE("get(<key>)");
@ -279,7 +293,7 @@ static void JS_APIAgency(std::string const& envelope,
TRI_V8_TRY_CATCH_BEGIN(isolate) TRI_V8_TRY_CATCH_BEGIN(isolate)
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER; onlyInClusterOrActiveFailover();
if (args.Length() < 1) { if (args.Length() < 1) {
TRI_V8_THROW_EXCEPTION_USAGE(std::string(envelope) + "([[...]])"); TRI_V8_THROW_EXCEPTION_USAGE(std::string(envelope) + "([[...]])");
@ -344,7 +358,7 @@ static void JS_RemoveAgency(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER; onlyInClusterOrActiveFailover();
if (args.Length() < 1) { if (args.Length() < 1) {
TRI_V8_THROW_EXCEPTION_USAGE("remove(<key>, <recursive>)"); TRI_V8_THROW_EXCEPTION_USAGE("remove(<key>, <recursive>)");
@ -376,7 +390,7 @@ static void JS_SetAgency(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER; onlyInClusterOrActiveFailover();
if (args.Length() < 2) { if (args.Length() < 2) {
TRI_V8_THROW_EXCEPTION_USAGE("set(<key>, <value>, <ttl>)"); TRI_V8_THROW_EXCEPTION_USAGE("set(<key>, <value>, <ttl>)");
@ -415,7 +429,7 @@ static void JS_Agency(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate) TRI_V8_TRY_CATCH_BEGIN(isolate)
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER; onlyInClusterOrActiveFailover();
if (args.Length() > 0) { if (args.Length() > 0) {
TRI_V8_THROW_EXCEPTION_USAGE("agency()"); TRI_V8_THROW_EXCEPTION_USAGE("agency()");
@ -458,7 +472,7 @@ static void JS_EndpointsAgency(v8::FunctionCallbackInfo<v8::Value> const& args)
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER; onlyInClusterOrActiveFailover();
if (args.Length() != 0) { if (args.Length() != 0) {
TRI_V8_THROW_EXCEPTION_USAGE("endpoints()"); TRI_V8_THROW_EXCEPTION_USAGE("endpoints()");
@ -503,7 +517,7 @@ static void JS_UniqidAgency(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER; onlyInClusterOrActiveFailover();
if (args.Length() > 2) { if (args.Length() > 2) {
TRI_V8_THROW_EXCEPTION_USAGE("uniqid(<count>, <timeout>)"); TRI_V8_THROW_EXCEPTION_USAGE("uniqid(<count>, <timeout>)");
@ -540,7 +554,7 @@ static void JS_VersionAgency(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER; onlyInClusterOrActiveFailover();
if (args.Length() != 0) { if (args.Length() != 0) {
TRI_V8_THROW_EXCEPTION_USAGE("version()"); TRI_V8_THROW_EXCEPTION_USAGE("version()");
@ -561,7 +575,8 @@ static void JS_DoesDatabaseExistClusterInfo(v8::FunctionCallbackInfo<v8::Value>
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER onlyInCluster();
if (args.Length() != 1) { if (args.Length() != 1) {
TRI_V8_THROW_EXCEPTION_USAGE("doesDatabaseExist(<database-id>)"); TRI_V8_THROW_EXCEPTION_USAGE("doesDatabaseExist(<database-id>)");
} }
@ -583,12 +598,13 @@ static void JS_DoesDatabaseExistClusterInfo(v8::FunctionCallbackInfo<v8::Value>
static void JS_Databases(v8::FunctionCallbackInfo<v8::Value> const& args) { static void JS_Databases(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
onlyInCluster();
if (args.Length() != 0) { if (args.Length() != 0) {
TRI_V8_THROW_EXCEPTION_USAGE("databases()"); TRI_V8_THROW_EXCEPTION_USAGE("databases()");
} }
ONLY_IN_CLUSTER
std::vector<DatabaseID> res = ClusterInfo::instance()->databases(true); std::vector<DatabaseID> res = ClusterInfo::instance()->databases(true);
v8::Handle<v8::Array> a = v8::Array::New(isolate, (int)res.size()); v8::Handle<v8::Array> a = v8::Array::New(isolate, (int)res.size());
std::vector<DatabaseID>::iterator it; std::vector<DatabaseID>::iterator it;
@ -608,7 +624,8 @@ static void JS_FlushClusterInfo(v8::FunctionCallbackInfo<v8::Value> const& args)
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER onlyInCluster();
if (args.Length() != 0) { if (args.Length() != 0) {
TRI_V8_THROW_EXCEPTION_USAGE("flush()"); TRI_V8_THROW_EXCEPTION_USAGE("flush()");
} }
@ -627,7 +644,8 @@ static void JS_GetCollectionInfoClusterInfo(v8::FunctionCallbackInfo<v8::Value>
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER onlyInCluster();
if (args.Length() != 2) { if (args.Length() != 2) {
TRI_V8_THROW_EXCEPTION_USAGE( TRI_V8_THROW_EXCEPTION_USAGE(
"getCollectionInfo(<database-id>, <collection-id>)"); "getCollectionInfo(<database-id>, <collection-id>)");
@ -698,7 +716,8 @@ static void JS_GetCollectionInfoCurrentClusterInfo(v8::FunctionCallbackInfo<v8::
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER onlyInCluster();
if (args.Length() != 3) { if (args.Length() != 3) {
TRI_V8_THROW_EXCEPTION_USAGE( TRI_V8_THROW_EXCEPTION_USAGE(
"getCollectionInfoCurrent(<database-id>, <collection-id>, <shardID>)"); "getCollectionInfoCurrent(<database-id>, <collection-id>, <shardID>)");
@ -774,7 +793,8 @@ static void JS_GetResponsibleServerClusterInfo(v8::FunctionCallbackInfo<v8::Valu
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER onlyInCluster();
if (args.Length() != 1) { if (args.Length() != 1) {
TRI_V8_THROW_EXCEPTION_USAGE("getResponsibleServer(<shard-id>)"); TRI_V8_THROW_EXCEPTION_USAGE("getResponsibleServer(<shard-id>)");
} }
@ -799,7 +819,8 @@ static void JS_GetResponsibleServersClusterInfo(v8::FunctionCallbackInfo<v8::Val
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER onlyInCluster();
if (args.Length() != 1 || !args[0]->IsArray()) { if (args.Length() != 1 || !args[0]->IsArray()) {
TRI_V8_THROW_EXCEPTION_USAGE("getResponsibleServers(<shard-ids>)"); TRI_V8_THROW_EXCEPTION_USAGE("getResponsibleServers(<shard-ids>)");
} }
@ -835,7 +856,8 @@ static void JS_GetResponsibleShardClusterInfo(v8::FunctionCallbackInfo<v8::Value
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER onlyInCluster();
if (args.Length() < 2 || args.Length() > 3) { if (args.Length() < 2 || args.Length() > 3) {
TRI_V8_THROW_EXCEPTION_USAGE( TRI_V8_THROW_EXCEPTION_USAGE(
"getResponsibleShard(<collection-id>, <document>, " "getResponsibleShard(<collection-id>, <document>, "
@ -898,7 +920,8 @@ static void JS_GetServerEndpointClusterInfo(v8::FunctionCallbackInfo<v8::Value>
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER onlyInCluster();
if (args.Length() != 1) { if (args.Length() != 1) {
TRI_V8_THROW_EXCEPTION_USAGE("getServerEndpoint(<server-id>)"); TRI_V8_THROW_EXCEPTION_USAGE("getServerEndpoint(<server-id>)");
} }
@ -918,7 +941,8 @@ static void JS_GetServerNameClusterInfo(v8::FunctionCallbackInfo<v8::Value> cons
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER onlyInCluster();
if (args.Length() != 1) { if (args.Length() != 1) {
TRI_V8_THROW_EXCEPTION_USAGE("getServerName(<endpoint>)"); TRI_V8_THROW_EXCEPTION_USAGE("getServerName(<endpoint>)");
} }
@ -938,7 +962,8 @@ static void JS_GetDBServers(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER onlyInCluster();
if (args.Length() != 0) { if (args.Length() != 0) {
TRI_V8_THROW_EXCEPTION_USAGE("getDBServers()"); TRI_V8_THROW_EXCEPTION_USAGE("getDBServers()");
} }
@ -979,7 +1004,7 @@ static void JS_GetCoordinators(v8::FunctionCallbackInfo<v8::Value> const& args)
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER onlyInCluster();
if (args.Length() != 0) { if (args.Length() != 0) {
TRI_V8_THROW_EXCEPTION_USAGE("getCoordinators()"); TRI_V8_THROW_EXCEPTION_USAGE("getCoordinators()");
@ -1059,7 +1084,8 @@ static void JS_IdServerState(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER onlyInClusterOrActiveFailover();
if (args.Length() != 0) { if (args.Length() != 0) {
TRI_V8_THROW_EXCEPTION_USAGE("id()"); TRI_V8_THROW_EXCEPTION_USAGE("id()");
} }
@ -1147,40 +1173,6 @@ static void JS_GetFoxxmasterSince(v8::FunctionCallbackInfo<v8::Value> const& arg
TRI_V8_TRY_CATCH_END TRI_V8_TRY_CATCH_END
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief return the primary servers id (only for secondaries)
////////////////////////////////////////////////////////////////////////////////
static void JS_IdOfPrimaryServerState(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER
if (args.Length() != 0) {
TRI_V8_THROW_EXCEPTION_USAGE("idOfPrimary()");
}
TRI_V8_RETURN_STRING(""); // no more secondaries
TRI_V8_TRY_CATCH_END
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the javascript startup path
////////////////////////////////////////////////////////////////////////////////
static void JS_JavaScriptPathServerState(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate);
if (args.Length() != 0) {
TRI_V8_THROW_EXCEPTION_USAGE("javaScriptPath()");
}
std::string const path = ServerState::instance()->getJavaScriptPath();
TRI_V8_RETURN_STD_STRING(path);
TRI_V8_TRY_CATCH_END
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief return whether the cluster is initialized /// @brief return whether the cluster is initialized
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -1262,29 +1254,6 @@ static void JS_SetRoleServerState(v8::FunctionCallbackInfo<v8::Value> const& arg
TRI_V8_TRY_CATCH_END TRI_V8_TRY_CATCH_END
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief redetermines the role from the agency
////////////////////////////////////////////////////////////////////////////////
static void JS_RedetermineRoleServerState(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER
if (args.Length() != 0) {
TRI_V8_THROW_EXCEPTION_USAGE("redetermineRole()");
}
/*bool changed = ServerState::instance()->redetermineRole();
if (changed) {
TRI_V8_RETURN_TRUE();
} else {
}*/
TRI_V8_RETURN_FALSE();
TRI_V8_TRY_CATCH_END
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief returns the server state /// @brief returns the server state
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -1321,7 +1290,8 @@ static void PrepareClusterCommRequest(v8::FunctionCallbackInfo<v8::Value> const&
v8::Local<v8::Context> context = isolate->GetCurrentContext(); v8::Local<v8::Context> context = isolate->GetCurrentContext();
TRI_V8_CURRENT_GLOBALS_AND_SCOPE; TRI_V8_CURRENT_GLOBALS_AND_SCOPE;
ONLY_IN_CLUSTER onlyInClusterOrActiveFailover();
TRI_ASSERT(args.Length() >= 4); TRI_ASSERT(args.Length() >= 4);
reqType = arangodb::rest::RequestType::GET; reqType = arangodb::rest::RequestType::GET;
@ -1552,7 +1522,8 @@ static void Return_PrepareClusterCommResultForJS(v8::FunctionCallbackInfo<v8::Va
static void JS_AsyncRequest(v8::FunctionCallbackInfo<v8::Value> const& args) { static void JS_AsyncRequest(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER
onlyInClusterOrActiveFailover();
if (args.Length() < 4 || args.Length() > 7) { if (args.Length() < 4 || args.Length() > 7) {
TRI_V8_THROW_EXCEPTION_USAGE( TRI_V8_THROW_EXCEPTION_USAGE(
@ -1609,7 +1580,8 @@ static void JS_AsyncRequest(v8::FunctionCallbackInfo<v8::Value> const& args) {
static void JS_SyncRequest(v8::FunctionCallbackInfo<v8::Value> const& args) { static void JS_SyncRequest(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER
onlyInCluster();
if (args.Length() < 4 || args.Length() > 7) { if (args.Length() < 4 || args.Length() > 7) {
TRI_V8_THROW_EXCEPTION_USAGE( TRI_V8_THROW_EXCEPTION_USAGE(
@ -1670,7 +1642,8 @@ static void JS_SyncRequest(v8::FunctionCallbackInfo<v8::Value> const& args) {
static void JS_Enquire(v8::FunctionCallbackInfo<v8::Value> const& args) { static void JS_Enquire(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
ONLY_IN_CLUSTER
onlyInCluster();
if (args.Length() != 1) { if (args.Length() != 1) {
TRI_V8_THROW_EXCEPTION_USAGE("enquire(operationID)"); TRI_V8_THROW_EXCEPTION_USAGE("enquire(operationID)");
@ -1702,7 +1675,8 @@ static void JS_Wait(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::Local<v8::Context> context = isolate->GetCurrentContext(); v8::Local<v8::Context> context = isolate->GetCurrentContext();
TRI_V8_CURRENT_GLOBALS_AND_SCOPE; TRI_V8_CURRENT_GLOBALS_AND_SCOPE;
ONLY_IN_CLUSTER
onlyInClusterOrActiveFailover();
if (args.Length() != 1) { if (args.Length() != 1) {
TRI_V8_THROW_EXCEPTION_USAGE("wait(obj)"); TRI_V8_THROW_EXCEPTION_USAGE("wait(obj)");
@ -1767,7 +1741,8 @@ static void JS_Drop(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::Local<v8::Context> context = isolate->GetCurrentContext(); v8::Local<v8::Context> context = isolate->GetCurrentContext();
TRI_V8_CURRENT_GLOBALS_AND_SCOPE; TRI_V8_CURRENT_GLOBALS_AND_SCOPE;
ONLY_IN_CLUSTER
onlyInCluster();
if (args.Length() != 1) { if (args.Length() != 1) {
TRI_V8_THROW_EXCEPTION_USAGE("drop(obj)"); TRI_V8_THROW_EXCEPTION_USAGE("drop(obj)");
@ -1868,7 +1843,8 @@ static void JS_ClusterDownload(v8::FunctionCallbackInfo<v8::Value> const& args)
static void JS_GetShardDistribution(v8::FunctionCallbackInfo<v8::Value> const& args) { static void JS_GetShardDistribution(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
ONLY_IN_CLUSTER
onlyInCluster();
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
auto& vocbase = GetContextVocBase(isolate); auto& vocbase = GetContextVocBase(isolate);
@ -1887,7 +1863,8 @@ static void JS_GetShardDistribution(v8::FunctionCallbackInfo<v8::Value> const& a
static void JS_GetCollectionShardDistribution(v8::FunctionCallbackInfo<v8::Value> const& args) { static void JS_GetCollectionShardDistribution(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate); TRI_V8_TRY_CATCH_BEGIN(isolate);
ONLY_IN_CLUSTER
onlyInCluster();
if (args.Length() != 1) { if (args.Length() != 1) {
TRI_V8_THROW_EXCEPTION_USAGE( TRI_V8_THROW_EXCEPTION_USAGE(
@ -2043,11 +2020,6 @@ void TRI_InitV8Cluster(v8::Isolate* isolate, v8::Handle<v8::Context> context) {
TRI_AddMethodVocbase(isolate, rt, TRI_AddMethodVocbase(isolate, rt,
TRI_V8_ASCII_STRING(isolate, "getFoxxmasterSince"), TRI_V8_ASCII_STRING(isolate, "getFoxxmasterSince"),
JS_GetFoxxmasterSince); JS_GetFoxxmasterSince);
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING(isolate, "idOfPrimary"),
JS_IdOfPrimaryServerState);
TRI_AddMethodVocbase(isolate, rt,
TRI_V8_ASCII_STRING(isolate, "javaScriptPath"),
JS_JavaScriptPathServerState);
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING(isolate, "initialized"), TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING(isolate, "initialized"),
JS_InitializedServerState); JS_InitializedServerState);
TRI_AddMethodVocbase(isolate, rt, TRI_AddMethodVocbase(isolate, rt,
@ -2056,9 +2028,6 @@ void TRI_InitV8Cluster(v8::Isolate* isolate, v8::Handle<v8::Context> context) {
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING(isolate, "role"), JS_RoleServerState); TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING(isolate, "role"), JS_RoleServerState);
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING(isolate, "setRole"), TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING(isolate, "setRole"),
JS_SetRoleServerState, true); JS_SetRoleServerState, true);
TRI_AddMethodVocbase(isolate, rt,
TRI_V8_ASCII_STRING(isolate, "redetermineRole"),
JS_RedetermineRoleServerState, true);
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING(isolate, "status"), JS_StatusServerState); TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING(isolate, "status"), JS_StatusServerState);
v8g->ServerStateTempl.Reset(isolate, rt); v8g->ServerStateTempl.Reset(isolate, rt);

View File

@ -26,7 +26,8 @@
const jsunity = require('jsunity'); const jsunity = require('jsunity');
const internal = require('internal'); const internal = require('internal');
const fs = require('fs'); const console = require('console');
const expect = require('chai').expect;
const arangosh = require('@arangodb/arangosh'); const arangosh = require('@arangodb/arangosh');
const crypto = require('@arangodb/crypto'); const crypto = require('@arangodb/crypto');
@ -74,12 +75,12 @@ function getUrl(endpoint) {
function baseUrl() { function baseUrl() {
return getUrl(arango.getEndpoint()); return getUrl(arango.getEndpoint());
}; }
function connectToServer(leader) { function connectToServer(leader) {
arango.reconnect(leader, "_system", "root", ""); arango.reconnect(leader, "_system", "root", "");
db._flushCache(); db._flushCache();
}; }
// getEndponts works with any server // getEndponts works with any server
function getClusterEndpoints() { function getClusterEndpoints() {
@ -477,7 +478,7 @@ function ActiveFailoverSuite() {
assertTrue(checkInSync(currentLead, servers)); assertTrue(checkInSync(currentLead, servers));
assertEqual(checkData(currentLead), 10000); assertEqual(checkData(currentLead), 10000);
} },
// Try to cleanup everything that was created // Try to cleanup everything that was created
/*testCleanup: function () { /*testCleanup: function () {
@ -494,6 +495,26 @@ function ActiveFailoverSuite() {
assertTrue(checkInSync(lead, servers)); assertTrue(checkInSync(lead, servers));
}*/ }*/
// Regression test. This endpoint was broken due to added checks in v8-cluster.cpp,
// which allowed certain calls only in cluster mode, but not in active failover.
testClusterHealth: function () {
console.warn({currentLead: getUrl(currentLead)});
const res = request.get({
url: getUrl(currentLead) + "/_admin/cluster/health",
auth: {
bearer: jwtRoot,
},
timeout: 30
});
console.warn(JSON.stringify(res));
console.warn(res.json);
expect(res).to.be.an.instanceof(request.Response);
// expect(res).to.be.have.property('statusCode', 200);
expect(res).to.have.property('json');
expect(res.json).to.include({error: false, code: 200});
expect(res.json).to.have.property('Health');
},
}; };
} }