001/*- 002 * #%L 003 * HAPI FHIR Storage api 004 * %% 005 * Copyright (C) 2014 - 2024 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.jpa.binary.api; 021 022import ca.uhn.fhir.rest.api.server.RequestDetails; 023import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; 024import jakarta.annotation.Nonnull; 025import org.hl7.fhir.instance.model.api.IBaseBinary; 026import org.hl7.fhir.instance.model.api.IIdType; 027 028import java.io.IOException; 029import java.io.InputStream; 030import java.io.OutputStream; 031 032public interface IBinaryStorageSvc { 033 034 /** 035 * Gets the maximum number of bytes that can be stored in a single binary 036 * file by this service. The default is {@link Long#MAX_VALUE} 037 */ 038 long getMaximumBinarySize(); 039 040 /** 041 * Given a blob ID, return true if it is valid for the underlying storage mechanism, false otherwise. 042 * 043 * @param theNewBlobId the blob ID to validate 044 * @return true if the blob ID is valid, false otherwise. 045 */ 046 default boolean isValidBinaryContentId(String theNewBlobId) { 047 return true; // default method here as we don't want to break existing implementations 048 } 049 050 /** 051 * Sets the maximum number of bytes that can be stored in a single binary 052 * file by this service. The default is {@link Long#MAX_VALUE} 053 * 054 * @param theMaximumBinarySize The maximum size 055 */ 056 void setMaximumBinarySize(long theMaximumBinarySize); 057 058 /** 059 * Gets the minimum number of bytes that will be stored. Binary content smaller 060 * * than this threshold may be inlined even if a binary storage service 061 * * is active. 062 */ 063 int getMinimumBinarySize(); 064 065 /** 066 * Sets the minimum number of bytes that will be stored. Binary content smaller 067 * than this threshold may be inlined even if a binary storage service 068 * is active. 069 */ 070 void setMinimumBinarySize(int theMinimumBinarySize); 071 072 /** 073 * Give the storage service the ability to veto items from storage 074 * 075 * @param theSize How large is the item 076 * @param theResourceId What is the resource ID it will be associated with 077 * @param theContentType What is the content type 078 * @return <code>true</code> if the storage service should store the item 079 */ 080 boolean shouldStoreBinaryContent(long theSize, IIdType theResourceId, String theContentType); 081 082 /** 083 * Generate a new binaryContent ID that will be passed to {@link #storeBinaryContent(IIdType, String, String, InputStream)} later 084 */ 085 String newBinaryContentId(); 086 087 /** 088 * Store a new binary blob 089 * 090 * @param theResourceId The resource ID that owns this blob. Note that it should not be possible to retrieve a blob without both the resource ID and the blob ID being correct. 091 * @param theBlobIdOrNull If set, forces 092 * @param theContentType The content type to associate with this blob 093 * @param theInputStream An InputStream to read from. This method should close the stream when it has been fully consumed. 094 * @return Returns details about the stored data 095 * @deprecated Use {@link #storeBinaryContent(IIdType theResourceId, String theBlobIdOrNull, String theContentType, 096 * InputStream theInputStream, RequestDetails theRequestDetails)} instead. This method 097 * will be removed because it doesn't receive the 'theRequestDetails' parameter it needs to forward to the pointcut) 098 */ 099 @Deprecated(since = "6.6.0", forRemoval = true) 100 @Nonnull 101 default StoredDetails storeBinaryContent( 102 IIdType theResourceId, String theBlobIdOrNull, String theContentType, InputStream theInputStream) 103 throws IOException { 104 return storeBinaryContent( 105 theResourceId, theBlobIdOrNull, theContentType, theInputStream, new ServletRequestDetails()); 106 } 107 108 /** 109 * Store a new binary blob 110 * 111 * @param theResourceId The resource ID that owns this blob. Note that it should not be possible to retrieve a blob without both the resource ID and the blob ID being correct. 112 * @param theBlobIdOrNull If set, forces 113 * @param theContentType The content type to associate with this blob 114 * @param theInputStream An InputStream to read from. This method should close the stream when it has been fully consumed. 115 * @param theRequestDetails The operation request details. 116 * @return Returns details about the stored data 117 */ 118 @Nonnull 119 StoredDetails storeBinaryContent( 120 IIdType theResourceId, 121 String theBlobIdOrNull, 122 String theContentType, 123 InputStream theInputStream, 124 RequestDetails theRequestDetails) 125 throws IOException; 126 127 StoredDetails fetchBinaryContentDetails(IIdType theResourceId, String theBlobId) throws IOException; 128 129 /** 130 * @return Returns <code>true</code> if the blob was found and written, of <code>false</code> if the blob was not found (i.e. it was expunged or the ID was invalid) 131 */ 132 boolean writeBinaryContent(IIdType theResourceId, String theBlobId, OutputStream theOutputStream) 133 throws IOException; 134 135 void expungeBinaryContent(IIdType theResourceId, String theBlobId); 136 137 /** 138 * Fetch the contents of the given blob 139 * 140 * @param theResourceId The resource ID 141 * @param theBlobId The blob ID 142 * @return The payload as a byte array 143 */ 144 byte[] fetchBinaryContent(IIdType theResourceId, String theBlobId) throws IOException; 145 146 /** 147 * Fetch the byte[] contents of a given Binary resource's `data` element. If the data is a standard base64encoded string that is embedded, return it. 148 * Otherwise, attempt to load the externalized binary blob via the the externalized binary storage service. 149 * 150 * @param theResource The Binary resource you want to extract data bytes from 151 * @return The binary data blob as a byte array 152 */ 153 byte[] fetchDataByteArrayFromBinary(IBaseBinary theResource) throws IOException; 154}