3131import com .google .cloud .bigquery .Schema ;
3232import com .google .cloud .bigquery .Table ;
3333import com .google .cloud .bigquery .TableId ;
34+ import com .google .cloud .bigquery .TableInfo ;
3435import com .google .cloud .storage .Storage ;
3536import feast .serving .ServingAPIProto ;
3637import feast .serving .ServingAPIProto .DataFormat ;
5657import java .util .Optional ;
5758import java .util .UUID ;
5859import java .util .stream .Collectors ;
60+ import org .joda .time .Duration ;
5961import org .slf4j .Logger ;
6062
6163public class BigQueryServingService implements ServingService {
6264
65+ public static final long TEMP_TABLE_EXPIRY_DURATION_MS = Duration .standardDays (1 ).getMillis ();
6366 private static final Logger log = org .slf4j .LoggerFactory .getLogger (BigQueryServingService .class );
6467
6568 private final BigQuery bigquery ;
@@ -179,22 +182,33 @@ private Table loadEntities(DatasetSource datasetSource) {
179182 switch (datasetSource .getDatasetSourceCase ()) {
180183 case FILE_SOURCE :
181184 try {
182- String tableName = generateTemporaryTableName ();
183- log .info ("Loading entity dataset to table {}.{}.{}" , projectId , datasetId , tableName );
184- TableId tableId = TableId .of (projectId , datasetId , tableName );
185- // Currently only avro supported
185+ // Currently only AVRO format is supported
186+
186187 if (datasetSource .getFileSource ().getDataFormat () != DataFormat .DATA_FORMAT_AVRO ) {
187188 throw Status .INVALID_ARGUMENT
188- .withDescription ("Invalid file format, only avro supported" )
189+ .withDescription ("Invalid file format, only AVRO is supported. " )
189190 .asRuntimeException ();
190191 }
192+
193+ TableId tableId = TableId .of (projectId , datasetId , createTempTableName ());
194+ log .info ("Loading entity rows to: {}.{}.{}" , projectId , datasetId , tableId .getTable ());
195+
191196 LoadJobConfiguration loadJobConfiguration =
192197 LoadJobConfiguration .of (
193198 tableId , datasetSource .getFileSource ().getFileUrisList (), FormatOptions .avro ());
194199 loadJobConfiguration =
195200 loadJobConfiguration .toBuilder ().setUseAvroLogicalTypes (true ).build ();
196201 Job job = bigquery .create (JobInfo .of (loadJobConfiguration ));
197202 job .waitFor ();
203+
204+ TableInfo expiry =
205+ bigquery
206+ .getTable (tableId )
207+ .toBuilder ()
208+ .setExpirationTime (System .currentTimeMillis () + TEMP_TABLE_EXPIRY_DURATION_MS )
209+ .build ();
210+ bigquery .update (expiry );
211+
198212 loadedEntityTable = bigquery .getTable (tableId );
199213 if (!loadedEntityTable .exists ()) {
200214 throw new RuntimeException (
@@ -204,7 +218,7 @@ private Table loadEntities(DatasetSource datasetSource) {
204218 } catch (Exception e ) {
205219 log .error ("Exception has occurred in loadEntities method: " , e );
206220 throw Status .INTERNAL
207- .withDescription ("Failed to load entity dataset into store" )
221+ .withDescription ("Failed to load entity dataset into store: " + e . toString () )
208222 .withCause (e )
209223 .asRuntimeException ();
210224 }
@@ -216,20 +230,23 @@ private Table loadEntities(DatasetSource datasetSource) {
216230 }
217231 }
218232
219- private String generateTemporaryTableName () {
220- String source = String .format ("feastserving%d" , System .currentTimeMillis ());
221- String guid = UUID .nameUUIDFromBytes (source .getBytes ()).toString ();
222- String suffix = guid .substring (0 , Math .min (guid .length (), 10 )).replaceAll ("-" , "" );
223- return String .format ("temp_%s" , suffix );
224- }
225-
226233 private TableId generateUUIDs (Table loadedEntityTable ) {
227234 try {
228235 String uuidQuery =
229236 createEntityTableUUIDQuery (generateFullTableName (loadedEntityTable .getTableId ()));
230- QueryJobConfiguration queryJobConfig = QueryJobConfiguration .newBuilder (uuidQuery ).build ();
237+ QueryJobConfiguration queryJobConfig =
238+ QueryJobConfiguration .newBuilder (uuidQuery )
239+ .setDestinationTable (TableId .of (projectId , datasetId , createTempTableName ()))
240+ .build ();
231241 Job queryJob = bigquery .create (JobInfo .of (queryJobConfig ));
232242 queryJob .waitFor ();
243+ TableInfo expiry =
244+ bigquery
245+ .getTable (queryJobConfig .getDestinationTable ())
246+ .toBuilder ()
247+ .setExpirationTime (System .currentTimeMillis () + TEMP_TABLE_EXPIRY_DURATION_MS )
248+ .build ();
249+ bigquery .update (expiry );
233250 queryJobConfig = queryJob .getConfiguration ();
234251 return queryJobConfig .getDestinationTable ();
235252 } catch (InterruptedException | BigQueryException e ) {
@@ -239,4 +256,8 @@ private TableId generateUUIDs(Table loadedEntityTable) {
239256 .asRuntimeException ();
240257 }
241258 }
259+
260+ public static String createTempTableName () {
261+ return "_" + UUID .randomUUID ().toString ().replace ("-" , "" );
262+ }
242263}
0 commit comments