Skip to content

Commit

Permalink
New stable version of API 0.2.13 that includes fetchMediaImageRegion
Browse files Browse the repository at this point in the history
  • Loading branch information
shaeberling committed Aug 19, 2023
1 parent ad2492f commit 3edb87c
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 7 deletions.
6 changes: 3 additions & 3 deletions appengine/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ dependencies {

// Specific Retrostore AppEngine dependencies..
implementation 'com.google.protobuf:protobuf-lite:3.0.0'
implementation 'org.retrostore:retrostore-client:0.2.9'
implementation 'org.retrostore:retrostore-client:0.2.13'
implementation "com.google.guava:guava:20.0"
implementation "com.googlecode.objectify:objectify:5.1.22"
implementation "com.google.code.gson:gson:2.8.0"
Expand Down Expand Up @@ -59,5 +59,5 @@ appengine {
}
}

sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,14 @@ private ApiResponseMediaImageRefs callInternal(FetchMediaImagesApiCall.Params pa
// Skip empty/UNKNOWN entries.
if (image.getData().size() == 0) continue;

String ref = params.appId + "/" + image.getFilename();
String token = params.appId + "/" + image.getFilename();
response.addMediaImageRef(MediaImageRef.newBuilder()
.setType(image.getType())
.setFilename(image.getFilename())
.setSize(image.getData().size())
.setUploadTime(image.getUploadTime())
.setDescription(image.getDescription())
.setDataRef(ref));
.setToken(token));
}

return response.setSuccess(true).setMessage("All good :-)").build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package org.retrostore.rpc.api;

import com.google.protobuf.InvalidProtocolBufferException;
import org.retrostore.client.common.proto.ApiResponseMediaImageRefs;
import org.retrostore.client.common.proto.ApiResponseMediaImages;
import org.retrostore.client.common.proto.DownloadSystemStateMemoryRegionParams;
import org.retrostore.client.common.proto.FetchMediaImageRegionParams;
import org.retrostore.client.common.proto.MediaImage;
import org.retrostore.client.common.proto.MediaImageRef;
import org.retrostore.data.app.AppManagement;
import org.retrostore.data.app.AppStoreItem;
import org.retrostore.data.xray.StateManagement;
import org.retrostore.data.xray.SystemState;
import org.retrostore.request.RequestData;
import org.retrostore.request.Responder;
import org.retrostore.request.Response;
import org.retrostore.rpc.internal.ApiCall;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Logger;

public class FetchMediaImageRegionApiCall implements ApiCall {
private static final Logger log = Logger.getLogger("DownloadStateApiCall");
private static final Map<String, byte[]> CACHE = new HashMap<>();

private final FetchMediaImagesApiCall mediaImageCall;

public FetchMediaImageRegionApiCall(AppManagement appManagement) {
mediaImageCall = new FetchMediaImagesApiCall(appManagement);
}

@Override
public String getName() {
return "fetchMediaImageRegion";
}

@Override
public Response call(RequestData data) {
FetchMediaImageRegionParams apiParams;
try {
apiParams = FetchMediaImageRegionParams.parseFrom(data.getRawBody());
} catch (InvalidProtocolBufferException e) {
String errMsg = "Cannot parse ProtoBuf params: " + e.getMessage();
log.warning(errMsg);
return responder -> responder.respond(new byte[0], Responder.ContentType.BYTES);
}


if (apiParams == null || apiParams.getToken().isBlank()) {
String errMsg = "Illegal params. Ensure 'token' is set.";
log.warning(errMsg);
return responder -> responder.respond(new byte[0], Responder.ContentType.BYTES);
}
String[] tokenSplit = apiParams.getToken().split("/");

if (tokenSplit.length != 2 || tokenSplit[0].isBlank() || tokenSplit[1].isBlank()) {
String errMsg = "Illegal params. Ensure 'token' has the right format.";
log.warning(errMsg);
return responder -> responder.respond(new byte[0], Responder.ContentType.BYTES);
}
String paramAppId = tokenSplit[0];
String paramFileName = tokenSplit[1];


if (apiParams.getStart() < 0) {
log.warning("Illegal params. Ensure 'start' is > 0.");
return responder -> responder.respond(new byte[0], Responder.ContentType.BYTES);
}
if (apiParams.getLength() <= 0 || apiParams.getLength() > 10 << 18) {
log.warning("Illegal params. Ensure 'length' is > 0 and not too large.");
return responder -> responder.respond(new byte[0], Responder.ContentType.BYTES);
}

// Check if the image is already in the runtime cache. If not, load it.
if (!CACHE.containsKey(apiParams.getToken())) {
FetchMediaImagesApiCall.Params mediaImageParams =
new FetchMediaImagesApiCall.Params(paramAppId, Set.of());


// Piggyback on top of the original media image fetch call, to avoid code duplication.
ApiResponseMediaImages mediaImages = mediaImageCall.callInternal(mediaImageParams);

// Return error if fetching the media images failed.
if (!mediaImages.getSuccess()) {
log.warning("Could not obtain media images.");
return responder -> responder.respond(new byte[0], Responder.ContentType.BYTES);
}

// Convert all media images to references.
for (MediaImage image : mediaImages.getMediaImageList()) {
// Skip empty/UNKNOWN entries.
if (image.getData().size() == 0) continue;

if (image.getFilename().equals(paramFileName)) {
CACHE.put(apiParams.getToken(), image.getData().toByteArray());
break;
}
}
}

byte[] mediaImageBytes = CACHE.get(apiParams.getToken());

// Ensure we don't copy beyond the actual size of the image.
int maxLength = mediaImageBytes.length - apiParams.getStart();
int len = Math.max(0, Math.min(maxLength, apiParams.getLength()));
byte[] result = new byte[len];

if (apiParams.getStart() <= mediaImageBytes.length) {
System.arraycopy(mediaImageBytes, apiParams.getStart(), result, 0, len);
}
return responder -> responder.respond(result, Responder.ContentType.BYTES);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.retrostore.rpc.api.DownloadStateApiCall;
import org.retrostore.rpc.api.DownloadStateMemoryRegionApiCall;
import org.retrostore.rpc.api.FetchMediaImageRefsApiCall;
import org.retrostore.rpc.api.FetchMediaImageRegionApiCall;
import org.retrostore.rpc.api.FetchMediaImagesApiCall;
import org.retrostore.rpc.api.GetAppApiCall;
import org.retrostore.rpc.api.ListAppsApiCall;
Expand Down Expand Up @@ -57,6 +58,7 @@ public ApiRequest(AppManagement appManagement, ImageServiceWrapper imageService,
new ListAppsNanoApiCall(appManagement, imageService),
new FetchMediaImagesApiCall(appManagement),
new FetchMediaImageRefsApiCall(appManagement),
new FetchMediaImageRegionApiCall(appManagement),
new UploadStateApiCall(stateManagement),
new DownloadStateApiCall(stateManagement),
new DownloadStateMemoryRegionApiCall(stateManagement));
Expand Down
4 changes: 2 additions & 2 deletions appengine/src/main/webapp/WEB-INF/appengine-web.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<runtime>java8</runtime>
<threadsafe>true</threadsafe>
<runtime>java11</runtime>
<app-engine-apis>true</app-engine-apis>
<ssl-enabled>true</ssl-enabled>

<system-properties>
Expand Down

0 comments on commit 3edb87c

Please sign in to comment.