From 78b7a75bdc4351e918a33a8b45e8cfa6992c5f2d Mon Sep 17 00:00:00 2001 From: Bojnourdi Date: Tue, 25 Aug 2015 15:41:43 +0200 Subject: [PATCH] The test on file are finished New class utility to convert "byte" to "hex" and vice versa "ChunkEJB" verifies the checksum data --- .../com/edf/gde/test/dao/FileDaoTest.java | 85 ++++++++++++++++++- .../src/java/com/edf/gde/common/HexUtils.java | 34 ++++++++ .../src/java/com/edf/gde/ejb/ChunkEJB.java | 38 +++++++-- .../src/java/com/edf/gde/entities/Study.java | 1 + 4 files changed, 147 insertions(+), 11 deletions(-) create mode 100644 projects/GDE_App/GDE-ejb/src/java/com/edf/gde/common/HexUtils.java diff --git a/projects/GDE-test/test/com/edf/gde/test/dao/FileDaoTest.java b/projects/GDE-test/test/com/edf/gde/test/dao/FileDaoTest.java index 0111312..ecea4e0 100644 --- a/projects/GDE-test/test/com/edf/gde/test/dao/FileDaoTest.java +++ b/projects/GDE-test/test/com/edf/gde/test/dao/FileDaoTest.java @@ -5,8 +5,11 @@ package com.edf.gde.test.dao; import com.edf.gde.base.BaseTest; import com.edf.gde.dao.FileDaoClient; +import com.edf.gde.transferables.ChunkTO; import com.edf.gde.transferables.FileTO; +import java.security.MessageDigest; import java.util.Date; +import java.util.Random; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; @@ -22,6 +25,27 @@ import org.junit.Test; */ public class FileDaoTest extends BaseTest { + protected String bytesToHex(byte[] bytes) { + char[] hexArray = "0123456789ABCDEF".toCharArray(); + char[] hexChars = new char[bytes.length * 2]; + for (int j = 0; j < bytes.length; j++) { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = hexArray[v >>> 4]; + hexChars[j * 2 + 1] = hexArray[v & 0x0F]; + } + return new String(hexChars); + } + + protected byte[] hexStringToByteArray(String s) { + int len = s.length(); + byte[] data = new byte[len / 2]; + for (int i = 0; i < len; i += 2) { + data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + + Character.digit(s.charAt(i + 1), 16)); + } + return data; + } + @BeforeClass public static void setUpClass() { } @@ -133,10 +157,11 @@ public class FileDaoTest extends BaseTest { assertEquals(createdFile.getUpdateDate(), foundFile.getUpdateDate()); passed(); } - - + + @Test public void createChunkTest() throws Exception { testName("createChunk"); + int dataSize = 1024 * 1024; /* Create a new file */ Date date = new Date(); String fileName = "/home/kavoos/chunk" + date.getTime() + ".txt"; @@ -147,6 +172,62 @@ public class FileDaoTest extends BaseTest { assertNotNull(createdFile); assertTrue(createdFile.getId() != 0); assertEquals(fileName, createdFile.getName()); + /* Create chunk */ + Random r = new Random(System.currentTimeMillis()); + byte[] buffer = new byte[dataSize]; + r.nextBytes(buffer); + MessageDigest digest = MessageDigest.getInstance("MD5"); + byte[] checkSum = digest.digest(buffer); + + ChunkTO chunkTO = new ChunkTO(); + chunkTO.setData(buffer); + chunkTO.setRank(0); + chunkTO.setChecksum(bytesToHex(checkSum)); + chunkTO.setFileId(createdFile.getId()); + chunkTO.setSize(dataSize); + dao.createChunk(chunkTO); + passed(); + } + + @Test + public void readChunkTest() throws Exception { + testName("readChunk"); + int dataSize = 1024 * 1024; + /* Create a new file */ + Date date = new Date(); + String fileName = "/home/kavoos/readchunk" + date.getTime() + ".txt"; + FileDaoClient dao = new FileDaoClient(); + FileTO fileTO = new FileTO(); + fileTO.setName(fileName); + FileTO createdFile = dao.createFile(fileTO); + assertNotNull(createdFile); + assertTrue(createdFile.getId() != 0); + assertEquals(fileName, createdFile.getName()); + /* Create chunk */ + Random r = new Random(System.currentTimeMillis()); + byte[] buffer = new byte[dataSize]; + r.nextBytes(buffer); + MessageDigest digest = MessageDigest.getInstance("MD5"); + byte[] checkSum = digest.digest(buffer); + ChunkTO chunkTO = new ChunkTO(); + chunkTO.setData(buffer); + chunkTO.setRank(0); + chunkTO.setChecksum(bytesToHex(checkSum)); + chunkTO.setFileId(createdFile.getId()); + chunkTO.setSize(dataSize); + dao.createChunk(chunkTO); + /* Read the file to find chunk id */ + createdFile = dao.readFile(createdFile.getId()); + assertNotNull(createdFile.getChunks()); + assertEquals(1, createdFile.getChunks().size()); + long chunkId = createdFile.getChunks().get(0).getId(); + + ChunkTO readedChunk = dao.readChunk(chunkId); + assertNotNull(readedChunk); + assertNotNull(readedChunk.getData()); + checkSum = digest.digest(readedChunk.getData()); + assertEquals(chunkTO.getChecksum(), bytesToHex(checkSum)); + passed(); } } diff --git a/projects/GDE_App/GDE-ejb/src/java/com/edf/gde/common/HexUtils.java b/projects/GDE_App/GDE-ejb/src/java/com/edf/gde/common/HexUtils.java new file mode 100644 index 0000000..7fd8a63 --- /dev/null +++ b/projects/GDE_App/GDE-ejb/src/java/com/edf/gde/common/HexUtils.java @@ -0,0 +1,34 @@ +/* + * (C) 2015 EDF + */ +package com.edf.gde.common; + +/** + * + * @author Kavoos + */ +public class HexUtils { + + static char[] hexArray = "0123456789ABCDEF".toCharArray(); + + public static String bytesToHex(byte[] bytes) { + char[] hexChars = new char[bytes.length * 2]; + for (int j = 0; j < bytes.length; j++) { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = hexArray[v >>> 4]; + hexChars[j * 2 + 1] = hexArray[v & 0x0F]; + } + return new String(hexChars); + } + + public static byte[] hexStringToByteArray(String s) { + int len = s.length(); + byte[] data = new byte[len / 2]; + for (int i = 0; i < len; i += 2) { + data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + + Character.digit(s.charAt(i + 1), 16)); + } + return data; + } + +} diff --git a/projects/GDE_App/GDE-ejb/src/java/com/edf/gde/ejb/ChunkEJB.java b/projects/GDE_App/GDE-ejb/src/java/com/edf/gde/ejb/ChunkEJB.java index c5450ce..9228d2d 100644 --- a/projects/GDE_App/GDE-ejb/src/java/com/edf/gde/ejb/ChunkEJB.java +++ b/projects/GDE_App/GDE-ejb/src/java/com/edf/gde/ejb/ChunkEJB.java @@ -3,6 +3,7 @@ */ package com.edf.gde.ejb; +import com.edf.gde.common.HexUtils; import com.edf.gde.dao.ChunkDao; import com.edf.gde.dao.FileDao; import com.edf.gde.dao.impl.ChunkDaoImpl; @@ -10,6 +11,8 @@ import com.edf.gde.dao.impl.FileDaoImpl; import com.edf.gde.entities.Chunk; import com.edf.gde.entities.GDEFile; import com.edf.gde.transferables.ChunkTO; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import javax.ejb.Stateless; import javax.ejb.LocalBean; import javax.persistence.EntityManager; @@ -27,16 +30,33 @@ public class ChunkEJB { private EntityManager em; public void createChunk(ChunkTO cto) { - ChunkDao dao = new ChunkDaoImpl(em); - FileDao fd = new FileDaoImpl(em); - GDEFile file = fd.findById(cto.getFileId()); - if (file == null) { - throw new RuntimeException("Invalid file id"); - } - if (file.isValid()) { - throw new RuntimeException("Cannot add chunk to validated file"); + try { + ChunkDao dao = new ChunkDaoImpl(em); + FileDao fd = new FileDaoImpl(em); + GDEFile file = fd.findById(cto.getFileId()); + if (file == null) { + throw new RuntimeException("Invalid file id"); + } + if (file.isValid()) { + throw new RuntimeException("Cannot add chunk to validated file"); + } + + MessageDigest digest = MessageDigest.getInstance("MD5"); + byte[] checkSum = digest.digest(cto.getData()); + String stringChecksum = HexUtils.bytesToHex(checkSum); + if (cto.getChecksum() == null) { + throw new RuntimeException("Bad checksum"); + } + if (!cto.getChecksum().equals(stringChecksum)) { + throw new RuntimeException("Bad checksum"); + } + Chunk chunk = Chunk.fromChunkTO(cto); + chunk.setSize(cto.getData().length); + dao.createChunk(chunk); + + } catch (RuntimeException | NoSuchAlgorithmException ex) { + throw new RuntimeException(ex.getMessage()); } - dao.createChunk(Chunk.fromChunkTO(cto)); } public ChunkTO readChunk(long id) { diff --git a/projects/GDE_App/GDE-ejb/src/java/com/edf/gde/entities/Study.java b/projects/GDE_App/GDE-ejb/src/java/com/edf/gde/entities/Study.java index 8f763a2..4aff8c8 100644 --- a/projects/GDE_App/GDE-ejb/src/java/com/edf/gde/entities/Study.java +++ b/projects/GDE_App/GDE-ejb/src/java/com/edf/gde/entities/Study.java @@ -77,6 +77,7 @@ public class Study implements Serializable { private boolean locked; @Column(name = "lock_owner") private Long lockOwner; + @OneToMany(fetch = FetchType.LAZY) @JoinTable( name = "study_files", -- 2.39.2