Skip to content

Commit a0d6c1b

Browse files
committed
SeriesService.addImageToSeries(): remove uploaded file when exception occurs.
Addressed to #301
1 parent ae9a557 commit a0d6c1b

8 files changed

+77
-1
lines changed

src/main/java/ru/mystamps/web/service/DatabaseImagePersistenceStrategy.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,11 @@ public ImageDto getPreview(ImageInfoDto image) {
9898
return imageDto;
9999
}
100100

101+
@Override
102+
public void removeIfPossible(ImageInfoDto image) {
103+
// It's supposed that this method will be used for removing a file when exception occurs.
104+
// In such case it's impossible to modify database because a whole transaction will be
105+
// rolled back.
106+
}
107+
101108
}

src/main/java/ru/mystamps/web/service/FilesystemImagePersistenceStrategy.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,16 @@ public ImageDto getPreview(ImageInfoDto image) {
117117
return get(previewDir, image, false);
118118
}
119119

120+
@Override
121+
public void removeIfPossible(ImageInfoDto image) {
122+
Path dest = generateFilePath(storageDir, image);
123+
try {
124+
Files.deleteIfExists(dest);
125+
} catch (Exception ex) { // NOPMD: AvoidCatchingGenericException
126+
LOG.warn("Couldn't delete file {}: {}", dest, ex.getMessage());
127+
}
128+
}
129+
120130
// protected to allow spying
121131
protected Path generateFilePath(File dir, ImageInfoDto image) {
122132
return new File(dir, generateFileName(image)).toPath();

src/main/java/ru/mystamps/web/service/ImagePersistenceStrategy.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ public interface ImagePersistenceStrategy {
2727
void savePreview(byte[] data, ImageInfoDto image);
2828
ImageDto get(ImageInfoDto image);
2929
ImageDto getPreview(ImageInfoDto image);
30+
void removeIfPossible(ImageInfoDto image);
3031
}

src/main/java/ru/mystamps/web/service/ImageService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,5 @@ public interface ImageService {
3030
ImageDto getOrCreatePreview(Integer imageId);
3131
void addToSeries(Integer seriesId, Integer imageId);
3232
List<Integer> findBySeriesId(Integer seriesId);
33+
void removeIfPossible(ImageInfoDto imageInfo);
3334
}

src/main/java/ru/mystamps/web/service/ImageServiceImpl.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,13 @@ public List<Integer> findBySeriesId(Integer seriesId) {
145145
return imageDao.findBySeriesId(seriesId);
146146
}
147147

148+
@Override
149+
public void removeIfPossible(ImageInfoDto imageInfo) {
150+
Validate.isTrue(imageInfo != null, "Image info must be non null");
151+
152+
imagePersistenceStrategy.removeIfPossible(imageInfo);
153+
}
154+
148155
private ImageDto createPreview(ImageInfoDto previewInfo, byte[] image) {
149156
try {
150157
byte[] preview = imagePreviewStrategy.createPreview(image);

src/main/java/ru/mystamps/web/service/SeriesServiceImpl.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,14 @@ public void addImageToSeries(AddImageDto dto, Integer seriesId, Integer userId)
171171

172172
ImageInfoDto imageInfo = imageService.save(dto.getImage());
173173
Integer imageId = imageInfo.getId();
174-
imageService.addToSeries(seriesId, imageId);
174+
175+
try {
176+
imageService.addToSeries(seriesId, imageId);
177+
178+
} catch (RuntimeException ex) { // NOPMD: AvoidCatchingGenericException
179+
imageService.removeIfPossible(imageInfo);
180+
throw ex;
181+
}
175182

176183
LOG.info(
177184
"Image #{} has been added to series #{} by user #{}",

src/test/groovy/ru/mystamps/web/service/ImageServiceImplTest.groovy

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,4 +318,28 @@ class ImageServiceImplTest extends Specification {
318318
result == expectedResult
319319
}
320320

321+
//
322+
// Tests for removeIfPossible()
323+
//
324+
325+
def "removeIfPossible() should throw exception when image info is null"() {
326+
when:
327+
service.removeIfPossible(null)
328+
then:
329+
thrown IllegalArgumentException
330+
}
331+
332+
@SuppressWarnings(['ClosureAsLastMethodParameter', 'UnnecessaryReturnKeyword'])
333+
def "removeIfPossible() should pass argument to strategy"() {
334+
given:
335+
ImageInfoDto expectedImageInfo = TestObjects.createImageInfoDto()
336+
when:
337+
service.removeIfPossible(expectedImageInfo)
338+
then:
339+
1 * imagePersistenceStrategy.removeIfPossible({ ImageInfoDto imageInfo ->
340+
assert imageInfo == expectedImageInfo
341+
return true
342+
})
343+
}
344+
321345
}

src/test/groovy/ru/mystamps/web/service/SeriesServiceImplTest.groovy

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,25 @@ class SeriesServiceImplTest extends Specification {
601601
})
602602
}
603603

604+
@SuppressWarnings(['ClosureAsLastMethodParameter', 'UnnecessaryReturnKeyword'])
605+
def "addImageToSeries() should remove image when exception occurs"() {
606+
given:
607+
ImageInfoDto expectedImageInfo = new ImageInfoDto(456, 'JPEG')
608+
and:
609+
imageService.addToSeries(_ as Integer, _ as Integer) >> { throw new IllegalStateException() }
610+
when:
611+
service.addImageToSeries(imageForm, 111, 222)
612+
then:
613+
imageService.save(_) >> expectedImageInfo
614+
and:
615+
1 * imageService.removeIfPossible({ ImageInfoDto imageInfo ->
616+
assert imageInfo == expectedImageInfo
617+
return true
618+
})
619+
and:
620+
thrown IllegalStateException
621+
}
622+
604623
//
605624
// Tests for countAll()
606625
//

0 commit comments

Comments
 (0)