2023-05-11 02:07:55 +02:00
package eu.openaire.urls_controller.models ;
import com.fasterxml.jackson.annotation.JsonInclude ;
import com.fasterxml.jackson.annotation.JsonProperty ;
import com.google.common.collect.LinkedHashMultimap ;
import com.google.common.collect.Multimaps ;
import com.google.common.collect.SetMultimap ;
import com.google.gson.Gson ;
import eu.openaire.urls_controller.util.GenericUtils ;
2024-05-30 10:52:04 +02:00
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
2023-05-11 02:07:55 +02:00
import java.util.Collection ;
2024-06-03 12:07:17 +02:00
import java.util.LinkedHashMap ;
2023-05-11 02:07:55 +02:00
import java.util.Map ;
2024-05-27 09:40:05 +02:00
import java.util.concurrent.locks.Lock ;
import java.util.concurrent.locks.ReentrantLock ;
2023-05-11 02:07:55 +02:00
@JsonInclude ( JsonInclude . Include . NON_NULL )
public class BulkImportReport {
2024-05-30 10:52:04 +02:00
private static final Logger logger = LoggerFactory . getLogger ( BulkImportReport . class ) ;
2023-05-18 16:30:40 +02:00
private static final Gson gson = new Gson ( ) ; // This is "transient" by default. It won't be included in any json object.
2023-05-11 02:07:55 +02:00
@JsonProperty
private String provenance ;
@JsonProperty
private String reportLocation ;
@JsonProperty
private String reportID ;
// This will not be serialized, since Gson cannot serialize Multimaps. Instead, it will be converted to the "simpler" map below.
transient private SetMultimap < String , String > eventsMultimap = Multimaps . synchronizedSetMultimap ( LinkedHashMultimap . create ( ) ) ;
// We need a "LinkedHashMultimap", se that the order of the keys (timestamps) stay ascending, so the final report makes sense in chronological order.
// We need for one key (timestamp) to have multiple values (events), in order to not lose events happening at the same time.
@JsonProperty
private Map < String , Collection < String > > eventsMap ;
2024-05-27 09:40:05 +02:00
transient private final Lock reportLock = new ReentrantLock ( true ) ;
2023-05-11 02:07:55 +02:00
public BulkImportReport ( String provenance , String reportLocation , String reportID ) {
this . provenance = provenance ;
this . reportLocation = reportLocation ;
this . reportID = reportID ;
}
public void addEvent ( String event ) {
2024-03-22 16:50:55 +01:00
eventsMultimap . put ( GenericUtils . getReadableCurrentTimeAndZone ( ) , event ) ; // This is synchronized.
2023-05-11 02:07:55 +02:00
}
2024-05-01 00:29:25 +02:00
/ * *
2024-05-27 09:40:05 +02:00
* Synchronize it with a lock , to avoid concurrency issues when concurrent calls are made to the same bulkImport - Report object .
2024-05-01 00:29:25 +02:00
* * /
2024-05-27 09:40:05 +02:00
public String getJsonReport ( )
2023-05-11 02:07:55 +02:00
{
2024-05-30 10:52:04 +02:00
String reportToReturn = null ;
2024-05-27 09:40:05 +02:00
reportLock . lock ( ) ;
2024-05-30 10:52:04 +02:00
try {
2024-06-03 12:07:17 +02:00
//Convert the SetMultimap<String, String> to Map<String, Collection<String>>, since Gson cannot serialize Multimaps.
eventsMap = new LinkedHashMap < > ( eventsMultimap . asMap ( ) ) ; // Make sure we use a clone of the original data, in order to avoid any exception in the "gson.toJson()" method, when at the same time another thread modifies the "eventsMultimap".
2024-05-30 10:52:04 +02:00
reportToReturn = gson . toJson ( this , BulkImportReport . class ) ;
} catch ( Exception e ) {
logger . error ( " Problem when producing the JSON-string with the BulkImportReport! | reportID: ' " + reportID + " ' " , e ) ;
} finally {
reportLock . unlock ( ) ;
}
return reportToReturn ; // It may be null.
2023-05-11 02:07:55 +02:00
}
public String getProvenance ( ) {
return provenance ;
}
public void setProvenance ( String provenance ) {
this . provenance = provenance ;
}
public String getReportLocation ( ) {
return reportLocation ;
}
public void setReportLocation ( String reportLocation ) {
this . reportLocation = reportLocation ;
}
public String getReportID ( ) {
return reportID ;
}
public void setReportID ( String reportID ) {
this . reportID = reportID ;
}
public SetMultimap < String , String > getEventsMultimap ( ) {
return eventsMultimap ;
}
public void setEventsMultimap ( SetMultimap < String , String > eventsMultimap ) {
this . eventsMultimap = eventsMultimap ;
}
public Map < String , Collection < String > > getEventsMap ( ) {
return eventsMap ;
}
public void setEventsMap ( Map < String , Collection < String > > eventsMap ) {
this . eventsMap = eventsMap ;
}
@Override
public String toString ( ) {
return " BulkImportReport{ " +
" provenance=' " + provenance + '\'' +
" , reportLocation=' " + reportLocation + '\'' +
" , reportID=' " + reportID + '\'' +
" , eventsMultimap= " + eventsMultimap +
" , eventsMap= " + eventsMap +
'}' ;
}
}