diff --git a/adastor.iml b/adastor.iml
index bd4e95b..1bfb2d9 100644
--- a/adastor.iml
+++ b/adastor.iml
@@ -4,15 +4,6 @@
-
-
-
-
-
-
-
-
-
@@ -23,7 +14,7 @@
-
+
@@ -119,6 +110,7 @@
+
diff --git a/adastor.ipr b/adastor.ipr
index 2a334d9..48ee024 100644
--- a/adastor.ipr
+++ b/adastor.ipr
@@ -14,17 +14,15 @@
-
+
hsqldb.local
true
- true
org.hsqldb.jdbc.JDBCDriver
- jdbc:hsqldb:file:$PROJECT_DIR$/database/adastor
+ jdbc:hsqldb:file:./database/adastor
-
@@ -37,6 +35,89 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
- -
-
-
- -
-
-
-
+
+
+
+
+
+
+
+
+ Android
+
+
+
+
@@ -171,19 +145,24 @@
-
+
+
+
+
+
-
+
-
-
+
+
"
master_key
sa
+ @:@
@@ -330,6 +309,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index b2c81e6..b76d2ab 100644
--- a/pom.xml
+++ b/pom.xml
@@ -66,6 +66,14 @@
+
+
+ commons-codec
+ commons-codec
+ 1.12
+
+
+
org.projectlombok
lombok
diff --git a/src/main/java/ru/bvn13/adastor/entities/Stortion.java b/src/main/java/ru/bvn13/adastor/entities/Stortion.java
index b488506..7d50501 100644
--- a/src/main/java/ru/bvn13/adastor/entities/Stortion.java
+++ b/src/main/java/ru/bvn13/adastor/entities/Stortion.java
@@ -5,14 +5,15 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
+import javax.persistence.*;
import java.time.LocalDateTime;
/**
* @author boykovn at 11.03.2019
*/
+@Table(
+ indexes = @Index(columnList = "hash")
+)
@Entity
@Getter
@Setter
diff --git a/src/main/java/ru/bvn13/adastor/entities/dtos/StortionDto.java b/src/main/java/ru/bvn13/adastor/entities/dtos/StortionDto.java
index 4f645a5..9392820 100644
--- a/src/main/java/ru/bvn13/adastor/entities/dtos/StortionDto.java
+++ b/src/main/java/ru/bvn13/adastor/entities/dtos/StortionDto.java
@@ -28,4 +28,6 @@ public class StortionDto {
@Transient
private long retention;
+ private String hash;
+
}
diff --git a/src/main/java/ru/bvn13/adastor/tasks/DiskFreeSpaceChecker.java b/src/main/java/ru/bvn13/adastor/tasks/DiskFreeSpaceChecker.java
index c341032..643ad2f 100644
--- a/src/main/java/ru/bvn13/adastor/tasks/DiskFreeSpaceChecker.java
+++ b/src/main/java/ru/bvn13/adastor/tasks/DiskFreeSpaceChecker.java
@@ -40,7 +40,7 @@ public class DiskFreeSpaceChecker {
private double getSpaceLeft() {
File path = new File(config.getStoragePath());
- double space = (double) path.getFreeSpace() / 1024 / 1024;
+ double space = (double) path.getFreeSpace();// / 1024 / 1024;
return space;
}
@@ -51,8 +51,8 @@ public class DiskFreeSpaceChecker {
final ExecutorService es = Executors.newFixedThreadPool(10);
stortionService.findAllSortedByRetention().forEach(stortionDto -> {
- double space = spaceLeft.accumulateAndGet((double) stortionDto.getSize(), (a, b) -> a + b);
- if (space >= mustFreeSpace) {
+ double virtualSpace = spaceLeft.accumulateAndGet((double) stortionDto.getSize(), (a, b) -> a + b);
+ if (virtualSpace <= mustFreeSpace) {
es.submit(() -> {
File file = new File(String.format("%s%s", config.getStoragePath(), stortionDto.getPath()));
if (file.exists()) {
diff --git a/src/main/java/ru/bvn13/adastor/web/repositories/CustomStortionRepository.java b/src/main/java/ru/bvn13/adastor/web/repositories/CustomStortionRepository.java
index ecefe47..2bf792d 100644
--- a/src/main/java/ru/bvn13/adastor/web/repositories/CustomStortionRepository.java
+++ b/src/main/java/ru/bvn13/adastor/web/repositories/CustomStortionRepository.java
@@ -2,13 +2,13 @@ package ru.bvn13.adastor.web.repositories;
import ru.bvn13.adastor.entities.Stortion;
-import java.util.stream.Stream;
+import java.util.Collection;
/**
* @author boykovn at 12.03.2019
*/
public interface CustomStortionRepository {
- Stream findAllSortedByRetention();
+ Collection findAllSortedByRetention();
}
diff --git a/src/main/java/ru/bvn13/adastor/web/repositories/impl/StortionRepositoryImpl.java b/src/main/java/ru/bvn13/adastor/web/repositories/impl/StortionRepositoryImpl.java
index 428d6b5..c2a1aa7 100644
--- a/src/main/java/ru/bvn13/adastor/web/repositories/impl/StortionRepositoryImpl.java
+++ b/src/main/java/ru/bvn13/adastor/web/repositories/impl/StortionRepositoryImpl.java
@@ -9,6 +9,7 @@ import ru.bvn13.adastor.web.repositories.CustomStortionRepository;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
+import java.util.Collection;
import java.util.stream.Stream;
/**
@@ -39,7 +40,7 @@ public class StortionRepositoryImpl implements CustomStortionRepository {
* @return queried collection
*/
@Override
- public Stream findAllSortedByRetention() {
+ public Collection findAllSortedByRetention() {
long min_age = config.getMinDaysStoring();
long max_age = config.getMaxDaysStoring();
@@ -51,7 +52,7 @@ public class StortionRepositoryImpl implements CustomStortionRepository {
query.setParameter("max_age", (double)max_age);
query.setParameter("max_size", max_size);
- return (Stream) query.getResultStream();
+ return query.getResultList();
}
}
diff --git a/src/main/java/ru/bvn13/adastor/web/services/StortionService.java b/src/main/java/ru/bvn13/adastor/web/services/StortionService.java
index baf0123..94efb41 100644
--- a/src/main/java/ru/bvn13/adastor/web/services/StortionService.java
+++ b/src/main/java/ru/bvn13/adastor/web/services/StortionService.java
@@ -1,5 +1,6 @@
package ru.bvn13.adastor.web.services;
+import org.apache.commons.codec.binary.Hex;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -18,9 +19,7 @@ import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
-import java.util.Formatter;
-import java.util.Optional;
-import java.util.UUID;
+import java.util.*;
import java.util.stream.Stream;
/**
@@ -78,17 +77,35 @@ public class StortionService {
String path = String.format("/%s", uuid);
String fullPath = String.format("%s/%s", config.getStoragePath(), uuid);
- long bytesCount;
- String hash;
- try(DigestInputStream dis = new DigestInputStream(new BufferedInputStream(is), MessageDigest.getInstance("SHA-1")); FileOutputStream fos = new FileOutputStream(fullPath)) {
- bytesCount = is.transferTo(fos);
- hash = formatMessageDigestToHex(dis);
+ long bytesCount = 0;
+ MessageDigest md;
+ try {
+ md = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
throw new InternalServerError("SHA-1 not found, Sorry.", e);
}
+ try(
+ DigestInputStream dis = new DigestInputStream(new BufferedInputStream(is), md);
+ FileOutputStream fos = new FileOutputStream(fullPath)
+ ) {
+ byte[] buffer = new byte[128];
+ int length = 0;
+ while ((length = dis.read(buffer)) > 0) {
+ fos.write(buffer, 0, length);
+ bytesCount += length;
+ }
+ }
+
+ if (dataLength != bytesCount) {
+ throw new InternalServerError("Something went wrong. Sorry.");
+ }
+
+ char[] hex = Hex.encodeHex(md.digest());
+ String hash = new String(hex);
Optional similarByHash = findAnyByHash(hash);
if (similarByHash.isPresent()) {
+ (new File(fullPath)).delete();
throw new StortionExistByHash(similarByHash.get());
}
@@ -97,27 +114,12 @@ public class StortionService {
stortion.setStoreDate(LocalDateTime.now());
stortion.setPath(path);
stortion.setSize(bytesCount);
+ stortion.setHash(hash);
stortionRepository.save(stortion);
return convertToDto(stortion);
}
- private String formatMessageDigestToHex(DigestInputStream dis) {
- final MessageDigest md = dis.getMessageDigest();
- final byte[] digest = md.digest();
-
- // Format as HEX
- try (Formatter formatter = new Formatter()) {
- for (final byte b : digest) {
- formatter.format("%02x", b);
- }
-
- final String sha1 = formatter.toString();
- return sha1;
- }
-
- }
-
private StortionDto convertToDto(Stortion stortion) {
StortionDto stortionDto = modelMapper.map(stortion, StortionDto.class);
stortionDto.setRetention(computeRetention(stortion));
@@ -125,8 +127,8 @@ public class StortionService {
}
public Stream findAllSortedByRetention() {
- Stream stortions = stortionRepository.findAllSortedByRetention();
- return stortions.map(this::convertToDto);
+ Collection stortions = stortionRepository.findAllSortedByRetention();
+ return stortions.stream().map(this::convertToDto);
}
/**
@@ -143,10 +145,6 @@ public class StortionService {
stortionRepository.deleteById(uuid);
}
- private Iterable findAllByHash(String hash) {
- return stortionRepository.findAllByHash(hash);
- }
-
private Optional findAnyByHash(String hash) {
return stortionRepository.findFirstByHash(hash).map(this::convertToDto);
}