Skip to content

Commit 2fddafd

Browse files
committed
MB-49271 [BP] Takeover via orchestrator using conn names < 200 chars
This is a backport of: MB-47866: Takeover via orchestrator using conn names < 200 chars Reviewed-on: http://review.couchbase.org/c/ns_server/+/159528 Change-Id: I616d3ef9bdb681ce683011e3d5313e51d5570f40 Reviewed-on: http://review.couchbase.org/c/ns_server/+/164898 Well-Formed: Restriction Checker Tested-by: Steve Watanabe <[email protected]> Tested-by: Build Bot <[email protected]> Reviewed-by: Abhijeeth Nuthan <[email protected]>
1 parent e82ca46 commit 2fddafd

File tree

2 files changed

+127
-14
lines changed

2 files changed

+127
-14
lines changed

src/dcp_replicator.erl

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
setup_replication/2, setup_replication/3,
3535
takeover/2, takeover/3,
3636
wait_for_data_move/3,
37+
trim_common_prefix/2,
3738
get_docs_estimate/3,
3839
get_connections/1]).
3940

@@ -235,13 +236,8 @@ get_connection_name(ConsumerNode, ProducerNode, Bucket) ->
235236
true ->
236237
CName;
237238
false ->
238-
%% Find the longest common prefix for the two nodes and chop
239-
%% it off (but not below a minimal length).
240-
LCP = binary:longest_common_prefix(
241-
[atom_to_binary(ConsumerNode, latin1),
242-
atom_to_binary(ProducerNode, latin1)]),
243-
CNode = maybe_cut_name(ConsumerNodeList, LCP),
244-
PNode = maybe_cut_name(ProducerNodeList, LCP),
239+
%% Trim off the common prefix to shorten the names.
240+
{CNode, PNode} = trim_common_prefix(ConsumerNode, ProducerNode),
245241

246242
Hash = binary_to_list(base64:encode(crypto:hash(sha, CName))),
247243
Bkt = string:slice(Bucket, 0, 60),
@@ -252,6 +248,16 @@ get_connection_name(ConsumerNode, ProducerNode, Bucket) ->
252248
CName2
253249
end.
254250

251+
trim_common_prefix(Consumer, Producer) ->
252+
%% Find the longest common prefix for the two nodes and chop
253+
%% it off (but not below a minimal length).
254+
LCP = binary:longest_common_prefix(
255+
[atom_to_binary(Consumer, latin1),
256+
atom_to_binary(Producer, latin1)]),
257+
Consumer1 = maybe_cut_name(atom_to_list(Consumer), LCP),
258+
Producer1 = maybe_cut_name(atom_to_list(Producer), LCP),
259+
{Consumer1, Producer1}.
260+
255261
%% Cut the specified number of bytes from the front of the name but don't
256262
%% shorten below a minimum length.
257263
maybe_cut_name(Name, MaxToChop) ->
@@ -380,5 +386,4 @@ get_connection_name_test() ->
380386
"AShortNodeName:travel-sample-with-a-very-very-very-very-"
381387
"long-bucket-name:A3aPD1Sik+5ZIz43M6NNTGn9XFw=", Conn56).
382388

383-
384389
-endif.

src/ns_single_vbucket_mover.erl

Lines changed: 114 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
-export([spawn_mover/5, mover/6]).
2020

2121
-include("ns_common.hrl").
22+
-ifdef(TEST).
23+
-include_lib("eunit/include/eunit.hrl").
24+
-endif.
2225

2326
spawn_mover(Bucket, VBucket, OldChain, NewChain, Quirks) ->
2427
Parent = self(),
@@ -416,18 +419,39 @@ dcp_takeover_via_orchestrator(Bucket, Parent,
416419
end).
417420

418421
start_takeover_replicator(NewMaster, OldMaster, Bucket, VBucket) ->
419-
ConnName = lists:concat(["replication:takeover:",
420-
binary_to_list(couch_uuids:random()), ":",
421-
atom_to_list(OldMaster), "->",
422-
atom_to_list(NewMaster), ":",
423-
Bucket, ":",
424-
integer_to_list(VBucket)]),
422+
ConnName = get_takeover_connection_name(NewMaster, OldMaster, Bucket,
423+
VBucket),
425424

426425
RepFeatures = dcp_sup:get_replication_features(),
427426
{ok, Pid} = dcp_replicator:start_link(undefined, NewMaster, OldMaster,
428427
Bucket, ConnName, RepFeatures),
429428
Pid.
430429

430+
get_takeover_connection_name(NewMaster, OldMaster, Bucket, VBucket) ->
431+
ConnName0 = lists:concat(["replication:takeover:",
432+
binary_to_list(couch_uuids:random()), ":",
433+
atom_to_list(OldMaster), "->",
434+
atom_to_list(NewMaster), ":",
435+
Bucket, ":",
436+
integer_to_list(VBucket)]),
437+
438+
case length(ConnName0) =< ?MAX_DCP_CONNECTION_NAME of
439+
true ->
440+
ConnName0;
441+
false ->
442+
{OldM, NewM} = dcp_replicator:trim_common_prefix(
443+
OldMaster, NewMaster),
444+
ConnName1 =
445+
lists:concat(["replication:takeover:",
446+
binary_to_list(couch_uuids:random()), ":",
447+
OldM, "->",
448+
NewM, ":",
449+
string:slice(Bucket, 0, 60), ":",
450+
integer_to_list(VBucket)]),
451+
true = length(ConnName1) =< ?MAX_DCP_CONNECTION_NAME,
452+
ConnName1
453+
end.
454+
431455
do_takeover(false, Pid, _Bucket, VBucket) ->
432456
do_takeover(Pid, VBucket);
433457
do_takeover(true, Pid, Bucket, VBucket) ->
@@ -582,3 +606,87 @@ update_vbucket_map(RebalancerPid, WorkerPid, Bucket, VBucket) ->
582606
[Bucket, VBucket, Error]),
583607
exit({failed_to_update_vbucket_map, Bucket, VBucket, Error})
584608
end.
609+
610+
-ifdef(TEST).
611+
get_takeover_connection_name_test() ->
612+
meck:new(couch_uuids, [passthrough]),
613+
meck:expect(couch_uuids, random,
614+
fun () -> <<"a5292f34ef9062cae8dc4a86e82ac3c8">> end),
615+
616+
%% Connection name fits into the maximum allowed
617+
618+
NodeA = 'nodeA.eng.couchbase.com',
619+
NodeB = 'nodeB.eng.couchbase.com',
620+
BucketAB = "bucket1",
621+
ConnAB = get_takeover_connection_name(NodeA, NodeB, BucketAB, 0),
622+
?assertEqual("replication:takeover:a5292f34ef9062cae8dc4a86e82ac3c8:"
623+
"nodeB.eng.couchbase.com->nodeA.eng.couchbase.com:bucket1:0",
624+
ConnAB),
625+
?assertEqual(true, length(ConnAB) =< ?MAX_DCP_CONNECTION_NAME),
626+
627+
%% Test where the connection name, using the pre-NEO method, won't
628+
%% fit into the maximum allowed.
629+
630+
Node1 = "[email protected]."
631+
"couchbase-new-pxxxxxxx.svc",
632+
Node2 = "[email protected]."
633+
"couchbase-new-pxxxxxxx.svc",
634+
Bucket12 = "com.yyyyyy.digital.ms.shoppingcart.shoppingcart.1234567890"
635+
"12345678901234567890",
636+
Conn12 = get_takeover_connection_name(list_to_atom(Node1),
637+
list_to_atom(Node2),
638+
Bucket12, 1023),
639+
?assertEqual("replication:takeover:a5292f34ef9062cae8dc4a86e82ac3c8:1."
640+
"platform-couchbase-cluster.couchb->0.platform-couchbase-"
641+
"cluster.couchb:com.yyyyyy.digital.ms.shoppingcart."
642+
"shoppingcart.123456789012:1023", Conn12),
643+
644+
%% Test that the node names aren't shortened too much (note the only
645+
%% difference is the last character).
646+
647+
Node3 = "ManyManyManyManyCommonCharacters_ns_1@platform-couchbase-cluster"
648+
"-0000",
649+
Node4 = "ManyManyManyManyCommonCharacters_ns_1@platform-couchbase-cluster"
650+
"-0001",
651+
LongBucket = "travel-sample-with-a-very-very-very-very-long-bucket-name",
652+
Conn34 = get_takeover_connection_name(list_to_atom(Node3),
653+
list_to_atom(Node4),
654+
LongBucket, 777),
655+
?assertEqual("replication:takeover:a5292f34ef9062cae8dc4a86e82ac3c8:"
656+
"s_1@platform-couchbase-cluster-0001->s_1@platform-couchbase-"
657+
"cluster-0000:travel-sample-with-a-very-very-very-very-"
658+
"long-bucket-name:777", Conn34),
659+
660+
%% Test with unique node names but one is much longer than the other.
661+
662+
Node5 = "AShortNodeName",
663+
Node6 = "ManyManyManyManyCommonCharacters_ns_1@platform-couchbase-cluster"
664+
"-AndEvenMoreCharactersToMakeThisNodeNameLongEnoughToRequireIt"
665+
"ToBeShortened",
666+
Conn56 = get_takeover_connection_name(list_to_atom(Node5),
667+
list_to_atom(Node6),
668+
LongBucket, 789),
669+
?assertEqual("replication:takeover:a5292f34ef9062cae8dc4a86e82ac3c8:"
670+
"ManyManyManyManyCommonCharacters_ns->AShortNodeName:"
671+
"travel-sample-with-a-very-very-very-very-long-bucket-name:"
672+
"789", Conn56),
673+
674+
%% Long node names with no common prefix.
675+
676+
Node7 = "ManyManyManyManyCommonCharacters_ns_1@platform-couchbase-cluster"
677+
"-AndEvenMoreCharactersToMakeThisNodeNameLongEnoughToRequireIt"
678+
"ToBeShortened",
679+
Node8 = "NoCommonPrefixManyCommonCharacters_ns_1@platform-couchbase-cluster"
680+
"-AndEvenMoreCharactersToMakeThisNodeNameLongEnoughToRequireIt"
681+
"ToBeShortened",
682+
Conn78 = get_takeover_connection_name(list_to_atom(Node7),
683+
list_to_atom(Node8),
684+
LongBucket, 222),
685+
?assertEqual("replication:takeover:a5292f34ef9062cae8dc4a86e82ac3c8:"
686+
"NoCommonPrefixManyCommonCharacters_->ManyManyManyMany"
687+
"CommonCharacters_ns:travel-sample-with-a-very-very-very-"
688+
"very-long-bucket-name:222", Conn78),
689+
690+
meck:unload(couch_uuids).
691+
692+
-endif.

0 commit comments

Comments
 (0)