diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index bf40feb8..fc5d5c29 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -694,7 +694,7 @@ public class ArbitraryResource { } ) @SecurityRequirement(name = "apiKey") - public String getMetadata(@HeaderParam(Security.API_KEY_HEADER) String apiKey, + public ArbitraryResourceMetadata getMetadata(@HeaderParam(Security.API_KEY_HEADER) String apiKey, @PathParam("service") Service service, @PathParam("name") String name, @PathParam("identifier") String identifier) { @@ -703,12 +703,20 @@ public class ArbitraryResource { ArbitraryDataResource resource = new ArbitraryDataResource(name, ResourceIdType.NAME, service, identifier); try { - byte[] metadata = ArbitraryMetadataManager.getInstance().fetchMetadata(resource, false); - if (metadata != null) { - return new String(metadata, StandardCharsets.UTF_8); + ArbitraryDataTransactionMetadata transactionMetadata = ArbitraryMetadataManager.getInstance().fetchMetadata(resource, false); + if (transactionMetadata != null) { + ArbitraryResourceMetadata resourceMetadata = ArbitraryResourceMetadata.fromTransactionMetadata(transactionMetadata); + if (resourceMetadata != null) { + return resourceMetadata; + } + else { + // The metadata file doesn't contain title, description, category, or tags + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.FILE_NOT_FOUND); + } } } catch (IllegalArgumentException e) { - throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_CRITERIA, e.getMessage()); + // No metadata exists for this resource + throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.FILE_NOT_FOUND, e.getMessage()); } throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_DATA); @@ -1279,7 +1287,7 @@ public class ArbitraryResource { ArbitraryDataTransactionMetadata transactionMetadata = resource.getLatestTransactionMetadata(); ArbitraryResourceMetadata resourceMetadata = ArbitraryResourceMetadata.fromTransactionMetadata(transactionMetadata); if (resourceMetadata != null) { - resourceInfo.metadata = ArbitraryResourceMetadata.fromTransactionMetadata(transactionMetadata); + resourceInfo.metadata = resourceMetadata; } updatedResources.add(resourceInfo); } diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java index 65ded8c9..b826a6e9 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java @@ -9,6 +9,7 @@ import org.apache.logging.log4j.Logger; import org.qortal.api.resource.TransactionsResource.ConfirmationStatus; import org.qortal.arbitrary.ArbitraryDataFile; import org.qortal.arbitrary.ArbitraryDataResource; +import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; import org.qortal.arbitrary.misc.Service; import org.qortal.controller.Controller; import org.qortal.data.network.ArbitraryPeerData; @@ -349,7 +350,7 @@ public class ArbitraryDataManager extends Thread { } // Entrypoint to request new metadata from peers - public byte[] fetchMetadata(ArbitraryTransactionData arbitraryTransactionData) { + public ArbitraryDataTransactionMetadata fetchMetadata(ArbitraryTransactionData arbitraryTransactionData) { ArbitraryDataResource resource = new ArbitraryDataResource( arbitraryTransactionData.getName(), diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java index b2b36355..99249b67 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java @@ -4,6 +4,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.arbitrary.ArbitraryDataFile; import org.qortal.arbitrary.ArbitraryDataResource; +import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; import org.qortal.controller.Controller; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.TransactionData; @@ -18,6 +19,7 @@ import org.qortal.utils.Base58; import org.qortal.utils.NTP; import org.qortal.utils.Triple; +import java.io.IOException; import java.util.*; import static org.qortal.controller.arbitrary.ArbitraryDataFileListManager.RELAY_REQUEST_MAX_DURATION; @@ -75,7 +77,7 @@ public class ArbitraryMetadataManager { } - public byte[] fetchMetadata(ArbitraryDataResource arbitraryDataResource, boolean useRateLimiter) { + public ArbitraryDataTransactionMetadata fetchMetadata(ArbitraryDataResource arbitraryDataResource, boolean useRateLimiter) { try (final Repository repository = RepositoryManager.getRepository()) { // Find latest transaction ArbitraryTransactionData latestTransaction = repository.getArbitraryRepository() @@ -91,17 +93,21 @@ public class ArbitraryMetadataManager { } ArbitraryDataFile metadataFile = ArbitraryDataFile.fromHash(metadataHash, signature); + if (!metadataFile.exists()) { + // Request from network + this.fetchArbitraryMetadata(latestTransaction, useRateLimiter); + } + + // Now check again as it may have been downloaded above if (metadataFile.exists()) { // Use local copy - return metadataFile.getBytes(); - } - else { - // Request from network - return this.fetchArbitraryMetadata(latestTransaction, useRateLimiter); + ArbitraryDataTransactionMetadata transactionMetadata = new ArbitraryDataTransactionMetadata(metadataFile.getFilePath()); + transactionMetadata.read(); + return transactionMetadata; } } - } catch (DataException e) { + } catch (DataException | IOException e) { LOGGER.error("Repository issue when fetching arbitrary transaction metadata", e); }