Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
  • 4 commits
  • 31 files changed
  • 0 commit comments
  • 1 contributor
Showing with 486 additions and 293 deletions.
  1. +1 −0  .gitignore
  2. +1 −0  configure.ac
  3. +1 −2  etc/couchdb/default.ini.tpl.in
  4. +3 −0  license.skip
  5. +1 −0  src/Makefile.am
  6. +75 −0 src/couch_replicator/Makefile.am
  7. +18 −0 src/{couchdb/couch_api_wrap.hrl → couch_replicator/include/couch_replicator.hrl}
  8. +37 −0 src/couch_replicator/src/couch_replicator.app.src
  9. +38 −38 src/{couchdb → couch_replicator/src}/couch_replicator.erl
  10. +5 −5 src/{couchdb/couch_api_wrap.erl → couch_replicator/src/couch_replicator_api.erl}
  11. +34 −0 src/couch_replicator/src/couch_replicator_app.erl
  12. +5 −5 src/{couchdb/couch_api_wrap_httpc.erl → couch_replicator/src/couch_replicator_httpc.erl}
  13. +1 −1  src/{couchdb/couch_httpc_pool.erl → couch_replicator/src/couch_replicator_httpc_pool.erl}
  14. +1 −1  src/{couchdb/couch_httpd_replicator.erl → couch_replicator/src/couch_replicator_httpd.erl}
  15. +151 −0 src/couch_replicator/src/couch_replicator_js_functions.hrl
  16. +3 −3 src/{couchdb/couch_replication_manager.erl → couch_replicator/src/couch_replicator_manager.erl}
  17. +2 −2 src/{couchdb/couch_replication_notifier.erl → couch_replicator/src/couch_replicator_notifier.erl}
  18. +42 −0 src/couch_replicator/src/couch_replicator_sup.erl
  19. +1 −1  src/{couchdb/couch_rep_sup.erl → couch_replicator/src/couch_replicator_tasks_sup.erl}
  20. +6 −7 src/{couchdb → couch_replicator/src}/couch_replicator_utils.erl
  21. +10 −11 src/{couchdb → couch_replicator/src}/couch_replicator_worker.erl
  22. +40 −0 src/couch_replicator/test/01-load.t
  23. +4 −4 test/etap/230-httpc-pool.t → src/couch_replicator/test/02-httpc-pool.t
  24. 0  test/etap/240-replication-compact.t → src/couch_replicator/test/03-replication-compact.t
  25. 0  test/etap/241-replication-large-atts.t → src/couch_replicator/test/04-replication-large-atts.t
  26. +3 −23 src/couchdb/Makefile.am
  27. +0 −1  src/couchdb/couch.app.tpl.in
  28. +0 −141 src/couchdb/couch_js_functions.hrl
  29. +3 −9 src/couchdb/couch_primary_sup.erl
  30. +0 −30 src/couchdb/couch_replicator.hrl
  31. +0 −9 test/etap/001-load.t
View
1  .gitignore
@@ -52,6 +52,7 @@ etc/couchdb/default.ini
etc/launchd/org.apache.couchdb.plist
etc/logrotate.d/couchdb
src/couch_mrview/ebin/
+src/couch_replicator/ebin/
src/couchdb/.libs/*
src/couchdb/couch.app
src/couchdb/couchjs
View
1  configure.ac
@@ -549,6 +549,7 @@ AC_CONFIG_FILES([share/Makefile])
AC_CONFIG_FILES([src/Makefile])
AC_CONFIG_FILES([src/couch_index/Makefile])
AC_CONFIG_FILES([src/couch_mrview/Makefile])
+AC_CONFIG_FILES([src/couch_replicator/Makefile])
AC_CONFIG_FILES([src/couchdb/couch.app.tpl])
AC_CONFIG_FILES([src/couchdb/Makefile])
AC_CONFIG_FILES([src/couchdb/priv/Makefile])
View
3  etc/couchdb/default.ini.tpl.in
@@ -87,7 +87,6 @@ stats_aggregator={couch_stats_aggregator, start, []}
stats_collector={couch_stats_collector, start, []}
uuids={couch_uuids, start, []}
auth_cache={couch_auth_cache, start_link, []}
-replication_manager={couch_replication_manager, start_link, []}
os_daemons={couch_os_daemons, start_link, []}
compaction_daemon={couch_compaction_daemon, start_link, []}
@@ -99,7 +98,7 @@ _utils = {couch_httpd_misc_handlers, handle_utils_dir_req, "%localdatadir%/www"}
_all_dbs = {couch_httpd_misc_handlers, handle_all_dbs_req}
_active_tasks = {couch_httpd_misc_handlers, handle_task_status_req}
_config = {couch_httpd_misc_handlers, handle_config_req}
-_replicate = {couch_httpd_replicator, handle_req}
+_replicate = {couch_replicator_httpd, handle_req}
_uuids = {couch_httpd_misc_handlers, handle_uuids_req}
_restart = {couch_httpd_misc_handlers, handle_restart_req}
_stats = {couch_httpd_stats_handlers, handle_stats_req}
View
3  license.skip
@@ -76,6 +76,9 @@
^src/couch_mrview/Makefile
^src/couch_mrview/Makefile.in
^src/couch_mrview/ebin/.*beam
+^src/couch_replicator/Makefile
+^src/couch_replicator/Makefile.in
+^src/couch_replicator/ebin/.*beam
^src/couchdb/.*beam
^src/couchdb/.deps/*
^src/couchdb/Makefile
View
1  src/Makefile.am
@@ -13,6 +13,7 @@
SUBDIRS = \
couch_index \
couch_mrview \
+ couch_replicator \
couchdb \
ejson \
erlang-oauth \
View
75 src/couch_replicator/Makefile.am
@@ -0,0 +1,75 @@
+## Licensed under the Apache License, Version 2.0 (the "License"); you may not
+## use this file except in compliance with the License. You may obtain a copy of
+## the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+## License for the specific language governing permissions and limitations under
+## the License.
+
+couch_replicatorlibdir = $(localerlanglibdir)/couch_replicator-0.1
+couch_replicatorincludedir = $(couch_replicatorlibdir)/include
+couch_replicatorebindir = $(couch_replicatorlibdir)/ebin
+
+couch_replicatorinclude_DATA = $(include_files)
+couch_replicatorebin_DATA = $(compiled_files)
+
+include_files = \
+ include/couch_replicator.hrl \
+ src/couch_replicator_js_functions.hrl
+
+source_files = \
+ src/couch_replicator_app.src \
+ src/couch_replicator.erl \
+ src/couch_replicator_api.erl \
+ src/couch_replicator_app.erl \
+ src/couch_replicator_httpc_pool.erl \
+ src/couch_replicator_httpc.erl \
+ src/couch_replicator_httpd.erl \
+ src/couch_replicator_manager.erl \
+ src/couch_replicator_notifier.erl \
+ src/couch_replicator_sup.erl \
+ src/couch_replicator_tasks_sup.erl \
+ src/couch_replicator_utils.erl \
+ src/couch_replicator_worker.erl
+
+test_files = \
+ test/001-httpc-pool.t \
+ test/002-replication-compact.t \
+ test/003-replication-large-atts.t
+
+compiled_files = \
+ ebin/couch_replicator.app \
+ ebin/couch_replicator.beam \
+ ebin/couch_replicator_api.beam \
+ ebin/couch_replicator_app.beam \
+ ebin/couch_replicator_httpc_pool.beam \
+ ebin/couch_replicator_httpc.beam \
+ ebin/couch_replicator_httpd.beam \
+ ebin/couch_replicator_manager.beam \
+ ebin/couch_replicator_notifier.beam \
+ ebin/couch_replicator_sup.beam \
+ ebin/couch_replicator_tasks_sup.beam \
+ ebin/couch_replicator_utils.beam \
+ ebin/couch_replicator_worker.beam
+
+EXTRA_DIST = $(include_files) $(source_files) $(test_files)
+CLEANFILES = $(compiled_files)
+
+check:
+ $(abs_top_builddir)/test/etap/run $(abs_top_srcdir)/src/couch_replicator/test
+
+ebin/%.app: src/%.app.src
+ @mkdir -p ebin/
+ sed -e "s|%version%|@version@|g" \
+ < $< > $@
+
+ebin/%.beam: src/%.erl $(include_files)
+ @mkdir -p ebin/
+ $(ERLC) -Wall -I$(top_srcdir)/src -I$(top_srcdir)/src/couchdb \
+ -o ebin/ $(ERLC_FLAGS) ${TEST} $<;
+
+
View
18 src/couchdb/couch_api_wrap.hrl → ...h_replicator/include/couch_replicator.hrl
@@ -10,6 +10,24 @@
% License for the specific language governing permissions and limitations under
% the License.
+-define(REP_ID_VERSION, 2).
+
+-record(rep, {
+ id,
+ source,
+ target,
+ options,
+ user_ctx,
+ doc_id
+}).
+
+-record(rep_stats, {
+ missing_checked = 0,
+ missing_found = 0,
+ docs_read = 0,
+ docs_written = 0,
+ doc_write_failures = 0
+}).
-record(httpdb, {
View
37 src/couch_replicator/src/couch_replicator.app.src
@@ -0,0 +1,37 @@
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
+{application, couch_replicator, [
+ {description, "CouchDB replicator"},
+ {vsn, "%version%"},
+ {modules, [
+ couch_replicator,
+ couch_replicator_api,
+ couch_replicator_app,
+ couch_replicator_httpc_pool,
+ couch_replicator_httpc,
+ couch_replicator_httpd,
+ couch_replicator_manager,
+ couch_replicator_notifier,
+ couch_replicator_sup,
+ couch_replicator_tasks_sup,
+ couch_replicator_utils,
+ couch_replicator_worker
+ ]},
+ {registered, [
+ couch_replication_manager,
+ couch_replicator_tasks_sup
+ ]},
+ {applications, [kernel, stdlib]},
+ {env, []},
+ {mod, {couch_replicator_app, []}}
+]}.
View
76 src/couchdb/couch_replicator.erl → ...couch_replicator/src/couch_replicator.erl
@@ -25,8 +25,8 @@
-export([handle_call/3, handle_cast/2, handle_info/2]).
-include("couch_db.hrl").
--include("couch_api_wrap.hrl").
--include("couch_replicator.hrl").
+-include_lib("couch_replicator/include/couch_replicator.hrl").
+
-import(couch_util, [
get_value/2,
@@ -84,7 +84,7 @@ replicate(#rep{id = RepId, options = Options, user_ctx = UserCtx} = Rep) ->
false ->
{ok, Listener} = rep_result_listener(RepId),
Result = do_replication_loop(Rep),
- couch_replication_notifier:stop(Listener),
+ couch_replicator_notifier:stop(Listener),
Result
end.
@@ -105,8 +105,8 @@ do_replication_loop(#rep{id = {BaseId, Ext} = Id, options = Options} = Rep) ->
async_replicate(#rep{id = {BaseId, Ext}, source = Src, target = Tgt} = Rep) ->
RepChildId = BaseId ++ Ext,
- Source = couch_api_wrap:db_uri(Src),
- Target = couch_api_wrap:db_uri(Tgt),
+ Source = couch_replicator_api:db_uri(Src),
+ Target = couch_replicator_api:db_uri(Tgt),
Timeout = get_value(connection_timeout, Rep#rep.options),
ChildSpec = {
RepChildId,
@@ -122,13 +122,13 @@ async_replicate(#rep{id = {BaseId, Ext}, source = Src, target = Tgt} = Rep) ->
%
% http://erlang.2086793.n4.nabble.com/PATCH-supervisor-atomically-delete-child-spec-when-child-terminates-td3226098.html
%
- case supervisor:start_child(couch_rep_sup, ChildSpec) of
+ case supervisor:start_child(couch_replicator_tasks_sup, ChildSpec) of
{ok, Pid} ->
?LOG_INFO("starting new replication `~s` at ~p (`~s` -> `~s`)",
[RepChildId, Pid, Source, Target]),
{ok, Pid};
{error, already_present} ->
- case supervisor:restart_child(couch_rep_sup, RepChildId) of
+ case supervisor:restart_child(couch_replicator_tasks_sup, RepChildId) of
{ok, Pid} ->
?LOG_INFO("restarting replication `~s` at ~p (`~s` -> `~s`)",
[RepChildId, Pid, Source, Target]),
@@ -138,7 +138,7 @@ async_replicate(#rep{id = {BaseId, Ext}, source = Src, target = Tgt} = Rep) ->
%% each other to start and somebody else won. Just grab
%% the Pid by calling start_child again.
{error, {already_started, Pid}} =
- supervisor:start_child(couch_rep_sup, ChildSpec),
+ supervisor:start_child(couch_replicator_tasks_sup, ChildSpec),
?LOG_INFO("replication `~s` already running at ~p (`~s` -> `~s`)",
[RepChildId, Pid, Source, Target]),
{ok, Pid};
@@ -147,7 +147,7 @@ async_replicate(#rep{id = {BaseId, Ext}, source = Src, target = Tgt} = Rep) ->
% Clause to deal with a change in the supervisor module introduced
% in R14B02. For more details consult the thread at:
% http://erlang.org/pipermail/erlang-bugs/2011-March/002273.html
- _ = supervisor:delete_child(couch_rep_sup, RepChildId),
+ _ = supervisor:delete_child(couch_replicator_tasks_sup, RepChildId),
async_replicate(Rep);
{error, _} = Error ->
Error
@@ -163,7 +163,7 @@ async_replicate(#rep{id = {BaseId, Ext}, source = Src, target = Tgt} = Rep) ->
rep_result_listener(RepId) ->
ReplyTo = self(),
- {ok, _Listener} = couch_replication_notifier:start_link(
+ {ok, _Listener} = couch_replicator_notifier:start_link(
fun({_, RepId2, _} = Ev) when RepId2 =:= RepId ->
ReplyTo ! Ev;
(_) ->
@@ -183,10 +183,10 @@ wait_for_result(RepId) ->
cancel_replication({BaseId, Extension}) ->
FullRepId = BaseId ++ Extension,
?LOG_INFO("Canceling replication `~s`...", [FullRepId]),
- case supervisor:terminate_child(couch_rep_sup, FullRepId) of
+ case supervisor:terminate_child(couch_replicator_tasks_sup, FullRepId) of
ok ->
?LOG_INFO("Replication `~s` canceled.", [FullRepId]),
- case supervisor:delete_child(couch_rep_sup, FullRepId) of
+ case supervisor:delete_child(couch_replicator_tasks_sup, FullRepId) of
ok ->
{ok, {cancelled, ?l2b(FullRepId)}};
{error, not_found} ->
@@ -206,7 +206,7 @@ cancel_replication(RepId, #user_ctx{name = Name, roles = Roles}) ->
false ->
{BaseId, Ext} = RepId,
case lists:keysearch(
- BaseId ++ Ext, 1, supervisor:which_children(couch_rep_sup)) of
+ BaseId ++ Ext, 1, supervisor:which_children(couch_replicator_tasks_sup)) of
{value, {_, Pid, _, _}} when is_pid(Pid) ->
case (catch gen_server:call(Pid, get_details, infinity)) of
{ok, #rep{user_ctx = #user_ctx{name = Name}}} ->
@@ -321,7 +321,7 @@ do_init(#rep{options = Options, id = {BaseId, Ext}} = Rep) ->
?LOG_DEBUG("Worker pids are: ~p", [Workers]),
- couch_replication_manager:replication_started(Rep),
+ couch_replicator_manager:replication_started(Rep),
{ok, State#rep_state{
changes_queue = ChangesQueue,
@@ -458,12 +458,12 @@ code_change(_OldVsn, State, _Extra) ->
terminate(normal, #rep_state{rep_details = #rep{id = RepId} = Rep,
checkpoint_history = CheckpointHistory} = State) ->
terminate_cleanup(State),
- couch_replication_notifier:notify({finished, RepId, CheckpointHistory}),
- couch_replication_manager:replication_completed(Rep);
+ couch_replicator_notifier:notify({finished, RepId, CheckpointHistory}),
+ couch_replicator_manager:replication_completed(Rep);
terminate(shutdown, #rep_state{rep_details = #rep{id = RepId}} = State) ->
% cancelled replication throught ?MODULE:cancel_replication/1
- couch_replication_notifier:notify({error, RepId, <<"cancelled">>}),
+ couch_replicator_notifier:notify({error, RepId, <<"cancelled">>}),
terminate_cleanup(State);
terminate(Reason, State) ->
@@ -475,16 +475,16 @@ terminate(Reason, State) ->
?LOG_ERROR("Replication `~s` (`~s` -> `~s`) failed: ~s",
[BaseId ++ Ext, Source, Target, to_binary(Reason)]),
terminate_cleanup(State),
- couch_replication_notifier:notify({error, RepId, Reason}),
- couch_replication_manager:replication_error(Rep, Reason).
+ couch_replicator_notifier:notify({error, RepId, Reason}),
+ couch_replicator_manager:replication_error(Rep, Reason).
terminate_cleanup(State) ->
update_task(State),
stop_db_compaction_notifier(State#rep_state.source_db_compaction_notifier),
stop_db_compaction_notifier(State#rep_state.target_db_compaction_notifier),
- couch_api_wrap:db_close(State#rep_state.source),
- couch_api_wrap:db_close(State#rep_state.target).
+ couch_replicator_api:db_close(State#rep_state.source),
+ couch_replicator_api:db_close(State#rep_state.target).
do_last_checkpoint(#rep_state{seqs_in_progress = [],
@@ -523,12 +523,12 @@ init_state(Rep) ->
source = Src, target = Tgt,
options = Options, user_ctx = UserCtx
} = Rep,
- {ok, Source} = couch_api_wrap:db_open(Src, [{user_ctx, UserCtx}]),
- {ok, Target} = couch_api_wrap:db_open(Tgt, [{user_ctx, UserCtx}],
+ {ok, Source} = couch_replicator_api:db_open(Src, [{user_ctx, UserCtx}]),
+ {ok, Target} = couch_replicator_api:db_open(Tgt, [{user_ctx, UserCtx}],
get_value(create_target, Options, false)),
- {ok, SourceInfo} = couch_api_wrap:get_db_info(Source),
- {ok, TargetInfo} = couch_api_wrap:get_db_info(Target),
+ {ok, SourceInfo} = couch_replicator_api:get_db_info(Source),
+ {ok, TargetInfo} = couch_replicator_api:get_db_info(Target),
[SourceLog, TargetLog] = find_replication_logs([Source, Target], Rep),
@@ -538,8 +538,8 @@ init_state(Rep) ->
#doc{body={CheckpointHistory}} = SourceLog,
State = #rep_state{
rep_details = Rep,
- source_name = couch_api_wrap:db_uri(Source),
- target_name = couch_api_wrap:db_uri(Target),
+ source_name = couch_replicator_api:db_uri(Source),
+ target_name = couch_replicator_api:db_uri(Target),
source = Source,
target = Target,
history = History,
@@ -573,7 +573,7 @@ fold_replication_logs([], _Vsn, _LogId, _NewId, _Rep, Acc) ->
lists:reverse(Acc);
fold_replication_logs([Db | Rest] = Dbs, Vsn, LogId, NewId, Rep, Acc) ->
- case couch_api_wrap:open_doc(Db, LogId, [ejson_body]) of
+ case couch_replicator_api:open_doc(Db, LogId, [ejson_body]) of
{error, <<"not_found">>} when Vsn > 1 ->
OldRepId = couch_replicator_utils:replication_id(Rep, Vsn - 1),
fold_replication_logs(Dbs, Vsn - 1,
@@ -604,7 +604,7 @@ spawn_changes_reader(StartSeq, Db, ChangesQueue, Options) ->
read_changes(StartSeq, Db, ChangesQueue, Options) ->
try
- couch_api_wrap:changes_since(Db, all_docs, StartSeq,
+ couch_replicator_api:changes_since(Db, all_docs, StartSeq,
fun(#doc_info{high_seq = Seq, id = Id} = DocInfo) ->
case Id of
<<>> ->
@@ -613,7 +613,7 @@ read_changes(StartSeq, Db, ChangesQueue, Options) ->
% is impossible to GET.
?LOG_ERROR("Replicator: ignoring document with empty ID in "
"source database `~s` (_changes sequence ~p)",
- [couch_api_wrap:db_uri(Db), Seq]);
+ [couch_replicator_api:db_uri(Db), Seq]);
_ ->
ok = couch_work_queue:queue(ChangesQueue, DocInfo)
end,
@@ -629,12 +629,12 @@ read_changes(StartSeq, Db, ChangesQueue, Options) ->
StartSeq ->
?LOG_INFO("Retrying _changes request to source database ~s"
" with since=~p in ~p seconds",
- [couch_api_wrap:db_uri(Db), LastSeq, Db#httpdb.wait / 1000]),
+ [couch_replicator_api:db_uri(Db), LastSeq, Db#httpdb.wait / 1000]),
ok = timer:sleep(Db#httpdb.wait),
Db#httpdb{wait = 2 * Db#httpdb.wait};
_ ->
?LOG_INFO("Retrying _changes request to source database ~s"
- " with since=~p", [couch_api_wrap:db_uri(Db), LastSeq]),
+ " with since=~p", [couch_replicator_api:db_uri(Db), LastSeq]),
Db
end,
read_changes(LastSeq, Db2, ChangesQueue, Options);
@@ -782,14 +782,14 @@ update_checkpoint(Db, Doc, DbType) ->
update_checkpoint(Db, #doc{id = LogId, body = LogBody} = Doc) ->
try
- case couch_api_wrap:update_doc(Db, Doc, [delay_commit]) of
+ case couch_replicator_api:update_doc(Db, Doc, [delay_commit]) of
{ok, PosRevId} ->
PosRevId;
{error, Reason} ->
throw({checkpoint_commit_failure, Reason})
end
catch throw:conflict ->
- case (catch couch_api_wrap:open_doc(Db, LogId, [ejson_body])) of
+ case (catch couch_replicator_api:open_doc(Db, LogId, [ejson_body])) of
{ok, #doc{body = LogBody, revs = {Pos, [RevId | _]}}} ->
% This means that we were able to update successfully the
% checkpoint doc in a previous attempt but we got a connection
@@ -810,12 +810,12 @@ commit_to_both(Source, Target) ->
ParentPid = self(),
SrcCommitPid = spawn_link(
fun() ->
- Result = (catch couch_api_wrap:ensure_full_commit(Source)),
+ Result = (catch couch_replicator_api:ensure_full_commit(Source)),
ParentPid ! {self(), Result}
end),
% commit tgt sync
- TargetResult = (catch couch_api_wrap:ensure_full_commit(Target)),
+ TargetResult = (catch couch_replicator_api:ensure_full_commit(Target)),
SourceResult = receive
{SrcCommitPid, Result} ->
@@ -902,14 +902,14 @@ db_monitor(_HttpDb) ->
source_cur_seq(#rep_state{source = #httpdb{} = Db, source_seq = Seq}) ->
- case (catch couch_api_wrap:get_db_info(Db#httpdb{retries = 3})) of
+ case (catch couch_replicator_api:get_db_info(Db#httpdb{retries = 3})) of
{ok, Info} ->
get_value(<<"update_seq">>, Info, Seq);
_ ->
Seq
end;
source_cur_seq(#rep_state{source = Db, source_seq = Seq}) ->
- {ok, Info} = couch_api_wrap:get_db_info(Db),
+ {ok, Info} = couch_replicator_api:get_db_info(Db),
get_value(<<"update_seq">>, Info, Seq).
View
10 src/couchdb/couch_api_wrap.erl → ...h_replicator/src/couch_replicator_api.erl
@@ -10,7 +10,7 @@
% License for the specific language governing permissions and limitations under
% the License.
--module(couch_api_wrap).
+-module(couch_replicator_api).
% This module wraps the native erlang API, and allows for performing
% operations on a remote vs. local databases via the same API.
@@ -19,7 +19,7 @@
% Many options and apis aren't yet supported here, they are added as needed.
-include("couch_db.hrl").
--include("couch_api_wrap.hrl").
+-include_lib("couch_replicator/include/couch_replicator.hrl").
-export([
db_open/2,
@@ -63,7 +63,7 @@ db_open(Db, Options) ->
db_open(Db, Options, false).
db_open(#httpdb{} = Db1, _Options, Create) ->
- {ok, Db} = couch_api_wrap_httpc:setup(Db1),
+ {ok, Db} = couch_replicator_httpc:setup(Db1),
case Create of
false ->
ok;
@@ -101,7 +101,7 @@ db_open(DbName, Options, Create) ->
db_close(#httpdb{httpc_pool = Pool}) ->
unlink(Pool),
- ok = couch_httpc_pool:stop(Pool);
+ ok = couch_replicator_httpc_pool:stop(Pool);
db_close(DbName) ->
catch couch_db:close(DbName).
@@ -440,7 +440,7 @@ options_to_query_args(HttpDb, Path, Options) ->
options_to_query_args(Options2, []);
{value, {atts_since, PAs}, Options2} ->
QueryArgs1 = options_to_query_args(Options2, []),
- FullUrl = couch_api_wrap_httpc:full_url(
+ FullUrl = couch_replicator_httpc:full_url(
HttpDb, [{path, Path}, {qs, QueryArgs1}]),
RevList = atts_since_arg(
length("GET " ++ FullUrl ++ " HTTP/1.1\r\n") +
View
34 src/couch_replicator/src/couch_replicator_app.erl
@@ -0,0 +1,34 @@
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
+-module(couch_replicator_app).
+
+-behaviour(application).
+
+-export([start/2, stop/1]).
+
+%%--------------------------------------------------------------------
+%% Func: start/2
+%% Returns: {ok, Pid} |
+%% {ok, Pid, State} |
+%% {error, Reason}
+%%--------------------------------------------------------------------
+start(_Type, _StartArgs) ->
+ couch_replicator_sup:start_link().
+
+%%--------------------------------------------------------------------
+%% Func: stop/1
+%% Returns: any
+%%--------------------------------------------------------------------
+stop(_State) ->
+ ok.
+
View
10 src/couchdb/couch_api_wrap_httpc.erl → ...replicator/src/couch_replicator_httpc.erl
@@ -10,11 +10,11 @@
% License for the specific language governing permissions and limitations under
% the License.
--module(couch_api_wrap_httpc).
+-module(couch_replicator_httpc).
-include("couch_db.hrl").
--include("couch_api_wrap.hrl").
-include("../ibrowse/ibrowse.hrl").
+-include_lib("couch_replicator/include/couch_replicator.hrl").
-export([setup/1]).
-export([send_req/3]).
@@ -30,7 +30,7 @@
setup(#httpdb{httpc_pool = nil, url = Url, http_connections = MaxConns} = Db) ->
- {ok, Pid} = couch_httpc_pool:start_link(Url, [{max_connections, MaxConns}]),
+ {ok, Pid} = couch_replicator_httpc_pool:start_link(Url, [{max_connections, MaxConns}]),
{ok, Db#httpdb{httpc_pool = Pid}}.
@@ -54,7 +54,7 @@ send_ibrowse_req(#httpdb{headers = BaseHeaders} = HttpDb, Params) ->
"_changes" ->
{ok, Worker} = ibrowse:spawn_link_worker_process(Url);
_ ->
- {ok, Worker} = couch_httpc_pool:get_worker(HttpDb#httpdb.httpc_pool)
+ {ok, Worker} = couch_replicator_httpc_pool:get_worker(HttpDb#httpdb.httpc_pool)
end,
IbrowseOptions = [
{response_format, binary}, {inactivity_timeout, HttpDb#httpdb.timeout} |
@@ -143,7 +143,7 @@ clean_mailbox_req(ReqId) ->
release_worker(Worker, #httpdb{httpc_pool = Pool}) ->
- ok = couch_httpc_pool:release_worker(Pool, Worker).
+ ok = couch_replicator_httpc_pool:release_worker(Pool, Worker).
maybe_retry(Error, Worker, #httpdb{retries = 0} = HttpDb, Params, _Cb) ->
View
2  src/couchdb/couch_httpc_pool.erl → ...cator/src/couch_replicator_httpc_pool.erl
@@ -10,7 +10,7 @@
% License for the specific language governing permissions and limitations under
% the License.
--module(couch_httpc_pool).
+-module(couch_replicator_httpc_pool).
-behaviour(gen_server).
% public API
View
2  src/couchdb/couch_httpd_replicator.erl → ...replicator/src/couch_replicator_httpd.erl
@@ -10,7 +10,7 @@
% License for the specific language governing permissions and limitations under
% the License.
--module(couch_httpd_replicator).
+-module(couch_replicator_httpd).
-include("couch_db.hrl").
View
151 src/couch_replicator/src/couch_replicator_js_functions.hrl
@@ -0,0 +1,151 @@
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
+-define(REP_DB_DOC_VALIDATE_FUN, <<"
+ function(newDoc, oldDoc, userCtx) {
+ function reportError(error_msg) {
+ log('Error writing document `' + newDoc._id +
+ '\\' to the replicator database: ' + error_msg);
+ throw({forbidden: error_msg});
+ }
+
+ function validateEndpoint(endpoint, fieldName) {
+ if ((typeof endpoint !== 'string') &&
+ ((typeof endpoint !== 'object') || (endpoint === null))) {
+
+ reportError('The `' + fieldName + '\\' property must exist' +
+ ' and be either a string or an object.');
+ }
+
+ if (typeof endpoint === 'object') {
+ if ((typeof endpoint.url !== 'string') || !endpoint.url) {
+ reportError('The url property must exist in the `' +
+ fieldName + '\\' field and must be a non-empty string.');
+ }
+
+ if ((typeof endpoint.auth !== 'undefined') &&
+ ((typeof endpoint.auth !== 'object') ||
+ endpoint.auth === null)) {
+
+ reportError('`' + fieldName +
+ '.auth\\' must be a non-null object.');
+ }
+
+ if ((typeof endpoint.headers !== 'undefined') &&
+ ((typeof endpoint.headers !== 'object') ||
+ endpoint.headers === null)) {
+
+ reportError('`' + fieldName +
+ '.headers\\' must be a non-null object.');
+ }
+ }
+ }
+
+ var isReplicator = (userCtx.roles.indexOf('_replicator') >= 0);
+ var isAdmin = (userCtx.roles.indexOf('_admin') >= 0);
+
+ if (oldDoc && !newDoc._deleted && !isReplicator &&
+ (oldDoc._replication_state === 'triggered')) {
+ reportError('Only the replicator can edit replication documents ' +
+ 'that are in the triggered state.');
+ }
+
+ if (!newDoc._deleted) {
+ validateEndpoint(newDoc.source, 'source');
+ validateEndpoint(newDoc.target, 'target');
+
+ if ((typeof newDoc.create_target !== 'undefined') &&
+ (typeof newDoc.create_target !== 'boolean')) {
+
+ reportError('The `create_target\\' field must be a boolean.');
+ }
+
+ if ((typeof newDoc.continuous !== 'undefined') &&
+ (typeof newDoc.continuous !== 'boolean')) {
+
+ reportError('The `continuous\\' field must be a boolean.');
+ }
+
+ if ((typeof newDoc.doc_ids !== 'undefined') &&
+ !isArray(newDoc.doc_ids)) {
+
+ reportError('The `doc_ids\\' field must be an array of strings.');
+ }
+
+ if ((typeof newDoc.filter !== 'undefined') &&
+ ((typeof newDoc.filter !== 'string') || !newDoc.filter)) {
+
+ reportError('The `filter\\' field must be a non-empty string.');
+ }
+
+ if ((typeof newDoc.query_params !== 'undefined') &&
+ ((typeof newDoc.query_params !== 'object') ||
+ newDoc.query_params === null)) {
+
+ reportError('The `query_params\\' field must be an object.');
+ }
+
+ if (newDoc.user_ctx) {
+ var user_ctx = newDoc.user_ctx;
+
+ if ((typeof user_ctx !== 'object') || (user_ctx === null)) {
+ reportError('The `user_ctx\\' property must be a ' +
+ 'non-null object.');
+ }
+
+ if (!(user_ctx.name === null ||
+ (typeof user_ctx.name === 'undefined') ||
+ ((typeof user_ctx.name === 'string') &&
+ user_ctx.name.length > 0))) {
+
+ reportError('The `user_ctx.name\\' property must be a ' +
+ 'non-empty string or null.');
+ }
+
+ if (!isAdmin && (user_ctx.name !== userCtx.name)) {
+ reportError('The given `user_ctx.name\\' is not valid');
+ }
+
+ if (user_ctx.roles && !isArray(user_ctx.roles)) {
+ reportError('The `user_ctx.roles\\' property must be ' +
+ 'an array of strings.');
+ }
+
+ if (!isAdmin && user_ctx.roles) {
+ for (var i = 0; i < user_ctx.roles.length; i++) {
+ var role = user_ctx.roles[i];
+
+ if (typeof role !== 'string' || role.length === 0) {
+ reportError('Roles must be non-empty strings.');
+ }
+ if (userCtx.roles.indexOf(role) === -1) {
+ reportError('Invalid role (`' + role +
+ '\\') in the `user_ctx\\'');
+ }
+ }
+ }
+ } else {
+ if (!isAdmin) {
+ reportError('The `user_ctx\\' property is missing (it is ' +
+ 'optional for admins only).');
+ }
+ }
+ } else {
+ if (!isAdmin) {
+ if (!oldDoc.user_ctx || (oldDoc.user_ctx.name !== userCtx.name)) {
+ reportError('Replication documents can only be deleted by ' +
+ 'admins or by the users who created them.');
+ }
+ }
+ }
+ }
+">>).
View
6 src/couchdb/couch_replication_manager.erl → ...plicator/src/couch_replicator_manager.erl
@@ -10,7 +10,7 @@
% License for the specific language governing permissions and limitations under
% the License.
--module(couch_replication_manager).
+-module(couch_replicator_manager).
-behaviour(gen_server).
% public API
@@ -21,8 +21,8 @@
-export([code_change/3, terminate/2]).
-include("couch_db.hrl").
--include("couch_replicator.hrl").
--include("couch_js_functions.hrl").
+-include_lib("couch_replicator/include/couch_replicator.hrl").
+-include("couch_replicator_js_functions.hrl").
-define(DOC_TO_REP, couch_rep_doc_id_to_rep_id).
-define(REP_TO_STATE, couch_rep_id_to_rep_state).
View
4 src/couchdb/couch_replication_notifier.erl → ...licator/src/couch_replicator_notifier.erl
@@ -10,7 +10,7 @@
% License for the specific language governing permissions and limitations under
% the License.
--module(couch_replication_notifier).
+-module(couch_replicator_notifier).
-behaviour(gen_event).
@@ -25,7 +25,7 @@
start_link(FunAcc) ->
couch_event_sup:start_link(couch_replication,
- {couch_replication_notifier, make_ref()}, FunAcc).
+ {couch_replicator_notifier, make_ref()}, FunAcc).
notify(Event) ->
gen_event:notify(couch_replication, Event).
View
42 src/couch_replicator/src/couch_replicator_sup.erl
@@ -0,0 +1,42 @@
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
+-module(couch_replicator_sup).
+-behaviour(supervisor).
+-export([init/1, start_link/0]).
+
+
+start_link() ->
+ supervisor:start_link({local,?MODULE}, ?MODULE, []).
+
+init([]) ->
+ Children = [
+ {couch_replication_event,
+ {gen_event, start_link, [{local, couch_replication}]},
+ permanent,
+ brutal_kill,
+ worker,
+ dynamic},
+ {couch_replicator_tasks_sup,
+ {couch_replicator_tasks_sup, start_link, []},
+ permanent,
+ infinity,
+ supervisor,
+ [couch_replicator_tasks_sup]},
+ {couch_replicator_manager,
+ {couch_replicator_manager, start_link, []},
+ permanent,
+ brutal_kill,
+ worker,
+ [couch_replicator_manager]}
+ ],
+ {ok, {{one_for_one, 10, 3600}, Children}}.
View
2  src/couchdb/couch_rep_sup.erl → ...icator/src/couch_replicator_tasks_sup.erl
@@ -10,7 +10,7 @@
% License for the specific language governing permissions and limitations under
% the License.
--module(couch_rep_sup).
+-module(couch_replicator_tasks_sup).
-behaviour(supervisor).
-export([init/1, start_link/0]).
View
13 src/couchdb/couch_replicator_utils.erl → ...replicator/src/couch_replicator_utils.erl
@@ -19,8 +19,7 @@
-export([sum_stats/2]).
-include("couch_db.hrl").
--include("couch_api_wrap.hrl").
--include("couch_replicator.hrl").
+-include_lib("couch_replicator/include/couch_replicator.hrl").
-include("../ibrowse/ibrowse.hrl").
-import(couch_util, [
@@ -109,23 +108,23 @@ filter_code(Filter, Source, UserCtx) ->
_ ->
throw({error, <<"Invalid filter. Must match `ddocname/filtername`.">>})
end,
- Db = case (catch couch_api_wrap:db_open(Source, [{user_ctx, UserCtx}])) of
+ Db = case (catch couch_replicator_api:db_open(Source, [{user_ctx, UserCtx}])) of
{ok, Db0} ->
Db0;
DbError ->
DbErrorMsg = io_lib:format("Could not open source database `~s`: ~s",
- [couch_api_wrap:db_uri(Source), couch_util:to_binary(DbError)]),
+ [couch_replicator_api:db_uri(Source), couch_util:to_binary(DbError)]),
throw({error, iolist_to_binary(DbErrorMsg)})
end,
try
- Body = case (catch couch_api_wrap:open_doc(
+ Body = case (catch couch_replicator_api:open_doc(
Db, <<"_design/", DDocName/binary>>, [ejson_body])) of
{ok, #doc{body = Body0}} ->
Body0;
DocError ->
DocErrorMsg = io_lib:format(
"Couldn't open document `_design/~s` from source "
- "database `~s`: ~s", [DDocName, couch_api_wrap:db_uri(Source),
+ "database `~s`: ~s", [DDocName, couch_replicator_api:db_uri(Source),
couch_util:to_binary(DocError)]),
throw({error, iolist_to_binary(DocErrorMsg)})
end,
@@ -133,7 +132,7 @@ filter_code(Filter, Source, UserCtx) ->
Body, [<<"filters">>, FilterName]),
re:replace(Code, [$^, "\s*(.*?)\s*", $$], "\\1", [{return, binary}])
after
- couch_api_wrap:db_close(Db)
+ couch_replicator_api:db_close(Db)
end.
View
21 src/couchdb/couch_replicator_worker.erl → ...eplicator/src/couch_replicator_worker.erl
@@ -21,8 +21,7 @@
-export([handle_call/3, handle_cast/2, handle_info/2]).
-include("couch_db.hrl").
--include("couch_api_wrap.hrl").
--include("couch_replicator.hrl").
+-include_lib("couch_replicator/include/couch_replicator.hrl").
% TODO: maybe make both buffer max sizes configurable
-define(DOC_BUFFER_BYTE_SIZE, 512 * 1024). % for remote targets
@@ -295,14 +294,14 @@ spawn_doc_reader(Source, Target, FetchParams) ->
fetch_doc(Source, {Id, Revs, PAs}, DocHandler, Acc) ->
try
- couch_api_wrap:open_doc_revs(
+ couch_replicator_api:open_doc_revs(
Source, Id, Revs, [{atts_since, PAs}], DocHandler, Acc)
catch
throw:{missing_stub, _} ->
?LOG_ERROR("Retrying fetch and update of document `~p` due to out of "
"sync attachment stubs. Missing revisions are: ~s",
[Id, couch_doc:revs_to_strs(Revs)]),
- couch_api_wrap:open_doc_revs(Source, Id, Revs, [], DocHandler, Acc)
+ couch_replicator_api:open_doc_revs(Source, Id, Revs, [], DocHandler, Acc)
end.
@@ -444,9 +443,9 @@ flush_docs(_Target, []) ->
#rep_stats{};
flush_docs(Target, DocList) ->
- {ok, Errors} = couch_api_wrap:update_docs(
+ {ok, Errors} = couch_replicator_api:update_docs(
Target, DocList, [delay_commit], replicated_changes),
- DbUri = couch_api_wrap:db_uri(Target),
+ DbUri = couch_replicator_api:db_uri(Target),
lists:foreach(
fun({Props}) ->
?LOG_ERROR("Replicator: couldn't write document `~s`, revision `~s`,"
@@ -460,12 +459,12 @@ flush_docs(Target, DocList) ->
}.
flush_doc(Target, #doc{id = Id, revs = {Pos, [RevId | _]}} = Doc) ->
- try couch_api_wrap:update_doc(Target, Doc, [], replicated_changes) of
+ try couch_replicator_api:update_doc(Target, Doc, [], replicated_changes) of
{ok, _} ->
ok;
Error ->
?LOG_ERROR("Replicator: error writing document `~s` to `~s`: ~s",
- [Id, couch_api_wrap:db_uri(Target), couch_util:to_binary(Error)]),
+ [Id, couch_replicator_api:db_uri(Target), couch_util:to_binary(Error)]),
Error
catch
throw:{missing_stub, _} = MissingStub ->
@@ -474,13 +473,13 @@ flush_doc(Target, #doc{id = Id, revs = {Pos, [RevId | _]}} = Doc) ->
?LOG_ERROR("Replicator: couldn't write document `~s`, revision `~s`,"
" to target database `~s`. Error: `~s`, reason: `~s`.",
[Id, couch_doc:rev_to_str({Pos, RevId}),
- couch_api_wrap:db_uri(Target), to_binary(Error), to_binary(Reason)]),
+ couch_replicator_api:db_uri(Target), to_binary(Error), to_binary(Reason)]),
{error, Error};
throw:Err ->
?LOG_ERROR("Replicator: couldn't write document `~s`, revision `~s`,"
" to target database `~s`. Error: `~s`.",
[Id, couch_doc:rev_to_str({Pos, RevId}),
- couch_api_wrap:db_uri(Target), to_binary(Err)]),
+ couch_replicator_api:db_uri(Target), to_binary(Err)]),
{error, Err}
end.
@@ -492,7 +491,7 @@ find_missing(DocInfos, Target) ->
{[{Id, Revs} | IdRevAcc], CountAcc + length(Revs)}
end,
{[], 0}, DocInfos),
- {ok, Missing} = couch_api_wrap:get_missing_revs(Target, IdRevs),
+ {ok, Missing} = couch_replicator_api:get_missing_revs(Target, IdRevs),
MissingRevsCount = lists:foldl(
fun({_Id, MissingRevs, _PAs}, Acc) -> Acc + length(MissingRevs) end,
0, Missing),
View
40 src/couch_replicator/test/01-load.t
@@ -0,0 +1,40 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
+% Test that we can load each module.
+
+main(_) ->
+ test_util:init_code_path(),
+ Modules = [
+ couch_replicator,
+ couch_replicator_api,
+ couch_replicator_app,
+ couch_replicator_httpc_pool,
+ couch_replicator_httpc,
+ couch_replicator_httpd,
+ couch_replicator_manager,
+ couch_replicator_notifier,
+ couch_replicator_sup,
+ couch_replicator_tasks_sup,
+ couch_replicator_utils,
+ couch_replicator_worker
+ ],
+
+ etap:plan(length(Modules)),
+ lists:foreach(
+ fun(Module) ->
+ etap_can:loaded_ok(Module, lists:concat(["Loaded: ", Module]))
+ end, Modules),
+ etap:end_tests().
View
8 test/etap/230-httpc-pool.t → src/couch_replicator/test/02-httpc-pool.t
@@ -177,7 +177,7 @@ spawn_client(Pool) ->
Parent = self(),
Ref = make_ref(),
Pid = spawn(fun() ->
- {ok, Worker} = couch_httpc_pool:get_worker(Pool),
+ {ok, Worker} = couch_replicator_httpc_pool:get_worker(Pool),
loop(Parent, Ref, Worker, Pool)
end),
{Pid, Ref}.
@@ -233,7 +233,7 @@ loop(Parent, Ref, Worker, Pool) ->
Parent ! {worker, Ref, Worker},
loop(Parent, Ref, Worker, Pool);
stop ->
- couch_httpc_pool:release_worker(Pool, Worker),
+ couch_replicator_httpc_pool:release_worker(Pool, Worker),
Parent ! {stop, Ref}
end.
@@ -241,10 +241,10 @@ loop(Parent, Ref, Worker, Pool) ->
spawn_pool() ->
Host = couch_config:get("httpd", "bind_address", "127.0.0.1"),
Port = couch_config:get("httpd", "port", "5984"),
- {ok, Pool} = couch_httpc_pool:start_link(
+ {ok, Pool} = couch_replicator_httpc_pool:start_link(
"http://" ++ Host ++ ":5984", [{max_connections, 3}]),
Pool.
stop_pool(Pool) ->
- ok = couch_httpc_pool:stop(Pool).
+ ok = couch_replicator_httpc_pool:stop(Pool).
View
0  test/etap/240-replication-compact.t → ..._replicator/test/03-replication-compact.t
File renamed without changes
View
0  test/etap/241-replication-large-atts.t → ...plicator/test/04-replication-large-atts.t
File renamed without changes
View
26 src/couchdb/Makefile.am
@@ -17,7 +17,7 @@ couchlibdir = $(localerlanglibdir)/couch-$(version)
couchincludedir = $(couchlibdir)/include
couchebindir = $(couchlibdir)/ebin
-couchinclude_DATA = couch_api_wrap.hrl couch_db.hrl couch_js_functions.hrl couch_replicator.hrl
+couchinclude_DATA = couch_db.hrl couch_js_functions.hrl
couchebin_DATA = $(compiled_files)
# dist_devdoc_DATA = $(doc_base) $(doc_modules)
@@ -28,8 +28,6 @@ CLEANFILES = $(compiled_files) $(doc_base)
source_files = \
couch.erl \
- couch_api_wrap.erl \
- couch_api_wrap_httpc.erl \
couch_app.erl \
couch_auth_cache.erl \
couch_btree.erl \
@@ -48,7 +46,6 @@ source_files = \
couch_external_manager.erl \
couch_external_server.erl \
couch_file.erl \
- couch_httpc_pool.erl \
couch_httpd.erl \
couch_httpd_db.erl \
couch_httpd_auth.erl \
@@ -56,7 +53,6 @@ source_files = \
couch_httpd_external.erl \
couch_httpd_misc_handlers.erl \
couch_httpd_proxy.erl \
- couch_httpd_replicator.erl \
couch_httpd_rewrite.erl \
couch_httpd_stats_handlers.erl \
couch_httpd_vhost.erl \
@@ -68,12 +64,6 @@ source_files = \
couch_primary_sup.erl \
couch_query_servers.erl \
couch_ref_counter.erl \
- couch_rep_sup.erl \
- couch_replication_manager.erl \
- couch_replication_notifier.erl \
- couch_replicator.erl \
- couch_replicator_worker.erl \
- couch_replicator_utils.erl \
couch_secondary_sup.erl \
couch_server.erl \
couch_server_sup.erl \
@@ -87,13 +77,11 @@ source_files = \
couch_work_queue.erl \
json_stream_parse.erl
-EXTRA_DIST = $(source_files) couch_api_wrap.hrl couch_db.hrl couch_js_functions.hrl couch_replicator.hrl
+EXTRA_DIST = $(source_files) couch_db.hrl couch_js_functions.hrl
compiled_files = \
couch.app \
couch.beam \
- couch_api_wrap.beam \
- couch_api_wrap_httpc.beam \
couch_app.beam \
couch_auth_cache.beam \
couch_btree.beam \
@@ -112,7 +100,6 @@ compiled_files = \
couch_external_manager.beam \
couch_external_server.beam \
couch_file.beam \
- couch_httpc_pool.beam \
couch_httpd.beam \
couch_httpd_db.beam \
couch_httpd_auth.beam \
@@ -120,7 +107,6 @@ compiled_files = \
couch_httpd_proxy.beam \
couch_httpd_external.beam \
couch_httpd_misc_handlers.beam \
- couch_httpd_replicator.beam \
couch_httpd_rewrite.beam \
couch_httpd_stats_handlers.beam \
couch_httpd_vhost.beam \
@@ -132,12 +118,6 @@ compiled_files = \
couch_primary_sup.beam \
couch_query_servers.beam \
couch_ref_counter.beam \
- couch_rep_sup.beam \
- couch_replication_manager.beam \
- couch_replication_notifier.beam \
- couch_replicator.beam \
- couch_replicator_worker.beam \
- couch_replicator_utils.beam \
couch_secondary_sup.beam \
couch_server.beam \
couch_server_sup.beam \
@@ -207,6 +187,6 @@ endif
# $(ERL) -noshell -run edoc_run files [\"$<\"]
-%.beam: %.erl couch_api_wrap.hrl couch_db.hrl couch_js_functions.hrl couch_replicator.hrl
+%.beam: %.erl couch_db.hrl couch_js_functions.hrl
$(ERLC) $(ERLC_FLAGS) ${TEST} $<;
View
1  src/couchdb/couch.app.tpl.in
@@ -11,7 +11,6 @@
couch_log,
couch_primary_services,
couch_query_servers,
- couch_rep_sup,
couch_secondary_services,
couch_server,
couch_server_sup,
View
141 src/couchdb/couch_js_functions.hrl
@@ -104,144 +104,3 @@
}
}
">>).
-
-
--define(REP_DB_DOC_VALIDATE_FUN, <<"
- function(newDoc, oldDoc, userCtx) {
- function reportError(error_msg) {
- log('Error writing document `' + newDoc._id +
- '\\' to the replicator database: ' + error_msg);
- throw({forbidden: error_msg});
- }
-
- function validateEndpoint(endpoint, fieldName) {
- if ((typeof endpoint !== 'string') &&
- ((typeof endpoint !== 'object') || (endpoint === null))) {
-
- reportError('The `' + fieldName + '\\' property must exist' +
- ' and be either a string or an object.');
- }
-
- if (typeof endpoint === 'object') {
- if ((typeof endpoint.url !== 'string') || !endpoint.url) {
- reportError('The url property must exist in the `' +
- fieldName + '\\' field and must be a non-empty string.');
- }
-
- if ((typeof endpoint.auth !== 'undefined') &&
- ((typeof endpoint.auth !== 'object') ||
- endpoint.auth === null)) {
-
- reportError('`' + fieldName +
- '.auth\\' must be a non-null object.');
- }
-
- if ((typeof endpoint.headers !== 'undefined') &&
- ((typeof endpoint.headers !== 'object') ||
- endpoint.headers === null)) {
-
- reportError('`' + fieldName +
- '.headers\\' must be a non-null object.');
- }
- }
- }
-
- var isReplicator = (userCtx.roles.indexOf('_replicator') >= 0);
- var isAdmin = (userCtx.roles.indexOf('_admin') >= 0);
-
- if (oldDoc && !newDoc._deleted && !isReplicator &&
- (oldDoc._replication_state === 'triggered')) {
- reportError('Only the replicator can edit replication documents ' +
- 'that are in the triggered state.');
- }
-
- if (!newDoc._deleted) {
- validateEndpoint(newDoc.source, 'source');
- validateEndpoint(newDoc.target, 'target');
-
- if ((typeof newDoc.create_target !== 'undefined') &&
- (typeof newDoc.create_target !== 'boolean')) {
-
- reportError('The `create_target\\' field must be a boolean.');
- }
-
- if ((typeof newDoc.continuous !== 'undefined') &&
- (typeof newDoc.continuous !== 'boolean')) {
-
- reportError('The `continuous\\' field must be a boolean.');
- }
-
- if ((typeof newDoc.doc_ids !== 'undefined') &&
- !isArray(newDoc.doc_ids)) {
-
- reportError('The `doc_ids\\' field must be an array of strings.');
- }
-
- if ((typeof newDoc.filter !== 'undefined') &&
- ((typeof newDoc.filter !== 'string') || !newDoc.filter)) {
-
- reportError('The `filter\\' field must be a non-empty string.');
- }
-
- if ((typeof newDoc.query_params !== 'undefined') &&
- ((typeof newDoc.query_params !== 'object') ||
- newDoc.query_params === null)) {
-
- reportError('The `query_params\\' field must be an object.');
- }
-
- if (newDoc.user_ctx) {
- var user_ctx = newDoc.user_ctx;
-
- if ((typeof user_ctx !== 'object') || (user_ctx === null)) {
- reportError('The `user_ctx\\' property must be a ' +
- 'non-null object.');
- }
-
- if (!(user_ctx.name === null ||
- (typeof user_ctx.name === 'undefined') ||
- ((typeof user_ctx.name === 'string') &&
- user_ctx.name.length > 0))) {
-
- reportError('The `user_ctx.name\\' property must be a ' +
- 'non-empty string or null.');
- }
-
- if (!isAdmin && (user_ctx.name !== userCtx.name)) {
- reportError('The given `user_ctx.name\\' is not valid');
- }
-
- if (user_ctx.roles && !isArray(user_ctx.roles)) {
- reportError('The `user_ctx.roles\\' property must be ' +
- 'an array of strings.');
- }
-
- if (!isAdmin && user_ctx.roles) {
- for (var i = 0; i < user_ctx.roles.length; i++) {
- var role = user_ctx.roles[i];
-
- if (typeof role !== 'string' || role.length === 0) {
- reportError('Roles must be non-empty strings.');
- }
- if (userCtx.roles.indexOf(role) === -1) {
- reportError('Invalid role (`' + role +
- '\\') in the `user_ctx\\'');
- }
- }
- }
- } else {
- if (!isAdmin) {
- reportError('The `user_ctx\\' property is missing (it is ' +
- 'optional for admins only).');
- }
- }
- } else {
- if (!isAdmin) {
- if (!oldDoc.user_ctx || (oldDoc.user_ctx.name !== userCtx.name)) {
- reportError('Replication documents can only be deleted by ' +
- 'admins or by the users who created them.');
- }
- }
- }
- }
-">>).
View
12 src/couchdb/couch_primary_sup.erl
@@ -43,18 +43,12 @@ init([]) ->
brutal_kill,
worker,
dynamic},
- {couch_replication_event,
- {gen_event, start_link, [{local, couch_replication}]},
- permanent,
- brutal_kill,
- worker,
- dynamic},
- {couch_replication_supervisor,
- {couch_rep_sup, start_link, []},
+ {couch_replicator,
+ {couch_replicator_sup, start_link, []},
permanent,
infinity,
supervisor,
- [couch_rep_sup]},
+ [couch_replicator_sup]},
{couch_log,
{couch_log, start_link, []},
permanent,
View
30 src/couchdb/couch_replicator.hrl
@@ -1,30 +0,0 @@
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-% http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
--define(REP_ID_VERSION, 2).
-
--record(rep, {
- id,
- source,
- target,
- options,
- user_ctx,
- doc_id
-}).
-
--record(rep_stats, {
- missing_checked = 0,
- missing_found = 0,
- docs_read = 0,
- docs_written = 0,
- doc_write_failures = 0
-}).
View
9 test/etap/001-load.t
@@ -19,8 +19,6 @@ main(_) ->
test_util:init_code_path(),
Modules = [
couch_auth_cache,
- couch_api_wrap,
- couch_api_wrap_httpc,
couch_btree,
couch_changes,
couch_compress,
@@ -41,7 +39,6 @@ main(_) ->
couch_httpd_db,
couch_httpd_external,
couch_httpd_misc_handlers,
- couch_httpd_replicator,
couch_httpd_rewrite,
couch_httpd_stats_handlers,
couch_key_tree,
@@ -49,12 +46,6 @@ main(_) ->
couch_os_process,
couch_query_servers,
couch_ref_counter,
- couch_replication_manager,
- couch_replication_notifier,
- couch_replicator,
- couch_replicator_worker,
- couch_replicator_utils,
- couch_rep_sup,
couch_server,
couch_server_sup,
couch_stats_aggregator,

No commit comments for this range

Something went wrong with that request. Please try again.