package eu.europeana.cloud.service.mcs.inmemory; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Repository; import com.google.common.io.BaseEncoding; import com.google.common.io.ByteStreams; import eu.europeana.cloud.common.model.File; import eu.europeana.cloud.service.mcs.exception.FileNotExistsException; import eu.europeana.cloud.service.mcs.exception.WrongContentRangeException; /** * InMemoryContentDAO */ @Repository public class InMemoryContentDAO { private final Map<String, byte[]> content = new HashMap<>(); public void putContent(String globalId, String schema, String version, File file, InputStream data) throws IOException { DigestInputStream md5DigestInputStream = md5InputStream(data); byte[] fileContent = ByteStreams.toByteArray(md5DigestInputStream); String actualContentMd5Hex = BaseEncoding.base16().lowerCase() .encode(md5DigestInputStream.getMessageDigest().digest()); int actualContentLength = fileContent.length; file.setContentLength(actualContentLength); file.setMd5(actualContentMd5Hex); content.put(generateKey(globalId, schema, version, file.getFileName()), fileContent); } private DigestInputStream md5InputStream(InputStream is) { try { MessageDigest md = MessageDigest.getInstance("MD5"); return new DigestInputStream(is, md); } catch (NoSuchAlgorithmException ex) { throw new AssertionError("Cannot get instance of MD5 but such algorithm should be provided", ex); } } public void getContent(String globalId, String schema, String version, String fileName, long rangeStart, long rangeEnd, OutputStream os) throws IOException, FileNotExistsException, WrongContentRangeException { byte[] data = content.get(generateKey(globalId, schema, version, fileName)); if (data == null) { throw new FileNotExistsException(); } if (rangeStart != -1) { if (rangeStart > data.length - 1) { throw new WrongContentRangeException("Cannot satisfy requested range - data length is " + data.length); } data = Arrays.copyOfRange(data, (int) rangeStart, (int) ((rangeEnd == -1 || rangeEnd > data.length - 1) ? data.length - 1 : rangeEnd) + 1); } os.write(data); } public void copyContent(String srcGlobalId, String srcRepName, String srcVersion, String srcFileName, String trgGlobalId, String trgRepName, String trgVersion, String trgFileName) throws FileNotExistsException { String srcKey = generateKey(srcGlobalId, srcRepName, srcVersion, srcFileName); String trgKey = generateKey(trgGlobalId, trgRepName, trgVersion, trgFileName); byte[] data = content.get(srcKey); if (data == null) { throw new FileNotExistsException(); } content.put(trgKey, data); } private String generateKey(String recordId, String repName, String version, String fileName) { return recordId + "|" + repName + "|" + version + "|" + fileName; } public void deleteContent(String globalId, String schema, String version, String fileName) throws FileNotExistsException { content.remove(generateKey(globalId, schema, version, fileName)); } }