package eu.europeana.cloud.service.mcs.rest.storage.selector;
import com.google.common.collect.ImmutableSet;
import eu.europeana.cloud.service.mcs.Storage;
import org.apache.tika.mime.MediaType;
import javax.ws.rs.BadRequestException;
import java.io.IOException;
import java.util.Set;
/**
* Select {@link Storage} based on {@link MediaType} and data size.
*
* @author krystian.
*/
public class StorageSelector {
private static final Set<MediaType> STORE_ONLY_IN_OBJECT_STORAGE =
ImmutableSet.of(MediaType.image("jp2"));
private final PreBufferedInputStream inputStream;
private final int objectStoreSizeThreshold;
private final MediaType userMediaType;
/**
* Creates {@link StorageSelector}.
* @param inputStream input stream
* @param userMediaType
*/
public StorageSelector(final PreBufferedInputStream inputStream, final String userMediaType) {
this.inputStream = inputStream;
this.objectStoreSizeThreshold = inputStream.getBufferSize();
this.userMediaType = MediaType.parse(userMediaType);
}
/**
* Select {@link Storage}.
* @return chosen storage
*/
public Storage selectStorage() {
return decide(assertUserMediaType(), getAvailable());
}
/**
* Make decision based {@link MediaType} and data size.
* @param detected media type
* @param available data size
* @return
*/
protected Storage decide(MediaType detected, int available) {
if (!STORE_ONLY_IN_OBJECT_STORAGE.contains(detected) && objectStoreSizeThreshold > available) {
return Storage.DATA_BASE;
} else {
return Storage.OBJECT_STORAGE;
}
}
private int getAvailable() {
int available;
try {
available = inputStream.available();
} catch (IOException e) {
throw new BadRequestException("Unable to check data content length!", e);
}
return available;
}
private MediaType assertUserMediaType() {
MediaType detected;
try {
detected = ContentStreamDetector.detectMediaType(inputStream);
} catch (IOException e) {
throw new BadRequestException("Unable to detect mime type.", e);
}
if (userMediaType == null || !userMediaType.equals(detected)) {
throw new BadRequestException("Provided media type does not match to content media type!");
}
return detected;
}
}