class RebuildAssetUploadMetadataTask extends TaskSupport {

  @Override
  protected Object execute() {
    long totalAssets = assetStore.countAssets(null);
    long processedAssets = 0;

    OIndexCursor assetCursor = assetStore.getIndex(AssetEntityAdapter.I_BUCKET_COMPONENT_NAME).cursor();
    ProgressLogIntervalHelper progressLogger = new ProgressLogIntervalHelper(log, 60);
    List<Entry<OCompositeKey, EntityId>> assets = assetStore.getNextPage(assetCursor, limit);

    if (!Iterables.isEmpty(assets) && !Strings2.isBlank(assetStore.getById(assets.get(0).getValue()).createdBy())) {
      return null;
    }

    while (assets != null && !assets.isEmpty()) {
      checkContinuation();

      Iterable<EntityId> assetIds = assets.stream().map(Entry::getValue).collect(toList());

      Collection<Asset> assetsToUpdate = stream(assetStore.getByIds(assetIds))
          .filter(asset -> Strings2.isEmpty(asset.createdBy()))
          .filter(asset -> asset.blobRef() != null).map(asset -> {
            BlobStore blobStore = blobStoreManager.get(asset.blobRef().getStore());
            Blob blob = blobStore.get(asset.blobRef().getBlobId());
            if (blob != null) {
              asset.createdBy(blob.getHeaders().get(BlobStore.CREATED_BY_HEADER));
              asset.createdByIp(blob.getHeaders().get(BlobStore.CREATED_BY_IP_HEADER));
              asset.blobCreated(blob.getMetrics().getCreationTime());
            }

            return asset;
          }).collect(toList());

      assetStore.save(assetsToUpdate);

      processedAssets += size(assetsToUpdate);
      progressLogger.info("{} / {} asset upload metadata processed in {} ms", processedAssets, totalAssets, progressLogger.getElapsed());

      assets = assetStore.getNextPage(assetCursor, limit);
    }

    progressLogger.flush();

    return null;
  }

  @Inject public  RebuildAssetUploadMetadataTask(final AssetStore assetStore,
                                        final BlobStoreManager blobStoreManager,
                                        final RebuildAssetUploadMetadataConfiguration configuration);

}