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

S3 support no preload patch #44

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
a8bd8d0
removed extraneous method
Sep 28, 2024
240066e
update model
Oct 3, 2024
d8b9ce5
bad jacs model version
Oct 3, 2024
7cfa12c
changes to support volumes on s3
cgoina Oct 6, 2024
aff0ed1
condition to allow switching to ktx sample after zarr sample
cgoina Oct 6, 2024
99c6caf
refactored to use the storage attributes
Oct 12, 2024
b105ac7
rough UI to set access and secret keys
Oct 14, 2024
9dcd22e
pass storage attributes
Oct 14, 2024
d9de308
pass in storage attributes from the dialog for sync root and import swc
Oct 15, 2024
67b88ff
use queryparam for datapath lookup
Oct 15, 2024
8e5e52c
set headers from a redirect
Oct 15, 2024
fa47f90
logging
Oct 15, 2024
ae7ef96
display credentials fields only if corresponding checkbox is ON
Oct 21, 2024
e11c76b
checkbox for visible storage credentials
Oct 21, 2024
4eacde1
checkbox for visible storage credentials
Oct 21, 2024
e11b353
Updated version to 9.21.RC1
Oct 23, 2024
919d56b
Updated module version to 3.78
Oct 23, 2024
81bb2ab
url changes in the unit test for finding the path
Oct 23, 2024
255c3f1
consider snapshot and release candidates as dev
Oct 24, 2024
6b2a9b5
Updated version to 9.21.RC2
Oct 24, 2024
2ae41df
Updated module version to 3.79
Oct 24, 2024
30d695d
Merge branch 'master' of github.com:JaneliaSciComp/workstation
Dec 5, 2024
5d48140
Merge branch 'master' into s3-support
Dec 5, 2024
afaf8df
update jade client api and jacs model
Dec 7, 2024
813a7d5
Merge branch 'master' of github.com:JaneliaSciComp/workstation
Jan 9, 2025
b3c679f
Merge branch 'master' into s3-support
Jan 9, 2025
76d5e1d
update pom version
Jan 9, 2025
ace7df2
No preloading
cgoina Jan 10, 2025
2b459e3
clean up
Jan 10, 2025
6af37e7
No preloading
cgoina Jan 10, 2025
f53d3f2
Merge branch 's3-support-no-preload-patch' of github.com:JaneliaSciCo…
cgoina Jan 10, 2025
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
4 changes: 2 additions & 2 deletions modules/AdministrationGUI/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
<parent>
<groupId>org.janelia</groupId>
<artifactId>workstation</artifactId>
<version>9.20.1</version>
<version>9.21.RC4</version>
<relativePath>../..</relativePath>
</parent>

<name>AdministrationGUI</name>
<groupId>org.janelia.workstation</groupId>
<artifactId>adminstration</artifactId>
<version>9.20.1</version>
<version>9.21.RC4</version>
<packaging>nbm</packaging>

<dependencies>
Expand Down
4 changes: 2 additions & 2 deletions modules/ColorDepthSearch/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
<parent>
<groupId>org.janelia</groupId>
<artifactId>workstation</artifactId>
<version>9.20.1</version>
<version>9.21.RC4</version>
<relativePath>../..</relativePath>
</parent>

<name>ColorDepthSearch</name>
<groupId>org.janelia.workstation</groupId>
<artifactId>colordepth</artifactId>
<version>9.20.1</version>
<version>9.21.RC4</version>
<packaging>nbm</packaging>

<dependencies>
Expand Down
4 changes: 2 additions & 2 deletions modules/CommonGUI/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
<parent>
<groupId>org.janelia</groupId>
<artifactId>workstation</artifactId>
<version>9.20.1</version>
<version>9.21.RC4</version>
<relativePath>../..</relativePath>
</parent>

<name>CommonGUI</name>
<groupId>org.janelia.workstation</groupId>
<artifactId>common-gui</artifactId>
<version>9.20.1</version>
<version>9.21.RC4</version>
<packaging>nbm</packaging>

<dependencies>
Expand Down
15 changes: 5 additions & 10 deletions modules/CommonLibraries/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
<parent>
<groupId>org.janelia</groupId>
<artifactId>workstation</artifactId>
<version>9.20.1</version>
<version>9.21.RC4</version>
<relativePath>../..</relativePath>
</parent>

<name>CommonLibraries</name>
<groupId>org.janelia.workstation</groupId>
<artifactId>libraries</artifactId>
<version>9.20.1</version>
<version>9.21.RC4</version>
<packaging>nbm</packaging>

<properties>
Expand Down Expand Up @@ -53,14 +53,6 @@
<groupId>org.janelia.jacs-model</groupId>
<artifactId>jacs-model-rendering</artifactId>
</dependency>
<dependency>
<groupId>org.janelia.jacs-storage</groupId>
<artifactId>jacsstorage-api</artifactId>
</dependency>
<dependency>
<groupId>org.janelia.jacs-storage</groupId>
<artifactId>jacsstorage-core</artifactId>
</dependency>
<dependency>
<groupId>org.janelia.jacs-storage</groupId>
<artifactId>jacsstorage-clients</artifactId>
Expand Down Expand Up @@ -776,6 +768,9 @@
<publicPackage>org.janelia.rendering</publicPackage>
<publicPackage>org.janelia.rendering.utils</publicPackage>
<publicPackage>org.janelia.rendering.ymlrepr</publicPackage>
<publicPackage>org.janelia.jacsstorage.clients.api</publicPackage>
<publicPackage>org.janelia.jacsstorage.clients.api.http</publicPackage>
<publicPackage>org.janelia.jacsstorage.clients.api.rendering</publicPackage>
<publicPackage>org.jdesktop.swingx.*</publicPackage>
<publicPackage>org.jnp.*</publicPackage>
<publicPackage>org.perf4j</publicPackage>
Expand Down
4 changes: 2 additions & 2 deletions modules/Core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
<parent>
<groupId>org.janelia</groupId>
<artifactId>workstation</artifactId>
<version>9.20.1</version>
<version>9.21.RC4</version>
<relativePath>../..</relativePath>
</parent>

<name>Core</name>
<groupId>org.janelia.workstation</groupId>
<artifactId>core</artifactId>
<version>9.20.1</version>
<version>9.21.RC4</version>
<packaging>nbm</packaging>

<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ public AsyncServiceMonitoringWorker executeColorDepthService(ColorDepthSearch se
// Invoke the service
ActivityLogHelper.logUserAction("AsyncServiceFacadeImpl.executeColorDepthService", search);
Long serviceId = asyncServiceClient.invokeService("colorDepthObjectSearch",
args, DEFAULT_PROCESSING_LOCATION, ImmutableMap.of());
args, DEFAULT_PROCESSING_LOCATION,
ImmutableMap.of(),
ImmutableMap.of() // invocation headers
);

// Create a monitoring worker
AsyncServiceMonitoringWorker executeWorker = new SearchMonitoringWorker(search, serviceId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ public void removeObjectStorage(List<String> storagePaths) {
WebTarget storageService = RestJsonClientManager.getInstance().getTarget(remoteStorageUrl, true);
for (String storagePath : storagePaths) {
WebTarget target = storageService.path("storage_content/storage_path_redirect")
.path(storagePath);
.queryParam("contentPath", storagePath);
Response response = target
.request("application/json")
.delete();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,11 @@ public boolean handleUnknownProperty(DeserializationContext ctxt, JsonParser jp,
return;
}

log.info("Redirect to {}", clientResponseContext.getLocation());
try (Response resp = clientRequestContext.getClient()
.target(clientResponseContext.getLocation())
.request()
.headers(clientRequestContext.getHeaders())
.method(clientRequestContext.getMethod())) {
clientResponseContext.setEntityStream((InputStream) resp.getEntity());
clientResponseContext.setStatusInfo(resp.getStatusInfo());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.Map;

import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

Expand Down Expand Up @@ -45,7 +46,8 @@ public AsyncServiceClient(String serverUrl) {
public Long invokeService(String serviceName,
List<String> serviceArgs,
String processingLocation,
Map<String, String> serviceResources) throws ServiceException {
Map<String, String> serviceResources,
Map<String, Object> invocationHeaders) throws ServiceException {
AsyncServiceData body = new AsyncServiceData();
if (serviceArgs != null) {
body.args.addAll(serviceArgs);
Expand All @@ -57,9 +59,12 @@ public Long invokeService(String serviceName,
body.processingLocation = processingLocation;
}
WebTarget target = service.path("async-services").path(serviceName);
Response response = target
.request("application/json")
.post(Entity.json(body));
Invocation.Builder requestInvocation = target
.request("application/json");
for (Map.Entry<String, Object> entry : invocationHeaders.entrySet()) {
requestInvocation = requestInvocation.header(entry.getKey(), String.valueOf(entry.getValue()));
}
Response response = requestInvocation.post(Entity.json(body));
if (response.getStatus() != 201) {
throw new ServiceException("Service " + serviceName + " returned status "+response.getStatus());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
package org.janelia.workstation.core.api.web;

import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.util.List;
import java.util.Optional;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Preconditions;

import org.apache.commons.lang3.RegExUtils;
import org.apache.commons.lang3.StringUtils;
import org.janelia.rendering.JADEBasedDataLocation;
import org.janelia.jacsstorage.clients.api.JadeResults;
import org.janelia.jacsstorage.clients.api.JadeStorageAttributes;
import org.janelia.jacsstorage.clients.api.JadeStorageVolume;
import org.janelia.jacsstorage.clients.api.http.HttpClientProvider;
import org.janelia.jacsstorage.clients.api.rendering.JadeBasedDataLocation;
import org.janelia.rendering.Streamable;
import org.janelia.rendering.utils.ClientProxy;
import org.janelia.rendering.utils.HttpClientProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -33,54 +29,18 @@ public class JadeServiceClient {

private static final Logger LOG = LoggerFactory.getLogger(JadeServiceClient.class);

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonAutoDetect(
fieldVisibility = JsonAutoDetect.Visibility.ANY,
setterVisibility = JsonAutoDetect.Visibility.NONE
)
private static class JadeResults<T> {
@JsonProperty
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
private List<T> resultList;
}

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonAutoDetect(
fieldVisibility = JsonAutoDetect.Visibility.ANY,
setterVisibility = JsonAutoDetect.Visibility.NONE
)
private static class JadeStorageVolume {
@JsonProperty
private String id;
@JsonProperty
private String storageServiceURL;
@JsonProperty
private String baseStorageRootDir;
@JsonProperty
private String storageVirtualPath;

String getVolumeStorageURI() {
try {
return UriBuilder.fromUri(new URI(storageServiceURL)).path("agent_storage/storage_volume").path(id).build().toString();
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e);
}
}

}

private final String jadeURL; // jade master node URL
private final HttpClientProvider httpClientProvider;
private final HttpClientProvider clientProvider;

public JadeServiceClient(String jadeURL, HttpClientProvider httpClientProvider) {
public JadeServiceClient(String jadeURL, HttpClientProvider clientProvider) {
Preconditions.checkArgument(StringUtils.isNotBlank(jadeURL));
this.jadeURL = jadeURL;
this.httpClientProvider = httpClientProvider;
this.clientProvider = clientProvider;
}

public Optional<String> findStorageURL(String storagePath) {
Preconditions.checkArgument(storagePath != null && storagePath.trim().length() > 0);
ClientProxy httpClient = getHttpClient();
Client httpClient = clientProvider.getClient();
try {
LOG.debug("Lookup storage for {}", storagePath);
WebTarget target = httpClient.target(jadeURL)
Expand All @@ -95,46 +55,45 @@ public Optional<String> findStorageURL(String storagePath) {
}
JadeResults<JadeStorageVolume> storageContentResults = response.readEntity(new GenericType<JadeResults<JadeStorageVolume>>() {
});
return storageContentResults.resultList.stream().findFirst().map(jadeVolume -> jadeVolume.storageServiceURL);
return storageContentResults.getResultList().stream().findFirst().map(JadeStorageVolume::getStorageServiceURL);
} finally {
httpClient.close();
}
}

public Optional<JADEBasedDataLocation> findDataLocation(String storagePathParam) {
public Optional<JadeBasedDataLocation> findDataLocation(String storagePathParam, JadeStorageAttributes storageAttributes) {
Preconditions.checkArgument(storagePathParam != null && storagePathParam.trim().length() > 0);
String storagePath = RegExUtils.replaceFirst(StringUtils.replaceChars(storagePathParam, '\\', '/'), "^((.+:)?/+)+", "/");
ClientProxy httpClient = getHttpClient();
Client httpClient = clientProvider.getClient();
try {
LOG.debug("Lookup storage for {}", storagePath);
WebTarget target = httpClient.target(jadeURL)
.path("storage_volumes")
.queryParam("dataStoragePath", storagePath);
Response response = target.request()
.get();
Response response = createRequest(target, storageAttributes).get();
int responseStatus = response.getStatus();
if (responseStatus != Response.Status.OK.getStatusCode()) {
LOG.error("Request to {} returned with status {}", target, responseStatus);
return Optional.empty();
}
JadeResults<JadeStorageVolume> storageContentResults = response.readEntity(new GenericType<JadeResults<JadeStorageVolume>>() {
});
return storageContentResults.resultList.stream().findFirst()
return storageContentResults.getResultList().stream().findFirst()
.map(jadeVolume -> {
String renderedVolumePath;
if (storagePath.startsWith(jadeVolume.storageVirtualPath)) {
renderedVolumePath = Paths.get(jadeVolume.storageVirtualPath).relativize(Paths.get(storagePath)).toString();
if (StringUtils.startsWith(storagePath, jadeVolume.getStorageVirtualPath())) {
renderedVolumePath = Paths.get(jadeVolume.getStorageVirtualPath()).relativize(Paths.get(storagePath)).toString();
} else {
renderedVolumePath = Paths.get(jadeVolume.baseStorageRootDir).relativize(Paths.get(storagePath)).toString();
renderedVolumePath = Paths.get(jadeVolume.getBaseStorageRootDir()).relativize(Paths.get(storagePath)).toString();
}
LOG.info("Create JADE volume location with URLs {}, {} and volume path {}", jadeVolume.storageServiceURL, jadeVolume.getVolumeStorageURI(), renderedVolumePath);
return new JADEBasedDataLocation(
jadeVolume.storageServiceURL,
LOG.info("Create JADE volume location with URLs {}, {} and volume path {}", jadeVolume.getStorageServiceURL(), jadeVolume.getVolumeStorageURI(), renderedVolumePath);
return new JadeBasedDataLocation(
jadeVolume.getStorageServiceURL(),
jadeVolume.getVolumeStorageURI(),
renderedVolumePath,
null,
null,
httpClientProvider);
storageAttributes);
})
;
} finally {
Expand All @@ -143,17 +102,16 @@ public Optional<JADEBasedDataLocation> findDataLocation(String storagePathParam)

}

public Streamable<InputStream> streamContent(String serverURL, String dataPath) {
public Streamable<InputStream> streamContent(String serverURL, String dataPath, JadeStorageAttributes storageAttributes) {
Preconditions.checkArgument(serverURL != null && serverURL.trim().length() > 0);
Preconditions.checkArgument(dataPath != null && dataPath.trim().length() > 0);
ClientProxy httpClient = getHttpClient();
Client httpClient = clientProvider.getClient();
try {
WebTarget target = httpClient.target(serverURL)
.path("agent_storage/storage_path/data_content")
.path(dataPath);
LOG.info("Streaming tile from {}", target);
Response response = target.request()
.get();
Response response = createRequest(target, storageAttributes).get();
int responseStatus = response.getStatus();
if (responseStatus == Response.Status.OK.getStatusCode()) {
InputStream is = (InputStream) response.getEntity();
Expand All @@ -167,16 +125,15 @@ public Streamable<InputStream> streamContent(String serverURL, String dataPath)
}
}

public boolean checkStoragePath(String storagePath) {
public boolean checkStoragePath(String storagePath, JadeStorageAttributes storageAttributes) {
Preconditions.checkArgument(storagePath != null && storagePath.trim().length() > 0);
ClientProxy httpClient = getHttpClient();
Client httpClient = clientProvider.getClient();
try {
LOG.debug("Check if storage path exists {}", storagePath);
WebTarget target = httpClient.target(jadeURL)
.path("storage_content/storage_path_redirect")
.path(storagePath);
Response response = target.request()
.head();
.queryParam("contentPath", storagePath);
Response response = createRequest(target, storageAttributes).head();
int responseStatus = response.getStatus();
if (responseStatus != Response.Status.OK.getStatusCode()) {
LOG.error("Request to {} returned with status {}", target, responseStatus);
Expand All @@ -189,8 +146,14 @@ public boolean checkStoragePath(String storagePath) {
}
}

private ClientProxy getHttpClient() {
return httpClientProvider.getClient();
private Invocation.Builder createRequest(WebTarget target, JadeStorageAttributes storageAttributes) {
Invocation.Builder requestBuilder = target.request();
for (String storageAttribute : storageAttributes.getAttributeNames()) {
requestBuilder = requestBuilder.header(
storageAttribute,
storageAttributes.getAttributeValue(storageAttribute)
);
}
return requestBuilder;
}

}
Loading
Loading