Skip to content

Commit 837c5da

Browse files
authored
Merge pull request #45 from JaneliaSciComp/s3-support
S3 support
2 parents 9a8542c + 9c72fa2 commit 837c5da

File tree

61 files changed

+620
-425
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+620
-425
lines changed

modules/AdministrationGUI/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
<parent>
66
<groupId>org.janelia</groupId>
77
<artifactId>workstation</artifactId>
8-
<version>9.20.1</version>
8+
<version>9.21.RC4</version>
99
<relativePath>../..</relativePath>
1010
</parent>
1111

1212
<name>AdministrationGUI</name>
1313
<groupId>org.janelia.workstation</groupId>
1414
<artifactId>adminstration</artifactId>
15-
<version>9.20.1</version>
15+
<version>9.21.RC4</version>
1616
<packaging>nbm</packaging>
1717

1818
<dependencies>

modules/ColorDepthSearch/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
<parent>
66
<groupId>org.janelia</groupId>
77
<artifactId>workstation</artifactId>
8-
<version>9.20.1</version>
8+
<version>9.21.RC4</version>
99
<relativePath>../..</relativePath>
1010
</parent>
1111

1212
<name>ColorDepthSearch</name>
1313
<groupId>org.janelia.workstation</groupId>
1414
<artifactId>colordepth</artifactId>
15-
<version>9.20.1</version>
15+
<version>9.21.RC4</version>
1616
<packaging>nbm</packaging>
1717

1818
<dependencies>

modules/CommonGUI/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
<parent>
66
<groupId>org.janelia</groupId>
77
<artifactId>workstation</artifactId>
8-
<version>9.20.1</version>
8+
<version>9.21.RC4</version>
99
<relativePath>../..</relativePath>
1010
</parent>
1111

1212
<name>CommonGUI</name>
1313
<groupId>org.janelia.workstation</groupId>
1414
<artifactId>common-gui</artifactId>
15-
<version>9.20.1</version>
15+
<version>9.21.RC4</version>
1616
<packaging>nbm</packaging>
1717

1818
<dependencies>

modules/CommonLibraries/pom.xml

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
<parent>
66
<groupId>org.janelia</groupId>
77
<artifactId>workstation</artifactId>
8-
<version>9.20.1</version>
8+
<version>9.21.RC4</version>
99
<relativePath>../..</relativePath>
1010
</parent>
1111

1212
<name>CommonLibraries</name>
1313
<groupId>org.janelia.workstation</groupId>
1414
<artifactId>libraries</artifactId>
15-
<version>9.20.1</version>
15+
<version>9.21.RC4</version>
1616
<packaging>nbm</packaging>
1717

1818
<properties>
@@ -53,14 +53,6 @@
5353
<groupId>org.janelia.jacs-model</groupId>
5454
<artifactId>jacs-model-rendering</artifactId>
5555
</dependency>
56-
<dependency>
57-
<groupId>org.janelia.jacs-storage</groupId>
58-
<artifactId>jacsstorage-api</artifactId>
59-
</dependency>
60-
<dependency>
61-
<groupId>org.janelia.jacs-storage</groupId>
62-
<artifactId>jacsstorage-core</artifactId>
63-
</dependency>
6456
<dependency>
6557
<groupId>org.janelia.jacs-storage</groupId>
6658
<artifactId>jacsstorage-clients</artifactId>
@@ -776,6 +768,9 @@
776768
<publicPackage>org.janelia.rendering</publicPackage>
777769
<publicPackage>org.janelia.rendering.utils</publicPackage>
778770
<publicPackage>org.janelia.rendering.ymlrepr</publicPackage>
771+
<publicPackage>org.janelia.jacsstorage.clients.api</publicPackage>
772+
<publicPackage>org.janelia.jacsstorage.clients.api.http</publicPackage>
773+
<publicPackage>org.janelia.jacsstorage.clients.api.rendering</publicPackage>
779774
<publicPackage>org.jdesktop.swingx.*</publicPackage>
780775
<publicPackage>org.jnp.*</publicPackage>
781776
<publicPackage>org.perf4j</publicPackage>

modules/Core/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
<parent>
66
<groupId>org.janelia</groupId>
77
<artifactId>workstation</artifactId>
8-
<version>9.20.1</version>
8+
<version>9.21.RC4</version>
99
<relativePath>../..</relativePath>
1010
</parent>
1111

1212
<name>Core</name>
1313
<groupId>org.janelia.workstation</groupId>
1414
<artifactId>core</artifactId>
15-
<version>9.20.1</version>
15+
<version>9.21.RC4</version>
1616
<packaging>nbm</packaging>
1717

1818
<dependencies>

modules/Core/src/main/java/org/janelia/workstation/core/api/facade/impl/rest/AsyncServiceFacadeImpl.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ public AsyncServiceMonitoringWorker executeColorDepthService(ColorDepthSearch se
3636
// Invoke the service
3737
ActivityLogHelper.logUserAction("AsyncServiceFacadeImpl.executeColorDepthService", search);
3838
Long serviceId = asyncServiceClient.invokeService("colorDepthObjectSearch",
39-
args, DEFAULT_PROCESSING_LOCATION, ImmutableMap.of());
39+
args, DEFAULT_PROCESSING_LOCATION,
40+
ImmutableMap.of(),
41+
ImmutableMap.of() // invocation headers
42+
);
4043

4144
// Create a monitoring worker
4245
AsyncServiceMonitoringWorker executeWorker = new SearchMonitoringWorker(search, serviceId);

modules/Core/src/main/java/org/janelia/workstation/core/api/facade/impl/rest/DomainFacadeImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ public void removeObjectStorage(List<String> storagePaths) {
208208
WebTarget storageService = RestJsonClientManager.getInstance().getTarget(remoteStorageUrl, true);
209209
for (String storagePath : storagePaths) {
210210
WebTarget target = storageService.path("storage_content/storage_path_redirect")
211-
.path(storagePath);
211+
.queryParam("contentPath", storagePath);
212212
Response response = target
213213
.request("application/json")
214214
.delete();

modules/Core/src/main/java/org/janelia/workstation/core/api/http/RestJsonClientManager.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,11 @@ public boolean handleUnknownProperty(DeserializationContext ctxt, JsonParser jp,
9595
return;
9696
}
9797

98+
log.info("Redirect to {}", clientResponseContext.getLocation());
9899
try (Response resp = clientRequestContext.getClient()
99100
.target(clientResponseContext.getLocation())
100101
.request()
102+
.headers(clientRequestContext.getHeaders())
101103
.method(clientRequestContext.getMethod())) {
102104
clientResponseContext.setEntityStream((InputStream) resp.getEntity());
103105
clientResponseContext.setStatusInfo(resp.getStatusInfo());

modules/Core/src/main/java/org/janelia/workstation/core/api/web/AsyncServiceClient.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.util.Map;
88

99
import javax.ws.rs.client.Entity;
10+
import javax.ws.rs.client.Invocation;
1011
import javax.ws.rs.client.WebTarget;
1112
import javax.ws.rs.core.Response;
1213

@@ -45,7 +46,8 @@ public AsyncServiceClient(String serverUrl) {
4546
public Long invokeService(String serviceName,
4647
List<String> serviceArgs,
4748
String processingLocation,
48-
Map<String, String> serviceResources) throws ServiceException {
49+
Map<String, String> serviceResources,
50+
Map<String, Object> invocationHeaders) throws ServiceException {
4951
AsyncServiceData body = new AsyncServiceData();
5052
if (serviceArgs != null) {
5153
body.args.addAll(serviceArgs);
@@ -57,9 +59,12 @@ public Long invokeService(String serviceName,
5759
body.processingLocation = processingLocation;
5860
}
5961
WebTarget target = service.path("async-services").path(serviceName);
60-
Response response = target
61-
.request("application/json")
62-
.post(Entity.json(body));
62+
Invocation.Builder requestInvocation = target
63+
.request("application/json");
64+
for (Map.Entry<String, Object> entry : invocationHeaders.entrySet()) {
65+
requestInvocation = requestInvocation.header(entry.getKey(), String.valueOf(entry.getValue()));
66+
}
67+
Response response = requestInvocation.post(Entity.json(body));
6368
if (response.getStatus() != 201) {
6469
throw new ServiceException("Service " + serviceName + " returned status "+response.getStatus());
6570
}
Lines changed: 39 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,24 @@
11
package org.janelia.workstation.core.api.web;
22

33
import java.io.InputStream;
4-
import java.net.URI;
5-
import java.net.URISyntaxException;
64
import java.nio.file.Paths;
7-
import java.util.List;
85
import java.util.Optional;
96

7+
import javax.ws.rs.client.Client;
8+
import javax.ws.rs.client.Invocation;
109
import javax.ws.rs.client.WebTarget;
1110
import javax.ws.rs.core.GenericType;
1211
import javax.ws.rs.core.Response;
13-
import javax.ws.rs.core.UriBuilder;
1412

15-
import com.fasterxml.jackson.annotation.JsonAutoDetect;
16-
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
17-
import com.fasterxml.jackson.annotation.JsonProperty;
1813
import com.google.common.base.Preconditions;
19-
2014
import org.apache.commons.lang3.RegExUtils;
2115
import org.apache.commons.lang3.StringUtils;
22-
import org.janelia.rendering.JADEBasedDataLocation;
16+
import org.janelia.jacsstorage.clients.api.JadeResults;
17+
import org.janelia.jacsstorage.clients.api.JadeStorageAttributes;
18+
import org.janelia.jacsstorage.clients.api.JadeStorageVolume;
19+
import org.janelia.jacsstorage.clients.api.http.HttpClientProvider;
20+
import org.janelia.jacsstorage.clients.api.rendering.JadeBasedDataLocation;
2321
import org.janelia.rendering.Streamable;
24-
import org.janelia.rendering.utils.ClientProxy;
25-
import org.janelia.rendering.utils.HttpClientProvider;
2622
import org.slf4j.Logger;
2723
import org.slf4j.LoggerFactory;
2824

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

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

36-
@JsonIgnoreProperties(ignoreUnknown = true)
37-
@JsonAutoDetect(
38-
fieldVisibility = JsonAutoDetect.Visibility.ANY,
39-
setterVisibility = JsonAutoDetect.Visibility.NONE
40-
)
41-
private static class JadeResults<T> {
42-
@JsonProperty
43-
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
44-
private List<T> resultList;
45-
}
46-
47-
@JsonIgnoreProperties(ignoreUnknown = true)
48-
@JsonAutoDetect(
49-
fieldVisibility = JsonAutoDetect.Visibility.ANY,
50-
setterVisibility = JsonAutoDetect.Visibility.NONE
51-
)
52-
private static class JadeStorageVolume {
53-
@JsonProperty
54-
private String id;
55-
@JsonProperty
56-
private String storageServiceURL;
57-
@JsonProperty
58-
private String baseStorageRootDir;
59-
@JsonProperty
60-
private String storageVirtualPath;
61-
62-
String getVolumeStorageURI() {
63-
try {
64-
return UriBuilder.fromUri(new URI(storageServiceURL)).path("agent_storage/storage_volume").path(id).build().toString();
65-
} catch (URISyntaxException e) {
66-
throw new IllegalArgumentException(e);
67-
}
68-
}
69-
70-
}
71-
7232
private final String jadeURL; // jade master node URL
73-
private final HttpClientProvider httpClientProvider;
33+
private final HttpClientProvider clientProvider;
7434

75-
public JadeServiceClient(String jadeURL, HttpClientProvider httpClientProvider) {
35+
public JadeServiceClient(String jadeURL, HttpClientProvider clientProvider) {
7636
Preconditions.checkArgument(StringUtils.isNotBlank(jadeURL));
7737
this.jadeURL = jadeURL;
78-
this.httpClientProvider = httpClientProvider;
38+
this.clientProvider = clientProvider;
7939
}
8040

8141
public Optional<String> findStorageURL(String storagePath) {
8242
Preconditions.checkArgument(storagePath != null && storagePath.trim().length() > 0);
83-
ClientProxy httpClient = getHttpClient();
43+
Client httpClient = clientProvider.getClient();
8444
try {
8545
LOG.debug("Lookup storage for {}", storagePath);
8646
WebTarget target = httpClient.target(jadeURL)
@@ -95,46 +55,45 @@ public Optional<String> findStorageURL(String storagePath) {
9555
}
9656
JadeResults<JadeStorageVolume> storageContentResults = response.readEntity(new GenericType<JadeResults<JadeStorageVolume>>() {
9757
});
98-
return storageContentResults.resultList.stream().findFirst().map(jadeVolume -> jadeVolume.storageServiceURL);
58+
return storageContentResults.getResultList().stream().findFirst().map(JadeStorageVolume::getStorageServiceURL);
9959
} finally {
10060
httpClient.close();
10161
}
10262
}
10363

104-
public Optional<JADEBasedDataLocation> findDataLocation(String storagePathParam) {
64+
public Optional<JadeBasedDataLocation> findDataLocation(String storagePathParam, JadeStorageAttributes storageAttributes) {
10565
Preconditions.checkArgument(storagePathParam != null && storagePathParam.trim().length() > 0);
10666
String storagePath = RegExUtils.replaceFirst(StringUtils.replaceChars(storagePathParam, '\\', '/'), "^((.+:)?/+)+", "/");
107-
ClientProxy httpClient = getHttpClient();
67+
Client httpClient = clientProvider.getClient();
10868
try {
10969
LOG.debug("Lookup storage for {}", storagePath);
11070
WebTarget target = httpClient.target(jadeURL)
11171
.path("storage_volumes")
11272
.queryParam("dataStoragePath", storagePath);
113-
Response response = target.request()
114-
.get();
73+
Response response = createRequest(target, storageAttributes).get();
11574
int responseStatus = response.getStatus();
11675
if (responseStatus != Response.Status.OK.getStatusCode()) {
11776
LOG.error("Request to {} returned with status {}", target, responseStatus);
11877
return Optional.empty();
11978
}
12079
JadeResults<JadeStorageVolume> storageContentResults = response.readEntity(new GenericType<JadeResults<JadeStorageVolume>>() {
12180
});
122-
return storageContentResults.resultList.stream().findFirst()
81+
return storageContentResults.getResultList().stream().findFirst()
12382
.map(jadeVolume -> {
12483
String renderedVolumePath;
125-
if (storagePath.startsWith(jadeVolume.storageVirtualPath)) {
126-
renderedVolumePath = Paths.get(jadeVolume.storageVirtualPath).relativize(Paths.get(storagePath)).toString();
84+
if (StringUtils.startsWith(storagePath, jadeVolume.getStorageVirtualPath())) {
85+
renderedVolumePath = Paths.get(jadeVolume.getStorageVirtualPath()).relativize(Paths.get(storagePath)).toString();
12786
} else {
128-
renderedVolumePath = Paths.get(jadeVolume.baseStorageRootDir).relativize(Paths.get(storagePath)).toString();
87+
renderedVolumePath = Paths.get(jadeVolume.getBaseStorageRootDir()).relativize(Paths.get(storagePath)).toString();
12988
}
130-
LOG.info("Create JADE volume location with URLs {}, {} and volume path {}", jadeVolume.storageServiceURL, jadeVolume.getVolumeStorageURI(), renderedVolumePath);
131-
return new JADEBasedDataLocation(
132-
jadeVolume.storageServiceURL,
89+
LOG.info("Create JADE volume location with URLs {}, {} and volume path {}", jadeVolume.getStorageServiceURL(), jadeVolume.getVolumeStorageURI(), renderedVolumePath);
90+
return new JadeBasedDataLocation(
91+
jadeVolume.getStorageServiceURL(),
13392
jadeVolume.getVolumeStorageURI(),
13493
renderedVolumePath,
13594
null,
13695
null,
137-
httpClientProvider);
96+
storageAttributes);
13897
})
13998
;
14099
} finally {
@@ -143,17 +102,16 @@ public Optional<JADEBasedDataLocation> findDataLocation(String storagePathParam)
143102

144103
}
145104

146-
public Streamable<InputStream> streamContent(String serverURL, String dataPath) {
105+
public Streamable<InputStream> streamContent(String serverURL, String dataPath, JadeStorageAttributes storageAttributes) {
147106
Preconditions.checkArgument(serverURL != null && serverURL.trim().length() > 0);
148107
Preconditions.checkArgument(dataPath != null && dataPath.trim().length() > 0);
149-
ClientProxy httpClient = getHttpClient();
108+
Client httpClient = clientProvider.getClient();
150109
try {
151110
WebTarget target = httpClient.target(serverURL)
152111
.path("agent_storage/storage_path/data_content")
153112
.path(dataPath);
154113
LOG.info("Streaming tile from {}", target);
155-
Response response = target.request()
156-
.get();
114+
Response response = createRequest(target, storageAttributes).get();
157115
int responseStatus = response.getStatus();
158116
if (responseStatus == Response.Status.OK.getStatusCode()) {
159117
InputStream is = (InputStream) response.getEntity();
@@ -167,16 +125,15 @@ public Streamable<InputStream> streamContent(String serverURL, String dataPath)
167125
}
168126
}
169127

170-
public boolean checkStoragePath(String storagePath) {
128+
public boolean checkStoragePath(String storagePath, JadeStorageAttributes storageAttributes) {
171129
Preconditions.checkArgument(storagePath != null && storagePath.trim().length() > 0);
172-
ClientProxy httpClient = getHttpClient();
130+
Client httpClient = clientProvider.getClient();
173131
try {
174132
LOG.debug("Check if storage path exists {}", storagePath);
175133
WebTarget target = httpClient.target(jadeURL)
176134
.path("storage_content/storage_path_redirect")
177-
.path(storagePath);
178-
Response response = target.request()
179-
.head();
135+
.queryParam("contentPath", storagePath);
136+
Response response = createRequest(target, storageAttributes).head();
180137
int responseStatus = response.getStatus();
181138
if (responseStatus != Response.Status.OK.getStatusCode()) {
182139
LOG.error("Request to {} returned with status {}", target, responseStatus);
@@ -189,8 +146,14 @@ public boolean checkStoragePath(String storagePath) {
189146
}
190147
}
191148

192-
private ClientProxy getHttpClient() {
193-
return httpClientProvider.getClient();
149+
private Invocation.Builder createRequest(WebTarget target, JadeStorageAttributes storageAttributes) {
150+
Invocation.Builder requestBuilder = target.request();
151+
for (String storageAttribute : storageAttributes.getAttributeNames()) {
152+
requestBuilder = requestBuilder.header(
153+
storageAttribute,
154+
storageAttributes.getAttributeValue(storageAttribute)
155+
);
156+
}
157+
return requestBuilder;
194158
}
195-
196159
}

0 commit comments

Comments
 (0)