You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2019/10/25 16:23:13 UTC
[couchdb] 01/01: Implement separate source and target replication
proxies
This is an automated email from the ASF dual-hosted git repository.
vatamane pushed a commit to branch source-and-target-replication-proxies
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 3e1690aef396db1b24f6083b29e44f50680af17d
Author: Nick Vatamaniuc <va...@apache.org>
AuthorDate: Fri Oct 25 12:18:03 2019 -0400
Implement separate source and target replication proxies
Previously if a proxy was specified it was used for both source and target
traffic. However, as mentioned in #2272, since both source and target now are
URLs, instead of one being a "local" database, it makes sense to allow separate
proxy settings for source and target endpoints.
We are still allowing old style, single proxy setting, however if users set
both the old style proxy and a per-endpoint one, an exception is raised about
the settings being mutually exclusive.
Fixes #2272
---
src/couch_replicator/src/couch_replicator_docs.erl | 25 +++++++++--
.../test/eunit/couch_replicator_proxy_tests.erl | 49 +++++++++++++++++++++-
2 files changed, 70 insertions(+), 4 deletions(-)
diff --git a/src/couch_replicator/src/couch_replicator_docs.erl b/src/couch_replicator/src/couch_replicator_docs.erl
index d097a16..6190632 100644
--- a/src/couch_replicator/src/couch_replicator_docs.erl
+++ b/src/couch_replicator/src/couch_replicator_docs.erl
@@ -241,15 +241,15 @@ parse_rep_doc(Doc, UserCtx) ->
-spec parse_rep_doc_without_id({[_]}, #user_ctx{}) -> {ok, #rep{}}.
parse_rep_doc_without_id({Props}, UserCtx) ->
- Proxy = get_value(<<"proxy">>, Props, <<>>),
+ {SrcProxy, TgtProxy} = parse_proxy_settings(Props),
Opts = make_options(Props),
case get_value(cancel, Opts, false) andalso
(get_value(id, Opts, nil) =/= nil) of
true ->
{ok, #rep{options = Opts, user_ctx = UserCtx}};
false ->
- Source = parse_rep_db(get_value(<<"source">>, Props), Proxy, Opts),
- Target = parse_rep_db(get_value(<<"target">>, Props), Proxy, Opts),
+ Source = parse_rep_db(get_value(<<"source">>, Props), SrcProxy, Opts),
+ Target = parse_rep_db(get_value(<<"target">>, Props), TgtProxy, Opts),
{Type, View} = case couch_replicator_filters:view_type(Props, Opts) of
{error, Error} ->
throw({bad_request, Error});
@@ -276,6 +276,25 @@ parse_rep_doc_without_id({Props}, UserCtx) ->
end.
+parse_proxy_settings(Props) when is_list(Props) ->
+ Proxy = get_value(<<"proxy">>, Props, <<>>),
+ SrcProxy = get_value(<<"source_proxy">>, Props, <<>>),
+ TgtProxy = get_value(<<"target_proxy">>, Props, <<>>),
+
+ case Proxy =/= <<>> of
+ true when SrcProxy =/= <<>> ->
+ Error = "`proxy` is mutually exclusive with `source_proxy`",
+ throw({bad_request, Error});
+ true when TgtProxy =/= <<>> ->
+ Error = "`proxy` is mutually exclusive with `target_proxy`",
+ throw({bad_request, Error});
+ true ->
+ {Proxy, Proxy};
+ false ->
+ {SrcProxy, TgtProxy}
+ end.
+
+
% Update a #rep{} record with a replication_id. Calculating the id might involve
% fetching a filter from the source db, and so it could fail intermetently.
% In case of a failure to fetch the filter this function will throw a
diff --git a/src/couch_replicator/test/eunit/couch_replicator_proxy_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_proxy_tests.erl
index 4f545bc..da46b8a 100644
--- a/src/couch_replicator/test/eunit/couch_replicator_proxy_tests.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_proxy_tests.erl
@@ -36,7 +36,10 @@ replicator_proxy_test_() ->
fun setup/0, fun teardown/1,
[
fun parse_rep_doc_without_proxy/1,
- fun parse_rep_doc_with_proxy/1
+ fun parse_rep_doc_with_proxy/1,
+ fun parse_rep_source_target_proxy/1,
+ fun mutually_exclusive_proxy_and_source_proxy/1,
+ fun mutually_exclusive_proxy_and_target_proxy/1
]
}
}
@@ -67,3 +70,47 @@ parse_rep_doc_with_proxy(_) ->
?assertEqual((Rep#rep.source)#httpdb.proxy_url, binary_to_list(ProxyURL)),
?assertEqual((Rep#rep.target)#httpdb.proxy_url, binary_to_list(ProxyURL))
end).
+
+
+parse_rep_source_target_proxy(_) ->
+ ?_test(begin
+ SrcProxyURL = <<"http://mysrcproxy.com">>,
+ TgtProxyURL = <<"http://mytgtproxy.com:9999">>,
+ ProxyDoc = {[
+ {<<"source">>, <<"http://unproxied.com">>},
+ {<<"target">>, <<"http://otherunproxied.com">>},
+ {<<"source_proxy">>, SrcProxyURL},
+ {<<"target_proxy">>, TgtProxyURL}
+ ]},
+ Rep = couch_replicator_docs:parse_rep_doc(ProxyDoc),
+ ?assertEqual((Rep#rep.source)#httpdb.proxy_url,
+ binary_to_list(SrcProxyURL)),
+ ?assertEqual((Rep#rep.target)#httpdb.proxy_url,
+ binary_to_list(TgtProxyURL))
+ end).
+
+
+mutually_exclusive_proxy_and_source_proxy(_) ->
+ ?_test(begin
+ ProxyDoc = {[
+ {<<"source">>, <<"http://unproxied.com">>},
+ {<<"target">>, <<"http://otherunproxied.com">>},
+ {<<"proxy">>, <<"oldstyleproxy.local">>},
+ {<<"source_proxy">>, <<"sourceproxy.local">>}
+ ]},
+ ?assertThrow({bad_rep_doc, _},
+ couch_replicator_docs:parse_rep_doc(ProxyDoc))
+ end).
+
+
+mutually_exclusive_proxy_and_target_proxy(_) ->
+ ?_test(begin
+ ProxyDoc = {[
+ {<<"source">>, <<"http://unproxied.com">>},
+ {<<"target">>, <<"http://otherunproxied.com">>},
+ {<<"proxy">>, <<"oldstyleproxy.local">>},
+ {<<"target_proxy">>, <<"targetproxy.local">>}
+ ]},
+ ?assertThrow({bad_rep_doc, _},
+ couch_replicator_docs:parse_rep_doc(ProxyDoc))
+ end).