Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for specifying rendering definitions #3

Merged
merged 6 commits into from
Aug 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import org.slf4j.LoggerFactory;
Expand All @@ -41,7 +42,6 @@
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.json.Json;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Cookie;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.CookieHandler;
Expand Down Expand Up @@ -98,6 +98,9 @@ public void start(Future<Void> future) {
router.get(
"/webclient/render_thumbnail/size/:longestSide/:imageId*")
.handler(this::renderThumbnail);
router.get(
"/webclient/render_thumbnail/:imageId*")
.handler(this::renderThumbnail);
router.get(
"/webgateway/render_thumbnail/:imageId/:longestSide*")
.handler(this::renderThumbnail);
Expand Down Expand Up @@ -136,16 +139,19 @@ public void stop() throws Exception {
* @param event Current routing context.
*/
private void renderThumbnail(RoutingContext event) {
HttpServerRequest request = event.request();
final String longestSide =
request.getParam("longestSide") == null? "96"
: request.getParam("longestSide");
final Long imageId = Long.parseLong(request.getParam("imageId"));
final HttpServerRequest request = event.request();
final HttpServerResponse response = event.response();
Map<String, Object> data = new HashMap<String, Object>();
data.put("longestSide", Integer.parseInt(longestSide));
data.put("imageId", imageId);
final Map<String, Object> data = new HashMap<String, Object>();
data.put("longestSide",
Optional.ofNullable(request.getParam("longestSide"))
.map(Integer::parseInt)
.orElse(96));
data.put("imageId", Long.parseLong(request.getParam("imageId")));
data.put("omeroSessionKey", event.get("omero.session_key"));
data.put("renderingDefId",
Optional.ofNullable(request.getParam("rdefId"))
.map(Long::parseLong)
.orElse(null));

vertx.eventBus().send(
ThumbnailVerticle.RENDER_THUMBNAIL_EVENT,
Expand Down Expand Up @@ -182,17 +188,18 @@ private void renderThumbnail(RoutingContext event) {
* @param event Current routing context.
*/
private void getThumbnails(RoutingContext event) {
HttpServerRequest request = event.request();
final String longestSide =
request.getParam("longestSide") == null? "96"
: request.getParam("longestSide");
final List<Long> imageIds = request.params().getAll("id").stream()
.map(x -> Long.parseLong(x))
.collect(Collectors.toList());
final HttpServerRequest request = event.request();
final HttpServerResponse response = event.response();
Map<String, Object> data = new HashMap<String, Object>();
data.put("longestSide", Integer.parseInt(longestSide));
data.put("imageIds", imageIds.toArray());
final Map<String, Object> data = new HashMap<String, Object>();
data.put("longestSide",
Optional.ofNullable(request.getParam("longestSide"))
.map(Integer::parseInt)
.orElse(96));
data.put("imageIds",
request.params().getAll("id").stream()
.map(Long::parseLong)
.collect(Collectors.toList())
.toArray());
data.put("omeroSessionKey", event.get("omero.session_key"));

vertx.eventBus().send(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,23 @@

package com.glencoesoftware.omero.ms.thumbnail;

import static omero.rtypes.rint;
import static omero.rtypes.unwrap;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.perf4j.StopWatch;
import org.perf4j.slf4j.Slf4JStopWatch;
import org.slf4j.LoggerFactory;

import omero.ServerError;
import omero.api.ThumbnailStorePrx;
import omero.model.Image;
import omero.sys.EventContext;

/**
* OMERO session aware handler whose event handler method conforms to the
Expand All @@ -32,6 +45,31 @@
*/
public class ThumbnailRequestHandler extends ThumbnailsRequestHandler {

private static final org.slf4j.Logger log =
LoggerFactory.getLogger(ThumbnailRequestHandler.class);

/**
* {@link RenderingDef} identifier of the rendering settings to use when
* requesting the thumbnail.
*/
protected Optional<Long> renderingDefId;

/**
* Default constructor with the ability to specify a rendering definition
* to use when requesting the thumbnail.
* @param longestSide Size to confine or upscale the longest side of the
* thumbnail to. The other side will then proportionately, based on aspect
* ratio, be scaled accordingly.
* @param imageId {@link Image} identifier to request a thumbnail for.
* @param renderingDefId {@link RenderingDef} identifier of the rendering
* settings to use.
*/
public ThumbnailRequestHandler(
int longestSide, long imageId, Optional<Long> renderingDefId) {
super(longestSide, Arrays.asList(imageId));
this.renderingDefId = renderingDefId;
}

/**
* Default constructor.
* @param longestSide Size to confine or upscale the longest side of the
Expand All @@ -48,11 +86,110 @@ public ThumbnailRequestHandler(int longestSide, long imageId) {
* @return JPEG thumbnail byte array.
*/
public byte[] renderThumbnail(omero.client client) {
Map<Long, byte[]> thumbnails = renderThumbnails(client);
if (thumbnails == null) {
return null;
try {
List<Image> images = getImages(client, imageIds);
if (images.size() == 1) {
return getThumbnail(
client, images.get(0), longestSide, renderingDefId);
}
log.debug("Cannot find any Image:{}", imageIds.get(0));
} catch (Exception e) {
log.error("Exception while retrieving thumbnails", e);
}
return thumbnails.get(imageIds.get(0));
return null;
}

/**
* Retrieves a JPEG thumbnail from the server.
* @param client OMERO client to use for thumbnail retrieval.
* @param image {@link Image} to retrieve thumbnail for.
* @param longestSide Size to confine or upscale the longest side of each
* thumbnail to. The other side will then proportionately, based on aspect
* ratio, be scaled accordingly.
* @param renderingDefId {@link RenderingDef} identifier of the rendering
* settings to use. May be <code>null</code>.
* @return JPEG thumbnail byte array.
* @throws ServerError If there was any sort of error retrieving the
* thumbnail.
*/
protected byte[] getThumbnail(
omero.client client, Image image, int longestSide,
Optional<Long> renderingDefId)
throws ServerError{
ThumbnailStorePrx thumbnailStore =
client.getSession().createThumbnailStore();
try {
Map<String, String> ctx = new HashMap<String, String>();
long pixelsId = (Long) unwrap(image.getPrimaryPixels().getId());
// Assume all the groups are the same
ctx.put(
"omero.group",
String.valueOf(unwrap(
image.getDetails().getGroup().getId()))
);

boolean hasRenderingSettings =
setPixelsId(ctx, thumbnailStore, pixelsId);
if (renderingDefId.isPresent()) {
Slf4JStopWatch t0 = new Slf4JStopWatch("setRenderingDefId");
try {
thumbnailStore.setRenderingDefId(renderingDefId.get(), ctx);
} finally {
t0.stop();
}
}
if (!hasRenderingSettings) {
// Operate as the object owner if we are an administrator
EventContext eventContext =
client.getSession().getAdminService().getEventContext();
if (eventContext.memberOfGroups.contains(0)) {
ctx.put(
"omero.user",
String.valueOf(unwrap(
image.getDetails().getOwner().getId()))
);
}
Slf4JStopWatch t0 = new Slf4JStopWatch("resetDefaults");
try {
thumbnailStore.resetDefaults();
} finally {
t0.stop();
}
setPixelsId(ctx, thumbnailStore, pixelsId);
}

Slf4JStopWatch t0 = new Slf4JStopWatch("getThumbnailByLongestSide");
try {
return thumbnailStore.getThumbnailByLongestSide(
rint(longestSide), ctx);
} finally {
t0.stop();
}
} finally {
thumbnailStore.close();
}
}

/**
* Sets the {@link Pixels} identifier on a thumbnail store in an
* instrumented fashion.
* @param ctx Calling context.
* @param thumbnailStore Thumbnail store to set <code>pixelsId</code> on.
* @param pixelsId {@link Pixels} identifier to set.
* @return <code>true</code> if a set of rendering settings is available
* for the {@link Pixels} object identified by <code>pixelsId</code>
* otherwise <code>false</code>
* @throws ServerError If there was any sort of error setting the
* identifier.
*/
private boolean setPixelsId(
Map<String, String> ctx, ThumbnailStorePrx thumbnailStore,
long pixelsId) throws ServerError {
StopWatch t0 = new Slf4JStopWatch("setPixelsId");
try {
return thumbnailStore.setPixelsId(pixelsId, ctx);
} finally {
t0.stop();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Map.Entry;

import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -98,14 +99,16 @@ private void renderThumbnail(Message<String> message) {
String omeroSessionKey = data.getString("omeroSessionKey");
int longestSide = data.getInteger("longestSide");
long imageId = data.getLong("imageId");
Optional<Long> renderingDefId =
Optional.ofNullable(data.getLong("renderingDefId"));
log.debug(
"Render thumbnail request Image:{} longest side {}",
imageId, longestSide);
"Render thumbnail request Image:{} longest side {} RenderingDef:{}",
imageId, longestSide, renderingDefId.orElse(null));

try (OmeroRequest<byte[]> request = new OmeroRequest<byte[]>(
host, port, omeroSessionKey)) {
byte[] thumbnail = request.execute(new ThumbnailRequestHandler(
longestSide, imageId)::renderThumbnail);
longestSide, imageId, renderingDefId)::renderThumbnail);
if (thumbnail == null) {
message.fail(404, "Cannot find Image:" + imageId);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public Map<Long, byte[]> renderThumbnails(omero.client client) {
}

/**
* Retrieves a single {@link Image} from the server.
* Retrieves a list of loaded {@link Image}s from the server.
* @param client OMERO client to use for querying.
* @param imageIds {@link Image} identifiers to query for.
* @return List of loaded {@link Image} and primary {@link Pixels}.
Expand Down