Skip to content

Commit

Permalink
Merge pull request #30 from causecode/ankit/environment-specific-ufiles
Browse files Browse the repository at this point in the history
Environment-specific UFiles feature.
  • Loading branch information
ankit-agrawal11 authored May 2, 2018
2 parents fa64d93 + 41a29e7 commit e91eed2
Show file tree
Hide file tree
Showing 22 changed files with 246 additions and 67 deletions.
29 changes: 20 additions & 9 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
docker:
# specify the version you desire here
- image: circleci/openjdk:8-jdk

# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
Expand All @@ -20,7 +20,7 @@ jobs:
# Customize the JVM maximum heap limit
JVM_OPTS: -Xmx3200m
TERM: dumb

steps:
- checkout

Expand All @@ -33,18 +33,29 @@ jobs:

- run: chmod +x ./.circleci/mavenCredsSetup.sh
- run: ./.circleci/mavenCredsSetup.sh
- run: gradle dependencies
- run: ./gradlew dependencies

- save_cache:
paths:
- ~/.m2
key: v1-dependencies-{{ checksum "build.gradle" }}

# run tests!
- run: gradle clean test
# Code climate coverage-test-reporter-id
- run: echo "export CC_TEST_REPORTER_ID=$CC_TEST_REPORTER_ID" >> $BASH_ENV

# Code climate test coverage reporter configuration
- run:
name: Setup Code Climate test-reporter
command: |
cp ./test-reporter-custom-builds/test-reporter-0.4.6-RC1-linux-amd64 ./cc-test-reporter
chmod +x ./cc-test-reporter
- run:
name: Run tests
command: |
./cc-test-reporter before-build
./gradlew clean test cc-jacoco
./cc-test-reporter format-coverage --input-type jacoco -d ./build/jacoco/jacocoXml/jacoco.xml
./cc-test-reporter upload-coverage
#run custom gradle tasks
- run: gradle cc-codenarc
- run: gradle simian
- run: gradle test cc-jacoco

- run: ./gradlew clean classes cc-codenarc
6 changes: 6 additions & 0 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: "2"

plugins:
codenarc:
enabled: true
channel: "beta"
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# File-Uploader Plugin (Latest 3.1.1)
# File-Uploader Plugin (Latest 3.1.2)

[![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)

Supported Grails 3.2.0

Expand Down
13 changes: 11 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ buildscript {
mavenCentral()
}
dependencies {
classpath "com.causecode.plugins:gradle-code-quality:1.0.1-RC1"
classpath "com.causecode.plugins:gradle-code-quality:1.0.2"
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
}
}

version "3.1.1"
version "3.1.2"
group "com.causecode.plugins"

apply plugin: "idea"
Expand Down Expand Up @@ -193,3 +193,12 @@ jar {
task wrapper(type: Wrapper) {
gradleVersion = gradleWrapperVersion
}

// Adding migration files to jar
sourceSets {
main {
resources {
srcDir 'grails-app/migrations'
}
}
}
16 changes: 15 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
# ChangeLog

## Version 3.1.1 [Unreleased]
## Version 3.1.2 [02-May-2018]

### Added
- Added environment specific UFile feature. This enables deletion of remote files only when the upload operation was
performed in the same environment.

## Modified
- Updated gradle-code-quality plugin version from 1.0.1-RC1 to 1.0.2

## Version 3.1.1 [06-April-2018]

### Added
- Functionality to disable URL renew job for installing application.

## Version 3.1.0 [08-March-2018]

### Added
- Ability to avoid duplicate file upload using checksum algorithm.

## Version 3.0.9 [28-Nov-2017]

### Database changes
Expand Down
21 changes: 17 additions & 4 deletions grails-app/domain/com/causecode/fileuploader/UFile.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ package com.causecode.fileuploader
import grails.util.Environment
import grails.util.Holders
import groovy.transform.EqualsAndHashCode
import groovy.util.logging.Slf4j

/**
* A domain class which will hold the UFile related data.
*/
@Slf4j
@EqualsAndHashCode
@SuppressWarnings(['GrailsDomainReservedSqlKeywordName', 'JavaIoPackageAccess'])
@SuppressWarnings(['GrailsDomainReservedSqlKeywordName', 'JavaIoPackageAccess', 'GrailsDomainWithServiceReference'])
class UFile implements Serializable {

private static final long serialVersionUID = 1
Expand All @@ -24,6 +26,8 @@ class UFile implements Serializable {

CDNProvider provider

String envName = Environment.current.name // development, production, test or custom environment.

Date dateUploaded = new Date()
Date expiresOn

Expand All @@ -45,7 +49,9 @@ class UFile implements Serializable {
Date dateCreated
Date lastUpdated

static transients = ['serialVersionUID']
FileUploaderService fileUploaderService

static transients = ['serialVersionUID', 'fileUploaderService']

static constraints = {
expiresOn nullable: true
Expand All @@ -58,6 +64,7 @@ class UFile implements Serializable {
checksumAlgorithm nullable: true
dateCreated bindable: false
lastUpdated bindable: false
envName bindable: false
}

static mapping = {
Expand All @@ -74,11 +81,17 @@ class UFile implements Serializable {
* Using Holder class to get service instead of injecting it as dependency injection with transient modifier.
* This prevents problem when we deserialize any instance of this class and the injected beans gets null value.
*/
Holders.applicationContext['fileUploaderService'].deleteFileForUFile(this)
if (this.envName == Environment.current.name) {
log.warn('Deleting file from CDN...')

fileUploaderService.deleteFileForUFile(this)
} else {
log.warn('File was uploaded from a different environment. Not deleting the actual file.')
}
}

String searchLink() {
Holders.applicationContext['fileUploaderService'].resolvePath(this)
fileUploaderService.resolvePath(this)
}

boolean canMoveToCDN() {
Expand Down
3 changes: 3 additions & 0 deletions grails-app/migrations/changelog-file-uploader.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
databaseChangeLog = {
include file: 'file-uploader-3.1.1-add-env-for-ufiles.groovy'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
databaseChangeLog = {

changeSet(author: 'Ankit Agrawal', id: '20180309-1') {
addColumn(tableName: 'ufile') {
column(name: 'env_name', type: 'VARCHAR')
}
}

changeSet(author: 'Ankit Agrawal', id: '20180309-2') {
grailsChange {
change {
sql.execute('update ufile set env_name = \'production\'')
sql.execute('ALTER TABLE ufile ALTER COLUMN env_name SET NOT NULL')
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class FileUploaderService {
if (uFileInstance) {
throw new DuplicateFileException(
"Checksum for file ${file.name} is ${checksumValidator.getChecksum(file)} and " +
"that checksum refers to an existing file ${uFileInstance} on server"
"that checksum refers to an existing file ${uFileInstance} on server", uFileInstance
)
}
}
Expand All @@ -110,7 +110,7 @@ class FileUploaderService {

if (storageTypes == 'CDN') {
type = UFileType.CDN_PUBLIC
fileGroupInstance.scopeFileName(userInstance, fileData, group, currentTimeMillis)
fileData.fileName = fileGroupInstance.scopeFileName(userInstance, fileData, group, currentTimeMillis)
long expirationPeriod = getExpirationPeriod(group)
File tempFile

Expand Down
5 changes: 3 additions & 2 deletions src/main/groovy/com/causecode/fileuploader/FileGroup.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,10 @@ class FileGroup {
* This method is used to modify fileName obtained from fileDataMap.
* @params userInstance, fileDataMap, group, currentTimeMillis
*
* @return scopedFileName {@link String}
* @throws StorageConfigurationException
*/
void scopeFileName(Object userInstance, Map fileDataMap, String group, Long currentTimeMillis)
String scopeFileName(Object userInstance, Map fileDataMap, String group, Long currentTimeMillis)
throws StorageConfigurationException {
String container = containerName

Expand Down Expand Up @@ -197,7 +198,7 @@ class FileGroup {
* logo-1415804444014-organizationlogo.png
*
*/
fileDataMap.fileName = fileNameBuilder.toString()
return fileNameBuilder.toString()
}

// Method which fetches containerName from application.groovy file and returns it.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,20 @@ class ChecksumValidator {
* Member variable to store the calculated hash code
*/
private String calculatedChecksum = null
private final ChecksumConfig checksumConfig
private final FileGroup fileGroup
private final ChecksumConfig CHECKSUM_CONFIG
private final FileGroup FILE_GROUP

ChecksumValidator(FileGroup fileGroup) {
this.fileGroup = fileGroup
this.checksumConfig = getChecksumConfig(fileGroup)
this.FILE_GROUP = fileGroup
this.CHECKSUM_CONFIG = getChecksumConfig(fileGroup)
}

/**
* returns if flag to calculate checksum is set or not.
* @return boolean
*/
boolean shouldCalculateChecksum() {
return this.checksumConfig.calculate
return this.CHECKSUM_CONFIG.calculate
}

/**
Expand All @@ -60,7 +60,7 @@ class ChecksumValidator {
* @return String
*/
String getAlgorithm() {
return this.checksumConfig.algorithm.toString()
return this.CHECKSUM_CONFIG.algorithm.toString()
}

/**
Expand Down Expand Up @@ -88,7 +88,7 @@ class ChecksumValidator {
*/
private String getChecksumForFile(def file) throws FileNotFoundException {
FileInputBean fileInputBean = getFileInputBeanForFile(file)
HashCalculator hashCalculator = new FileHashCalculator(fileInputBean, this.checksumConfig.algorithm)
HashCalculator hashCalculator = new FileHashCalculator(fileInputBean, this.CHECKSUM_CONFIG.algorithm)
return hashCalculator.calculateHash()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import java.security.MessageDigest
class FileHashCalculator implements HashCalculator {

//FileInputBean instance
private final FileInputBean fileInputBean
private final FileInputBean FILE_INPUT_BEAN

/**
* Constructs FileHashCalculator instance and throws FileNotFoundException If Input File Is null or not exists
Expand All @@ -33,7 +33,7 @@ class FileHashCalculator implements HashCalculator {
* @throws FileNotFoundException
*/
FileHashCalculator(FileInputBean fileInputBean) throws FileNotFoundException {
this.fileInputBean = fileInputBean
this.FILE_INPUT_BEAN = fileInputBean
validateInputs()
}

Expand All @@ -51,7 +51,7 @@ class FileHashCalculator implements HashCalculator {
* This Method validates inputs.
*/
private void validateInputs() throws FileNotFoundException {
if (!fileInputBean) {
if (!FILE_INPUT_BEAN) {
throw new FileNotFoundException('File not found')
}
}
Expand All @@ -62,9 +62,9 @@ class FileHashCalculator implements HashCalculator {
*/
@Override
String calculateHash() {
log.info "Starting checksum calculation For File ${fileInputBean.name}"
log.info "Starting checksum calculation For File ${FILE_INPUT_BEAN.name}"
MessageDigest messageDigest = MessageDigest.getInstance(this.algorithm.toString())
String hexHasString = new HexBinaryAdapter().marshal(messageDigest.digest(this.fileInputBean.bytes))
String hexHasString = new HexBinaryAdapter().marshal(messageDigest.digest(this.FILE_INPUT_BEAN.bytes))
log.info "Calculated Checksum is:- ${hexHasString}"

return hexHasString
Expand Down
Loading

0 comments on commit e91eed2

Please sign in to comment.