class TapeLibraryContentAddressableStorage implements ContentAddressableStorage {

    @Override
    public ObjectContent getObject(String containerName, String objectName)
        throws ContentAddressableStorageNotFoundException, ContentAddressableStorageServerException {

        LOGGER.debug(String.format("Download object %s from container %s", objectName, containerName));

        Optional<TapeObjectReferentialEntity> objectReferentialEntity;
        try {
            objectReferentialEntity = objectReferentialRepository.find(containerName, objectName);
        } catch (ObjectReferentialException e) {
            throw new ContentAddressableStorageServerException(e);
        }

        if (!objectReferentialEntity.isPresent()) {
            throw new ContentAddressableStorageNotFoundException(
                ErrorMessage.OBJECT_NOT_FOUND + containerName + "/" + objectName);
        }

        // get TARs containing the object segments
        TapeLibraryObjectStorageLocation location = objectReferentialEntity.get().getLocation();
        if (!(location instanceof TapeLibraryTarObjectStorageLocation)) {
            // TODO: 15/07/19 object is in the local FS and not yet in TAR (throw exception or read it from local FS ?)
            throw new UnsupportedOperationException("Object stored in tar. Not implemented yet");
        }

        List<TarEntryDescription> tarEntryDescriptions =
            ((TapeLibraryTarObjectStorageLocation) location).getTarEntries();

        if (tarEntryDescriptions == null || tarEntryDescriptions.isEmpty()) {
            throw new IllegalStateException("empty TAR description for object : " + containerName + "/" + objectName);
        }

        List<InputStream> inputStreams = tarEntryDescriptions.stream().
            // Supplier of entry input streams
                map(tarEntry -> entryInputStreamSupplier(containerName, objectName, tarEntry))
            .collect(Collectors.toList());

        InputStream fullInputStream = new SequenceInputStream(new Vector<>(inputStreams).elements());

        try {
            return new ObjectContent(
                new ExactDigestValidatorInputStream(
                    new ExactSizeInputStream(fullInputStream, objectReferentialEntity.get().getSize()),
                    VitamConfiguration.getDefaultDigestType(), objectReferentialEntity.get().getDigest())
                , objectReferentialEntity.get().getSize());
        } catch (IOException e) {
            throw new ContentAddressableStorageServerException(e);
        }
    }

    public  TapeLibraryContentAddressableStorage(
        BasicFileStorage basicFileStorage,
        ObjectReferentialRepository objectReferentialRepository,
        ArchiveReferentialRepository archiveReferentialRepository,
        ReadRequestReferentialRepository readRequestReferentialRepository,
        FileBucketTarCreatorManager fileBucketTarCreatorManager,
        QueueRepository readWriteQueue, TapeCatalogService tapeCatalogService,
        String outputTarStorageFolder,
        ArchiveOutputRetentionPolicy archiveOutputRetentionPolicy);

}