27
27
#include " ApplicationFeatures/ApplicationServer.h"
28
28
#include " Aql/QueryCache.h"
29
29
#include " Basics/DownCast.h"
30
- #include " Basics/ReadLocker.h"
31
30
#include " Basics/StaticStrings.h"
32
31
#include " Basics/VelocyPackHelper.h"
33
32
#include " Basics/WriteLocker.h"
33
+ #include " Cluster/ClusterCollectionMethods.h"
34
34
#include " Cluster/ClusterFeature.h"
35
35
#include " Cluster/ClusterInfo.h"
36
36
#include " Cluster/ClusterMethods.h"
37
- #include " Cluster/ClusterCollectionMethods.h"
38
37
#include " Cluster/FollowerInfo.h"
39
38
#include " Cluster/ServerState.h"
40
39
#include " Logger/LogMacros.h"
57
56
#include " VocBase/Properties/UserInputCollectionProperties.h"
58
57
#include " VocBase/Validators.h"
59
58
#include " velocypack/Builder.h"
60
- #include " VocBase/Properties/UserInputCollectionProperties.h"
61
59
62
60
#ifdef USE_ENTERPRISE
63
61
#include " Enterprise/Sharding/ShardingStrategyEE.h"
@@ -366,6 +364,20 @@ size_t LogicalCollection::replicationFactor() const noexcept {
366
364
}
367
365
368
366
size_t LogicalCollection::writeConcern () const noexcept {
367
+ if (_groupId.has_value () && ServerState::instance ()->isDBServer ()) {
368
+ TRI_ASSERT (replicationVersion () == replication::Version::TWO)
369
+ << " Set a groupId although we are not in Replication Two" ;
370
+ auto & ci = vocbase ().server ().getFeature <ClusterFeature>().clusterInfo ();
371
+
372
+ auto const & group = ci.getCollectionGroupById (
373
+ replication2::agency::CollectionGroupId{_groupId.value ()});
374
+ if (group) {
375
+ return group->attributes .mutableAttributes .writeConcern ;
376
+ }
377
+ // If we cannot find a group this means the shard is dropped
378
+ // while we are still in this method. Let's just take the
379
+ // value at creation then.
380
+ }
369
381
TRI_ASSERT (_sharding != nullptr );
370
382
return _sharding->writeConcern ();
371
383
}
@@ -804,6 +816,16 @@ Result LogicalCollection::appendVPack(velocypack::Builder& build,
804
816
VPackValue (std::to_string (planId ().id ())));
805
817
}
806
818
819
+ std::shared_ptr<replication2::agency::CollectionGroupPlanSpecification const >
820
+ group;
821
+ if (_groupId.has_value ()) {
822
+ TRI_ASSERT (replicationVersion () == replication::Version::TWO)
823
+ << " Set a groupId although we are not in Replication Two" ;
824
+ auto & ci = vocbase ().server ().getFeature <ClusterFeature>().clusterInfo ();
825
+ group = ci.getCollectionGroupById (
826
+ replication2::agency::CollectionGroupId{_groupId.value ()});
827
+ }
828
+ bool isReplicationTWO = group != nullptr ;
807
829
#ifdef USE_ENTERPRISE
808
830
if (isSmart () && type () == TRI_COL_TYPE_EDGE &&
809
831
ServerState::instance ()->isRunningInCluster ()) {
@@ -816,25 +838,54 @@ Result LogicalCollection::appendVPack(velocypack::Builder& build,
816
838
}
817
839
edgeCollection->shardMapToVelocyPack (build);
818
840
bool includeShardsEntry = false ;
819
- _sharding->toVelocyPack (build, ctx != Serialization::List,
841
+ _sharding->toVelocyPack (build, isReplicationTWO, ctx != Serialization::List,
820
842
includeShardsEntry);
821
843
} else {
822
- _sharding->toVelocyPack (build, ctx != Serialization::List);
844
+ _sharding->toVelocyPack (build, isReplicationTWO,
845
+ ctx != Serialization::List);
823
846
}
824
847
#else
825
- _sharding->toVelocyPack (build, ctx != Serialization::List);
848
+ _sharding->toVelocyPack (build, isReplicationTWO, ctx != Serialization::List);
826
849
#endif
827
-
828
- includeVelocyPackEnterprise (build);
829
- TRI_ASSERT (build.isOpenObject ());
830
-
831
- if (replicationVersion () == replication::Version::TWO &&
832
- _groupId.has_value ()) {
850
+ if (group) {
833
851
build.add (" groupId" , VPackValue (_groupId.value ()));
834
852
if (_replicatedStateId) {
835
853
build.add (" replicatedStateId" , VPackValue (*_replicatedStateId));
836
854
}
855
+ // For replication1 the _sharding is responsible.
856
+ // For TWO the group contains those attributes
857
+
858
+ // Future TODO: It would be nice if we could use a "serializeInPlace"
859
+ // method Which does serialization but not the open/close object.
860
+ TRI_ASSERT (!build.hasKey (StaticStrings::ReplicationFactor))
861
+ << " replicationFactor already serialized from _sharding" ;
862
+ TRI_ASSERT (!build.hasKey (StaticStrings::WriteConcern))
863
+ << " writeConcern already serialized from _sharding" ;
864
+ TRI_ASSERT (!build.hasKey (StaticStrings::MinReplicationFactor))
865
+ << " minReplicationFactor already serialized from _sharding" ;
866
+ if (group->attributes .mutableAttributes .replicationFactor == 0 ) {
867
+ build.add (StaticStrings::ReplicationFactor,
868
+ VPackValue (StaticStrings::Satellite));
869
+ // For Backwards Compatibility, WriteConcern should return 0 here for
870
+ // satellites
871
+ build.add (StaticStrings::WriteConcern, VPackValue (0 ));
872
+ // minReplicationFactor deprecated in 3.6
873
+ build.add (StaticStrings::MinReplicationFactor, VPackValue (0 ));
874
+
875
+ } else {
876
+ build.add (
877
+ StaticStrings::ReplicationFactor,
878
+ VPackValue (group->attributes .mutableAttributes .replicationFactor ));
879
+ build.add (StaticStrings::WriteConcern,
880
+ VPackValue (group->attributes .mutableAttributes .writeConcern ));
881
+ // minReplicationFactor deprecated in 3.6
882
+ build.add (StaticStrings::MinReplicationFactor,
883
+ VPackValue (group->attributes .mutableAttributes .writeConcern ));
884
+ }
837
885
}
886
+
887
+ includeVelocyPackEnterprise (build);
888
+ TRI_ASSERT (build.isOpenObject ());
838
889
// We leave the object open
839
890
return {};
840
891
}
@@ -904,7 +955,7 @@ Result LogicalCollection::properties(velocypack::Slice slice) {
904
955
}
905
956
906
957
size_t replicationFactor = _sharding->replicationFactor ();
907
- size_t writeConcern = _sharding ->writeConcern ();
958
+ size_t writeConcern = this ->writeConcern ();
908
959
VPackSlice replicationFactorSlice =
909
960
slice.get (StaticStrings::ReplicationFactor);
910
961
@@ -1004,7 +1055,7 @@ Result LogicalCollection::properties(velocypack::Slice slice) {
1004
1055
if ((ServerState::instance ()->isCoordinator () ||
1005
1056
(ServerState::instance ()->isSingleServer () &&
1006
1057
(isSatellite () || isSmart ()))) &&
1007
- writeConcern != _sharding ->writeConcern ()) { // check if changed
1058
+ writeConcern != this ->writeConcern ()) { // check if changed
1008
1059
if (!_sharding->distributeShardsLike ().empty ()) {
1009
1060
CollectionNameResolver resolver (vocbase ());
1010
1061
std::string name = resolver.getCollectionNameCluster (DataSourceId{
0 commit comments