2727import java .util .List ;
2828import java .util .Optional ;
2929import java .util .Random ;
30+ import java .util .function .Predicate ;
3031
3132import org .apache .commons .codec .digest .DigestUtils ;
3233import org .apache .commons .io .FileUtils ;
3334import org .apache .commons .io .IOUtils ;
35+ import org .apache .commons .lang3 .RandomStringUtils ;
36+ import org .apache .commons .lang3 .StringUtils ;
3437import org .junit .Before ;
3538import org .junit .Test ;
3639
@@ -72,6 +75,22 @@ public class BinaryFieldEndpointTest extends AbstractFieldEndpointTest {
7275
7376 private static final String FIELD_NAME = "binaryField" ;
7477
78+ /**
79+ * Predicate to filter out directories belonging to the old binaryImageCache structure
80+ */
81+ private static final Predicate <Path > IS_OLD_STRUCTURE = p -> {
82+ File f = p .toFile ();
83+ return f .isDirectory () && StringUtils .length (f .getName ()) == 8 ;
84+ };
85+
86+ /**
87+ * Predicate to filter out directories belonging to the new binaryImageCache structure
88+ */
89+ private static final Predicate <Path > IS_NEW_STRUCTURE = p -> {
90+ File f = p .toFile ();
91+ return f .isDirectory () && StringUtils .length (f .getName ()) == 2 ;
92+ };
93+
7594 /**
7695 * Update the schema and add a binary field.
7796 *
@@ -362,33 +381,33 @@ public void testCacheMigration() throws IOException {
362381 }
363382 tx (tx -> {
364383 tx .binaryDao ().findAll ().runInExistingTx (tx ).forEach (binary -> {
365- String sha512sum = binary .getSHA512Sum ();
366- String [] parts = sha512sum .split ("(?<=\\ G.{8})" );
367- StringBuffer buffer = new StringBuffer ();
368- buffer .append (File .separator );
369- for (String part : parts ) {
370- buffer .append (part + File .separator );
371- }
372- String baseFolder = Paths .get (imageCache , buffer .toString ()).toString ();
373- String baseName = "image-" + randomImageManipulation ().getCacheKey () + ".jpg" ;
374384 try {
375- Files .createDirectories (Path .of (baseFolder ));
376- try (InputStream i = binary .openBlockingStream ().get (); OutputStream o = new BufferedOutputStream (new FileOutputStream (new File (Paths .get (baseFolder , baseName ).toString ())))) {
385+ Path baseFolder = createOldBinaryImageCacheStructure (imageCache , binary .getSHA512Sum ());
386+ String baseName = "image-" + randomImageManipulation ().getCacheKey () + ".jpg" ;
387+ try (InputStream i = binary .openBlockingStream ().get (); OutputStream o = new BufferedOutputStream (new FileOutputStream (new File (baseFolder .toFile (), baseName ).toString ()))) {
377388 i .transferTo (o );
378389 }
379390 } catch (Exception e ) {
380391 throw new RuntimeException (e );
381392 }
382393 });
394+
395+ // also create an empty folder structure (old structure)
396+ createOldBinaryImageCacheStructure (imageCache , createRandomSha512Sum ());
397+
398+ // and create a folder structure for a binary, which does not exist
399+ Path baseFolder = createOldBinaryImageCacheStructure (imageCache , createRandomSha512Sum ());
400+ String baseName = "image-" + randomImageManipulation ().getCacheKey () + ".jpg" ;
401+ new File (baseFolder .toFile (), baseName ).createNewFile ();
383402 });
384403 assertThat (Files .walk (Path .of (imageCache )).filter (path -> {
385404 File file = new File (path .toString ());
386405 return file .exists () && file .isFile () && file .getName ().startsWith ("image-" );
387- }).count ()).isEqualTo (4 );
406+ }).count ()).isEqualTo (5 );
388407 assertThat (Files .walk (Path .of (imageCache )).filter (path -> {
389408 File file = new File (path .toString ());
390409 return file .exists () && file .isFile () && file .getName ().endsWith (".jpg" );
391- }).count ()).isEqualTo (4 );
410+ }).count ()).isEqualTo (5 );
392411
393412 grantAdmin ();
394413 HibJob job = tx (tx -> { return tx .jobDao ().enqueueImageCacheMigration (user ()); });
@@ -408,6 +427,64 @@ public void testCacheMigration() throws IOException {
408427 File file = new File (path .toString ());
409428 return file .exists () && file .isFile () && file .getName ().endsWith (".jpg" );
410429 }).count ()).isEqualTo (4 );
430+
431+ assertThat (Files .walk (Path .of (imageCache )).filter (IS_OLD_STRUCTURE )).as ("Directories/Files in binaryImageCache of the old structure" ).isEmpty ();
432+ }
433+
434+ /**
435+ * Create a random sha512sum
436+ * @return sha512sum
437+ */
438+ protected String createRandomSha512Sum () {
439+ Buffer dummyContent = Buffer .buffer (RandomStringUtils .random (100 ));
440+ return com .gentics .mesh .util .FileUtils .hash (dummyContent ).blockingGet ();
441+ }
442+
443+ /**
444+ * Create the old folder structure for the given sha512sum
445+ * @param imageCache base image cache directory
446+ * @param sha512sum sha512sum
447+ * @return path to the deepest folder
448+ * @throws IOException
449+ */
450+ protected Path createOldBinaryImageCacheStructure (String imageCache , String sha512sum ) throws IOException {
451+ String [] parts = sha512sum .split ("(?<=\\ G.{8})" );
452+ StringBuffer buffer = new StringBuffer ();
453+ buffer .append (File .separator );
454+ for (String part : parts ) {
455+ buffer .append (part + File .separator );
456+ }
457+ Path dir = Paths .get (imageCache , buffer .toString ());
458+ Files .createDirectories (dir );
459+ return dir ;
460+ }
461+
462+ /**
463+ * Test that getting an image variant of an existing binary will put the file into the new structure of the binaryImageCache, but not the old one
464+ * @throws IOException
465+ */
466+ @ Test
467+ public void testImageCacheUsage () throws IOException {
468+ String imageCache = options ().getImageOptions ().getImageCacheDirectory ();
469+
470+ // assert that image cache directory is empty
471+ assertThat (Files .list (Path .of (imageCache ))).as ("Directories/Files in binaryImageCache" ).isEmpty ();
472+
473+ // first create an image
474+ byte [] bytes = getBinary ("/pictures/blume.jpg" );
475+ NodeResponse nodeResponse = createBinaryNode ();
476+ call (() -> client ().updateNodeBinaryField (PROJECT_NAME , nodeResponse .getUuid (), "en" , nodeResponse .getVersion (), "binary" ,
477+ new ByteArrayInputStream (bytes ), bytes .length , "blume.jpg" ,"image/jpg" ));
478+
479+ // assert that image cache directory is still empty
480+ assertThat (Files .list (Path .of (imageCache ))).as ("Directories/Files in binaryImageCache" ).isEmpty ();
481+
482+ // get a resized variant of the image
483+ call (() -> client ().downloadBinaryField (PROJECT_NAME , nodeResponse .getUuid (), "en" , "binary" , randomImageManipulation ()));
484+
485+ // assert that the image cache contains exactly two (nested) directories of the new structure, but none of the old structure
486+ assertThat (Files .walk (Path .of (imageCache )).filter (IS_OLD_STRUCTURE )).as ("Directories/Files in binaryImageCache of the old structure" ).isEmpty ();
487+ assertThat (Files .walk (Path .of (imageCache )).filter (IS_NEW_STRUCTURE )).as ("Directories/Files in binaryImageCache of the new structure" ).hasSize (2 );
411488 }
412489
413490 private ImageManipulationParameters randomImageManipulation () {
0 commit comments