diff --git a/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java b/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java index 7d76be3d..15bb398e 100644 --- a/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java +++ b/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java @@ -3,6 +3,8 @@ package org.qortal.api.gateway.resource; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import org.apache.commons.lang3.StringUtils; +import org.qortal.api.ApiError; +import org.qortal.api.ApiExceptionFactory; import org.qortal.api.Security; import org.qortal.arbitrary.ArbitraryDataFile; import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType; @@ -11,6 +13,9 @@ import org.qortal.arbitrary.ArbitraryDataRenderer; import org.qortal.arbitrary.ArbitraryDataResource; import org.qortal.arbitrary.misc.Service; import org.qortal.data.arbitrary.ArbitraryResourceStatus; +import org.qortal.repository.DataException; +import org.qortal.repository.Repository; +import org.qortal.repository.RepositoryManager; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -31,30 +36,6 @@ public class GatewayResource { @Context HttpServletResponse response; @Context ServletContext context; - /** - * We need to allow resource status checking (and building) via the gateway, as the node's API port - * may not be forwarded and will almost certainly not be authenticated. Since gateways allow for - * all resources to be loaded except those that are blocked, there is no need for authentication. - */ - @GET - @Path("/arbitrary/resource/status/{service}/{name}") - public ArbitraryResourceStatus getDefaultResourceStatus(@PathParam("service") Service service, - @PathParam("name") String name, - @QueryParam("build") Boolean build) { - - return this.getStatus(service, name, null, build); - } - - @GET - @Path("/arbitrary/resource/status/{service}/{name}/{identifier}") - public ArbitraryResourceStatus getResourceStatus(@PathParam("service") Service service, - @PathParam("name") String name, - @PathParam("identifier") String identifier, - @QueryParam("build") Boolean build) { - - return this.getStatus(service, name, identifier, build); - } - private ArbitraryResourceStatus getStatus(Service service, String name, String identifier, Boolean build) { // If "build=true" has been specified in the query string, build the resource before returning its status @@ -69,8 +50,13 @@ public class GatewayResource { } } - ArbitraryDataResource resource = new ArbitraryDataResource(name, ResourceIdType.NAME, service, identifier); - return resource.getStatus(); + try (final Repository repository = RepositoryManager.getRepository()) { + ArbitraryDataResource resource = new ArbitraryDataResource(name, ResourceIdType.NAME, service, identifier); + return resource.getStatus(repository); + + } catch (DataException e) { + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); + } } diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index b17e810c..b7eb6cd4 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -531,8 +531,14 @@ public class ArbitraryResource { @PathParam("identifier") String identifier) { Security.checkApiCallAllowed(request); - ArbitraryDataResource resource = new ArbitraryDataResource(name, ResourceIdType.NAME, service, identifier); - return resource.delete(false); + + try (final Repository repository = RepositoryManager.getRepository()) { + ArbitraryDataResource resource = new ArbitraryDataResource(name, ResourceIdType.NAME, service, identifier); + return resource.delete(repository, false); + + } catch (DataException e) { + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); + } } @POST diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java index 4aed21fc..96fc4e48 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java @@ -59,28 +59,34 @@ public class ArbitraryDataResource { } public ArbitraryResourceStatus getStatusAndUpdateCache(boolean updateCache) { - ArbitraryResourceStatus arbitraryResourceStatus = this.getStatus(); + ArbitraryResourceStatus arbitraryResourceStatus = null; - if (updateCache) { - // Update cache if possible - ArbitraryResourceStatus.Status status = arbitraryResourceStatus != null ? arbitraryResourceStatus.getStatus() : null; - ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(this.service, this.resourceId, this.identifier); + try (final Repository repository = RepositoryManager.getRepository()) { + arbitraryResourceStatus = this.getStatus(repository); - try (final Repository repository = RepositoryManager.getRepository()) { + if (updateCache) { + // Update cache if possible + ArbitraryResourceStatus.Status status = arbitraryResourceStatus != null ? arbitraryResourceStatus.getStatus() : null; + ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(this.service, this.resourceId, this.identifier); repository.getArbitraryRepository().setStatus(arbitraryResourceData, status); repository.saveChanges(); - - } catch (DataException e) { - LOGGER.info("Unable to update status cache for resource {}: {}", arbitraryResourceData, e.getMessage()); } + } catch (DataException e) { + LOGGER.info("Unable to update status cache for resource {}: {}", this.toString(), e.getMessage()); } return arbitraryResourceStatus; } - public ArbitraryResourceStatus getStatus() { + /** + * Get current status of resource + * + * @param repository + * @return the resource's status + */ + public ArbitraryResourceStatus getStatus(Repository repository) { // Calculate the chunk counts - this.calculateChunkCounts(); + this.calculateChunkCounts(repository); if (!this.exists) { return new ArbitraryResourceStatus(Status.NOT_PUBLISHED, this.localChunkCount, this.totalChunkCount); @@ -111,11 +117,11 @@ public class ArbitraryDataResource { } // Check if we have all data locally for this resource - if (!this.allFilesDownloaded()) { - if (this.isDownloading()) { + if (!this.allFilesDownloaded(repository)) { + if (this.isDownloading(repository)) { return new ArbitraryResourceStatus(Status.DOWNLOADING, this.localChunkCount, this.totalChunkCount); } - else if (this.isDataPotentiallyAvailable()) { + else if (this.isDataPotentiallyAvailable(repository)) { return new ArbitraryResourceStatus(Status.PUBLISHED, this.localChunkCount, this.totalChunkCount); } return new ArbitraryResourceStatus(Status.MISSING_DATA, this.localChunkCount, this.totalChunkCount); @@ -157,9 +163,9 @@ public class ArbitraryDataResource { return null; } - public boolean delete(boolean deleteMetadata) { + public boolean delete(Repository repository, boolean deleteMetadata) { try { - this.fetchTransactions(); + this.fetchTransactions(repository); if (this.transactions == null) { return false; } @@ -208,7 +214,7 @@ public class ArbitraryDataResource { } } - private boolean allFilesDownloaded() { + private boolean allFilesDownloaded(Repository repository) { // Use chunk counts to speed things up if we can if (this.localChunkCount != null && this.totalChunkCount != null && this.localChunkCount >= this.totalChunkCount) { @@ -216,7 +222,7 @@ public class ArbitraryDataResource { } try { - this.fetchTransactions(); + this.fetchTransactions(repository); if (this.transactions == null) { return false; } @@ -236,9 +242,14 @@ public class ArbitraryDataResource { } } - private void calculateChunkCounts() { + /** + * Calculate chunk counts of a resource + * + * @param repository optional - a new instance will be created if null + */ + private void calculateChunkCounts(Repository repository) { try { - this.fetchTransactions(); + this.fetchTransactions(repository); if (this.transactions == null) { this.exists = false; this.localChunkCount = 0; @@ -263,9 +274,9 @@ public class ArbitraryDataResource { } catch (DataException e) {} } - private boolean isRateLimited() { + private boolean isRateLimited(Repository repository) { try { - this.fetchTransactions(); + this.fetchTransactions(repository); if (this.transactions == null) { return true; } @@ -289,9 +300,9 @@ public class ArbitraryDataResource { * This is only used to give an indication to the user of progress * @return - whether data might be available on the network */ - private boolean isDataPotentiallyAvailable() { + private boolean isDataPotentiallyAvailable(Repository repository) { try { - this.fetchTransactions(); + this.fetchTransactions(repository); if (this.transactions == null) { return false; } @@ -324,9 +335,9 @@ public class ArbitraryDataResource { * This is only used to give an indication to the user of progress * @return - whether we are trying to download the resource */ - private boolean isDownloading() { + private boolean isDownloading(Repository repository) { try { - this.fetchTransactions(); + this.fetchTransactions(repository); if (this.transactions == null) { return false; } @@ -357,15 +368,19 @@ public class ArbitraryDataResource { } - - private void fetchTransactions() throws DataException { + /** + * Fetch relevant arbitrary transactions for resource + * + * @param repository + * @throws DataException + */ + private void fetchTransactions(Repository repository) throws DataException { if (this.transactions != null && !this.transactions.isEmpty()) { // Already fetched return; } - try (final Repository repository = RepositoryManager.getRepository()) { - + try { // Get the most recent PUT ArbitraryTransactionData latestPut = repository.getArbitraryRepository() .getLatestTransaction(this.resourceId, this.service, ArbitraryTransactionData.Method.PUT, this.identifier); diff --git a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java index a189adf2..c0d441e0 100644 --- a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java +++ b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java @@ -407,7 +407,7 @@ public class ArbitraryTransaction extends Transaction { // Update status ArbitraryDataResource resource = new ArbitraryDataResource(name, ArbitraryDataFile.ResourceIdType.NAME, service, identifier); - ArbitraryResourceStatus arbitraryResourceStatus = resource.getStatus(); + ArbitraryResourceStatus arbitraryResourceStatus = resource.getStatus(repository); ArbitraryResourceStatus.Status status = arbitraryResourceStatus != null ? arbitraryResourceStatus.getStatus() : null; repository.getArbitraryRepository().setStatus(arbitraryResourceData, status); }