@ParametersAreNonnullByDefault public class

BackwardCompatibleAttachmentStore

extends Object
implements AttachmentStore StreamAttachmentStore
java.lang.Object
   ↳ com.atlassian.jira.issue.attachment.BackwardCompatibleAttachmentStore

Class Overview

AttachmentStore implementation that wraps around two AttachmentStores (a file system implementation, and a remote Blobstore implementation), and handles delegating to them appropriately given dark feature flags.

Summary

Public Constructors
BackwardCompatibleAttachmentStore(AttachmentDirectoryAccessor directoryAccessor, ThumbnailAccessor thumbnailAccessor, StoreAttachmentBeanMapper storeAttachmentBeanMapper, CachedBackwardCompatibleStoreAdapterProvider backwardCompatibleStoreAdapterProvider, AttachmentKeyMapper attachmentKeyMapper, ProjectManager projectManager)
Public Methods
void checkValidAttachmentDirectory(Issue issue)
Checks that the Attachment directory of the given issue is right to go - writable, accessible etc.
void checkValidTemporaryAttachmentDirectory()
Checks that the temporary directory for attachment uploads is right to go - writable, accessible etc.
@Nonnull Promise<Attachment> copy(Attachment originalAttachment, Attachment metaData, String newIssueKey)
Copy an attachment to another issue.
Promise<Unit> copyAttachment(AttachmentKey sourceAttachmentKey, AttachmentKey newAttachmentKey)
Copies attachment identified by oldAttachmentKey to be identified also by newAttachmentKey.
Promise<Void> deleteAttachment(Attachment attachment)
Delete the specified attachment.
Promise<Unit> deleteAttachment(AttachmentKey attachmentKey)
Delete the attachment identified by provided attachmentKey.
Promise<Void> deleteAttachmentContainerForIssue(Issue issue)
Delete the container for attachments for a given issue.
Promise<Unit> deleteTemporaryAttachment(TemporaryAttachmentId temporaryAttachmentId)
Deletes temporary attachment created previously by putTemporaryAttachment(java.io.InputStream, long).
@Nonnull Option<ErrorCollection> errors()
Health status for this component.
Promise<Boolean> exists(AttachmentKey attachmentKey)
Checks if attachment exists.
<A> Promise<A> getAttachment(AttachmentKey attachmentKey, Function<InputStream, A> inputStreamProcessor)
Retrieve data for a given attachment.
<A> Promise<A> getAttachment(Attachment metaData, Function<InputStream, A> inputStreamProcessor)
Retrieve data for a given attachment.
<A> Promise<A> getAttachmentData(AttachmentKey attachmentKey, Function<AttachmentGetData, A> attachmentGetDataProcessor)
Retrieve data for a given attachment.
File getAttachmentDirectory(Issue issue, boolean createDirectory)
Returns the physical directory of the attachments for the given issue.
File getAttachmentDirectory(String issueKey)
File getAttachmentDirectory(Issue issue)
Returns the physical directory of the attachments for the given issue.
File getAttachmentDirectory(String attachmentDirectory, String projectKey, String issueKey)
Get the attachment directory for the given attachment base directory, project key, and issue key.
File getAttachmentFile(Issue issue, Attachment attachment)
Returns the physical File for the given Attachment.
File getAttachmentFile(Attachment attachment)
Returns the physical File for the given Attachment.
File getAttachmentFile(AttachmentStore.AttachmentAdapter adapter, File attachmentDir)
This is intended for cases where you want more control over where the attachment actually lives and you just want something to handle the look up logic for the various possible filenames an attachment can have.
File getLegacyThumbnailFile(Attachment attachment)
Returns the old legacy file name for thumbnails.
File getTemporaryAttachmentDirectory()
@Nonnull File getThumbnailDirectory(Issue issue)
Returns the physical directory of the thumbnails for the given issue, creating if necessary.
@Nonnull File getThumbnailFile(Attachment attachment)
Just like the attachments themselves, thumbnails can succumb to file system encoding problems.
@Nonnull File getThumbnailFile(Issue issue, Attachment attachment)
Returns the file handle for the given attachment's thumbnail.
Promise<Void> move(Attachment metaData, String newIssueKey)
Moves an attachment from its current issue under a new one
Promise<Unit> moveAttachment(AttachmentKey oldAttachmentKey, AttachmentKey newAttachmentKey)
Move attachment identified by oldAttachmentKey to be identified by newAttachmentKey and will be not reachable under oldAttachmentKey anymore.
Promise<Unit> moveTemporaryToAttachment(TemporaryAttachmentId temporaryAttachmentId, AttachmentKey destinationKey)
Moving temporary attachment created by putTemporaryAttachment(java.io.InputStream, long) to real attachment.
Promise<StoreAttachmentResult> putAttachment(StoreAttachmentBean storeAttachmentBean)
Store attachment data for a given attachment.
Promise<Attachment> putAttachment(Attachment metadata, InputStream source)
Store attachment data for a given attachment.
Promise<Attachment> putAttachment(Attachment metadata, File source)
Store attachment data for a given attachment.
Promise<TemporaryAttachmentId> putTemporaryAttachment(InputStream inputStream, long size)
Creates temporaryAttachment in store which can be later moved to attachment via moveTemporaryToAttachment(TemporaryAttachmentId, AttachmentKey)
[Expand]
Inherited Methods
From class java.lang.Object
From interface com.atlassian.jira.issue.attachment.AttachmentHealth
From interface com.atlassian.jira.issue.attachment.AttachmentStore
From interface com.atlassian.jira.issue.attachment.StreamAttachmentStore

Public Constructors

public BackwardCompatibleAttachmentStore (AttachmentDirectoryAccessor directoryAccessor, ThumbnailAccessor thumbnailAccessor, StoreAttachmentBeanMapper storeAttachmentBeanMapper, CachedBackwardCompatibleStoreAdapterProvider backwardCompatibleStoreAdapterProvider, AttachmentKeyMapper attachmentKeyMapper, ProjectManager projectManager)

Public Methods

public void checkValidAttachmentDirectory (Issue issue)

Checks that the Attachment directory of the given issue is right to go - writable, accessible etc. Will create it if necessary.

Parameters
issue the issue whose attachment directory to check.

public void checkValidTemporaryAttachmentDirectory ()

Checks that the temporary directory for attachment uploads is right to go - writable, accessible etc.

@Nonnull public Promise<Attachment> copy (Attachment originalAttachment, Attachment metaData, String newIssueKey)

Copy an attachment to another issue.

Parameters
originalAttachment the original attachment.
metaData the meta data of the copied attachment.
newIssueKey the issue that the attachment will be copied to.
Returns
  • a promise of an attachment or AttachmentCopyException if there are any errors.

public Promise<Unit> copyAttachment (AttachmentKey sourceAttachmentKey, AttachmentKey newAttachmentKey)

Copies attachment identified by oldAttachmentKey to be identified also by newAttachmentKey.

Parameters
sourceAttachmentKey attachmentKey of existing attachment which should be copied
newAttachmentKey attachmentKey under which copied

public Promise<Void> deleteAttachment (Attachment attachment)

Delete the specified attachment.

Returns
  • a promise that will contain an AttachmentCleanupException in case of error.

public Promise<Unit> deleteAttachment (AttachmentKey attachmentKey)

Delete the attachment identified by provided attachmentKey.

Returns
  • a promise that will contain an AttachmentCleanupException in case of error.

public Promise<Void> deleteAttachmentContainerForIssue (Issue issue)

Delete the container for attachments for a given issue. For file systems, this means the attachment directory for that issue.

Parameters
issue The issue to delete attachments for.
Returns
  • A promise that will contain a AttachmentCleanupException if there is a problem deleting the attachment directory.

public Promise<Unit> deleteTemporaryAttachment (TemporaryAttachmentId temporaryAttachmentId)

Deletes temporary attachment created previously by putTemporaryAttachment(java.io.InputStream, long).

Parameters
temporaryAttachmentId id of temporary attachment

@Nonnull public Option<ErrorCollection> errors ()

Health status for this component. Specifically the errors that cause the attachment subsystem to fail.

Returns
  • An option of an error collection that contains error messages if there are any issues. The option will be none if there are no errors.

public Promise<Boolean> exists (AttachmentKey attachmentKey)

Checks if attachment exists.

Parameters
attachmentKey key of attachment to check for existence
Returns
  • a com.atlassian.util.concurrent.Promise to boolean result, true if attachment exists and false otherwise

public Promise<A> getAttachment (AttachmentKey attachmentKey, Function<InputStream, A> inputStreamProcessor)

Retrieve data for a given attachment.

Parameters
attachmentKey The key of attachment used to identify attachment data
inputStreamProcessor Function that processes the attachment data.
Returns
  • A promise of an object that represented the processed attachment data (i.e. from running the inputStreamProcessor over the attachment data). The promise will contain an AttachmentRuntimeException in case of error.

public Promise<A> getAttachment (Attachment metaData, Function<InputStream, A> inputStreamProcessor)

Retrieve data for a given attachment.

Parameters
metaData attachment metadata, used to determine the logical key under which to store the attachment data
inputStreamProcessor Function that processes the attachment data.
Returns
  • A promise of an object that represented the processed attachment data (i.e. from running the inputStreamProcessor over the attachment data). The promise will contain an AttachmentRuntimeException in case of error.

public Promise<A> getAttachmentData (AttachmentKey attachmentKey, Function<AttachmentGetData, A> attachmentGetDataProcessor)

Retrieve data for a given attachment. Provides more information to consumer than (@link StreamAttachmentStore#getAttachment)

Parameters
attachmentKey The key of attachment used to identify attachment data
attachmentGetDataProcessor Function that processes the attachment data.
Returns
  • A promise of an object that represented the processed attachment data (i.e. from running the inputStreamProcessor over the attachment data). The promise will contain an AttachmentRuntimeException in case of error.

public File getAttachmentDirectory (Issue issue, boolean createDirectory)

Returns the physical directory of the attachments for the given issue. This will create it if necessary.

Parameters
issue the issue whose attachment directory you want
createDirectory If true, and the directory does not currently exist, then the directory is created.
Returns
  • the issue's attachment directory

public File getAttachmentDirectory (String issueKey)

public File getAttachmentDirectory (Issue issue)

Returns the physical directory of the attachments for the given issue. This will create it if necessary.

Parameters
issue the issue whose attachment directory you want
Returns
  • The issue's attachment directory.

public File getAttachmentDirectory (String attachmentDirectory, String projectKey, String issueKey)

Get the attachment directory for the given attachment base directory, project key, and issue key.

The idea is to encapsulate all of the path-joinery magic to make future refactoring easier if we ever decide to move away from attachment-base/project-key/issue-ket

Parameters
attachmentDirectory base of attachments
projectKey the project key the issue belongs to
issueKey the issue key for the issue
Returns
  • the directory attachments for this issue live in

public File getAttachmentFile (Issue issue, Attachment attachment)

Returns the physical File for the given Attachment. This method performs better as it does not need to look up the issue object.

Parameters
issue the issue the attachment belongs to.
attachment the attachment.
Returns
  • the file.

public File getAttachmentFile (Attachment attachment)

Returns the physical File for the given Attachment. If you are calling this on multiple attachments for the same issue, consider using the overriden method that passes in the issue. Else, this goes to the database for each call.

Parameters
attachment the attachment.
Returns
  • the file.

public File getAttachmentFile (AttachmentStore.AttachmentAdapter adapter, File attachmentDir)

This is intended for cases where you want more control over where the attachment actually lives and you just want something to handle the look up logic for the various possible filenames an attachment can have.

In practice, this is just used during Project Import

Parameters
adapter it's not an attachment but it acts like one for our purposes.
attachmentDir the directory the attachments live in. This is different that the system-wide attachment directory. i.e. this would "attachments/MKY/MKY-1" and not just "attachments"
Returns
  • the actual attachment

public File getLegacyThumbnailFile (Attachment attachment)

Returns the old legacy file name for thumbnails.

http://jira.atlassian.com/browse/JRA-23311

Parameters
attachment the attachment in play
Returns
  • the full legacy thumbnail file name

public File getTemporaryAttachmentDirectory ()

@Nonnull public File getThumbnailDirectory (Issue issue)

Returns the physical directory of the thumbnails for the given issue, creating if necessary.

Parameters
issue the issue whose thumbnail directory you want
Returns
  • the issue's thumbnail directory

@Nonnull public File getThumbnailFile (Attachment attachment)

Just like the attachments themselves, thumbnails can succumb to file system encoding problems. However we are going to regenerate thumbnails by only using the new naming scheme and not the legacy one. We can't do this for attachments, but we can for thumbnails since they are ephemeral objects anyway.

http://jira.atlassian.com/browse/JRA-23311

Parameters
attachment the attachment for which to get the thumbnail file
Returns
  • a non-null file handle (the file itself might not exist)

@Nonnull public File getThumbnailFile (Issue issue, Attachment attachment)

Returns the file handle for the given attachment's thumbnail. This method performs better than getThumbnailFile(Attachment) if you already have the issue.

Parameters
issue the issue to which the attachment belongs
attachment the attachment for which to get the thumbnail file
Returns
  • a non-null file handle (the file itself might not exist)

public Promise<Void> move (Attachment metaData, String newIssueKey)

Moves an attachment from its current issue under a new one

Parameters
metaData attachment metadata, used to determine the logical key of the attachment to be moved.
newIssueKey the key of the new issue under which the attachment will reside.
Returns

public Promise<Unit> moveAttachment (AttachmentKey oldAttachmentKey, AttachmentKey newAttachmentKey)

Move attachment identified by oldAttachmentKey to be identified by newAttachmentKey and will be not reachable under oldAttachmentKey anymore.

Parameters
oldAttachmentKey the old AttachmentKey
newAttachmentKey the new AttachmentKey

public Promise<Unit> moveTemporaryToAttachment (TemporaryAttachmentId temporaryAttachmentId, AttachmentKey destinationKey)

Moving temporary attachment created by putTemporaryAttachment(java.io.InputStream, long) to real attachment.

Parameters
temporaryAttachmentId id of temporary attachment, returned by putTemporaryAttachment(java.io.InputStream, long)
destinationKey destination key of under which attachment will be identified

public Promise<StoreAttachmentResult> putAttachment (StoreAttachmentBean storeAttachmentBean)

Store attachment data for a given attachment.

Parameters
storeAttachmentBean attachment metadata, used to determine the logical key under which to store the attachment data
Returns
  • A promise of an attachment that performs the 'put' operation once the promise is claimed. The promise will contain an AttachmentRuntimeException in case of error.

public Promise<Attachment> putAttachment (Attachment metadata, InputStream source)

Store attachment data for a given attachment.

Parameters
metadata attachment metadata, used to determine the logical key under which to store the attachment data
source source data. The attachment store will close this stream when it has completed. The stream will be closed once the operation is complete.
Returns
  • A promise of an attachment that performs the 'put' operation once the promise is claimed. The promise will contain an AttachmentRuntimeException in case of error.

public Promise<Attachment> putAttachment (Attachment metadata, File source)

Store attachment data for a given attachment.

Parameters
metadata attachment metadata, used to determine the logical key under which to store the attachment data
source source data. It is assumed that the file will exist during the attachment process (i.e. relatively long lived).
Returns
  • A promise of an attachment that performs the 'put' operation once the promise is claimed.

public Promise<TemporaryAttachmentId> putTemporaryAttachment (InputStream inputStream, long size)

Creates temporaryAttachment in store which can be later moved to attachment via moveTemporaryToAttachment(TemporaryAttachmentId, AttachmentKey)

Parameters
inputStream stream to temporary attachment data
size the size of provided stream
Returns
  • returns promise to temporaryAttachmentId