@Nullable public Blob get(BlobRef blobRef) { return blobStore.get(blobRef.getBlobId()); }
/** * Identifies if the instance is writable. The writable state is a configuration option and not representative of the * underlying storage implementation. To communicate the underlying implementations status see * {@link #isStorageAvailable()} * * @return {@code true} if the blob store is writable * @since 3.15 */ default boolean isWritable() { return getBlobStoreConfiguration().isWritable(); }
/** * Create an asset blob by hard linking to the {@code sourceFile}. * * @param sourceFile the file to be hard linked * @param headers a map of headers to be applied to the resulting blob * @param hashes the algorithms and precalculated hashes of the content * @param contentType content type * @param size precalculated size for the blob * @return {@link AssetBlob} */ public AssetBlob createByHardLinking(final Path sourceFile, final Map<String, String> headers, final Map<HashAlgorithm, HashCode> hashes, final String contentType, final long size) { return createAssetBlob( store -> store.create(sourceFile, headers, size, hashes.get(SHA1)), hashes, false, contentType); }
private void detect(final BlobStore blobStore, final Consumer<String> handler) { Stream<BlobId> blobIds = blobStore.getBlobIdStream(); blobIds.forEach(id -> { BlobAttributes attributes = blobStore.getBlobAttributes(id); if (attributes != null) { checkIfOrphaned(handler, id, attributes); } else{ log.warn("Skipping cleanup for blob {} because blob properties not found", id); } }); }
@Override public boolean isPromotable(final String blobStoreName) { BlobStore blobStore = get(blobStoreName); return blobStore != null && blobStore.isGroupable() && blobStore.isWritable() && !store.findParent(blobStore.getBlobStoreConfiguration().getName()).isPresent(); }
@Override public void close() { try { blobStore.deleteHard(blob.getId()); } catch (BlobStoreException e) { log.debug("Unable to delete blob {} in blob store {}", blob.getId(), blobStore.getBlobStoreConfiguration().getName(), e); } }
@Override @Guarded(by = STARTED) public BlobStore update(final BlobStoreConfiguration configuration) throws Exception { checkNotNull(configuration); BlobStore blobStore = get(configuration.getName()); checkNotNull(blobStore); log.debug("Updating BlobStore: {} with attributes: {}", configuration.getName(), configuration.getAttributes()); BlobStoreDescriptor blobStoreDescriptor = blobStoreDescriptors.get(configuration.getType()); blobStoreDescriptor.validateConfig(configuration); BlobStoreConfiguration currentConfig = blobStore.getBlobStoreConfiguration(); blobStore.stop(); try { blobStore.init(configuration); blobStore.start(); store.update(configuration); eventManager.post(new BlobStoreUpdatedEvent(blobStore)); } catch (Exception e) { log.error("Failed to update configuration", e); if (blobStore.isStarted()) { blobStore.stop(); } blobStore.init(currentConfig); blobStore.start(); throw new BlobStoreException("Failed to start blob store with new configuration.", null); } return blobStore; }
@Override public void check(final Repository repository, final BlobStore blobStore, final Supplier<Boolean> isCancelled) { log.info("Checking integrity of assets in repository '{}' with blob store '{}'", repository.getName(), blobStore.getBlobStoreConfiguration().getName()); ProgressLogIntervalHelper progressLogger = new ProgressLogIntervalHelper(log, 60); long processed = 0; BlobId blobId = blobRef.getBlobId(); BlobAttributes blobAttributes = blobStore.getBlobAttributes(blobId); failed++; else if (!blobDataExists(blobStore.get(blobId))){ log.error(BLOB_DATA_MISSING_FOR_ASSET, asset.name()); failed++;
@Override @Guarded(by = STARTED) public void forceDelete(final String name) throws Exception { checkNotNull(name); databaseFreezeService.checkUnfrozen("Unable to delete a BlobStore while database is frozen."); BlobStore blobStore = blobStore(name); log.debug("Deleting BlobStore: {}", name); blobStore.stop(); blobStore.remove(); untrack(name); store.delete(blobStore.getBlobStoreConfiguration()); eventManager.post(new BlobStoreDeletedEvent(blobStore)); }
@Subscribe public void on(final BlobStoreConfigurationUpdatedEvent event) { handleRemoteOnly(event, evt -> { try { // only update if tracked String name = evt.getName(); if (stores.containsKey(name)) { BlobStore blobStore = blobStore(name); blobStore.stop(); blobStore.init(event.getEntity()); blobStore.start(); } } catch (Exception e) { log.warn("update blob store from remote event failed: {}", evt.getName(), e); } }); }
private Optional<Context> buildContext(final String blobStoreName, final BlobStore blobStore, final BlobId blobId) { return Optional.of(new Context(blobStoreName, blobStore, blobId)) .map(c -> c.blob(c.blobStore.get(c.blobId, true))) .map(c -> c.blobAttributes(c.blobStore.getBlobAttributes(c.blobId))) .map(c -> c.properties(c.blobAttributes.getProperties())) .map(c -> c.repositoryName(c.properties.getProperty(HEADER_PREFIX + REPO_NAME_HEADER))) .map(c -> c.repository(repositoryManager.get(c.repositoryName))) .map(c -> c.restoreBlobStrategy(restoreBlobStrategies.get(c.repository.getFormat().getValue()))); }
@Subscribe public void on(final BlobStoreConfigurationDeletedEvent event) { handleRemoteOnly(event, evt -> { try { // only delete if tracked String name = evt.getName(); if (stores.containsKey(name)) { BlobStore blobStore = blobStore(name); blobStore.stop(); blobStore.remove(); untrack(name); } } catch (Exception e) { log.warn("delete blob store from remote event failed: {}", evt.getName(), e); } }); }
@Override protected void doStart() throws Exception { blobStore.start(); try (ODatabaseDocumentTx db = databaseInstance.get().connect()) { // register schema entityType = entityAdapter.register(db); } log.info("OrientRawBinaryStore started."); }
@Override @Guarded(by = STARTED) public BlobStore create(final BlobStoreConfiguration configuration) throws Exception { checkNotNull(configuration); log.debug("Creating BlobStore: {} with attributes: {}", configuration.getName(), configuration.getAttributes()); BlobStoreDescriptor blobStoreDescriptor = blobStoreDescriptors.get(configuration.getType()); blobStoreDescriptor.validateConfig(configuration); BlobStore blobStore = newBlobStore(configuration); try { store.create(configuration); } catch (Exception e) { try { blobStore.remove(); } catch (Exception removeException) { // if an error occurs on remove log and rethrow original to avoid losing the root cause log.error("Error removing BlobStore {} after create failed", configuration.getName(), removeException); } throw e; } track(configuration.getName(), blobStore); blobStore.start(); eventManager.post(new BlobStoreCreatedEvent(blobStore)); return blobStore; }
log.info("{}Actions will be logged, but no changes will be made.", logPrefix); for (BlobId blobId : (Iterable<BlobId>)store.getBlobIdStream()::iterator) { Optional<Context> context = buildContext(blobStoreName, store, blobId); if (context.isPresent()) { store.undelete(blobStoreUsageChecker, c.blobId, c.blobAttributes, dryRun))
@Override protected void doStop() throws Exception { blobStore.stop(); entityType = null; }
@Override protected Object execute() throws Exception { BlobStore blobStore = blobStoreManager.get(getBlobStoreField()); if (blobStore != null) { blobStore.compact(blobStoreUsageChecker); } else { log.warn("Unable to find blob store: {}", getBlobStoreField()); } return null; }
/** * Create an asset blob by copying the source blob. Throws an exception if the blob has already been deleted. * * @param blobId blobId of a blob already present in the blobstore * @param headers a map of headers to be applied to the resulting blob * @param hashes the algorithms and precalculated hashes of the content * @return {@link AssetBlob} * @since 3.1 */ public AssetBlob createByCopying(final BlobId blobId, final Map<String, String> headers, final Map<HashAlgorithm, HashCode> hashes, final boolean hashesVerified) { checkArgument(!Strings2.isBlank(headers.get(BlobStore.CONTENT_TYPE_HEADER)), "Blob content type is required"); // This might be a place where we might consider passing in a BlobRef instead of a BlobId, for a post-fabric world // where repositories could be writing/reading from multiple blob stores. return createAssetBlob( store -> store.copy(blobId, headers), hashes, hashesVerified, headers.get(BlobStore.CONTENT_TYPE_HEADER)); }
private void delete(final BlobStore blobStore) { detect(blobStore, blobId -> { log.info("Deleting orphaned blob {} from blobstore {}", blobId, blobStore.getBlobStoreConfiguration().getName()); blobStore.deleteHard(new BlobId(blobId)); }); }
@Subscribe public void on(final BlobStoreConfigurationCreatedEvent event) { handleRemoteOnly(event, evt -> { // only create if not tracked String name = evt.getName(); if (!stores.containsKey(name)) { store.list().stream() .filter(c -> c.getName().equals(name)) .findFirst() .ifPresent(c -> { try { BlobStore blobStore = newBlobStore(c); track(name, blobStore); blobStore.start(); } catch (Exception e) { log.warn("create blob store from remote event failed: {}", name, e); } }); } }); }