diff --git a/src/mod_pubsub/mod_pubsub.erl b/src/mod_pubsub/mod_pubsub.erl index 0cda9de11..f3c2c57a6 100644 --- a/src/mod_pubsub/mod_pubsub.erl +++ b/src/mod_pubsub/mod_pubsub.erl @@ -1248,7 +1248,7 @@ iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang, Access, Plugins) -> case xml:remove_cdata(Els) of [{xmlelement, "item", ItemAttrs, Payload}] -> ItemId = xml:get_attr_s("id", ItemAttrs), - publish_item(Host, ServerHost, Node, From, ItemId, Payload); + publish_item(Host, ServerHost, Node, From, ItemId, Payload, Access); [] -> %% Publisher attempts to publish to persistent node with no item {error, extended_error(?ERR_BAD_REQUEST, @@ -2030,8 +2030,10 @@ unsubscribe_node(Host, Node, From, Subscriber, SubId) -> %% publish_item(Host, ServerHost, Node, Publisher, "", Payload) -> %% if publisher does not specify an ItemId, the service MUST generate the ItemId - publish_item(Host, ServerHost, Node, Publisher, uniqid(), Payload); + publish_item(Host, ServerHost, Node, Publisher, uniqid(), Payload, all); publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) -> + publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, all). +publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, Access) -> Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId}) -> Features = features(Type), PublishFeature = lists:member("publish", Features), @@ -2122,7 +2124,7 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) -> Type = select_type(ServerHost, Host, Node), case lists:member("auto-create", features(Type)) of true -> - case create_node(Host, ServerHost, Node, Publisher, Type) of + case create_node(Host, ServerHost, Node, Publisher, Type, Access, []) of {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "create", [{"node", NewNode}], []}]}]} -> publish_item(Host, ServerHost, list_to_binary(NewNode), @@ -2621,13 +2623,15 @@ get_options_helper(JID, Lang, Node, NodeID, SubID, Type) -> read_sub(Subscriber, Node, NodeID, SubID, Lang) -> case pubsub_subscription:get_subscription(Subscriber, NodeID, SubID) of - {error, notfound} -> - {error, extended_error(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; {result, #pubsub_subscription{options = Options}} -> {result, XdataEl} = pubsub_subscription:get_options_xform(Lang, Options), OptionsEl = {xmlelement, "options", [{"jid", jlib:jid_to_string(Subscriber)}, - {"subid", SubID}|nodeAttr(Node)], - [XdataEl]}, + {"subid", SubID}|nodeAttr(Node)], + [XdataEl]}, + PubsubEl = {xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [OptionsEl]}, + {result, PubsubEl}; + _ -> OptionsEl = {xmlelement, "options", [{"jid", jlib:jid_to_string(Subscriber)}, + {"subid", SubID}|nodeAttr(Node)]}, PubsubEl = {xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [OptionsEl]}, {result, PubsubEl} end. @@ -2678,12 +2682,14 @@ set_options_helper(Configuration, JID, NodeID, SubID, Type) -> write_sub(_Subscriber, _NodeID, _SubID, invalid) -> {error, extended_error(?ERR_BAD_REQUEST, "invalid-options")}; +write_sub(_Subscriber, _NodeID, _SubID, []) -> + {result, []}; write_sub(Subscriber, NodeID, SubID, Options) -> case pubsub_subscription:set_subscription(Subscriber, NodeID, SubID, Options) of - {error, notfound} -> - {error, extended_error(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; {result, _} -> - {result, []} + {result, []}; + {error, _} -> + {error, extended_error('not-acceptable', "invalid-subid")} end. %% @spec (Host, Node, JID, Plugins) -> {error, Reason} | {result, Response} diff --git a/src/mod_pubsub/node_hometree.erl b/src/mod_pubsub/node_hometree.erl index 522677a15..56b3ae90e 100644 --- a/src/mod_pubsub/node_hometree.erl +++ b/src/mod_pubsub/node_hometree.erl @@ -97,9 +97,11 @@ init(_Host, _ServerHost, _Options) -> pubsub_subscription:init(), mnesia:create_table(pubsub_state, [{disc_copies, [node()]}, + {index, [nodeidx]}, {attributes, record_info(fields, pubsub_state)}]), mnesia:create_table(pubsub_item, [{disc_only_copies, [node()]}, + {index, [nodeidx]}, {attributes, record_info(fields, pubsub_item)}]), ItemsFields = record_info(fields, pubsub_item), case mnesia:table_info(pubsub_item, attributes) of @@ -224,7 +226,7 @@ create_node_permission(Host, ServerHost, NodeId, _ParentNodeId, Owner, Access) - %% @doc

create_node(NodeIdx, Owner) -> OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), - set_state(#pubsub_state{stateid = {OwnerKey, NodeIdx}, affiliation = owner}), + set_state(#pubsub_state{stateid = {OwnerKey, NodeIdx}, nodeidx = NodeIdx, affiliation = owner}), {result, {default, broadcast}}. %% @spec (Nodes) -> {result, {default, broadcast, Reply}} @@ -507,6 +509,7 @@ publish_item(NodeIdx, Publisher, PublishModel, MaxItems, ItemId, Payload) -> payload = Payload}; _ -> #pubsub_item{itemid = {ItemId, NodeIdx}, + nodeidx = NodeIdx, creation = {Now, GenKey}, modification = PubId, payload = Payload} @@ -860,8 +863,8 @@ get_nodes_helper(NodeTree, %% ```get_states(NodeIdx) -> %% node_default:get_states(NodeIdx).'''

get_states(NodeIdx) -> - States = case catch mnesia:match_object( - #pubsub_state{stateid = {'_', NodeIdx}, _ = '_'}) of + States = case catch mnesia:index_read( + pubsub_state, NodeIdx, #pubsub_state.nodeidx) of List when is_list(List) -> List; _ -> [] end, @@ -875,8 +878,8 @@ get_states(NodeIdx) -> get_state(NodeIdx, JID) -> StateId = {JID, NodeIdx}, case catch mnesia:read({pubsub_state, StateId}) of - [State] when is_record(State, pubsub_state) -> State; - _ -> #pubsub_state{stateid=StateId} + [#pubsub_state{} = State] -> State; + _ -> #pubsub_state{stateid=StateId, nodeidx=NodeIdx} end. %% @spec (State) -> ok | {error, Reason} @@ -911,7 +914,7 @@ del_state(NodeIdx, JID) -> %% ```get_items(NodeIdx, From) -> %% node_default:get_items(NodeIdx, From).'''

get_items(NodeIdx, _From) -> - Items = mnesia:match_object(#pubsub_item{itemid = {'_', NodeIdx}, _ = '_'}), + Items = mnesia:index_read(pubsub_item, NodeIdx, #pubsub_item.nodeidx), {result, lists:reverse(lists:keysort(#pubsub_item.modification, Items))}. get_items(NodeIdx, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) -> diff --git a/src/mod_pubsub/pubsub.hrl b/src/mod_pubsub/pubsub.hrl index 5a943ee44..552d507a7 100644 --- a/src/mod_pubsub/pubsub.hrl +++ b/src/mod_pubsub/pubsub.hrl @@ -136,8 +136,9 @@ options = [] }). -%% @type pubsubState() = {pubsub_state, StateId, Items, Affiliation, Subscriptions} +%% @type pubsubState() = {pubsub_state, StateId, NodeIdx, Items, Affiliation, Subscriptions} %% StateId = {ljid(), nodeIdx()} +%% NodeIdx = nodeIdx(), %% Items = [itemId()] %% Affiliation = affiliation() %% Subscriptions = [{subscription(), subId()}]. @@ -146,6 +147,7 @@ -record(pubsub_state, { stateid, + nodeidx, items = [], affiliation = 'none', subscriptions = [] @@ -161,6 +163,7 @@ -record(pubsub_item, { itemid, + nodeidx, creation = {'unknown','unknown'}, modification = {'unknown','unknown'}, payload = [] diff --git a/src/mod_pubsub/pubsub_subscription.erl b/src/mod_pubsub/pubsub_subscription.erl index 600f1e119..8ddf15957 100644 --- a/src/mod_pubsub/pubsub_subscription.erl +++ b/src/mod_pubsub/pubsub_subscription.erl @@ -160,6 +160,8 @@ create_table() -> Other -> Other end. +add_subscription(_JID, _NodeID, []) -> + make_subid(); add_subscription(_JID, _NodeID, Options) -> SubID = make_subid(), mnesia:write(#pubsub_subscription{subid = SubID, options = Options}), @@ -174,11 +176,8 @@ read_subscription(_JID, _NodeID, SubID) -> _ -> {error, notfound} end. -write_subscription(JID, NodeID, SubID, Options) -> - case read_subscription(JID, NodeID, SubID) of - {error, notfound} -> {error, notfound}; - Sub -> mnesia:write(Sub#pubsub_subscription{options = Options}) - end. +write_subscription(_JID, _NodeID, SubID, Options) -> + mnesia:write(#pubsub_subscription{subid = SubID, options = Options}). make_subid() -> {T1, T2, T3} = now(),