Skip to content

Commit

Permalink
Merge pull request #41 from causecode/dev
Browse files Browse the repository at this point in the history
Merge dev to master
  • Loading branch information
Shivam Pandey authored Feb 4, 2019
2 parents 7e8cde9 + ecec1ab commit 800932d
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 24 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# File-Uploader Plugin (Latest 4.0.0)
# File-Uploader Plugin (Latest 4.0.1)

[![Maintainability](https://api.codeclimate.com/v1/badges/13bfee73c29ecd2ea4b2/maintainability)](https://codeclimate.com/github/causecode/grails-file-uploader/maintainability)
[![Test Coverage](https://api.codeclimate.com/v1/badges/13bfee73c29ecd2ea4b2/test_coverage)](https://codeclimate.com/github/causecode/grails-file-uploader/test_coverage)

File-Uploader Plugin >= 4.0.0 supports Grails 3.3.x (Tested with 3.3.5)
File-Uploader Plugin >= 4.0.1 supports Grails 3.3.x (Tested with 3.3.5)
File-Uploader Plugin <= 3.1.x supports Grails 3.2.x (Tested upto 3.2.5)

# For Grails 2.x refer branch [here](https://github.com/causecode/grails-file-uploader/tree/grails-2.x-master)
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ buildscript {
}
}

version "4.0.0"
version "4.0.1"
group "com.causecode.plugins"

apply plugin: "idea"
Expand Down
7 changes: 6 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# ChangeLog

## Version 4.0.0 [Unreleased]
## Version 4.0.1 [Unreleased]

### Added
- Field to store the container name in UFile domain.

## Version 4.0.0 [19-12-2018]

### Changed
- Upgraded the plugin to support grails 3.3.5
Expand Down
1 change: 1 addition & 0 deletions grails-app/conf/application.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ fileuploader {
maxSize = 1024 * 1024 * 2 // 2 MB
allowedExtensions = ["jpg", "jpeg", "gif", "png", "txt"]
path = '/tmp'
container = 'test-container'
}
}

Expand Down
8 changes: 5 additions & 3 deletions grails-app/domain/com/causecode/fileuploader/UFile.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class UFile implements Serializable {
String fileGroup
String name
String path
String containerName // Name of the cloud container.

//Contains calculated hash value of file content
String checksum
Expand Down Expand Up @@ -65,6 +66,7 @@ class UFile implements Serializable {
dateCreated bindable: false
lastUpdated bindable: false
envName bindable: false
containerName size: 3..63, nullable: true
}

static mapping = {
Expand Down Expand Up @@ -103,8 +105,8 @@ class UFile implements Serializable {
new File(path).exists()
}

String getContainer() {
containerName(Holders.flatConfig["fileuploader.groups.${fileGroup}.container"])
String getContainerFromConfig() {
containerNameFromConfig(Holders.flatConfig["fileuploader.groups.${fileGroup}.container"])
}

String getFullName() {
Expand All @@ -124,7 +126,7 @@ class UFile implements Serializable {
* @param containerName Name of the Amazon file container or Google bucket.
* @return Modified container name as described above.
*/
static String containerName(String containerName) {
static String containerNameFromConfig(String containerName) {
if (!containerName) {
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ class FileUploaderService {
FileGroup fileGroupInstance = new FileGroup(group)
ChecksumValidator checksumValidator = new ChecksumValidator(fileGroupInstance)

String containerName

if (checksumValidator.shouldCalculateChecksum()) {
UFile uFileInstance = UFile.findByChecksumAndChecksumAlgorithm(checksumValidator.getChecksum(file),
checksumValidator.algorithm)
Expand Down Expand Up @@ -100,6 +102,7 @@ class FileUploaderService {
throw new StorageConfigurationException('Provider not defined in the Config. Please define one.')
}

containerName = getContainerNameFromConfig(fileGroupInstance)
expireOn = isPublicGroup(group) ? null : new Date(new Date().time + expirationPeriod * 1000)
path = uploadFileToCloud(fileData, fileGroupInstance, tempFile)
} else {
Expand All @@ -110,7 +113,8 @@ class FileUploaderService {

UFile ufile = new UFile(
[name : fileData.fileName, size: fileData.fileSize, path: path, type: type,
extension: fileData.fileExtension, expiresOn: expireOn, fileGroup: group, provider: cdnProvider])
extension: fileData.fileExtension, expiresOn: expireOn, fileGroup: group, provider: cdnProvider,
containerName: containerName])

if (checksumValidator.shouldCalculateChecksum()) {
ufile.checksum = checksumValidator.getChecksum(file)
Expand All @@ -121,6 +125,23 @@ class FileUploaderService {
return ufile
}

/**
* This method checks if the configuration {@link FileGroup} contains the {@link String} container name.
*
* @param fileGroup {@link FileGroup}
* @return {@link String} - containerName
* @throws StorageConfigurationException - When container name is not defined.
*/
private static String getContainerNameFromConfig(FileGroup fileGroup) throws StorageConfigurationException {
String containerName = fileGroup.containerName

if (!containerName) {
throw new StorageConfigurationException('Container name not defined in the Config. Please define one.')
}

return containerName
}

/**
* Method is used to upload file to cloud provider. Then it gets the path of uploaded file
* @params fileData , fileGroupInstance, tempFile
Expand Down Expand Up @@ -177,7 +198,7 @@ class FileUploaderService {
CDNFileUploader fileUploaderInstance
try {
fileUploaderInstance = providerService.getProviderInstance(ufileInstance.provider.name())
fileUploaderInstance.deleteFile(ufileInstance.container, ufileInstance.fullName)
fileUploaderInstance.deleteFile(ufileInstance.containerFromConfig, ufileInstance.fullName)
} finally {
fileUploaderInstance?.close()
}
Expand Down Expand Up @@ -375,7 +396,7 @@ class FileUploaderService {
Boolean makePublic = isPublicGroup(uFileInstance.fileGroup)
long expirationPeriod = getExpirationPeriod(uFileInstance.fileGroup)

amazonFileUploaderInstance.updatePreviousFileMetaData(uFileInstance.container,
amazonFileUploaderInstance.updatePreviousFileMetaData(uFileInstance.containerFromConfig,
uFileInstance.fullName, makePublic, expirationPeriod)
}

Expand Down Expand Up @@ -452,13 +473,13 @@ class FileUploaderService {
CDNFileUploader fileUploaderInstance
try {
fileUploaderInstance = providerService.getProviderInstance(toCDNProvider.name())
fileUploaderInstance.uploadFile(uFile.container, downloadedFile, fileName, makePublic,
fileUploaderInstance.uploadFile(uFile.containerFromConfig, downloadedFile, fileName, makePublic,
expirationPeriod)

if (makePublic) {
savedUrlPath = fileUploaderInstance.getPermanentURL(uFile.container, fileName)
savedUrlPath = fileUploaderInstance.getPermanentURL(uFile.containerFromConfig, fileName)
} else {
savedUrlPath = fileUploaderInstance.getTemporaryURL(uFile.container, fileName,
savedUrlPath = fileUploaderInstance.getTemporaryURL(uFile.containerFromConfig, fileName,
expirationPeriod)
}
} finally {
Expand Down
4 changes: 2 additions & 2 deletions src/main/groovy/com/causecode/fileuploader/FileGroup.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,9 @@ class FileGroup {
return fileNameBuilder.toString()
}

// Method which fetches containerName from application.groovy file and returns it.
// Method which fetches container from application.groovy file and returns it.
String getContainerName() {
return UFile.containerName(this.groupConfig.container ?: this.config.container)
return UFile.containerNameFromConfig(this.groupConfig.container ?: this.config.container)
}

// Method that fetched CDNProvider from the config and returns it.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class DefaultTemporaryUrlRenewer implements TemporaryUrlRenewer {
private boolean updateExpirationPeriodAndUrl(UFile uFile) {
long expirationPeriod = getExpirationPeriod(uFile.fileGroup)

uFile.path = cdnFileUploader.getTemporaryURL(uFile.container, uFile.fullName, expirationPeriod)
uFile.path = cdnFileUploader.getTemporaryURL(uFile.containerFromConfig, uFile.fullName, expirationPeriod)
uFile.expiresOn = new Date(new Date().time + expirationPeriod * 1000)

if (NucleusUtils.save(uFile, true)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class BaseFileUploaderServiceSpecSetup extends Specification implements BaseTest
void mockFileGroupConstructor(String storageTypes) {
new FileGroup(_) >> { String group ->
fileGroupMock.groupName = group
fileGroupMock.containerName >> 'test-container'
fileGroupMock.groupConfig >> [storageTypes: storageTypes]

return fileGroupMock
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import grails.util.Holders
import groovy.json.JsonBuilder
import org.apache.commons.fileupload.disk.DiskFileItem
import org.apache.commons.validator.UrlValidator
import org.grails.plugins.codecs.HTMLCodec
import org.springframework.context.MessageSource
import org.springframework.context.i18n.LocaleContextHolder
import org.springframework.web.multipart.MultipartFile
Expand All @@ -34,7 +33,7 @@ import javax.servlet.http.Part
// Suppressed Methods counts since this class contains more than 30 methods.
@ConfineMetaClassChanges([FileUploaderService, File])
@Build([UFile, UFileMoveHistory])
@SuppressWarnings('MethodCount')
@SuppressWarnings(['MethodCount', 'FileLengthRule'])
class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup implements ServiceUnitTest<FileUploaderService>,
BuildDataTest {

Expand Down Expand Up @@ -92,6 +91,7 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup implement

new FileGroup(_) >> fileGroupMock
fileGroupMock.cdnProvider >> provider
fileGroupMock.containerName >> 'test-bucket'
fileGroupMock.groupConfig >> [storageTypes: 'CDN']

when: 'The saveFile method is called'
Expand All @@ -100,7 +100,7 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup implement
then: 'UFile instance should be successfully saved'
ufileInstancefile.provider == provider
ufileInstancefile.extension == 'txt'
ufileInstancefile.container == 'causecode-test'
ufileInstancefile.containerFromConfig == 'causecode-test'
ufileInstancefile.fileGroup == fileGroup

file.delete()
Expand All @@ -125,6 +125,7 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup implement
and: 'Mocked FileGroup class method call'
new FileGroup(_) >> fileGroupMock
fileGroupMock.cdnProvider >> CDNProvider.GOOGLE
fileGroupMock.containerName >> 'test-container'
fileGroupMock.groupConfig >> [storageTypes: 'CDN']
mockGetFileNameAndExtensions()

Expand Down Expand Up @@ -544,6 +545,7 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup implement
mockGetFileNameAndExtensions()
mockUploadFileMethod(true)
mockGetProviderInstance('google')
4 * fileGroupMock.containerName >> 'test-container'
5 * fileGroupMock.cdnProvider >> {
return
} >> {
Expand All @@ -565,6 +567,7 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup implement
then: 'Method should return instance of UFile'
result.fileGroup == 'testGoogle'
result.type == UFileType.CDN_PUBLIC
result.containerName == 'test-container'

when: 'saveFile method is hit and file belongs to StandardMultiartFile'
mockUploadFileMethod(true)
Expand Down Expand Up @@ -608,6 +611,7 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup implement

then: 'Method should return saved UFile instance'
result.id != null
assert result.containerName == null

when: 'saveFile method is called and error occurs while saving file'
result = service.saveFile('testLocal', commonsMultipartFileInstance, 'test')
Expand Down Expand Up @@ -787,6 +791,7 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup implement
and: 'Mocked FileGroup Instance'
new FileGroup(_) >> fileGroupMock
fileGroupMock.cdnProvider >> CDNProvider.GOOGLE
fileGroupMock.containerName >> 'test-container'
fileGroupMock.groupConfig >> [storageTypes: 'CDN', checksum: [calculate: true, algorithm: Algorithm.SHA1]]

and: 'The saveFile method has been already called once for given file'
Expand Down Expand Up @@ -838,5 +843,32 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup implement
Exception exception = thrown(IllegalArgumentException)
exception.message == "No enum constant ${Algorithm.canonicalName}.ABCD"
}
}

void "test saveFile method when container name is not defined in the config"() {
given: 'Instances of CommonsMultipartFile to upload'
File fileInstance = getFileInstance('/tmp/test.txt')

DiskFileItem fileItem = getDiskFileItemInstance(fileInstance)
CommonsMultipartFile commonsMultipartFileInstance = new CommonsMultipartFile(fileItem)

and: 'Mocked methods of FileGroup to return empty container name'
mockFileGroupConstructor('CDN')
fileGroupMock.containerName >> {
return null
}

fileGroupMock.cdnProvider >> {
return CDNProvider.GOOGLE
}

and: 'Mocked getFileNameAndExtensions method of fileGroupMock'
mockGetFileNameAndExtensions()

when: 'saveFile is called and container name is not defined'
service.saveFile('testGoogle', commonsMultipartFileInstance, 'test')

then: 'Method should throw StorageConfigurationException and message should match'
StorageConfigurationException exception = thrown(StorageConfigurationException)
exception.message == 'Container name not defined in the Config. Please define one.'
}
}
8 changes: 4 additions & 4 deletions src/test/groovy/com/causecode/fileuploader/UFileSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ class UFileSpec extends Specification implements BaseTestSetup, DomainUnitTest<U
given: 'Parameter variable'
String containerName = null

when: 'containerName method is called and containerName parameter has null value'
def result = UFile.containerName(containerName)
when: 'containerNameFromConfig method is called and containerNameFromConfig parameter has null value'
def result = UFile.containerNameFromConfig(containerName)

then: 'The method should return null'
result == null
Expand All @@ -132,9 +132,9 @@ class UFileSpec extends Specification implements BaseTestSetup, DomainUnitTest<U
return Environment.PRODUCTION
}

result = UFile.containerName(containerName)
result = UFile.containerNameFromConfig(containerName)

then: 'Method returns containerName'
then: 'Method returns containerNameFromConfig'
result == 'test'
}

Expand Down

0 comments on commit 800932d

Please sign in to comment.