Added DELETE /resource/{service}/{name}/{identifier} API endpoint, to delete local data

This commit is contained in:
CalDescent 2021-12-24 13:04:16 +00:00
parent 42aca2e40f
commit 0bde1e97dc
3 changed files with 75 additions and 1 deletions

View File

@ -401,6 +401,26 @@ public class ArbitraryResource {
}
}
@DELETE
@Path("/resource/{service}/{name}/{identifier}")
@Operation(
summary = "Delete arbitrary resource with supplied service, name and identifier",
responses = {
@ApiResponse(
content = @Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "string"))
)
}
)
@SecurityRequirement(name = "apiKey")
public boolean deleteResource(@PathParam("service") Service service,
@PathParam("name") String name,
@PathParam("identifier") String identifier) {
Security.checkApiCallAllowed(request);
ArbitraryDataResource resource = new ArbitraryDataResource(name, ResourceIdType.NAME, service, identifier);
return resource.delete();
}
@POST
@Path("/compute")
@Operation(

View File

@ -11,9 +11,14 @@ import org.qortal.list.ResourceListManager;
import org.qortal.repository.DataException;
import org.qortal.repository.Repository;
import org.qortal.repository.RepositoryManager;
import org.qortal.settings.Settings;
import org.qortal.utils.ArbitraryTransactionUtils;
import org.qortal.utils.FilesystemUtils;
import org.qortal.utils.NTP;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
@ -32,6 +37,11 @@ public class ArbitraryDataResource {
this.resourceId = resourceId.toLowerCase();
this.resourceIdType = resourceIdType;
this.service = service;
// If identifier is a blank string, or reserved keyword "default", treat it as null
if (identifier == null || identifier.equals("") || identifier.equals("default")) {
identifier = null;
}
this.identifier = identifier;
}
@ -81,6 +91,42 @@ public class ArbitraryDataResource {
return new ArbitraryResourceSummary(ArbitraryResourceStatus.DOWNLOADED);
}
public boolean delete() {
try {
this.fetchTransactions();
List<ArbitraryTransactionData> transactionDataList = new ArrayList<>(this.transactions);
for (ArbitraryTransactionData transactionData : transactionDataList) {
byte[] hash = transactionData.getData();
byte[] metadataHash = transactionData.getMetadataHash();
byte[] signature = transactionData.getSignature();
ArbitraryDataFile arbitraryDataFile = ArbitraryDataFile.fromHash(hash, signature);
arbitraryDataFile.setMetadataHash(metadataHash);
// Delete any chunks or complete files from each transaction
arbitraryDataFile.deleteAll();
}
// Also delete cached data for the entire resource
this.deleteCache();
return true;
} catch (DataException | IOException e) {
return false;
}
}
public void deleteCache() throws IOException {
String baseDir = Settings.getInstance().getTempDataPath();
String identifier = this.identifier != null ? this.identifier : "default";
Path cachePath = Paths.get(baseDir, "reader", this.resourceIdType.toString(), this.resourceId, this.service.toString(), identifier);
if (cachePath.toFile().exists()) {
FilesystemUtils.safeDeleteDirectory(cachePath, true);
}
}
private boolean allFilesDownloaded() {
try {
this.fetchTransactions();
@ -229,7 +275,7 @@ public class ArbitraryDataResource {
@Override
public String toString() {
return String.format("%s %s %s %s", this.serviceString(), this.resourceIdString(), this.resourceIdTypeString(), this.identifierString());
return String.format("%s %s %s", this.serviceString(), this.resourceIdString(), this.identifierString());
}

View File

@ -1,5 +1,6 @@
package org.qortal.controller.arbitrary;
import java.io.IOException;
import java.util.*;
import org.apache.logging.log4j.LogManager;
@ -343,6 +344,13 @@ public class ArbitraryDataManager extends Thread {
// Remove from the signature requests list now that we have all files for this signature
ArbitraryDataFileListManager.getInstance().removeFromSignatureRequests(signature58);
// Delete cached files themselves
try {
resource.deleteCache();
} catch (IOException e) {
LOGGER.info("Unable to delete cache for resource {}: {}", resource, e.getMessage());
}
}
}