mirror of
https://github.com/ceph/ceph
synced 2024-12-27 14:03:25 +00:00
rgw: rework lifecycle parsing
Use new style xml parsing, instead of inheriting from XMLParser. Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
This commit is contained in:
parent
408f04ff4a
commit
dc808953f2
@ -30,6 +30,9 @@ namespace ceph {
|
||||
ObjectSection(Formatter& f, const char *name) : formatter(f) {
|
||||
formatter.open_object_section(name);
|
||||
}
|
||||
ObjectSection(Formatter& f, const char *name, const char *ns) : formatter(f) {
|
||||
formatter.open_object_section_in_ns(name, ns);
|
||||
}
|
||||
~ObjectSection() {
|
||||
formatter.close_section();
|
||||
}
|
||||
@ -41,6 +44,9 @@ namespace ceph {
|
||||
ArraySection(Formatter& f, const char *name) : formatter(f) {
|
||||
formatter.open_array_section(name);
|
||||
}
|
||||
ArraySection(Formatter& f, const char *name, const char *ns) : formatter(f) {
|
||||
formatter.open_array_section_in_ns(name, ns);
|
||||
}
|
||||
~ArraySection() {
|
||||
formatter.close_section();
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ typedef enum {
|
||||
lc_processing,
|
||||
lc_failed,
|
||||
lc_complete,
|
||||
}LC_BUCKET_STATUS;
|
||||
} LC_BUCKET_STATUS;
|
||||
|
||||
class LCExpiration
|
||||
{
|
||||
@ -46,7 +46,7 @@ protected:
|
||||
string date;
|
||||
public:
|
||||
LCExpiration() {}
|
||||
~LCExpiration() {}
|
||||
LCExpiration(const string& _days, const string& _date) : days(_days), date(_date) {}
|
||||
|
||||
void encode(bufferlist& bl) const {
|
||||
ENCODE_START(3, 2, bl);
|
||||
@ -92,7 +92,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
};
|
||||
WRITE_CLASS_ENCODER(LCExpiration);
|
||||
WRITE_CLASS_ENCODER(LCExpiration)
|
||||
|
||||
class LCTransition
|
||||
{
|
||||
@ -153,7 +153,7 @@ public:
|
||||
}
|
||||
void dump(Formatter *f) const;
|
||||
};
|
||||
WRITE_CLASS_ENCODER(LCTransition);
|
||||
WRITE_CLASS_ENCODER(LCTransition)
|
||||
|
||||
class LCFilter
|
||||
{
|
||||
@ -209,7 +209,7 @@ class LCFilter
|
||||
}
|
||||
void dump(Formatter *f) const;
|
||||
};
|
||||
WRITE_CLASS_ENCODER(LCFilter);
|
||||
WRITE_CLASS_ENCODER(LCFilter)
|
||||
|
||||
|
||||
|
||||
|
@ -27,77 +27,100 @@ static bool check_date(const string& _date)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LCExpiration_S3::xml_end(const char * el) {
|
||||
LCDays_S3 *lc_days = static_cast<LCDays_S3 *>(find_first("Days"));
|
||||
LCDeleteMarker_S3 *lc_dm = static_cast<LCDeleteMarker_S3 *>(find_first("ExpiredObjectDeleteMarker"));
|
||||
LCDate_S3 *lc_date = static_cast<LCDate_S3 *>(find_first("Date"));
|
||||
|
||||
if ((!lc_days && !lc_dm && !lc_date) || (lc_days && lc_dm)
|
||||
|| (lc_days && lc_date) || (lc_dm && lc_date)) {
|
||||
return false;
|
||||
}
|
||||
if (lc_days) {
|
||||
days = lc_days->get_data();
|
||||
} else if (lc_dm) {
|
||||
dm_expiration = lc_dm->get_data().compare("true") == 0;
|
||||
if (!dm_expiration) {
|
||||
return false;
|
||||
}
|
||||
void LCExpiration_S3::dump_xml(Formatter *f) const {
|
||||
if (dm_expiration) {
|
||||
encode_xml("ExpiredObjectDeleteMarker", "true", f);
|
||||
} else if (!days.empty()) {
|
||||
encode_xml("Days", days, f);
|
||||
} else {
|
||||
date = lc_date->get_data();
|
||||
encode_xml("Date", date, f);
|
||||
}
|
||||
}
|
||||
|
||||
void LCExpiration_S3::decode_xml(XMLObj *obj)
|
||||
{
|
||||
bool has_days = RGWXMLDecoder::decode_xml("Days", days, obj);
|
||||
bool has_date = RGWXMLDecoder::decode_xml("Date", date, obj);
|
||||
string dm;
|
||||
bool has_dm = RGWXMLDecoder::decode_xml("ExpiredObjectDeleteMarker", dm, obj);
|
||||
|
||||
if ((!has_days && !has_dm && !has_date) || (has_days && has_dm)
|
||||
|| (has_days && has_date) || (has_dm && has_date)) {
|
||||
throw RGWXMLDecoder::err("bad Expiration section");
|
||||
}
|
||||
|
||||
if (has_date && !check_date(date)) {
|
||||
//We need return xml error according to S3
|
||||
if (!check_date(date)) {
|
||||
return false;
|
||||
}
|
||||
throw RGWXMLDecoder::err("bad date in Date section");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LCNoncurExpiration_S3::xml_end(const char *el) {
|
||||
LCDays_S3 *lc_noncur_days = static_cast<LCDays_S3 *>(find_first("NoncurrentDays"));
|
||||
if (!lc_noncur_days) {
|
||||
return false;
|
||||
}
|
||||
days = lc_noncur_days->get_data();
|
||||
return true;
|
||||
void LCNoncurExpiration_S3::decode_xml(XMLObj *obj)
|
||||
{
|
||||
RGWXMLDecoder::decode_xml("NoncurrentDays", days, obj, true);
|
||||
}
|
||||
|
||||
bool LCMPExpiration_S3::xml_end(const char *el) {
|
||||
LCDays_S3 *lc_mp_days = static_cast<LCDays_S3 *>(find_first("DaysAfterInitiation"));
|
||||
if (!lc_mp_days) {
|
||||
return false;
|
||||
}
|
||||
days = lc_mp_days->get_data();
|
||||
return true;
|
||||
void LCNoncurExpiration_S3::dump_xml(Formatter *f) const
|
||||
{
|
||||
encode_xml("NoncurrentDays", days, f);
|
||||
}
|
||||
|
||||
bool RGWLifecycleConfiguration_S3::xml_end(const char *el) {
|
||||
XMLObjIter iter = find("Rule");
|
||||
LCRule_S3 *rule = static_cast<LCRule_S3 *>(iter.get_next());
|
||||
if (!rule)
|
||||
return false;
|
||||
while (rule) {
|
||||
add_rule(rule);
|
||||
rule = static_cast<LCRule_S3 *>(iter.get_next());
|
||||
void LCMPExpiration_S3::decode_xml(XMLObj *obj)
|
||||
{
|
||||
RGWXMLDecoder::decode_xml("DaysAfterInitiation", days, obj, true);
|
||||
}
|
||||
|
||||
void LCMPExpiration_S3::dump_xml(Formatter *f) const
|
||||
{
|
||||
encode_xml("DaysAfterInitiation", days, f);
|
||||
}
|
||||
|
||||
void RGWLifecycleConfiguration_S3::decode_xml(XMLObj *obj)
|
||||
{
|
||||
vector<LCRule_S3> rules;
|
||||
|
||||
RGWXMLDecoder::decode_xml("Rule", rules, obj, true);
|
||||
|
||||
for (auto& rule : rules) {
|
||||
add_rule(&rule);
|
||||
}
|
||||
|
||||
if (cct->_conf->rgw_lc_max_rules < rule_map.size()) {
|
||||
ldout(cct, 5) << "Warn: The lifecycle config has too many rules, rule number is:"
|
||||
<< rule_map.size() << ", max number is:" << cct->_conf->rgw_lc_max_rules << dendl;
|
||||
return false;
|
||||
stringstream ss;
|
||||
ss << "Warn: The lifecycle config has too many rules, rule number is:"
|
||||
<< rule_map.size() << ", max number is:" << cct->_conf->rgw_lc_max_rules;
|
||||
throw RGWXMLDecoder::err(ss.str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LCFilter_S3::xml_end(const char* el) {
|
||||
void LCFilter_S3::dump_xml(Formatter *f) const
|
||||
{
|
||||
if (has_prefix()) {
|
||||
encode_xml("Prefix", prefix, f);
|
||||
}
|
||||
bool multi = has_multi_condition();
|
||||
if (multi) {
|
||||
f->open_array_section("And");
|
||||
}
|
||||
if (has_tags()) {
|
||||
const auto& tagset_s3 = static_cast<const RGWObjTagSet_S3 &>(obj_tags);
|
||||
tagset_s3.dump_xml(f);
|
||||
}
|
||||
if (multi) {
|
||||
f->close_section();
|
||||
}
|
||||
}
|
||||
|
||||
XMLObj *o = find_first("And");
|
||||
void LCFilter_S3::decode_xml(XMLObj *obj)
|
||||
{
|
||||
XMLObj *o = obj->find_first("And");
|
||||
bool single_cond = false;
|
||||
int num_conditions = 0;
|
||||
// If there is an AND condition, every tag is a child of and
|
||||
// else we only support single conditions and return false if we see multiple
|
||||
|
||||
if (o == nullptr){
|
||||
o = this;
|
||||
o = obj;
|
||||
single_cond = true;
|
||||
}
|
||||
|
||||
@ -114,65 +137,56 @@ bool LCFilter_S3::xml_end(const char* el) {
|
||||
num_conditions++;
|
||||
}
|
||||
|
||||
return !(single_cond && num_conditions > 1);
|
||||
if (single_cond && num_conditions > 1) {
|
||||
throw RGWXMLDecoder::err("Bad filter: badly formed multiple conditions");
|
||||
}
|
||||
}
|
||||
|
||||
bool LCTransition_S3::xml_end(const char* el) {
|
||||
LCDays_S3 *lc_days = static_cast<LCDays_S3 *>(find_first("Days"));
|
||||
LCDate_S3 *lc_date = static_cast<LCDate_S3 *>(find_first("Date"));
|
||||
if ((lc_days && lc_date) || (!lc_days && !lc_date)) {
|
||||
return false;
|
||||
void LCTransition_S3::decode_xml(XMLObj *obj)
|
||||
{
|
||||
bool has_days = RGWXMLDecoder::decode_xml("Days", days, obj);
|
||||
bool has_date = RGWXMLDecoder::decode_xml("Date", date, obj);
|
||||
if ((has_days && has_date) || (!has_days && !has_date)) {
|
||||
throw RGWXMLDecoder::err("bad Transition section");
|
||||
}
|
||||
if (lc_days) {
|
||||
days = lc_days->get_data();
|
||||
} else {
|
||||
date = lc_date->get_data();
|
||||
|
||||
if (has_date && !check_date(date)) {
|
||||
//We need return xml error according to S3
|
||||
if (!check_date(date)) {
|
||||
return false;
|
||||
}
|
||||
throw RGWXMLDecoder::err("bad Date in Transition section");
|
||||
}
|
||||
LCStorageClass_S3 *lc_storage_class = static_cast<LCStorageClass_S3 *>(find_first("StorageClass"));
|
||||
if (!lc_storage_class) {
|
||||
return false;
|
||||
|
||||
if (!RGWXMLDecoder::decode_xml("StorageClass", storage_class, obj)) {
|
||||
throw RGWXMLDecoder::err("missing StorageClass in Transition section");
|
||||
}
|
||||
storage_class = lc_storage_class->get_data();
|
||||
if (storage_class.compare("STANDARD_IA") != 0 && storage_class.compare("ONEZONE_IA") != 0 &&
|
||||
storage_class.compare("GLACIER") != 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LCNoncurTransition_S3::xml_end(const char* el) {
|
||||
LCDays_S3 *lc_noncur_days = static_cast<LCDays_S3 *>(find_first("NoncurrentDays"));
|
||||
if (!lc_noncur_days) {
|
||||
return false;
|
||||
void LCTransition_S3::dump_xml(Formatter *f) const {
|
||||
if (!days.empty()) {
|
||||
encode_xml("Days", days, f);
|
||||
} else {
|
||||
encode_xml("Date", date, f);
|
||||
}
|
||||
days = lc_noncur_days->get_data();
|
||||
LCStorageClass_S3 *lc_storage_class = static_cast<LCStorageClass_S3 *>(find_first("StorageClass"));
|
||||
if (!lc_storage_class) {
|
||||
return false;
|
||||
}
|
||||
storage_class = lc_storage_class->get_data();
|
||||
if (storage_class.compare("STANDARD_IA") != 0 && storage_class.compare("ONEZONE_IA") != 0 &&
|
||||
storage_class.compare("GLACIER") != 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
encode_xml("StorageClass", storage_class, f);
|
||||
}
|
||||
|
||||
void LCNoncurTransition_S3::decode_xml(XMLObj *obj)
|
||||
{
|
||||
if (!RGWXMLDecoder::decode_xml("NoncurrentDays", days, obj)) {
|
||||
throw RGWXMLDecoder::err("missing NoncurrentDays in NoncurrentVersionTransition section");
|
||||
}
|
||||
if (!RGWXMLDecoder::decode_xml("StorageClass", storage_class, obj)) {
|
||||
throw RGWXMLDecoder::err("missing StorageClass in NoncurrentVersionTransition section");
|
||||
}
|
||||
}
|
||||
|
||||
bool LCRule_S3::xml_end(const char *el) {
|
||||
LCID_S3 *lc_id;
|
||||
LCPrefix_S3 *lc_prefix;
|
||||
LCStatus_S3 *lc_status;
|
||||
LCExpiration_S3 *lc_expiration;
|
||||
LCNoncurExpiration_S3 *lc_noncur_expiration;
|
||||
LCMPExpiration_S3 *lc_mp_expiration;
|
||||
LCFilter_S3 *lc_filter;
|
||||
LCTransition_S3 *lc_transition;
|
||||
LCNoncurTransition_S3 *lc_noncur_transition;
|
||||
void LCNoncurTransition_S3::dump_xml(Formatter *f) const
|
||||
{
|
||||
encode_xml("NoncurrentDays", days, f);
|
||||
encode_xml("StorageClass", storage_class, f);
|
||||
}
|
||||
|
||||
void LCRule_S3::decode_xml(XMLObj *obj)
|
||||
{
|
||||
id.clear();
|
||||
prefix.clear();
|
||||
status.clear();
|
||||
@ -181,19 +195,12 @@ bool LCRule_S3::xml_end(const char *el) {
|
||||
// S3 generates a 48 bit random ID, maybe we could generate shorter IDs
|
||||
static constexpr auto LC_ID_LENGTH = 48;
|
||||
|
||||
lc_id = static_cast<LCID_S3 *>(find_first("ID"));
|
||||
if (lc_id){
|
||||
id = lc_id->get_data();
|
||||
} else {
|
||||
if (!RGWXMLDecoder::decode_xml("ID", id, obj)) {
|
||||
gen_rand_alphanumeric_lower(cct, &id, LC_ID_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
lc_filter = static_cast<LCFilter_S3 *>(find_first("Filter"));
|
||||
|
||||
if (lc_filter){
|
||||
filter = *lc_filter;
|
||||
} else {
|
||||
LCFilter_S3 filter_s3;
|
||||
if (!RGWXMLDecoder::decode_xml("Filter", filter_s3, obj)) {
|
||||
// Ideally the following code should be deprecated and we should return
|
||||
// False here, The new S3 LC configuration xml spec. makes Filter mandatory
|
||||
// and Prefix optional. However older clients including boto2 still generate
|
||||
@ -202,101 +209,103 @@ bool LCRule_S3::xml_end(const char *el) {
|
||||
// argument. A day will come when S3 enforces their own xml-spec, but it is
|
||||
// not this day
|
||||
|
||||
lc_prefix = static_cast<LCPrefix_S3 *>(find_first("Prefix"));
|
||||
|
||||
if (!lc_prefix){
|
||||
return false;
|
||||
if (!RGWXMLDecoder::decode_xml("Prefix", prefix, obj)) {
|
||||
throw RGWXMLDecoder::err("missing Prefix in Filter");
|
||||
}
|
||||
}
|
||||
filter = (LCFilter)filter_s3;
|
||||
|
||||
prefix = lc_prefix->get_data();
|
||||
if (!RGWXMLDecoder::decode_xml("Status", status, obj)) {
|
||||
throw RGWXMLDecoder::err("missing Status in Filter");
|
||||
}
|
||||
if (status.compare("Enabled") != 0 && status.compare("Disabled") != 0) {
|
||||
throw RGWXMLDecoder::err("bad Status in Filter");
|
||||
}
|
||||
|
||||
|
||||
lc_status = static_cast<LCStatus_S3 *>(find_first("Status"));
|
||||
if (!lc_status)
|
||||
return false;
|
||||
status = lc_status->get_data();
|
||||
if (status.compare("Enabled") != 0 && status.compare("Disabled") != 0)
|
||||
return false;
|
||||
LCExpiration_S3 s3_expiration;
|
||||
LCExpiration_S3 s3_noncur_expiration;
|
||||
LCExpiration_S3 s3_mp_expiration;
|
||||
LCFilter_S3 s3_filter;
|
||||
|
||||
lc_expiration = static_cast<LCExpiration_S3 *>(find_first("Expiration"));
|
||||
lc_noncur_expiration = static_cast<LCNoncurExpiration_S3 *>(find_first("NoncurrentVersionExpiration"));
|
||||
lc_mp_expiration = static_cast<LCMPExpiration_S3 *>(find_first("AbortIncompleteMultipartUpload"));
|
||||
bool has_expiration = RGWXMLDecoder::decode_xml("Expiration", s3_expiration, obj);
|
||||
bool has_noncur_expiration = RGWXMLDecoder::decode_xml("NoncurrentVersionExpiration", s3_noncur_expiration, obj);
|
||||
bool has_mp_expiration = RGWXMLDecoder::decode_xml("AbortIncompleteMultipartUpload", s3_mp_expiration, obj);
|
||||
|
||||
XMLObjIter iter = find("Transition");
|
||||
lc_transition = static_cast<LCTransition_S3 *>(iter.get_next());
|
||||
XMLObjIter noncur_iter = find("NoncurrentVersionTransition");
|
||||
lc_noncur_transition = static_cast<LCNoncurTransition_S3 *>(noncur_iter.get_next());
|
||||
vector<LCTransition_S3> transitions;
|
||||
vector<LCNoncurTransition_S3> noncur_transitions;
|
||||
|
||||
if (!lc_expiration && !lc_noncur_expiration && !lc_mp_expiration && !lc_transition && !lc_noncur_transition) {
|
||||
return false;
|
||||
} else {
|
||||
if (lc_expiration) {
|
||||
if (lc_expiration->has_days()) {
|
||||
expiration.set_days(lc_expiration->get_days_str());
|
||||
} else if (lc_expiration->has_date()) {
|
||||
expiration.set_date(lc_expiration->get_date());
|
||||
} else {
|
||||
dm_expiration = lc_expiration->get_dm_expiration();
|
||||
}
|
||||
}
|
||||
if (lc_noncur_expiration) {
|
||||
noncur_expiration = *lc_noncur_expiration;
|
||||
}
|
||||
if (lc_mp_expiration) {
|
||||
mp_expiration = *lc_mp_expiration;
|
||||
}
|
||||
while (lc_transition) {
|
||||
if (!add_transition(lc_transition)) {
|
||||
return false;
|
||||
}
|
||||
lc_transition = static_cast<LCTransition_S3 *>(iter.get_next());
|
||||
}
|
||||
while (lc_noncur_transition) {
|
||||
if (!add_noncur_transition(lc_noncur_transition)) {
|
||||
return false;
|
||||
}
|
||||
lc_noncur_transition = static_cast<LCNoncurTransition_S3 *>(noncur_iter.get_next());
|
||||
bool has_transition = RGWXMLDecoder::decode_xml("Transition", transitions, obj);
|
||||
bool has_noncur_transition = RGWXMLDecoder::decode_xml("NoncurrentVersionTransition", noncur_transitions, obj);
|
||||
|
||||
if (!has_expiration &&
|
||||
!has_noncur_expiration &&
|
||||
!has_mp_expiration &&
|
||||
!has_transition &&
|
||||
!has_noncur_transition) {
|
||||
throw RGWXMLDecoder::err("bad Rule");
|
||||
}
|
||||
|
||||
if (has_expiration) {
|
||||
if (s3_expiration.has_days() ||
|
||||
s3_expiration.has_date()) {
|
||||
expiration = s3_expiration;
|
||||
} else {
|
||||
dm_expiration = s3_expiration.get_dm_expiration();
|
||||
}
|
||||
}
|
||||
if (has_noncur_expiration) {
|
||||
noncur_expiration = s3_noncur_expiration;
|
||||
}
|
||||
if (has_mp_expiration) {
|
||||
mp_expiration = s3_mp_expiration;
|
||||
}
|
||||
for (auto& t : transitions) {
|
||||
if (!add_transition(&t)) {
|
||||
throw RGWXMLDecoder::err("Failed to add transition");
|
||||
}
|
||||
}
|
||||
for (auto& t : noncur_transitions) {
|
||||
if (!add_noncur_transition(&t)) {
|
||||
throw RGWXMLDecoder::err("Failed to add non-current version transition");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void LCRule_S3::to_xml(ostream& out) {
|
||||
out << "<Rule>" ;
|
||||
out << "<ID>" << id << "</ID>";
|
||||
void LCRule_S3::dump_xml(Formatter *f) const {
|
||||
encode_xml("ID", id, f);
|
||||
// In case of an empty filter and an empty Prefix, we defer to Prefix.
|
||||
if (!filter.empty()) {
|
||||
LCFilter_S3& lc_filter = static_cast<LCFilter_S3&>(filter);
|
||||
lc_filter.to_xml(out);
|
||||
const LCFilter_S3& lc_filter = static_cast<const LCFilter_S3&>(filter);
|
||||
encode_xml("Filter", lc_filter, f);
|
||||
} else {
|
||||
out << "<Prefix>" << prefix << "</Prefix>";
|
||||
encode_xml("Prefix", prefix, f);
|
||||
}
|
||||
out << "<Status>" << status << "</Status>";
|
||||
encode_xml("Status", status, f);
|
||||
if (!expiration.empty() || dm_expiration) {
|
||||
LCExpiration_S3 expir(expiration.get_days_str(), expiration.get_date(), dm_expiration);
|
||||
expir.to_xml(out);
|
||||
encode_xml("Expiration", expir, f);
|
||||
}
|
||||
if (!noncur_expiration.empty()) {
|
||||
LCNoncurExpiration_S3& noncur_expir = static_cast<LCNoncurExpiration_S3&>(noncur_expiration);
|
||||
noncur_expir.to_xml(out);
|
||||
const LCNoncurExpiration_S3& noncur_expir = static_cast<const LCNoncurExpiration_S3&>(noncur_expiration);
|
||||
encode_xml("NoncurrentVersionExpiration", noncur_expir, f);
|
||||
}
|
||||
if (!mp_expiration.empty()) {
|
||||
LCMPExpiration_S3& mp_expir = static_cast<LCMPExpiration_S3&>(mp_expiration);
|
||||
mp_expir.to_xml(out);
|
||||
const LCMPExpiration_S3& mp_expir = static_cast<const LCMPExpiration_S3&>(mp_expiration);
|
||||
encode_xml("AbortIncompleteMultipartUpload", mp_expir, f);
|
||||
}
|
||||
if (!transitions.empty()) {
|
||||
for (auto &elem : transitions) {
|
||||
LCTransition_S3& tran = static_cast<LCTransition_S3&>(elem.second);
|
||||
tran.to_xml(out);
|
||||
const LCTransition_S3& tran = static_cast<const LCTransition_S3&>(elem.second);
|
||||
encode_xml("Transition", tran, f);
|
||||
}
|
||||
}
|
||||
if (!noncur_transitions.empty()) {
|
||||
for (auto &elem : noncur_transitions) {
|
||||
LCNoncurTransition_S3& noncur_tran = static_cast<LCNoncurTransition_S3&>(elem.second);
|
||||
noncur_tran.to_xml(out);
|
||||
const LCNoncurTransition_S3& noncur_tran = static_cast<const LCNoncurTransition_S3&>(elem.second);
|
||||
encode_xml("NoncurrentVersionTransition", noncur_tran, f);
|
||||
}
|
||||
}
|
||||
out << "</Rule>";
|
||||
}
|
||||
|
||||
int RGWLifecycleConfiguration_S3::rebuild(RGWRados *store, RGWLifecycleConfiguration& dest)
|
||||
@ -316,58 +325,11 @@ int RGWLifecycleConfiguration_S3::rebuild(RGWRados *store, RGWLifecycleConfigura
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RGWLifecycleConfiguration_S3::dump_xml(Formatter *f) const
|
||||
{
|
||||
f->open_object_section_in_ns("LifecycleConfiguration", XMLNS_AWS_S3);
|
||||
|
||||
for (auto iter = rule_map.begin(); iter != rule_map.end(); ++iter) {
|
||||
const LCRule_S3& rule = static_cast<const LCRule_S3&>(iter->second);
|
||||
rule.dump_xml(f);
|
||||
}
|
||||
|
||||
f->close_section(); // Lifecycle
|
||||
}
|
||||
|
||||
XMLObj *RGWLCXMLParser_S3::alloc_obj(const char *el)
|
||||
{
|
||||
XMLObj * obj = NULL;
|
||||
if (strcmp(el, "LifecycleConfiguration") == 0) {
|
||||
obj = new RGWLifecycleConfiguration_S3(cct);
|
||||
} else if (strcmp(el, "Rule") == 0) {
|
||||
obj = new LCRule_S3(cct);
|
||||
} else if (strcmp(el, "ID") == 0) {
|
||||
obj = new LCID_S3();
|
||||
} else if (strcmp(el, "Prefix") == 0) {
|
||||
obj = new LCPrefix_S3();
|
||||
} else if (strcmp(el, "Filter") == 0) {
|
||||
obj = new LCFilter_S3();
|
||||
} else if (strcmp(el, "Status") == 0) {
|
||||
obj = new LCStatus_S3();
|
||||
} else if (strcmp(el, "Expiration") == 0) {
|
||||
obj = new LCExpiration_S3();
|
||||
} else if (strcmp(el, "Days") == 0) {
|
||||
obj = new LCDays_S3();
|
||||
} else if (strcmp(el, "Date") == 0) {
|
||||
obj = new LCDate_S3();
|
||||
} else if (strcmp(el, "ExpiredObjectDeleteMarker") == 0) {
|
||||
obj = new LCDeleteMarker_S3();
|
||||
} else if (strcmp(el, "NoncurrentVersionExpiration") == 0) {
|
||||
obj = new LCNoncurExpiration_S3();
|
||||
} else if (strcmp(el, "NoncurrentDays") == 0) {
|
||||
obj = new LCDays_S3();
|
||||
} else if (strcmp(el, "AbortIncompleteMultipartUpload") == 0) {
|
||||
obj = new LCMPExpiration_S3();
|
||||
} else if (strcmp(el, "DaysAfterInitiation") == 0) {
|
||||
obj = new LCDays_S3();
|
||||
} else if (strcmp(el, "StorageClass") == 0) {
|
||||
obj = new LCStorageClass_S3();
|
||||
} else if (strcmp(el, "Transition") == 0) {
|
||||
obj = new LCTransition_S3();
|
||||
} else if (strcmp(el, "NoncurrentVersionTransition") == 0) {
|
||||
obj = new LCNoncurTransition_S3();
|
||||
for (auto iter = rule_map.begin(); iter != rule_map.end(); ++iter) {
|
||||
const LCRule_S3& rule = static_cast<const LCRule_S3&>(iter->second);
|
||||
encode_xml("Rule", rule, f);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,134 +14,23 @@
|
||||
#include "rgw_xml.h"
|
||||
#include "rgw_tag_s3.h"
|
||||
|
||||
class LCID_S3 : public XMLObj
|
||||
class LCFilter_S3 : public LCFilter
|
||||
{
|
||||
public:
|
||||
LCID_S3() {}
|
||||
~LCID_S3() override {}
|
||||
string& to_str() { return data; }
|
||||
void dump_xml(Formatter *f) const;
|
||||
void decode_xml(XMLObj *obj);
|
||||
};
|
||||
|
||||
class LCPrefix_S3 : public XMLObj
|
||||
{
|
||||
public:
|
||||
LCPrefix_S3() {}
|
||||
~LCPrefix_S3() override {}
|
||||
string& to_str() { return data; }
|
||||
};
|
||||
|
||||
class LCFilter_S3 : public LCFilter, public XMLObj
|
||||
{
|
||||
public:
|
||||
~LCFilter_S3() override {}
|
||||
string& to_str() { return data; }
|
||||
void to_xml(ostream& out){
|
||||
out << "<Filter>";
|
||||
stringstream ss;
|
||||
if (has_prefix())
|
||||
out << "<Prefix>" << prefix << "</Prefix>";
|
||||
if (has_tags()){
|
||||
for (const auto&kv : obj_tags.get_tags()){
|
||||
ss << "<Tag>";
|
||||
ss << "<Key>" << kv.first << "</Key>";
|
||||
ss << "<Value>" << kv.second << "</Value>";
|
||||
ss << "</Tag>";
|
||||
}
|
||||
}
|
||||
|
||||
if (has_multi_condition()) {
|
||||
out << "<And>" << ss.str() << "</And>";
|
||||
} else {
|
||||
out << ss.str();
|
||||
}
|
||||
|
||||
out << "</Filter>";
|
||||
}
|
||||
void dump_xml(Formatter *f) const {
|
||||
f->open_object_section("Filter");
|
||||
if (has_multi_condition())
|
||||
f->open_object_section("And");
|
||||
if (!prefix.empty())
|
||||
encode_xml("Prefix", prefix, f);
|
||||
if (has_tags()){
|
||||
const auto& tagset_s3 = static_cast<const RGWObjTagSet_S3 &>(obj_tags);
|
||||
tagset_s3.dump_xml(f);
|
||||
}
|
||||
if (has_multi_condition())
|
||||
f->close_section(); // And;
|
||||
f->close_section(); // Filter
|
||||
}
|
||||
bool xml_end(const char *el) override;
|
||||
};
|
||||
|
||||
class LCStatus_S3 : public XMLObj
|
||||
{
|
||||
public:
|
||||
LCStatus_S3() {}
|
||||
~LCStatus_S3() override {}
|
||||
string& to_str() { return data; }
|
||||
};
|
||||
|
||||
class LCDays_S3 : public XMLObj
|
||||
{
|
||||
public:
|
||||
LCDays_S3() {}
|
||||
~LCDays_S3() override {}
|
||||
string& to_str() { return data; }
|
||||
};
|
||||
|
||||
class LCDate_S3 : public XMLObj
|
||||
{
|
||||
public:
|
||||
LCDate_S3() {}
|
||||
~LCDate_S3() override {}
|
||||
string& to_str() { return data; }
|
||||
};
|
||||
|
||||
class LCDeleteMarker_S3 : public XMLObj
|
||||
{
|
||||
public:
|
||||
LCDeleteMarker_S3() {}
|
||||
~LCDeleteMarker_S3() override {}
|
||||
string& to_str() { return data; }
|
||||
};
|
||||
|
||||
class LCExpiration_S3 : public LCExpiration, public XMLObj
|
||||
class LCExpiration_S3 : public LCExpiration
|
||||
{
|
||||
private:
|
||||
bool dm_expiration;
|
||||
bool dm_expiration{false};
|
||||
public:
|
||||
LCExpiration_S3(): dm_expiration(false) {}
|
||||
LCExpiration_S3(string _days, string _date, bool _dm_expiration) {
|
||||
days = _days;
|
||||
date = _date;
|
||||
dm_expiration = _dm_expiration;
|
||||
}
|
||||
~LCExpiration_S3() override {}
|
||||
LCExpiration_S3() {}
|
||||
LCExpiration_S3(string _days, string _date, bool _dm_expiration) : LCExpiration(_days, _date), dm_expiration(_dm_expiration) {}
|
||||
|
||||
bool xml_end(const char *el) override;
|
||||
void to_xml(ostream& out) {
|
||||
out << "<Expiration>";
|
||||
if (dm_expiration) {
|
||||
out << "<ExpiredObjectDeleteMarker>" << "true" << "</ExpiredObjectDeleteMarker>";
|
||||
} else if (!days.empty()){
|
||||
out << "<Days>" << days << "</Days>";
|
||||
} else {
|
||||
out << "<Date>" << date << "</Date>";
|
||||
}
|
||||
out << "</Expiration>";
|
||||
}
|
||||
void dump_xml(Formatter *f) const {
|
||||
f->open_object_section("Expiration");
|
||||
if (dm_expiration) {
|
||||
encode_xml("ExpiredObjectDeleteMarker", "true", f);
|
||||
} else if (!days.empty()) {
|
||||
encode_xml("Days", days, f);
|
||||
} else {
|
||||
encode_xml("Date", date, f);
|
||||
}
|
||||
f->close_section(); // Expiration
|
||||
}
|
||||
void dump_xml(Formatter *f) const;
|
||||
void decode_xml(XMLObj *obj);
|
||||
|
||||
void set_dm_expiration(bool _dm_expiration) {
|
||||
dm_expiration = _dm_expiration;
|
||||
@ -152,180 +41,67 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class LCNoncurExpiration_S3 : public LCExpiration, public XMLObj
|
||||
class LCNoncurExpiration_S3 : public LCExpiration
|
||||
{
|
||||
public:
|
||||
LCNoncurExpiration_S3() {}
|
||||
~LCNoncurExpiration_S3() override {}
|
||||
|
||||
bool xml_end(const char *el) override;
|
||||
void to_xml(ostream& out) {
|
||||
out << "<NoncurrentVersionExpiration>" << "<NoncurrentDays>" << days << "</NoncurrentDays>"<< "</NoncurrentVersionExpiration>";
|
||||
}
|
||||
void dump_xml(Formatter *f) const {
|
||||
f->open_object_section("NoncurrentVersionExpiration");
|
||||
encode_xml("NoncurrentDays", days, f);
|
||||
f->close_section();
|
||||
}
|
||||
void decode_xml(XMLObj *obj);
|
||||
void dump_xml(Formatter *f) const;
|
||||
};
|
||||
|
||||
class LCMPExpiration_S3 : public LCExpiration, public XMLObj
|
||||
class LCMPExpiration_S3 : public LCExpiration
|
||||
{
|
||||
public:
|
||||
LCMPExpiration_S3() {}
|
||||
~LCMPExpiration_S3() {}
|
||||
|
||||
bool xml_end(const char *el) override;
|
||||
void to_xml(ostream& out) {
|
||||
out << "<AbortIncompleteMultipartUpload>" << "<DaysAfterInitiation>" << days << "</DaysAfterInitiation>" << "</AbortIncompleteMultipartUpload>";
|
||||
}
|
||||
void dump_xml(Formatter *f) const {
|
||||
f->open_object_section("AbortIncompleteMultipartUpload");
|
||||
encode_xml("DaysAfterInitiation", days, f);
|
||||
f->close_section();
|
||||
}
|
||||
void decode_xml(XMLObj *obj);
|
||||
void dump_xml(Formatter *f) const;
|
||||
};
|
||||
|
||||
class LCStorageClass_S3 : public XMLObj
|
||||
{
|
||||
public:
|
||||
LCStorageClass_S3() {}
|
||||
~LCStorageClass_S3() override {}
|
||||
string& to_str() { return data; }
|
||||
};
|
||||
|
||||
class LCTransition_S3 : public LCTransition, public XMLObj
|
||||
class LCTransition_S3 : public LCTransition
|
||||
{
|
||||
public:
|
||||
LCTransition_S3() {}
|
||||
~LCTransition_S3() {}
|
||||
|
||||
bool xml_end(const char *el) override;
|
||||
void to_xml(ostream& out) {
|
||||
out << "<Transition>";
|
||||
if (!days.empty()) {
|
||||
out << "<Days>" << days << "</Days>";
|
||||
} else {
|
||||
out << "<Date>" << date << "</Date>";
|
||||
}
|
||||
out << "<StorageClass>" << storage_class << "</StorageClass>" << "</Transition>";
|
||||
}
|
||||
|
||||
void dump_xml(Formatter *f) const {
|
||||
f->open_object_section("Transition");
|
||||
if (!days.empty()) {
|
||||
encode_xml("Days", days, f);
|
||||
} else {
|
||||
encode_xml("Date", date, f);
|
||||
}
|
||||
encode_xml("StorageClass", storage_class, f);
|
||||
f->close_section();
|
||||
}
|
||||
void decode_xml(XMLObj *obj);
|
||||
void dump_xml(Formatter *f) const;
|
||||
};
|
||||
|
||||
class LCNoncurTransition_S3 : public LCTransition, public XMLObj
|
||||
class LCNoncurTransition_S3 : public LCTransition
|
||||
{
|
||||
public:
|
||||
LCNoncurTransition_S3() {}
|
||||
~LCNoncurTransition_S3() {}
|
||||
|
||||
bool xml_end(const char *el) override;
|
||||
void to_xml(ostream& out) {
|
||||
out << "<NoncurrentVersionTransition>" << "<NoncurrentDays>" << days << "</NoncurrentDays>"
|
||||
<< "<StorageClass>" << storage_class << "</StorageClass>" << "</NoncurrentVersionTransition>";
|
||||
}
|
||||
|
||||
void dump_xml(Formatter *f) const {
|
||||
f->open_object_section("NoncurrentVersionTransition");
|
||||
encode_xml("NoncurrentDays", days, f);
|
||||
encode_xml("StorageClass", storage_class, f);
|
||||
f->close_section();
|
||||
}
|
||||
void decode_xml(XMLObj *obj);
|
||||
void dump_xml(Formatter *f) const;
|
||||
};
|
||||
|
||||
|
||||
class LCRule_S3 : public LCRule, public XMLObj
|
||||
class LCRule_S3 : public LCRule
|
||||
{
|
||||
private:
|
||||
CephContext *cct;
|
||||
public:
|
||||
LCRule_S3(): cct(nullptr) {}
|
||||
explicit LCRule_S3(CephContext *_cct): cct(_cct) {}
|
||||
~LCRule_S3() override {}
|
||||
|
||||
void to_xml(ostream& out);
|
||||
bool xml_end(const char *el) override;
|
||||
bool xml_start(const char *el, const char **attr);
|
||||
void dump_xml(Formatter *f) const {
|
||||
f->open_object_section("Rule");
|
||||
encode_xml("ID", id, f);
|
||||
// In case of an empty filter and an empty Prefix, we defer to Prefix.
|
||||
if (!filter.empty()) {
|
||||
const LCFilter_S3& lc_filter = static_cast<const LCFilter_S3&>(filter);
|
||||
lc_filter.dump_xml(f);
|
||||
} else {
|
||||
encode_xml("Prefix", prefix, f);
|
||||
}
|
||||
encode_xml("Status", status, f);
|
||||
if (!expiration.empty() || dm_expiration) {
|
||||
LCExpiration_S3 expir(expiration.get_days_str(), expiration.get_date(), dm_expiration);
|
||||
expir.dump_xml(f);
|
||||
}
|
||||
if (!noncur_expiration.empty()) {
|
||||
const LCNoncurExpiration_S3& noncur_expir = static_cast<const LCNoncurExpiration_S3&>(noncur_expiration);
|
||||
noncur_expir.dump_xml(f);
|
||||
}
|
||||
if (!mp_expiration.empty()) {
|
||||
const LCMPExpiration_S3& mp_expir = static_cast<const LCMPExpiration_S3&>(mp_expiration);
|
||||
mp_expir.dump_xml(f);
|
||||
}
|
||||
if (!transitions.empty()) {
|
||||
for (auto &elem : transitions) {
|
||||
const LCTransition_S3& tran = static_cast<const LCTransition_S3&>(elem.second);
|
||||
tran.dump_xml(f);
|
||||
}
|
||||
}
|
||||
if (!noncur_transitions.empty()) {
|
||||
for (auto &elem : noncur_transitions) {
|
||||
const LCNoncurTransition_S3& noncur_tran = static_cast<const LCNoncurTransition_S3&>(elem.second);
|
||||
noncur_tran.dump_xml(f);
|
||||
}
|
||||
}
|
||||
f->close_section(); // Rule
|
||||
}
|
||||
void dump_xml(Formatter *f) const;
|
||||
void decode_xml(XMLObj *obj);
|
||||
|
||||
void set_ctx(CephContext *ctx) {
|
||||
cct = ctx;
|
||||
}
|
||||
};
|
||||
|
||||
class RGWLCXMLParser_S3 : public RGWXMLParser
|
||||
{
|
||||
CephContext *cct;
|
||||
|
||||
XMLObj *alloc_obj(const char *el) override;
|
||||
public:
|
||||
explicit RGWLCXMLParser_S3(CephContext *_cct) : cct(_cct) {}
|
||||
};
|
||||
|
||||
class RGWLifecycleConfiguration_S3 : public RGWLifecycleConfiguration, public XMLObj
|
||||
class RGWLifecycleConfiguration_S3 : public RGWLifecycleConfiguration
|
||||
{
|
||||
public:
|
||||
explicit RGWLifecycleConfiguration_S3(CephContext *_cct) : RGWLifecycleConfiguration(_cct) {}
|
||||
RGWLifecycleConfiguration_S3() : RGWLifecycleConfiguration(NULL) {}
|
||||
~RGWLifecycleConfiguration_S3() override {}
|
||||
RGWLifecycleConfiguration_S3() : RGWLifecycleConfiguration(nullptr) {}
|
||||
|
||||
bool xml_end(const char *el) override;
|
||||
|
||||
void to_xml(ostream& out) {
|
||||
out << "<LifecycleConfiguration xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\">";
|
||||
multimap<string, LCRule>::iterator iter;
|
||||
for (iter = rule_map.begin(); iter != rule_map.end(); ++iter) {
|
||||
LCRule_S3& rule = static_cast<LCRule_S3&>(iter->second);
|
||||
rule.to_xml(out);
|
||||
}
|
||||
out << "</LifecycleConfiguration>";
|
||||
}
|
||||
void decode_xml(XMLObj *obj);
|
||||
int rebuild(RGWRados *store, RGWLifecycleConfiguration& dest);
|
||||
void dump_xml(Formatter *f) const;
|
||||
};
|
||||
|
@ -5118,8 +5118,8 @@ void RGWPutLC::execute()
|
||||
{
|
||||
bufferlist bl;
|
||||
|
||||
RGWLifecycleConfiguration_S3 *config = NULL;
|
||||
RGWLCXMLParser_S3 parser(s->cct);
|
||||
RGWLifecycleConfiguration_S3 config;
|
||||
RGWXMLParser parser;
|
||||
RGWLifecycleConfiguration_S3 new_config(s->cct);
|
||||
|
||||
content_md5 = s->info.env->get("HTTP_CONTENT_MD5");
|
||||
@ -5172,20 +5172,25 @@ void RGWPutLC::execute()
|
||||
op_ret = -ERR_MALFORMED_XML;
|
||||
return;
|
||||
}
|
||||
config = static_cast<RGWLifecycleConfiguration_S3 *>(parser.find_first("LifecycleConfiguration"));
|
||||
if (!config) {
|
||||
op_ret = -ERR_MALFORMED_XML;
|
||||
|
||||
try {
|
||||
RGWXMLDecoder::decode_xml("LifecycleConfiguration", config, &parser);
|
||||
} catch (RGWXMLDecoder::err& err) {
|
||||
ldpp_dout(this, 5) << "Bad lifecycle configuration: " << err << dendl;
|
||||
op_ret = -EINVAL;
|
||||
return;
|
||||
}
|
||||
|
||||
op_ret = config->rebuild(store, new_config);
|
||||
op_ret = config.rebuild(store, new_config);
|
||||
if (op_ret < 0)
|
||||
return;
|
||||
|
||||
if (s->cct->_conf->subsys.should_gather<ceph_subsys_rgw, 15>()) {
|
||||
ldpp_dout(this, 15) << "New LifecycleConfiguration:";
|
||||
new_config.to_xml(*_dout);
|
||||
*_dout << dendl;
|
||||
XMLFormatter xf;
|
||||
new_config.dump_xml(&xf);
|
||||
stringstream ss;
|
||||
xf.flush(ss);
|
||||
ldpp_dout(this, 15) << "New LifecycleConfiguration:" << ss.str() << dendl;
|
||||
}
|
||||
|
||||
op_ret = store->get_lc()->set_bucket_config(s->bucket_info, s->bucket_attrs, &new_config);
|
||||
|
@ -402,7 +402,7 @@ void RGWGetObjTags_ObjStore_S3::send_response_data(bufferlist& bl)
|
||||
|
||||
int RGWPutObjTags_ObjStore_S3::get_params()
|
||||
{
|
||||
RGWObjTagsXMLParser parser;
|
||||
RGWXMLParser parser;
|
||||
|
||||
if (!parser.init()){
|
||||
return -EINVAL;
|
||||
@ -421,17 +421,17 @@ int RGWPutObjTags_ObjStore_S3::get_params()
|
||||
return -ERR_MALFORMED_XML;
|
||||
}
|
||||
|
||||
RGWObjTagSet_S3 *obj_tags_s3;
|
||||
RGWObjTagging_S3 *tagging;
|
||||
RGWObjTagging_S3 tagging;
|
||||
|
||||
tagging = static_cast<RGWObjTagging_S3 *>(parser.find_first("Tagging"));
|
||||
obj_tags_s3 = static_cast<RGWObjTagSet_S3 *>(tagging->find_first("TagSet"));
|
||||
if(!obj_tags_s3){
|
||||
try {
|
||||
RGWXMLDecoder::decode_xml("Tagging", tagging, &parser);
|
||||
} catch (RGWXMLDecoder::err& err) {
|
||||
ldout(s->cct, 5) << "Malformed tagging request: " << err << dendl;
|
||||
return -ERR_MALFORMED_XML;
|
||||
}
|
||||
|
||||
RGWObjTags obj_tags;
|
||||
r = obj_tags_s3->rebuild(obj_tags);
|
||||
r = tagging.rebuild(obj_tags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -1758,7 +1758,7 @@ int RGWPostObj_ObjStore_S3::get_tags()
|
||||
{
|
||||
string tags_str;
|
||||
if (part_str(parts, "tagging", &tags_str)) {
|
||||
RGWObjTagsXMLParser parser;
|
||||
RGWXMLParser parser;
|
||||
if (!parser.init()){
|
||||
ldout(s->cct, 0) << "Couldn't init RGWObjTags XML parser" << dendl;
|
||||
err_msg = "Server couldn't process the request";
|
||||
@ -1770,17 +1770,17 @@ int RGWPostObj_ObjStore_S3::get_tags()
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
RGWObjTagSet_S3 *obj_tags_s3;
|
||||
RGWObjTagging_S3 *tagging;
|
||||
RGWObjTagging_S3 tagging;
|
||||
|
||||
tagging = static_cast<RGWObjTagging_S3 *>(parser.find_first("Tagging"));
|
||||
obj_tags_s3 = static_cast<RGWObjTagSet_S3 *>(tagging->find_first("TagSet"));
|
||||
if(!obj_tags_s3){
|
||||
return -ERR_MALFORMED_XML;
|
||||
try {
|
||||
RGWXMLDecoder::decode_xml("Tagging", tagging, &parser);
|
||||
} catch (RGWXMLDecoder::err& err) {
|
||||
ldout(s->cct, 5) << "Malformed tagging request: " << err << dendl;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
RGWObjTags obj_tags;
|
||||
int r = obj_tags_s3->rebuild(obj_tags);
|
||||
int r = tagging.rebuild(obj_tags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -9,43 +9,41 @@
|
||||
|
||||
#include "rgw_tag_s3.h"
|
||||
|
||||
bool RGWObjTagEntry_S3::xml_end(const char*){
|
||||
RGWObjTagKey_S3 *key_obj = static_cast<RGWObjTagKey_S3 *>(find_first("Key"));
|
||||
RGWObjTagValue_S3 *val_obj = static_cast<RGWObjTagValue_S3 *>(find_first("Value"));
|
||||
|
||||
if (!key_obj)
|
||||
return false;
|
||||
|
||||
string s = key_obj->get_data();
|
||||
if (s.empty()){
|
||||
return false;
|
||||
}
|
||||
|
||||
key = s;
|
||||
if (val_obj) {
|
||||
val = val_obj->get_data();
|
||||
}
|
||||
|
||||
return true;
|
||||
void RGWObjTagEntry_S3::decode_xml(XMLObj *obj) {
|
||||
RGWXMLDecoder::decode_xml("Key", key, obj, true);
|
||||
RGWXMLDecoder::decode_xml("Value", val, obj, true);
|
||||
}
|
||||
|
||||
bool RGWObjTagSet_S3::xml_end(const char*){
|
||||
XMLObjIter iter = find("Tag");
|
||||
RGWObjTagEntry_S3 *tagentry = static_cast<RGWObjTagEntry_S3 *>(iter.get_next());
|
||||
while (tagentry) {
|
||||
const std::string& key = tagentry->get_key();
|
||||
const std::string& val = tagentry->get_val();
|
||||
if (!add_tag(key,val))
|
||||
return false;
|
||||
void RGWObjTagEntry_S3::dump_xml(Formatter *f) const {
|
||||
encode_xml("Key", key, f);
|
||||
encode_xml("Value", val, f);
|
||||
|
||||
tagentry = static_cast<RGWObjTagEntry_S3 *>(iter.get_next());
|
||||
if (key.empty()) {
|
||||
throw RGWXMLDecoder::err("empty key");
|
||||
}
|
||||
|
||||
if (val.empty()) {
|
||||
throw RGWXMLDecoder::err("empty val");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int RGWObjTagSet_S3::rebuild(RGWObjTags& dest){
|
||||
void RGWObjTagSet_S3::decode_xml(XMLObj *obj) {
|
||||
vector<RGWObjTagEntry_S3> entries;
|
||||
|
||||
RGWXMLDecoder::decode_xml("Tag", entries, obj, true);
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int RGWObjTagSet_S3::rebuild(RGWObjTags& dest) {
|
||||
int ret;
|
||||
for (const auto &it: tag_map){
|
||||
for (const auto &it : tag_map){
|
||||
ret = dest.check_and_add_tag(it.first, it.second);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -53,34 +51,15 @@ int RGWObjTagSet_S3::rebuild(RGWObjTags& dest){
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool RGWObjTagging_S3::xml_end(const char*){
|
||||
RGWObjTagSet_S3 *tagset = static_cast<RGWObjTagSet_S3 *> (find_first("TagSet"));
|
||||
return tagset != nullptr;
|
||||
|
||||
void RGWObjTagging_S3::decode_xml(XMLObj *obj) {
|
||||
RGWXMLDecoder::decode_xml("TagSet", tagset, obj, true);
|
||||
}
|
||||
|
||||
void RGWObjTagSet_S3::dump_xml(Formatter *f) const {
|
||||
for (const auto& tag: tag_map){
|
||||
f->open_object_section("Tag");
|
||||
f->dump_string("Key", tag.first);
|
||||
f->dump_string("Value", tag.second);
|
||||
f->close_section();
|
||||
for (const auto& tag : tag_map){
|
||||
Formatter::ObjectSection os(*f, "Tag");
|
||||
encode_xml("Key", tag.first, f);
|
||||
encode_xml("Value", tag.second, f);
|
||||
}
|
||||
}
|
||||
|
||||
XMLObj *RGWObjTagsXMLParser::alloc_obj(const char *el){
|
||||
XMLObj* obj = nullptr;
|
||||
if(strcmp(el,"Tagging") == 0) {
|
||||
obj = new RGWObjTagging_S3();
|
||||
} else if (strcmp(el,"TagSet") == 0) {
|
||||
obj = new RGWObjTagSet_S3();
|
||||
} else if (strcmp(el,"Tag") == 0) {
|
||||
obj = new RGWObjTagEntry_S3();
|
||||
} else if (strcmp(el,"Key") == 0) {
|
||||
obj = new RGWObjTagKey_S3();
|
||||
} else if (strcmp(el,"Value") == 0) {
|
||||
obj = new RGWObjTagValue_S3();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
@ -14,15 +14,7 @@
|
||||
#include "rgw_tag.h"
|
||||
#include "rgw_xml.h"
|
||||
|
||||
struct RGWObjTagKey_S3: public XMLObj
|
||||
{
|
||||
};
|
||||
|
||||
struct RGWObjTagValue_S3: public XMLObj
|
||||
{
|
||||
};
|
||||
|
||||
class RGWObjTagEntry_S3: public XMLObj
|
||||
class RGWObjTagEntry_S3
|
||||
{
|
||||
std::string key;
|
||||
std::string val;
|
||||
@ -31,32 +23,31 @@ public:
|
||||
RGWObjTagEntry_S3(const std::string &k, const std::string &v):key(k),val(v) {};
|
||||
~RGWObjTagEntry_S3() {}
|
||||
|
||||
bool xml_end(const char*) override;
|
||||
const std::string& get_key () const { return key;}
|
||||
const std::string& get_val () const { return val;}
|
||||
//void to_xml(CephContext *cct, ostream& out) const;
|
||||
};
|
||||
const std::string& get_key () const { return key; }
|
||||
const std::string& get_val () const { return val; }
|
||||
|
||||
class RGWObjTagSet_S3: public RGWObjTags, public XMLObj
|
||||
{
|
||||
public:
|
||||
bool xml_end(const char*) override;
|
||||
void dump_xml(Formatter *f) const;
|
||||
void decode_xml(XMLObj *obj);
|
||||
};
|
||||
|
||||
class RGWObjTagSet_S3: public RGWObjTags
|
||||
{
|
||||
public:
|
||||
int rebuild(RGWObjTags& dest);
|
||||
|
||||
void dump_xml(Formatter *f) const;
|
||||
void decode_xml(XMLObj *obj);
|
||||
};
|
||||
|
||||
class RGWObjTagging_S3: public XMLObj
|
||||
class RGWObjTagging_S3
|
||||
{
|
||||
RGWObjTagSet_S3 tagset;
|
||||
public:
|
||||
bool xml_end(const char*) override;
|
||||
void decode_xml(XMLObj *obj);
|
||||
int rebuild(RGWObjTags& dest) {
|
||||
return tagset.rebuild(dest);
|
||||
}
|
||||
};
|
||||
|
||||
class RGWObjTagsXMLParser : public RGWXMLParser
|
||||
{
|
||||
XMLObj *alloc_obj(const char *el) override;
|
||||
public:
|
||||
RGWObjTagsXMLParser() {}
|
||||
~RGWObjTagsXMLParser() {}
|
||||
};
|
||||
|
||||
#endif /* RGW_TAG_S3_H */
|
||||
|
@ -120,6 +120,20 @@ find(string name)
|
||||
return iter;
|
||||
}
|
||||
|
||||
XMLObjIter XMLObj::find_first()
|
||||
{
|
||||
XMLObjIter iter;
|
||||
map<string, XMLObj *>::iterator first;
|
||||
map<string, XMLObj *>::iterator last;
|
||||
first = children.begin();
|
||||
if (first != children.end()) {
|
||||
last = children.upper_bound(first->first);
|
||||
}else
|
||||
last = children.end();
|
||||
iter.set(first, last);
|
||||
return iter;
|
||||
}
|
||||
|
||||
XMLObj *XMLObj::
|
||||
find_first(string name)
|
||||
{
|
||||
|
@ -51,6 +51,7 @@ public:
|
||||
void add_child(string el, XMLObj *obj);
|
||||
bool get_attr(string name, string& attr);
|
||||
XMLObjIter find(string name);
|
||||
XMLObjIter find_first();
|
||||
XMLObj *find_first(string name);
|
||||
|
||||
friend ostream& operator<<(ostream &out, const XMLObj &obj);
|
||||
@ -117,6 +118,11 @@ public:
|
||||
static void decode_xml(const char *name, T& val, T& default_val, XMLObj *obj);
|
||||
};
|
||||
|
||||
static inline ostream& operator<<(ostream &out, RGWXMLDecoder::err& err)
|
||||
{
|
||||
return out << err.message;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void decode_xml_obj(T& val, XMLObj *obj)
|
||||
{
|
||||
@ -155,17 +161,17 @@ void do_decode_xml_obj(list<T>& l, const string& name, XMLObj *obj)
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void do_decode_xml_obj(vector<T>& l, const string& name, XMLObj *obj)
|
||||
void decode_xml_obj(std::vector<T>& v, XMLObj *obj)
|
||||
{
|
||||
l.clear();
|
||||
v.clear();
|
||||
|
||||
XMLObjIter iter = obj->find(name);
|
||||
XMLObjIter iter = obj->find_first();
|
||||
XMLObj *o;
|
||||
|
||||
while (o = iter.get_next()) {
|
||||
while ((o = iter.get_next())) {
|
||||
T val;
|
||||
decode_xml_obj(val, o);
|
||||
l.push_back(val);
|
||||
v.push_back(val);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user