Skip to content

Commit cc5354e

Browse files
authored
Merge pull request ceph#43371 from liavt/master
rgw: notifications on object replication
2 parents 5d4e82b + b303ae1 commit cc5354e

File tree

5 files changed

+91
-11
lines changed

5 files changed

+91
-11
lines changed

doc/radosgw/s3-notification-compatibility.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,14 @@ Event Types
110110
+------------------------------------------------+-----------------+-------------------------------------------+
111111
| ``s3:ObjectLifecycle:Transition:NonCurrent`` | Supported, Ceph extension |
112112
+------------------------------------------------+-----------------+-------------------------------------------+
113+
| ``s3:ObjectSynced:*`` | Supported, Ceph extension |
114+
+------------------------------------------------+-----------------+-------------------------------------------+
115+
| ``s3:ObjectSynced:Create`` | Supported, Ceph Extension |
116+
+------------------------------------------------+-----------------+-------------------------------------------+
117+
| ``s3:ObjectSynced:Delete`` | Defined, Ceph extension (not generated) |
118+
+------------------------------------------------+-----------------+-------------------------------------------+
119+
| ``s3:ObjectSynced:DeletionMarkerCreated`` | Defined, Ceph extension (not generated) |
120+
+------------------------------------------------+-----------------+-------------------------------------------+
113121
| ``s3:ObjectRestore:Post`` | Not applicable to Ceph |
114122
+------------------------------------------------+-----------------+-------------------------------------------+
115123
| ``s3:ObjectRestore:Complete`` | Not applicable to Ceph |
@@ -124,6 +132,10 @@ Event Types
124132
.. note::
125133

126134
In case of multipart upload, an ``ObjectCreated:CompleteMultipartUpload`` notification will be sent at the end of the process.
135+
136+
.. note::
137+
138+
The ``s3:ObjectSynced:Create`` event is sent when an object successfully syncs to a zone. It must be explicitely set for each zone.
127139

128140
Topic Configuration
129141
-------------------

src/rgw/rgw_cr_rados.cc

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,8 @@ int RGWAsyncFetchRemoteObj::_send_request(const DoutPrefixProvider *dpp)
652652
rgw::sal::RadosObject src_obj(store, key, &bucket);
653653
rgw::sal::RadosBucket dest_bucket(store, dest_bucket_info);
654654
rgw::sal::RadosObject dest_obj(store, dest_key.value_or(key), &dest_bucket);
655+
656+
std::string etag;
655657

656658
std::optional<uint64_t> bytes_transferred;
657659
int r = store->getRados()->fetch_remote_obj(obj_ctx,
@@ -662,8 +664,8 @@ int RGWAsyncFetchRemoteObj::_send_request(const DoutPrefixProvider *dpp)
662664
&src_obj,
663665
&dest_bucket, /* dest */
664666
nullptr, /* source */
665-
dest_placement_rule,
666-
NULL, /* real_time* src_mtime, */
667+
dest_placement_rule,
668+
nullptr, /* real_time* src_mtime, */
667669
NULL, /* real_time* mtime, */
668670
NULL, /* const real_time* mod_ptr, */
669671
NULL, /* const real_time* unmod_ptr, */
@@ -677,7 +679,7 @@ int RGWAsyncFetchRemoteObj::_send_request(const DoutPrefixProvider *dpp)
677679
versioned_epoch,
678680
real_time(), /* delete_at */
679681
NULL, /* string *ptag, */
680-
NULL, /* string *petag, */
682+
&etag, /* string *petag, */
681683
NULL, /* void (*progress_cb)(off_t, void *), */
682684
NULL, /* void *progress_data*); */
683685
dpp,
@@ -690,12 +692,53 @@ int RGWAsyncFetchRemoteObj::_send_request(const DoutPrefixProvider *dpp)
690692
if (counters) {
691693
counters->inc(sync_counters::l_fetch_err, 1);
692694
}
693-
} else if (counters) {
694-
if (bytes_transferred) {
695-
counters->inc(sync_counters::l_fetch, *bytes_transferred);
696-
} else {
697-
counters->inc(sync_counters::l_fetch_not_modified);
698-
}
695+
} else {
696+
// r >= 0
697+
if (bytes_transferred) {
698+
// send notification that object was succesfully synced
699+
std::string user_id = "rgw sync";
700+
std::string req_id = "0";
701+
702+
RGWObjTags obj_tags;
703+
auto iter = attrs.find(RGW_ATTR_TAGS);
704+
if (iter != attrs.end()) {
705+
try {
706+
auto it = iter->second.cbegin();
707+
obj_tags.decode(it);
708+
} catch (buffer::error &err) {
709+
ldpp_dout(dpp, 1) << "ERROR: " << __func__ << ": caught buffer::error couldn't decode TagSet " << dendl;
710+
}
711+
}
712+
713+
// NOTE: we create a mutable copy of bucket.get_tenant as the get_notification function expects a std::string&, not const
714+
std::string tenant(dest_bucket.get_tenant());
715+
716+
std::unique_ptr<rgw::sal::Notification> notify
717+
= store->get_notification(dpp, &dest_obj, nullptr, rgw::notify::ObjectSyncedCreate,
718+
&dest_bucket, user_id,
719+
tenant,
720+
req_id, null_yield);
721+
722+
auto notify_res = static_cast<rgw::sal::RadosNotification*>(notify.get())->get_reservation();
723+
int ret = rgw::notify::publish_reserve(dpp, rgw::notify::ObjectSyncedCreate, notify_res, &obj_tags);
724+
if (ret < 0) {
725+
ldpp_dout(dpp, 1) << "ERROR: reserving notification failed, with error: " << ret << dendl;
726+
// no need to return, the sync already happened
727+
} else {
728+
ret = rgw::notify::publish_commit(&dest_obj, dest_obj.get_obj_size(), ceph::real_clock::now(), etag, dest_obj.get_instance(), rgw::notify::ObjectSyncedCreate, notify_res, dpp);
729+
if (ret < 0) {
730+
ldpp_dout(dpp, 1) << "ERROR: publishing notification failed, with error: " << ret << dendl;
731+
}
732+
}
733+
}
734+
735+
if (counters) {
736+
if (bytes_transferred) {
737+
counters->inc(sync_counters::l_fetch, *bytes_transferred);
738+
} else {
739+
counters->inc(sync_counters::l_fetch_not_modified);
740+
}
741+
}
699742
}
700743
return r;
701744
}

src/rgw/rgw_notify.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ static inline void populate_event(reservation_t& res,
686686
event.x_amz_id_2 = res.store->getRados()->host_id; // RGW on which the change was made
687687
// configurationId is filled from notification configuration
688688
event.bucket_name = res.bucket->get_name();
689-
event.bucket_ownerIdentity = res.bucket->get_owner()->get_id().id;
689+
event.bucket_ownerIdentity = res.bucket->get_owner() ? res.bucket->get_owner()->get_id().id : "";
690690
event.bucket_arn = to_string(rgw::ARN(res.bucket->get_key()));
691691
event.object_key = res.object_name ? *res.object_name : obj->get_name();
692692
event.object_size = size;

src/rgw/rgw_notify_event_type.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ namespace rgw::notify {
4242
return "s3:ObjectLifecycle:Transition:Current";
4343
case ObjectTransitionNoncurrent:
4444
return "s3:ObjectLifecycle:Transition:Noncurrent";
45+
case ObjectSynced:
46+
return "s3:ObjectSynced:*";
47+
case ObjectSyncedCreate:
48+
return "s3:ObjectSynced:Create";
49+
case ObjectSyncedDelete:
50+
return "s3:ObjectSynced:Delete";
51+
case ObjectSyncedDeletionMarkerCreated:
52+
return "s3:ObjectSynced:DeletionMarkerCreated";
4553
case UnknownEvent:
4654
return "s3:UnknownEvent";
4755
}
@@ -72,6 +80,11 @@ namespace rgw::notify {
7280
case ObjectTransitionCurrent:
7381
case ObjectTransitionNoncurrent:
7482
return "OBJECT_TRANSITION";
83+
case ObjectSynced:
84+
case ObjectSyncedCreate:
85+
case ObjectSyncedDelete:
86+
case ObjectSyncedDeletionMarkerCreated:
87+
return "OBJECT_SYNCED";
7588
case ObjectRemoved:
7689
case UnknownEvent:
7790
return "UNKNOWN_EVENT";
@@ -118,6 +131,14 @@ namespace rgw::notify {
118131
return ObjectTransitionCurrent;
119132
if (s == "s3:ObjectLifecycle:Transition:Noncurrent")
120133
return ObjectTransitionNoncurrent;
134+
if (s == "s3:ObjectSynced:*" || s == "OBJECT_SYNCED")
135+
return ObjectSynced;
136+
if (s == "s3:ObjectSynced:Create")
137+
return ObjectSyncedCreate;
138+
if (s == "s3:ObjectSynced:Delete")
139+
return ObjectSyncedDelete;
140+
if (s == "s3:ObjectSynced:DeletionMarkerCreated")
141+
return ObjectSyncedDeletionMarkerCreated;
121142
return UnknownEvent;
122143
}
123144

src/rgw/rgw_notify_event_type.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ namespace rgw::notify {
2525
ObjectTransition = 0xF000,
2626
ObjectTransitionCurrent = 0x1000,
2727
ObjectTransitionNoncurrent = 0x2000,
28-
UnknownEvent = 0x10000
28+
ObjectSynced = 0xF0000,
29+
ObjectSyncedCreate = 0x10000,
30+
ObjectSyncedDelete = 0x20000,
31+
ObjectSyncedDeletionMarkerCreated = 0x40000,
32+
UnknownEvent = 0x100000
2933
};
3034

3135
using EventTypeList = std::vector<EventType>;

0 commit comments

Comments
 (0)