完成Tracker.java接口开发,update path
Change-Id: I8b1096af3aa3c7ebdf623905c5d47cfe72b86da2
diff --git a/src/main/java/entity/SeedDownload.java b/src/main/java/entity/SeedDownload.java
new file mode 100644
index 0000000..caafda8
--- /dev/null
+++ b/src/main/java/entity/SeedDownload.java
@@ -0,0 +1,119 @@
+package entity;
+
+import java.time.LocalDateTime;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "SeedDownload")
+public class SeedDownload {
+
+ @Id
+ @Column(name = "task_id", length = 64, nullable = false)
+ public String taskId;
+
+ @Column(name = "user_id", length = 36, nullable = false)
+ public String userId;
+
+ @Column(name = "seed_id", length = 64, nullable = false)
+ public String seedId;
+
+ @Column(name = "download_start", nullable = false)
+ public LocalDateTime downloadStart;
+
+ @Column(name = "download_end")
+ public LocalDateTime downloadEnd;
+
+ @Column(name = "is_dedicated", nullable = false)
+ public boolean isDedicated;
+
+ @Column(name = "client_ip", length = 45)
+ public String clientIp;
+
+ // Constructors
+ public SeedDownload() {}
+
+ public SeedDownload(String taskId, String userId, String seedId, LocalDateTime downloadStart, LocalDateTime downloadEnd, boolean isDedicated, String clientIp) {
+ this.taskId = taskId;
+ this.userId = userId;
+ this.seedId = seedId;
+ this.downloadStart = downloadStart;
+ this.downloadEnd = downloadEnd;
+ this.isDedicated = isDedicated;
+ this.clientIp = clientIp;
+ }
+
+ // Getters and Setters
+ public String getTaskId() {
+ return taskId;
+ }
+
+ public void setTaskId(String taskId) {
+ this.taskId = taskId;
+ }
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ public String getSeedId() {
+ return seedId;
+ }
+
+ public void setSeedId(String seedId) {
+ this.seedId = seedId;
+ }
+
+ public LocalDateTime getDownloadStart() {
+ return downloadStart;
+ }
+
+ public void setDownloadStart(LocalDateTime downloadStart) {
+ this.downloadStart = downloadStart;
+ }
+
+ public LocalDateTime getDownloadEnd() {
+ return downloadEnd;
+ }
+
+ public void setDownloadEnd(LocalDateTime downloadEnd) {
+ this.downloadEnd = downloadEnd;
+ }
+
+ public boolean isDedicated() {
+ return isDedicated;
+ }
+
+ public void setDedicated(boolean dedicated) {
+ isDedicated = dedicated;
+ }
+
+ public String getClientIp() {
+ return clientIp;
+ }
+
+ public void setClientIp(String clientIp) {
+ this.clientIp = clientIp;
+ }
+
+ // equals and hashCode based on taskId
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SeedDownload)) return false;
+ SeedDownload that = (SeedDownload) o;
+ return taskId != null && taskId.equals(that.taskId);
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 + (taskId != null ? taskId.hashCode() : 0);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/entity/config.java b/src/main/java/entity/config.java
index 0cf39c1..71f3b4f 100644
--- a/src/main/java/entity/config.java
+++ b/src/main/java/entity/config.java
@@ -1,14 +1,15 @@
package entity;
public class config {
- public String TrackerURL;
- public int FarmNumber;
- public int FakeTime;
- public int BegVote;
+ public static final String TrackerURL="";
+ public static final int FarmNumber=3;
+ public static final int FakeTime=3;
+ public static final int BegVote=3;
// 请根据实际环境修改为可达的地址
- public String SqlURL = "192.168.5.9:3306";
- public String Database = "pt_database";
- public String TestDatabase = "pt_database_test";
- public String SqlPassword = "123456";
- public String SqlUsername = "root";
+ public static final String SqlURL = "192.168.5.9:3306";
+ public static final String Database = "pt_database";
+ public static final String TestDatabase = "pt_database_test";
+ public static final String SqlPassword = "123456";
+ public static final String SqlUsername = "root";
+ public static final String TORRENT_STORAGE_DIR = "torrents";
}
diff --git a/src/main/java/tracker/Tracker.java b/src/main/java/tracker/Tracker.java
index 6334ebb..210b9bf 100644
--- a/src/main/java/tracker/Tracker.java
+++ b/src/main/java/tracker/Tracker.java
@@ -1,20 +1,24 @@
package tracker;
import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.Map;
-
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
-
import com.querydsl.jpa.impl.JPAUpdateClause;
-
import entity.QUserPT;
-import entity.TTorent;
+import entity.Seed;
+import entity.SeedDownload;
import entity.TransRecord;
import entity.config;
+import entity.TTorent;
+import java.time.LocalDateTime;
public class Tracker implements TrackerInterface {
private final EntityManagerFactory emf;
@@ -163,17 +167,69 @@
}
}
+ @Override
+ public int SaveTorrent(String seedid, File TTorent){
+ try {
+ Path storageDir = Paths.get(config.TORRENT_STORAGE_DIR);
+ if (!Files.exists(storageDir)) {
+ Files.createDirectories(storageDir);
+ }
+ String filename = TTorent.getName();
+ Path target = storageDir.resolve(seedid + "_" + filename);
+ Files.copy(TTorent.toPath(), target, StandardCopyOption.REPLACE_EXISTING);
+
+ EntityManager em = emf.createEntityManager();
+ EntityTransaction tx = em.getTransaction();
+ try {
+ tx.begin();
+ Seed seed = em.find(Seed.class, seedid);
+ seed.url = target.toString();
+ em.merge(seed);
+ tx.commit();
+ return 0;
+ } catch (Exception e) {
+ if (tx.isActive()) tx.rollback();
+ return 1;
+ } finally {
+ em.close();
+ }
+ } catch (Exception e) {
+ return 1;
+ }
+ }
@Override
- public int SaveTorrent(File TTorent){
- return 0;
- };//保存seedid对应的ttorent信息
-
- @Override
- public File GetTTorent(String seedid,String userid){
- return null;
- };//根据种子id获得ttorent信息然后构建Ttorent文件并返回,同时记录用户的下载行为
-
+ public File GetTTorent(String seedid, String userid, String ip) {
+ EntityManager em = emf.createEntityManager();
+ EntityTransaction tx = em.getTransaction();
+ File file = null;
+ try {
+ Seed seed = em.find(Seed.class, seedid);
+ if (seed == null || seed.url == null) {
+ return null;
+ }
+ file = new File(seed.url);
+ if (!file.exists()) {
+ return null;
+ }
+ tx.begin();
+ SeedDownload sd = new SeedDownload();
+ sd.seedId = seedid;
+ sd.userId = userid;
+ sd.clientIp = ip;
+ LocalDateTime now = LocalDateTime.now();
+ sd.downloadStart = now;
+ sd.downloadEnd = now;
+ em.persist(sd);
+ tx.commit();
+ } catch (Exception e) {
+ if (tx.isActive()) tx.rollback();
+ // ignore persistence errors and still return the file
+ } finally {
+ em.close();
+ }
+ return file;
+ }
@Override
public int AddRecord(TransRecord rd){
diff --git a/src/main/java/tracker/TrackerInterface.java b/src/main/java/tracker/TrackerInterface.java
index 1496a26..4776d11 100644
--- a/src/main/java/tracker/TrackerInterface.java
+++ b/src/main/java/tracker/TrackerInterface.java
@@ -11,8 +11,8 @@
public boolean AddMagic(String userid,int magic);//给用户增加魔力值,返回0成功,返回1失败;
public boolean ReduceMagic(String userid,int magic);//给用户减少魔力值,返回0成功,返回1失败;
- public int SaveTorrent(File TTorent);//保存seedid对应的ttorent信息
- public File GetTTorent(String seedid,String userid);//根据种子id获得ttorent信息然后构建Ttorent文件并返回,同时记录用户的下载行为
+ public int SaveTorrent(String seedid,File TTorent);//保存seedid对应的ttorent信息
+ public File GetTTorent(String seedid,String userid,String ip);//根据种子id获得ttorent信息然后构建Ttorent文件并返回,同时记录用户的下载行为
public int AddRecord(TransRecord rd);//新增一个seedid对应的种子的传输任务记录
}
\ No newline at end of file
diff --git a/src/test/java/databasetest/DataManagerTest.java b/src/test/java/databasetest/DataManagerTest.java
new file mode 100644
index 0000000..1256240
--- /dev/null
+++ b/src/test/java/databasetest/DataManagerTest.java
@@ -0,0 +1,5 @@
+package databasetest;
+
+public class DataManagerTest {
+
+}
diff --git a/src/test/java/trackertest/TrackerTest.java b/src/test/java/trackertest/TrackerTest.java
index 3c4898b..104f017 100644
--- a/src/test/java/trackertest/TrackerTest.java
+++ b/src/test/java/trackertest/TrackerTest.java
@@ -1,4 +1,6 @@
package trackertest;
+
+import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@@ -19,6 +21,7 @@
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
+import entity.Seed;
import entity.TransRecord;
import entity.TransportId;
import entity.config;
@@ -66,6 +69,19 @@
@AfterAll
static void teardown() {
+ // 清理:删除测试过程中保存的所有 torrent 文件
+ File storageDir = new File(config.TORRENT_STORAGE_DIR);
+ if (storageDir.exists() && storageDir.isDirectory()) {
+ File[] files = storageDir.listFiles();
+ if (files != null) {
+ for (File f : files) {
+ if (f.isFile()) {
+ f.delete();
+ }
+ }
+ }
+ }
+
if (em != null && em.isOpen()) em.close();
if (emf != null && emf.isOpen()) emf.close();
}
@@ -298,4 +314,80 @@
}))
.collect(Collectors.toList());
}
+
+ @TestFactory
+ Collection<DynamicTest> testSaveTorrent() {
+ List<String> seedIds = em.createQuery(
+ "select s.seedid from Seed s", String.class
+ ).getResultList();
+ return seedIds.stream()
+ .map(sid -> DynamicTest.dynamicTest("SaveTorrent for seed " + sid, () -> {
+ // 准备一个临时空文件
+ File temp = File.createTempFile(sid + "_test", ".torrent");
+ // 调用 SaveTorrent
+ int ret = tracker.SaveTorrent(sid, temp);
+ Assertions.assertEquals(0, ret, "SaveTorrent 应返回 0");
+
+ // 验证文件已按约定存储
+ File stored = new File(config.TORRENT_STORAGE_DIR,
+ sid + "_" + temp.getName());
+ Assertions.assertTrue(stored.exists(), "存储文件应存在");
+
+ // 验证数据库中 url 字段已更新
+ em.clear();
+ Seed seed = em.find(Seed.class, sid);
+ // 将 seed.url 转为 File 再取绝对路径进行比较
+ Assertions.assertEquals(
+ stored.getAbsolutePath(),
+ new File(seed.url).getAbsolutePath(),
+ "Seed.url 应更新为存储路径"
+ );
+
+ // 清理测试文件
+ stored.delete();
+ temp.delete();
+ }))
+ .collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testGetTTorent() {
+ // 拿到所有 seedid
+ List<String> seedIds = em.createQuery(
+ "select s.seedid from Seed s", String.class
+ ).getResultList();
+ return seedIds.stream()
+ .map(sid -> DynamicTest.dynamicTest("GetTTorent for seed " + sid, () -> {
+ // 准备一个临时空文件并 SaveTorrent
+ File temp = File.createTempFile(sid + "_test", ".torrent");
+ int saveRet = tracker.SaveTorrent(sid, temp);
+ Assertions.assertEquals(0, saveRet, "SaveTorrent 应返回 0");
+
+ // 刷新上下文并取回更新后的 seed 实体
+ em.clear();
+ Seed seed = em.find(Seed.class, sid);
+ Assertions.assertNotNull(seed.url, "Seed.url 应已被更新");
+
+ // 调用 GetTTorent 并断言路径一致
+ String uid = userIds.get(0), ip = "127.0.0.1";
+ File ret = tracker.GetTTorent(sid, uid, ip);
+ File expected = new File(seed.url);
+ Assertions.assertNotNull(ret, "应返回文件对象");
+ Assertions.assertEquals(
+ expected.getAbsolutePath(),
+ ret.getAbsolutePath(),
+ "返回文件路径应与Seed.url一致"
+ );
+
+ // 清理:删掉本地文件,回滚 DB url 字段,删掉 temp
+ expected.delete();
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ seed.url = null;
+ em.merge(seed);
+ tx.commit();
+ temp.delete();
+ }))
+ .collect(Collectors.toList());
+ }
}