}
}
-void tags_from_attributes(const req_state* s, rgw::sal::RGWObject* obj, KeyValueMap& tags) {
+void tags_from_attributes(const req_state* s, rgw::sal::RGWObject* obj, KeyMultiValueMap& tags) {
const auto src_obj = get_object_with_atttributes(s, obj);
if (!src_obj) {
return;
}
} else {
// try to fetch tags from the attributes
- KeyValueMap tags;
+ KeyMultiValueMap tags;
tags_from_attributes(s, obj, tags);
if (!match(filter.s3_filter.tag_filter, tags)) {
return false;
return std::includes(kv.begin(), kv.end(), filter.kv.begin(), filter.kv.end());
}
+bool match(const rgw_s3_key_value_filter& filter, const KeyMultiValueMap& kv) {
+ // all filter pairs must exist with the same value in the object's metadata/tags
+ // object metadata/tags may include items not in the filter
+ for (auto& filter : filter.kv) {
+ auto result = kv.equal_range(filter.first);
+ if (std::any_of(result.first, result.second, [&filter](const pair<string,string>& p) { return p.second == filter.second;}))
+ continue;
+ else
+ return false;
+ }
+ return true;
+}
+
bool match(const rgw::notify::EventTypeList& events, rgw::notify::EventType event) {
// if event list exists, and none of the events in the list matches the event type, filter the message
if (!events.empty() && std::find(events.begin(), events.end(), event) == events.end()) {
WRITE_CLASS_ENCODER(rgw_s3_key_filter)
using KeyValueMap = boost::container::flat_map<std::string, std::string>;
+using KeyMultiValueMap = std::multimap<std::string, std::string>;
struct rgw_s3_key_value_filter {
KeyValueMap kv;
// return true if the key matches the prefix/suffix/regex rules of the key filter
bool match(const rgw_s3_key_filter& filter, const std::string& key);
-// return true if the key matches the metadata/tags rules of the metadata/tags filter
+
+// return true if the key matches the metadata rules of the metadata filter
bool match(const rgw_s3_key_value_filter& filter, const KeyValueMap& kv);
+
+// return true if the key matches the tag rules of the tag filter
+bool match(const rgw_s3_key_value_filter& filter, const KeyMultiValueMap& kv);
+
// return true if the event type matches (equal or contained in) one of the events in the list
bool match(const rgw::notify::EventTypeList& events, rgw::notify::EventType event);
// meta data
KeyValueMap x_meta_map;
// tags
- KeyValueMap tags;
+ KeyMultiValueMap tags;
// opaque data received from the topic
// could be used to identify the gateway
std::string opaque_data;
#include "rgw_tag.h"
#include "rgw_common.h"
-bool RGWObjTags::add_tag(const string&key, const string& val){
- return tag_map.emplace(std::make_pair(key,val)).second;
+void RGWObjTags::add_tag(const string& key, const string& val){
+ tag_map.emplace(std::make_pair(key,val));
}
-bool RGWObjTags::emplace_tag(std::string&& key, std::string&& val){
- return tag_map.emplace(std::move(key), std::move(val)).second;
+void RGWObjTags::emplace_tag(std::string&& key, std::string&& val){
+ tag_map.emplace(std::move(key), std::move(val));
}
int RGWObjTags::check_and_add_tag(const string&key, const string& val){
return -ERR_INVALID_TAG;
}
- // if we get a conflicting key, either the XML is malformed or the user
- // supplied an invalid string
- if (!add_tag(key,val))
- return -EINVAL;
+ add_tag(key,val);
return 0;
}
#include <string>
#include <include/types.h>
-#include <boost/container/flat_map.hpp>
+#include <map>
class RGWObjTags
{
public:
- using tag_map_t = boost::container::flat_map <std::string, std::string>;
+ using tag_map_t = std::multimap <std::string, std::string>;
protected:
tag_map_t tag_map;
}
void dump(Formatter *f) const;
- bool add_tag(const std::string& key, const std::string& val="");
- bool emplace_tag(std::string&& key, std::string&& val);
+ void add_tag(const std::string& key, const std::string& val="");
+ void emplace_tag(std::string&& key, std::string&& val);
int check_and_add_tag(const std::string& key, const std::string& val="");
size_t count() const {return tag_map.size();}
int set_from_string(const std::string& input);
for (auto& entry : entries) {
const std::string& key = entry.get_key();
const std::string& val = entry.get_val();
- if (!add_tag(key,val)) {
- throw RGWXMLDecoder::err("failed to add tag");
- }
+ add_tag(key,val);
}
}