Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Register bucket_validator mods with riak_core

Call validation functions when bucket props are set
  • Loading branch information...
commit 60be2c3017380eec34557ac29852a806e1ea3cf4 1 parent d8d6f90
@russelldb russelldb authored
Showing with 39 additions and 11 deletions.
  1. +10 −1 src/riak_core.erl
  2. +29 −10 src/riak_core_bucket.erl
View
11 src/riak_core.erl
@@ -23,7 +23,7 @@
-export([stop/0, stop/1, join/1, join/4, remove/1, down/1, leave/0,
remove_from_cluster/1]).
-export([register_vnode_module/1, vnode_modules/0]).
--export([register/1, register/2, bucket_fixups/0]).
+-export([register/1, register/2, bucket_fixups/0, bucket_validators/0]).
-export([add_guarded_event_handler/3, add_guarded_event_handler/4]).
-export([delete_guarded_event_handler/3]).
-compile({no_auto_import,[register/2]}).
@@ -261,6 +261,12 @@ bucket_fixups() ->
{ok, Mods} -> Mods
end.
+bucket_validators() ->
+ case application:get_env(riak_core, bucket_validators) of
+ undefined -> [];
+ {ok, Mods} -> Mods
+ end.
+
%% Get the application name if not supplied, first by get_application
%% then by searching by module name
get_app(undefined, Module) ->
@@ -289,6 +295,9 @@ register(App, [{bucket_fixup, FixupMod}|T]) ->
register(App, T);
register(App, [{vnode_module, VNodeMod}|T]) ->
register_mod(get_app(App, VNodeMod), VNodeMod, vnode_modules),
+ register(App, T);
+register(App, [{bucket_validator, ValidationMod}|T]) ->
+ register_mod(get_app(App, ValidationMod), ValidationMod, bucket_validators),
register(App, T).
register_vnode_module(VNodeMod) when is_atom(VNodeMod) ->
View
39 src/riak_core_bucket.erl
@@ -57,16 +57,22 @@ append_bucket_defaults(Items) when is_list(Items) ->
%% @spec set_bucket(riak_object:bucket(), BucketProps::riak_core_bucketprops()) -> ok
%% @doc Set the given BucketProps in Bucket.
-set_bucket(Name, BucketProps) ->
- F = fun(Ring, _Args) ->
- OldBucket = get_bucket(Name),
- NewBucket = merge_props(BucketProps, OldBucket),
- {new_ring, riak_core_ring:update_meta({bucket,Name},
- NewBucket,
- Ring)}
- end,
- {ok, _NewRing} = riak_core_ring_manager:ring_trans(F, undefined),
- ok.
+set_bucket(Name, BucketProps0) ->
+ case validate_props(BucketProps0, riak_core:bucket_validators(), []) of
+ {ok, BucketProps} ->
+ F = fun(Ring, _Args) ->
+ OldBucket = get_bucket(Name),
+ NewBucket = merge_props(BucketProps, OldBucket),
+ {new_ring, riak_core_ring:update_meta({bucket,Name},
+ NewBucket,
+ Ring)}
+ end,
+ {ok, _NewRing} = riak_core_ring_manager:ring_trans(F, undefined),
+ ok;
+ {error, Details} ->
+ lager:error("Bucket validation failed ~p~n", [Details]),
+ {error, Details}
+ end.
%% @spec merge_props(list(), list()) -> list()
%% @doc Merge two sets of bucket props. If duplicates exist, the
@@ -101,6 +107,19 @@ get_bucket(Name, Ring) ->
{ok, Bucket} -> Bucket
end.
+%% @private
+-spec validate_props(BucketProps::list({PropName::atom(), Value::any()}),
+ Validators::list(module()),
+ Errors::list({PropName::atom(), Error::atom()})) ->
+ {ok, BucketProps::list({PropName::atom(), Value::any()})} |
+ {error, Errors::list({PropName::atom(), Error::atom()})}.
+validate_props(BucketProps, [], []) ->
+ {ok, BucketProps};
+validate_props(_, [], Errors) ->
+ {error, Errors};
+validate_props(BucketProps0, [{_App, Validator}|T], Errors0) ->
+ {BucketProps, Errors} = Validator:validate(BucketProps0),
+ validate_props(BucketProps, T, lists:flatten([Errors|Errors0])).
%% ===================================================================
%% EUnit tests
Please sign in to comment.
Something went wrong with that request. Please try again.