11using System . Text . Json ;
22using System . Text . Json . Serialization ;
33using Azure ;
4+ using System . Threading . Tasks ;
5+ using Azure . Storage . Sas ;
46using Microsoft . OneFuzz . Service . OneFuzzLib . Orm ;
57
68namespace Microsoft . OneFuzz . Service {
@@ -9,16 +11,20 @@ namespace Microsoft.OneFuzz.Service {
911 public record SignalREvent
1012 (
1113 string Target ,
12- List < EventMessage > arguments
14+ List < DownloadableEventMessage > arguments
1315 ) ;
1416
1517
1618 public interface IEvents {
1719 Async . Task SendEvent ( BaseEvent anEvent ) ;
1820
19- Async . Task QueueSignalrEvent ( EventMessage message ) ;
21+ Async . Task QueueSignalrEvent ( DownloadableEventMessage message ) ;
2022
2123 void LogEvent ( BaseEvent anEvent ) ;
24+
25+ Async . Task < OneFuzzResult < EventMessage > > GetEvent ( Guid eventId ) ;
26+ Async . Task < OneFuzzResult < DownloadableEventMessage > > GetDownloadableEvent ( Guid eventId ) ;
27+ Async . Task < DownloadableEventMessage > MakeDownloadable ( EventMessage eventMessage ) ;
2228 }
2329
2430 public class Events : IEvents {
@@ -29,63 +35,119 @@ public class Events : IEvents {
2935 private readonly ICreds _creds ;
3036 private readonly JsonSerializerOptions _options ;
3137
32- public Events ( IQueue queue , IWebhookOperations webhook , ILogTracer log , IContainers containers , ICreds creds ) {
33- _queue = queue ;
34- _webhook = webhook ;
38+ public Events ( ILogTracer log , IOnefuzzContext context ) {
39+ _queue = context . Queue ;
40+ _webhook = context . WebhookOperations ;
3541 _log = log ;
36- _containers = containers ;
37- _creds = creds ;
42+ _containers = context . Containers ;
43+ _creds = context . Creds ;
3844 _options = new JsonSerializerOptions ( EntityConverter . GetJsonSerializerOptions ( ) ) {
3945 DefaultIgnoreCondition = JsonIgnoreCondition . WhenWritingNull
4046 } ;
4147 _options . Converters . Add ( new RemoveUserInfo ( ) ) ;
4248 }
4349
44- public async Async . Task QueueSignalrEvent ( EventMessage message ) {
50+ public virtual async Async . Task QueueSignalrEvent ( DownloadableEventMessage message ) {
4551 var tags = new ( string , string ) [ ] {
4652 ( "event_type" , message . EventType . ToString ( ) ) ,
4753 ( "event_id" , message . EventId . ToString ( ) )
4854 } ;
4955 try {
50- var ev = new SignalREvent ( "events" , new List < EventMessage > ( ) { message } ) ;
56+ var ev = new SignalREvent ( "events" , new List < DownloadableEventMessage > ( ) { message } ) ;
5157 await _queue . SendMessage ( "signalr-events" , JsonSerializer . Serialize ( ev , _options ) , StorageType . Config ) ;
5258 } catch ( RequestFailedException ex ) {
5359 if ( ex . Message . Contains ( "The request body is too large" ) && message . Event is ITruncatable < BaseEvent > truncatableEvent ) {
5460 _log . WithTags ( tags ) . Warning ( $ "The EventMessage was too large for Azure Queue. Truncating event data and trying again.") ;
5561 message = message with {
5662 Event = truncatableEvent . Truncate ( 1000 )
5763 } ;
58- var ev = new SignalREvent ( "events" , new List < EventMessage > ( ) { message } ) ;
64+ var ev = new SignalREvent ( "events" , new List < DownloadableEventMessage > ( ) { message } ) ;
5965 await _queue . SendMessage ( "signalr-events" , JsonSerializer . Serialize ( ev , _options ) , StorageType . Config ) ;
6066 } else {
6167 // Not handled
6268 throw ex ;
6369 }
6470 }
65-
6671 }
6772
6873 public async Async . Task SendEvent ( BaseEvent anEvent ) {
6974 var eventType = anEvent . GetEventType ( ) ;
7075
7176 var instanceId = await _containers . GetInstanceId ( ) ;
72-
77+ var creationDate = DateTime . UtcNow ;
7378 var eventMessage = new EventMessage (
7479 Guid . NewGuid ( ) ,
7580 eventType ,
7681 anEvent ,
7782 instanceId ,
78- _creds . GetInstanceName ( )
83+ _creds . GetInstanceName ( ) ,
84+ creationDate
7985 ) ;
80- await QueueSignalrEvent ( eventMessage ) ;
81- await _webhook . SendEvent ( eventMessage ) ;
86+
87+ var downloadableEventMessage = await MakeDownloadable ( eventMessage ) ;
88+
89+ await QueueSignalrEvent ( downloadableEventMessage ) ;
90+ await _webhook . SendEvent ( downloadableEventMessage ) ;
8291 LogEvent ( anEvent ) ;
8392 }
8493
85- public void LogEvent ( BaseEvent anEvent ) {
94+ public virtual void LogEvent ( BaseEvent anEvent ) {
8695 var serializedEvent = JsonSerializer . Serialize ( anEvent , anEvent . GetType ( ) , _options ) ;
8796 _log . Info ( $ "sending event: { anEvent . GetEventType ( ) : Tag:EventType} - { serializedEvent } ") ;
8897 }
98+
99+ public async Async . Task < OneFuzzResult < EventMessage > > GetEvent ( Guid eventId ) {
100+ var blob = await _containers . GetBlob ( WellKnownContainers . Events , eventId . ToString ( ) , StorageType . Corpus ) ;
101+ if ( blob == null ) {
102+ return OneFuzzResult < EventMessage > . Error ( ErrorCode . UNABLE_TO_FIND , $ "Could not find container for event with id { eventId } ") ;
103+ }
104+
105+ var eventMessage = JsonSerializer . Deserialize < EventMessage > ( blob , _options ) ;
106+ if ( eventMessage == null ) {
107+ return OneFuzzResult < EventMessage > . Error ( ErrorCode . UNEXPECTED_DATA_SHAPE , $ "Could not deserialize event with id { eventId } ") ;
108+ }
109+
110+ return OneFuzzResult < EventMessage > . Ok ( eventMessage ) ;
111+ }
112+
113+ public async Async . Task < OneFuzzResult < DownloadableEventMessage > > GetDownloadableEvent ( Guid eventId ) {
114+ var eventMessageResult = await GetEvent ( eventId ) ;
115+ if ( ! eventMessageResult . IsOk ) {
116+ return eventMessageResult . ErrorV ;
117+ }
118+
119+ var sasUrl = await _containers . GetFileSasUrl ( WellKnownContainers . Events , eventId . ToString ( ) , StorageType . Corpus , BlobSasPermissions . Read ) ;
120+ if ( sasUrl == null ) {
121+ return OneFuzzResult < DownloadableEventMessage > . Error ( ErrorCode . UNABLE_TO_FIND , $ "Could not find container for event with id { eventId } ") ;
122+ }
123+
124+ var eventMessage = eventMessageResult . OkV ! ;
125+
126+ return OneFuzzResult < DownloadableEventMessage > . Ok ( new DownloadableEventMessage (
127+ eventMessage . EventId ,
128+ eventMessage . EventType ,
129+ eventMessage . Event ,
130+ eventMessage . InstanceId ,
131+ eventMessage . InstanceName ,
132+ eventMessage . CreatedAt ,
133+ sasUrl
134+ ) ) ;
135+ }
136+
137+ public async Task < DownloadableEventMessage > MakeDownloadable ( EventMessage eventMessage ) {
138+ await _containers . SaveBlob ( WellKnownContainers . Events , eventMessage . EventId . ToString ( ) , JsonSerializer . Serialize ( eventMessage , _options ) , StorageType . Corpus ) ;
139+ var sasUrl = await _containers . GetFileSasUrl ( WellKnownContainers . Events , eventMessage . EventId . ToString ( ) , StorageType . Corpus , BlobSasPermissions . Read ) ;
140+
141+ return new DownloadableEventMessage (
142+ eventMessage . EventId ,
143+ eventMessage . EventType ,
144+ eventMessage . Event ,
145+ eventMessage . InstanceId ,
146+ eventMessage . InstanceName ,
147+ eventMessage . CreatedAt ,
148+ sasUrl
149+ ) ;
150+ }
89151 }
90152
91153
0 commit comments